X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=utils%2Fmdsal-openflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Futils%2Fmdsal%2Fopenflow%2FInstructionUtils.java;h=4c59d45c555d382d70361647de70c6ff9620d4c6;hb=167d2bf5a154baf68f9c507341e44ad346433f04;hp=da480aa255f72158088f84b6c47182e6c2b1060a;hpb=575bbdf346277eaff628ceb619c76dcfdd1f2321;p=netvirt.git diff --git a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java index da480aa255..4c59d45c55 100644 --- a/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java +++ b/utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java @@ -1,10 +1,9 @@ /* - * Copyright (C) 2013 Red Hat, Inc. + * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html - * */ package org.opendaylight.ovsdb.utils.mdsal.openflow; @@ -44,6 +43,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; @@ -69,17 +70,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder; -import com.google.common.collect.Lists; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class InstructionUtils { - private static final Logger logger = LoggerFactory.getLogger(InstructionUtils.class); + private static final Logger LOG = LoggerFactory.getLogger(InstructionUtils.class); private static final int IPV4 = 0x8100; private static final int MAX_LENGTH = 0xffff; @@ -92,7 +92,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSendToControllerInstructions(String nodeName, InstructionBuilder ib) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); OutputActionBuilder output = new OutputActionBuilder(); @@ -125,7 +125,7 @@ public class InstructionUtils { public static InstructionBuilder createNormalInstructions(String nodeName, InstructionBuilder ib) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); OutputActionBuilder output = new OutputActionBuilder(); @@ -147,6 +147,35 @@ public class InstructionUtils { return ib; } + /** + * Create LOCAL Reserved Port Instruction + * + * @param ib Map InstructionBuilder without any instructions + * @param dpidLong Long the datapath ID of a switch/node + * @return ib Map InstructionBuilder with instructions + */ + public static InstructionBuilder createLocalInstructions(InstructionBuilder ib, long dpidLong) { + List actionList = new ArrayList<>(); + ActionBuilder ab = new ActionBuilder(); + + OutputActionBuilder output = new OutputActionBuilder(); + output.setOutputNodeConnector(new NodeConnectorId("openflow:" + dpidLong + ":" + + OutputPortValues.LOCAL.toString())); + ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build()); + ab.setOrder(0); + ab.setKey(new ActionKey(0)); + actionList.add(ab.build()); + + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + + // Wrap our Apply Action in an Instruction + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + + return ib; + } + /** * Create Output Port Instruction * @@ -158,10 +187,10 @@ public class InstructionUtils { public static InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, Long dpidLong, Long port) { NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port); - logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", + LOG.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} inPort={} ", dpidLong, port); - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); OutputActionBuilder oab = new OutputActionBuilder(); oab.setOutputNodeConnector(ncid); @@ -193,11 +222,11 @@ public class InstructionUtils { Long dpidLong, Long port, List instructions) { NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port); - logger.debug( + LOG.debug( "addOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); List existingActions; @@ -237,14 +266,17 @@ public class InstructionUtils { public static boolean removeOutputPortFromInstructions(InstructionBuilder ib, Long dpidLong, Long port, List instructions) { - NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port); - logger.debug( + final NodeConnectorId ncid = new NodeConnectorId("openflow:" + dpidLong + ":" + port); + final Uri ncidUri = new Uri(ncid); + LOG.debug( "removeOutputPortFromInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab; + // Start of by locating actions that will have port removed, from the existing instructionList + // List existingActions; if (instructions != null) { for (Instruction in : instructions) { @@ -256,38 +288,67 @@ public class InstructionUtils { } } - int index = 0; + int removedActionOrder = 0; boolean isPortDeleted = false; boolean removeFlow = true; + + // Locate specific action that has the port to be removed. Then, take note on its action order + // and remove it from list, in addition to flag that it was found. + // for (Action action : actionList) { if (action.getAction() instanceof OutputActionCase) { OutputActionCase opAction = (OutputActionCase) action.getAction(); - if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) { + if (opAction.getOutputAction().getOutputNodeConnector().equals(ncidUri)) { /* Find the output port in action list and remove */ - index = actionList.indexOf(action); + removedActionOrder = action.getOrder(); actionList.remove(action); isPortDeleted = true; break; } - removeFlow = false; } } if (isPortDeleted) { - for (int i = index; i < actionList.size(); i++) { + // Iterate through all actions in the modified list and adjust the order of + // the actions left behind. With that, all actions that have order higher than + // the action removed gets their value decremented by 1. Note that this iteration + // visits all entries to account for cases where the list order is not the same + // as the action's order. + // + for (int i = 0; i < actionList.size(); i++) { Action action = actionList.get(i); - if (action.getOrder() != i) { - /* Shift the action order */ + if (action.getOrder() > removedActionOrder) { + /* Shift the action by rebuilding action, using adjusted order */ ab = new ActionBuilder(); ab.setAction(action.getAction()); - ab.setOrder(i); - ab.setKey(new ActionKey(i)); + ab.setOrder(action.getOrder() - 1); + ab.setKey(new ActionKey(action.getOrder() - 1)); Action actionNewOrder = ab.build(); actionList.remove(action); actionList.add(i, actionNewOrder); + } else if (action.getOrder() == removedActionOrder) { + // Sanity: implementation assumes no two actions have the same order + // + LOG.error("Found action with same order as the action removed for {}, order {} index {}: {}", + ncid, removedActionOrder, i, action); + } + + // If action refers to a port output, then flow should be preserved. + // We do this, so that if we are only left with non-output port actions, + // we still remove the flow + // + if (action.getAction() instanceof OutputActionCase) { + removeFlow = false; } + } + } else { + // If port we are asked to delete is not found, this implementation will leave actions + // alone and not remove the flow, as long as a remaining OutputActionCase is found. + // + for (Action action : actionList) { if (action.getAction() instanceof OutputActionCase) { removeFlow = false; + break; } } } @@ -297,16 +358,16 @@ public class InstructionUtils { ApplyActionsBuilder aab = new ApplyActionsBuilder(); aab.setAction(actionList); ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); - logger.debug("removeOutputPortFromInstructions() : applyAction {}", aab.build()); + LOG.debug("removeOutputPortFromInstructions() : applyAction {}", aab.build()); return false; } else { - /* if all output port are removed. Return true to indicate flow remove */ + /* if all output ports are removed. Return true to indicate flow remove */ return true; } } /** - * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action + * Create Set Vlan ID Instruction - This includes push vlan action, and set field -> vlan vid action * * @param ib Map InstructionBuilder without any instructions * @param vlanId Integer representing a VLAN ID Integer representing a VLAN ID @@ -314,7 +375,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetVlanInstructions(InstructionBuilder ib, VlanId vlanId) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); /* First we push vlan header */ @@ -349,7 +410,7 @@ public class InstructionUtils { */ public static InstructionBuilder createPopVlanInstructions(InstructionBuilder ib) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); PopVlanActionBuilder popVlanActionBuilder = new PopVlanActionBuilder(); @@ -376,7 +437,7 @@ public class InstructionUtils { */ public static InstructionBuilder createNwSrcInstructions(InstructionBuilder ib, Ipv4Prefix prefixsrc) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetNwSrcActionBuilder setNwsrcActionBuilder = new SetNwSrcActionBuilder(); @@ -403,11 +464,13 @@ public class InstructionUtils { * * @param ib Map InstructionBuilder without any instructions * @param prefixdst String containing an IPv4 prefix + * @param extraAction (optional) Additional action to be performed in actionList * @return ib Map InstructionBuilder with instructions */ - public static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst) { + public static InstructionBuilder createNwDstInstructions(InstructionBuilder ib, Ipv4Prefix prefixdst, + ActionBuilder extraAction) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetNwDstActionBuilder setNwDstActionBuilder = new SetNwDstActionBuilder(); @@ -419,6 +482,12 @@ public class InstructionUtils { ab.setKey(new ActionKey(0)); actionList.add(ab.build()); + if (extraAction != null) { + extraAction.setOrder(1); + extraAction.setKey(new ActionKey(1)); + actionList.add(extraAction.build()); + } + // Create an Apply Action ApplyActionsBuilder aab = new ApplyActionsBuilder(); aab.setAction(actionList); @@ -445,7 +514,7 @@ public class InstructionUtils { ab.setKey(new ActionKey(0)); // Add our drop action to a list - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); actionList.add(ab.build()); // Create an Apply Action @@ -485,7 +554,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetTunnelIdInstructions(InstructionBuilder ib, BigInteger tunnelId) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -516,7 +585,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetSrcTCPPort(InstructionBuilder ib, PortNumber tcpport) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -547,7 +616,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetDstTCPPort(InstructionBuilder ib, PortNumber tcpport) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -578,7 +647,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetSrcUDPPort(InstructionBuilder ib, PortNumber udpport) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -609,7 +678,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetDstUDPPort(InstructionBuilder ib, PortNumber udpport) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -641,7 +710,7 @@ public class InstructionUtils { public static InstructionBuilder createSetIcmpCodeInstruction(InstructionBuilder ib, short code) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder(); @@ -671,7 +740,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSetIcmpTypeInstruction(InstructionBuilder ib, short type) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder(); @@ -708,7 +777,7 @@ public class InstructionUtils { ab.setKey(new ActionKey(0)); // Add our drop action to a list - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); actionList.add(ab.build()); // Create an Apply Action @@ -729,7 +798,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSrcArpMacInstructions(InstructionBuilder ib, MacAddress macsrc) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -759,7 +828,7 @@ public class InstructionUtils { */ public static InstructionBuilder createDstArpMacInstructions(InstructionBuilder ib, MacAddress macdst) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -788,7 +857,7 @@ public class InstructionUtils { */ public static InstructionBuilder createDstArpIpInstructions(InstructionBuilder ib, Ipv4Prefix dstiparp) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -816,7 +885,7 @@ public class InstructionUtils { */ public static InstructionBuilder createSrcArpIpInstructions(InstructionBuilder ib, Ipv4Prefix srciparp) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); @@ -844,7 +913,7 @@ public class InstructionUtils { */ public static InstructionBuilder createTunnelIpv4SrcInstructions(InstructionBuilder ib, Ipv4Prefix srcIp) { - List actionList = new ArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); // Build the tunnel endpoint source IPv4 address @@ -878,7 +947,7 @@ public class InstructionUtils { */ public static InstructionBuilder createTunnelIpv4DstInstructions(InstructionBuilder ib, Ipv4Prefix dstIp) { - List actionList = new ArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); // Build the tunnel endpoint dst IPv4 address @@ -935,7 +1004,7 @@ public class InstructionUtils { public static InstructionBuilder createDlSrcInstructions(InstructionBuilder ib, MacAddress macAddress) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetDlSrcActionBuilder dlSrcActionBuilder= new SetDlSrcActionBuilder(); @@ -960,7 +1029,7 @@ public class InstructionUtils { public static InstructionBuilder createDlDstInstructions(InstructionBuilder ib, MacAddress macAddress) { - List actionList = Lists.newArrayList(); + List actionList = new ArrayList<>(); ActionBuilder ab = new ActionBuilder(); SetDlDstActionBuilder dlDstActionBuilder= new SetDlDstActionBuilder(); @@ -982,10 +1051,10 @@ public class InstructionUtils { return ib; } - public static ArrayList - actionList (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) { + public static List + actionList(org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action... actions) { - ArrayList alist + List alist = new ArrayList<>(); int count = 0; for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action : actions) { @@ -1010,7 +1079,7 @@ public class InstructionUtils { } public static Instructions getInstructions(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) { - ArrayList ins + List ins = new ArrayList<>(); int order = 0; for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) { @@ -1028,6 +1097,37 @@ public class InstructionUtils { return getInstructions(applyActionIns(dropAction())); } + /** + * Extracts the existing instructions (if any) from the flow. + * + * @param flow The flow. + * @return The instructions in the flow (empty if none). + */ + public static List extractExistingInstructions(Flow flow) { + if (flow != null) { + Instructions ins = flow.getInstructions(); + if (ins != null) { + return ins.getInstruction(); + } + } + return Collections.emptyList(); + } + + /** + * Configures the flow builder to have the single given instruction. + * + * @param flowBuilder The flow builder. + * @param instruction The instruction. + * @return The flow builder. + */ + public static FlowBuilder setFlowBuilderInstruction(FlowBuilder flowBuilder, Instruction instruction) { + flowBuilder.setInstructions( + new InstructionsBuilder() + .setInstruction(Collections.singletonList(instruction)) + .build()); + return flowBuilder; + } + /** * Get a list of Instructions containing Nicira extensions that can have * additional OF/OXM instructions added to the returned Instruction list @@ -1037,7 +1137,7 @@ public class InstructionUtils { */ public static List getInstructionList( org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction... instructions) { - ArrayList ins + List ins = new ArrayList<>(); int order = 0; for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction i : instructions) {