NETVIRT-1193: ACL dropping IPv6 RA packets from external router. 42/70242/6
authorSomashekar Byrappa <somashekar.b@altencalsoftlabs.com>
Mon, 26 Mar 2018 13:30:06 +0000 (19:00 +0530)
committerSam Hague <shague@redhat.com>
Thu, 12 Apr 2018 18:40:05 +0000 (18:40 +0000)
When an IPv6 subnet is created without specifying ipv6_ra_mode,
it is expected that the VMs with this subnet obtains global IPv6
address from non-OpenStack router using SLAAC.

Hence added below ACL flow to allow IPv6 RA packets from external
router if ipv6_ra_mode is not specified.
Since ipv6_src for RA packets are always link-local address, flow
contains match ipv6_src=fe80::/10 to allow from entire link-local
prefix.

cookie=0x6900000, duration=12.117s, table=240, n_packets=0, n_bytes=0, priority=63010,icmp6,reg6=0x400/0xfffff00,ipv6_src=fe80::/10,icmp_type=134,icmp_code=0 actions=resubmit(,220)

Change-Id: I030a99dd2e4385748a6b49cb2735e154b229da01
Signed-off-by: Somashekar Byrappa <somashekar.b@altencalsoftlabs.com>
15 files changed:
aclservice/api/src/main/java/org/opendaylight/netvirt/aclservice/api/utils/AclInterface.java
aclservice/api/src/main/yang/aclservice.yang
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/EgressAclServiceImpl.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/IngressAclServiceImpl.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclInterfaceListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclInterfaceStateListener.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclConstants.java
aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclServiceUtils.java
aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/AclServiceTestBase.java
aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/IdentifiedPortSubnetBuilder.xtend [moved from aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/IdentifiedSubnetIpPrefixBuilder.xtend with 61% similarity]
aclservice/shell/src/main/java/org/opendaylight/netvirt/aclservice/shell/DisplayAclDataCaches.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronPortChangeListener.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronSecurityRuleConstants.java
neutronvpn/impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnUtils.java

index a70ae4cb5f91740fe192182965934fcc8d620175..656bc04aef166cdcbc8d105a2213dd3ed0764583 100644 (file)
@@ -15,8 +15,8 @@ import java.util.SortedSet;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 
 /**
  * The Class AclInterface.
@@ -44,8 +44,8 @@ public final class AclInterface {
     /** The allowed address pairs. */
     private final List<AllowedAddressPairs> allowedAddressPairs;
 
-    /** The IP broadcast CIDRs. */
-    private final List<IpPrefixOrAddress> subnetIpPrefixes;
+    /** List to contain subnet IP CIDRs along with subnet gateway IP. */
+    List<SubnetInfo> subnetInfo;
 
     /** The ingress remote acl tags. */
     private final SortedSet<Integer> ingressRemoteAclTags;
