Merge "Added Security Rule for Custom ICMP"
[ovsdb.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / providers / openflow13 / services / EgressAclService.java
index 79219d463c1fa42f246079f334c24d0246772ddd..e62ebb05387c5f0a8ca73230438f03b7108e4e39 100644 (file)
@@ -1,12 +1,11 @@
 /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (c) 2014, 2015 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
- *
- * Authors : Madhu Venugopal
  */
+
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import java.math.BigInteger;
@@ -14,14 +13,16 @@ import java.util.List;
 
 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
 import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.neutron.spi.Neutron_IPs;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
-import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
@@ -43,7 +44,11 @@ import com.google.common.collect.Lists;
 
 public class EgressAclService extends AbstractServiceInstance implements EgressAclProvider, ConfigInterface {
 
-    static final Logger logger = LoggerFactory.getLogger(EgressAclService.class);
+    private static final Logger LOG = LoggerFactory.getLogger(EgressAclService.class);
+    private volatile SecurityServicesManager securityServicesManager;
+    private static final int DHCP_SOURCE_PORT = 67;
+    private static final int DHCP_DESTINATION_PORT = 68;
+    private static final String HOST_MASK = "/32";
 
     public EgressAclService() {
         super(Service.EGRESS_ACL);
@@ -54,37 +59,102 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     }
 
     @Override
-    public void programPortSecurityACL(Long dpid, String segmentationId, String attachedMac, long localPort,
-                                       NeutronSecurityGroup securityGroup) {
+    public void programPortSecurityAcl(Long dpid, String segmentationId, String attachedMac, long localPort,
+                                       NeutronSecurityGroup securityGroup,
+                                       List<Neutron_IPs> srcAddressList, boolean write) {
+
+        LOG.trace("programPortSecurityAcl: neutronSecurityGroup: {} ", securityGroup);
+        if (securityGroup == null || securityGroup.getSecurityRules() == null) {
+            return;
+        }
 
-        logger.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
         List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
         /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
         for (NeutronSecurityRule portSecurityRule : portSecurityList) {
             /**
-             * Neutron Port Security ACL "egress" and "IPv4"
-             *
+             * Neutron Port Security Acl "egress" and "IPv4"
              * Check that the base conditions for flow based Port Security are true:
              * Port Security Rule Direction ("egress") and Protocol ("IPv4")
              * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
              * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
              *
              */
-            if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
+            if (portSecurityRule.getSecurityRuleEthertype().equals("IPv4")
+                    && portSecurityRule.getSecurityRuleDirection().equals("egress")) {
+                LOG.debug("programPortSecurityAcl: Acl Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+                if (null == portSecurityRule.getSecurityRuleProtocol()) {
+                    /* TODO Rework on the priority values */
+                    egressAclIPv4(dpid, segmentationId, attachedMac,
+                                  write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                } else if (null != portSecurityRule.getSecurityRemoteGroupID()) {
+                  //Remote Security group is selected
+                    List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
+                            .getVmListForSecurityGroup(srcAddressList,portSecurityRule.getSecurityRemoteGroupID());
+                    if (null != remoteSrcAddressList) {
+                        for (Neutron_IPs vmIp :remoteSrcAddressList ) {
+                            switch (portSecurityRule.getSecurityRuleProtocol()) {
+                            case MatchUtils.TCP:
+                                egressAclTcp(dpid, segmentationId, attachedMac,
+                                             portSecurityRule,vmIp.getIpAddress(), write,
+                                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                                break;
+                            case MatchUtils.UDP:
+                                egressAclUdp(dpid, segmentationId, attachedMac,
+                                             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;
+                            }
+                        }
+                    }
+                } else {
+                    //CIDR is selected
+                    switch (portSecurityRule.getSecurityRuleProtocol()) {
+                    case MatchUtils.TCP:
+                        egressAclTcp(dpid, segmentationId, attachedMac,
+                                     portSecurityRule, null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                        break;
+                    case MatchUtils.UDP:
+                        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);
+                    }
+                }
+            }
+            /*
+             * Code is refactored to handle all the protocols. More
+             * protocols  will be added incrementrally
+             * TODO Connection tracking will be used to track active TCP connections This code
+             * may be reused then.
+             */
+            /* if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
                 portSecurityRule.getSecurityRuleDirection().equalsIgnoreCase("egress")) {
-                logger.debug("Egress IPV4 ACL  Port Security Rule: {} ", portSecurityRule);
+                LOG.debug("Egress IPV4 ACL  Port Security Rule: {} ", portSecurityRule);
                 // ToDo: Implement Port Range
 
-                /**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
-                 */
+             *//**
+             * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
+             *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
                      !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
                              .equalsIgnoreCase("0.0.0.0/0"))) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #1 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -98,16 +168,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                     continue;
                 }
-                /**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
-                 */
+              *//**
+              * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
+              *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
                      !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
                              .equalsIgnoreCase("0.0.0.0/0"))) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #2 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -121,14 +191,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
                     continue;
                 }
-                /**
-                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-                 */
+               *//**
+               * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+               *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #3 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -139,16 +209,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                             portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PROTO_PREFIX_MATCH_PRIORITY);
                     continue;
                 }
-                /**
-                 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
-                 */
+                *//**
+                * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+                *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
                      !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
                              .equalsIgnoreCase("0.0.0.0/0"))) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #4 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -158,14 +228,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                             portSecurityRule.getSecurityRuleRemoteIpPrefix(), Constants.PREFIX_MATCH_PRIORITY);
                     continue;
                 }
