Handle learn security groups 12/43712/6
authorSlava <slava.radune@hpe.com>
Thu, 11 Aug 2016 12:04:10 +0000 (15:04 +0300)
committerAswin Suryanarayanan <asuryana@redhat.com>
Sun, 21 Aug 2016 09:51:38 +0000 (15:21 +0530)
Change-Id: I9d3385502a1e902ba6dd1a034927595d04b54ee8
Signed-off-by: Slava <slava.radune@hpe.com>
12 files changed:
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AclServiceImplFactory.java
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/EgressAclServiceImpl.java
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/IngressAclServiceImpl.java
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImpl.java [new file with mode: 0644]
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnIngressAclServiceImpl.java [new file with mode: 0644]
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/listeners/AclNodeListener.java
vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/utils/AclConstants.java
vpnservice/aclservice/impl/src/main/yang/aclservice-config.yang
vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImplTest.java [new file with mode: 0644]
vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/StatelessEgressAclServiceImplTest.java
vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/utils/AclServiceTestUtils.java

index 4adbf6b4e01180245d70b5ec541057d4aa8fb6a2..a7be27b23aad5f293dbdb9d725ca977789faff8b 100644 (file)
@@ -236,6 +236,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param dpId the dpId
      * @param lportTag the lport tag
      * @param addOrRemove whether to delete or add flow
+     * @return program succeeded
      */
     protected abstract boolean programAclRules(List<Uuid> aclUuidList, BigInteger dpId, int lportTag, int addOrRemove,
                                             String portId);
index c114c47092cb1411c32d5b3a20687ba7bfa75ad6..254098f8d70bbdbd2d870311fc3141b2a2dcddab 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.netvirt.aclservice;
 
-//import java.util.Map;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.config.rev160806.AclserviceConfig;
@@ -16,6 +15,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
 public class AclServiceImplFactory implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(AclServiceImplFactory.class);
@@ -28,41 +28,12 @@ public class AclServiceImplFactory implements AutoCloseable {
     public AclServiceImplFactory(DataBroker dataBroker, IMdsalApiManager mdsalManager, AclserviceConfig config) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
-        this.securityGroupMode = config.getSecurityGroupMode();
+        if (config != null) {
+            this.securityGroupMode = config.getSecurityGroupMode();
+        }
         LOG.info("AclserviceConfig: {}", config);
     }
 
-    /* alternate use for ConfigAdmin
-    public void setSecurityGroupMode(String securityGroupMode) {
-        LOG.info("setSecurityGroupMode: {}", securityGroupMode);
-    }
-
-    public void updateConfigParameter(Map<String, Object> configParameters) {
-        LOG.info("Config parameters received : {}", configParameters.entrySet());
-        if (configParameters != null && !configParameters.isEmpty()) {
-            for (Map.Entry<String, Object> paramEntry : configParameters.entrySet()) {
-                if (paramEntry.getKey().equalsIgnoreCase(SECURITY_GROUP_MODE)) {
-                    LOG.info("setSecurityGroupMode: {}", paramEntry.getValue());
-
-                    //Please remove the break if you add more config nobs.
-                    break;
-                }
-                if (paramEntry.getKey().equalsIgnoreCase("teststring")) {
-                    LOG.info("testString: {}", paramEntry.getValue());
-
-                    //Please remove the break if you add more config nobs.
-                    break;
-                }
-                if (paramEntry.getKey().equalsIgnoreCase("testint")) {
-                    LOG.info("testInt: {}", Integer.parseInt((String)paramEntry.getValue()));
-
-                    //Please remove the break if you add more config nobs.
-                    break;
-                }
-            }
-        }
-    }*/
-
     protected InstanceIdentifier<AclserviceConfig> getWildCardPath() {
         return InstanceIdentifier
                 .create(AclserviceConfig.class);
@@ -83,8 +54,10 @@ public class AclServiceImplFactory implements AutoCloseable {
             return new IngressAclServiceImpl(dataBroker, mdsalManager);
         } else if (securityGroupMode == SecurityGroupMode.Stateless) {
             return new StatelessIngressAclServiceImpl(dataBroker, mdsalManager);
-        } else {
+        } else if (securityGroupMode == SecurityGroupMode.Transparent) {
             return new TransparentIngressAclServiceImpl(dataBroker, mdsalManager);
+        } else {
+            return new LearnIngressAclServiceImpl(dataBroker, mdsalManager);
         }
     }
 
@@ -94,8 +67,10 @@ public class AclServiceImplFactory implements AutoCloseable {
             return new EgressAclServiceImpl(dataBroker, mdsalManager);
         } else if (securityGroupMode == SecurityGroupMode.Stateless) {
             return new StatelessEgressAclServiceImpl(dataBroker, mdsalManager);
-        } else {
+        } else if (securityGroupMode == SecurityGroupMode.Transparent) {
             return new TransparentEgressAclServiceImpl(dataBroker, mdsalManager);
+        } else {
+            return new LearnEgressAclServiceImpl(dataBroker, mdsalManager);
         }
     }
 }