@@ -64,7 +64,7 @@ public final class AclInterface {
         this.portSecurityEnabled = builder.portSecurityEnabled;
         this.securityGroups = builder.securityGroups;
         this.allowedAddressPairs = builder.allowedAddressPairs;
-        this.subnetIpPrefixes = builder.subnetIpPrefixes;
+        this.subnetInfo = builder.subnetInfo;
         this.ingressRemoteAclTags = builder.ingressRemoteAclTags;
         this.egressRemoteAclTags = builder.egressRemoteAclTags;
         this.isMarkedForDelete = builder.isMarkedForDelete;
@@ -134,12 +134,12 @@ public final class AclInterface {
     }
 
     /**
-     * Gets the Subnet IP Prefix.
+     * Gets the Subnet info.
      *
-     * @return the Subnet IP Prefix
+     * @return the Subnet info
      */
-    public List<IpPrefixOrAddress> getSubnetIpPrefixes() {
-        return subnetIpPrefixes;
+    public List<SubnetInfo> getSubnetInfo() {
+        return subnetInfo;
     }
 
     /**
@@ -266,7 +266,7 @@ public final class AclInterface {
     public String toString() {
         return "AclInterface [interfaceId=" + interfaceId + ", lportTag=" + lportTag + ", dpId=" + dpId + ", elanId="
                 + elanId + ", portSecurityEnabled=" + portSecurityEnabled + ", securityGroups=" + securityGroups
-                + ", allowedAddressPairs=" + allowedAddressPairs + ", subnetIpPrefixes=" + subnetIpPrefixes
+                + ", allowedAddressPairs=" + allowedAddressPairs + ", subnetInfo=" + subnetInfo
                 + ", ingressRemoteAclTags=" + ingressRemoteAclTags + ", egressRemoteAclTags=" + egressRemoteAclTags
                 + ", isMarkedForDelete=" + isMarkedForDelete + "]";
     }
@@ -287,7 +287,7 @@ public final class AclInterface {
         private boolean portSecurityEnabled;
         private List<Uuid> securityGroups;
         private List<AllowedAddressPairs> allowedAddressPairs;
-        private List<IpPrefixOrAddress> subnetIpPrefixes;
+        private List<SubnetInfo> subnetInfo;
         private SortedSet<Integer> ingressRemoteAclTags;
         private SortedSet<Integer> egressRemoteAclTags;
         private boolean isMarkedForDelete;
@@ -303,7 +303,7 @@ public final class AclInterface {
             this.portSecurityEnabled = from.portSecurityEnabled;
             this.securityGroups = from.securityGroups;
             this.allowedAddressPairs = from.allowedAddressPairs;
-            this.subnetIpPrefixes = from.subnetIpPrefixes;
+            this.subnetInfo = from.subnetInfo;
             this.ingressRemoteAclTags = from.ingressRemoteAclTags;
             this.egressRemoteAclTags = from.egressRemoteAclTags;
             this.isMarkedForDelete = from.isMarkedForDelete;
@@ -344,8 +344,8 @@ public final class AclInterface {
             return this;
         }
 
-        public Builder subnetIpPrefixes(List<IpPrefixOrAddress> list) {
-            this.subnetIpPrefixes = list == null ? null : ImmutableList.copyOf(list);
+        public Builder subnetInfo(List<SubnetInfo> list) {
+            this.subnetInfo = list == null ? null : ImmutableList.copyOf(list);
             return this;
         }
 
index f76a7796346fc32f7cbe9492d0c8e8dec77302d3..c6cbe4403d72a7953c023bc08cb8766749b52416 100644 (file)
@@ -32,6 +32,46 @@ module aclservice {
 
     }
 
+    //  IP VERSION
+    identity ip-version-base {
+        description "the base identity for ip versions";
+    }
+
+    identity ip-version-v4 {
+        description "IPv4";
+        base ip-version-base;
+    }
+
+    identity ip-version-v6 {
+        description "IPv6";
+        base ip-version-base;
+    }
+
+    //  DHCP
+    identity dhcpv6-base {
+        description "the base identity for DHCPv6 information";
+    }
+
+    identity dhcpv6-off {
+        description "DHCPv6 off";
+        base dhcpv6-base;
+    }
+
+    identity dhcpv6-stateful {
+        description "DHCPv6 stateful";
+        base dhcpv6-base;
+    }
+
+    identity dhcpv6-slaac {
+        description "SLAAC";
+        base dhcpv6-base;
+    }
+
+    identity dhcpv6-stateless {
+        description "DHCPv6 stateless";
+        base dhcpv6-base;
+    }
+
     typedef ip-prefix-or-address {
         description "ip prefix or ip address";
         type union {
@@ -81,16 +121,40 @@ module aclservice {
         }
     }
 
-    container ports-subnet-ip-prefixes {
-        list port-subnet-ip-prefixes {
+    container port-subnets {
+        config false;
+        list port-subnet {
             key port-id;
             leaf port-id {
                 type string;
                 description "Port ID";
             }
-            leaf-list subnet-ip-prefixes {
-                type ip-prefix-or-address;
-                description "Subnet IP Prefixes of the Port.";
+            list subnet-info {
+                key subnet-id;
+                leaf subnet-id {
+                    type yang:uuid;
+                    description "Subnet ID";
+                }
+                leaf ip-version {
+                    description "IP version";
+                    type identityref {
+                        base "ip-version-base";
+                    }
+                }
+                leaf ip-prefix {
+                    type ip-prefix-or-address;
+                    description "Subnet IP prefix.";
+                }
+                leaf ipv6-ra-mode {
+                    description "IPv6 RA mode";
+                    type identityref {
+                        base "dhcpv6-base";
+                    }
+                }
+                leaf gateway-ip {
+                    type inet:ip-address;
+                    description "default gateway used by devices in this subnet";
+                }
             }
         }
     }
index 756d6209fc1dd26ad0ffef7c13c388c24c5f3fd3..d2282f9532dc413c6c2c05b055031836d2288294 100644 (file)
@@ -61,6 +61,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev16060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -197,9 +198,10 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             programAclWithAllowedAddress(portAfter, addedAaps, Action.UPDATE, NwConstants.ADD_FLOW);
             updateRemoteAclFilterTable(portAfter, portAfter.getSecurityGroups(), addedAaps, NwConstants.ADD_FLOW);
         }
-        if (portAfter.getSubnetIpPrefixes() != null && portBefore.getSubnetIpPrefixes() == null) {
+        if (portAfter.getSubnetInfo() != null && portBefore.getSubnetInfo() == null) {
             programBroadcastRules(portAfter, NwConstants.ADD_FLOW);
         }
+        handleSubnetChange(portBefore, portAfter);
 
         List<Uuid> addedAcls = AclServiceUtils.getUpdatedAclList(portAfter.getSecurityGroups(),
                 portBefore.getSecurityGroups());
@@ -214,6 +216,20 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         handleAclChange(portAfter, addedAcls, NwConstants.ADD_FLOW);
     }
 
+    private void handleSubnetChange(AclInterface portBefore, AclInterface portAfter) {
+        List<SubnetInfo> deletedSubnets =
+                AclServiceUtils.getSubnetDiff(portBefore.getSubnetInfo(), portAfter.getSubnetInfo());
+        List<SubnetInfo> addedSubnets =
+                AclServiceUtils.getSubnetDiff(portAfter.getSubnetInfo(), portBefore.getSubnetInfo());
+
+        if (deletedSubnets != null && !deletedSubnets.isEmpty()) {
+            programIcmpv6RARule(portAfter, deletedSubnets, NwConstants.DEL_FLOW);
+        }
+        if (addedSubnets != null && !addedSubnets.isEmpty()) {
+            programIcmpv6RARule(portAfter, addedSubnets, NwConstants.ADD_FLOW);
+        }
+    }
+
     private void handleAclChange(AclInterface port, List<Uuid> aclList, int addOrRemove) {
         int operationForAclRules = (addOrRemove == NwConstants.DEL_FLOW) ? NwConstants.MOD_FLOW : addOrRemove;
         programAclRules(port, aclList, operationForAclRules);
@@ -517,6 +533,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      */
     protected abstract void programBroadcastRules(AclInterface port, int addOrRemove);
 
+    protected abstract void programIcmpv6RARule(AclInterface port, List<SubnetInfo> subnets, int addOrRemove);
+
     /**
      * Writes/remove the flow to/from the datastore.
      *
index 299ce0794fd61900c04ce6329104f5b9f90c833e..54876351194cd9c52c9df6750e9b1156598b402d 100644 (file)
@@ -43,6 +43,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev16060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -333,6 +334,11 @@ public class EgressAclServiceImpl extends AbstractAclServiceImpl {
         }
     }
 
+    @Override
+    protected void programIcmpv6RARule(AclInterface port, List<SubnetInfo> subnets, int addOrRemove) {
+        // No action required on egress.
+    }
+
     /**
      * Programs broadcast rules.
      *
index 1137c31189e98a0ac6f43873c10949755d1365d2..5bfb4c755228d189ea135772a59ea45622c64496 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
 import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
+import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
@@ -32,6 +33,7 @@ import org.opendaylight.netvirt.aclservice.utils.AclConstants;
 import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
 import org.opendaylight.netvirt.aclservice.utils.AclServiceOFFlowBuilder;
 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress;
@@ -40,6 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev16060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -129,7 +132,8 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
         if (action == Action.ADD || action == Action.REMOVE) {
             ingressAclDhcpAllowServerTraffic(dpid, lportTag, addOrRemove);
             ingressAclDhcpv6AllowServerTraffic(dpid, lportTag, addOrRemove);
-            ingressAclIcmpv6AllowedTraffic(dpid, lportTag, addOrRemove);
+            ingressAclIcmpv6AllowedTraffic(port, addOrRemove);
+            programIcmpv6RARule(port, port.getSubnetInfo(), addOrRemove);
 
             programArpRule(dpid, lportTag, addOrRemove);
             programIpv4BroadcastRule(port, addOrRemove);
@@ -208,13 +212,15 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
     }
 
     /**
-     * Add rules to ensure that certain ICMPv6 like MLD_QUERY (130), NS (135), NA (136) are allowed into the VM.
+     * Add rules to ensure that certain ICMPv6 like MLD_QUERY (130), RS (134), NS (135), NA (136) are
+     * allowed into the VM.
      *
-     * @param dpId the dpid
-     * @param lportTag the lport tag
+     * @param port the port
      * @param addOrRemove is write or delete
      */
-    private void ingressAclIcmpv6AllowedTraffic(BigInteger dpId, int lportTag, int addOrRemove) {
+    private void ingressAclIcmpv6AllowedTraffic(AclInterface port, int addOrRemove) {
+        BigInteger dpId = port.getDpId();
+        int lportTag = port.getLPortTag();
         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
 
         // Allow ICMPv6 Multicast Listener Query packets.
@@ -242,6 +248,27 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
                 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
     }
 
+    @Override
+    protected void programIcmpv6RARule(AclInterface port, List<SubnetInfo> subnets, int addOrRemove) {
+        // Allow ICMPv6 Router Advertisement packets from external routers only if ipv6_ra_mode is not
+        // specified for an IPv6 subnet.
+        if (!AclServiceUtils.isIpv6RaAllowedFromExternalRouters(subnets)) {
+            return;
+        }
+        List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
+        List<MatchInfoBase> matches =
+                AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_RA, 0, port.getLPortTag(), serviceMode);
+        // Allow ICMPv6 Router Advertisement packets if originating from any LinkLocal Address.
+        matches.addAll(AclServiceUtils.buildIpMatches(
+                new IpPrefixOrAddress(new IpPrefix(AclConstants.IPV6_LINK_LOCAL_PREFIX.toCharArray())),
+                AclServiceManager.MatchCriteria.MATCH_SOURCE));
+
+        String flowName = "Ingress_ICMPv6" + "_" + port.getDpId() + "_" + port.getLPortTag() + "_"
+                + AclConstants.ICMPV6_TYPE_RA + "_LinkLocal_Permit_";
+        syncFlow(port.getDpId(), getAclAntiSpoofingTable(), flowName, AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, "ACL",
+                0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+    }
+
     /**
      * Adds the rule to allow arp packets.
      *
@@ -283,9 +310,9 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
         BigInteger dpId = port.getDpId();
         int lportTag = port.getLPortTag();
         MatchInfoBase lportMatchInfo = AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode);
-        List<IpPrefixOrAddress> cidrs = port.getSubnetIpPrefixes();
-        if (cidrs != null) {
-            List<String> broadcastAddresses = AclServiceUtils.getIpBroadcastAddresses(cidrs);
+        List<SubnetInfo> subnetInfoList = port.getSubnetInfo();
+        if (subnetInfoList != null) {
+            List<String> broadcastAddresses = AclServiceUtils.getIpBroadcastAddresses(subnetInfoList);
             for (String broadcastAddress : broadcastAddresses) {
                 List<MatchInfoBase> matches =
                         AclServiceUtils.buildBroadcastIpV4Matches(broadcastAddress);
index c32514988ee29f294ef8071a45926b98b06ba865..826eb51335e6762afd45d3c780b1dfa79f07ce73 100644 (file)
@@ -94,7 +94,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
                 if (aclInterface.getDpId() != null) {
                     aclServiceManager.notify(aclInterface, null, Action.REMOVE);
                 }
-                AclServiceUtils.deleteSubnetIpPrefixes(dataBroker, interfaceId);
+                aclServiceUtils.deleteSubnetInfo(interfaceId);
             }
         }
     }
@@ -221,9 +221,7 @@ public class AclInterfaceListener extends AsyncDataTreeChangeListenerBase<Interf
                         .lPortTag(interfaceState.getIfIndex()).isMarkedForDelete(false);
             }
 
-            if (prevAclInterface == null) {
-                builder.subnetIpPrefixes(AclServiceUtils.getSubnetIpPrefixes(dataBroker, interfaceId));
-            }
+            builder.subnetInfo(aclServiceUtils.getSubnetInfo(interfaceId));
             if (prevAclInterface == null || prevAclInterface.getElanId() == null) {
                 builder.elanId(AclServiceUtils.getElanIdFromInterface(interfaceId, dataBroker));
             }
index 52f29c1d9cc45d9e70ab462144d6739e08ed75f9..ee49260d3674d9a6557fc95764fdbcaf358c951c 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -149,11 +149,10 @@ public class AclInterfaceStateListener extends AsyncDataTreeChangeListenerBase<I
                 .isMarkedForDelete(false);
 
             if (AclServiceUtils.isOfInterest(prevAclInterface)) {
-                if (prevAclInterface.getSubnetIpPrefixes() == null) {
+                if (prevAclInterface.getSubnetInfo() == null) {
                     // For upgrades
-                    List<IpPrefixOrAddress> subnetIpPrefixes = AclServiceUtils.getSubnetIpPrefixes(dataBroker,
-                            added.getName());
-                    builder.subnetIpPrefixes(subnetIpPrefixes);
+                    List<SubnetInfo> subnetInfo = aclServiceUtils.getSubnetInfo(added.getName());
+                    builder.subnetInfo(subnetInfo);
                 }
                 SortedSet<Integer> ingressRemoteAclTags =
                         aclServiceUtils.getRemoteAclTags(aclInPort.getSecurityGroups(), DirectionIngress.class);
index 90848357ed712d9b5a6a0cada0a2ee606844508f..28f10f97beee41c15994c1249ff3bada26516eb1 100644 (file)
@@ -76,6 +76,7 @@ public interface AclConstants {
 
     String IPV4_ALL_NETWORK = "0.0.0.0/0";
     String IPV6_ALL_NETWORK = "::/0";
+    String IPV6_LINK_LOCAL_PREFIX = "fe80::/10";
     String BROADCAST_MAC = "ff:ff:ff:ff:ff:ff";
     String IPV4_ALL_SUBNET_BROADCAST_ADDR = "255.255.255.255";
 
index 51532d6df8474144eb24f3279605d93d9e7cd4f6..979320d7771ed5731f520e20ba4e553ca07dade6 100644 (file)
@@ -121,7 +121,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev16060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortsSubnetIpPrefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortSubnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.AclPortsByIp;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.AclPortsByIpKey;
@@ -131,8 +132,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev16060
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.acl.ip.prefixes.PortIdsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.acl.ports.lookup.acl.ports.by.ip.acl.ip.prefixes.PortIdsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
@@ -383,7 +385,7 @@ public final class AclServiceUtils {
      */
     public static List<MatchInfoBase> buildIcmpV6Matches(int icmpType, int icmpCode, int lportTag,
             Class<? extends ServiceModeBase> serviceMode) {
-        List<MatchInfoBase> matches = new ArrayList<>(6);
+        List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV6);
         matches.add(MatchIpProtocol.ICMPV6);
         if (icmpType != 0) {
@@ -508,10 +510,10 @@ public final class AclServiceUtils {
         return dpId;
     }
 
-    public static List<String> getIpBroadcastAddresses(List<IpPrefixOrAddress> cidrs) {
+    public static List<String> getIpBroadcastAddresses(List<SubnetInfo> subnetInfoList) {
         List<String> ipBroadcastAddresses = new ArrayList<>();
-        for (IpPrefixOrAddress cidr : cidrs) {
-            IpPrefix cidrIpPrefix = cidr.getIpPrefix();
+        for (SubnetInfo subnetInfo : subnetInfoList) {
+            IpPrefix cidrIpPrefix = subnetInfo.getIpPrefix().getIpPrefix();
             if (cidrIpPrefix != null) {
                 Ipv4Prefix cidrIpv4Prefix = cidrIpPrefix.getIpv4Prefix();
                 if (cidrIpv4Prefix != null) {
@@ -845,20 +847,25 @@ public final class AclServiceUtils {
                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
     }
 
-    public static List<IpPrefixOrAddress> getSubnetIpPrefixes(DataBroker broker, String portId) {
-        InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
-                .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
-        Optional<PortSubnetIpPrefixes> portSubnetIpPrefixes = read(broker, LogicalDatastoreType.OPERATIONAL, id);
-        if (portSubnetIpPrefixes.isPresent()) {
-            return portSubnetIpPrefixes.get().getSubnetIpPrefixes();
+    public List<SubnetInfo> getSubnetInfo(String portId) {
+        InstanceIdentifier<PortSubnet> id = InstanceIdentifier.builder(PortSubnets.class)
+                .child(PortSubnet.class, new PortSubnetKey(portId)).build();
+
+        Optional<PortSubnet> portSubnet = read(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+        if (portSubnet.isPresent()) {
+            return portSubnet.get().getSubnetInfo();
         }
         return null;
     }
 
-    public static void deleteSubnetIpPrefixes(DataBroker broker, String portId) {
-        InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
-                    .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
-        MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, id);
+    public void deleteSubnetInfo(String portId) {
+        InstanceIdentifier<PortSubnet> id = InstanceIdentifier.builder(PortSubnets.class)
+                .child(PortSubnet.class, new PortSubnetKey(portId)).build();
+        try {
+            SingleTransactionDataBroker.syncDelete(dataBroker, LogicalDatastoreType.OPERATIONAL, id);
+        } catch (TransactionCommitFailedException e) {
+            LOG.error("Failed to delete subnet info for port={}", portId, e);
+        }
     }
 
     private static List<MatchInfoBase> updateAAPMatches(boolean isSourceIpMacMatch, List<MatchInfoBase> flows,
@@ -1501,4 +1508,35 @@ public final class AclServiceUtils {
         }
         return inetAddress;
     }
+
+    public static Boolean isIpv6RaAllowedFromExternalRouters(List<SubnetInfo> subnetInfoList) {
+        if (subnetInfoList != null && !subnetInfoList.isEmpty()) {
+            for (SubnetInfo subnetInfo : subnetInfoList) {
+                if (subnetInfo != null && IpVersionV6.class.equals(subnetInfo.getIpVersion())
+                        && subnetInfo.getIpv6RaMode() == null) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gets the subnet difference by performing (subnetInfo1 - subnetInfo2).
+     *
+     * @param subnetInfo1 the subnet info 1
+     * @param subnetInfo2 the subnet info 2
+     * @return the subnet diff
+     */
+    public static List<SubnetInfo> getSubnetDiff(List<SubnetInfo> subnetInfo1, List<SubnetInfo> subnetInfo2) {
+        if (subnetInfo1 == null) {
+            return Collections.emptyList();
+        }
+        List<SubnetInfo> newSubnetList = new ArrayList<>(subnetInfo1);
+        if (subnetInfo2 == null) {
+            return newSubnetList;
+        }
+        newSubnetList.removeAll(subnetInfo2);
+        return newSubnetList;
+    }
 }
index 5ba8cf5dbd92f23f9550afc904fa460403caa227..3571d03bf3892db67cc292b93232b1bf8396476b 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.cont
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.MatchesBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIpBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
@@ -52,8 +53,13 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterface;
@@ -93,9 +99,12 @@ public abstract class AclServiceTestBase {
     static String IP_PREFIX_2 = "10.0.0.2/32";
     static String IP_PREFIX_3 = "10.0.0.3/32";
     static String IP_PREFIX_4 = "10.0.0.4/32";
-    static String SUBNET_IP_PREFIX_1 = "10.0.0.0/24";
     static long ELAN_TAG = 5000L;
 
+    static String SUBNET_IP_PREFIX_1 = "10.0.0.0/24";
+    static Uuid SUBNET_ID_1 = new Uuid("39add98b-63b7-42e6-8368-ff807eee165e");
+    static SubnetInfo SUBNET_INFO_1 = buildSubnetInfo(SUBNET_ID_1, SUBNET_IP_PREFIX_1, IpVersionV4.class, "10.0.0.1");
+
     static final AllowedAddressPairs AAP_PORT_1 = buildAap(IP_PREFIX_1, PORT_MAC_1);
     static final AllowedAddressPairs AAP_PORT_2 = buildAap(IP_PREFIX_2, PORT_MAC_2);
     static final AllowedAddressPairs AAP_PORT_3 = buildAap(IP_PREFIX_3, PORT_MAC_3);
@@ -127,10 +136,8 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         testInterfaceManager.addInterfaceInfo(newInterfaceInfo("port1"));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName("port1")
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName("port1").addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         // When
         putNewStateInterface(dataBroker, "port1", PORT_MAC_1);
@@ -150,14 +157,10 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
@@ -191,14 +194,10 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_UNSPECIFIED,
@@ -256,14 +255,10 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         // Given
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
@@ -299,14 +294,10 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         // Given
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
@@ -343,14 +334,10 @@ public abstract class AclServiceTestBase {
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
         // Given
         prepareInterfaceWithIcmpAcl();
 
@@ -372,10 +359,8 @@ public abstract class AclServiceTestBase {
         LOG.info("newInterfaceWithDstPortRange - start");
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
         // Given
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 333, 777, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
@@ -406,10 +391,8 @@ public abstract class AclServiceTestBase {
         LOG.info("newInterfaceWithDstAllPorts - start");
 
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
         // Given
         Matches matches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, 1, 65535, AclConstants.SOURCE_REMOTE_IP_PREFIX_UNSPECIFIED,
@@ -440,10 +423,8 @@ public abstract class AclServiceTestBase {
         LOG.info("newInterfaceWithTwoAclsHavingSameRules - start");
 
         newAllowedAddressPair(PORT_3, Arrays.asList(SG_UUID_1, SG_UUID_2), Collections.singletonList(AAP_PORT_3));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_3)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_3).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
         // Given
         Matches icmpEgressMatches = newMatch(AclConstants.SOURCE_LOWER_PORT_UNSPECIFIED,
                 AclConstants.SOURCE_UPPER_PORT_UNSPECIFIED, AclConstants.DEST_LOWER_PORT_2,
@@ -482,14 +463,10 @@ public abstract class AclServiceTestBase {
     public void newInterfaceWithIcmpAclHavingOverlappingMac() throws Exception {
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_2));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
         // Given
         prepareInterfaceWithIcmpAcl();
 
@@ -510,14 +487,10 @@ public abstract class AclServiceTestBase {
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
                 Arrays.asList(AAP_PORT_2, buildAap(AclConstants.IPV4_ALL_NETWORK, PORT_MAC_2)));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         prepareInterfaceWithIcmpAcl();
         // When
@@ -545,14 +518,10 @@ public abstract class AclServiceTestBase {
         newAllowedAddressPair(PORT_1, Collections.singletonList(SG_UUID_1), Collections.singletonList(AAP_PORT_1));
         newAllowedAddressPair(PORT_2, Collections.singletonList(SG_UUID_1),
                 Arrays.asList(AAP_PORT_2, aapWithSameMac, aapWithDifferentMac));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_1)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
-        dataBrokerUtil.put(new IdentifiedSubnetIpPrefixBuilder()
-                .interfaceName(PORT_2)
-                .addAllIpPrefixOrAddress(Collections.singletonList(
-                        new IpPrefixOrAddress(SUBNET_IP_PREFIX_1.toCharArray()))));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_1).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
+        dataBrokerUtil.put(new IdentifiedPortSubnetBuilder().interfaceName(PORT_2).addAllSubnetInfo(
+                Collections.singletonList(SUBNET_INFO_1)));
 
         prepareInterfaceWithIcmpAcl();
         // When
@@ -655,6 +624,13 @@ public abstract class AclServiceTestBase {
                 .setMacAddress(new MacAddress(macAddress)).build();
     }
 
+    protected static SubnetInfo buildSubnetInfo(Uuid subnetId, String ipPrefix,
+            Class<? extends IpVersionBase> ipVersion, String gwIp) {
+        return new SubnetInfoBuilder().setKey(new SubnetInfoKey(subnetId)).setIpVersion(ipVersion)
+                .setIpPrefix(new IpPrefixOrAddress(ipPrefix.toCharArray()))
+                .setGatewayIp(new IpAddress(gwIp.toCharArray())).build();
+    }
+
     protected void setUpData() throws Exception {
         newElan(ELAN, ELAN_TAG);
         newElanInterface(ELAN, PORT_1, true);
similarity index 61%
rename from aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/IdentifiedSubnetIpPrefixBuilder.xtend
rename to aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/tests/IdentifiedPortSubnetBuilder.xtend
index 679030e81290d4a44a8136695263815d2634596c..b3852f4fe4e0c2563ed77877b93d9d0b681a126c 100644 (file)
@@ -7,39 +7,38 @@
  */
 package org.opendaylight.netvirt.aclservice.tests
 
+import java.util.ArrayList
+import java.util.List
+import javax.annotation.concurrent.NotThreadSafe
 import org.opendaylight.netvirt.aclservice.tests.infra.DataTreeIdentifierDataObjectPairBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortSubnets
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnet
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetKey
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 
 import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.OPERATIONAL
-import static extension org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions.operator_doubleGreaterThan
-import javax.annotation.concurrent.NotThreadSafe
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress
 
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesKey
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixes
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortsSubnetIpPrefixes
-
-import java.util.List
-import java.util.ArrayList
+import static extension org.opendaylight.mdsal.binding.testutils.XtendBuilderExtensions.operator_doubleGreaterThan
 
 @NotThreadSafe
-class IdentifiedSubnetIpPrefixBuilder implements DataTreeIdentifierDataObjectPairBuilder<PortSubnetIpPrefixes>  {
+class IdentifiedPortSubnetBuilder implements DataTreeIdentifierDataObjectPairBuilder<PortSubnet>  {
 
     var String newInterfaceName
-    List<IpPrefixOrAddress> newIpPrefixOrAddress = new ArrayList
+    List<SubnetInfo> subnetInfoList = new ArrayList
 
     override dataObject() {
-        new PortSubnetIpPrefixesBuilder >> [
-            key = new PortSubnetIpPrefixesKey(newInterfaceName)
+        new PortSubnetBuilder >> [
+            key = new PortSubnetKey(newInterfaceName)
             portId = newInterfaceName
-            subnetIpPrefixes = newIpPrefixOrAddress
+            subnetInfo = subnetInfoList
         ]
     }
 
     override identifier() {
-        InstanceIdentifier.builder(PortsSubnetIpPrefixes)
-                    .child(PortSubnetIpPrefixes, new PortSubnetIpPrefixesKey(newInterfaceName)).build
+        InstanceIdentifier.builder(PortSubnets)
+                    .child(PortSubnet, new PortSubnetKey(newInterfaceName)).build
     }
 
     override type() {
@@ -51,8 +50,8 @@ class IdentifiedSubnetIpPrefixBuilder implements DataTreeIdentifierDataObjectPai
         this
     }
 
-    def addAllIpPrefixOrAddress(List<IpPrefixOrAddress> ipPrefixOrAddress) {
-        this.newIpPrefixOrAddress.addAll(ipPrefixOrAddress)
+    def addAllSubnetInfo(List<SubnetInfo> subnetInfoList) {
+        this.subnetInfoList.addAll(subnetInfoList)
         this
     }
 
index 5beec73aed73cb96602fee704dea767db247b06a..527eda10f167c367198cd4a7c25d8389cce719f7 100644 (file)
@@ -35,7 +35,7 @@ public class DisplayAclDataCaches extends OsgiCommandSupport {
     private static final String ACL_INT_TAB = "   %-4s  %-4s  %-4s  %-4s %-4s  %-6s  %-20s  %-20s %-4s";
     private static final String ACL_INT_TAB_FOR = KEY_TAB + ACL_INT_TAB;
     private static final String ACL_INT_HEAD = String.format(ACL_INT_TAB_FOR, "UUID", "PortSecurityEnabled",
-            "InterfaceId", "LPortTag", "DpId", "ElanId", "SecurityGroups", "AllowedAddressPairs", "SubnetIpPrefixes",
+            "InterfaceId", "LPortTag", "DpId", "ElanId", "SecurityGroups", "AllowedAddressPairs", "SubnetInfo",
             "MarkedForDelete")
             + "\n   -------------------------------------------------------------------------------------------------";
     private static final String REM_ID_TAB = "   %-20s  ";
@@ -182,7 +182,7 @@ public class DisplayAclDataCaches extends OsgiCommandSupport {
                             aclInterface.isPortSecurityEnabled(), aclInterface.getInterfaceId(),
                             aclInterface.getLPortTag(), aclInterface.getDpId(), aclInterface.getElanId(),
                             aclInterface.getSecurityGroups(), aclInterface.getAllowedAddressPairs(),
-                            aclInterface.getSubnetIpPrefixes(), aclInterface.isMarkedForDelete()));
+                            aclInterface.getSubnetInfo(), aclInterface.isMarkedForDelete()));
                 }
             }
         } else if (uuidStr == null) {
@@ -203,7 +203,7 @@ public class DisplayAclDataCaches extends OsgiCommandSupport {
                                 aclInterface.isPortSecurityEnabled(), aclInterface.getInterfaceId(),
                                 aclInterface.getLPortTag(), aclInterface.getDpId(), aclInterface.getElanId(),
                                 aclInterface.getSecurityGroups(), aclInterface.getAllowedAddressPairs(),
-                                aclInterface.getSubnetIpPrefixes(), aclInterface.isMarkedForDelete()));
+                                aclInterface.getSubnetInfo(), aclInterface.isMarkedForDelete()));
                     }
                 }
             }
@@ -314,7 +314,7 @@ public class DisplayAclDataCaches extends OsgiCommandSupport {
                     aclInterface.isPortSecurityEnabled(), aclInterface.getInterfaceId(),
                     aclInterface.getLPortTag(), aclInterface.getDpId(), aclInterface.getElanId(),
                     aclInterface.getSecurityGroups(), aclInterface.getAllowedAddressPairs(),
-                    aclInterface.getSubnetIpPrefixes(), aclInterface.isMarkedForDelete()));
+                    aclInterface.getSubnetInfo(), aclInterface.isMarkedForDelete()));
 
         } else if (key == null) {
             if (!validateAll()) {
@@ -332,7 +332,7 @@ public class DisplayAclDataCaches extends OsgiCommandSupport {
                             aclInterface.isPortSecurityEnabled(), aclInterface.getInterfaceId(),
                             aclInterface.getLPortTag(), aclInterface.getDpId(), aclInterface.getElanId(),
                             aclInterface.getSecurityGroups(), aclInterface.getAllowedAddressPairs(),
-                            aclInterface.getSubnetIpPrefixes(), aclInterface.isMarkedForDelete()));
+                            aclInterface.getSubnetInfo(), aclInterface.isMarkedForDelete()));
                 }
             }
         }
index 4cb7d9da875f1da7687cd07eede88838af5d7a4e..ddbb2ad81c5a341131e638be12f6ab83e9c27281 100644 (file)
@@ -757,7 +757,7 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
             })));
     }
 