-                /**
+                 *//**
                  * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
-                 */
+                 *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #5 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -177,14 +247,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                     Constants.PROTO_PORT_MATCH_PRIORITY);
                     continue;
                 }
-                /**
-                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
-                 */
+                  *//**
+                  * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
+                  *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #6 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -195,16 +265,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                     portSecurityRule.getSecurityRulePortMin(), Constants.PROTO_PORT_MATCH_PRIORITY);
                     continue;
                 }
-                /**
-                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
-                 */
+                   *//**
+                   * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
+                   *//*
                 if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
                     String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
                     ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
                      String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
                              .equalsIgnoreCase("0.0.0.0/0"))) {
-                    logger.debug(
+                    LOG.debug(
                             "Rule #7 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
                             portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
                             portSecurityRule.getSecurityRulePortMax(),
@@ -215,11 +285,176 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                      portSecurityRule.getSecurityRuleProtocol(), Constants.PROTO_MATCH_PRIORITY);
                     continue;
                 }
-                logger.debug("ACL Match combination not found for rule: {}", portSecurityRule);
+                LOG.debug("ACL Match combination not found for rule: {}", portSecurityRule);
+            }*/
+        }
+    }
+
+    @Override
+    public void programFixedSecurityAcl(Long dpid, String segmentationId, String attachedMac,
+                                        long localPort, List<Neutron_IPs> srcAddressList,
+                                        boolean isLastPortinBridge, boolean isComputePort ,boolean write) {
+        // If it is the only port in the bridge add the rule to allow any DHCP client traffic
+        if (isLastPortinBridge) {
+            egressAclDhcpAllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
+        }
+        if (isComputePort) {
+            // add rule to drop the DHCP server traffic originating from the vm.
+            egressAclDhcpDropServerTrafficfromVm(dpid, localPort, write,
+                                                 Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
+            //Adds rule to check legitimate ip/mac pair for each packet from the vm
+            for (Neutron_IPs srcAddress : srcAddressList) {
+                String addressWithPrefix = srcAddress.getIpAddress() + HOST_MASK;
+                egressAclAllowTrafficFromVmIpMacPair(dpid, localPort, attachedMac, addressWithPrefix,
+                                                     Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
             }
         }
     }
 
+    /**
+     * Allows IPv4 packet egress from the src mac address.
+     * @param dpidLong the dpid
+     * @param segmentationId the segementation id
+     * @param srcMac the src mac address
+     * @param write add or remove
+     * @param protoPortMatchPriority the protocol match priority.
+     */
+    private void egressAclIPv4(Long dpidLong, String segmentationId, String srcMac,
+                               boolean write, Integer protoPortMatchPriority ) {
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+        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 destination IP address
+     * @param write add or delete
+     * @param protoPortMatchPriority the protocol match priroty
+     */
+    private void egressAclTcp(Long dpidLong, String segmentationId, String srcMac,
+                              NeutronSecurityRule portSecurityRule, String dstAddress,
+                              boolean write, Integer protoPortMatchPriority) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowId = "Egress_Custom_Tcp" + segmentationId + "_" + srcMac + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+        if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
+                                                     portSecurityRule.getSecurityRulePortMin());
+        } else {
+            /*TODO TCP PortRange Match*/
+
+        }
+
+        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()));
+        }
+        flowId = flowId + "_Permit_";
+        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
+     * 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
+     * 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 priroty
+     */
+    private void egressAclUdp(Long dpidLong, String segmentationId, String srcMac,
+                              NeutronSecurityRule portSecurityRule, String dstAddress,
+                              boolean write, Integer protoPortMatchPriority) {
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowId = "Eress_UDP" + segmentationId + "_" + srcMac + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
+        if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+            flowId = flowId + portSecurityRule.getSecurityRulePortMin();
+            matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
+                                                     portSecurityRule.getSecurityRulePortMin());
+        } else {
+            /*TODO UDP PortRange Match*/
+
+        }
+
+        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()));
+        }
+        flowId = flowId + "_Permit_";
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+    }
     public void egressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
                                         int priority, boolean write) {
 
@@ -230,7 +465,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         flowBuilder.setMatch(MatchUtils.createSmacTcpPortWithFlagMatch(matchBuilder,
                                                                        attachedMac, Constants.TCP_SYN, segmentationId).build());
-        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
 
         String flowId = "TCP_Syn_Egress_Default_Drop_" + segmentationId + "_" + attachedMac;
         flowBuilder.setId(new FlowId(flowId));
@@ -257,7 +492,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             // Add InstructionBuilder to the Instruction(s)Builder List
             isb.setInstruction(instructions);
 
-            logger.debug("Instructions contain: {}", ib.getInstruction());
+            LOG.debug("Instructions contain: {}", ib.getInstruction());
             // Add InstructionsBuilder to FlowBuilder
             flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
@@ -277,12 +512,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
 
         flowBuilder.setMatch(MatchUtils
-                                     .createSmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
-                                                                         tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
+                             .createSmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
+                                                                 tcpPort, Constants.TCP_SYN, segmentationId, srcIpPrefix).build());
 
