2 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netvirt.aclservice;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.List;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.genius.mdsalutil.ActionInfo;
17 import org.opendaylight.genius.mdsalutil.InstructionInfo;
18 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
19 import org.opendaylight.genius.mdsalutil.NwConstants;
20 import org.opendaylight.genius.mdsalutil.NxMatchFieldType;
21 import org.opendaylight.genius.mdsalutil.NxMatchInfo;
22 import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
23 import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
24 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
25 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetSource;
26 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
27 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
28 import org.opendaylight.netvirt.aclservice.utils.AclConstants;
29 import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
30 import org.opendaylight.netvirt.aclservice.utils.AclServiceOFFlowBuilder;
31 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Provides the stateful implementation for egress (w.r.t VM) ACL service.
43 * Note: Table names used are w.r.t switch. Hence, switch ingress is VM egress
46 public class StatefulEgressAclServiceImpl extends AbstractEgressAclServiceImpl {
48 private static final Logger LOG = LoggerFactory.getLogger(StatefulEgressAclServiceImpl.class);
50 public StatefulEgressAclServiceImpl(DataBroker dataBroker, IMdsalApiManager mdsalManager, AclDataUtil aclDataUtil,
51 AclServiceUtils aclServiceUtils) {
52 super(dataBroker, mdsalManager, aclDataUtil, aclServiceUtils);
56 * Program conntrack rules.
58 * @param dpid the dpid
59 * @param dhcpMacAddress the dhcp mac address.
60 * @param allowedAddresses the allowed addresses
61 * @param lportTag the lport tag
62 * @param addOrRemove addorRemove
65 protected void programSpecificFixedRules(BigInteger dpid, String dhcpMacAddress,
66 List<AllowedAddressPairs> allowedAddresses, int lportTag, String portId, Action action, int addOrRemove) {
67 programEgressAclFixedConntrackRule(dpid, allowedAddresses, lportTag, portId, action, addOrRemove);
71 protected String syncSpecificAclFlow(BigInteger dpId, int lportTag, int addOrRemove, Ace ace, String portId,
72 Map<String, List<MatchInfoBase>> flowMap, String flowName) {
73 List<MatchInfoBase> matches = flowMap.get(flowName);
74 flowName += "Egress" + lportTag + ace.getKey().getRuleName();
75 matches.add(AclServiceUtils.buildLPortTagMatch(lportTag));
76 matches.add(new NxMatchInfo(NxMatchFieldType.ct_state,
77 new long[] {AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK}));
79 Long elanId = AclServiceUtils.getElanIdFromInterface(portId, dataBroker);
80 List<ActionInfo> actionsInfos = new ArrayList<>();
81 actionsInfos.add(new ActionNxConntrack(2, 1, 0, elanId.intValue(), (short) 255));
82 List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(actionsInfos);
84 // For flows related remote ACL, unique flow priority is used for
85 // each flow to avoid overlapping flows
86 int priority = getEgressSpecificAclFlowPriority(dpId, addOrRemove, flowName);
88 syncFlow(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE, flowName, priority, "ACL", 0, 0,
89 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
93 private int getEgressSpecificAclFlowPriority(BigInteger dpId, int addOrRemove, String flowName) {
95 if (addOrRemove == NwConstants.DEL_FLOW) {
96 priority = aclServiceUtils.releaseAndRemoveFlowPriorityFromCache(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
99 priority = aclServiceUtils.allocateAndSaveFlowPriorityInCache(dpId, NwConstants.INGRESS_ACL_FILTER_TABLE,
106 * Adds the rule to send the packet to the netfilter to check whether it is
109 * @param dpId the dpId
110 * @param allowedAddresses the allowed addresses
111 * @param priority the priority of the flow
112 * @param flowId the flowId
113 * @param conntrackState the conntrack state of the packets thats should be
115 * @param conntrackMask the conntrack mask
116 * @param portId the portId
117 * @param addOrRemove whether to add or remove the flow
119 private void programConntrackRecircRules(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses,
120 Integer priority, String flowId, String portId, int addOrRemove) {
121 for (AllowedAddressPairs allowedAddress : allowedAddresses) {
122 IpPrefixOrAddress attachIp = allowedAddress.getIpAddress();
123 MacAddress attachMac = allowedAddress.getMacAddress();
125 List<MatchInfoBase> matches = new ArrayList<>();
126 matches.add(new MatchEthernetSource(attachMac));
127 matches.addAll(AclServiceUtils.buildIpMatches(attachIp, MatchCriteria.MATCH_SOURCE));
129 Long elanTag = AclServiceUtils.getElanIdFromInterface(portId, dataBroker);
130 List<InstructionInfo> instructions = new ArrayList<>();
131 List<ActionInfo> actionsInfos = new ArrayList<>();
132 actionsInfos.add(new ActionNxConntrack(2, 0, 0, elanTag.intValue(), NwConstants.INGRESS_ACL_FILTER_TABLE));
133 instructions.add(new InstructionApplyActions(actionsInfos));
135 String flowName = "Egress_Fixed_Conntrk_" + dpId + "_" + attachMac.getValue() + "_"
136 + String.valueOf(attachIp.getValue()) + "_" + flowId;
137 syncFlow(dpId, NwConstants.INGRESS_ACL_TABLE, flowName, AclConstants.PROTO_MATCH_PRIORITY, "ACL", 0, 0,
138 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
143 * Programs the default connection tracking rules.
145 * @param dpid the dp id
146 * @param allowedAddresses the allowed addresses
147 * @param lportTag the lport tag
148 * @param portId the portId
149 * @param action the action
150 * @param write whether to add or remove the flow.
152 private void programEgressAclFixedConntrackRule(BigInteger dpid, List<AllowedAddressPairs> allowedAddresses,
153 int lportTag, String portId, Action action, int write) {
154 programConntrackRecircRules(dpid, allowedAddresses, AclConstants.CT_STATE_UNTRACKED_PRIORITY,
155 "Recirc", portId, write);
156 programEgressConntrackDropRules(dpid, lportTag, write);
157 LOG.info("programEgressAclFixedConntrackRule : default connection tracking rule are added.");
161 * Adds the rule to drop the unknown/invalid packets .
163 * @param dpId the dpId
164 * @param lportTag the lport tag
165 * @param priority the priority of the flow
166 * @param flowId the flowId
167 * @param conntrackState the conntrack state of the packets thats should be
169 * @param conntrackMask the conntrack mask
170 * @param tableId table id
171 * @param addOrRemove whether to add or remove the flow
173 private void programConntrackDropRule(BigInteger dpId, int lportTag, Integer priority, String flowId,
174 int conntrackState, int conntrackMask, int addOrRemove) {
175 List<MatchInfoBase> matches = AclServiceOFFlowBuilder.addLPortTagMatches(lportTag, conntrackState,
177 List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
179 flowId = "Egress_Fixed_Conntrk_Drop" + dpId + "_" + lportTag + "_" + flowId;
180 syncFlow(dpId, NwConstants.EGRESS_ACL_FILTER_TABLE, flowId, priority, "ACL", 0, 0,
181 AclConstants.COOKIE_ACL_DROP_FLOW, matches, instructions, addOrRemove);
185 * Adds the rules to drop the unknown/invalid packets .
187 * @param dpId the dpId
188 * @param lportTag the lport tag
189 * @param addOrRemove whether to add or remove the flow
191 private void programEgressConntrackDropRules(BigInteger dpId, int lportTag, int addOrRemove) {
192 programConntrackDropRule(dpId, lportTag, AclConstants.CT_STATE_TRACKED_NEW_DROP_PRIORITY, "Tracked_New",
193 AclConstants.TRACKED_NEW_CT_STATE, AclConstants.TRACKED_NEW_CT_STATE_MASK, addOrRemove);
194 programConntrackDropRule(dpId, lportTag, AclConstants.CT_STATE_TRACKED_INVALID_PRIORITY, "Tracked_Invalid",
195 AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, addOrRemove);