X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=interfacemanager%2Finterfacemanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgenius%2Finterfacemanager%2Fservicebindings%2Fflowbased%2Futilities%2FFlowBasedServicesUtils.java;h=4beb1586b88124bb97992037397fb19887e9f6bf;hb=2c09ea59c20f55eff03f858b431e8805996423ce;hp=fc49004c986328a4122ae511607a2265e56b2747;hpb=1dfb34b5c6b47c27f39407c986deac6c4634ec7b;p=genius.git diff --git a/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java b/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java index fc49004c9..4beb1586b 100644 --- a/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java +++ b/interfacemanager/interfacemanager-impl/src/main/java/org/opendaylight/genius/interfacemanager/servicebindings/flowbased/utilities/FlowBasedServicesUtils.java @@ -13,6 +13,7 @@ import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; @@ -48,6 +49,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.SplitHorizon; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.BoundServicesStateList; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings; 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; @@ -55,6 +57,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceTypeFlowBased; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflow; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.StypeOpenflowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.bound.services.state.list.BoundServicesState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.bound.services.state.list.BoundServicesStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.bound.services.state.list.BoundServicesStateKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfo; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.ServicesInfoKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices; @@ -130,10 +135,10 @@ public class FlowBasedServicesUtils { matches.add(new MatchInPort(dpId, portNo)); int vlanId = 0; IfL2vlan l2vlan = iface.getAugmentation(IfL2vlan.class); - if (l2vlan != null && l2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Transparent) { + if (l2vlan != null) { vlanId = l2vlan.getVlanId() == null ? 0 : l2vlan.getVlanId().getValue(); } - if (vlanId > 0) { + if (vlanId >= 0 && l2vlan.getL2vlanMode() != IfL2vlan.L2vlanMode.Transparent) { matches.add(new MatchVlanVid(vlanId)); } return matches; @@ -207,8 +212,8 @@ public class FlowBasedServicesUtils { } String serviceRef = boundServiceNew.getServiceName(); - String flowRef = getFlowRef(dpId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, iface.getName(), boundServiceNew, - boundServiceNew.getServicePriority()); + String flowRef = getFlowRef(dpId, NwConstants.VLAN_INTERFACE_INGRESS_TABLE, iface.getName(), + boundServiceNew, boundServiceNew.getServicePriority()); StypeOpenflow stypeOpenflow = boundServiceNew.getAugmentation(StypeOpenflow.class); Flow ingressFlow = MDSALUtil.buildFlowNew(tableId, flowRef, stypeOpenflow.getFlowPriority(), serviceRef, 0, 0, stypeOpenflow.getFlowCookie(), matches, instructionSet); @@ -234,7 +239,6 @@ public class FlowBasedServicesUtils { public static void installLPortDispatcherFlow(BigInteger dpId, BoundServices boundService, String interfaceName, WriteTransaction writeTransaction, int interfaceTag, short currentServiceIndex, short nextServiceIndex) { - LOG.debug("Installing LPort Dispatcher Flow {}, {}", dpId, interfaceName); String serviceRef = boundService.getServiceName(); List matches = FlowBasedServicesUtils.getMatchInfoForDispatcherTable(dpId, interfaceTag, currentServiceIndex); @@ -268,17 +272,14 @@ public class FlowBasedServicesUtils { } } - ////////////////////////////////////////// - // FIXME: workaround for https://bugs.opendaylight.org/show_bug.cgi?id=7451 - int flowPriority = DEFAULT_DISPATCHER_PRIORITY; - ////////////////////////////////////////// - // build the flow and install it - String flowRef = getFlowRef(dpId, NwConstants.LPORT_DISPATCHER_TABLE, interfaceName, boundService, - currentServiceIndex); + String flowRef = getFlowRef(dpId, NwConstants.LPORT_DISPATCHER_TABLE, interfaceName, + boundService, currentServiceIndex); Flow ingressFlow = MDSALUtil.buildFlowNew(NwConstants.LPORT_DISPATCHER_TABLE, flowRef, - flowPriority, serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, + DEFAULT_DISPATCHER_PRIORITY, serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, instructions); + LOG.debug("Installing LPort Dispatcher Flow on DPN {}, for interface {}, with flowRef {}", dpId, + interfaceName, flowRef); installFlow(dpId, ingressFlow, writeTransaction); } @@ -302,48 +303,58 @@ public class FlowBasedServicesUtils { private static void installEgressDispatcherFlow(BigInteger dpId, BoundServices boundService, String interfaceName, WriteTransaction writeTransaction, int interfaceTag, short currentServiceIndex, short nextServiceIndex) { - String serviceRef = boundService.getServiceName(); - List matches = FlowBasedServicesUtils - .getMatchInfoForEgressDispatcherTable(interfaceTag, currentServiceIndex); - // Get the metadata and mask from the service's write metadata - // instruction - StypeOpenflow stypeOpenFlow = boundService.getAugmentation(StypeOpenflow.class); - List serviceInstructions = stypeOpenFlow.getInstruction(); - int instructionSize = serviceInstructions.size(); + // Get the metadata and mask from the service's write metadata instruction + StypeOpenflow stypeOpenflow = boundService.getAugmentation(StypeOpenflow.class); + if (stypeOpenflow == null) { + LOG.warn("Could not install egress dispatcher flow, missing service openflow configuration"); + return; + } + List serviceInstructions = stypeOpenflow.getInstruction() != null + ? stypeOpenflow.getInstruction() + : Collections.emptyList(); // build the final instruction for LPort Dispatcher table flow entry + List finalApplyActions = new ArrayList<>(); List instructions = new ArrayList<>(); if (boundService.getServicePriority() != ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME, NwConstants.DEFAULT_EGRESS_SERVICE_INDEX)) { BigInteger[] metadataValues = IfmUtil.mergeOpenflowMetadataWriteInstructions(serviceInstructions); BigInteger metadataMask = MetaDataUtil.getWriteMetaDataMaskForEgressDispatcherTable(); instructions.add(MDSALUtil.buildAndGetWriteMetadaInstruction(metadataValues[0], metadataMask, - ++instructionSize)); - instructions.add(MDSALUtil.buildAndGetSetReg6ActionInstruction(0, ++instructionSize, 0, 31, + instructions.size())); + finalApplyActions.add(MDSALUtil.createSetReg6Action(finalApplyActions.size(), 0, 31, MetaDataUtil.getReg6ValueForLPortDispatcher(interfaceTag, nextServiceIndex))); } - if (serviceInstructions != null && !serviceInstructions.isEmpty()) { - for (Instruction info : serviceInstructions) { + + final int applyActionsOffset = finalApplyActions.size(); + for (Instruction info : serviceInstructions) { + if (info.getInstruction() instanceof WriteActionsCase) { + List writeActions = ActionConverterUtil.convertServiceActionToFlowAction( + ((WriteActionsCase) info.getInstruction()).getWriteActions().getAction()); + instructions.add(MDSALUtil.buildWriteActionsInstruction(writeActions, instructions.size())); + } else if (info.getInstruction() instanceof ApplyActionsCase) { + List applyActions = ActionConverterUtil.convertServiceActionToFlowAction( + ((ApplyActionsCase) info.getInstruction()).getApplyActions().getAction(), + applyActionsOffset); + finalApplyActions.addAll(applyActions); + } else if (!(info.getInstruction() instanceof WriteMetadataCase)) { // Skip meta data write as that is handled already - if (info.getInstruction() instanceof WriteMetadataCase) { - continue; - } else if (info.getInstruction() instanceof WriteActionsCase) { - info = MDSALUtil.buildWriteActionsInstruction(ActionConverterUtil.convertServiceActionToFlowAction( - ((WriteActionsCase) info.getInstruction()).getWriteActions().getAction())); - } else if (info.getInstruction() instanceof ApplyActionsCase) { - info = MDSALUtil.buildApplyActionsInstruction(ActionConverterUtil.convertServiceActionToFlowAction( - ((ApplyActionsCase) info.getInstruction()).getApplyActions().getAction())); - } - instructions.add(info); + instructions.add(MDSALUtil.buildInstruction(info, instructions.size())); } } + if (!finalApplyActions.isEmpty()) { + instructions.add(MDSALUtil.buildApplyActionsInstruction(finalApplyActions, instructions.size())); + } // build the flow and install it + String serviceRef = boundService.getServiceName(); + List matches = FlowBasedServicesUtils + .getMatchInfoForEgressDispatcherTable(interfaceTag, currentServiceIndex); String flowRef = getFlowRef(dpId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, interfaceName, boundService, - currentServiceIndex); + currentServiceIndex); Flow egressFlow = MDSALUtil.buildFlowNew(NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, flowRef, - boundService.getServicePriority(), serviceRef, 0, 0, stypeOpenFlow.getFlowCookie(), matches, + boundService.getServicePriority(), serviceRef, 0, 0, stypeOpenflow.getFlowCookie(), matches, instructions); LOG.debug("Installing Egress Dispatcher Flow for interface : {}, with flow-ref : {}", interfaceName, flowRef); installFlow(dpId, egressFlow, writeTransaction); @@ -413,16 +424,31 @@ public class FlowBasedServicesUtils { } public static void bindDefaultEgressDispatcherService(DataBroker dataBroker, List> futures, - Interface interfaceInfo, String portNo, String interfaceName, int ifIndex) { + Interface interfaceInfo, String portNo, + String interfaceName, int ifIndex) { + List instructions = + IfmUtil.getEgressInstructionsForInterface(interfaceInfo, portNo, null, true, ifIndex, 0); + bindDefaultEgressDispatcherService(dataBroker, futures, interfaceName, instructions); + } + + public static void bindDefaultEgressDispatcherService(DataBroker dataBroker, List> futures, + Interface interfaceInfo, String interfaceName, int ifIndex, long groupId) { + List instructions = + IfmUtil.getEgressInstructionsForInterface(interfaceInfo, StringUtils.EMPTY, null, true, ifIndex, groupId); + bindDefaultEgressDispatcherService(dataBroker, futures, interfaceName, instructions); + } + + public static void bindDefaultEgressDispatcherService(DataBroker dataBroker, List> futures, + String interfaceName, List instructions) { WriteTransaction tx = dataBroker.newWriteOnlyTransaction(); int priority = ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME, - NwConstants.DEFAULT_EGRESS_SERVICE_INDEX); - List instructions = IfmUtil.getEgressInstructionsForInterface(interfaceInfo, portNo, null, true, - ifIndex); - BoundServices serviceInfo = getBoundServices(String.format("%s.%s", "default", interfaceName), - ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME, - NwConstants.DEFAULT_EGRESS_SERVICE_INDEX), - priority, NwConstants.EGRESS_DISPATCHER_TABLE_COOKIE, instructions); + NwConstants.DEFAULT_EGRESS_SERVICE_INDEX); + BoundServices + serviceInfo = + getBoundServices(String.format("%s.%s", "default", interfaceName), + ServiceIndex.getIndex(NwConstants.DEFAULT_EGRESS_SERVICE_NAME, + NwConstants.DEFAULT_EGRESS_SERVICE_INDEX), + priority, NwConstants.EGRESS_DISPATCHER_TABLE_COOKIE, instructions); IfmUtil.bindService(tx, interfaceName, serviceInfo, ServiceModeEgress.class); futures.add(tx.submit()); } @@ -468,7 +494,7 @@ public class FlowBasedServicesUtils { boundServicesOld.getAugmentation(StypeOpenflow.class); // build the flow and install it String flowRef = getFlowRef(dpId, NwConstants.LPORT_DISPATCHER_TABLE, iface, boundServicesOld, - currentServiceIndex); + currentServiceIndex); FlowKey flowKey = new FlowKey(new FlowId(flowRef)); Node nodeDpn = buildInventoryDpnNode(dpId); InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) @@ -490,7 +516,7 @@ public class FlowBasedServicesUtils { short currentServiceIndex, BoundServices boundServicesOld) { // build the flow and install it String flowRef = getFlowRef(dpId, NwConstants.EGRESS_LPORT_DISPATCHER_TABLE, iface, boundServicesOld, - currentServiceIndex); + currentServiceIndex); FlowKey flowKey = new FlowKey(new FlowId(flowRef)); Node nodeDpn = buildInventoryDpnNode(dpId); InstanceIdentifier flowInstanceId = InstanceIdentifier.builder(Nodes.class) @@ -521,16 +547,17 @@ public class FlowBasedServicesUtils { return String.format("%d:%s:%s", tableId, dpnId, infName); } - private static String getFlowRef(BigInteger dpnId, short tableId, String iface, BoundServices service, - short currentServiceIndex) { - return String.valueOf(dpnId) + tableId + NwConstants.FLOWID_SEPARATOR + iface + NwConstants.FLOWID_SEPARATOR - + currentServiceIndex; + private static String getFlowRef(BigInteger dpnId, short tableId, String iface,BoundServices service, + short currentServiceIndex) { + return String.valueOf(dpnId) + NwConstants.FLOWID_SEPARATOR + tableId + NwConstants.FLOWID_SEPARATOR + iface + + NwConstants.FLOWID_SEPARATOR + currentServiceIndex; } private static String getSplitHorizonFlowRef(BigInteger dpnId, short tableId, String iface, short currentServiceIndex, BigInteger shFlag) { - return new StringBuffer().append(dpnId).append(tableId).append(NwConstants.FLOWID_SEPARATOR).append(iface) - .append(NwConstants.FLOWID_SEPARATOR).append(shFlag.toString()).toString(); + return new StringBuffer().append(dpnId).append(NwConstants.FLOWID_SEPARATOR).append(tableId).append(NwConstants + .FLOWID_SEPARATOR).append(iface).append(NwConstants.FLOWID_SEPARATOR) + .append(shFlag.toString()).toString(); } /** @@ -630,6 +657,52 @@ public class FlowBasedServicesUtils { futures.add(inventoryConfigShardTransaction.submit()); } + public static BoundServicesState buildBoundServicesState( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface + interfaceState, Class serviceMode) { + NodeConnectorId nodeConnectorId = IfmUtil.getNodeConnectorIdFromInterface(interfaceState); + BigInteger dpId = IfmUtil.getDpnFromNodeConnectorId(nodeConnectorId); + long portNo = IfmUtil.getPortNumberFromNodeConnectorId(nodeConnectorId); + BoundServicesStateKey boundServicesStateKey = new BoundServicesStateKey(interfaceState.getName(), serviceMode); + return new BoundServicesStateBuilder().setDpid(dpId).setIfIndex(interfaceState.getIfIndex()) + .setInterfaceName(interfaceState.getName()).setInterfaceType(interfaceState.getType()).setPortNo(portNo) + .setServiceMode(serviceMode).setKey(boundServicesStateKey).build(); + } + + public static BoundServicesState getBoundServicesState(DataBroker dataBroker, + String interfaceName, + Class + serviceMode) { + InstanceIdentifier id = InstanceIdentifier.builder(BoundServicesStateList.class) + .child(BoundServicesState.class, new BoundServicesStateKey(interfaceName, serviceMode)).build(); + return IfmUtil.read(LogicalDatastoreType.OPERATIONAL, id, dataBroker).orNull(); + } + + public static void addBoundServicesState(List> futures, + DataBroker dataBroker, String interfaceName, + BoundServicesState interfaceBoundServicesState) { + LOG.info("adding bound-service state information for interface : {}, service-mode : {}", + interfaceBoundServicesState.getInterfaceName(), interfaceBoundServicesState.getServiceMode().getName()); + InstanceIdentifier id = InstanceIdentifier.builder(BoundServicesStateList.class) + .child(BoundServicesState.class, new BoundServicesStateKey(interfaceName, + interfaceBoundServicesState.getServiceMode())).build(); + WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction(); + writeTransaction.put(LogicalDatastoreType.OPERATIONAL, id, interfaceBoundServicesState, true); + futures.add(writeTransaction.submit()); + } + + public static void removeBoundServicesState(List> futures, + DataBroker dataBroker, + String interfaceName, Class serviceMode) { + LOG.info("remove bound-service state information for interface : {}, service-mode : {}", interfaceName, + serviceMode.getName()); + InstanceIdentifier id = InstanceIdentifier.builder(BoundServicesStateList.class) + .child(BoundServicesState.class, new BoundServicesStateKey(interfaceName, serviceMode)).build(); + WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction(); + writeTransaction.delete(LogicalDatastoreType.OPERATIONAL, id); + futures.add(writeTransaction.submit()); + } + private static boolean isExternal(Interface iface) { if (iface == null) { return false;