Merge "Added Security Rule for Custom ICMP"
authorSam Hague <shague@redhat.com>
Mon, 28 Sep 2015 12:51:01 +0000 (12:51 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 28 Sep 2015 12:51:02 +0000 (12:51 +0000)
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclService.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclServiceTest.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java

index 8ae8fab07d2ebf68d4e965c8f14f77799b89fee2..e62ebb05387c5f0a8ca73230438f03b7108e4e39 100644 (file)
@@ -103,6 +103,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                              portSecurityRule,vmIp.getIpAddress(), write,
                                              Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                                 break;
+                            case MatchUtils.ICMP:
+                                egressAclIcmp(dpid, segmentationId, attachedMac,
+                                               portSecurityRule, vmIp.getIpAddress(),write,
+                                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                                break;
                             default:
                                 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
                                 break;
@@ -120,6 +125,10 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                         egressAclUdp(dpid, segmentationId, attachedMac,
                                      portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                         break;
+                    case MatchUtils.ICMP:
+                        egressAclIcmp(dpid, segmentationId, attachedMac,
+                                       portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                        break;
                     default:
                         LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
                     }
@@ -364,6 +373,43 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
 
     }
+
+    /**
+     * Creates a egress match with src macaddress. If dest address is specified
+     * destination specific match will be created. Otherwise a match with a
+     * CIDR will be created.
+     * @param dpidLong the dpid
+     * @param segmentationId the segmentation id
+     * @param srcMac the source mac address.
+     * @param portSecurityRule the security rule in the SG
+     * @param dstAddress the source IP address
+     * @param write add or delete
+     * @param protoPortMatchPriority the protocol match priority
+     */
+    private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
+                               NeutronSecurityRule portSecurityRule, String dstAddress,
+                               boolean write, Integer protoPortMatchPriority) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowId = "Egress_ICMP" + segmentationId + "_" + srcMac + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+        matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+                                                    portSecurityRule.getSecurityRulePortMin().shortValue(),
+                                                    portSecurityRule.getSecurityRulePortMax().shortValue());
+        if (null != dstAddress) {
+            flowId = flowId + dstAddress;
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                    MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                    new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+        }
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+    }
+
     /**
      * Creates a egress match with src macaddress. If dest address is specified
      * destination specific match will be created. Otherwise a match with a
index 2201374b20aff722e87886230002055c1f178490..2e8cd8533d5b0d39a6e1f003757dbeda3ae330d9 100644 (file)
@@ -98,6 +98,10 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                                 ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule,vmIp.getIpAddress(),
                                               write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                                 break;
+                            case MatchUtils.ICMP:
+                                ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, vmIp.getIpAddress(),
+                                               write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                                break;
                             default:
                                 LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
                                 break;
@@ -115,6 +119,10 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                         ingressAclUdp(dpid, segmentationId, attachedMac,
                                       portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                         break;
+                    case MatchUtils.ICMP:
+                        ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, null,
+                                       write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                        break;
                     default:
                         LOG.error("programPortSecurityAcl: Protocol not supported", portSecurityRule);
                     }
@@ -377,6 +385,45 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
 
     }
 
+    /**
+     * Creates a ingress match to the dst macaddress. If src address is specified
+     * source specific match will be created. Otherwise a match with a CIDR will
+     * be created.
+     * @param dpidLong the dpid
+     * @param segmentationId the segmentation id
+     * @param dstMac the destination mac address.
+     * @param portSecurityRule the security rule in the SG
+     * @param srcAddress the destination IP address
+     * @param write add or delete
+     * @param protoPortMatchPriority the protocol match priority
+     */
+    private void ingressAclIcmp(Long dpidLong, String segmentationId, String dstMac,
+                                NeutronSecurityRule portSecurityRule, String srcAddress,
+                                boolean write, Integer protoPortMatchPriority) {
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        FlowBuilder flowBuilder = new FlowBuilder();
+        String flowId = "ingressAclICMP" + segmentationId + "_" + dstMac;
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
+        matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
+                        portSecurityRule.getSecurityRulePortMin().shortValue(),
+                        portSecurityRule.getSecurityRulePortMax().shortValue());
+        if (null != srcAddress) {
+            flowId = flowId + srcAddress;
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                    MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+
+        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                    new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+        }
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        flowId = flowId + "_Permit_";
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+    }
+
     public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
                                  Integer securityRulePortMin, Integer protoPortMatchPriority) {
 
index bf6774d19b8d8c9d95e7fedf05389f6aa098326f..b28a1443a05d4221e7f297f5c8bf7b7c4e98ffec 100644 (file)
@@ -435,6 +435,76 @@ public class EgressAclServiceTest {
         verify(commitFuture, times(2)).get();
     }
 
+    /**
+     *  Test ICMP add with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+
+        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+
+        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).get();
+    }
+
+    /**
+     *  Test ICMP remove with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+
+        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+
+        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).get();
+    }
+
+    /**
+     *  Test ICMP add with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+
+        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+
+        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(2)).get();
+    }
+
+    /**
+     *  Test ICMP remove with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+
+        egressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+
+        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(2)).get();
+    }
+
     /**
      *  Test IPv4 invalid ether type test case.
      */
index 6454c7ae4461c33c2464b1cd5d073f39cb357622..34708360daeb02308e3a7210f9b84bf864b7aa83 100644 (file)
@@ -416,6 +416,76 @@ public class IngressAclServiceTest {
         verify(commitFuture, times(2)).get();
     }
 
+    /**
+     *  Test ICMP add with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+
+        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+
+        verify(writeTransaction, times(2)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).get();
+    }
+
+    /**
+     *  Test ICMP remove with code, type and CIDR selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp1() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+
+        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+
+        verify(writeTransaction, times(1)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(1)).submit();
+        verify(commitFuture, times(1)).get();
+    }
+
+    /**
+     *  Test ICMP add with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleAddIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+
+        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,true);
+
+        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(2)).get();
+    }
+
+    /**
+     *  Test ICMP remove with code, type and remote SG selected.
+     */
+    @Test
+    public void testProgramPortSecurityACLRuleRemoveIcmp2() throws Exception {
+        when(portSecurityRule.getSecurityRuleProtocol()).thenReturn("icmp");
+        when(portSecurityRule.getSecurityRulePortMax()).thenReturn(50);
+        when(portSecurityRule.getSecurityRulePortMin()).thenReturn(50);
+        when(portSecurityRule.getSecurityRuleRemoteIpPrefix()).thenReturn("0.0.0.0/24");
+        when(portSecurityRule.getSecurityRemoteGroupID()).thenReturn("85cc3048-abc3-43cc-89b3-377341426ac5");
+
+        ingressAclServiceSpy.programPortSecurityAcl(Long.valueOf(1554), "2", MAC_ADDRESS, 124, securityGroup,neutronSrcIpList,false);
+
+        verify(writeTransaction, times(2)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(2)).submit();
+        verify(commitFuture, times(2)).get();
+    }
+
     /**
      *  Test IPv4 invalid ether type test case.
      */
index 0df0937d2c979b7e7b072dd60a133d5c1ee2103f..cbf49d86ff0690f5aeecd25c5d8640b60c531e7b 100644 (file)
@@ -80,6 +80,7 @@ public class MatchUtils {
     public static final String TCP = "tcp";
     public static final String UDP = "udp";
     private static final int TCP_SYN = 0x0002;
+    public static final String ICMP = "icmp";
 
     /**
      * Create Ingress Port Match dpidLong, inPort