Optimize issues in acl flow table class
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / EgressAclServiceImpl.java
1 /*
2  * Copyright (c) 2018 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 package org.opendaylight.netvirt.aclservice;
9
10 import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
11 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
12
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.Set;
17 import java.util.stream.Collectors;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.genius.mdsalutil.FlowEntity;
20 import org.opendaylight.genius.mdsalutil.InstructionInfo;
21 import org.opendaylight.genius.mdsalutil.MDSALUtil;
22 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
23 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
24 import org.opendaylight.genius.mdsalutil.NwConstants;
25 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
26 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
27 import org.opendaylight.genius.mdsalutil.matches.MatchArpSha;
28 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetSource;
29 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
30 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
31 import org.opendaylight.genius.utils.ServiceIndex;
32 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
33 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
34 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
35 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
36 import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
37 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
38 import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
39 import org.opendaylight.netvirt.aclservice.utils.AclServiceOFFlowBuilder;
40 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl.InterfaceType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfo;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.opendaylight.yangtools.yang.common.Uint64;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 /**
57  * Provides the implementation for egress (w.r.t VM) ACL service.
58  *
59  * <p>
60  * Note: Table names used are w.r.t switch. Hence, switch ingress is VM egress
61  * and vice versa.
62  */
63 public class EgressAclServiceImpl extends AbstractAclServiceImpl {
64
65     private static final Logger LOG = LoggerFactory.getLogger(EgressAclServiceImpl.class);
66
67     /**
68      * Initialize the member variables.
69      */
70     public EgressAclServiceImpl(DataBroker dataBroker, IMdsalApiManager mdsalManager, AclDataUtil aclDataUtil,
71             AclServiceUtils aclServiceUtils, JobCoordinator jobCoordinator, AclInterfaceCache aclInterfaceCache) {
72         // Service mode is w.rt. switch
73         super(ServiceModeIngress.class, dataBroker, mdsalManager, aclDataUtil, aclServiceUtils,
74                 jobCoordinator, aclInterfaceCache);
75     }
76
77     /**
78      * Bind service.
79      *
80      * @param aclInterface the acl interface
81      */
82     @Override
83     public void bindService(AclInterface aclInterface) {
84         String interfaceName = aclInterface.getInterfaceId();
85         LOG.debug("Binding ACL service for interface {}", interfaceName);
86         if (aclInterface.getInterfaceType() == InterfaceType.DhcpService) {
87             LOG.debug("{} is a DHCP serice port. No binding needed", interfaceName);
88             return;
89         }
90         jobCoordinator.enqueueJob(interfaceName, () -> {
91             int instructionKey = 0;
92             List<Instruction> instructions = new ArrayList<>();
93             instructions.add(MDSALUtil.buildAndGetGotoTableInstruction(getAclAntiSpoofingTable(), ++instructionKey));
94             short serviceIndex = ServiceIndex.getIndex(AclConstants.INGRESS_ACL_SERVICE_NAME,
95                     AclConstants.INGRESS_ACL_SERVICE_INDEX);
96             int flowPriority = AclConstants.INGRESS_ACL_SERVICE_INDEX;
97             BoundServices serviceInfo =
98                     AclServiceUtils.getBoundServices(String.format("%s.%s.%s", "acl", "ingressacl", interfaceName),
99                             serviceIndex, flowPriority, AclConstants.COOKIE_ACL_BASE, instructions);
100             InstanceIdentifier<BoundServices> path =
101                     AclServiceUtils.buildServiceId(interfaceName, serviceIndex, serviceMode);
102
103             return Collections.singletonList(
104                     txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.put(
105                             path, serviceInfo, CREATE_MISSING_PARENTS)));
106         });
107     }
108
109     /**
110      * Unbind service.
111      *
112      * @param aclInterface the acl interface
113      */
114     @Override
115     protected void unbindService(AclInterface aclInterface) {
116         String interfaceName = aclInterface.getInterfaceId();
117         InstanceIdentifier<BoundServices> path = AclServiceUtils.buildServiceId(interfaceName,
118                 ServiceIndex.getIndex(NwConstants.ACL_SERVICE_NAME, NwConstants.ACL_SERVICE_INDEX), serviceMode);
119
120         LOG.debug("UnBinding ACL service for interface {}", interfaceName);
121         jobCoordinator.enqueueJob(interfaceName, () -> Collections.singletonList(txRunner
122                 .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path))));
123     }
124
125     /**
126      * Programs DHCP Service flows.
127      *
128      * @param flowEntries the flow entries
129      * @param port the acl interface
130      * @param action add/modify/remove action
131      * @param addOrRemove addorRemove
132      */
133     @Override
134     protected void programDhcpService(List<FlowEntity> flowEntries, AclInterface port,
135             Action action, int addOrRemove) {
136         // No action required on egress.
137     }
138
139     /**
140      * Programs DHCP service flows.
141      *
142      * @param flowEntries the flow entries
143      * @param port the acl interface
144      * @param allowedAddresses the allowed addresses
145      * @param addOrRemove addorRemove
146      */
147     @Override
148     protected void processDhcpServiceUpdate(List<FlowEntity> flowEntries, AclInterface port,
149             List<AllowedAddressPairs> allowedAddresses, int addOrRemove) {
150         // No action required on egress.
151     }
152
153     @Override
154     protected void programAntiSpoofingRules(List<FlowEntity> flowEntries, AclInterface port,
155             List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
156         LOG.info("{} programAntiSpoofingRules for port {}, AAPs={}, action={}, addOrRemove={}", this.directionString,
157                 port.getInterfaceId(), allowedAddresses, action, addOrRemove);
158
159         Uint64 dpid = Uint64.valueOf(port.getDpId());
160         int lportTag = port.getLPortTag();
161         if (action != Action.UPDATE) {
162             programCommitterDropFlow(flowEntries, dpid, lportTag, addOrRemove);
163             egressAclIcmpv6AllowedList(flowEntries, dpid, lportTag, addOrRemove);
164         }
165         List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(allowedAddresses);
166         if (!hasDuplicateMac(port.getAllowedAddressPairs(), filteredAAPs, action)) {
167             programL2BroadcastAllowRule(flowEntries, port, filteredAAPs, addOrRemove);
168             egressAclDhcpAllowClientTraffic(flowEntries, port, filteredAAPs, lportTag, addOrRemove);
169             egressAclDhcpv6AllowClientTraffic(flowEntries, port, filteredAAPs, lportTag, addOrRemove);
170         }
171         programArpRule(flowEntries, dpid, filteredAAPs, lportTag, addOrRemove);
172     }
173
174     private void programCommitterDropFlow(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
175             int addOrRemove) {
176         List<MatchInfoBase> matches = new ArrayList<>();
177         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
178
179         Uint64 metaData = Uint64.fromLongBits(MetaDataUtil.getLportTagMetaData(lportTag).longValue()
180                 | MetaDataUtil.getAclDropMetaData(AclConstants.METADATA_DROP_FLAG).longValue());
181         Uint64 metaDataMask = Uint64.fromLongBits(MetaDataUtil.METADATA_MASK_LPORT_TAG.longValue()
182                 | MetaDataUtil.METADATA_MASK_ACL_DROP.longValue());
183         matches.add(new MatchMetadata(metaData, metaDataMask));
184
185         String flowName = "Egress_" + dpId + "_" + lportTag + "_Drop";
186         addFlowEntryToList(flowEntries, dpId, getAclCommitterTable(), flowName,
187                 AclConstants.CT_STATE_TRACKED_INVALID_PRIORITY, 0, 0, AclServiceUtils.getDropFlowCookie(lportTag),
188                 matches, instructions, addOrRemove);
189     }
190
191     @Override
192     protected void programRemoteAclTableFlow(List<FlowEntity> flowEntries, Uint64 dpId, Integer aclTag,
193             AllowedAddressPairs aap, int addOrRemove) {
194         List<MatchInfoBase> flowMatches = new ArrayList<>();
195         flowMatches.addAll(AclServiceUtils.buildIpAndDstServiceMatch(aclTag, aap));
196
197         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclCommitterTable());
198         String flowNameAdded = "Acl_Filter_Egress_" + aap.getIpAddress().stringValue() + "_" + aclTag;
199
200         addFlowEntryToList(flowEntries, dpId, getAclRemoteAclTable(), flowNameAdded,
201                 AclConstants.ACL_DEFAULT_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, flowMatches,
202                 instructions, addOrRemove);
203     }
204
205     @Override
206     protected void programGotoClassifierTableRules(List<FlowEntity> flowEntries, Uint64 dpId,
207             List<AllowedAddressPairs> aaps, int lportTag, int addOrRemove) {
208         List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(aaps);
209         for (AllowedAddressPairs aap : filteredAAPs) {
210             IpPrefixOrAddress attachIp = aap.getIpAddress();
211             MacAddress mac = aap.getMacAddress();
212
213             List<MatchInfoBase> matches = new ArrayList<>();
214             matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
215             matches.add(new MatchEthernetSource(mac));
216             matches.addAll(AclServiceUtils.buildIpMatches(attachIp, MatchCriteria.MATCH_SOURCE));
217
218             List<InstructionInfo> gotoInstructions = new ArrayList<>();
219             gotoInstructions.add(new InstructionGotoTable(getAclConntrackClassifierTable()));
220
221             String flowName = "Egress_Fixed_Goto_Classifier_" + dpId + "_" + lportTag + "_"
222                     + mac.getValue() + "_" + attachIp.stringValue();
223             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
224                     AclConstants.PROTO_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, gotoInstructions,
225                     addOrRemove);
226         }
227     }
228
229     /**
230      * Add rule to allow certain ICMPv6 traffic from VM ports.
231      *
232      * @param flowEntries the flow entries
233      * @param dpId the dpId
234      * @param lportTag the lport tag
235      * @param addOrRemove add/remove the flow.
236      */
237     private void egressAclIcmpv6AllowedList(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
238             int addOrRemove) {
239         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
240
241         for (Integer icmpv6Type: AclConstants.allowedIcmpv6NdList()) {
242             List<MatchInfoBase> matches = AclServiceUtils.buildIcmpV6Matches(icmpv6Type, 0, lportTag, serviceMode);
243             String flowName = "Egress_ICMPv6" + "_" + dpId + "_" + lportTag + "_" + icmpv6Type + "_Permit_";
244             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
245                     AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
246                     instructions, addOrRemove);
247         }
248     }
249
250     /**
251      * Add rule to ensure only DHCP server traffic from the specified mac is allowed.
252      *
253      * @param flowEntries the flow entries
254      * @param port the Acl Interface port
255      * @param allowedAddresses the allowed addresses
256      * @param lportTag the lport tag
257      * @param addOrRemove whether to add or remove the flow
258      */
259     private void egressAclDhcpAllowClientTraffic(List<FlowEntity> flowEntries, AclInterface port,
260             List<AllowedAddressPairs> allowedAddresses, int lportTag, int addOrRemove) {
261         Uint64 dpId = Uint64.valueOf(port.getDpId());
262         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
263         for (AllowedAddressPairs aap : allowedAddresses) {
264             if (!AclServiceUtils.isIPv4Address(aap)) {
265                 continue;
266             }
267             List<MatchInfoBase> matches = new ArrayList<>();
268             matches.addAll(AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_CLIENT_PORT_IPV4,
269                 AclConstants.DHCP_SERVER_PORT_IPV4, lportTag, serviceMode));
270             matches.add(new MatchEthernetSource(aap.getMacAddress()));
271
272             String flowName =
273                     "Egress_DHCP_Client_v4" + dpId + "_" + lportTag + "_" + aap.getMacAddress().getValue() + "_Permit_";
274             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
275                     AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE,
276                     matches, instructions, addOrRemove);
277         }
278     }
279
280     /**
281      * Add rule to ensure only DHCPv6 server traffic from the specified mac is allowed.
282      *
283      * @param flowEntries the flow entries
284      * @param port the Acl Interface port
285      * @param allowedAddresses the allowed addresses
286      * @param lportTag the lport tag
287      * @param addOrRemove whether to add or remove the flow
288      */
289     private void egressAclDhcpv6AllowClientTraffic(List<FlowEntity> flowEntries, AclInterface port,
290             List<AllowedAddressPairs> allowedAddresses, int lportTag, int addOrRemove) {
291         Uint64 dpId = Uint64.valueOf(port.getDpId());
292         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
293         for (AllowedAddressPairs aap : allowedAddresses) {
294             if (AclServiceUtils.isIPv4Address(aap)) {
295                 continue;
296             }
297             List<MatchInfoBase> matches = new ArrayList<>();
298             matches.addAll(AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_CLIENT_PORT_IPV6,
299                 AclConstants.DHCP_SERVER_PORT_IPV6, lportTag, serviceMode));
300             matches.add(new MatchEthernetSource(aap.getMacAddress()));
301
302             String flowName = "Egress_DHCP_Client_v6" + "_" + dpId + "_" + lportTag + "_"
303                     + aap.getMacAddress().getValue() + "_Permit_";
304             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
305                     AclConstants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE,
306                     matches, instructions, addOrRemove);
307         }
308     }
309
310     /**
311      * Adds the rule to allow arp packets.
312      *
313      * @param flowEntries the flow entries
314      * @param dpId the dpId
315      * @param allowedAddresses the allowed addresses
316      * @param lportTag the lport tag
317      * @param addOrRemove whether to add or remove the flow
318      */
319     protected void programArpRule(List<FlowEntity> flowEntries, Uint64 dpId,
320             List<AllowedAddressPairs> allowedAddresses, int lportTag, int addOrRemove) {
321         for (AllowedAddressPairs allowedAddress : allowedAddresses) {
322             if (!AclServiceUtils.isIPv4Address(allowedAddress)) {
323                 continue; // For IPv6 allowed addresses
324             }
325
326             IpPrefixOrAddress allowedAddressIp = allowedAddress.getIpAddress();
327             MacAddress allowedAddressMac = allowedAddress.getMacAddress();
328             List<MatchInfoBase> arpIpMatches = AclServiceUtils.buildArpIpMatches(allowedAddressIp);
329             List<MatchInfoBase> matches = new ArrayList<>();
330             matches.add(MatchEthernetType.ARP);
331             matches.add(new MatchArpSha(allowedAddressMac));
332             matches.add(new MatchEthernetSource(allowedAddressMac));
333             matches.addAll(arpIpMatches);
334             matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
335
336             List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
337             LOG.debug("{} ARP Rule on DPID {}, lportTag {}",
338                     addOrRemove == NwConstants.DEL_FLOW ? "Deleting" : "Adding", dpId, lportTag);
339             String flowName = "Egress_ARP_" + dpId + "_" + lportTag + "_" + allowedAddress.getMacAddress().getValue()
340                     + allowedAddressIp.stringValue();
341             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
342                     AclConstants.PROTO_ARP_TRAFFIC_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
343                     instructions, addOrRemove);
344         }
345     }
346
347     @Override
348     protected void programIcmpv6RARule(List<FlowEntity> flowEntries, AclInterface port, List<SubnetInfo> subnets,
349             int addOrRemove) {
350         // No action required on egress.
351     }
352
353     /**
354      * Programs broadcast rules.
355      *
356      * @param flowEntries the flow entries
357      * @param port the Acl Interface port
358      * @param addOrRemove whether to delete or add flow
359      */
360     @Override
361     protected void programBroadcastRules(List<FlowEntity> flowEntries, AclInterface port, Action action,
362              int addOrRemove) {
363         List<AllowedAddressPairs> allowedAddressPairs = port.getAllowedAddressPairs();
364         List<AllowedAddressPairs> filteredAAPs = AclServiceUtils.excludeMulticastAAPs(allowedAddressPairs);
365         if (!hasDuplicateMac(allowedAddressPairs, filteredAAPs, action)) {
366             programL2BroadcastAllowRule(flowEntries, port, filteredAAPs, addOrRemove);
367         }
368     }
369
370     /**
371      * Programs broadcast rules.
372      *
373      * @param flowEntries the flow entries
374      * @param port the Acl Interface port
375      * @param subnetInfoList the port subnet info list
376      * @param addOrRemove whether to delete or add flow
377      */
378     protected void programSubnetBroadcastRules(List<FlowEntity> flowEntries, AclInterface port,
379             List<SubnetInfo> subnetInfoList, int addOrRemove) {
380         // No action required on egress.
381     }
382
383     /**
384      * Programs Non-IP broadcast rules.
385      *
386      * @param flowEntries the flow entries
387      * @param port the Acl Interface port
388      * @param filteredAAPs the filtered AAPs list
389      * @param addOrRemove whether to delete or add flow
390      */
391     private void programL2BroadcastAllowRule(List<FlowEntity> flowEntries, AclInterface port,
392             List<AllowedAddressPairs> filteredAAPs, int addOrRemove) {
393         Uint64 dpId = Uint64.valueOf(port.getDpId());
394         int lportTag = port.getLPortTag();
395         Set<MacAddress> macs = filteredAAPs.stream().map(AllowedAddressPairs::getMacAddress)
396                 .collect(Collectors.toSet());
397         for (MacAddress mac : macs) {
398             List<MatchInfoBase> matches = new ArrayList<>();
399             matches.add(new MatchEthernetSource(mac));
400             matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
401
402             List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
403
404             String flowName = "Egress_L2Broadcast_" + dpId + "_" + lportTag + "_" + mac.getValue();
405             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
406                     AclConstants.PROTO_L2BROADCAST_TRAFFIC_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE,
407                     matches, instructions, addOrRemove);
408         }
409     }
410
411     private boolean hasDuplicateMac(List<AllowedAddressPairs> allowedAddresses,
412             List<AllowedAddressPairs> filteredAAPs, Action action) {
413         // Do not proceed further if Port Up OR down event.
414         if (action != Action.UPDATE) {
415             return false;
416         }
417         // exclude multicastAAPs from PortBefore/PortAfter AAPs
418         List<AllowedAddressPairs> excludeMulticastAAPs = AclServiceUtils.excludeMulticastAAPs(allowedAddresses);
419         // GET Delta of ADDED/DELETED aaps with PortBefore/PortAfter-AAPs
420         List<AllowedAddressPairs> filteredAllowedAddresses = excludeMulticastAAPs.stream().filter(
421             aap -> !filteredAAPs.contains(aap)).collect(Collectors.toList());
422         Set<MacAddress> macs = filteredAAPs.stream().map(aap -> aap.getMacAddress()).collect(Collectors.toSet());
423         List<AllowedAddressPairs> aapWithDuplicateMac = filteredAllowedAddresses.stream()
424             .filter(entry -> macs.contains(entry.getMacAddress())).collect(Collectors.toList());
425
426         return !aapWithDuplicateMac.isEmpty();
427     }
428
429     @Override
430     protected boolean isValidDirection(Class<? extends DirectionBase> direction) {
431         return direction.equals(DirectionEgress.class);
432     }
433
434     private short getAclAntiSpoofingTable() {
435         return NwConstants.INGRESS_ACL_ANTI_SPOOFING_TABLE;
436     }
437
438     private short getAclConntrackClassifierTable() {
439         return NwConstants.INGRESS_ACL_CONNTRACK_CLASSIFIER_TABLE;
440     }
441
442     @Override
443     protected short getAclConntrackSenderTable() {
444         return NwConstants.INGRESS_ACL_CONNTRACK_SENDER_TABLE;
445     }
446
447     @Override
448     protected short getAclForExistingTrafficTable() {
449         return NwConstants.INGRESS_ACL_FOR_EXISTING_TRAFFIC_TABLE;
450     }
451
452     @Override
453     protected short getAclFilterCumDispatcherTable() {
454         return NwConstants.INGRESS_ACL_FILTER_CUM_DISPATCHER_TABLE;
455     }
456
457     @Override
458     protected short getAclRuleBasedFilterTable() {
459         return NwConstants.INGRESS_ACL_RULE_BASED_FILTER_TABLE;
460     }
461
462     @Override
463     protected short getAclRemoteAclTable() {
464         return NwConstants.INGRESS_REMOTE_ACL_TABLE;
465     }
466
467     @Override
468     protected short getAclCommitterTable() {
469         return NwConstants.INGRESS_ACL_COMMITTER_TABLE;
470     }
471 }