CORD-592 Added DHCP classless static route option for service dependency
And moved config registration code to cordvtnmanager
Change-Id: I2657ca21659fa1abfb81799a922524ca9c52ead6
diff --git a/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java b/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
index ba5a4af..607e3b0 100644
--- a/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
+++ b/src/main/java/org/opencord/cordvtn/impl/CordVtnDhcpProxy.java
@@ -16,6 +16,7 @@
package org.opencord.cordvtn.impl;
import com.google.common.collect.Lists;
+import com.google.common.primitives.Bytes;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -27,6 +28,7 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onlab.packet.UDP;
@@ -56,7 +58,11 @@
import org.slf4j.Logger;
import java.nio.ByteBuffer;
+import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument;
import static org.onlab.packet.DHCP.DHCPOptionCode.*;
@@ -76,8 +82,9 @@
private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
private static final byte PACKET_TTL = (byte) 127;
- // TODO add MTU option code to ONOS DHCP implementation and remove this
+ // TODO add MTU, static route option codes to ONOS DHCP and remove here
private static final byte DHCP_OPTION_MTU = (byte) 26;
+ private static final byte DHCP_OPTION_CLASSLESS_STATIC_ROUTE = (byte) 121;
private static final byte[] DHCP_DATA_LEASE_INFINITE =
ByteBuffer.allocate(4).putInt(-1).array();
private static final byte[] DHCP_DATA_MTU_DEFAULT =
@@ -117,13 +124,12 @@
@Deactivate
protected void deactivate() {
+ configRegistry.removeListener(configListener);
packetService.removeProcessor(packetProcessor);
cancelPackets();
log.info("Stopped");
}
- // TODO implement public method forceRenew
-
private void requestPackets() {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
@@ -341,6 +347,7 @@
option.setData(broadcast.toOctets());
options.add(option);
+ // domain server
option = new DHCPOption();
option.setCode(OptionCode_DomainServer.getValue());
option.setLength((byte) 4);
@@ -363,7 +370,15 @@
options.add(option);
}
- // TODO add host route option if network has service dependency
+ // classless static routes
+ byte[] data = getClasslessStaticRoutesData(vtnNet);
+ if (data.length >= 5) {
+ option = new DHCPOption();
+ option.setCode(DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
+ option.setLength((byte) data.length);
+ option.setData(data);
+ options.add(option);
+ }
// end option
option = new DHCPOption();
@@ -374,6 +389,45 @@
dhcpReply.setOptions(options);
return dhcpReply;
}
+
+ private byte[] getClasslessStaticRoutesData(VtnNetwork vtnNet) {
+ List<Byte> result = Lists.newArrayList();
+ List<Byte> router = Bytes.asList(vtnNet.serviceIp().toOctets());
+
+ // static routes for the providers
+ Set<VtnNetwork> providers = vtnNet.providers().stream()
+ .map(provider -> cordVtnService.vtnNetwork(provider.id()))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+
+ providers.stream().forEach(provider -> {
+ result.add((byte) provider.subnet().prefixLength());
+ result.addAll(getSignificantOctets(provider.subnet()));
+ result.addAll(router);
+ });
+
+ // static routes for the bidirectional subscribers
+ Set<VtnNetwork> subscribers = cordVtnService.vtnNetworks().stream()
+ .filter(net -> net.isBidirectionalProvider(vtnNet.id()))
+ .collect(Collectors.toSet());
+
+ subscribers.stream().forEach(subscriber -> {
+ result.add((byte) subscriber.subnet().prefixLength());
+ result.addAll(getSignificantOctets(subscriber.subnet()));
+ result.addAll(router);
+ });
+
+ return Bytes.toArray(result);
+ }
+
+ private List<Byte> getSignificantOctets(IpPrefix ipPrefix) {
+ int numOfOctets = ipPrefix.prefixLength() / 8;
+ if (ipPrefix.prefixLength() % 8 != 0) {
+ numOfOctets += 1;
+ }
+ byte[] result = Arrays.copyOfRange(ipPrefix.address().toOctets(), 0, numOfOctets);
+ return Bytes.asList(result);
+ }
}
private void readConfiguration() {