East-West Routing support for IPv6 traffic 43/39943/4
authorSridhar Gaddam <sgaddam@redhat.com>
Mon, 6 Jun 2016 13:28:47 +0000 (18:58 +0530)
committerSridhar Gaddam <sgaddam@redhat.com>
Tue, 7 Jun 2016 15:00:12 +0000 (20:30 +0530)
This patch implements support for IPv6 East West Routing.
The following use-cases are tested.
1. Dual stack network (One IPv4 + One IPv6 subnets).
2. An IPv6 only network.
3. A network with an IPv4 + Multiple IPv6 subnets.

Change-Id: I884ba2a979dd03e1b3c6d5b972ed44b84db064a2
Signed-off-by: Sridhar Gaddam <sgaddam@redhat.com>
features/pom.xml
features/src/main/features/features.xml
openstack/net-virt-providers/pom.xml
openstack/net-virt-providers/src/main/java/org/opendaylight/netvirt/openstack/netvirt/providers/openflow13/services/L3ForwardingService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/netvirt/openstack/netvirt/providers/openflow13/services/RoutingService.java
openstack/net-virt-providers/src/test/java/org/opendaylight/netvirt/openstack/netvirt/providers/openflow13/services/L3FowardingServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/netvirt/openstack/netvirt/providers/openflow13/services/RoutingServiceTest.java
routemgr/routemgr-features/pom.xml
routemgr/routemgr-features/src/main/features/features.xml
utils/mdsal-openflow/src/main/java/org/opendaylight/netvirt/utils/mdsal/openflow/MatchUtils.java

index 52b4a2d9311691fea1fa2304e0a140e810132519..513e00f9e0a8d4813e0b9ab31694205b9468a4a8 100644 (file)
@@ -145,6 +145,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.googlecode.java-ipv6</groupId>
+      <artifactId>java-ipv6</artifactId>
+      <version>0.16</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.neutron</groupId>
       <artifactId>features-neutron</artifactId>
index e4733ccf153e766dd8730fc53bc95b3b3f747f4c..b6e0835daa4129a36bbfe832d051c99b0c0f32a4 100644 (file)
@@ -31,6 +31,7 @@
     <bundle>mvn:org.opendaylight.netvirt/openstack.net-virt/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.netvirt/openstack.net-virt-providers/{{VERSION}}</bundle>
     <bundle>mvn:commons-net/commons-net/{{VERSION}}</bundle>
+    <bundle>wrap:mvn:com.googlecode.java-ipv6/java-ipv6/{{VERSION}}</bundle>
     <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.netvirt/openstack.net-virt/{{VERSION}}/xml/config</configfile>
     <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.netvirt/openstack.net-virt-providers/{{VERSION}}/xml/config</configfile>
   </feature>
@@ -57,6 +58,7 @@
     <bundle>mvn:org.opendaylight.netvirt/openstack.net-virt/{{VERSION}}</bundle>
     <bundle>mvn:org.opendaylight.netvirt/openstack.net-virt-providers/{{VERSION}}</bundle>
     <bundle>mvn:commons-net/commons-net/{{VERSION}}</bundle>
+    <bundle>wrap:mvn:com.googlecode.java-ipv6/java-ipv6/{{VERSION}}</bundle>
     <configfile finalname="etc/opendaylight/karaf/netvirt-impl-default-config.xml">mvn:org.opendaylight.netvirt/openstack.net-virt/{{VERSION}}/xml/config</configfile>
     <configfile finalname="etc/opendaylight/karaf/netvirt-providers-impl-default-config.xml">mvn:org.opendaylight.netvirt/openstack.net-virt-providers/{{VERSION}}/xml/config</configfile>
   </feature>
index f610e0535057ad4f9854317543abed64b0596025..ad046e31ff2cd274c8b345472474b48139db2627 100644 (file)
@@ -176,6 +176,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.googlecode.java-ipv6</groupId>
+      <artifactId>java-ipv6</artifactId>
+      <version>0.16</version>
+    </dependency>
   </dependencies>
 
   <build>
index 977b49edc2cb8347b7bb14c96791fd86b3851baf..fd8d095f6906fd1d5b7ca1548c5065a46f7ec29d 100644 (file)
@@ -8,17 +8,13 @@
 
 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
 
-import java.math.BigInteger;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.List;
-
-import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import com.google.common.collect.Lists;
 import org.opendaylight.netvirt.openstack.netvirt.api.Action;
 import org.opendaylight.netvirt.openstack.netvirt.api.L3ForwardingProvider;
 import org.opendaylight.netvirt.openstack.netvirt.api.Status;
 import org.opendaylight.netvirt.openstack.netvirt.api.StatusCode;
 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.netvirt.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.netvirt.utils.mdsal.openflow.InstructionUtils;