-        logger.debug(" MatchBuilder contains:  {}", flowBuilder.getMatch());
+        LOG.debug(" MatchBuilder contains:  {}", flowBuilder.getMatch());
         String flowId = "UcastEgress_" + segmentationId + "_" + attachedMac +
-                        securityRulePortMin + securityRuleIpPrefix;
+                securityRulePortMin + securityRuleIpPrefix;
         // Add Flow Attributes
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
@@ -297,17 +532,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         if (write) {
             // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
             InstructionsBuilder isb = new InstructionsBuilder();
             List<Instruction> instructionsList = Lists.newArrayList();
 
-            ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
             ib.setOrder(0);
             ib.setKey(new InstructionKey(0));
             instructionsList.add(ib.build());
             isb.setInstruction(instructionsList);
 
-            logger.debug("Instructions contain: {}", ib.getInstruction());
+            LOG.debug("Instructions contain: {}", ib.getInstruction());
             // Add InstructionsBuilder to FlowBuilder
             flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
@@ -327,13 +561,13 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         FlowBuilder flowBuilder = new FlowBuilder();
 
         flowBuilder.setMatch(MatchUtils
-                                     .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
+                             .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
         flowBuilder.setMatch(MatchUtils
-                                     .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+                             .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
 
-        logger.debug("MatchBuilder contains:  {}", flowBuilder.getMatch());
+        LOG.debug("MatchBuilder contains:  {}", flowBuilder.getMatch());
         String flowId = "EgressAllProto_" + segmentationId + "_" +
-                        attachedMac + "_AllowEgressTCPSyn_" + securityRuleProtcol;
+                attachedMac + "_AllowEgressTCPSyn_" + securityRuleProtcol;
         // Add Flow Attributes
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
@@ -348,17 +582,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         if (write) {
             // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
             InstructionsBuilder isb = new InstructionsBuilder();
             List<Instruction> instructionsList = Lists.newArrayList();
 
-            ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
             ib.setOrder(0);
             ib.setKey(new InstructionKey(0));
             instructionsList.add(ib.build());
             isb.setInstruction(instructionsList);
 
-            logger.debug("Instructions contain: {}", ib.getInstruction());
+            LOG.debug("Instructions contain: {}", ib.getInstruction());
             // Add InstructionsBuilder to FlowBuilder
             flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
@@ -371,25 +604,25 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                         boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
 
         String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
-        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
         MatchBuilder matchBuilder = new MatchBuilder();
         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         FlowBuilder flowBuilder = new FlowBuilder();
 
         flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
-                                     .build());
+                             .build());
         if (securityRuleIpPrefix != null) {
+            Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
             flowBuilder.setMatch(MatchUtils
-                                         .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
-                                         .build());
+                                 .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
+                                 .build());
         } else {
             flowBuilder.setMatch(MatchUtils
-                                         .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
-                                         .build());
+                                 .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
+                                 .build());
         }
-        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
         String flowId = "Egress_Proto_ACL" + segmentationId + "_" +
-                        attachedMac + "_Permit_" + securityRuleIpPrefix;
+                attachedMac + "_Permit_" + securityRuleIpPrefix;
         // Add Flow Attributes
         flowBuilder.setId(new FlowId(flowId));
         FlowKey key = new FlowKey(new FlowId(flowId));
