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.List;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.genius.mdsalutil.FlowEntity;
15 import org.opendaylight.genius.mdsalutil.InstructionInfo;
16 import org.opendaylight.genius.mdsalutil.MDSALUtil;
17 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
18 import org.opendaylight.genius.mdsalutil.NwConstants;
19 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
20 import org.opendaylight.netvirt.aclservice.api.AclServiceListener;
21 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 public abstract class AbstractAclServiceImpl implements AclServiceListener {
31 private static final Logger LOG = LoggerFactory.getLogger(AbstractAclServiceImpl.class);
33 private final IMdsalApiManager mdsalManager;
34 private final OdlInterfaceRpcService interfaceManager;
35 private final DataBroker dataBroker;
38 * Initialize the member variables.
39 * @param dataBroker the data broker instance.
40 * @param interfaceManager the interface manager instance.
41 * @param mdsalManager the mdsal manager instance.
43 public AbstractAclServiceImpl(DataBroker dataBroker, OdlInterfaceRpcService interfaceManager,
44 IMdsalApiManager mdsalManager) {
45 this.dataBroker = dataBroker;
46 this.interfaceManager = interfaceManager;
47 this.mdsalManager = mdsalManager;
51 public boolean applyAcl(Interface port) {
53 if (!AclServiceUtils.isPortSecurityEnabled(port)) {
56 BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName());
57 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
58 interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName());
59 String attachMac = interfaceState.getPhysAddress().getValue();
60 programFixedRules(dpId, "", attachMac, NwConstants.ADD_FLOW);
61 List<Uuid> aclUuidList = AclServiceUtils.getInterfaceAcls(port);
62 programAclRules(aclUuidList, dpId, attachMac,NwConstants.ADD_FLOW );
63 // TODO: uncomment bindservice() when the acl flow programming is
65 // bindService(port.getName());
70 public boolean updateAcl(Interface portBefore, Interface portAfter) {
71 boolean result = false;
72 boolean isPortSecurityEnable = AclServiceUtils.isPortSecurityEnabled(portAfter);
73 boolean isPortSecurityEnableBefore = AclServiceUtils.isPortSecurityEnabled(portBefore);
74 // if port security is changed, apply/remove Acls
75 if (isPortSecurityEnableBefore != isPortSecurityEnable) {
76 if (isPortSecurityEnable) {
77 result = applyAcl(portAfter);
79 result = removeAcl(portAfter);
81 } else if (isPortSecurityEnable) {
82 // Acls has been updated, find added/removed Acls and act accordingly.
83 this.processInterfaceUpdate(portBefore, portAfter);
89 private void processInterfaceUpdate(Interface portBefore, Interface portAfter) {
90 List<Uuid> addedAcls = AclServiceUtils.getUpdatedAclList(portAfter, portBefore);
91 List<Uuid> deletedAcls = AclServiceUtils.getUpdatedAclList(portBefore, portAfter);
92 if (addedAcls != null && !addedAcls.isEmpty()) {
93 updateCustomRules(portAfter, addedAcls, NwConstants.ADD_FLOW);
95 if (deletedAcls != null && !deletedAcls.isEmpty()) {
96 updateCustomRules(portAfter, deletedAcls, NwConstants.DEL_FLOW);
100 private void updateCustomRules(Interface portAfter, List<Uuid> aclUuidList, int action) {
101 BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, portAfter.getName());
102 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
103 interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, portAfter.getName());
104 String attachMac = interfaceState.getPhysAddress().getValue();
105 programAclRules(aclUuidList, dpId, attachMac, action);
109 public boolean removeAcl(Interface port) {
110 if (!AclServiceUtils.isPortSecurityEnabled(port)) {
113 BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName());
114 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
115 interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName());
116 String attachMac = interfaceState.getPhysAddress().getValue();
117 programFixedRules(dpId, "", attachMac, NwConstants.DEL_FLOW);
118 List<Uuid> aclUuidList = AclServiceUtils.getInterfaceAcls(port);
119 programAclRules(aclUuidList, dpId, attachMac,NwConstants.DEL_FLOW );
121 // TODO: uncomment unbindService() when the acl flow programming is
123 // unbindService(port.getName());
128 public boolean applyAce(Interface port, Ace ace) {
129 if (!AclServiceUtils.isPortSecurityEnabled(port)) {
132 BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName());
133 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
134 interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName());
135 String attachMac = interfaceState.getPhysAddress().getValue();
136 programAceRule(dpId, attachMac, NwConstants.ADD_FLOW, ace);
141 public boolean removeAce(Interface port, Ace ace) {
142 if (!AclServiceUtils.isPortSecurityEnabled(port)) {
145 BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName());
146 org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface
147 interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName());
148 String attachMac = interfaceState.getPhysAddress().getValue();
149 programAceRule(dpId, attachMac, NwConstants.DEL_FLOW, ace);
157 * @param interfaceName the interface name
159 protected abstract void bindService(String interfaceName);
164 * @param interfaceName the interface name
166 protected abstract void unbindService(String interfaceName);
169 * Program the default anti-spoofing rule and the conntrack rules.
171 * @param dpid the dpid
172 * @param dhcpMacAddress the dhcp mac address.
173 * @param attachMac The vm mac address
174 * @param addOrRemove addorRemove
176 protected abstract void programFixedRules(BigInteger dpid, String dhcpMacAddress,
177 String attachMac, int addOrRemove);
180 * Programs the acl custom rules.
182 * @param aclUuidList the list of acl uuid to be applied
183 * @param dpId the dpId
184 * @param attachMac the attached mac
185 * @param addOrRemove whether to delete or add flow
187 protected abstract void programAclRules(List<Uuid> aclUuidList, BigInteger dpId, String attachMac,
191 * Programs the ace custom rule.
193 * @param dpId the dpId
194 * @param attachMac the attached mac
195 * @param addOrRemove whether to delete or add flow
196 * @param ace rule to be program
198 protected abstract void programAceRule(BigInteger dpId, String attachMac, int addOrRemove, Ace ace);
201 * Writes/remove the flow to/from the datastore.
202 * @param dpId the dpId
203 * @param tableId the tableId
204 * @param flowId the flowId
205 * @param priority the priority
206 * @param flowName the flow name
207 * @param idleTimeOut the idle timeout
208 * @param hardTimeOut the hard timeout
209 * @param cookie the cookie
210 * @param matches the list of matches to be writted
211 * @param instructions the list of instruction to be written.
212 * @param addOrRemove add or remove the entries.
214 protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
215 int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
216 List<InstructionInfo> instructions, int addOrRemove) {
217 if (addOrRemove == NwConstants.DEL_FLOW) {
218 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId,
219 priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null);
220 LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
221 mdsalManager.removeFlow(flowEntity);
223 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId,
224 priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions);
225 LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
226 mdsalManager.installFlow(flowEntity);