@@ -31,12 +27,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import java.math.BigInteger;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.List;
 
 public class L3ForwardingService extends AbstractServiceInstance implements L3ForwardingProvider, ConfigInterface {
     private static final Logger LOG = LoggerFactory.getLogger(L3ForwardingService.class);
@@ -52,14 +51,6 @@ public class L3ForwardingService extends AbstractServiceInstance implements L3Fo
     @Override
     public Status programForwardingTableEntry(Long dpid, String segmentationId, InetAddress ipAddress,
                                               String macAddress, Action action) {
-        if (ipAddress instanceof Inet6Address) {
-            // WORKAROUND: For now ipv6 is not supported
-            // TODO: implement ipv6 case
-            LOG.debug("ipv6 address is not implemented yet. dpid {} segmentationId {} ipAddress {} macAddress {} Action {}",
-                      dpid, segmentationId, ipAddress, macAddress, action);
-            return new Status(StatusCode.NOTIMPLEMENTED);
-        }
-
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
         FlowBuilder flowBuilder = new FlowBuilder();
         String flowName = "L3Forwarding_" + segmentationId + "_" + ipAddress.getHostAddress();
@@ -67,7 +58,11 @@ public class L3ForwardingService extends AbstractServiceInstance implements L3Fo
 
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
-        MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress()));
+        if (ipAddress instanceof Inet6Address) {
+            MatchUtils.createDstL3IPv6Match(matchBuilder, MatchUtils.iPv6PrefixFromIPv6Address(ipAddress.getHostAddress()));
+        } else {
+            MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress()));
+        }
 
         flowBuilder.setMatch(matchBuilder.build());
 
index 38d216c47b6c3497b164e50f818dfec797f29d20..27eba0083ea53a9f224a53d6990bebe28e08a1ac 100644 (file)
@@ -8,24 +8,19 @@
 
 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
 
-import java.math.BigInteger;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.List;
-
+import com.google.common.collect.Lists;
+import com.googlecode.ipv6.IPv6Address;
+import com.googlecode.ipv6.IPv6NetworkMask;
 import org.apache.commons.net.util.SubnetUtils;
-import org.opendaylight.netvirt.openstack.netvirt.api.StatusCode;
+import org.opendaylight.netvirt.openstack.netvirt.api.*;
+import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
-import org.opendaylight.netvirt.openstack.netvirt.api.Action;
-import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
-import org.opendaylight.netvirt.openstack.netvirt.api.RoutingProvider;
-import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
-import org.opendaylight.netvirt.openstack.netvirt.api.Status;
 import org.opendaylight.netvirt.utils.mdsal.openflow.ActionUtils;
 import org.opendaylight.netvirt.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.netvirt.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
@@ -38,8 +33,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-
-import com.google.common.collect.Lists;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
 import org.osgi.framework.BundleContext;
