[CORD-1628] DHCP relay app configuration change for multiple servers
Change-Id: I13747d8e6451658dfd9344c428b6aad11bf5af62
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 0305cd8..deeaa36 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp4HandlerImpl.java
@@ -17,8 +17,11 @@
package org.onosproject.dhcprelay;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
@@ -36,8 +39,11 @@
import org.onlab.packet.dhcp.DhcpOption;
import org.onlab.packet.dhcp.DhcpRelayAgentOption;
import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
import org.onosproject.dhcprelay.store.DhcpRecord;
import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.routeservice.Route;
@@ -100,6 +106,8 @@
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected HostService hostService;
+ 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,
@@ -110,6 +118,18 @@
private VlanId dhcpConnectVlan = null;
private Ip4Address dhcpGatewayIp = null;
+ @Activate
+ protected void activate() {
+ hostService.addListener(hostListener);
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ hostService.removeListener(hostListener);
+ this.dhcpConnectMac = null;
+ this.dhcpConnectVlan = null;
+ }
+
@Override
public void setDhcpServerIp(IpAddress dhcpServerIp) {
checkNotNull(dhcpServerIp, "DHCP server IP can't be null");
@@ -160,6 +180,64 @@
}
@Override
+ public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+ if (configs.size() == 0) {
+ // no config to update
+ return;
+ }
+
+ // TODO: currently we pick up first DHCP server config.
+ // 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.getDhcpServerIp4().isPresent(),
+ "IP of DHCP server not exists");
+ 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");
+ return;
+ }
+
+ log.info("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();
+ }
+ }
+
+ @Override
+ public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+ log.warn("Indirect config feature for DHCPv4 handler not implement yet");
+ }
+
public void processDhcpPacket(PacketContext context, BasePacket payload) {
checkNotNull(payload, "DHCP payload can't be null");
checkState(payload instanceof DHCP, "Payload is not a DHCP");
@@ -813,4 +891,96 @@
}
packetService.emit(o);
}
+
+ class InternalHostListener implements HostListener {
+ @Override
+ public void event(HostEvent event) {
+ switch (event.type()) {
+ case HOST_ADDED:
+ case HOST_UPDATED:
+ hostUpdated(event.subject());
+ break;
+ case HOST_REMOVED:
+ hostRemoved(event.subject());
+ break;
+ case HOST_MOVED:
+ hostMoved(event.subject());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Handle host move.
+ * If the host DHCP server or gateway and it moved to the location different
+ * to user configured, unsets the connect mac and vlan
+ *
+ * @param host the host
+ */
+ private void hostMoved(Host host) {
+ if (this.dhcpServerConnectPoint == null) {
+ return;
+ }
+ if (this.dhcpGatewayIp != null) {
+ if (host.ipAddresses().contains(this.dhcpGatewayIp) &&
+ !host.locations().contains(this.dhcpServerConnectPoint)) {
+ this.dhcpConnectMac = null;
+ this.dhcpConnectVlan = null;
+ }
+ return;
+ }
+ if (this.dhcpServerIp != null) {
+ if (host.ipAddresses().contains(this.dhcpServerIp) &&
+ !host.locations().contains(this.dhcpServerConnectPoint)) {
+ this.dhcpConnectMac = null;
+ this.dhcpConnectVlan = null;
+ }
+ }
+ }
+
+ /**
+ * Handle host updated.
+ * If the host is DHCP server or gateway, update connect mac and vlan.
+ *
+ * @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();
+ }
+ return;
+ }
+ if (this.dhcpServerIp != null) {
+ if (host.ipAddresses().contains(this.dhcpServerIp)) {
+ this.dhcpConnectMac = host.mac();
+ this.dhcpConnectVlan = host.vlan();
+ }
+ }
+ }
+
+ /**
+ * Handle host removed.
+ * If the host is DHCP server or gateway, unset connect mac and vlan.
+ *
+ * @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;
+ }
+ return;
+ }
+ if (this.dhcpServerIp != null) {
+ if (host.ipAddresses().contains(this.dhcpServerIp)) {
+ this.dhcpConnectMac = null;
+ this.dhcpConnectVlan = null;
+ }
+ }
+ }
}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
index f5375bf..19123dc 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/Dhcp6HandlerImpl.java
@@ -25,9 +25,11 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.dhcprelay.api.DhcpHandler;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.packet.PacketContext;
+import java.util.Collection;
import java.util.Optional;
@Component
@@ -79,4 +81,14 @@
public void setDhcpServerIp(IpAddress dhcpServerIp) {
}
+
+ @Override
+ public void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+
+ }
+
+ @Override
+ public void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs) {
+
+ }
}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java
deleted file mode 100644
index 0ed8411..0000000
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayConfig.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2016-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;
-
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.config.Config;
-
-import static org.onosproject.net.config.Config.FieldPresence.MANDATORY;
-import static org.onosproject.net.config.Config.FieldPresence.OPTIONAL;
-import org.onlab.packet.Ip4Address;
-/**
- * DHCP Relay Config class.
- */
-public class DhcpRelayConfig extends Config<ApplicationId> {
-
- private static final String DHCP_CONNECT_POINT = "dhcpserverConnectPoint";
- private static final String DHCP_SERVER_IP = "serverip";
- private static final String DHCP_GATEWAY_IP = "gatewayip";
-
- @Override
- public boolean isValid() {
- return hasOnlyFields(DHCP_CONNECT_POINT, DHCP_SERVER_IP, DHCP_GATEWAY_IP) &&
- isConnectPoint(DHCP_CONNECT_POINT, MANDATORY) &&
- isIpAddress(DHCP_SERVER_IP, MANDATORY) &&
- isIpAddress(DHCP_GATEWAY_IP, OPTIONAL);
- }
-
- /**
- * Returns the dhcp server connect point.
- *
- * @return dhcp server connect point
- */
- public ConnectPoint getDhcpServerConnectPoint() {
- return ConnectPoint.deviceConnectPoint(object.path(DHCP_CONNECT_POINT).asText());
- }
-
- /**
- * Returns the dhcp server ip.
- *
- * @return ip address or null if not set
- */
- public Ip4Address getDhcpServerIp() {
- String ip = get(DHCP_SERVER_IP, null);
- return ip != null ? Ip4Address.valueOf(ip) : null;
- }
-
- /**
- * Returns the optional dhcp gateway ip, if configured. This option is
- * typically used if the dhcp server is not directly attached to a switch;
- * For example, the dhcp server may be reached via an external gateway connected
- * to the dhcpserverConnectPoint.
- *
- * @return gateway ip or null if not set
- */
- public Ip4Address getDhcpGatewayIp() {
- String gip = get(DHCP_GATEWAY_IP, null);
- return gip != null ? Ip4Address.valueOf(gip) : null;
- }
-}
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 afab19a..ba19fa7 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -38,7 +38,6 @@
import org.onlab.packet.IPv6;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
-import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onlab.packet.UDP;
@@ -49,12 +48,14 @@
import org.onosproject.core.CoreService;
import org.onosproject.dhcprelay.api.DhcpHandler;
import org.onosproject.dhcprelay.api.DhcpRelayService;
+import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
+import org.onosproject.dhcprelay.config.IndirectDhcpRelayConfig;
import org.onosproject.dhcprelay.store.DhcpRecord;
import org.onosproject.dhcprelay.store.DhcpRelayStore;
+import org.onosproject.net.config.Config;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
@@ -64,8 +65,6 @@
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.OutboundPacket;
@@ -87,7 +86,7 @@
@Component(immediate = true)
@Service
public class DhcpRelayManager implements DhcpRelayService {
- public static final String DHCP_RELAY_APP = "org.onosproject.dhcp-relay";
+ public static final String DHCP_RELAY_APP = "org.onosproject.dhcprelay";
public static final ProviderId PROVIDER_ID = new ProviderId("host", DHCP_RELAY_APP);
public static final String HOST_LOCATION_PROVIDER =
"org.onosproject.provider.host.impl.HostLocationProvider";
@@ -95,12 +94,22 @@
private final InternalConfigListener cfgListener = new InternalConfigListener();
private final Set<ConfigFactory> factories = ImmutableSet.of(
- new ConfigFactory<ApplicationId, DhcpRelayConfig>(APP_SUBJECT_FACTORY,
- DhcpRelayConfig.class,
- "dhcprelay") {
+ new ConfigFactory<ApplicationId, DefaultDhcpRelayConfig>(APP_SUBJECT_FACTORY,
+ DefaultDhcpRelayConfig.class,
+ DefaultDhcpRelayConfig.KEY,
+ true) {
@Override
- public DhcpRelayConfig createConfig() {
- return new DhcpRelayConfig();
+ public DefaultDhcpRelayConfig createConfig() {
+ return new DefaultDhcpRelayConfig();
+ }
+ },
+ new ConfigFactory<ApplicationId, IndirectDhcpRelayConfig>(APP_SUBJECT_FACTORY,
+ IndirectDhcpRelayConfig.class,
+ IndirectDhcpRelayConfig.KEY,
+ true) {
+ @Override
+ public IndirectDhcpRelayConfig createConfig() {
+ return new IndirectDhcpRelayConfig();
}
}
);
@@ -139,7 +148,6 @@
protected boolean arpEnabled = true;
private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
- private InternalHostListener hostListener = new InternalHostListener();
private ApplicationId appId;
@Activate
@@ -156,7 +164,6 @@
packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
// listen host event for dhcp server or the gateway
- hostService.addListener(hostListener);
requestDhcpPackets();
modified(context);
@@ -172,7 +179,6 @@
cfgService.removeListener(cfgListener);
factories.forEach(cfgService::unregisterConfigFactory);
packetService.removeProcessor(dhcpRelayPacketProcessor);
- hostService.removeListener(hostListener);
cancelDhcpPackets();
cancelArpPackets();
v4Handler.getDhcpGatewayIp().ifPresent(hostService::stopMonitoringIp);
@@ -202,74 +208,44 @@
}
}
+ /**
+ * Updates DHCP relay app configuration.
+ */
private void updateConfig() {
- DhcpRelayConfig cfg = cfgService.getConfig(appId, DhcpRelayConfig.class);
- if (cfg == null) {
- log.warn("Dhcp Server info not available");
+ DefaultDhcpRelayConfig defaultConfig =
+ cfgService.getConfig(appId, DefaultDhcpRelayConfig.class);
+ IndirectDhcpRelayConfig indirectConfig =
+ cfgService.getConfig(appId, IndirectDhcpRelayConfig.class);
+
+ if (defaultConfig != null) {
+ updateConfig(defaultConfig);
+ }
+
+ if (indirectConfig != null) {
+ updateConfig(indirectConfig);
+ }
+ }
+
+ /**
+ * Updates DHCP relay app configuration with given configuration.
+ *
+ * @param config the configuration ot update
+ */
+ private void updateConfig(Config config) {
+ if (config == null) {
+ // Ignore if config is not present
return;
}
- Optional<IpAddress> oldDhcpServerIp = v4Handler.getDhcpServerIp();
- Optional<IpAddress> oldDhcpGatewayIp = v4Handler.getDhcpGatewayIp();
- v4Handler.setDhcpServerConnectPoint(cfg.getDhcpServerConnectPoint());
- v4Handler.setDhcpServerIp(cfg.getDhcpServerIp());
- v4Handler.setDhcpGatewayIp(cfg.getDhcpGatewayIp());
- v4Handler.setDhcpConnectMac(null);
- v4Handler.setDhcpConnectVlan(null);
-
- log.info("DHCP server connect point: " + cfg.getDhcpServerConnectPoint());
- log.info("DHCP server ipaddress " + cfg.getDhcpServerIp());
-
- IpAddress ipToProbe = v4Handler.getDhcpGatewayIp().isPresent() ? cfg.getDhcpGatewayIp() :
- cfg.getDhcpServerIp();
- String hostToProbe = v4Handler.getDhcpGatewayIp().isPresent() ? "gateway" : "DHCP server";
-
- // TODO: DHCPv6 server config
- Set<Host> hosts = hostService.getHostsByIp(ipToProbe);
- if (hosts.isEmpty()) {
- log.info("Probing to resolve {} IP {}", hostToProbe, ipToProbe);
- oldDhcpGatewayIp.ifPresent(hostService::stopMonitoringIp);
- oldDhcpServerIp.ifPresent(hostService::stopMonitoringIp);
- hostService.startMonitoringIp(ipToProbe);
- } else {
- // Probe target is known; There should be only 1 host with this ip
- hostUpdated(hosts.iterator().next());
+ if (config instanceof DefaultDhcpRelayConfig) {
+ DefaultDhcpRelayConfig defaultConfig = (DefaultDhcpRelayConfig) config;
+ v4Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
+ v6Handler.setDefaultDhcpServerConfigs(defaultConfig.dhcpServerConfigs());
}
- }
-
- private void hostRemoved(Host host) {
- v4Handler.getDhcpServerIp().ifPresent(ip -> {
- if (host.ipAddresses().contains(ip)) {
- log.warn("DHCP server {} removed", ip);
- v4Handler.setDhcpConnectMac(null);
- v4Handler.setDhcpConnectVlan(null);
- }
- });
- v4Handler.getDhcpGatewayIp().ifPresent(ip -> {
- if (host.ipAddresses().contains(ip)) {
- log.warn("DHCP gateway {} removed", ip);
- v4Handler.setDhcpConnectMac(null);
- v4Handler.setDhcpConnectVlan(null);
- }
- });
- // TODO: v6 handler
- }
-
- private void hostUpdated(Host host) {
- v4Handler.getDhcpGatewayIp().ifPresent(ip -> {
- if (host.ipAddresses().contains(ip)) {
- log.warn("DHCP gateway {} removed", ip);
- v4Handler.setDhcpConnectMac(host.mac());
- v4Handler.setDhcpConnectVlan(host.vlan());
- }
- });
- v4Handler.getDhcpServerIp().ifPresent(ip -> {
- if (host.ipAddresses().contains(ip)) {
- log.warn("DHCP server {} removed", ip);
- v4Handler.setDhcpConnectMac(host.mac());
- v4Handler.setDhcpConnectVlan(host.vlan());
- }
- });
- // TODO: v6 handler
+ if (config instanceof IndirectDhcpRelayConfig) {
+ IndirectDhcpRelayConfig indirectConfig = (IndirectDhcpRelayConfig) config;
+ v4Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
+ v6Handler.setIndirectDhcpServerConfigs(indirectConfig.dhcpServerConfigs());
+ }
}
/**
@@ -471,35 +447,20 @@
private class InternalConfigListener implements NetworkConfigListener {
@Override
public void event(NetworkConfigEvent event) {
- if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
- event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
- event.configClass().equals(DhcpRelayConfig.class)) {
- updateConfig();
+ if (event.type() != NetworkConfigEvent.Type.CONFIG_ADDED &&
+ event.type() != NetworkConfigEvent.Type.CONFIG_UPDATED) {
+ // Ignore unhandled event type
+ return;
+ }
+ if (!event.configClass().equals(DefaultDhcpRelayConfig.class) &&
+ !event.configClass().equals(IndirectDhcpRelayConfig.class)) {
+ // Ignore unhandled config type
+ return;
+ }
+ event.config().ifPresent(config -> {
+ updateConfig(config);
log.info("Reconfigured");
- }
- }
- }
-
- /**
- * Internal listener for host events.
- */
- private class InternalHostListener implements HostListener {
- @Override
- public void event(HostEvent event) {
- switch (event.type()) {
- case HOST_ADDED:
- case HOST_UPDATED:
- hostUpdated(event.subject());
- break;
- case HOST_REMOVED:
- hostRemoved(event.subject());
- break;
- case HOST_MOVED:
- // XXX todo -- moving dhcp server
- break;
- default:
- break;
- }
+ });
}
}
}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
index d015532..a821be5 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/api/DhcpHandler.java
@@ -21,9 +21,11 @@
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+import org.onosproject.dhcprelay.config.DhcpServerConfig;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.packet.PacketContext;
+import java.util.Collection;
import java.util.Optional;
/**
@@ -42,6 +44,7 @@
* Gets DHCP server IP.
*
* @return IP address of DHCP server; empty value if not exist
+ * @deprecated 1.12 get the address from config service
*/
Optional<IpAddress> getDhcpServerIp();
@@ -49,48 +52,76 @@
* Gets DHCP gateway IP.
*
* @return IP address of DHCP gateway; empty value if not exist
+ * @deprecated 1.12 get the address from config service
*/
+ @Deprecated
Optional<IpAddress> getDhcpGatewayIp();
/**
* Gets DHCP connect Mac address.
*
* @return the connect Mac address of server or gateway
+ * @deprecated 1.12 get host mac from host server
*/
+ @Deprecated
Optional<MacAddress> getDhcpConnectMac();
/**
* Sets DHCP gateway IP.
*
* @param dhcpGatewayIp the DHCP gateway IP
+ * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
+ @Deprecated
void setDhcpGatewayIp(IpAddress dhcpGatewayIp);
/**
* Sets DHCP connect vlan.
*
* @param dhcpConnectVlan the DHCP connect vlan
+ * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
+ @Deprecated
void setDhcpConnectVlan(VlanId dhcpConnectVlan);
/**
* Sets DHCP connect Mac address.
*
* @param dhcpConnectMac the connect Mac address
+ * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
+ @Deprecated
void setDhcpConnectMac(MacAddress dhcpConnectMac);
/**
* Sets DHCP server connect point.
*
* @param dhcpServerConnectPoint the server connect point
+ * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
+ @Deprecated
void setDhcpServerConnectPoint(ConnectPoint dhcpServerConnectPoint);
/**
* Sets DHCP server IP.
*
* @param dhcpServerIp the DHCP server IP
+ * @deprecated 1.12 use setDefaultDhcpServerConfigs or setindirectDhcpServerConfigs
*/
+ @Deprecated
void setDhcpServerIp(IpAddress dhcpServerIp);
+
+ /**
+ * Sets DHCP server config for default case.
+ *
+ * @param configs the config
+ */
+ void setDefaultDhcpServerConfigs(Collection<DhcpServerConfig> configs);
+
+ /**
+ * Sets DHCP server config for indirect case.
+ *
+ * @param configs the config
+ */
+ void setIndirectDhcpServerConfigs(Collection<DhcpServerConfig> configs);
}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
index 089b8ba..5a4ecde 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/cli/DhcpRelayCommand.java
@@ -25,9 +25,10 @@
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
-import org.onosproject.dhcprelay.DhcpRelayConfig;
+import org.onosproject.dhcprelay.config.DefaultDhcpRelayConfig;
import org.onosproject.dhcprelay.DhcpRelayManager;
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;
@@ -65,16 +66,20 @@
@Override
protected void execute() {
- DhcpRelayConfig cfg = CFG_SERVICE.getConfig(APP_ID, DhcpRelayConfig.class);
- if (cfg == null) {
+ DefaultDhcpRelayConfig cfg = CFG_SERVICE.getConfig(APP_ID, DefaultDhcpRelayConfig.class);
+ if (cfg == null || cfg.dhcpServerConfigs().size() == 0) {
print(MISSING_SERVER_CFG);
return;
}
// DHCP server information
- ConnectPoint connectPoint = cfg.getDhcpServerConnectPoint();
- Ip4Address gatewayAddress = cfg.getDhcpGatewayIp();
- Ip4Address serverIp = cfg.getDhcpServerIp();
+ // 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) {
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
new file mode 100644
index 0000000..959c01b
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DefaultDhcpRelayConfig.java
@@ -0,0 +1,47 @@
+/*
+ * 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.config;
+
+import com.google.common.collect.Lists;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * DHCP Relay Config class for default use case (directly connected hosts).
+ */
+public class DefaultDhcpRelayConfig extends Config<ApplicationId> {
+ public static final String KEY = "default";
+
+
+
+ @Override
+ public boolean isValid() {
+ // check if all configs are valid
+ AtomicBoolean valid = new AtomicBoolean(true);
+ array.forEach(config -> valid.compareAndSet(true, DhcpServerConfig.isValid(config)));
+ return valid.get();
+ }
+
+ public List<DhcpServerConfig> dhcpServerConfigs() {
+ List<DhcpServerConfig> configs = Lists.newArrayList();
+ array.forEach(node -> configs.add(new DhcpServerConfig(node)));
+ return configs;
+ }
+}
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
new file mode 100644
index 0000000..2451a7a
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/DhcpServerConfig.java
@@ -0,0 +1,149 @@
+/*
+ * 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.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Optional;
+
+/**
+ * DHCP server configuration.
+ */
+public class DhcpServerConfig {
+ 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 ConnectPoint connectPoint;
+ private Ip4Address serverIp4Addr;
+ private Ip4Address gatewayIp4Addr;
+ private Ip6Address serverIp6Addr;
+ private Ip6Address gatewayIp6Addr;
+
+ protected DhcpServerConfig() {
+ // empty config not allowed here
+ }
+
+ public DhcpServerConfig(JsonNode config) {
+ if (!config.has(DHCP_CONNECT_POINT)) {
+ // connect point doesn't exist
+ throw new IllegalArgumentException("Missing " + DHCP_CONNECT_POINT);
+ }
+ connectPoint = ConnectPoint.deviceConnectPoint(config.path(DHCP_CONNECT_POINT).asText());
+
+ if (!config.has(DHCP_SERVER_IP)) {
+ // server ip doesn't exist
+ throw new IllegalArgumentException("Missing " + DHCP_SERVER_IP);
+ }
+ ArrayNode serverIps = (ArrayNode) config.path(DHCP_SERVER_IP);
+ serverIps.forEach(node -> {
+ if (node.isTextual()) {
+ IpAddress ip = IpAddress.valueOf(node.asText());
+ if (ip.isIp4() && serverIp4Addr == null) {
+ serverIp4Addr = ip.getIp4Address();
+ }
+ if (ip.isIp6() && serverIp6Addr == null) {
+ serverIp6Addr = ip.getIp6Address();
+ }
+ }
+ });
+
+ if (!config.has(DHCP_GATEWAY_IP)) {
+ // gateway ip doesn't exist, ignore the gateway
+ return;
+ }
+ 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();
+ }
+ }
+ });
+ }
+
+ /**
+ * Verify a json config is a valid DHCP server config.
+ *
+ * @param jsonConfig the json config
+ * @return true if valid; false otherwise
+ */
+ public static boolean isValid(JsonNode jsonConfig) {
+ return jsonConfig.has(DHCP_CONNECT_POINT) && jsonConfig.has(DHCP_SERVER_IP);
+ }
+
+ /**
+ * Returns the dhcp server connect point.
+ *
+ * @return dhcp server connect point
+ */
+ public Optional<ConnectPoint> getDhcpServerConnectPoint() {
+ return Optional.ofNullable(connectPoint);
+ }
+
+ /**
+ * Returns the IPv4 address of DHCP server.
+ *
+ * @return IPv4 address of server; empty value if not set
+ */
+ public Optional<Ip4Address> getDhcpServerIp4() {
+ return Optional.ofNullable(serverIp4Addr);
+ }
+
+ /**
+ * Returns the optional IPv4 address of dhcp gateway, if configured.
+ * This option is typically used if the dhcp server is not directly attached
+ * to a switch; For example, the dhcp server may be reached via an external
+ * gateway connected to the dhcpserverConnectPoint.
+ *
+ * @return IPv4 address of gateway; empty value if not set
+ */
+ public Optional<Ip4Address> getDhcpGatewayIp4() {
+ return Optional.ofNullable(gatewayIp4Addr);
+ }
+
+ /**
+ * Returns the IPv6 address of DHCP server.
+ *
+ * @return IPv6 address of server ; empty value if not set
+ */
+ public Optional<Ip6Address> getDhcpServerIp6() {
+ return Optional.ofNullable(serverIp6Addr);
+ }
+
+ /**
+ * Returns the optional IPv6 address of dhcp gateway, if configured.
+ * This option is typically used if the dhcp server is not directly attached
+ * to a switch; For example, the dhcp server may be reached via an external
+ * gateway connected to the dhcpserverConnectPoint.
+ *
+ * @return IPv6 address of gateway; empty value if not set
+ */
+ public Optional<Ip6Address> getDhcpGatewayIp6() {
+ return Optional.ofNullable(gatewayIp6Addr);
+ }
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java
new file mode 100644
index 0000000..02e76b2
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/IndirectDhcpRelayConfig.java
@@ -0,0 +1,25 @@
+/*
+ * 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.config;
+
+/**
+ * DHCP Relay Config class for indirect use case (indirectly connected hosts).
+ */
+public class IndirectDhcpRelayConfig extends DefaultDhcpRelayConfig {
+ public static final String KEY = "indirect";
+}
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/package-info.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/package-info.java
new file mode 100644
index 0000000..b9ca580
--- /dev/null
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/config/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ * Configuration utility for DHCP relay app.
+ */
+package org.onosproject.dhcprelay.config;
\ No newline at end of file
diff --git a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
index 60e04f9..1e87ba6 100644
--- a/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
+++ b/apps/dhcprelay/src/main/java/org/onosproject/dhcprelay/store/DistributedDhcpRelayStore.java
@@ -81,7 +81,7 @@
@Override
public void setDelegate(StoreDelegate<DhcpRelayStoreEvent> delegate) {
- checkNotNull("Delegate can't be null", delegate);
+ checkNotNull(delegate, "Delegate can't be null");
this.delegate = delegate;
}