IPv6 support for vRouter
Changes:
- Adds support to CPRM;
- Updates DHM;
- Fixes SingleSwitchFibInstaller;
- Updates the driver;
- IPv6 unit tests;
Change-Id: I0d9a143fbf5ee8d77ffe3ed3e180fede200d3cdd
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
index 5cd78a9..9a16bfd 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/ControlPlaneRedirectManager.java
@@ -17,6 +17,7 @@
package org.onosproject.routing.impl;
import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -24,9 +25,17 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.EthType;
+import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+
+import static org.onlab.packet.Ethernet.TYPE_ARP;
+import static org.onlab.packet.Ethernet.TYPE_IPV4;
+import static org.onlab.packet.Ethernet.TYPE_IPV6;
+import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
+import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
import org.onosproject.app.ApplicationService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
@@ -85,7 +94,7 @@
private static final int MIN_IP_PRIORITY = 10;
private static final int IPV4_PRIORITY = 2000;
private static final int IPV6_PRIORITY = 500;
- private static final int ACL_PRIORITY = 40001;
+ static final int ACL_PRIORITY = 40001;
private static final int OSPF_IP_PROTO = 0x59;
private static final String APP_NAME = "org.onosproject.vrouter";
@@ -228,59 +237,180 @@
intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
intf.vlan(), false, install);
}
-
- // IPv4 to router
- TrafficSelector toSelector = DefaultTrafficSelector.builder()
- .matchInPort(intf.connectPoint().port())
- .matchEthDst(intf.mac())
- .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
- .matchVlanId(intf.vlan())
- .matchIPDst(ip.ipAddress().toIpPrefix())
- .build();
-
- flowObjectiveService.forward(deviceId,
- buildForwardingObjective(toSelector, null, cpNextId, install));
-
- // IPv4 from router
- TrafficSelector fromSelector = DefaultTrafficSelector.builder()
- .matchInPort(controlPlanePort)
- .matchEthSrc(intf.mac())
- .matchVlanId(intf.vlan())
- .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
- .matchIPSrc(ip.ipAddress().toIpPrefix())
- .build();
-
- flowObjectiveService.forward(deviceId,
- buildForwardingObjective(fromSelector, null, intfNextId, install));
-
- // ARP to router
- toSelector = DefaultTrafficSelector.builder()
- .matchInPort(intf.connectPoint().port())
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .matchVlanId(intf.vlan())
- .build();
-
- TrafficTreatment puntTreatment = DefaultTrafficTreatment.builder()
+ List<ForwardingObjective> fwdToSend = Lists.newArrayList();
+ TrafficSelector selector;
+ // IP traffic toward the router.
+ selector = buildIPDstSelector(
+ ip.ipAddress().toIpPrefix(),
+ intf.connectPoint().port(),
+ null,
+ intf.mac(),
+ intf.vlan()
+ );
+ fwdToSend.add(buildForwardingObjective(selector, null, cpNextId, install, ACL_PRIORITY));
+ // IP traffic from the router.
+ selector = buildIPSrcSelector(
+ ip.ipAddress().toIpPrefix(),
+ controlPlanePort,
+ intf.mac(),
+ null,
+ intf.vlan()
+ );
+ fwdToSend.add(buildForwardingObjective(selector, null, intfNextId, install, ACL_PRIORITY));
+ // We build the punt treatment.
+ TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.punt()
.build();
-
- flowObjectiveService.forward(deviceId,
- buildForwardingObjective(toSelector, puntTreatment, cpNextId, install));
-
- // ARP from router
- fromSelector = DefaultTrafficSelector.builder()
- .matchInPort(controlPlanePort)
- .matchEthSrc(intf.mac())
- .matchVlanId(intf.vlan())
- .matchEthType(EthType.EtherType.ARP.ethType().toShort())
- .matchArpSpa(ip.ipAddress().getIp4Address())
- .build();
-
- flowObjectiveService.forward(deviceId,
- buildForwardingObjective(fromSelector, puntTreatment, intfNextId, install));
+ // Handling of neighbour discovery protocols.
+ // IPv4 traffic - we have to deal with the ARP protocol.
+ // IPv6 traffic - we have to deal with the NDP protocol.
+ if (ip.ipAddress().isIp4()) {
+ // ARP traffic towards the router.
+ selector = buildArpSelector(
+ intf.connectPoint().port(),
+ intf.vlan(),
+ null,
+ null
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+ // ARP traffic from the router.
+ selector = buildArpSelector(
+ controlPlanePort,
+ intf.vlan(),
+ ip.ipAddress().getIp4Address(),
+ intf.mac()
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+ } else {
+ // Neighbour solicitation traffic towards the router.
+ selector = buildNdpSelector(
+ intf.connectPoint().port(),
+ intf.vlan(),
+ null,
+ NEIGHBOR_SOLICITATION,
+ null
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+ // Neighbour solicitation traffic from the router.
+ selector = buildNdpSelector(
+ controlPlanePort,
+ intf.vlan(),
+ ip.ipAddress().toIpPrefix(),
+ NEIGHBOR_SOLICITATION,
+ intf.mac()
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+ // Neighbour advertisement traffic towards the router.
+ selector = buildNdpSelector(
+ intf.connectPoint().port(),
+ intf.vlan(),
+ null,
+ NEIGHBOR_ADVERTISEMENT,
+ null
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+ // Neighbour advertisement traffic from the router.
+ selector = buildNdpSelector(
+ controlPlanePort,
+ intf.vlan(),
+ ip.ipAddress().toIpPrefix(),
+ NEIGHBOR_ADVERTISEMENT,
+ intf.mac()
+ );
+ fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+ }
+ // Finally we push the fwd objectives through the flow objective service.
+ fwdToSend.stream().forEach(forwardingObjective ->
+ flowObjectiveService.forward(deviceId, forwardingObjective)
+ );
}
}
+ static TrafficSelector.Builder buildBaseSelectorBuilder(PortNumber inPort,
+ MacAddress srcMac,
+ MacAddress dstMac,
+ VlanId vlanId) {
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ if (inPort != null) {
+ selectorBuilder.matchInPort(inPort);
+ }
+ if (srcMac != null) {
+ selectorBuilder.matchEthSrc(srcMac);
+ }
+ if (dstMac != null) {
+ selectorBuilder.matchEthDst(dstMac);
+ }
+ if (vlanId != null) {
+ selectorBuilder.matchVlanId(vlanId);
+ }
+ return selectorBuilder;
+ }
+
+ static TrafficSelector buildIPDstSelector(IpPrefix dstIp,
+ PortNumber inPort,
+ MacAddress srcMac,
+ MacAddress dstMac,
+ VlanId vlanId) {
+ TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, srcMac, dstMac, vlanId);
+ if (dstIp.isIp4()) {
+ selector.matchEthType(TYPE_IPV4);
+ selector.matchIPDst(dstIp);
+ } else {
+ selector.matchEthType(TYPE_IPV6);
+ selector.matchIPv6Dst(dstIp);
+ }
+ return selector.build();
+ }
+
+ static TrafficSelector buildIPSrcSelector(IpPrefix srcIp,
+ PortNumber inPort,
+ MacAddress srcMac,
+ MacAddress dstMac,
+ VlanId vlanId) {
+ TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, srcMac, dstMac, vlanId);
+ if (srcIp.isIp4()) {
+ selector.matchEthType(TYPE_IPV4);
+ selector.matchIPSrc(srcIp);
+ } else {
+ selector.matchEthType(TYPE_IPV6);
+ selector.matchIPv6Src(srcIp);
+ }
+ return selector.build();
+ }
+
+ static TrafficSelector buildArpSelector(PortNumber inPort,
+ VlanId vlanId,
+ Ip4Address arpSpa,
+ MacAddress srcMac) {
+ TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, null, null, vlanId);
+ selector.matchEthType(TYPE_ARP);
+ if (arpSpa != null) {
+ selector.matchArpSpa(arpSpa);
+ }
+ if (srcMac != null) {
+ selector.matchEthSrc(srcMac);
+ }
+ return selector.build();
+ }
+
+ static TrafficSelector buildNdpSelector(PortNumber inPort,
+ VlanId vlanId,
+ IpPrefix srcIp,
+ byte subProto,
+ MacAddress srcMac) {
+ TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, null, null, vlanId);
+ selector.matchEthType(TYPE_IPV6)
+ .matchIPProtocol(PROTOCOL_ICMP6)
+ .matchIcmpv6Type(subProto);
+ if (srcIp != null) {
+ selector.matchIPv6Src(srcIp);
+ }
+ if (srcMac != null) {
+ selector.matchEthSrc(srcMac);
+ }
+ return selector.build();
+ }
+
/**
* Installs or removes OSPF forwarding rules.
*
@@ -289,6 +419,7 @@
* objective
**/
private void updateOspfForwarding(Interface intf, boolean install) {
+ // FIXME IPv6 support has not been implemented yet
// OSPF to router
TrafficSelector toSelector = DefaultTrafficSelector.builder()
.matchInPort(intf.connectPoint().port())
@@ -311,7 +442,7 @@
}
log.debug("OSPF flows intf:{} nextid:{}", intf, cpNextId);
flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(),
- buildForwardingObjective(toSelector, null, cpNextId, install ? ospfEnabled : install));
+ buildForwardingObjective(toSelector, null, cpNextId, install ? ospfEnabled : install, ACL_PRIORITY));
}
/**
@@ -370,7 +501,8 @@
private ForwardingObjective buildForwardingObjective(TrafficSelector selector,
TrafficTreatment treatment,
int nextId,
- boolean add) {
+ boolean add,
+ int priority) {
DefaultForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder();
fobBuilder.withSelector(selector);
if (treatment != null) {
@@ -380,7 +512,7 @@
fobBuilder.nextStep(nextId);
}
fobBuilder.fromApp(appId)
- .withPriority(ACL_PRIORITY)
+ .withPriority(priority)
.withFlag(ForwardingObjective.Flag.VERSATILE);
return add ? fobBuilder.add() : fobBuilder.remove();
@@ -425,22 +557,22 @@
public void event(NetworkConfigEvent event) {
if (event.configClass().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
switch (event.type()) {
- case CONFIG_ADDED:
- case CONFIG_UPDATED:
- readConfig();
- if (event.prevConfig().isPresent()) {
+ case CONFIG_ADDED:
+ case CONFIG_UPDATED:
+ readConfig();
+ if (event.prevConfig().isPresent()) {
updateConfig(event);
}
- break;
- case CONFIG_REGISTERED:
- case CONFIG_UNREGISTERED:
- case CONFIG_REMOVED:
- removeConfig();
+ break;
+ case CONFIG_REGISTERED:
+ case CONFIG_UNREGISTERED:
+ case CONFIG_REMOVED:
+ removeConfig();
break;
- default:
- break;
+ default:
+ break;
}
}
}
@@ -520,12 +652,10 @@
private ForwardingObjective.Builder createPeerObjBuilder(
int nextId, IpPrefix ipAddresses) {
- TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
- sbuilder.matchEthType(EthType.EtherType.IPV4.ethType().toShort());
- sbuilder.matchIPDst(ipAddresses);
+ TrafficSelector selector = buildIPDstSelector(ipAddresses, null, null, null, null);
DefaultForwardingObjective.Builder builder =
DefaultForwardingObjective.builder()
- .withSelector(sbuilder.build())
+ .withSelector(selector)
.fromApp(appId)
.withPriority(getPriorityFromPrefix(ipAddresses))
.withFlag(ForwardingObjective.Flag.SPECIFIC);
@@ -577,7 +707,8 @@
peerRemoved(event);
break;
case HOST_UPDATED:
- //TODO We assume BGP peer does not change IP for now
+ //FIXME We assume BGP peer does not change IP for now
+ // but we can discover new address.
break;
default:
break;
@@ -628,11 +759,10 @@
}
private Set<Interface> filterInterfaces(List<String> interfaces) {
- Set<Interface> intfs = interfaceService.getInterfaces().stream()
+ return interfaceService.getInterfaces().stream()
.filter(intf -> intf.connectPoint().deviceId().equals(controlPlaneConnectPoint.deviceId()))
.filter(intf -> interfaces.contains(intf.name()))
.collect(Collectors.toSet());
- return intfs;
}
private void removeConfig() {
@@ -707,3 +837,4 @@
}
}
}
+
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java b/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
index d5c0d27..a1a7d25 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/DirectHostManager.java
@@ -28,7 +28,8 @@
import org.onlab.packet.EthType;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
-import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.IP;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
@@ -63,6 +64,7 @@
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.packet.IpAddress.Version.INET6;
/**
* Reactively handles sending packets to hosts that are directly connected to
@@ -104,8 +106,8 @@
private InternalPacketProcessor packetProcessor = new InternalPacketProcessor();
private InternalHostListener hostListener = new InternalHostListener();
- private Cache<IpAddress, Queue<IPv4>> ipPacketCache = CacheBuilder.newBuilder()
- .weigher((IpAddress key, Queue<IPv4> value) -> value.size())
+ private Cache<IpAddress, Queue<IP>> ipPacketCache = CacheBuilder.newBuilder()
+ .weigher((IpAddress key, Queue<IP> value) -> value.size())
.maximumWeight(MAX_QUEUED_PACKETS)
.expireAfterAccess(MAX_QUEUE_DURATION, TimeUnit.SECONDS)
.build();
@@ -134,19 +136,27 @@
private void enable() {
hostService.addListener(hostListener);
packetService.addProcessor(packetProcessor, PacketProcessor.director(3));
-
+ // Requests packets for IPv4 traffic.
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(EthType.EtherType.IPV4.ethType().toShort()).build();
packetService.requestPackets(selector, PacketPriority.REACTIVE, appId, Optional.empty());
+ // Requests packets for IPv6 traffic.
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.IPV6.ethType().toShort()).build();
+ packetService.requestPackets(selector, PacketPriority.REACTIVE, appId, Optional.empty());
}
private void disable() {
packetService.removeProcessor(packetProcessor);
hostService.removeListener(hostListener);
-
+ // Withdraws IPv4 request.
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(EthType.EtherType.IPV4.ethType().toShort()).build();
packetService.cancelPackets(selector, PacketPriority.REACTIVE, appId, Optional.empty());
+ // Withdraws IPv6 request.
+ selector = DefaultTrafficSelector.builder()
+ .matchEthType(EthType.EtherType.IPV6.ethType().toShort()).build();
+ packetService.cancelPackets(selector, PacketPriority.REACTIVE, appId, Optional.empty());
}
@Deactivate
@@ -158,57 +168,82 @@
componentConfigService.unregisterProperties(getClass(), false);
}
- private void handle(Ethernet eth) {
+ private boolean handle(Ethernet eth) {
checkNotNull(eth);
-
- if (!(eth.getEtherType() == EthType.EtherType.IPV4.ethType().toShort())) {
- return;
+ // If the DirectHostManager is not enabled and the
+ // packets are different from what we expect just
+ // skip them.
+ if (!enabled || (eth.getEtherType() != Ethernet.TYPE_IPV6
+ && eth.getEtherType() != Ethernet.TYPE_IPV4)) {
+ return false;
}
-
- IPv4 ipv4 = (IPv4) eth.getPayload().clone();
-
- Ip4Address dstIp = Ip4Address.valueOf(ipv4.getDestinationAddress());
-
+ // According to the type we set the destIp.
+ IpAddress dstIp;
+ if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
+ IPv4 ip = (IPv4) eth.getPayload();
+ dstIp = IpAddress.valueOf(ip.getDestinationAddress());
+ } else {
+ IPv6 ip = (IPv6) eth.getPayload();
+ dstIp = IpAddress.valueOf(INET6, ip.getDestinationAddress());
+ }
+ // Looking for a candidate output port.
Interface egressInterface = interfaceService.getMatchingInterface(dstIp);
if (egressInterface == null) {
log.info("No egress interface found for {}", dstIp);
- return;
+ return false;
}
-
+ // Looking for the destination mac.
Optional<Host> host = hostService.getHostsByIp(dstIp).stream()
.filter(h -> h.location().equals(egressInterface.connectPoint()))
.filter(h -> h.vlan().equals(egressInterface.vlan()))
.findAny();
-
+ // If we don't have a destination we start the monitoring
+ // and we queue the packets waiting for a destination.
if (host.isPresent()) {
- transformAndSend(ipv4, egressInterface, host.get().mac());
+ transformAndSend(
+ (IP) eth.getPayload(),
+ eth.getEtherType(),
+ egressInterface,
+ host.get().mac()
+ );
} else {
hostService.startMonitoringIp(dstIp);
ipPacketCache.asMap().compute(dstIp, (ip, queue) -> {
if (queue == null) {
- queue = new ConcurrentLinkedQueue();
+ queue = new ConcurrentLinkedQueue<>();
}
- queue.add(ipv4);
+ queue.add((IP) eth.getPayload());
return queue;
});
}
+
+ return true;
}
- private void transformAndSend(IPv4 ipv4, Interface egressInterface, MacAddress macAddress) {
-
+ private void transformAndSend(IP ip, short ethType,
+ Interface egressInterface,
+ MacAddress macAddress) {
+ // Base processing for IPv4
+ if (ethType == Ethernet.TYPE_IPV4) {
+ IPv4 ipv4 = (IPv4) ip;
+ ipv4.setTtl((byte) (ipv4.getTtl() - 1));
+ ipv4.setChecksum((short) 0);
+ // Base processing for IPv6.
+ } else {
+ IPv6 ipv6 = (IPv6) ip;
+ ipv6.setHopLimit((byte) (ipv6.getHopLimit() - 1));
+ ipv6.resetChecksum();
+ }
+ // Sends and serializes.
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(macAddress);
eth.setSourceMACAddress(egressInterface.mac());
- eth.setEtherType(EthType.EtherType.IPV4.ethType().toShort());
- eth.setPayload(ipv4);
+ eth.setEtherType(ethType);
+ eth.setPayload(ip);
if (!egressInterface.vlan().equals(VlanId.NONE)) {
eth.setVlanID(egressInterface.vlan().toShort());
}
-
- ipv4.setTtl((byte) (ipv4.getTtl() - 1));
- ipv4.setChecksum((short) 0);
-
send(eth, egressInterface.connectPoint());
}
@@ -221,7 +256,7 @@
private void sendQueued(IpAddress ipAddress, MacAddress macAddress) {
log.debug("Sending queued packets for {} ({})", ipAddress, macAddress);
ipPacketCache.asMap().computeIfPresent(ipAddress, (ip, packets) -> {
- packets.forEach(ipv4 -> {
+ packets.forEach(ipPackets -> {
Interface egressInterface = interfaceService.getMatchingInterface(ipAddress);
if (egressInterface == null) {
@@ -229,7 +264,14 @@
return;
}
- transformAndSend(ipv4, egressInterface, macAddress);
+ // According to the type of the address we set proper
+ // protocol.
+ transformAndSend(
+ ipPackets,
+ ipAddress.isIp4() ? Ethernet.TYPE_IPV4 : Ethernet.TYPE_IPV6,
+ egressInterface,
+ macAddress
+ );
});
return null;
});
@@ -253,7 +295,9 @@
return;
}
- handle(eth);
+ if (!handle(eth)) {
+ return;
+ }
context.block();
}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java b/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
index f0fe3fe..24dd468 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/SingleSwitchFibInstaller.java
@@ -126,7 +126,7 @@
protected ApplicationService applicationService;
@Property(name = "routeToNextHop", boolValue = false,
- label = "Install a /32 route to each next hop")
+ label = "Install a /32 or /128 route to each next hop")
private boolean routeToNextHop = false;
// Device id of data-plane switch - should be learned from config
@@ -333,11 +333,7 @@
private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
Integer nextId) {
- TrafficSelector selector = DefaultTrafficSelector.builder()
- .matchEthType(Ethernet.TYPE_IPV4)
- .matchIPDst(prefix)
- .build();
-
+ TrafficSelector selector = buildIpSelectorFromIpPrefix(prefix).build();
int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
@@ -357,11 +353,30 @@
return fwdBuilder;
}
+ /**
+ * Method to build IPv4 or IPv6 selector.
+ *
+ * @param prefixToMatch the prefix to match
+ * @return the traffic selector builder
+ */
+ private TrafficSelector.Builder buildIpSelectorFromIpPrefix(IpPrefix prefixToMatch) {
+ TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+ // If the prefix is IPv4
+ if (prefixToMatch.isIp4()) {
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
+ selectorBuilder.matchIPDst(prefixToMatch);
+ return selectorBuilder;
+ }
+ // If the prefix is IPv6
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
+ selectorBuilder.matchIPv6Dst(prefixToMatch);
+ return selectorBuilder;
+ }
+
private synchronized void addNextHop(ResolvedRoute route) {
prefixToNextHop.put(route.prefix(), route.nextHop());
if (nextHopsCount.count(route.nextHop()) == 0) {
// There was no next hop in the multiset
-
Interface egressIntf = interfaceService.getMatchingInterface(route.nextHop());
if (egressIntf == null) {
log.warn("no egress interface found for {}", route);