Remove ovsdb related in resources
[netvirt.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / netvirt / openstack / netvirt / providers / openflow13 / services / EgressAclService.java
1 /*
2  * Copyright (c) 2014 - 2016 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
10
11 import com.google.common.collect.Lists;
12
13 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
14 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
15 import org.opendaylight.netvirt.openstack.netvirt.api.EgressAclProvider;
16 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityGroupCacheManger;
17 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
18 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
19 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
20 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
21 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
22 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
23 import org.opendaylight.netvirt.utils.mdsal.openflow.ActionUtils;
24 import org.opendaylight.netvirt.utils.mdsal.openflow.FlowUtils;
25 import org.opendaylight.netvirt.utils.mdsal.openflow.InstructionUtils;
26 import org.opendaylight.netvirt.utils.mdsal.openflow.MatchUtils;
27 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
39 import org.osgi.framework.BundleContext;
40 import org.osgi.framework.ServiceReference;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import java.net.Inet4Address;
45 import java.net.Inet6Address;
46 import java.net.InetAddress;
47 import java.net.UnknownHostException;
48 import java.util.List;
49 import java.util.Map;
50
51 public class EgressAclService extends AbstractServiceInstance implements EgressAclProvider, ConfigInterface {
52
53     private static final Logger LOG = LoggerFactory.getLogger(EgressAclService.class);
54     private volatile SecurityServicesManager securityServicesManager;
55     private volatile SecurityGroupCacheManger securityGroupCacheManger;
56     private static final int DHCP_SOURCE_PORT = 67;
57     private static final int DHCP_DESTINATION_PORT = 68;
58     private static final int DHCPV6_SOURCE_PORT = 547;
59     private static final int DHCPV6_DESTINATION_PORT = 546;
60     private static final String HOST_MASK = "/32";
61     private static final String V6_HOST_MASK = "/128";
62     private static final int PORT_RANGE_MIN = 1;
63     private static final int PORT_RANGE_MAX = 65535;
64
65     public EgressAclService() {
66         super(Service.EGRESS_ACL);
67     }
68
69     public EgressAclService(Service service) {
70         super(service);
71     }
72
73     @Override
74     public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
75                                        NeutronSecurityGroup securityGroup, String portUuid, boolean write) {
76
77         LOG.trace("programPortSecurityGroup: neutronSecurityGroup: {} ", securityGroup);
78         if (securityGroup == null || securityGroup.getSecurityRules() == null) {
79             return;
80         }
81
82         List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
83         /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
84         for (NeutronSecurityRule portSecurityRule : portSecurityList) {
85
86             /**
87              * Neutron Port Security Acl "egress" and "IPv4"
88              * Check that the base conditions for flow based Port Security are true:
89              * Port Security Rule Direction ("egress") and Protocol ("IPv4")
90              * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
91              * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
92              *
93              */
94
95             if (portSecurityRule == null
96                     || portSecurityRule.getSecurityRuleEthertype() == null
97                     || portSecurityRule.getSecurityRuleDirection() == null) {
98                 continue;
99             }
100
101             if (NeutronSecurityRule.DIRECTION_EGRESS.equals(portSecurityRule.getSecurityRuleDirection())) {
102                 LOG.debug("programPortSecurityGroup: Acl Rule matching IP and ingress is: {} ", portSecurityRule);
103                 if (null != portSecurityRule.getSecurityRemoteGroupID()) {
104                     //Remote Security group is selected
105                     List<Neutron_IPs> remoteSrcAddressList = securityServicesManager
106                             .getVmListForSecurityGroup(portUuid,portSecurityRule.getSecurityRemoteGroupID());
107                     if (null != remoteSrcAddressList) {
108                         for (Neutron_IPs vmIp :remoteSrcAddressList ) {
109
110                             programPortSecurityRule(dpid, segmentationId, attachedMac,
111                                                     localPort, portSecurityRule, vmIp, write);
112                         }
113                         if (write) {
114                             securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
115                         } else {
116                             securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
117                                                                      portUuid);
118                         }
119                     }
120                 } else {
121                     programPortSecurityRule(dpid, segmentationId, attachedMac, localPort,
122                                             portSecurityRule, null, write);
123                 }
124                 if (write) {
125                     securityGroupCacheManger.portAdded(securityGroup.getSecurityGroupUUID(), portUuid);
126                 } else {
127                     securityGroupCacheManger.portRemoved(securityGroup.getSecurityGroupUUID(), portUuid);
128                 }
129             }
130         }
131     }
132
133     @Override
134     public void programPortSecurityRule(Long dpid, String segmentationId, String attachedMac,
135                                         long localPort, NeutronSecurityRule portSecurityRule,
136                                         Neutron_IPs vmIp, boolean write) {
137         String securityRuleEtherType = portSecurityRule.getSecurityRuleEthertype();
138         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(securityRuleEtherType);
139         if (!isIpv6 && !NeutronSecurityRule.ETHERTYPE_IPV4.equals(securityRuleEtherType)) {
140             LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.",
141                       securityRuleEtherType);
142             return;
143         }
144
145         if (null == portSecurityRule.getSecurityRuleProtocol()) {
146             /* TODO Rework on the priority values */
147             egressAclIp(dpid, isIpv6, segmentationId, attachedMac,
148                           write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
149         } else {
150             String ipaddress = null;
151             if (null != vmIp) {
152                 ipaddress = vmIp.getIpAddress();
153                 try {
154                     InetAddress address = InetAddress.getByName(ipaddress);
155                     if ((isIpv6 && (address instanceof Inet4Address)) || (!isIpv6 && address instanceof Inet6Address)) {
156                         LOG.debug("programPortSecurityRule: Remote vmIP {} does not match with "
157                                 + "SecurityRuleEthertype {}.", ipaddress, securityRuleEtherType);
158                         return;
159                     }
160                 } catch (UnknownHostException e) {
161                     LOG.warn("Invalid IP address {}", ipaddress, e);
162                     return;
163                 }
164             }
165
166             switch (portSecurityRule.getSecurityRuleProtocol()) {
167                 case MatchUtils.TCP:
168                     LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
169                     egressAclTcp(dpid, segmentationId, attachedMac,
170                              portSecurityRule,ipaddress, write,
171                              Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
172                     break;
173                 case MatchUtils.UDP:
174                     LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
175                     egressAclUdp(dpid, segmentationId, attachedMac,
176                              portSecurityRule, ipaddress, write,
177                              Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
178                     break;
179                 case MatchUtils.ICMP:
180                 case MatchUtils.ICMPV6:
181                     LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
182                     egressAclIcmp(dpid, segmentationId, attachedMac,
183                               portSecurityRule, ipaddress,write,
184                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
185                     break;
186                 default:
187                     LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other "
188                             + "protocol = ", portSecurityRule.getSecurityRuleProtocol());
189                     egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
190                                               portSecurityRule, ipaddress, write,
191                                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
192                     break;
193             }
194         }
195     }
196
197     private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
198                                                NeutronSecurityRule portSecurityRule, String dstAddress,
199                                                boolean write, Integer priority) {
200         MatchBuilder matchBuilder = new MatchBuilder();
201         String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
202         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
203
204         short proto = 0;
205         try {
206             Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
207             proto = protocol.shortValue();
208             flowId = flowId + proto;
209         } catch (NumberFormatException e) {
210             LOG.error("Protocol vlaue conversion failure", e);
211         }
212         matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
213
214         if (null != dstAddress) {
215             flowId = flowId + dstAddress;
216             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
217                                                          MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
218
219         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
220             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
221             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
222                     new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
223         }
224         flowId = flowId + "_Permit";
225         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
226         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, priority, matchBuilder, getTable());
227         addInstructionWithConntrackCommit(flowBuilder, false);
228         syncFlow(flowBuilder ,nodeBuilder, write);
229     }
230
231     @Override
232     public void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac,
233                                         long localPort, List<Neutron_IPs> srcAddressList,
234                                         boolean isLastPortinBridge, boolean isComputePort ,boolean write) {
235         // If it is the only port in the bridge add the rule to allow any DHCP client traffic
236         //if (isLastPortinBridge) {
237         egressAclDhcpAllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
238         egressAclDhcpv6AllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
239         // }
240         if (isComputePort) {
241             programArpRule(dpid, segmentationId, localPort, attachedMac, write);
242             if (securityServicesManager.isConntrackEnabled()) {
243                 programEgressAclFixedConntrackRule(dpid, segmentationId, localPort, attachedMac, write);
244             }
245             // add rule to drop the DHCP server traffic originating from the vm.
246             egressAclDhcpDropServerTrafficfromVm(dpid, localPort, write,
247                                                  Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
248             egressAclDhcpv6DropServerTrafficfromVm(dpid, localPort, write,
249                                                    Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
250             //Adds rule to check legitimate ip/mac pair for each packet from the vm
251             for (Neutron_IPs srcAddress : srcAddressList) {
252                 try {
253                     InetAddress address = InetAddress.getByName(srcAddress.getIpAddress());
254                     if (address instanceof Inet4Address) {
255                         String addressWithPrefix = srcAddress.getIpAddress() + HOST_MASK;
256                         egressAclAllowTrafficFromVmIpMacPair(dpid, localPort, attachedMac, addressWithPrefix,
257                                                              Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
258                     } else if (address instanceof Inet6Address) {
259                         String addressWithPrefix = srcAddress.getIpAddress() + V6_HOST_MASK;
260                         egressAclAllowTrafficFromVmIpV6MacPair(dpid, localPort, attachedMac, addressWithPrefix,
261                                                                Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
262                     }
263                 } catch (UnknownHostException e) {
264                     LOG.warn("Invalid IP address {}", srcAddress.getIpAddress(), e);
265                 }
266             }
267         }
268     }
269
270     private void programArpRule(Long dpid, String segmentationId, long localPort, String attachedMac, boolean write) {
271         MatchBuilder matchBuilder = new MatchBuilder();
272         String flowId = "Egress_ARP_" + segmentationId + "_" + localPort + "_";
273         MatchUtils.createV4EtherMatchWithType(matchBuilder,null,null,MatchUtils.ETHERTYPE_ARP);
274         MatchUtils.addArpMacMatch(matchBuilder, attachedMac, null);
275         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, Constants.PROTO_MATCH_PRIORITY,
276                                                               matchBuilder, getTable());
277         addPipelineInstruction(flowBuilder, null, false);
278         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
279         syncFlow(flowBuilder ,nodeBuilder, write);
280     }
281
282     private void programEgressAclFixedConntrackRule(Long dpid,
283                                              String segmentationId, long localPort, String attachMac, boolean write) {
284         try {
285             programConntrackUntrackRule(dpid, segmentationId, localPort,attachMac,
286                                         Constants.CT_STATE_UNTRACKED_PRIORITY, write );
287             programConntrackTrackedPlusEstRule(dpid, segmentationId, localPort,
288                                                Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
289             programConntrackTrackedPlusRelRule(dpid, segmentationId, localPort,
290                                                Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
291             programConntrackNewDropRule(dpid, segmentationId, localPort,
292                                         Constants.CT_STATE_NEW_PRIORITY_DROP, write );
293             programConntrackInvDropRule(dpid, segmentationId, localPort,
294                                         Constants.CT_STATE_NEW_PRIORITY_DROP, write );
295             LOG.info("programEgressAclFixedConntrackRule :  default connection tracking rule are added.");
296         } catch (Exception e) {
297             LOG.error("Failed to add default conntrack rules : " , e);
298         }
299     }
300
301     private void programConntrackUntrackRule(Long dpidLong, String segmentationId,
302                                              long localPort, String attachMac, Integer priority, boolean write) {
303         MatchBuilder matchBuilder = new MatchBuilder();
304         String flowName = "Egress_Fixed_Conntrk_Untrk_" + segmentationId + "_" + localPort + "_";
305         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder, attachMac, null,MatchUtils.ETHERTYPE_IPV4);
306         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.UNTRACKED_CT_STATE,
307                                              MatchUtils.UNTRACKED_CT_STATE_MASK);
308         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
309         addInstructionWithConntrackRecirc(flowBuilder);
310         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
311         syncFlow(flowBuilder ,nodeBuilder, write);
312     }
313
314     private void programConntrackTrackedPlusEstRule(Long dpidLong, String segmentationId,
315                                                     long localPort,Integer priority, boolean write) {
316         MatchBuilder matchBuilder = new MatchBuilder();
317         String flowName = "Egress_Fixed_Conntrk_TrkEst_" + segmentationId + "_" + localPort + "_";
318         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
319         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_EST_CT_STATE,
320                                              MatchUtils.TRACKED_CT_STATE_MASK);
321         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
322         addPipelineInstruction(flowBuilder, null, false);
323         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
324         syncFlow(flowBuilder ,nodeBuilder, write);
325     }
326
327     private void programConntrackTrackedPlusRelRule(Long dpidLong, String segmentationId,
328                                                     long localPort,Integer priority, boolean write) {
329         MatchBuilder matchBuilder = new MatchBuilder();
330         String flowName = "Egress_Fixed_Conntrk_TrkRel_" + segmentationId + "_" + localPort + "_";
331         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
332         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_REL_CT_STATE,
333                                              MatchUtils.TRACKED_CT_STATE_MASK);
334         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
335         addPipelineInstruction(flowBuilder, null, false);
336         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
337         syncFlow(flowBuilder ,nodeBuilder, write);
338     }
339
340     private void programConntrackNewDropRule(Long dpidLong, String segmentationId,
341                                              long localPort, Integer priority, boolean write) {
342         MatchBuilder matchBuilder = new MatchBuilder();
343
344         String flowName = "Egress_Fixed_Conntrk_NewDrop_" + segmentationId + "_" + localPort + "_";
345         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
346         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_NEW_CT_STATE,
347                                              MatchUtils.TRACKED_NEW_CT_STATE_MASK);
348         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
349         addPipelineInstruction(flowBuilder, null, true);
350         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
351         syncFlow(flowBuilder ,nodeBuilder, write);
352     }
353
354     private void programConntrackInvDropRule(Long dpidLong, String segmentationId,
355                                              long localPort, Integer priority, boolean write) {
356         MatchBuilder matchBuilder = new MatchBuilder();
357         String flowName = "Egress_Fixed_Conntrk_InvDrop_" + segmentationId + "_" + localPort + "_";
358         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
359         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_INV_CT_STATE,
360                                              MatchUtils.TRACKED_INV_CT_STATE_MASK);
361         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
362         addPipelineInstruction(flowBuilder, null, true);
363         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
364         syncFlow(flowBuilder ,nodeBuilder, write);
365     }
366
367     /**
368      * Allows IPv4/v6 packet egress from the src mac address.
369      * @param dpidLong the dpid
370      * @param isIpv6 whether the rule is for ipv6
371      * @param segmentationId the segementation id
372      * @param srcMac the src mac address
373      * @param write add or remove
374      * @param protoPortMatchPriority the protocol match priority.
375      */
376     private void egressAclIp(Long dpidLong, boolean isIpv6, String segmentationId, String srcMac,
377                                boolean write, Integer protoPortMatchPriority ) {
378         MatchBuilder matchBuilder = new MatchBuilder();
379         String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
380         if (isIpv6) {
381             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
382         } else {
383             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
384         }
385         addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
386         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
387         addInstructionWithConntrackCommit(flowBuilder, false);
388         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
389         syncFlow(flowBuilder ,nodeBuilder, write);
390     }
391
392     /**
393      * Creates a egress match with src macaddress. If dest address is specified
394      * destination specific match will be created. Otherwise a match with a
395      * CIDR will be created.
396      * @param dpidLong the dpid
397      * @param segmentationId the segmentation id
398      * @param srcMac the source mac address.
399      * @param portSecurityRule the security rule in the SG
400      * @param dstAddress the destination IP address
401      * @param write add or delete
402      * @param protoPortMatchPriority the protocol match priroty
403      */
404     private void egressAclTcp(Long dpidLong, String segmentationId, String srcMac,
405                               NeutronSecurityRule portSecurityRule, String dstAddress,
406                               boolean write, Integer protoPortMatchPriority) {
407         boolean portRange = false;
408         MatchBuilder matchBuilder = new MatchBuilder();
409         String flowId = "Egress_TCP_" + segmentationId + "_" + srcMac + "_";
410         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
411         if (isIpv6) {
412             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
413         } else {
414             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
415         }
416
417         /* Custom TCP Match */
418         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
419             flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
420             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
421                                                      portSecurityRule.getSecurityRulePortMin());
422         } else {
423             /* All TCP Match */
424             if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
425                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
426                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
427                             + portSecurityRule.getSecurityRulePortMax() + "_";
428                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
429             } else {
430                 portRange = true;
431             }
432         }
433         if (null != dstAddress) {
434             flowId = flowId + dstAddress;
435             if (isIpv6) {
436                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
437                         MatchUtils.iPv6PrefixFromIPv6Address(dstAddress));
438             } else {
439                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
440                         MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
441             }
442         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
443             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
444             if (isIpv6) {
445                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
446                         new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
447             } else {
448                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
449                         new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
450             }
451         }
452         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
453         if (portRange) {
454             Map<Integer, Integer> portMaskMap = MatchUtils
455                     .getLayer4MaskForRange(portSecurityRule.getSecurityRulePortMin(),
456                                            portSecurityRule.getSecurityRulePortMax());
457             for (Integer port: portMaskMap.keySet()) {
458                 String rangeflowId = flowId + port + "_" + portMaskMap.get(port) + "_";
459                 rangeflowId = rangeflowId + "_Permit";
460                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
461                                                   0, port, portMaskMap.get(port));
462                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
463                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
464                                                                       matchBuilder, getTable());
465                 addInstructionWithConntrackCommit(flowBuilder, false);
466                 syncFlow(flowBuilder ,nodeBuilder, write);
467             }
468         } else {
469             flowId = flowId + "_Permit";
470             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
471             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
472                                                                   matchBuilder, getTable());
473             addInstructionWithConntrackCommit(flowBuilder, false);
474             syncFlow(flowBuilder ,nodeBuilder, write);
475         }
476     }
477
478     private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
479             NeutronSecurityRule portSecurityRule, String dstAddress,
480             boolean write, Integer protoPortMatchPriority) {
481
482         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
483         if (isIpv6) {
484             egressAclIcmpV6(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
485                             protoPortMatchPriority);
486         } else {
487             egressAclIcmpV4(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
488                             protoPortMatchPriority);
489         }
490     }
491
492     /**
493      * Creates a icmp egress match with src macaddress. If dest address is specified
494      * destination specific match will be created. Otherwise a match with a
495      * CIDR will be created.
496      * @param dpidLong the dpid
497      * @param segmentationId the segmentation id
498      * @param srcMac the source mac address.
499      * @param portSecurityRule the security rule in the SG
500      * @param dstAddress the source IP address
501      * @param write add or delete
502      * @param protoPortMatchPriority the protocol match priority
503      */
504     private void egressAclIcmpV4(Long dpidLong, String segmentationId, String srcMac,
505                                  NeutronSecurityRule portSecurityRule, String dstAddress,
506                                  boolean write, Integer protoPortMatchPriority) {
507
508         MatchBuilder matchBuilder = new MatchBuilder();
509         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
510         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
511         /*Custom ICMP Match */
512         if (portSecurityRule.getSecurityRulePortMin() != null
513                 && portSecurityRule.getSecurityRulePortMax() != null) {
514             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
515                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
516             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
517                     portSecurityRule.getSecurityRulePortMin().shortValue(),
518                     portSecurityRule.getSecurityRulePortMax().shortValue());
519         } else {
520             /* All ICMP Match */ // We are getting from neutron NULL for both min and max
521             flowId = flowId + "all" + "_" ;
522             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
523         }
524         if (null != dstAddress) {
525             flowId = flowId + dstAddress;
526             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
527                     MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
528         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
529             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
530             if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
531                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
532                     new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
533             }
534         }
535         flowId = flowId + "_Permit";
536         addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
537         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
538         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
539         addInstructionWithConntrackCommit(flowBuilder, false);
540         syncFlow(flowBuilder ,nodeBuilder, write);
541     }
542
543     /**
544      * Creates a icmpv6 egress match with src macaddress. If dest address is specified
545      * destination specific match will be created. Otherwise a match with a
546      * CIDR will be created.
547      * @param dpidLong the dpid
548      * @param segmentationId the segmentation id
549      * @param srcMac the source mac address.
550      * @param portSecurityRule the security rule in the SG
551      * @param dstAddress the source IP address
552      * @param write add or delete
553      * @param protoPortMatchPriority the protocol match priority
554      */
555     private void egressAclIcmpV6(Long dpidLong, String segmentationId, String srcMac,
556                                  NeutronSecurityRule portSecurityRule, String dstAddress,
557                                  boolean write, Integer protoPortMatchPriority) {
558
559         MatchBuilder matchBuilder = new MatchBuilder();
560         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
561         matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
562
563         /*Custom ICMP Match */
564         if (portSecurityRule.getSecurityRulePortMin() != null
565                 && portSecurityRule.getSecurityRulePortMax() != null) {
566             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
567                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
568             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder,
569                     portSecurityRule.getSecurityRulePortMin().shortValue(),
570                     portSecurityRule.getSecurityRulePortMax().shortValue());
571         } else {
572             /* All ICMP Match */ // We are getting from neutron NULL for both min and max
573             flowId = flowId + "all" + "_" ;
574             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
575         }
576         if (null != dstAddress) {
577             flowId = flowId + dstAddress;
578             matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
579                     MatchUtils.iPv6PrefixFromIPv6Address(dstAddress));
580         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
581             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
582             matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
583                     new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
584         }
585         flowId = flowId + "_Permit";
586         addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
587         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
588         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
589         addInstructionWithConntrackCommit(flowBuilder, false);
590         syncFlow(flowBuilder ,nodeBuilder, write);
591     }
592
593     /**
594      * Creates a egress match with src macaddress. If dest address is specified
595      * destination specific match will be created. Otherwise a match with a
596      * CIDR will be created.
597      * @param dpidLong the dpid
598      * @param segmentationId the segmentation id
599      * @param srcMac the source mac address.
600      * @param portSecurityRule the security rule in the SG
601      * @param dstAddress the source IP address
602      * @param write add or delete
603      * @param protoPortMatchPriority the protocol match priroty
604      */
605     private void egressAclUdp(Long dpidLong, String segmentationId, String srcMac,
606                               NeutronSecurityRule portSecurityRule, String dstAddress,
607                               boolean write, Integer protoPortMatchPriority) {
608         boolean portRange = false;
609         MatchBuilder matchBuilder = new MatchBuilder();
610         String flowId = "Egress_UDP_" + segmentationId + "_" + srcMac + "_";
611         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
612         if (isIpv6) {
613             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
614         } else {
615             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
616         }
617
618         /* Custom UDP Match */
619         if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
620             flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
621             matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
622                                                      portSecurityRule.getSecurityRulePortMin());
623         } else {
624             /* All UDP Match */
625             if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
626                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
627                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
628                     + portSecurityRule.getSecurityRulePortMax() + "_";
629                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
630             } else {
631                 portRange = true;
632             }
633         }
634         if (null != dstAddress) {
635             flowId = flowId + dstAddress;
636             if (isIpv6) {
637                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
638                         MatchUtils.iPv6PrefixFromIPv6Address(dstAddress));
639             } else {
640                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
641                         MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
642             }
643         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
644             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
645             if (isIpv6) {
646                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder, null,
647                         new Ipv6Prefix(portSecurityRule
648                                        .getSecurityRuleRemoteIpPrefix()));
649             } else {
650                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
651                         new Ipv4Prefix(portSecurityRule
652                                        .getSecurityRuleRemoteIpPrefix()));
653             }
654         }
655         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
656         if (portRange) {
657             Map<Integer, Integer> portMaskMap = MatchUtils
658                     .getLayer4MaskForRange(portSecurityRule.getSecurityRulePortMin(),
659                                            portSecurityRule.getSecurityRulePortMax());
660             for (Integer port: portMaskMap.keySet()) {
661                 String rangeflowId = flowId + port + "_" + portMaskMap.get(port) + "_";
662                 rangeflowId = rangeflowId + "_Permit";
663                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.UDP_SHORT,
664                                                   0, port, portMaskMap.get(port));
665                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
666                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
667                                                                       matchBuilder, getTable());
668                 addInstructionWithConntrackCommit(flowBuilder, false);
669                 syncFlow(flowBuilder ,nodeBuilder, write);
670             }
671         } else {
672             flowId = flowId + "_Permit";
673             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
674             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
675                                                                   matchBuilder, getTable());
676             addInstructionWithConntrackCommit(flowBuilder, false);
677             syncFlow(flowBuilder ,nodeBuilder, write);
678         }
679     }
680
681     /**
682      * Adds flow to allow any DHCP client traffic.
683      *
684      * @param dpidLong the dpid
685      * @param write whether to write or delete the flow
686      * @param priority the priority
687      */
688     private void egressAclDhcpAllowClientTrafficFromVm(Long dpidLong,
689                                                        boolean write, Integer priority) {
690         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
691         String flowName = "Egress_DHCP_Client"  + "_Permit_";
692         MatchBuilder matchBuilder = new MatchBuilder();
693         MatchUtils.createDhcpMatch(matchBuilder, DHCP_DESTINATION_PORT, DHCP_SOURCE_PORT);
694         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
695         addPipelineInstruction(flowBuilder, null, false);
696         syncFlow(flowBuilder ,nodeBuilder, write);
697     }
698
699     /**
700      * Adds flow to allow any DHCP IPv6 client traffic.
701      *
702      * @param dpidLong the dpid
703      * @param write whether to write or delete the flow
704      * @param priority the priority
705      */
706     private void egressAclDhcpv6AllowClientTrafficFromVm(Long dpidLong,
707                                                          boolean write, Integer priority) {
708         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
709         String flowName = "Egress_DHCPv6_Client"  + "_Permit_";
710         MatchBuilder matchBuilder = new MatchBuilder();
711         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_DESTINATION_PORT, DHCPV6_SOURCE_PORT);
712         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
713         addPipelineInstruction(flowBuilder, null, false);
714         syncFlow(flowBuilder ,nodeBuilder, write);
715     }
716
717     /**
718      * Adds rule to prevent DHCP spoofing by the vm attached to the port.
719      *
720      * @param dpidLong the dpid
721      * @param localPort the local port
722      * @param write is write or delete
723      * @param priority  the priority
724      */
725     private void egressAclDhcpDropServerTrafficfromVm(Long dpidLong, long localPort,
726                                                       boolean write, Integer priority) {
727         String flowName = "Egress_DHCP_Server" + "_" + localPort + "_DROP_";
728         MatchBuilder matchBuilder = new MatchBuilder();
729         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
730         MatchUtils.createDhcpMatch(matchBuilder, DHCP_SOURCE_PORT, DHCP_DESTINATION_PORT);
731         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
732         addPipelineInstruction(flowBuilder, null, true);
733         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
734         syncFlow(flowBuilder ,nodeBuilder, write);
735     }
736
737     /**
738      * Adds rule to prevent DHCPv6 spoofing by the vm attached to the port.
739      *
740      * @param dpidLong the dpid
741      * @param localPort the local port
742      * @param write is write or delete
743      * @param priority  the priority
744      */
745     private void egressAclDhcpv6DropServerTrafficfromVm(Long dpidLong, long localPort,
746                                                         boolean write, Integer priority) {
747
748         String flowName = "Egress_DHCPv6_Server" + "_" + localPort + "_DROP_";
749         MatchBuilder matchBuilder = new MatchBuilder();
750         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
751         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_SOURCE_PORT, DHCPV6_DESTINATION_PORT);
752         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
753         addPipelineInstruction(flowBuilder, null, true);
754         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
755         syncFlow(flowBuilder ,nodeBuilder, write);
756     }
757
758     /**
759      * Adds rule to check legitimate ip/mac pair for each packet from the vm.
760      *
761      * @param dpidLong the dpid
762      * @param localPort the local port
763      * @param srcIp the vm ip address
764      * @param attachedMac the vm mac address
765      * @param priority  the priority
766      * @param write is write or delete
767      */
768     private void egressAclAllowTrafficFromVmIpMacPair(Long dpidLong, long localPort,
769                                                       String attachedMac, String srcIp,
770                                                       Integer priority, boolean write) {
771         MatchBuilder matchBuilder = new MatchBuilder();
772         MatchUtils.createSrcL3Ipv4MatchWithMac(matchBuilder, new Ipv4Prefix(srcIp),new MacAddress(attachedMac));
773         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
774         LOG.debug("egressAclAllowTrafficFromVmIpMacPair: MatchBuilder contains: {}", matchBuilder);
775         String flowName = "Egress_Allow_VM_IP_MAC" + "_" + localPort + attachedMac + "_Permit_";
776         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
777         addPipelineInstruction(flowBuilder, null, false);
778         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
779         syncFlow(flowBuilder ,nodeBuilder, write);
780     }
781
782     /**
783      * Adds rule to check legitimate ip/mac pair for each packet from the vm.
784      *
785      * @param dpidLong the dpid
786      * @param localPort the local port
787      * @param srcIp the vm ip address
788      * @param attachedMac the vm mac address
789      * @param priority  the priority
790      * @param write is write or delete
791      */
792     private void egressAclAllowTrafficFromVmIpV6MacPair(Long dpidLong, long localPort,
793                                                         String attachedMac, String srcIp,
794                                                         Integer priority, boolean write) {
795         MatchBuilder matchBuilder = new MatchBuilder();
796         MatchUtils.createSrcL3Ipv6MatchWithMac(matchBuilder, new Ipv6Prefix(srcIp),new MacAddress(attachedMac));
797         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
798         LOG.debug("egressAclAllowTrafficFromVmIpMacPair: MatchBuilder contains: {}", matchBuilder);
799         String flowName = "Egress_Allow_VM_IPv6_MAC" + "_" + localPort + attachedMac + "_Permit_";
800         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
801         addPipelineInstruction(flowBuilder, null, false);
802         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
803         syncFlow(flowBuilder ,nodeBuilder, write);
804     }
805
806     private void addConntrackMatch(MatchBuilder matchBuilder, int state, int mask) {
807         if (securityServicesManager.isConntrackEnabled()) {
808             MatchUtils.addCtState(matchBuilder, state, mask );
809         }
810
811     }
812
813     private FlowBuilder addInstructionWithConntrackCommit( FlowBuilder flowBuilder , boolean isDrop) {
814         InstructionBuilder instructionBuilder = null;
815         if (securityServicesManager.isConntrackEnabled()) {
816             Action conntrackAction = ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff);
817             instructionBuilder = InstructionUtils
818                     .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
819         }
820         return addPipelineInstruction(flowBuilder,instructionBuilder, isDrop);
821     }
822
823     private FlowBuilder addInstructionWithConntrackRecirc( FlowBuilder flowBuilder) {
824         InstructionBuilder instructionBuilder = null;
825         if (securityServicesManager.isConntrackEnabled()) {
826             Action conntrackAction = ActionUtils.nxConntrackAction(0, 0L, 0, (short)0x0);
827
828             instructionBuilder = InstructionUtils
829                     .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
830             List<Instruction> instructionsList = Lists.newArrayList();
831             instructionsList.add(instructionBuilder.build());
832             InstructionsBuilder isb = new InstructionsBuilder();
833             isb.setInstruction(instructionsList);
834             flowBuilder.setInstructions(isb.build());
835         }
836         return flowBuilder;
837     }
838
839     private FlowBuilder addPipelineInstruction( FlowBuilder flowBuilder ,
840                                                 InstructionBuilder instructionBuilder,boolean isDrop) {
841         InstructionBuilder pipeLineIndstructionBuilder = createPipleLineInstructionBuilder(isDrop);
842         List<Instruction> instructionsList = Lists.newArrayList();
843         instructionsList.add(pipeLineIndstructionBuilder.build());
844         if (null != instructionBuilder) {
845             instructionsList.add(instructionBuilder.build());
846         }
847         InstructionsBuilder isb = new InstructionsBuilder();
848         isb.setInstruction(instructionsList);
849         flowBuilder.setInstructions(isb.build());
850         return flowBuilder;
851     }
852
853     private InstructionBuilder createPipleLineInstructionBuilder(boolean drop) {
854         InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
855         if (drop) {
856             InstructionUtils.createDropInstructions(ib);
857         }
858         ib.setOrder(0);
859         List<Instruction> instructionsList = Lists.newArrayList();
860         ib.setKey(new InstructionKey(0));
861         instructionsList.add(ib.build());
862         return ib;
863     }
864     /**
865      * Add or remove flow to the node.
866      * @param flowBuilder the flow builder
867      * @param nodeBuilder the node builder
868      * @param write whether it is a write
869      */
870     private void syncFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder,
871                           boolean write) {
872         if (write) {
873             writeFlow(flowBuilder, nodeBuilder);
874         } else {
875             removeFlow(flowBuilder, nodeBuilder);
876         }
877     }
878
879
880     @Override
881     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
882         super.setDependencies(bundleContext.getServiceReference(EgressAclProvider.class.getName()), this);
883         securityServicesManager =
884                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
885         securityGroupCacheManger =
886                 (SecurityGroupCacheManger) ServiceHelper.getGlobalInstance(SecurityGroupCacheManger.class, this);
887     }
888
889     @Override
890     public void setDependencies(Object impl) {}
891 }