index 4c294c05bb32dac4fd33302fde89bc1f56781d8a..cb695c4bc3122332d39b581d6b65f6d0464533ab 100644 (file)
@@ -191,7 +191,8 @@ public class EgressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove add/remove the flow.
      */
-    private void egressAclDhcpDropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag, int addOrRemove) {
+    protected void egressAclDhcpDropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
+            int addOrRemove) {
         List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_SERVER_PORT_IPV4,
                 AclConstants.DHCP_CLIENT_PORT_IPV4, lportTag);
 
@@ -211,7 +212,7 @@ public class EgressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove add/remove the flow.
      */
-    private void egressAclDhcpv6DropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
+    protected void egressAclDhcpv6DropServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
             int addOrRemove) {
         List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_SERVER_PORT_IPV6,
                 AclConstants.DHCP_CLIENT_PORT_IPV6, lportTag);
@@ -353,7 +354,7 @@ public class EgressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove whether to add or remove the flow
      */
-    private void programArpRule(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses, int lportTag,
+    protected void programArpRule(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses, int lportTag,
             int addOrRemove) {
         for (AllowedAddressPairs allowedAddress : allowedAddresses) {
             String attachMac = allowedAddress.getMacAddress().getValue();
index a3f84a198496ef3c516bca5379a85e6fa49a77fd..ad71afe3fa4a82c3be4b85552b70cf3590742960 100644 (file)
@@ -192,8 +192,8 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param addOrRemove is write or delete
      * @param protoPortMatchPriority the priority
      */
-    private void ingressAclDhcpAllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag, int addOrRemove,
-            int protoPortMatchPriority) {
+    protected void ingressAclDhcpAllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
+            int addOrRemove, int protoPortMatchPriority) {
         final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_SERVER_PORT_IPV4,
                 AclConstants.DHCP_CLIENT_PORT_IPV4, lportTag);
 
@@ -215,7 +215,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param addOrRemove is write or delete
      * @param protoPortMatchPriority the priority
      */
-    private void ingressAclDhcpv6AllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
+    protected void ingressAclDhcpv6AllowServerTraffic(BigInteger dpId, String dhcpMacAddress, int lportTag,
             int addOrRemove, Integer protoPortMatchPriority) {
         final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_SERVER_PORT_IPV6,
                 AclConstants.DHCP_CLIENT_PORT_IPV6, lportTag);
@@ -351,7 +351,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove whether to add or remove the flow
      */
-    private void programArpRule(BigInteger dpId, int lportTag, int addOrRemove) {
+    protected void programArpRule(BigInteger dpId, int lportTag, int addOrRemove) {
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(new MatchInfo(MatchFieldType.eth_type, new long[] {NwConstants.ETHTYPE_ARP}));
         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
diff --git a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImpl.java b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImpl.java
new file mode 100644 (file)
index 0000000..3bda6f7
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.ActionType;
+import org.opendaylight.genius.mdsalutil.InstructionInfo;
+import org.opendaylight.genius.mdsalutil.InstructionType;
+import org.opendaylight.genius.mdsalutil.MatchInfoBase;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
+import org.opendaylight.netvirt.aclservice.utils.AclConstants;
+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.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
+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;
+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.AceType;
+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.AceIp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LearnEgressAclServiceImpl extends EgressAclServiceImpl {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LearnEgressAclServiceImpl.class);
+
+    /**
+     * Initialize the member variables.
+     *
+     * @param dataBroker
+     *            the data broker instance.
+     * @param mdsalManager
+     *            the mdsal manager instance.
+     */
+    public LearnEgressAclServiceImpl(DataBroker dataBroker,
+            IMdsalApiManager mdsalManager) {
+        super(dataBroker, mdsalManager);
+    }
+
+    @Override
+    protected void programFixedRules(BigInteger dpid, String dhcpMacAddress,
+            List<AllowedAddressPairs> allowedAddresses, int lportTag, String portId, Action action, int addOrRemove) {
+        LOG.info("programFixedRules :  adding default rules.");
+
+        if (action == Action.ADD || action == Action.REMOVE) {
+            egressAclDhcpDropServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove);
+            egressAclDhcpv6DropServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove);
+        }
+        programArpRule(dpid, allowedAddresses, lportTag, addOrRemove);
+    }
+
+    @Override
+    protected void programAceRule(BigInteger dpId, int lportTag, int addOrRemove, Ace ace, String portId,
+            List<AllowedAddressPairs> syncAllowedAddresses) {
+        SecurityRuleAttr aceAttr = AclServiceUtils.getAccesssListAttributes(ace);
+        if (!aceAttr.getDirection().equals(DirectionEgress.class)) {
+            return;
+        }
+        Matches matches = ace.getMatches();
+        AceType aceType = matches.getAceType();
+        Map<String, List<MatchInfoBase>> flowMap = null;
+        if (aceType instanceof AceIp) {
+            flowMap = AclServiceOFFlowBuilder.programIpFlow(matches);
+        }
+        if (null == flowMap) {
+            LOG.error("Failed to apply ACL {} lportTag {}", ace.getKey(), lportTag);
+            return;
+        }
+
+        // The flow map contains list of flows if port range is selected.
+        for (Map.Entry<String, List<MatchInfoBase>> flow : flowMap.entrySet()) {
+            List<MatchInfoBase> flowMatches = flow.getValue();
+            flowMatches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
+            List<ActionInfo> actionsInfos = new ArrayList<>();
+            addLearnActions(flowMatches, actionsInfos);
+
+            List<InstructionInfo> instructions = new ArrayList<>();
+            instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+            String flowName = flow.getKey() + "Egress" + lportTag + ace.getKey().getRuleName();
+            syncFlow(dpId, NwConstants.INGRESS_LEARN2_TABLE, flowName, AclConstants.PROTO_MATCH_PRIORITY, "ACL", 0, 0,
+                    AclConstants.COOKIE_ACL_BASE, flowMatches, instructions, addOrRemove);
+        }
+    }
+
+    /*
+     * learn header
+     *
+     * 0 1 2 3 4 5 6 7 idleTO hardTO prio cook flags table finidle finhrad
+     *
+     * learn flowmod learnFlowModType srcField dstField FlowModNumBits 0 1 2 3
+     */
+    private void addLearnActions(List<MatchInfoBase> flows, List<ActionInfo> actionsInfos) {
+        boolean isTcp = AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_tcp_src_with_mask)
+                || AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_tcp_dst_with_mask);
+        boolean isUdp = AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_udp_src_with_mask)
+                || AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_udp_dst_with_mask);
+        if (isTcp) {
+            addTcpLearnActions(actionsInfos);
+        } else if (isUdp) {
+            addUdpLearnActions(actionsInfos);
+        } else if (actionsInfos.isEmpty()) {
+            addAllowAllLearnActions(actionsInfos);
+        } else {
+            addOtherProtocolsLearnActions(actionsInfos);
+        }
+    }
+
+    private void addOtherProtocolsLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[5][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[4] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.EGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addAllowAllLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[5][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[4] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.EGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addTcpLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[6][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.IP_PROT_TCP),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getFlowModHeaderLen() };
+        flowMod[4] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[5] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "3600"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "3600"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.EGRESS_LEARN_TABLE), "60", "60" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addUdpLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[6][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.IP_PROT_UDP),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_UDP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_UDP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getFlowModHeaderLen() };
+        flowMod[4] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[5] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.EGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+}
diff --git a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnIngressAclServiceImpl.java b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/LearnIngressAclServiceImpl.java
new file mode 100644 (file)
index 0000000..b456244
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.mdsalutil.ActionInfo;
+import org.opendaylight.genius.mdsalutil.ActionType;
+import org.opendaylight.genius.mdsalutil.InstructionInfo;
+import org.opendaylight.genius.mdsalutil.InstructionType;
+import org.opendaylight.genius.mdsalutil.MatchInfoBase;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
+import org.opendaylight.netvirt.aclservice.utils.AclConstants;
+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.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
+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;
+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.AceType;
+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.AceIp;
+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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class LearnIngressAclServiceImpl extends IngressAclServiceImpl {
+
+    private static final Logger LOG = LoggerFactory.getLogger(LearnIngressAclServiceImpl.class);
+
+    public LearnIngressAclServiceImpl(DataBroker dataBroker, IMdsalApiManager mdsalManager) {
+        super(dataBroker, mdsalManager);
+    }
+
+    @Override
+    protected void programFixedRules(BigInteger dpid, String dhcpMacAddress, List<AllowedAddressPairs> allowedAddresses,
+            int lportTag, String portId, Action action, int addOrRemove) {
+        LOG.info("programFixedRules :  adding default rules.");
+
+        ingressAclDhcpAllowServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove,
+                AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
+        ingressAclDhcpv6AllowServerTraffic(dpid, dhcpMacAddress, lportTag, addOrRemove,
+                AclConstants.PROTO_PREFIX_MATCH_PRIORITY);
+        programArpRule(dpid, lportTag, addOrRemove);
+    }
+
+    @Override
+    protected void programAceRule(BigInteger dpId, int lportTag, int addOrRemove, Ace ace, String portId,
+            List<AllowedAddressPairs> syncAllowedAddresses) {
+        SecurityRuleAttr aceAttr = AclServiceUtils.getAccesssListAttributes(ace);
+        if (!aceAttr.getDirection().equals(DirectionIngress.class)) {
+            return;
+        }
+        Matches matches = ace.getMatches();
+        AceType aceType = matches.getAceType();
+        Map<String, List<MatchInfoBase>> flowMap = null;
+        if (aceType instanceof AceIp) {
+            flowMap = AclServiceOFFlowBuilder.programIpFlow(matches);
+        }
+        if (null == flowMap) {
+            LOG.error("Failed to apply ACL {} lportTag {}", ace.getKey(), lportTag);
+            return;
+        }
+
+        // The flow map contains list of flows if port range is selected.
+        for (Map.Entry<String, List<MatchInfoBase>> flow : flowMap.entrySet()) {
+            List<MatchInfoBase> flowMatches = flow.getValue();
+            flowMatches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
+            List<ActionInfo> actionsInfos = new ArrayList<>();
+            addLearnActions(flowMatches, actionsInfos);
+
+            List<InstructionInfo> instructions = new ArrayList<>();
+            instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+            String flowName = flow.getKey() + "Ingress" + lportTag + ace.getKey().getRuleName();
+            syncFlow(dpId, NwConstants.EGRESS_LEARN2_TABLE, flowName, AclConstants.PROTO_MATCH_PRIORITY, "ACL", 0, 0,
+                    AclConstants.COOKIE_ACL_BASE, flowMatches, instructions, addOrRemove);
+        }
+    }
+
+    /*
+     * learn header
+     *
+     * 0 1 2 3 4 5 6 7 idleTO hardTO prio cook flags table finidle finhrad
+     *
+     * learn flowmod learnFlowModType srcField dstField FlowModNumBits 0 1 2 3
+     */
+    private void addLearnActions(List<MatchInfoBase> flows, List<ActionInfo> actionsInfos) {
+        boolean isTcp = AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_tcp_src_with_mask)
+                || AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_tcp_dst_with_mask);
+        boolean isUdp = AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_udp_src_with_mask)
+                || AclServiceUtils.containsMatchFieldType(flows, NxMatchFieldType.nx_udp_dst_with_mask);
+        if (isTcp) {
+            addTcpLearnActions(actionsInfos);
+        } else if (isUdp) {
+            addUdpLearnActions(actionsInfos);
+        } else if (actionsInfos.isEmpty()) {
+            addAllowAllLearnActions(actionsInfos);
+        } else {
+            addOtherProtocolsLearnActions(actionsInfos);
+        }
+    }
+
+    private void addOtherProtocolsLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[5][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[4] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.INGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addAllowAllLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[5][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[4] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.INGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addTcpLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[6][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.IP_PROT_TCP),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getFlowModHeaderLen() };
+        flowMod[4] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[5] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "3600"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "3600"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.INGRESS_LEARN_TABLE), "60", "60" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+
+    private void addUdpLearnActions(List<ActionInfo> actionsInfos) {
+        String[][] flowMod = new String[6][];
+
+        flowMod[0] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.ETHTYPE_IPV4),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_TYPE.getFlowModHeaderLen() };
+        flowMod[1] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_VALUE.name(),
+                Integer.toString(NwConstants.IP_PROT_UDP),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_PROTO.getFlowModHeaderLen() };
+        flowMod[2] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_IP_SRC.getFlowModHeaderLen() };
+        flowMod[3] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_UDP_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_UDP_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_TCP_SRC.getFlowModHeaderLen() };
+        flowMod[4] = new String[] { NwConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
+                NwConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getFlowModHeaderLen() };
+        flowMod[5] = new String[] {
+                NwConstants.LearnFlowModsType.COPY_FROM_VALUE.name(), AclConstants.LEARN_MATCH_REG_VALUE,
+                NwConstants.NxmOfFieldType.NXM_NX_REG0.getHexType(), "8" };
+
+        String[] header = new String[] {
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_IDLE_TO_KEY, "60"),
+                AclConstants.getGlobalConf(AclConstants.SECURITY_GROUP_UDP_HARD_TO_KEY, "60"),
+                AclConstants.PROTO_MATCH_PRIORITY.toString(),
+                AclConstants.COOKIE_ACL_BASE.toString(), "0",
+                Short.toString(NwConstants.INGRESS_LEARN_TABLE), "0", "0" };
+        actionsInfos.add(new ActionInfo(ActionType.learn, header, flowMod));
+    }
+}
index 2a7f305263bfa9f62b26717944cccfba21a1084f..ad6ca691a4946462b5b3503e359f9eba239d340e 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.netvirt.aclservice.listeners;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
@@ -40,6 +41,8 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
+
 /**
  * Listener to handle flow capable node updates.
  */
