[CORD-1880] Improve DHCP relay CLI

Change-Id: I38b8b0fdfefa8831c70c74708549fd6805f624bc
This commit is contained in:
Yi Tseng 2017-09-07 16:22:51 -07:00
parent 81cc6426ef
commit 919b2dffdc
8 changed files with 787 additions and 568 deletions

View File

@ -17,7 +17,7 @@
package org.onosproject.dhcprelay;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@ -39,6 +39,7 @@ import org.onlab.packet.dhcp.CircuitId;
import org.onlab.packet.dhcp.DhcpOption;
import org.onlab.packet.dhcp.DhcpRelayAgentOption;
import org.onosproject.dhcprelay.api.DhcpHandler;
import org.onosproject.dhcprelay.api.DhcpServerInfo;
import org.onosproject.dhcprelay.config.DhcpServerConfig;
import org.onosproject.dhcprelay.store.DhcpRecord;
import org.onosproject.dhcprelay.store.DhcpRelayStore;
@ -114,24 +115,8 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
protected HostProviderService providerService;
private InternalHostListener hostListener = new InternalHostListener();
private Ip4Address dhcpServerIp = null;
// dhcp server may be connected directly to the SDN network or
// via an external gateway. When connected directly, the dhcpConnectPoint, dhcpConnectMac,
// and dhcpConnectVlan refer to the server. When connected via the gateway, they refer
// to the gateway.
private ConnectPoint dhcpServerConnectPoint = null;
private MacAddress dhcpConnectMac = null;
private VlanId dhcpConnectVlan = null;
private Ip4Address dhcpGatewayIp = null;
private Ip4Address relayAgentIp = null;
// Indirect case DHCP server
private Ip4Address indirectDhcpServerIp = null;
private ConnectPoint indirectDhcpServerConnectPoint = null;
private MacAddress indirectDhcpConnectMac = null;
private VlanId indirectDhcpConnectVlan = null;
private Ip4Address indirectDhcpGatewayIp = null;
private Ip4Address indirectRelayAgentIp = null;
private List<DhcpServerInfo> defaultServerInfoList = Lists.newArrayList();
private List<DhcpServerInfo> indirectServerInfoList = Lists.newArrayList();
@Activate
protected void activate() {
@ -143,81 +128,42 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
protected void deactivate() {
providerRegistry.unregister(this);
hostService.removeListener(hostListener);
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
if (dhcpGatewayIp != null) {
hostService.stopMonitoringIp(dhcpGatewayIp);
}
if (dhcpServerIp != null) {
hostService.stopMonitoringIp(dhcpServerIp);
}
if (indirectDhcpGatewayIp != null) {
hostService.stopMonitoringIp(indirectDhcpGatewayIp);
}
if (indirectDhcpServerIp != null) {
hostService.stopMonitoringIp(indirectDhcpServerIp);
}
hostService.removeListener(hostListener);
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
defaultServerInfoList.forEach(this::stopMonitoringIps);
defaultServerInfoList.clear();
indirectServerInfoList.forEach(this::stopMonitoringIps);
indirectServerInfoList.clear();
}
@Override
public void setDhcpServerIp(IpAddress dhcpServerIp) {
checkNotNull(dhcpServerIp, "DHCP server IP can't be null");
checkState(dhcpServerIp.isIp4(), "Invalid server IP for DHCPv4 relay handler");
this.dhcpServerIp = dhcpServerIp.getIp4Address();
}
@Override
public void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
checkNotNull(dhcpServerConnectPoint, "Server connect point can't null");
this.dhcpServerConnectPoint = dhcpServerConnectPoint;
}
@Override
public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
this.dhcpConnectMac = dhcpConnectMac;
}
@Override
public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
this.dhcpConnectVlan = dhcpConnectVlan;
}
@Override
public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
if (dhcpGatewayIp != null) {
checkState(dhcpGatewayIp.isIp4(), "Invalid gateway IP for DHCPv4 relay handler");
this.dhcpGatewayIp = dhcpGatewayIp.getIp4Address();
} else {
// removes gateway config
this.dhcpGatewayIp = null;
}
}
@Override
public Optional<IpAddress> getDhcpServerIp() {
return Optional.ofNullable(dhcpServerIp);
}
@Override
public Optional<IpAddress> getDhcpGatewayIp() {
return Optional.ofNullable(dhcpGatewayIp);
}
@Override
public Optional<MacAddress> getDhcpConnectMac() {
return Optional.ofNullable(dhcpConnectMac);
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
serverInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
hostService.stopMonitoringIp(gatewayIp);
});
serverInfo.getDhcpServerIp4().ifPresent(serverIp -> {
hostService.stopMonitoringIp(serverIp);
});
}
@Override
public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
setDhcpServerConfigs(configs, defaultServerInfoList);
}
@Override
public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
setDhcpServerConfigs(configs, indirectServerInfoList);
}
@Override
public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
return defaultServerInfoList;
}
@Override
public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
return indirectServerInfoList;
}
public void setDhcpServerConfigs(Collection<DhcpServerConfig> configs, List<DhcpServerInfo> serverInfoList) {
if (configs.size() == 0) {
// no config to update
return;
@ -226,105 +172,62 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
// TODO: currently we pick up first DHCP server config.
// Will use other server configs in the future for HA.
DhcpServerConfig serverConfig = configs.iterator().next();
if (!serverConfig.getDhcpServerConnectPoint().isPresent()) {
log.warn("Connect point from server config not exists");
return;
}
if (!serverConfig.getDhcpServerIp4().isPresent()) {
log.warn("IP from DHCP server config not exists");
return;
}
Ip4Address oldServerIp = this.dhcpServerIp;
Ip4Address oldGatewayIp = this.dhcpGatewayIp;
// stop monitoring gateway or server
if (oldGatewayIp != null) {
hostService.stopMonitoringIp(oldGatewayIp);
} else if (oldServerIp != null) {
hostService.stopMonitoringIp(oldServerIp);
}
this.dhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
this.dhcpServerIp = serverConfig.getDhcpServerIp4().get();
this.dhcpGatewayIp = serverConfig.getDhcpGatewayIp4().orElse(null);
// reset server mac and vlan
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
log.info("DHCP server connect point: " + this.dhcpServerConnectPoint);
log.info("DHCP server IP: " + this.dhcpServerIp);
IpAddress ipToProbe = MoreObjects.firstNonNull(this.dhcpGatewayIp, this.dhcpServerIp);
String hostToProbe = this.dhcpGatewayIp != null ? "gateway" : "DHCP server";
if (ipToProbe == null) {
log.warn("Server IP not set, can't probe it");
// not a DHCPv4 config
return;
}
log.info("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
hostService.startMonitoringIp(ipToProbe);
if (!serverInfoList.isEmpty()) {
// remove old server info
DhcpServerInfo oldServerInfo = serverInfoList.remove(0);
Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
if (!hosts.isEmpty()) {
Host host = hosts.iterator().next();
this.dhcpConnectVlan = host.vlan();
this.dhcpConnectMac = host.mac();
// stop monitoring gateway or server
oldServerInfo.getDhcpGatewayIp4().ifPresent(gatewayIp -> {
hostService.stopMonitoringIp(gatewayIp);
});
oldServerInfo.getDhcpServerIp4().ifPresent(serverIp -> {
hostService.stopMonitoringIp(serverIp);
});
}
this.relayAgentIp = serverConfig.getRelayAgentIp4().orElse(null);
}
@Override
public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
if (configs.size() == 0) {
// no config to update
return;
}
// TODO: currently we pick up first indirect DHCP server config.
// Will use other server configs in the future for HA.
DhcpServerConfig serverConfig = configs.iterator().next();
checkState(serverConfig.getDhcpServerConnectPoint().isPresent(),
// Create new server info according to the config
DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
DhcpServerInfo.Version.DHCP_V4);
checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
"Connect point not exists");
checkState(serverConfig.getDhcpServerIp4().isPresent(),
checkState(newServerInfo.getDhcpServerIp4().isPresent(),
"IP of DHCP server not exists");
Ip4Address oldServerIp = this.indirectDhcpServerIp;
Ip4Address oldGatewayIp = this.indirectDhcpGatewayIp;
// stop monitoring gateway or server
if (oldGatewayIp != null) {
hostService.stopMonitoringIp(oldGatewayIp);
} else if (oldServerIp != null) {
hostService.stopMonitoringIp(oldServerIp);
log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp4().orElse(null));
IpAddress ipToProbe;
if (newServerInfo.getDhcpGatewayIp4().isPresent()) {
ipToProbe = newServerInfo.getDhcpGatewayIp4().get();
} else {
ipToProbe = newServerInfo.getDhcpServerIp4().orElse(null);
}
String hostToProbe = newServerInfo.getDhcpGatewayIp4()
.map(ip -> "gateway").orElse("server");
this.indirectDhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
this.indirectDhcpServerIp = serverConfig.getDhcpServerIp4().get();
this.indirectDhcpGatewayIp = serverConfig.getDhcpGatewayIp4().orElse(null);
// reset server mac and vlan
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
log.info("Indirect DHCP server connect point: " + this.indirectDhcpServerConnectPoint);
log.info("Indirect DHCP server IP: " + this.indirectDhcpServerIp);
IpAddress ipToProbe = MoreObjects.firstNonNull(this.indirectDhcpGatewayIp, this.indirectDhcpServerIp);
String hostToProbe = this.indirectDhcpGatewayIp != null ? "gateway" : "DHCP server";
log.info("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
log.debug("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
hostService.startMonitoringIp(ipToProbe);
Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
if (!hosts.isEmpty()) {
Host host = hosts.iterator().next();
this.indirectDhcpConnectVlan = host.vlan();
this.indirectDhcpConnectMac = host.mac();
newServerInfo.setDhcpConnectVlan(host.vlan());
newServerInfo.setDhcpConnectMac(host.mac());
}
// Add new server info
serverInfoList.add(0, newServerInfo);
this.indirectRelayAgentIp = serverConfig.getRelayAgentIp4().orElse(null);
// Remove duplicated server info
Set<DhcpServerInfo> nonDupServerInfoList = Sets.newLinkedHashSet();
nonDupServerInfoList.addAll(serverInfoList);
serverInfoList.clear();
serverInfoList.addAll(nonDupServerInfoList);
}
@Override
@ -333,7 +236,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
checkState(payload instanceof DHCP, "Payload is not a DHCP");
DHCP dhcpPayload = (DHCP) payload;
if (!configured()) {
log.warn("Missing DHCP relay server config. Abort packet processing");
log.warn("Missing default DHCP relay server config. Abort packet processing");
return;
}
@ -399,7 +302,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @return true if all information we need have been initialized
*/
private boolean configured() {
return dhcpServerConnectPoint != null && dhcpServerIp != null;
return !defaultServerInfoList.isEmpty();
}
/**
@ -424,15 +327,8 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
*
* @return the Interface facing to the server; null if not found
*/
private Interface getServerInterface() {
if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
return null;
}
return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
.stream()
.filter(iface -> interfaceContainsVlan(iface, dhcpConnectVlan))
.findFirst()
.orElse(null);
private Interface getDefaultServerInterface() {
return getServerInterface(defaultServerInfoList);
}
/**
@ -442,12 +338,19 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @return the Interface facing to the server; null if not found
*/
private Interface getIndirectServerInterface() {
if (indirectDhcpServerConnectPoint == null || indirectDhcpConnectVlan == null) {
return getServerInterface();
return getServerInterface(indirectServerInfoList);
}
private Interface getServerInterface(List<DhcpServerInfo> serverInfos) {
DhcpServerInfo serverInfo = serverInfos.get(0);
ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
if (dhcpServerConnectPoint == null || dhcpConnectVlan == null) {
return null;
}
return interfaceService.getInterfacesByPort(indirectDhcpServerConnectPoint)
return interfaceService.getInterfacesByPort(dhcpServerConnectPoint)
.stream()
.filter(iface -> interfaceContainsVlan(iface, indirectDhcpConnectVlan))
.filter(iface -> interfaceContainsVlan(iface, dhcpConnectVlan))
.findFirst()
.orElse(null);
}
@ -484,6 +387,34 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
VlanId dhcpConnectVlan = null;
MacAddress dhcpConnectMac = null;
Ip4Address dhcpServerIp = null;
Ip4Address relayAgentIp = null;
VlanId indirectDhcpConnectVlan = null;
MacAddress indirectDhcpConnectMac = null;
Ip4Address indirectDhcpServerIp = null;
Ip4Address indirectRelayAgentIp = null;
if (!defaultServerInfoList.isEmpty()) {
DhcpServerInfo serverInfo = defaultServerInfoList.get(0);
dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
relayAgentIp = serverInfo.getRelayAgentIp4().orElse(null);
}
if (!indirectServerInfoList.isEmpty()) {
DhcpServerInfo indirectServerInfo = indirectServerInfoList.get(0);
indirectDhcpConnectVlan = indirectServerInfo.getDhcpConnectVlan().orElse(null);
indirectDhcpConnectMac = indirectServerInfo.getDhcpConnectMac().orElse(null);
indirectDhcpServerIp = indirectServerInfo.getDhcpServerIp4().orElse(null);
indirectRelayAgentIp = indirectServerInfo.getRelayAgentIp4().orElse(null);
}
Ip4Address clientInterfaceIp =
interfaceService.getInterfacesByPort(context.inPacket().receivedFrom())
.stream()
@ -500,7 +431,7 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
return null;
}
boolean isDirectlyConnected = directlyConnected(dhcpPacket);
Interface serverInterface = isDirectlyConnected ? getServerInterface() : getIndirectServerInterface();
Interface serverInterface = isDirectlyConnected ? getDefaultServerInterface() : getIndirectServerInterface();
if (serverInterface == null) {
log.warn("Can't get {} server interface, ignore", isDirectlyConnected ? "direct" : "indirect");
return null;
@ -512,10 +443,8 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
return null;
}
if (dhcpConnectMac == null) {
log.warn("DHCP {} not yet resolved .. Aborting DHCP "
log.warn("DHCP Server/Gateway IP not yet resolved .. Aborting DHCP "
+ "packet processing from client on port: {}",
(dhcpGatewayIp == null) ? "server IP " + dhcpServerIp
: "gateway IP " + dhcpGatewayIp,
context.inPacket().receivedFrom());
return null;
}
@ -917,10 +846,12 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @param packet the packet
*/
private void handleDhcpDiscoverAndRequest(Ethernet packet, DHCP dhcpPayload) {
ConnectPoint portToFotward = dhcpServerConnectPoint;
if (!directlyConnected(dhcpPayload) && indirectDhcpServerConnectPoint != null) {
portToFotward = indirectDhcpServerConnectPoint;
boolean direct = directlyConnected(dhcpPayload);
DhcpServerInfo serverInfo = defaultServerInfoList.get(0);
if (!direct && !indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
}
ConnectPoint portToFotward = serverInfo.getDhcpServerConnectPoint().orElse(null);
// send packet to dhcp server connect point.
if (portToFotward != null) {
TrafficTreatment t = DefaultTrafficTreatment.builder()
@ -1040,6 +971,9 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
class InternalHostListener implements HostListener {
@Override
public void event(HostEvent event) {
if (!configured()) {
return;
}
switch (event.type()) {
case HOST_ADDED:
case HOST_UPDATED:
@ -1065,32 +999,54 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostMoved(Host host) {
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp) &&
!host.locations().contains(this.dhcpServerConnectPoint)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
Set<ConnectPoint> hostConnectPoints = host.locations().stream()
.map(hl -> new ConnectPoint(hl.elementId(), hl.port()))
.collect(Collectors.toSet());
DhcpServerInfo serverInfo;
ConnectPoint dhcpServerConnectPoint;
Ip4Address dhcpGatewayIp;
Ip4Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp) &&
!host.locations().contains(this.dhcpServerConnectPoint)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
if (!indirectServerInfoList.isEmpty()) {
// Indirect server
serverInfo = indirectServerInfoList.get(0);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp) &&
!host.locations().contains(this.indirectDhcpServerConnectPoint)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
}
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp) &&
!host.locations().contains(this.indirectDhcpServerConnectPoint)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
}
@ -1102,30 +1058,46 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostUpdated(Host host) {
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
this.dhcpConnectMac = host.mac();
this.dhcpConnectVlan = host.vlan();
DhcpServerInfo serverInfo;
Ip4Address dhcpGatewayIp;
Ip4Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp)) {
this.dhcpConnectMac = host.mac();
this.dhcpConnectVlan = host.vlan();
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
this.indirectDhcpConnectMac = host.mac();
this.indirectDhcpConnectVlan = host.vlan();
}
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
this.indirectDhcpConnectMac = host.mac();
this.indirectDhcpConnectVlan = host.vlan();
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
}
}
/**
@ -1135,28 +1107,44 @@ public class Dhcp4HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostRemoved(Host host) {
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
DhcpServerInfo serverInfo;
Ip4Address dhcpGatewayIp;
Ip4Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp4().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp4().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
}
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
}

View File

@ -17,9 +17,9 @@
package org.onosproject.dhcprelay;
import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Deactivate;
import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
import com.google.common.collect.ImmutableSet;
import org.apache.felix.scr.annotations.Component;
@ -47,6 +47,7 @@ import org.onlab.packet.dhcp.Dhcp6IaAddressOption;
import org.onlab.packet.dhcp.Dhcp6IaPrefixOption;
import org.onlab.util.HexString;
import org.onosproject.dhcprelay.api.DhcpHandler;
import org.onosproject.dhcprelay.api.DhcpServerInfo;
import org.onosproject.dhcprelay.store.DhcpRelayStore;
import org.onosproject.net.host.HostProvider;
import org.onosproject.net.host.HostProviderRegistry;
@ -83,6 +84,7 @@ import java.util.Collection;
import java.util.Optional;
import java.util.Set;
import java.util.ArrayList;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
@ -134,6 +136,9 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
private Ip6Address indirectDhcpGatewayIp = null;
private Ip6Address indirectRelayAgentIpFromCfg = null;
private List<DhcpServerInfo> defaultServerInfoList = Lists.newArrayList();
private List<DhcpServerInfo> indirectServerInfoList = Lists.newArrayList();
// CLIENT message types
public static final Set<Byte> MSG_TYPE_FROM_CLIENT =
@ -159,114 +164,31 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
protected void deactivate() {
providerRegistry.unregister(this);
hostService.removeListener(hostListener);
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
defaultServerInfoList.forEach(this::stopMonitoringIps);
defaultServerInfoList.clear();
indirectServerInfoList.forEach(this::stopMonitoringIps);
indirectServerInfoList.clear();
}
if (dhcpGatewayIp != null) {
hostService.stopMonitoringIp(dhcpGatewayIp);
} else if (dhcpServerIp != null) {
hostService.stopMonitoringIp(dhcpServerIp);
}
private void stopMonitoringIps(DhcpServerInfo serverInfo) {
serverInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
hostService.stopMonitoringIp(gatewayIp);
});
serverInfo.getDhcpServerIp6().ifPresent(serverIp -> {
hostService.stopMonitoringIp(serverIp);
});
}
@Override
public void setDhcpServerIp(IpAddress dhcpServerIp) {
checkNotNull(dhcpServerIp, "DHCP server IP can't be null");
checkState(dhcpServerIp.isIp6(), "Invalid server IP for DHCPv6 relay handler");
this.dhcpServerIp = dhcpServerIp.getIp6Address();
public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
return defaultServerInfoList;
}
@Override
public void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
checkNotNull(dhcpServerConnectPoint, "Server connect point can't null");
this.dhcpServerConnectPoint = dhcpServerConnectPoint;
public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
return indirectServerInfoList;
}
@Override
public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
this.dhcpConnectMac = dhcpConnectMac;
}
@Override
public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
this.dhcpConnectVlan = dhcpConnectVlan;
}
@Override
public void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
if (dhcpGatewayIp != null) {
checkState(dhcpGatewayIp.isIp6(), "Invalid gateway IP for DHCPv6 relay handler");
this.dhcpGatewayIp = dhcpGatewayIp.getIp6Address();
} else {
// removes gateway config
this.dhcpGatewayIp = null;
}
}
@Override
public Optional<IpAddress> getDhcpServerIp() {
return Optional.ofNullable(dhcpServerIp);
}
@Override
public Optional<IpAddress> getDhcpGatewayIp() {
return Optional.ofNullable(dhcpGatewayIp);
}
@Override
public Optional<MacAddress> getDhcpConnectMac() {
return Optional.ofNullable(dhcpConnectMac);
}
// Indirect DHCP server
public void setIndirectDhcpServerIp(IpAddress dhcpServerIp) {
checkNotNull(dhcpServerIp, "DHCP indirect server IP can't be null");
checkState(dhcpServerIp.isIp6(), "Invalid indirect server IP for DHCPv6 relay handler");
this.indirectDhcpServerIp = dhcpServerIp.getIp6Address();
}
public void setIndirectDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
checkNotNull(dhcpServerConnectPoint, "Indirect Server connect point can't null");
this.indirectDhcpServerConnectPoint = dhcpServerConnectPoint;
}
public void setIndirectDhcpConnectMac(MacAddress dhcpConnectMac) {
this.indirectDhcpConnectMac = dhcpConnectMac;
}
public void setIndirectDhcpConnectVlan(VlanId dhcpConnectVlan) {
this.indirectDhcpConnectVlan = dhcpConnectVlan;
}
public void setIndirectDhcpGatewayIp(IpAddress dhcpGatewayIp) {
if (dhcpGatewayIp != null) {
checkState(dhcpGatewayIp.isIp6(), "Invalid indirect gateway IP for DHCPv6 relay handler");
this.indirectDhcpGatewayIp = dhcpGatewayIp.getIp6Address();
} else {
// removes gateway config
this.indirectDhcpGatewayIp = null;
}
}
public Optional<IpAddress> getIndirectDhcpServerIp() {
return Optional.ofNullable(indirectDhcpServerIp);
}
public Optional<IpAddress> getIndirectDhcpGatewayIp() {
return Optional.ofNullable(indirectDhcpGatewayIp);
}
public Optional<MacAddress> getIndirectDhcpConnectMac() {
return Optional.ofNullable(indirectDhcpConnectMac);
}
@Override
public void processDhcpPacket(PacketContext context, BasePacket payload) {
checkNotNull(payload, "DHCP6 payload can't be null");
@ -323,12 +245,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
* @return true if all information we need have been initialized
*/
public boolean configured() {
log.warn("dhcpServerConnectPoint {} dhcpServerIp {}," +
" indirectDhcpServerConnectPoint {} indirectDhcpServerIp {}",
this.dhcpServerConnectPoint, this.dhcpServerIp,
this.indirectDhcpServerConnectPoint, this.indirectDhcpServerIp);
return (this.dhcpServerConnectPoint != null && this.dhcpServerIp != null) ||
(this.indirectDhcpServerConnectPoint != null && this.indirectDhcpServerIp != null);
return !defaultServerInfoList.isEmpty();
}
@Override
@ -950,7 +867,6 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
*/
private InternalPacket processDhcp6PacketFromServer(PacketContext context,
Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
// get dhcp6 header.
Ethernet etherReply = receivedPacket.duplicate();
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
@ -1056,7 +972,7 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
return new InternalPacket(etherReply, clientConnectionPoint);
}
// Returns the first v4 interface ip out of a set of interfaces or null.
// Returns the first v6 interface ip out of a set of interfaces or null.
// Checks all interfaces, and ignores v6 interface ips
private Ip6Address getRelayAgentIPv6Address(Set<Interface> intfs) {
for (Interface intf : intfs) {
@ -1072,6 +988,17 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
@Override
public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
setDhcpServerConfigs(configs, defaultServerInfoList);
reloadServerSettings();
}
@Override
public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
setDhcpServerConfigs(configs, indirectServerInfoList);
reloadServerSettings();
}
public void setDhcpServerConfigs(Collection<DhcpServerConfig> configs, List<DhcpServerInfo> serverInfoList) {
if (configs.size() == 0) {
// no config to update
return;
@ -1080,111 +1007,62 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
// TODO: currently we pick up first DHCP server config.
// Will use other server configs in the future for HA.
DhcpServerConfig serverConfig = configs.iterator().next();
if (!serverConfig.getDhcpServerConnectPoint().isPresent()) {
log.warn("Connect point not exists");
return;
}
if (!serverConfig.getDhcpServerIp6().isPresent()) {
log.warn("IP of DHCP6 server not exists");
return;
}
Ip6Address oldServerIp = this.dhcpServerIp;
Ip6Address oldGatewayIp = this.dhcpGatewayIp;
// stop monitoring gateway or server
if (oldGatewayIp != null) {
hostService.stopMonitoringIp(oldGatewayIp);
} else if (oldServerIp != null) {
hostService.stopMonitoringIp(oldServerIp);
}
this.dhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
this.dhcpServerIp = serverConfig.getDhcpServerIp6().get();
this.dhcpGatewayIp = serverConfig.getDhcpGatewayIp6().orElse(null);
this.relayAgentIpFromCfg = serverConfig.getRelayAgentIp6().orElse(null);
// reset server mac and vlan
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
log.info("DHCP6 server connect point: " + this.dhcpServerConnectPoint);
log.info("DHCP6 server IP: " + this.dhcpServerIp);
IpAddress ipToProbe = MoreObjects.firstNonNull(this.dhcpGatewayIp, this.dhcpServerIp);
String hostToProbe = this.dhcpGatewayIp != null ? "gateway" : "DHCP6 server";
if (ipToProbe == null) {
log.warn("Server IP6 not set, can't probe it");
// not a DHCPv6 config
return;
}
log.info("Probing to resolve {} IP6 {}", hostToProbe, ipToProbe);
if (!serverInfoList.isEmpty()) {
// remove old server info
DhcpServerInfo oldServerInfo = serverInfoList.remove(0);
// stop monitoring gateway or server
oldServerInfo.getDhcpGatewayIp6().ifPresent(gatewayIp -> {
hostService.stopMonitoringIp(gatewayIp);
});
oldServerInfo.getDhcpServerIp6().ifPresent(serverIp -> {
hostService.stopMonitoringIp(serverIp);
});
}
// Create new server info according to the config
DhcpServerInfo newServerInfo = new DhcpServerInfo(serverConfig,
DhcpServerInfo.Version.DHCP_V6);
checkState(newServerInfo.getDhcpServerConnectPoint().isPresent(),
"Connect point not exists");
checkState(newServerInfo.getDhcpServerIp6().isPresent(),
"IP of DHCP server not exists");
log.debug("DHCP server connect point: {}", newServerInfo.getDhcpServerConnectPoint().orElse(null));
log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp6().orElse(null));
IpAddress ipToProbe;
if (newServerInfo.getDhcpGatewayIp6().isPresent()) {
ipToProbe = newServerInfo.getDhcpGatewayIp6().get();
} else {
ipToProbe = newServerInfo.getDhcpServerIp6().orElse(null);
}
String hostToProbe = newServerInfo.getDhcpGatewayIp6()
.map(ip -> "gateway").orElse("server");
log.debug("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
hostService.startMonitoringIp(ipToProbe);
Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
if (!hosts.isEmpty()) {
Host host = hosts.iterator().next();
this.dhcpConnectVlan = host.vlan();
this.dhcpConnectMac = host.mac();
newServerInfo.setDhcpConnectVlan(host.vlan());
newServerInfo.setDhcpConnectMac(host.mac());
}
// Add new server info
serverInfoList.add(0, newServerInfo);
}
@Override
public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
if (configs.size() == 0) {
// no config to update
return;
}
// TODO: currently we pick up Second DHCP server config for indirect.
// Will use other server configs in the future for HA.
DhcpServerConfig serverConfig = configs.iterator().next();
checkState(serverConfig.getDhcpServerConnectPoint().isPresent(),
"Connect point not exists");
checkState(serverConfig.getDhcpServerIp6().isPresent(),
"IP of DHCP6 server not exists");
Ip6Address oldServerIp = this.indirectDhcpServerIp;
Ip6Address oldGatewayIp = this.indirectDhcpGatewayIp;
// stop monitoring gateway or server
if (oldGatewayIp != null) {
hostService.stopMonitoringIp(oldGatewayIp);
} else if (oldServerIp != null) {
hostService.stopMonitoringIp(oldServerIp);
}
this.indirectDhcpServerConnectPoint = serverConfig.getDhcpServerConnectPoint().get();
this.indirectDhcpServerIp = serverConfig.getDhcpServerIp6().get();
this.indirectDhcpGatewayIp = serverConfig.getDhcpGatewayIp6().orElse(null);
this.indirectRelayAgentIpFromCfg = serverConfig.getRelayAgentIp6().orElse(null);
// reset server mac and vlan
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
log.info("DHCP6 server connect point: " + this.indirectDhcpServerConnectPoint);
log.info("DHCP6 server IP: " + this.indirectDhcpServerIp);
IpAddress ipToProbe = MoreObjects.firstNonNull(this.indirectDhcpGatewayIp, this.indirectDhcpServerIp);
String hostToProbe = this.indirectDhcpGatewayIp != null ? "gateway" : "DHCP6 server";
if (ipToProbe == null) {
log.warn("Server IP6 not set, can't probe it");
return;
}
log.info("Probing to resolve {} IP6 {}", hostToProbe, ipToProbe);
hostService.startMonitoringIp(ipToProbe);
Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
if (!hosts.isEmpty()) {
Host host = hosts.iterator().next();
this.indirectDhcpConnectVlan = host.vlan();
this.indirectDhcpConnectMac = host.mac();
}
// Remove duplicated server info
Set<DhcpServerInfo> nonDupServerInfoList = Sets.newLinkedHashSet();
nonDupServerInfoList.addAll(serverInfoList);
serverInfoList.clear();
serverInfoList.addAll(nonDupServerInfoList);
}
class InternalHostListener implements HostListener {
@ -1215,37 +1093,62 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostMoved(Host host) {
if (this.dhcpServerConnectPoint == null && this.indirectDhcpServerConnectPoint == null) {
return;
}
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp) &&
!host.locations().contains(this.dhcpServerConnectPoint)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
Set<ConnectPoint> hostConnectPoints = host.locations().stream()
.map(hl -> new ConnectPoint(hl.elementId(), hl.port()))
.collect(Collectors.toSet());
DhcpServerInfo serverInfo;
ConnectPoint dhcpServerConnectPoint;
Ip6Address dhcpGatewayIp;
Ip6Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpServerConnectPoint == null) {
return;
}
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp) &&
!host.locations().contains(this.dhcpServerConnectPoint)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp) &&
!host.locations().contains(this.indirectDhcpServerConnectPoint)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
}
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp) &&
!host.locations().contains(this.indirectDhcpServerConnectPoint)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpServerConnectPoint == null) {
return;
}
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp) &&
!hostConnectPoints.contains(dhcpServerConnectPoint)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
reloadServerSettings();
}
/**
@ -1255,30 +1158,45 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostUpdated(Host host) {
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
this.dhcpConnectMac = host.mac();
this.dhcpConnectVlan = host.vlan();
DhcpServerInfo serverInfo;
Ip6Address dhcpGatewayIp;
Ip6Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp)) {
this.dhcpConnectMac = host.mac();
this.dhcpConnectVlan = host.vlan();
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
this.indirectDhcpConnectMac = host.mac();
this.indirectDhcpConnectVlan = host.vlan();
}
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
this.indirectDhcpConnectMac = host.mac();
this.indirectDhcpConnectVlan = host.vlan();
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectMac(host.mac());
serverInfo.setDhcpConnectVlan(host.vlan());
}
}
}
reloadServerSettings();
}
/**
@ -1288,31 +1206,69 @@ public class Dhcp6HandlerImpl implements DhcpHandler, HostProvider {
* @param host the host
*/
private void hostRemoved(Host host) {
if (this.dhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.dhcpGatewayIp)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
DhcpServerInfo serverInfo;
Ip6Address dhcpGatewayIp;
Ip6Address dhcpServerIp;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
//return;
}
if (this.dhcpServerIp != null) {
if (host.ipAddresses().contains(this.dhcpServerIp)) {
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
}
if (this.indirectDhcpGatewayIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpGatewayIp)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
if (dhcpGatewayIp != null) {
if (host.ipAddresses().contains(dhcpGatewayIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
if (dhcpServerIp != null) {
if (host.ipAddresses().contains(dhcpServerIp)) {
serverInfo.setDhcpConnectVlan(null);
serverInfo.setDhcpConnectMac(null);
}
}
//return;
}
if (this.indirectDhcpServerIp != null) {
if (host.ipAddresses().contains(this.indirectDhcpServerIp)) {
this.indirectDhcpConnectMac = null;
this.indirectDhcpConnectVlan = null;
}
reloadServerSettings();
}
private void reloadServerSettings() {
DhcpServerInfo serverInfo;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
this.dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
this.dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
this.dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
this.dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
this.dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
}
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
this.indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
this.indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
this.indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
this.indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
this.indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
this.indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6().orElse(null);
}
}
/**

View File

@ -55,6 +55,7 @@ import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcprelay.api.DhcpHandler;
import org.onosproject.dhcprelay.api.DhcpRelayService;
import org.onosproject.dhcprelay.api.DhcpServerInfo;
import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
import org.onosproject.dhcprelay.config.IgnoreDhcpConfig;
import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
@ -485,6 +486,22 @@ public class DhcpRelayManager implements DhcpRelayService {
.findFirst();
}
@Override
public List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
return ImmutableList.<DhcpServerInfo>builder()
.addAll(v4Handler.getDefaultDhcpServerInfoList())
.addAll(v6Handler.getDefaultDhcpServerInfoList())
.build();
}
@Override
public List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
return ImmutableList.<DhcpServerInfo>builder()
.addAll(v4Handler.getIndirectDhcpServerInfoList())
.addAll(v6Handler.getIndirectDhcpServerInfoList())
.build();
}
/**
* Gets DHCP data from a packet.
*

View File

@ -26,6 +26,8 @@ import org.onosproject.net.ConnectPoint;
import org.onosproject.net.packet.PacketContext;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
@ -47,7 +49,9 @@ public interface DhcpHandler {
* @deprecated 1.12 get the address from config service
*/
@Deprecated
Optional<IpAddress> getDhcpServerIp();
default Optional<IpAddress> getDhcpServerIp() {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Gets DHCP gateway IP.
@ -56,7 +60,9 @@ public interface DhcpHandler {
* @deprecated 1.12 get the address from config service
*/
@Deprecated
Optional<IpAddress> getDhcpGatewayIp();
default Optional<IpAddress> getDhcpGatewayIp() {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Gets DHCP connect Mac address.
@ -65,7 +71,9 @@ public interface DhcpHandler {
* @deprecated 1.12 get host mac from host service
*/
@Deprecated
Optional<MacAddress> getDhcpConnectMac();
default Optional<MacAddress> getDhcpConnectMac() {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Sets DHCP gateway IP.
@ -74,7 +82,9 @@ public interface DhcpHandler {
* @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
@Deprecated
void setDhcpGatewayIp(IpAddress dhcpGatewayIp);
default void setDhcpGatewayIp(IpAddress dhcpGatewayIp) {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Sets DHCP connect vlan.
@ -83,7 +93,9 @@ public interface DhcpHandler {
* @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
@Deprecated
void setDhcpConnectVlan(VlanId dhcpConnectVlan);
default void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Sets DHCP connect Mac address.
@ -92,7 +104,9 @@ public interface DhcpHandler {
* @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
@Deprecated
void setDhcpConnectMac(MacAddress dhcpConnectMac);
default void setDhcpConnectMac(MacAddress dhcpConnectMac) {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Sets DHCP server connect point.
@ -101,7 +115,9 @@ public interface DhcpHandler {
* @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
@Deprecated
void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint);
default void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint) {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Sets DHCP server IP.
@ -110,7 +126,27 @@ public interface DhcpHandler {
* @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
@Deprecated
void setDhcpServerIp(IpAddress dhcpServerIp);
default void setDhcpServerIp(IpAddress dhcpServerIp) {
throw new UnsupportedOperationException("Method deprecated");
}
/**
* Gets list of default DHCP server information.
*
* @return list of default DHCP server information
*/
default List<DhcpServerInfo> getDefaultDhcpServerInfoList() {
return Collections.emptyList();
}
/**
* Gets list of indirect DHCP server information.
*
* @return list of indirect DHCP server information
*/
default List<DhcpServerInfo> getIndirectDhcpServerInfoList() {
return Collections.emptyList();
}
/**
* Sets DHCP server config for default case.

View File

@ -22,6 +22,7 @@ import org.onosproject.dhcprelay.store.DhcpRecord;
import org.onosproject.net.HostId;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
public interface DhcpRelayService {
@ -44,6 +45,22 @@ public interface DhcpRelayService {
* Gets mac address of DHCP server.
*
* @return the mac address of DHCP server; empty if not exist
* @deprecated 1.12, use get DHCP server configs method
*/
@Deprecated
Optional<MacAddress> getDhcpServerMacAddress();
/**
* Gets list of default DHCP server information.
*
* @return list of default DHCP server information
*/
List<DhcpServerInfo> getDefaultDhcpServerInfoList();
/**
* Gets list of indirect DHCP server information.
*
* @return list of indirect DHCP server information
*/
List<DhcpServerInfo> getIndirectDhcpServerInfoList();
}

View File

@ -0,0 +1,156 @@
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.dhcprelay.api;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.dhcprelay.config.DhcpServerConfig;
import java.util.Optional;
/**
* class contains DHCP server information.
*/
public class DhcpServerInfo extends DhcpServerConfig {
public enum Version {
DHCP_V4,
DHCP_V6
}
private MacAddress dhcpConnectMac;
private VlanId dhcpConnectVlan;
private Version version;
/**
* Creates DHCP server information from config.
*
* @param config DHCP server config
* @param version DHCP version for the server
*/
public DhcpServerInfo(DhcpServerConfig config, Version version) {
this.connectPoint = config.getDhcpServerConnectPoint().orElse(null);
this.version = version;
switch (version) {
case DHCP_V4:
this.serverIp4Addr = config.getDhcpServerIp4().orElse(null);
this.gatewayIp4Addr = config.getDhcpGatewayIp4().orElse(null);
this.relayAgentIp4Addr = config.getRelayAgentIp4().orElse(null);
break;
case DHCP_V6:
this.serverIp6Addr = config.getDhcpServerIp6().orElse(null);
this.gatewayIp6Addr = config.getDhcpGatewayIp6().orElse(null);
this.relayAgentIp6Addr = config.getRelayAgentIp6().orElse(null);
break;
default:
break;
}
}
/**
* Sets DHCP server or gateway mac address.
*
* @param dhcpConnectMac the mac address
*/
public void setDhcpConnectMac(MacAddress dhcpConnectMac) {
this.dhcpConnectMac = dhcpConnectMac;
}
/**
* Sets DHCP server or gateway vlan id.
*
* @param dhcpConnectVlan the vlan id
*/
public void setDhcpConnectVlan(VlanId dhcpConnectVlan) {
this.dhcpConnectVlan = dhcpConnectVlan;
}
/**
* Gets DHCP server or gateway mac address.
*
* @return the mac address
*/
public Optional<MacAddress> getDhcpConnectMac() {
return Optional.ofNullable(dhcpConnectMac);
}
/**
* Gets DHCP server or gateway vlan id.
*
* @return the vlan id.
*/
public Optional<VlanId> getDhcpConnectVlan() {
return Optional.ofNullable(dhcpConnectVlan);
}
/**
* Get DHCP version of the DHCP server.
*
* @return the version; can be DHCP_V4 or DHCP_V6
*/
public Version getVersion() {
return version;
}
@Override
public String toString() {
MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(this);
toStringHelper
.add("dhcpConnectMac", dhcpConnectMac)
.add("dhcpConnectVlan", dhcpConnectVlan)
.add("connectPoint", connectPoint)
.add("version", version);
switch (version) {
case DHCP_V4:
toStringHelper
.add("serverIp4Addr", serverIp4Addr)
.add("gatewayIp4Addr", gatewayIp4Addr)
.add("relayAgentIp4Addr", relayAgentIp4Addr);
break;
case DHCP_V6:
toStringHelper
.add("serverIp6Addr", serverIp6Addr)
.add("gatewayIp6Addr", gatewayIp6Addr)
.add("relayAgentIp6Addr", relayAgentIp6Addr);
break;
default:
break;
}
return toStringHelper.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DhcpServerInfo)) {
return false;
}
DhcpServerInfo that = (DhcpServerInfo) o;
return super.equals(o) &&
Objects.equal(dhcpConnectMac, that.dhcpConnectMac) &&
Objects.equal(dhcpConnectVlan, that.dhcpConnectVlan) &&
version == that.version;
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), dhcpConnectMac, dhcpConnectVlan, version);
}
}

View File

@ -17,26 +17,20 @@
package org.onosproject.dhcprelay.cli;
import org.apache.karaf.shell.commands.Command;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.Tools;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
import org.onosproject.dhcprelay.DhcpRelayManager;
import org.onosproject.dhcprelay.api.DhcpServerInfo;
import org.onosproject.dhcprelay.api.DhcpRelayService;
import org.onosproject.dhcprelay.config.DhcpServerConfig;
import org.onosproject.dhcprelay.store.DhcpRecord;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.host.HostService;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
/**
@ -47,46 +41,37 @@ public class DhcpRelayCommand extends AbstractShellCommand {
private static final String HEADER = "DHCP relay records ([D]: Directly connected):";
private static final String NO_RECORDS = "No DHCP relay record found";
private static final String HOST = "id=%s/%s, locations=%s%s, last-seen=%s, IPv4=%s, IPv6=%s";
private static final String DHCP_SERVER_GW = "DHCP Server: %s, %s via %s (Mac: %s)";
private static final String DHCP_SERVER = "DHCP Server: %s, %s (Mac: %s)";
private static final String DHCP_SERVER_GW = "DHCP Server: %s, %s via %s (Mac: %s, relay IP overwrite: %s)";
private static final String DHCP_SERVER = "DHCP Server: %s, %s (Mac: %s, relay IP overwrite: %s)";
private static final String MISSING_SERVER_CFG = "DHCP Server info not available";
private static final String DIRECTLY = "[D]";
private static final String EMPTY = "";
private static final String NA = "N/A";
private static final String STATUS_FMT = "[%s, %s]";
private static final String STATUS_FMT_NH = "[%s via %s, %s]";
private static final String DEFAULT_SERVERS = "Default DHCP servers:";
private static final String INDIRECT_SERVERS = "Indirect DHCP servers:";
private static final DhcpRelayService DHCP_RELAY_SERVICE = get(DhcpRelayService.class);
private static final NetworkConfigRegistry CFG_SERVICE = get(NetworkConfigRegistry.class);
private static final HostService HOST_SERVICE = get(HostService.class);
private static final CoreService CORE_SERVICE = get(CoreService.class);
private static final ApplicationId APP_ID =
CORE_SERVICE.getAppId(DhcpRelayManager.DHCP_RELAY_APP);
@Override
protected void execute() {
// TODO: add indirect config
DefaultDhcpRelayConfig cfg = CFG_SERVICE.getConfig(APP_ID, DefaultDhcpRelayConfig.class);
if (cfg == null || cfg.dhcpServerConfigs().size() == 0) {
List<DhcpServerInfo> defaultDhcpServerInfoList = DHCP_RELAY_SERVICE.getDefaultDhcpServerInfoList();
List<DhcpServerInfo> indirectDhcpServerInfoList = DHCP_RELAY_SERVICE.getIndirectDhcpServerInfoList();
if (defaultDhcpServerInfoList.isEmpty() && indirectDhcpServerInfoList.isEmpty()) {
print(MISSING_SERVER_CFG);
return;
}
// DHCP server information
// TODO: currently we pick up first DHCP server config.
// Will use other server configs in the future.
DhcpServerConfig serverConfig = cfg.dhcpServerConfigs().get(0);
ConnectPoint connectPoint = serverConfig.getDhcpServerConnectPoint().orElse(null);
Ip4Address gatewayAddress = serverConfig.getDhcpGatewayIp4().orElse(null);
Ip4Address serverIp = serverConfig.getDhcpServerIp4().orElse(null);
String serverMac = DHCP_RELAY_SERVICE.getDhcpServerMacAddress()
.map(MacAddress::toString).orElse(NA);
if (gatewayAddress != null) {
print(DHCP_SERVER_GW, connectPoint, serverIp, gatewayAddress, serverMac);
} else {
print(DHCP_SERVER, connectPoint, serverIp, serverMac);
if (!defaultDhcpServerInfoList.isEmpty()) {
print(DEFAULT_SERVERS);
listServers(defaultDhcpServerInfoList);
}
if (!indirectDhcpServerInfoList.isEmpty()) {
print(INDIRECT_SERVERS);
listServers(indirectDhcpServerInfoList);
}
// DHCP records
@ -106,6 +91,44 @@ public class DhcpRelayCommand extends AbstractShellCommand {
ip6State(record)));
}
private void listServers(List<DhcpServerInfo> dhcpServerInfoList) {
dhcpServerInfoList.forEach(dhcpServerInfo -> {
String connectPoint = dhcpServerInfo.getDhcpServerConnectPoint()
.map(Object::toString).orElse(NA);
String serverMac = dhcpServerInfo.getDhcpConnectMac()
.map(Object::toString).orElse(NA);
String gatewayAddress;
String serverIp;
String relayAgentIp;
switch (dhcpServerInfo.getVersion()) {
case DHCP_V4:
gatewayAddress = dhcpServerInfo.getDhcpGatewayIp4()
.map(Object::toString).orElse(null);
serverIp = dhcpServerInfo.getDhcpServerIp4()
.map(Object::toString).orElse(NA);
relayAgentIp = dhcpServerInfo.getRelayAgentIp4()
.map(Object::toString).orElse(NA);
break;
case DHCP_V6:
gatewayAddress = dhcpServerInfo.getDhcpGatewayIp6()
.map(Object::toString).orElse(null);
serverIp = dhcpServerInfo.getDhcpServerIp6()
.map(Object::toString).orElse(NA);
relayAgentIp = dhcpServerInfo.getRelayAgentIp6()
.map(Object::toString).orElse(NA);
break;
default:
return;
}
if (gatewayAddress != null) {
print(DHCP_SERVER_GW, connectPoint, serverIp, gatewayAddress, serverMac, relayAgentIp);
} else {
print(DHCP_SERVER, connectPoint, serverIp, serverMac, relayAgentIp);
}
});
}
private String ip4State(DhcpRecord record) {
String nextHopIp = findNextHopIp(IpAddress::isIp4,
record.nextHop().orElse(null),

View File

@ -19,6 +19,7 @@ package org.onosproject.dhcprelay.config;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.google.common.base.Objects;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
@ -35,13 +36,13 @@ public class DhcpServerConfig {
private static final String DHCP_GATEWAY_IP = "gatewayIps";
private static final String RELAY_AGENT_IP = "relayAgentIps";
private ConnectPoint connectPoint;
private Ip4Address serverIp4Addr;
private Ip4Address gatewayIp4Addr;
private Ip4Address relayAgentIp4Addr;
private Ip6Address serverIp6Addr;
private Ip6Address gatewayIp6Addr;
private Ip6Address relayAgentIp6Addr;
protected ConnectPoint connectPoint;
protected Ip4Address serverIp4Addr;
protected Ip4Address gatewayIp4Addr;
protected Ip4Address relayAgentIp4Addr;
protected Ip6Address serverIp6Addr;
protected Ip6Address gatewayIp6Addr;
protected Ip6Address relayAgentIp6Addr;
protected DhcpServerConfig() {
// empty config not allowed here
@ -183,4 +184,29 @@ public class DhcpServerConfig {
public Optional<Ip6Address> getRelayAgentIp6() {
return Optional.ofNullable(relayAgentIp6Addr);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DhcpServerConfig that = (DhcpServerConfig) o;
return Objects.equal(connectPoint, that.connectPoint) &&
Objects.equal(serverIp4Addr, that.serverIp4Addr) &&
Objects.equal(gatewayIp4Addr, that.gatewayIp4Addr) &&
Objects.equal(relayAgentIp4Addr, that.relayAgentIp4Addr) &&
Objects.equal(serverIp6Addr, that.serverIp6Addr) &&
Objects.equal(gatewayIp6Addr, that.gatewayIp6Addr) &&
Objects.equal(relayAgentIp6Addr, that.relayAgentIp6Addr);
}
@Override
public int hashCode() {
return Objects.hashCode(connectPoint, serverIp4Addr, gatewayIp4Addr,
relayAgentIp4Addr, serverIp6Addr, gatewayIp6Addr,
relayAgentIp6Addr);
}
}