[CORD-1735] Add "relayAgentIps" option to DHCP relay application config
Change-Id: I2d95b5a285c81c15002ad94686b26ce03910198e
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
index 4d2bebb..0df73e4 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
@@ -117,6 +117,7 @@
private MacAddress dhcpConnectMac = null;
private VlanId dhcpConnectVlan = null;
private Ip4Address dhcpGatewayIp = null;
+ private Ip4Address relayAgentIp = null;
@Activate
protected void activate() {
@@ -128,6 +129,12 @@
hostService.removeListener(hostListener);
this.dhcpConnectMac = null;
this.dhcpConnectVlan = null;
+
+ if (dhcpGatewayIp != null) {
+ hostService.stopMonitoringIp(dhcpGatewayIp);
+ } else if (dhcpServerIp != null) {
+ hostService.stopMonitoringIp(dhcpServerIp);
+ }
}
@Override
@@ -231,6 +238,8 @@
this.dhcpConnectVlan = host.vlan();
this.dhcpConnectMac = host.mac();
}
+
+ this.relayAgentIp = serverConfig.getRelayAgentIp4().orElse(null);
}
@Override
@@ -238,6 +247,7 @@
log.warn("Indirect config feature for DHCPv4 handler not implement yet");
}
+ @Override
public void processDhcpPacket(PacketContext context, BasePacket payload) {
checkNotNull(payload, "DHCP payload can't be null");
checkState(payload instanceof DHCP, "Payload is not a DHCP");
@@ -340,7 +350,7 @@
* @return the first interface IP; null if not exists an IP address in
* these interfaces
*/
- private Ip4Address getRelayAgentIPv4Address(Interface iface) {
+ private Ip4Address getFirstIpFromInterface(Interface iface) {
checkNotNull(iface, "Interface can't be null");
return iface.ipAddressesList().stream()
.map(InterfaceIpAddress::ipAddress)
@@ -398,9 +408,9 @@
log.warn("Can't get server interface, ignore");
return null;
}
- Ip4Address relayAgentIp = getRelayAgentIPv4Address(serverInterface);
- MacAddress relayAgentMac = serverInterface.mac();
- if (relayAgentIp == null || relayAgentMac == null) {
+ Ip4Address ipFacingServer = getFirstIpFromInterface(serverInterface);
+ MacAddress macFacingServer = serverInterface.mac();
+ if (ipFacingServer == null || macFacingServer == null) {
log.warn("No IP address for server Interface {}", serverInterface);
return null;
}
@@ -414,11 +424,11 @@
}
// get dhcp header.
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
- etherReply.setSourceMACAddress(relayAgentMac);
+ etherReply.setSourceMACAddress(macFacingServer);
etherReply.setDestinationMACAddress(dhcpConnectMac);
etherReply.setVlanID(dhcpConnectVlan.toShort());
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
- ipv4Packet.setSourceAddress(relayAgentIp.toInt());
+ ipv4Packet.setSourceAddress(ipFacingServer.toInt());
ipv4Packet.setDestinationAddress(dhcpServerIp.toInt());
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
@@ -459,6 +469,12 @@
dhcpPacket.setGatewayIPAddress(clientInterfaceIp.toInt());
}
+ // replace giaddr if relay agent IP is set
+ // FIXME for both direct and indirect case now, should be separated
+ if (relayAgentIp != null) {
+ dhcpPacket.setGatewayIPAddress(relayAgentIp.toInt());
+ }
+
udpPacket.setPayload(dhcpPacket);
// As a DHCP relay, the source port should be server port(67) instead
// of client port(68)
@@ -590,8 +606,8 @@
// we leave the srcMac from the original packet
// figure out the relay agent IP corresponding to the original request
- Ip4Address relayAgentIP = getRelayAgentIPv4Address(clientInterface);
- if (relayAgentIP == null) {
+ Ip4Address ipFacingClient = getFirstIpFromInterface(clientInterface);
+ if (ipFacingClient == null) {
log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. "
+ "Aborting relay for dhcp packet from server {}",
etherReply.getDestinationMAC(), clientInterface.vlan(),
@@ -600,7 +616,7 @@
}
// SRC_IP: relay agent IP
// DST_IP: offered IP
- ipv4Packet.setSourceAddress(relayAgentIP.toInt());
+ ipv4Packet.setSourceAddress(ipFacingClient.toInt());
ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
if (directlyConnected(dhcpPayload)) {
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
index ba19fa7..e5c9973 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -181,9 +181,6 @@
packetService.removeProcessor(dhcpRelayPacketProcessor);
cancelDhcpPackets();
cancelArpPackets();
- v4Handler.getDhcpGatewayIp().ifPresent(hostService::stopMonitoringIp);
- v4Handler.getDhcpServerIp().ifPresent(hostService::stopMonitoringIp);
- // TODO: DHCPv6 Handler
compCfgService.unregisterProperties(getClass(), false);
log.info("DHCP-RELAY Stopped");
@@ -236,15 +233,15 @@
// Ignore if config is not present
return;
}
- if (config instanceof DefaultDhcpRelayConfig) {
- DefaultDhcpRelayConfig defaultConfig = (DefaultDhcpRelayConfig) config;
- v4Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
- v6Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
- }
+
if (config instanceof IndirectDhcpRelayConfig) {
IndirectDhcpRelayConfig indirectConfig = (IndirectDhcpRelayConfig) config;
v4Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
v6Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
+ } else if (config instanceof DefaultDhcpRelayConfig) {
+ DefaultDhcpRelayConfig defaultConfig = (DefaultDhcpRelayConfig) config;
+ v4Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
+ v6Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
}
}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
index 959c01b..daf97bf 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
@@ -29,8 +29,6 @@
public class DefaultDhcpRelayConfig extends Config<ApplicationId> {
public static final String KEY = "default";
-
-
@Override
public boolean isValid() {
// check if all configs are valid
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
index 2451a7a..a5c304b 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
@@ -33,12 +33,15 @@
private static final String DHCP_CONNECT_POINT = "dhcpServerConnectPoint";
private static final String DHCP_SERVER_IP = "serverIps";
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 DhcpServerConfig() {
// empty config not allowed here
@@ -68,22 +71,34 @@
}
});
- if (!config.has(DHCP_GATEWAY_IP)) {
- // gateway ip doesn't exist, ignore the gateway
- return;
+ if (config.has(DHCP_GATEWAY_IP)) {
+ ArrayNode gatewayIps = (ArrayNode) config.path(DHCP_GATEWAY_IP);
+ gatewayIps.forEach(node -> {
+ if (node.isTextual()) {
+ IpAddress ip = IpAddress.valueOf(node.asText());
+ if (ip.isIp4() && gatewayIp4Addr == null) {
+ gatewayIp4Addr = ip.getIp4Address();
+ }
+ if (ip.isIp6() && gatewayIp6Addr == null) {
+ gatewayIp6Addr = ip.getIp6Address();
+ }
+ }
+ });
}
- ArrayNode gatewayIps = (ArrayNode) config.path(DHCP_GATEWAY_IP);
- gatewayIps.forEach(node -> {
- if (node.isTextual()) {
- IpAddress ip = IpAddress.valueOf(node.asText());
- if (ip.isIp4() && gatewayIp4Addr == null) {
- gatewayIp4Addr = ip.getIp4Address();
+ if (config.has(RELAY_AGENT_IP)) {
+ ArrayNode relayAgentIps = (ArrayNode) config.path(RELAY_AGENT_IP);
+ relayAgentIps.forEach(node -> {
+ if (node.isTextual()) {
+ IpAddress ip = IpAddress.valueOf(node.asText());
+ if (ip.isIp4() && relayAgentIp4Addr == null) {
+ relayAgentIp4Addr = ip.getIp4Address();
+ }
+ if (ip.isIp6() && relayAgentIp6Addr == null) {
+ relayAgentIp6Addr = ip.getIp6Address();
+ }
}
- if (ip.isIp6() && gatewayIp6Addr == null) {
- gatewayIp6Addr = ip.getIp6Address();
- }
- }
- });
+ });
+ }
}
/**
@@ -146,4 +161,26 @@
public Optional<Ip6Address> getDhcpGatewayIp6() {
return Optional.ofNullable(gatewayIp6Addr);
}
+
+ /**
+ * Returns the optional IPv4 address for relay agent, if configured.
+ * This option is used if we want to replace the giaddr field in DHCPv4
+ * payload.
+ *
+ * @return the giaddr; empty value if not set
+ */
+ public Optional<Ip4Address> getRelayAgentIp4() {
+ return Optional.ofNullable(relayAgentIp4Addr);
+ }
+
+ /**
+ * Returns the optional IPv6 address for relay agent, if configured.
+ * This option is used if we want to replace the link-address field in DHCPv6
+ * payload.
+ *
+ * @return the giaddr; empty value if not set
+ */
+ public Optional<Ip6Address> getRelayAgentIp6() {
+ return Optional.ofNullable(relayAgentIp6Addr);
+ }
}