@@ -47,6 +40,11 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.math.BigInteger;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.List;
+
 public class RoutingService extends AbstractServiceInstance implements RoutingProvider, ConfigInterface {
     private static final Logger LOG = LoggerFactory.getLogger(RoutingService.class);
     public RoutingService() {
@@ -60,21 +58,6 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr
     @Override
     public Status programRouterInterface(Long dpid, String sourceSegId, String destSegId, String macAddress,
                                          InetAddress address, int mask, Action action) {
-        if (address instanceof Inet6Address) {
-            // WORKAROUND: For now ipv6 is not supported
-            // TODO: implement ipv6 case
-            LOG.debug("ipv6 address is not implemented yet. address {}", address);
-            return new Status(StatusCode.NOTIMPLEMENTED);
-        }
-
-        SubnetUtils addressSubnetInfo = new SubnetUtils(address.getHostAddress() + "/" + mask);
-        final String prefixString = addressSubnetInfo.getInfo().getNetworkAddress() + "/" + mask;
-
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
-        FlowBuilder flowBuilder = new FlowBuilder();
-        String flowName = "Routing_" + sourceSegId + "_" + destSegId + "_" + prefixString;
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(2048);
-
         boolean isExternalNet = sourceSegId.equals(Constants.EXTERNAL_NETWORK);
         MatchBuilder matchBuilder = new MatchBuilder();
         if (isExternalNet) {
@@ -86,7 +69,22 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr
             MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId));
         }
 
-        MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
+        final String prefixString;
+        if (address instanceof Inet6Address) {
+            IPv6Address iPv6Address = IPv6Address.fromString(address.getHostAddress());
+            IPv6Address maskedV6Address = iPv6Address.maskWithNetworkMask(IPv6NetworkMask.fromPrefixLength(mask));
+            prefixString = maskedV6Address.toString() + "/" + mask;
+            MatchUtils.createDstL3IPv6Match(matchBuilder, new Ipv6Prefix(prefixString));
+        } else {
+            SubnetUtils addressSubnetInfo = new SubnetUtils(address.getHostAddress() + "/" + mask);
+            prefixString = addressSubnetInfo.getInfo().getNetworkAddress() + "/" + mask;
+            MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
+        }
+
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
+        FlowBuilder flowBuilder = new FlowBuilder();
+        String flowName = "Routing_" + sourceSegId + "_" + destSegId + "_" + prefixString;
+        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(2048);
         flowBuilder.setMatch(matchBuilder.build());
 
         if (action.equals(Action.ADD)) {
index 589bc9c3b3af8454673beb04a2500d283fe1947b..878dfee47138cce555f07deb9c04570854dd513f 100644 (file)
@@ -58,6 +58,7 @@ public class L3FowardingServiceTest {
 
     private static final String SEGMENTATION_ID = "2";
     private static final String HOST_ADDRESS = "127.0.0.1";
+    private static final String IPV6_HOST_ADDRESS = "2001:db8::1";
     private static final String MAC_ADDRESS = "87:1D:5E:02:40:B7";
 
     @Before
@@ -99,4 +100,28 @@ public class L3FowardingServiceTest {
         verify(commitFuture, times(2)).get(); // 1 + 1 above
     }
 
+    /**
+     * Test method {@link L3ForwardingService#programForwardingTableEntry(Long, String, InetAddress, String, Action)}
+     */
+    @Test
+    public void testProgramForwardingTableEntryForIpv6() throws Exception {
+        InetAddress address = InetAddress.getByName(IPV6_HOST_ADDRESS);
+
+        assertEquals("Error, did not return the expected StatusCode",
+                new Status(StatusCode.SUCCESS),
+                l3ForwardingService.programForwardingTableEntry(Long.valueOf(123),
+                        SEGMENTATION_ID, address, MAC_ADDRESS, Action.ADD));
+        verify(writeTransaction, times(1)).put(any(LogicalDatastoreType.class),
+                any(InstanceIdentifier.class), any(Node.class), anyBoolean());
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).checkedGet();
+
+        assertEquals("Error, did not return the expected StatusCode",
+                new Status(StatusCode.SUCCESS),
+                l3ForwardingService.programForwardingTableEntry(Long.valueOf(123),
+                        SEGMENTATION_ID, address, MAC_ADDRESS, Action.DELETE));
+        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(1)).get();
+    }
 }
index e7675e327441074fa5a41846f653014788cf0451..d1d53910fabf4d46c3b44ba55f3c598925584eda 100644 (file)
@@ -8,16 +8,7 @@
 
 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
 
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.net.InetAddress;
-
+import com.google.common.util.concurrent.CheckedFuture;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,12 +22,20 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile
 import org.opendaylight.netvirt.openstack.netvirt.api.Action;
 import org.opendaylight.netvirt.openstack.netvirt.api.Status;
 import org.opendaylight.netvirt.openstack.netvirt.api.StatusCode;
+import org.opendaylight.netvirt.openstack.netvirt.providers.NetvirtProvidersProvider;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.support.membermodification.MemberModifier;
 
-import com.google.common.util.concurrent.CheckedFuture;
+import java.net.InetAddress;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Mockito.*;
 
 /**
  * Unit test fort {@link RoutingService}
@@ -55,6 +54,7 @@ public class RoutingServiceTest {
 
     private static final String SEGMENTATION_ID = "2";
     private static final String HOST_ADDRESS = "127.0.0.1";
+    private static final String IPV6_HOST_ADDRESS = "2001:db8::1";
     private static final String MAC_ADDRESS = "87:1D:5E:02:40:B8";
 
     @Before
@@ -64,6 +64,8 @@ public class RoutingServiceTest {
         when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction);
 
         when(orchestrator.getNextServiceInPipeline(any(Service.class))).thenReturn(Service.ARP_RESPONDER);
+        NetvirtProvidersProvider netvirtProvider = mock(NetvirtProvidersProvider.class);
+        MemberModifier.field(NetvirtProvidersProvider.class, "hasProviderEntityOwnership").set(netvirtProvider, new AtomicBoolean(true));
     }
 
     /**
@@ -91,6 +93,30 @@ public class RoutingServiceTest {
         verify(commitFuture, times(2)).get(); // 1 + 1 above
     }
 
+    /**
+     * Test method {@link RoutingService#programRouterInterface(Long, String, String, String, InetAddress, int, Action)}
+     */
+    @Test
+    public void testProgramRouterInterfaceForIpv6() throws Exception {
+        InetAddress address = InetAddress.getByName(IPV6_HOST_ADDRESS);
+
+        assertEquals("Error, did not return the expected StatusCode",
+                new Status(StatusCode.SUCCESS),
+                routingService.programRouterInterface(Long.valueOf(123),
+                        SEGMENTATION_ID, SEGMENTATION_ID, MAC_ADDRESS, address, 64, Action.ADD));
+        verify(writeTransaction, times(1)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), anyBoolean());
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).checkedGet();
+
+        assertEquals("Error, did not return the expected StatusCode",
+                new Status(StatusCode.SUCCESS),
+                routingService.programRouterInterface(Long.valueOf(123),
+                        SEGMENTATION_ID, SEGMENTATION_ID, MAC_ADDRESS, address, 1, Action.DELETE));
+        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(1)).get();
+    }
+
     /**
      * Test method {@link RoutingService#programDefaultRouteEntry(Long, String, String, InetAddress, Action)}
      */
