Rate limit for subnet route punt packets for IPv6 13/72213/12
authorKarthikeyan Krishnan <karthikeyangceb007@gmail.com>
Thu, 24 May 2018 04:56:46 +0000 (10:26 +0530)
committerSridhar Gaddam <sgaddam@redhat.com>
Wed, 20 Jun 2018 12:05:24 +0000 (12:05 +0000)
Adds a learn action for subnet route punt flow which
installs a learn flow with higher priority than the
punt flow and matches on dst ipv6 address + vpn id
and drops the matching packets till the flow is
deleted after hard timeout expiry.

Depends-ON: https://git.opendaylight.org/gerrit/#/c/73025/

JIRA: NETVIRT-1213

Spec:
http://docs.opendaylight.org/projects/netvirt/en/latest/specs/fluorine/subnet-routing-for-hidden-ipv6.html

Change-Id: I42cad4be7eada8d81cfca6407aea1f69f022ad2f
Signed-off-by: Karthikeyan Krishnan <karthikeyangceb007@gmail.com>
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnNodeListener.java

index 7095e14e74c32efc135ffad26fafd0cee445deb0..8e84209f822c56a2e6e3f9a4cbc52a98d6481567 100644 (file)
@@ -117,6 +117,7 @@ public class VpnNodeListener extends AsyncClusteredDataTreeChangeListenerBase<No
                 makeTableMissFlow(tx, dpId, NwConstants.ADD_FLOW);
                 makeL3IntfTblMissFlow(tx, dpId, NwConstants.ADD_FLOW);
                 makeSubnetRouteTableMissFlow(tx, dpId, NwConstants.ADD_FLOW);
+                makeIpv6SubnetRouteTableMissFlow(tx, dpId, NwConstants.ADD_FLOW);
                 createTableMissForVpnGwFlow(tx, dpId);
                 createL3GwMacArpFlows(tx, dpId);
                 programTableMissForVpnVniDemuxTable(tx, dpId, NwConstants.ADD_FLOW);