-    private static InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal,
+    private InterfaceAclBuilder handlePortSecurityUpdated(Port portOriginal,
             Port portUpdated, boolean origSecurityEnabled, boolean updatedSecurityEnabled,
             InterfaceBuilder interfaceBuilder) {
         InterfaceAclBuilder interfaceAclBuilder = null;
@@ -767,6 +767,7 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
             if (updatedSecurityEnabled) {
                 // Handle security group enabled
                 NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, portUpdated);
+                neutronvpnUtils.populateSubnetInfo(portUpdated);
             } else {
                 // Handle security group disabled
                 interfaceAclBuilder.setSecurityGroups(new ArrayList<>());
@@ -786,6 +787,11 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
                 interfaceAclBuilder.setAllowedAddressPairs(NeutronvpnUtils.getAllowedAddressPairsForFixedIps(
                         updatedAddressPairs, portOriginal.getMacAddress(), portOriginal.getFixedIps(),
                         portUpdated.getFixedIps()));
+
+                if (portOriginal.getFixedIps() != null
+                        && !portOriginal.getFixedIps().equals(portUpdated.getFixedIps())) {
+                    neutronvpnUtils.populateSubnetInfo(portUpdated);
+                }
             }
         }
         return interfaceAclBuilder;
@@ -826,7 +832,7 @@ public class NeutronPortChangeListener extends AsyncDataTreeChangeListenerBase<P
             interfaceAclBuilder.setPortSecurityEnabled(true);
             NeutronvpnUtils.populateInterfaceAclBuilder(interfaceAclBuilder, port);
             interfaceBuilder.addAugmentation(InterfaceAcl.class, interfaceAclBuilder.build());