@@ -404,17 +637,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         if (write) {
             // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
             InstructionsBuilder isb = new InstructionsBuilder();
             List<Instruction> instructionsList = Lists.newArrayList();
 
-            ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
             ib.setOrder(0);
             ib.setKey(new InstructionKey(0));
             instructionsList.add(ib.build());
             isb.setInstruction(instructionsList);
 
-            logger.debug("Instructions contain: {}", ib.getInstruction());
+            LOG.debug("Instructions contain: {}", ib.getInstruction());
             // Add InstructionsBuilder to FlowBuilder
             flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
@@ -436,7 +668,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         flowBuilder.setMatch(MatchUtils.createSmacTcpSyn(matchBuilder, attachedMac, tcpPort,
                                                          Constants.TCP_SYN, segmentationId).build());
 
-        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        LOG.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
         String flowId = "Ucast_this.getTable()" + segmentationId + "_" + attachedMac + securityRulePortMin;
         // Add Flow Attributes
         flowBuilder.setId(new FlowId(flowId));
@@ -452,17 +684,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         if (write) {
             // Instantiate the Builders for the OF Actions and Instructions
-            InstructionBuilder ib = new InstructionBuilder();
             InstructionsBuilder isb = new InstructionsBuilder();
             List<Instruction> instructionsList = Lists.newArrayList();
 
-            ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
             ib.setOrder(0);
             ib.setKey(new InstructionKey(0));
             instructionsList.add(ib.build());
             isb.setInstruction(instructionsList);
 
-            logger.debug("Instructions contain: {}", ib.getInstruction());
+            LOG.debug("Instructions contain: {}", ib.getInstruction());
             // Add InstructionsBuilder to FlowBuilder
             flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
@@ -471,9 +702,127 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         }
     }
 
+    /**
+     * Adds flow to allow any DHCP client traffic.
+     *
+     * @param dpidLong the dpid
+     * @param write whether to write or delete the flow
+     * @param protoPortMatchPriority the priority
+     */
+    private void egressAclDhcpAllowClientTrafficFromVm(Long dpidLong,
+                                                       boolean write, Integer protoPortMatchPriority) {
+
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+
+        MatchUtils.createDhcpMatch(matchBuilder, DHCP_DESTINATION_PORT, DHCP_SOURCE_PORT).build();
+        LOG.debug("egressAclDHCPAllowClientTrafficFromVm: MatchBuilder contains: {}", matchBuilder);
+        String flowId = "Egress_DHCP_Client"  + "_Permit_";
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+    }
+
+    /**
+     * Adds rule to prevent DHCP spoofing by the vm attached to the port.
+     *
+     * @param dpidLong the dpid
+     * @param localPort the local port
+     * @param write is write or delete
+     * @param protoPortMatchPriority  the priority
+     */
+    private void egressAclDhcpDropServerTrafficfromVm(Long dpidLong, long localPort,
+                                                      boolean write, Integer protoPortMatchPriority) {
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        //FlowBuilder flowBuilder = new FlowBuilder();
+        MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        MatchUtils.createDhcpMatch(matchBuilder, DHCP_SOURCE_PORT, DHCP_DESTINATION_PORT).build();
+        LOG.debug("egressAclDHCPDropServerTrafficfromVM: MatchBuilder contains: {}", matchBuilder);
+        String flowId = "Egress_DHCP_Server" + "_" + localPort + "_DROP_";
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, true);
+
+    }
+
+    /**
+     * Adds rule to check legitimate ip/mac pair for each packet from the vm.
+     *
+     * @param dpidLong the dpid
+     * @param localPort the local port
+     * @param srcIp the vm ip address
+     * @param attachedMac the vm mac address
+     * @param protoPortMatchPriority  the priority
+     * @param write is write or delete
+     */
+    private void egressAclAllowTrafficFromVmIpMacPair(Long dpidLong, long localPort,
+                                                      String attachedMac, String srcIp,
+                                                      Integer protoPortMatchPriority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        MatchUtils.createSrcL3Ipv4MatchWithMac(matchBuilder, new Ipv4Prefix(srcIp),new MacAddress(attachedMac));
+        MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        LOG.debug("egressAclAllowTrafficFromVmIpMacPair: MatchBuilder contains: {}", matchBuilder);
+        String flowId = "Egress_Allow_VM_IP_MAC" + "_" + localPort + attachedMac + "_Permit_";
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong;
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+
+    }
+
+    /**
+     * Add or remove flow to the node.
+     *
+     * @param flowId the the flow id
+     * @param nodeBuilder the node builder
+     * @param matchBuilder the matchbuilder
+     * @param protoPortMatchPriority the protocol priority
+     * @param write whether it is a write
+     * @param drop whether it is a drop or forward
+     */
+    private void syncFlow(String flowId, NodeBuilder nodeBuilder,
+                          MatchBuilder matchBuilder,Integer protoPortMatchPriority,
+                          boolean write,boolean drop) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(this.getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+
+            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+            if (drop) {
+                InstructionUtils.createDropInstructions(ib);
+            }
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+
+    }
+
+
+
     @Override
     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
-        super.setOrchestrator(bundleContext.getServiceReference(EgressAclProvider.class.getName()), this);
+        super.setDependencies(bundleContext.getServiceReference(EgressAclProvider.class.getName()), this);
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
     }
 
     @Override