@@ -65,7 +68,7 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
      *
      * @param mdsalManager the mdsal manager
      * @param dataBroker the data broker
-     * @param config - acl service configuration
+     * @param config aclservice configuration
      */
     public AclNodeListener(final IMdsalApiManager mdsalManager, DataBroker dataBroker, AclserviceConfig config) {
         super(FlowCapableNode.class, AclNodeListener.class);
@@ -77,9 +80,11 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
 
     public void start() {
         LOG.info("{} start", getClass().getSimpleName());
-        this.securityGroupMode = config.getSecurityGroupMode();
+        if (config != null) {
+            this.securityGroupMode = config.getSecurityGroupMode();
+        }
         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
-        LOG.info("AclserviceConfig: {}", config);
+        LOG.info("AclserviceConfig: {}", this.config);
     }
 
     /*
@@ -149,7 +154,8 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
      * @param dpnId the dpn id
      */
     private void createTableDefaultEntries(BigInteger dpnId) {
-        LOG.info("installing security group default rule in mode {}", this.securityGroupMode);
+        LOG.info("Adding default ACL entries for mode: "
+                + (securityGroupMode == null ? SecurityGroupMode.Stateful : securityGroupMode));
         if (securityGroupMode == null || securityGroupMode == SecurityGroupMode.Stateful) {
             addIngressAclTableMissFlow(dpnId);
             addEgressAclTableMissFlow(dpnId);
@@ -160,9 +166,12 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
         } else if (securityGroupMode == SecurityGroupMode.Transparent) {
             addTransparentIngressAclTableMissFlow(dpnId);
             addTransparentEgressAclTableMissFlow(dpnId);
-        } else {
+        } else if (securityGroupMode == SecurityGroupMode.Stateless) {
             addStatelessIngressAclTableMissFlow(dpnId);
             addStatelessEgressAclTableMissFlow(dpnId);
+        } else if (securityGroupMode == SecurityGroupMode.Learn) {
+            addLearnIngressAclTableMissFlow(dpnId);
+            addLearnEgressAclTableMissFlow(dpnId);
         }
     }
 
@@ -191,6 +200,109 @@ public class AclNodeListener extends AsyncDataTreeChangeListenerBase<FlowCapable
         LOG.debug("Added Ingress ACL Table Miss Flows for dpn {}", dpId);
     }
 