-            neutronvpnUtils.populateSubnetIpPrefixes(port);
+            neutronvpnUtils.populateSubnetInfo(port);
         }
         return interfaceBuilder.build();
     }
index 43d6a8ae6a6ea32a41077726b8524c759c214949..31f1b3cfe4ac8c11a1089577afb14d67a121a136 100644 (file)
@@ -7,11 +7,20 @@
  */
 package org.opendaylight.netvirt.neutronvpn;
 
+import com.google.common.collect.ImmutableBiMap;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AclBase;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Base;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Off;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Slaac;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.Dhcpv6Stateless;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.IpVersionV6;
 
 public interface NeutronSecurityRuleConstants {
     Class<DirectionEgress> DIRECTION_EGRESS = DirectionEgress.class;
@@ -30,4 +39,21 @@ public interface NeutronSecurityRuleConstants {
     // default acp type
     Class<? extends AclBase> ACLTYPE = Ipv4Acl.class;
 
+    ImmutableBiMap<Class<? extends IpVersionBase>, Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight
+            .netvirt.aclservice.rev160608.IpVersionBase>> IP_VERSION_MAP =
+            ImmutableBiMap.of(IpVersionV4.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV4.class,
+                    IpVersionV6.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionV6.class);
+
+    ImmutableBiMap<Class<? extends Dhcpv6Base>, Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt
+            .aclservice.rev160608.Dhcpv6Base>> RA_MODE_MAP =
+            ImmutableBiMap.of(Dhcpv6Off.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Off.class,
+                    Dhcpv6Stateful.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Stateful.class,
+                    Dhcpv6Slaac.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Slaac.class,
+                    Dhcpv6Stateless.class,
+                    org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Stateless.class);
 }
index 4b9cdd77418d263a1a1ed7bcb49d17b05f9e03ed..e70bc013778ad117e50f0565d38843fe44b7163d 100644 (file)
@@ -37,6 +37,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
@@ -62,14 +63,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.Dhcpv6Base;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAclBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortsSubnetIpPrefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpVersionBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.PortSubnets;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.ports.subnet.ip.prefixes.PortSubnetIpPrefixesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.PortSubnetKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfoKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeFlat;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.SegmentTypeGre;
@@ -690,35 +696,46 @@ public class NeutronvpnUtils {
         interfaceAclBuilder.setAllowedAddressPairs(aclAllowedAddressPairs);
     }
 
-    protected void populateSubnetIpPrefixes(Port port) {
-        List<IpPrefixOrAddress> subnetIpPrefixes = getSubnetIpPrefixes(port);
-        if (subnetIpPrefixes != null) {
+    protected void populateSubnetInfo(Port port) {
+        List<SubnetInfo> portSubnetInfo = getSubnetInfo(port);
+        if (portSubnetInfo != null) {
             String portId = port.getUuid().getValue();
-            InstanceIdentifier<PortSubnetIpPrefixes> portSubnetIpPrefixIdentifier =
-                NeutronvpnUtils.buildPortSubnetIpPrefixIdentifier(portId);
-            PortSubnetIpPrefixesBuilder subnetIpPrefixesBuilder = new PortSubnetIpPrefixesBuilder()
-                    .setKey(new PortSubnetIpPrefixesKey(portId)).setPortId(portId)
-                    .setSubnetIpPrefixes(subnetIpPrefixes);
-            MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL, portSubnetIpPrefixIdentifier,
-                    subnetIpPrefixesBuilder.build());
-            LOG.debug("Created Subnet IP Prefixes for port {}", port.getUuid().getValue());
+            InstanceIdentifier<PortSubnet> portSubnetIdentifier = buildPortSubnetIdentifier(portId);
+
+            PortSubnetBuilder portSubnetBuilder = new PortSubnetBuilder().setKey(new PortSubnetKey(portId))
+                    .setPortId(portId).setSubnetInfo(portSubnetInfo);
+            try {
+                SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                        portSubnetIdentifier, portSubnetBuilder.build());
+            } catch (TransactionCommitFailedException e) {
+                LOG.error("Failed to populate subnet info for port={}", portId, e);
+            }
+            LOG.debug("Created Subnet info for port={}", portId);
         }
     }
 
-    protected List<IpPrefixOrAddress> getSubnetIpPrefixes(Port port) {
-        List<Uuid> subnetIds = getSubnetIdsFromNetworkId(port.getNetworkId());
-        if (subnetIds == null) {
-            LOG.error("Failed to get Subnet Ids for the Network {}", port.getNetworkId());
+    protected List<SubnetInfo> getSubnetInfo(Port port) {
+        List<FixedIps> portFixedIps = port.getFixedIps();
+        if (portFixedIps == null) {
+            LOG.error("Failed to get Fixed IPs for the port {}", port.getName());
             return null;
         }
-        List<IpPrefixOrAddress> subnetIpPrefixes = new ArrayList<>();
-        for (Uuid subnetId : subnetIds) {
+        List<SubnetInfo> subnetInfoList = new ArrayList<>();
+        for (FixedIps portFixedIp : portFixedIps) {
+            Uuid subnetId = portFixedIp.getSubnetId();
             Subnet subnet = getNeutronSubnet(subnetId);
             if (subnet != null) {
-                subnetIpPrefixes.add(new IpPrefixOrAddress(subnet.getCidr()));
+                Class<? extends IpVersionBase> ipVersion =
+                        NeutronSecurityRuleConstants.IP_VERSION_MAP.get(subnet.getIpVersion());
+                Class<? extends Dhcpv6Base> raMode = subnet.getIpv6RaMode() == null ? null
+                        : NeutronSecurityRuleConstants.RA_MODE_MAP.get(subnet.getIpv6RaMode());
+                SubnetInfo subnetInfo = new SubnetInfoBuilder().setKey(new SubnetInfoKey(subnetId))
+                        .setIpVersion(ipVersion).setIpPrefix(new IpPrefixOrAddress(subnet.getCidr()))
+                        .setIpv6RaMode(raMode).setGatewayIp(subnet.getGatewayIp()).build();
+                subnetInfoList.add(subnetInfo);
             }
         }
-        return subnetIpPrefixes;
+        return subnetInfoList;
     }
 
     protected Subnet getNeutronSubnet(Uuid subnetId) {
@@ -1011,9 +1028,9 @@ public class NeutronvpnUtils {
                 FloatingIpIdToPortMappingKey(floatingIpId)).build();
     }
 
-    static InstanceIdentifier<PortSubnetIpPrefixes> buildPortSubnetIpPrefixIdentifier(String portId) {
-        InstanceIdentifier<PortSubnetIpPrefixes> id = InstanceIdentifier.builder(PortsSubnetIpPrefixes.class)
-            .child(PortSubnetIpPrefixes.class, new PortSubnetIpPrefixesKey(portId)).build();
+    static InstanceIdentifier<PortSubnet> buildPortSubnetIdentifier(String portId) {
+        InstanceIdentifier<PortSubnet> id = InstanceIdentifier.builder(PortSubnets.class)
+                .child(PortSubnet.class, new PortSubnetKey(portId)).build();
         return id;
     }