index 2f2d5295ea38f762ef686ec0db397e91bb3773b0..486a900573482856cdd9160ca371ba014cdfc97d 100644 (file)
@@ -135,6 +135,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
       <groupId>commons-net</groupId>
       <artifactId>commons-net</artifactId>
     </dependency>
+    <dependency>
+      <groupId>com.googlecode.java-ipv6</groupId>
+      <artifactId>java-ipv6</artifactId>
+      <version>0.16</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.neutron</groupId>
       <artifactId>features-neutron</artifactId>
index 90b718bed228a93f2e912de68569b6f2f3468c32..47ff039e706545d6838fb8cad3f3999a2eed24cd 100644 (file)
@@ -28,6 +28,7 @@
     <bundle>mvn:org.opendaylight.netvirt/routemgr-impl/${project.version}</bundle>
     <bundle>mvn:org.opendaylight.netvirt/routemgr-api/${project.version}</bundle>
     <bundle>mvn:commons-net/commons-net/{{VERSION}}</bundle>
+    <bundle>wrap:mvn:com.googlecode.java-ipv6/java-ipv6/{{VERSION}}</bundle>
     <configfile finalname="etc/opendaylight/karaf/97-routemgrmain.xml">mvn:org.opendaylight.netvirt/routemgr-config/${project.version}/xml/config</configfile>
   </feature>
 <!--
index dbdc3538ea10db43731217ab6f7c33af564e4cb5..2b1cf3c41ac657488c0f211b474b3415401bbea7 100644 (file)
@@ -8,12 +8,8 @@
 
 package org.opendaylight.netvirt.utils.mdsal.openflow;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
@@ -28,15 +24,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv6MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.MetadataBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TcpFlagMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
@@ -44,54 +32,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtStateKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtZoneKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg3Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg4Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg5Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg6Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg7Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxTunIdKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfTcpDstKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfTcpSrcKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfUdpDstKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfUdpSrcKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.ct.state.grouping.NxmNxCtStateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.ct.zone.grouping.NxmNxCtZoneBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsi.grouping.NxmNxNsiBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.id.grouping.NxmNxTunIdBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNspKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNsiKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsi.grouping.NxmNxNsiBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.tcp.src.grouping.NxmOfTcpSrcBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.tcp.dst.grouping.NxmOfTcpDstBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.tcp.src.grouping.NxmOfTcpSrcBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.udp.dst.grouping.NxmOfUdpDstBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.udp.src.grouping.NxmOfUdpSrcBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class MatchUtils {
     private static final Logger LOG = LoggerFactory.getLogger(MatchUtils.class);
@@ -335,6 +301,28 @@ public class MatchUtils {
 
     }
 
+    /**
+     * @param matchBuilder MatchBuilder Object without a match yet
+     * @param dstip        String containing an IPv6 prefix
+     * @return matchBuilder Map Object with a match
+     */
+    public static MatchBuilder createDstL3IPv6Match(MatchBuilder matchBuilder, Ipv6Prefix dstip) {
+
+        EthernetMatchBuilder eth = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x86DDL));
+        eth.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(eth.build());
+
+        Ipv6MatchBuilder ipv6match = new Ipv6MatchBuilder();
+        ipv6match.setIpv6Destination(dstip);
+
+        matchBuilder.setLayer3Match(ipv6match.build());
+
+        return matchBuilder;
+
+    }
+
     /**
      * @param matchBuilder MatchBuilder Object without a match yet
      * @param dstip        String containing an IPv4 prefix