+    private void addLearnEgressAclTableMissFlow(BigInteger dpId) {
+        List<InstructionInfo> mkInstructions = new ArrayList<>();
+        List<ActionInfo> actionsInfos = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
+                new String[] {Short.toString(NwConstants.EGRESS_LEARN_TABLE) }));
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
+                new String[] {Short.toString(NwConstants.EGRESS_LEARN2_TABLE) }));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        List<MatchInfo> mkMatches = new ArrayList<>();
+        FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_ACL_TABLE,
+                "RESUB-" + getTableMissFlowId(NwConstants.EGRESS_ACL_TABLE),
+                AclConstants.PROTO_MATCH_PRIORITY, "Egress resubmit ACL Table Block", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(doubleResubmitTable);
+
+        mkMatches = new ArrayList<>();
+        mkInstructions = new ArrayList<>();
+        actionsInfos = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN_TABLE,
+                "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN_TABLE), 0,
+                "Egress Learn ACL Table Miss Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+
+        flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
+                "LEARN-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE), 0,
+                "Egress Learn2 ACL Table Miss Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+
+        List<NxMatchInfo> nxMkMatches = new ArrayList<>();
+        nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
+                new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
+
+        short dispatcherTableId = NwConstants.EGRESS_LPORT_DISPATCHER_TABLE;
+        List<InstructionInfo> instructions = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
+        instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.EGRESS_LEARN2_TABLE,
+                "LEARN2-REG-" + getTableMissFlowId(NwConstants.EGRESS_LEARN2_TABLE),
+                AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
+        mdsalManager.installFlow(flowEntity);
+        LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
+    }
+
+    private void addLearnIngressAclTableMissFlow(BigInteger dpId) {
+        List<InstructionInfo> mkInstructions = new ArrayList<>();
+        List<ActionInfo> actionsInfos = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
+                new String[] {Short.toString(NwConstants.INGRESS_LEARN_TABLE) }));
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit,
+                new String[] {Short.toString(NwConstants.INGRESS_LEARN2_TABLE) }));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        List<MatchInfo> mkMatches = new ArrayList<>();
+        FlowEntity doubleResubmitTable = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_ACL_TABLE,
+                "RESUB-" + getTableMissFlowId(NwConstants.INGRESS_ACL_TABLE),
+                AclConstants.PROTO_MATCH_PRIORITY, "Ingress resubmit ACL Table Block", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(doubleResubmitTable);
+
+        mkMatches = new ArrayList<>();
+        mkInstructions = new ArrayList<>();
+        actionsInfos = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[] {}));
+        mkInstructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN_TABLE,
+                "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN_TABLE), 0,
+                "Ingress Learn ACL Table Miss Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+
+        flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
+                "LEARN-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE), 0,
+                "Ingress Learn2 ACL Table Miss Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, mkMatches, mkInstructions);
+        mdsalManager.installFlow(flowEntity);
+
+        List<NxMatchInfo> nxMkMatches = new ArrayList<>();
+        nxMkMatches.add(new NxMatchInfo(NxMatchFieldType.nxm_reg_6,
+                new long[] {Long.valueOf(AclConstants.LEARN_MATCH_REG_VALUE)}));
+
+        short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE;
+        List<InstructionInfo> instructions = new ArrayList<>();
+        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)}));
+        instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
+
+        flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.INGRESS_LEARN2_TABLE,
+                "LEARN2-REG-" + getTableMissFlowId(NwConstants.INGRESS_LEARN2_TABLE),
+                AclConstants.PROTO_MATCH_PRIORITY, "Egress Learn2 ACL Table match reg Flow", 0, 0,
+                AclConstants.COOKIE_ACL_BASE, nxMkMatches, instructions);
+        mdsalManager.installFlow(flowEntity);
+        LOG.debug("Added learn ACL Table Miss Flows for dpn {}", dpId);
+
+    }
+
     /**
      * Adds the ingress acl table transparent flow.
      *
index f91e73a85b93db45c3aa2f94b5a18d40f1260016..77c783b64b257f521e86ee34f92f5792e6ccc1cd 100644 (file)
@@ -9,6 +9,9 @@
 package org.opendaylight.netvirt.aclservice.utils;
 
 import java.math.BigInteger;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
 
 /**
@@ -68,11 +71,33 @@ public final class AclConstants {
     public static final int ICMPV6_TYPE_NA = 136;
     public static final int ICMPV6_TYPE_MLD2_REPORT = 143;
 
+    public static final BigInteger METADATA_MASK_LEARN_FLAG = new BigInteger("FFFFFFFFFFFFFFFE", 16);
+
+    public static final String SECURITY_GROUP_TCP_IDLE_TO_KEY = "security-group-tcp-idle-timeout";
+    public static final String SECURITY_GROUP_TCP_HARD_TO_KEY = "security-group-tcp-hard-timeout";
+    public static final String SECURITY_GROUP_TCP_FIN_IDLE_TO_KEY = "security-group-tcp-fin-idle-timeout";
+    public static final String SECURITY_GROUP_TCP_FIN_HARD_TO_KEY = "security-group-tcp-fin-hard-timeout";
+    public static final String SECURITY_GROUP_UDP_IDLE_TO_KEY = "security-group-udp-idle-timeout";
+    public static final String SECURITY_GROUP_UDP_HARD_TO_KEY = "security-group-udp-hard-timeout";
+
+    public static final String LEARN_MATCH_REG_VALUE = "1";
+
     private AclConstants() {
     }
 
-    public static boolean isStatelessAcl() {
-        final String enabledPropertyStr = ConfigProperties.getProperty(AclConstants.class, "stateless.sg.enabled");
-        return enabledPropertyStr != null && enabledPropertyStr.equalsIgnoreCase("yes");
+    private static Map<String, Object> globalConf = Collections.synchronizedMap(new HashMap<>());
+
+    public static String getGlobalConf(String key, String defaultValue) {
+        String ret = defaultValue;
+        String value = (String)globalConf.get(key);
+        if (value == null) {
+            String propertyStr = ConfigProperties.getProperty(AclConstants.class, key);
+            if (propertyStr != null) {
+                ret = propertyStr;
+            }
+            globalConf.put(key, ret);
+        }
+        return ret;
     }
+
 }
index e7bdd956b5208f07989fd54a604e9d77d7fd43de..21b29fa4c3a584649bda7bfaa429560592be894d 100644 (file)
@@ -18,6 +18,7 @@ module aclservice-config {
                 enum "transparent";
                 enum "stateless";
                 enum "stateful";
+                enum "learn";
             }
         }
     }
diff --git a/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImplTest.java b/vpnservice/aclservice/impl/src/test/java/org/opendaylight/netvirt/aclservice/LearnEgressAclServiceImplTest.java
new file mode 100644 (file)
index 0000000..1bdc609
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netvirt.aclservice;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import java.math.BigInteger;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.genius.mdsalutil.ActionType;
+import org.opendaylight.genius.mdsalutil.FlowEntity;
+import org.opendaylight.genius.mdsalutil.MatchFieldType;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
+import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceTestUtils;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
+import org.opendaylight.netvirt.aclservice.utils.MethodInvocationParamSaver;
+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.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.AclKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.AceBuilder;
+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.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160218.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
+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.DirectionEgress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttrBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairsBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+@RunWith(MockitoJUnitRunner.class)
+public class LearnEgressAclServiceImplTest {
+
+    private LearnEgressAclServiceImpl testedService;
+
+    @Mock
+    DataBroker dataBroker;
+    @Mock
+    IMdsalApiManager mdsalManager;
+    @Mock
+    WriteTransaction mockWriteTx;
+    @Mock
+    ReadOnlyTransaction mockReadTx;
+
+    MethodInvocationParamSaver<Void> installFlowValueSaver = null;
+    MethodInvocationParamSaver<Void> removeFlowValueSaver = null;
+
+    @Before
+    public void setUp() {
+        testedService = new LearnEgressAclServiceImpl(dataBroker, mdsalManager);
+        doReturn(Futures.immediateCheckedFuture(null)).when(mockWriteTx).submit();
+        doReturn(mockReadTx).when(dataBroker).newReadOnlyTransaction();
+        doReturn(mockWriteTx).when(dataBroker).newWriteOnlyTransaction();
+        installFlowValueSaver = new MethodInvocationParamSaver<Void>(null);
+        doAnswer(installFlowValueSaver).when(mdsalManager).installFlow(any(FlowEntity.class));
+        removeFlowValueSaver = new MethodInvocationParamSaver<Void>(null);
+        doAnswer(installFlowValueSaver).when(mdsalManager).removeFlow(any(FlowEntity.class));
+
+    }
+
+    @Test
+    public void addAcl__NullInterface() {
+        assertEquals(false, testedService.applyAcl(null));
+    }
+
+    @Test
+    public void addAcl__MissingInterfaceStateShouldFail() throws Exception {
+        AclInterface ai = new AclInterface();
+        ai.setPortSecurityEnabled(true);
+        ai.setDpId(BigInteger.ONE);
+        assertEquals(false, testedService.applyAcl(ai));
+    }
+
+    @Test
+    public void addAcl__SinglePort() throws Exception {
+        Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
+        AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
+        assertEquals(true, testedService.applyAcl(ai));
+        assertEquals(4, installFlowValueSaver.getNumOfInvocations());
+
+        FlowEntity flow = (FlowEntity) installFlowValueSaver.getInvocationParams(3).get(0);
+        AclServiceTestUtils.verifyMatchInfo(flow.getMatchInfoList(),
+                NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65535");
+        AclServiceTestUtils.verifyActionTypeExist(flow.getInstructionInfoList().get(0).getActionInfos(),
+                ActionType.learn);
+
+    }
+
+    @Test
+    public void addAcl__AllowAll() throws Exception {
+        Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
+        AclInterface ai = stubAllowAllInterface(sgUuid, "if_name");
+        assertEquals(true, testedService.applyAcl(ai));
+        assertEquals(4, installFlowValueSaver.getNumOfInvocations());
+
+        FlowEntity flow = (FlowEntity) installFlowValueSaver.getInvocationParams(3).get(0);
+        AclServiceTestUtils.verifyActionTypeExist(flow.getInstructionInfoList().get(0).getActionInfos(),
+                ActionType.learn);
+    }
+
+    @Test
+    public void addAcl__MultipleRanges() throws Exception {
+        Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
+        AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 84);
+        assertEquals(true, testedService.applyAcl(ai));
+        assertEquals(5, installFlowValueSaver.getNumOfInvocations());
+        FlowEntity firstRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(3).get(0);
+        AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
+                NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65532");
+
+        FlowEntity secondRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(4).get(0);
+        AclServiceTestUtils.verifyMatchInfo(secondRangeFlow.getMatchInfoList(),
+                NxMatchFieldType.nx_tcp_dst_with_mask, "84", "65535");
+    }
+
+    @Test
+    public void addAcl__UdpSinglePortShouldNotCreateSynRule() throws Exception {
+        Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
+        AclInterface ai = stubUdpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
+        assertEquals(true, testedService.applyAcl(ai));
+        assertEquals(4, installFlowValueSaver.getNumOfInvocations());
+        FlowEntity flow = (FlowEntity) installFlowValueSaver.getInvocationParams(3).get(0);
+        AclServiceTestUtils.verifyMatchInfo(flow.getMatchInfoList(),
+                NxMatchFieldType.nx_udp_dst_with_mask, "80", "65535");
+        AclServiceTestUtils.verifyActionTypeExist(flow.getInstructionInfoList().get(0).getActionInfos(),
+                ActionType.learn);
+    }
+
+    @Test
+    @Ignore
+    public void removeAcl__SinglePort() throws Exception {
+        Uuid sgUuid = new Uuid("12345678-1234-1234-1234-123456789012");
+        AclInterface ai = stubTcpAclInterface(sgUuid, "if_name", "1.1.1.1/32", 80, 80);
+        assertEquals(true, testedService.removeAcl(ai));
+        assertEquals(1, removeFlowValueSaver.getNumOfInvocations());
+        FlowEntity firstRangeFlow = (FlowEntity) removeFlowValueSaver.getInvocationParams(0).get(0);
+        AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(), MatchFieldType.tcp_flags, "2");
+        AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
+                NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65535");
+
+    }
+
+    private AclInterface stubUdpAclInterface(Uuid sgUuid, String ifName, String ipv4PrefixStr,
+            int tcpPortLower, int tcpPortUpper) {
+        AclInterface ai = new AclInterface();
+        ai.setPortSecurityEnabled(true);
+        ai.setSecurityGroups(Arrays.asList(sgUuid));
+        ai.setDpId(BigInteger.ONE);
+        ai.setLPortTag(new Integer(2));
+        stubInterfaceAcl(ifName, ai);
+
+        stubAccessList(sgUuid, ipv4PrefixStr, tcpPortLower, tcpPortUpper, (short)NwConstants.IP_PROT_UDP);
+        return ai;
+    }
+
+    private AclInterface stubTcpAclInterface(Uuid sgUuid, String ifName, String ipv4PrefixStr,
+            int tcpPortLower, int tcpPortUpper) {
+        AclInterface ai = new AclInterface();
+        ai.setPortSecurityEnabled(true);
+        ai.setDpId(BigInteger.ONE);
+        ai.setLPortTag(Integer.valueOf(2));
+        ai.setSecurityGroups(Arrays.asList(sgUuid));
+        stubInterfaceAcl(ifName, ai);
+
+        stubAccessList(sgUuid, ipv4PrefixStr, tcpPortLower, tcpPortUpper, (short)NwConstants.IP_PROT_TCP);
+        return ai;
+    }
+
+    private void stubInterfaceAcl(String ifName, AclInterface ai) {
+        AllowedAddressPairsBuilder aapb = new AllowedAddressPairsBuilder();
+        aapb.setIpAddress(new IpPrefixOrAddress("1.1.1.1/32".toCharArray()));
+        aapb.setMacAddress(new MacAddress("AA:BB:CC:DD:EE:FF"));
+        ai.setAllowedAddressPairs(Arrays.asList(aapb.build()));
+    }
+
+    private AclInterface stubAllowAllInterface(Uuid sgUuid, String ifName) {
+        AclInterface ai = new AclInterface();
+        ai.setPortSecurityEnabled(true);
+        ai.setSecurityGroups(Arrays.asList(sgUuid));
+        ai.setDpId(BigInteger.ONE);
+        ai.setLPortTag(new Integer(2));
+        stubInterfaceAcl(ifName, ai);
+
+        stubAccessList(sgUuid, null, -1, -1, (short)-1);
+        return ai;
+    }
+
+    private void stubAccessList(Uuid sgUuid, String ipv4PrefixStr, int portLower, int portUpper, short protocol) {
+        AclBuilder ab = new AclBuilder();
+        ab.setAclName("AAA");
+        ab.setKey(new AclKey(sgUuid.getValue(),Ipv4Acl.class));
+
+        AceIpBuilder aceIpBuilder = new AceIpBuilder();
+        if (portLower != -1 && portUpper != -1) {
+            DestinationPortRangeBuilder dprb = new DestinationPortRangeBuilder();
+            dprb.setLowerPort(new PortNumber(portLower));
+            dprb.setUpperPort(new PortNumber(portUpper));
+            aceIpBuilder.setDestinationPortRange(dprb.build());
+        }
+        if (ipv4PrefixStr != null) {
+            AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
+            Ipv4Prefix ipv4Prefix = new Ipv4Prefix(ipv4PrefixStr);
+            aceIpv4Builder.setSourceIpv4Network(ipv4Prefix);
+            aceIpBuilder.setAceIpVersion(aceIpv4Builder.build());
+        }
+        if (protocol != -1) {
+            aceIpBuilder.setProtocol(protocol);
+        }
+        MatchesBuilder matches = new MatchesBuilder();
+        matches.setAceType(aceIpBuilder.build());
+        AceBuilder aceBuilder = new AceBuilder();
+        aceBuilder.setMatches(matches.build());
+        SecurityRuleAttrBuilder securityRuleAttrBuilder = new SecurityRuleAttrBuilder();
+        securityRuleAttrBuilder.setDirection(DirectionEgress.class);
+        aceBuilder.addAugmentation(SecurityRuleAttr.class, securityRuleAttrBuilder.build());
+        AccessListEntriesBuilder aleb = new AccessListEntriesBuilder();
+        aleb.setAce(Arrays.asList(aceBuilder.build()));
+        ab.setAccessListEntries(aleb.build());
+
+        InstanceIdentifier<Acl> aclKey = AclServiceUtils.getAclInstanceIdentifier(sgUuid.getValue());
+        when(mockReadTx.read(LogicalDatastoreType.CONFIGURATION, aclKey))
+            .thenReturn(Futures.immediateCheckedFuture(Optional.of(ab.build())));
+    }
+}
index 48542452e883dce330e825810078082d33ca941c..78eab005fa2bfbb286dc337a072b0cccec6f536d 100644 (file)
@@ -135,8 +135,6 @@ public class StatelessEgressAclServiceImplTest {
         assertEquals(true, testedService.applyAcl(ai));
         assertEquals(2, installFlowValueSaver.getNumOfInvocations());
         FlowEntity firstRangeFlow = (FlowEntity) installFlowValueSaver.getInvocationParams(0).get(0);
-        // should have been 80-83 will be fixed as part of the port range support
-        // https://bugs.opendaylight.org/show_bug.cgi?id=6200
         AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(),
                 NxMatchFieldType.nx_tcp_dst_with_mask, "80", "65532");
         AclServiceTestUtils.verifyMatchInfo(firstRangeFlow.getMatchInfoList(), MatchFieldType.tcp_flags, "2");
index 32a387b41dd6972e0bb4e7bf0ef129b8960ce367..485f41f6eb0c2a938f2831317e55f7db80b9da75 100644 (file)
@@ -201,6 +201,12 @@ public class AclServiceTestUtils {
         AclDataUtil.removeAclInterfaceMap(prapreaAclIds(aclNames), inter);
     }
 
+    public static void verifyActionTypeExist(List<ActionInfo> flowActions, ActionType actionType) {
+        Iterable<ActionInfo> actions = filter(flowActions,
+                (item -> ((ActionInfo) item).getActionType().equals(actionType)));
+        assertFalse(Iterables.isEmpty(actions));
+    }
+
     public static void verifyActionInfo(List<ActionInfo> flowActions, ActionType actionType, String... params) {
         Iterable<ActionInfo> actions = filter(flowActions,
                 (item -> ((ActionInfo) item).getActionType().equals(actionType)));
@@ -224,6 +230,17 @@ public class AclServiceTestUtils {
         }
     }
 
+    public static void verifyLearnActionFlowModInfo(List<ActionInfo> flowActions,
+            NwConstants.LearnFlowModsType type, String... params) {
+        Iterable<ActionInfo> actions = filter(flowActions,
+                (item -> ((ActionInfo) item).getActionType().equals(ActionType.learn)
+                        && ((ActionInfo) item).getActionValuesMatrix()[0].equals(type.name())));
+        assertFalse(Iterables.isEmpty(actions));
+        for (ActionInfo action : actions) {
+            verifyActionValues(action, params);
+        }
+    }
+
     public static void verifyInstructionInfo(List<InstructionInfo> instructionInfoList, InstructionType type,
             String ... params) {
         Iterable<InstructionInfo> matches = filter(instructionInfoList,