@@ -165,14 +166,14 @@ public class VpnNodeListener extends AsyncClusteredDataTreeChangeListenerBase<No
     }
 
     private void makeSubnetRouteTableMissFlow(WriteTransaction writeFlowTx, BigInteger dpnId, int addOrRemove) {
-        final BigInteger cookieTableMiss = new BigInteger("8000004", 16);
         List<ActionInfo> actionsInfos = new ArrayList<>();
         List<InstructionInfo> instructions = new ArrayList<>();
         actionsInfos.add(new ActionPuntToController());
         int learnTimeout = vpnConfig.getSubnetRoutePuntTimeout().intValue();
         if (learnTimeout != 0) {
-            actionsInfos.add(new ActionLearn(0, learnTimeout, VpnConstants.DEFAULT_FLOW_PRIORITY, cookieTableMiss,
-                    0, NwConstants.L3_SUBNET_ROUTE_TABLE, 0, 0,
+            actionsInfos.add(new ActionLearn(0, learnTimeout, VpnConstants.DEFAULT_FLOW_PRIORITY,
+                    NwConstants.COOKIE_SUBNET_ROUTE_TABLE_MISS, 0, NwConstants.L3_SUBNET_ROUTE_TABLE,
+                    0, 0,
                     Arrays.asList(
                             new ActionLearn.MatchFromValue(NwConstants.ETHTYPE_IPV4,
                                     NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getType(),
@@ -189,9 +190,11 @@ public class VpnNodeListener extends AsyncClusteredDataTreeChangeListenerBase<No
         instructions.add(new InstructionApplyActions(actionsInfos));
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
-        String flowRef = getTableMissFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, NwConstants.TABLE_MISS_FLOW);
+        String flowRef = getSubnetRouteTableMissFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE,
+                NwConstants.ETHTYPE_IPV4, NwConstants.TABLE_MISS_FLOW);
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, flowRef,
-            NwConstants.TABLE_MISS_PRIORITY, "Subnet Route Table Miss", 0, 0, cookieTableMiss, matches, instructions);
+            NwConstants.TABLE_MISS_PRIORITY, "Subnet Route Table Miss", 0, 0,
+                NwConstants.COOKIE_SUBNET_ROUTE_TABLE_MISS, matches, instructions);
 
         if (addOrRemove == NwConstants.ADD_FLOW) {
             mdsalManager.addFlowToTx(flowEntity, writeFlowTx);
@@ -200,6 +203,46 @@ public class VpnNodeListener extends AsyncClusteredDataTreeChangeListenerBase<No
         }
     }
 
+    private void makeIpv6SubnetRouteTableMissFlow(WriteTransaction writeFlowTx, BigInteger dpnId, int addOrRemove) {
+        List<ActionInfo> actionsInfos = new ArrayList<>();
+        List<InstructionInfo> instructions = new ArrayList<>();
+        actionsInfos.add(new ActionPuntToController());
+        int learnTimeout = vpnConfig.getSubnetRoutePuntTimeout().intValue();
+        if (learnTimeout != 0) {
+            actionsInfos.add(new ActionLearn(0, learnTimeout, VpnConstants.DEFAULT_FLOW_PRIORITY,
+                    NwConstants.COOKIE_SUBNET_ROUTE_TABLE_MISS, 0, NwConstants.L3_SUBNET_ROUTE_TABLE,
+                    0, 0,
+                    Arrays.asList(
+                            new ActionLearn.MatchFromValue(NwConstants.ETHTYPE_IPV6,
+                                    NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getType(),
+                                    NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLenInt()),
+                            new ActionLearn.MatchFromField(NwConstants.NxmOfFieldType.NXM_NX_IPV6_DST.getType(),
+                                    NwConstants.NxmOfFieldType.NXM_NX_IPV6_DST.getType(),
+                                    NwConstants.NxmOfFieldType.NXM_NX_IPV6_DST.getFlowModHeaderLenInt()),
+                            new ActionLearn.MatchFromField(NwConstants.NxmOfFieldType.OXM_OF_METADATA.getType(),
+                                    MetaDataUtil.METADATA_VPN_ID_OFFSET,
+                                    NwConstants.NxmOfFieldType.OXM_OF_METADATA.getType(),
+                                    MetaDataUtil.METADATA_VPN_ID_OFFSET,
+                                    MetaDataUtil.METADATA_VPN_ID_BITLEN))));
+        }
+
+        instructions.add(new InstructionApplyActions(actionsInfos));
+        List<MatchInfo> matches = new ArrayList<>();
+        matches.add(MatchEthernetType.IPV6);
+        String flowRef = getSubnetRouteTableMissFlowRef(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE,
+                NwConstants.ETHTYPE_IPV6, NwConstants.TABLE_MISS_FLOW);
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId, NwConstants.L3_SUBNET_ROUTE_TABLE, flowRef,
+                NwConstants.TABLE_MISS_PRIORITY, "IPv6 Subnet Route Table Miss", 0, 0,
+                NwConstants.COOKIE_SUBNET_ROUTE_TABLE_MISS, matches, instructions);
+        if (addOrRemove == NwConstants.ADD_FLOW) {
+            LOG.debug("makeIpv6SubnetRouteTableMissFlow: Install Ipv6 Subnet Route Table Miss entry");
+            mdsalManager.addFlowToTx(flowEntity, writeFlowTx);
+        } else {
+            LOG.debug("makeIpv6SubnetRouteTableMissFlow: Remove Ipv6 Subnet Route Table Miss entry");
+            mdsalManager.removeFlowToTx(flowEntity, writeFlowTx);
+        }
+    }
+
     private void programTableMissForVpnVniDemuxTable(WriteTransaction writeFlowTx, BigInteger dpnId, int addOrRemove) {
         List<ActionInfo> actionsInfos = Collections.singletonList(new ActionNxResubmit(NwConstants
                 .LPORT_DISPATCHER_TABLE));
@@ -245,8 +288,12 @@ public class VpnNodeListener extends AsyncClusteredDataTreeChangeListenerBase<No
     }
 
     private String getTableMissFlowRef(BigInteger dpnId, short tableId, int tableMiss) {
-        return new StringBuffer().append(FLOWID_PREFIX).append(dpnId).append(NwConstants.FLOWID_SEPARATOR)
-            .append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(tableMiss)
-            .append(FLOWID_PREFIX).toString();
+        return FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + tableMiss
+                + FLOWID_PREFIX;
+    }
+
+    private String getSubnetRouteTableMissFlowRef(BigInteger dpnId, short tableId, int etherType, int tableMiss) {
+        return FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + etherType
+                + NwConstants.FLOWID_SEPARATOR + tableMiss + FLOWID_PREFIX;
     }
 }