X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnservice%2Faclservice%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Faclservice%2FAbstractAclServiceImpl.java;h=f4c6e72cd3be390172541d10a51fe01ccf6766ec;hb=96a39c19c225d5df70ec56da4868d7a403d293b8;hp=57cc010fd84cafde43ff6c1b3123cd0744256bcd;hpb=06d3b0d63d7cab796af20e6c91491b6f9d7d8c01;p=netvirt.git diff --git a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java index 57cc010fd8..f4c6e72cd3 100644 --- a/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java +++ b/vpnservice/aclservice/impl/src/main/java/org/opendaylight/netvirt/aclservice/AbstractAclServiceImpl.java @@ -8,21 +8,32 @@ package org.opendaylight.netvirt.aclservice; import java.math.BigInteger; +import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.genius.mdsalutil.ActionInfo; +import org.opendaylight.genius.mdsalutil.ActionType; import org.opendaylight.genius.mdsalutil.FlowEntity; import org.opendaylight.genius.mdsalutil.InstructionInfo; +import org.opendaylight.genius.mdsalutil.InstructionType; import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.genius.mdsalutil.MatchInfoBase; import org.opendaylight.genius.mdsalutil.NwConstants; import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; import org.opendaylight.netvirt.aclservice.api.AclServiceListener; +import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action; +import org.opendaylight.netvirt.aclservice.api.utils.AclInterface; +import org.opendaylight.netvirt.aclservice.api.utils.AclInterfaceCacheUtil; +import org.opendaylight.netvirt.aclservice.utils.AclConstants; +import org.opendaylight.netvirt.aclservice.utils.AclDataUtil; import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeEgress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,47 +41,50 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener { private static final Logger LOG = LoggerFactory.getLogger(AbstractAclServiceImpl.class); - private final IMdsalApiManager mdsalManager; - private final OdlInterfaceRpcService interfaceManager; - private final DataBroker dataBroker; + protected final IMdsalApiManager mdsalManager; + protected final DataBroker dataBroker; + protected final Class serviceMode; /** * Initialize the member variables. - * @param dataBroker the data broker instance. - * @param interfaceManager the interface manager instance. - * @param mdsalManager the mdsal manager instance. + * + * @param serviceMode + * the service mode + * @param dataBroker + * the data broker instance. + * @param mdsalManager + * the mdsal manager instance. */ - public AbstractAclServiceImpl(DataBroker dataBroker, OdlInterfaceRpcService interfaceManager, - IMdsalApiManager mdsalManager) { + public AbstractAclServiceImpl(Class serviceMode, DataBroker dataBroker, + IMdsalApiManager mdsalManager) { this.dataBroker = dataBroker; - this.interfaceManager = interfaceManager; this.mdsalManager = mdsalManager; + this.serviceMode = serviceMode; } @Override - public boolean applyAcl(Interface port) { - - if (!AclServiceUtils.isPortSecurityEnabled(port)) { + public boolean applyAcl(AclInterface port) { + if (port == null) { + LOG.error("port cannot be null"); + return false; + } + BigInteger dpId = port.getDpId(); + if (dpId == null || port.getLPortTag() == null) { + LOG.error("Unable to find DP Id from ACL interface with id {}", port.getInterfaceId()); return false; } - BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName()); - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface - interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName()); - String attachMac = interfaceState.getPhysAddress().getValue(); - programFixedRules(dpId, "", attachMac, NwConstants.ADD_FLOW); - List aclUuidList = AclServiceUtils.getInterfaceAcls(port); - programAclRules(aclUuidList, dpId, attachMac,NwConstants.ADD_FLOW ); - // TODO: uncomment bindservice() when the acl flow programming is - // implemented - // bindService(port.getName()); + programAclWithAllowedAddress(dpId, port.getAllowedAddressPairs(), port.getLPortTag(), port.getSecurityGroups(), + Action.ADD, NwConstants.ADD_FLOW, port.getInterfaceId()); + + bindService(port.getInterfaceId()); return true; } @Override - public boolean updateAcl(Interface portBefore, Interface portAfter) { + public boolean updateAcl(AclInterface portBefore, AclInterface portAfter) { boolean result = false; - boolean isPortSecurityEnable = AclServiceUtils.isPortSecurityEnabled(portAfter); - boolean isPortSecurityEnableBefore = AclServiceUtils.isPortSecurityEnabled(portBefore); + boolean isPortSecurityEnable = portAfter.getPortSecurityEnabled(); + boolean isPortSecurityEnableBefore = portBefore.getPortSecurityEnabled(); // if port security is changed, apply/remove Acls if (isPortSecurityEnableBefore != isPortSecurityEnable) { if (isPortSecurityEnable) { @@ -80,88 +94,128 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener { } } else if (isPortSecurityEnable) { // Acls has been updated, find added/removed Acls and act accordingly. - this.processInterfaceUpdate(portBefore, portAfter); + processInterfaceUpdate(portBefore, portAfter); } return result; } - private void processInterfaceUpdate(Interface portBefore, Interface portAfter) { - List addedAcls = AclServiceUtils.getUpdatedAclList(portAfter, portBefore); - List deletedAcls = AclServiceUtils.getUpdatedAclList(portBefore, portAfter); + private void processInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) { + BigInteger dpId = portAfter.getDpId(); + List addedAllowedAddressPairs = + AclServiceUtils.getUpdatedAllowedAddressPairs(portAfter.getAllowedAddressPairs(), + portBefore.getAllowedAddressPairs()); + List deletedAllowedAddressPairs = + AclServiceUtils.getUpdatedAllowedAddressPairs(portBefore.getAllowedAddressPairs(), + portAfter.getAllowedAddressPairs()); + if (addedAllowedAddressPairs != null && !addedAllowedAddressPairs.isEmpty()) { + programAclWithAllowedAddress(dpId, addedAllowedAddressPairs, portAfter.getLPortTag(), + portAfter.getSecurityGroups(), Action.UPDATE, NwConstants.ADD_FLOW, portAfter.getInterfaceId()); + } + if (deletedAllowedAddressPairs != null && !deletedAllowedAddressPairs.isEmpty()) { + programAclWithAllowedAddress(dpId, deletedAllowedAddressPairs, portAfter.getLPortTag(), + portAfter.getSecurityGroups(), Action.UPDATE, NwConstants.DEL_FLOW, portAfter.getInterfaceId()); + } + + List addedAcls = AclServiceUtils.getUpdatedAclList(portAfter.getSecurityGroups(), + portBefore.getSecurityGroups()); + List deletedAcls = AclServiceUtils.getUpdatedAclList(portBefore.getSecurityGroups(), + portAfter.getSecurityGroups()); if (addedAcls != null && !addedAcls.isEmpty()) { - updateCustomRules(portAfter, addedAcls, NwConstants.ADD_FLOW); + updateCustomRules(dpId, portAfter.getLPortTag(), addedAcls, NwConstants.ADD_FLOW, + portAfter.getInterfaceId(), portAfter.getAllowedAddressPairs()); } if (deletedAcls != null && !deletedAcls.isEmpty()) { - updateCustomRules(portAfter, deletedAcls, NwConstants.DEL_FLOW); + updateCustomRules(dpId, portAfter.getLPortTag(), deletedAcls, NwConstants.DEL_FLOW, + portAfter.getInterfaceId(), portAfter.getAllowedAddressPairs()); } } - private void updateCustomRules(Interface portAfter, List aclUuidList, int action) { - BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, portAfter.getName()); - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface - interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, portAfter.getName()); - String attachMac = interfaceState.getPhysAddress().getValue(); - programAclRules(aclUuidList, dpId, attachMac, action); + private void updateCustomRules(BigInteger dpId, int lportTag, List aclUuidList, int action, + String portId, List syncAllowedAddresses) { + programAclRules(aclUuidList, dpId, lportTag, action, portId); + syncRemoteAclRules(aclUuidList, action, portId, syncAllowedAddresses); + } + + private void syncRemoteAclRules(List aclUuidList, int action, String currentPortId, + List syncAllowedAddresses) { + for (Uuid remoteAclId : aclUuidList) { + Set portSet = AclDataUtil.getRemoteAclInterfaces(remoteAclId); + if (portSet == null) { + continue; + } + for (String remotePortId : portSet) { + AclInterface port = AclInterfaceCacheUtil.getAclInterfaceFromCache(remotePortId); + if (currentPortId.equals(port.getInterfaceId())) { + continue; + } + List remoteAceList = AclServiceUtils.getAceWithRemoteAclId(dataBroker, port, remoteAclId); + for (Ace ace : remoteAceList) { + programAceRule(port.getDpId(), port.getLPortTag(), action, ace, port.getInterfaceId(), + syncAllowedAddresses); + } + } + } + } + + private void programAclWithAllowedAddress(BigInteger dpId, List allowedAddresses, + int lportTag, List aclUuidList, Action action, int addOrRemove, + String portId) { + programFixedRules(dpId, "", allowedAddresses, lportTag, action, addOrRemove); + if (action == Action.ADD || action == Action.REMOVE) { + programAclRules(aclUuidList, dpId, lportTag, addOrRemove, portId); + } + syncRemoteAclRules(aclUuidList, addOrRemove, portId, allowedAddresses); } + @Override - public boolean removeAcl(Interface port) { - if (!AclServiceUtils.isPortSecurityEnabled(port)) { + public boolean removeAcl(AclInterface port) { + BigInteger dpId = port.getDpId(); + if (dpId == null) { + LOG.error("Unable to find DP Id from ACL interface with id {}", port.getInterfaceId()); return false; } - BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName()); - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface - interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName()); - String attachMac = interfaceState.getPhysAddress().getValue(); - programFixedRules(dpId, "", attachMac, NwConstants.DEL_FLOW); - List aclUuidList = AclServiceUtils.getInterfaceAcls(port); - programAclRules(aclUuidList, dpId, attachMac,NwConstants.DEL_FLOW ); - - // TODO: uncomment unbindService() when the acl flow programming is - // implemented - // unbindService(port.getName()); + programAclWithAllowedAddress(dpId, port.getAllowedAddressPairs(), port.getLPortTag(), port.getSecurityGroups(), + Action.REMOVE, NwConstants.DEL_FLOW, port.getInterfaceId()); + + unbindService(port.getInterfaceId()); return true; } @Override - public boolean applyAce(Interface port, Ace ace) { - if (!AclServiceUtils.isPortSecurityEnabled(port)) { + public boolean applyAce(AclInterface port, Ace ace) { + if (!port.isPortSecurityEnabled()) { return false; } - BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName()); - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface - interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName()); - String attachMac = interfaceState.getPhysAddress().getValue(); - programAceRule(dpId, attachMac, NwConstants.ADD_FLOW, ace); + programAceRule(port.getDpId(), port.getLPortTag(), NwConstants.ADD_FLOW, ace, + port.getInterfaceId(), null); return true; } @Override - public boolean removeAce(Interface port, Ace ace) { - if (!AclServiceUtils.isPortSecurityEnabled(port)) { + public boolean removeAce(AclInterface port, Ace ace) { + if (!port.isPortSecurityEnabled()) { return false; } - BigInteger dpId = AclServiceUtils.getDpnForInterface(interfaceManager, port.getName()); - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface - interfaceState = AclServiceUtils.getInterfaceStateFromOperDS(dataBroker, port.getName()); - String attachMac = interfaceState.getPhysAddress().getValue(); - programAceRule(dpId, attachMac, NwConstants.DEL_FLOW, ace); + programAceRule(port.getDpId(), port.getLPortTag(), NwConstants.DEL_FLOW, ace, + port.getInterfaceId(), null); return true; } - /** * Bind service. * - * @param interfaceName the interface name + * @param interfaceName + * the interface name */ protected abstract void bindService(String interfaceName); /** * Unbind service. * - * @param interfaceName the interface name + * @param interfaceName + * the interface name */ protected abstract void unbindService(String interfaceName); @@ -170,60 +224,112 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener { * * @param dpid the dpid * @param dhcpMacAddress the dhcp mac address. - * @param attachMac The vm mac address + * @param allowedAddresses the allowed addresses + * @param lportTag the lport tag + * @param action add/modify/remove action * @param addOrRemove addorRemove */ protected abstract void programFixedRules(BigInteger dpid, String dhcpMacAddress, - String attachMac, int addOrRemove); + List allowedAddresses, int lportTag, Action action, int addOrRemove); /** * Programs the acl custom rules. * * @param aclUuidList the list of acl uuid to be applied * @param dpId the dpId - * @param attachMac the attached mac + * @param lportTag the lport tag * @param addOrRemove whether to delete or add flow */ - protected abstract void programAclRules(List aclUuidList, BigInteger dpId, String attachMac, - int addOrRemove); + protected abstract boolean programAclRules(List aclUuidList, BigInteger dpId, int lportTag, int addOrRemove, + String portId); /** * Programs the ace custom rule. * * @param dpId the dpId - * @param attachMac the attached mac + * @param lportTag the lport tag * @param addOrRemove whether to delete or add flow * @param ace rule to be program */ - protected abstract void programAceRule(BigInteger dpId, String attachMac, int addOrRemove, Ace ace); + protected abstract void programAceRule(BigInteger dpId, int lportTag, int addOrRemove, Ace ace, String portId, + List syncAllowedAddresses); /** * Writes/remove the flow to/from the datastore. - * @param dpId the dpId - * @param tableId the tableId - * @param flowId the flowId - * @param priority the priority - * @param flowName the flow name - * @param idleTimeOut the idle timeout - * @param hardTimeOut the hard timeout - * @param cookie the cookie - * @param matches the list of matches to be writted - * @param instructions the list of instruction to be written. - * @param addOrRemove add or remove the entries. + * + * @param dpId + * the dpId + * @param tableId + * the tableId + * @param flowId + * the flowId + * @param priority + * the priority + * @param flowName + * the flow name + * @param idleTimeOut + * the idle timeout + * @param hardTimeOut + * the hard timeout + * @param cookie + * the cookie + * @param matches + * the list of matches to be writted + * @param instructions + * the list of instruction to be written. + * @param addOrRemove + * add or remove the entries. */ protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName, - int idleTimeOut, int hardTimeOut, BigInteger cookie, List matches, - List instructions, int addOrRemove) { + int idleTimeOut, int hardTimeOut, BigInteger cookie, List matches, + List instructions, int addOrRemove) { if (addOrRemove == NwConstants.DEL_FLOW) { - FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId,flowId, - priority, flowName , idleTimeOut, hardTimeOut, cookie, matches, null); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName, idleTimeOut, + hardTimeOut, cookie, matches, null); LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId); mdsalManager.removeFlow(flowEntity); } else { - FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, - priority, flowName, idleTimeOut, hardTimeOut, cookie, matches, instructions); + FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName, idleTimeOut, + hardTimeOut, cookie, matches, instructions); LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId); mdsalManager.installFlow(flowEntity); } } + + /** + * Gets the dispatcher table resubmit instructions based on ingress/egress + * service mode w.r.t switch. + * + * @param actionsInfos the actions infos + * @return the instructions for dispatcher table resubmit + */ + protected List getDispatcherTableResubmitInstructions(List actionsInfos) { + short dispatcherTableId = NwConstants.LPORT_DISPATCHER_TABLE; + if (ServiceModeEgress.class.equals(this.serviceMode)) { + dispatcherTableId = AclConstants.EGRESS_LPORT_DISPATCHER_TABLE; + } + + List instructions = new ArrayList<>(); + actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[] {Short.toString(dispatcherTableId)})); + instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos)); + return instructions; + } + + protected String getOperAsString(int flowOper) { + String oper; + switch (flowOper) { + case NwConstants.ADD_FLOW: + oper = "Add"; + break; + case NwConstants.DEL_FLOW: + oper = "Del"; + break; + case NwConstants.MOD_FLOW: + oper = "Mod"; + break; + default: + oper = "UNKNOWN"; + } + return oper; + } }