/* * Copyright (c) 2014, 2017 ConteXtream Systems, 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.sfc.util.openflow; import com.google.common.collect.Lists; import com.google.common.net.InetAddresses; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.openflowplugin.extension.api.path.ActionPath; import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.ActionUtil; import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.ResubmitConvertor; import org.opendaylight.sfc.provider.api.SfcDataStoreAPI; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropAction; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.mpls.action._case.PopMplsActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.mpls.action._case.PushMplsActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.type.action._case.SetDlTypeActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; 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.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; 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.inventory.rev130819.tables.table.FlowKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.GoToTableCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.WriteMetadataCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTableBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.write.metadata._case.WriteMetadataBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.MetadataBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.ProtocolMatchFieldsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TcpFlagsMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder; 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 org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmitBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.resubmit.grouping.NxActionResubmitBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpThaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxEncapEthDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxEncapEthSrcCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshMdtypeCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshNpCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc1CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc2CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc3CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc4CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNsiCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNspCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunGpeNpCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpOpCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPopNshNodesNodeTableFlowApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionPushNshNodesNodeTableFlowApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNodesNodeTableFlowApplyActionsCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNsh; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.pop.nsh.grouping.NxPopNshBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNsh; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.push.nsh.grouping.NxPushNshBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshMdtypeCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshNpCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc2CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc3CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc4CaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNsiCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNspCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunGpeNpCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIdCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxTunIpv4DstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpTpaCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxEncapEthDstKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxEncapEthSrcKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxEncapEthTypeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNshMdtypeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNshNpKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNshc1Key; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNsiKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNspKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxTunGpeNpKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.encap.eth.dst.grouping.NxmNxEncapEthDstBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.encap.eth.src.grouping.NxmNxEncapEthSrcBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.encap.eth.type.grouping.NxmNxEncapEthTypeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsh.mdtype.grouping.NxmNxNshMdtypeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsh.np.grouping.NxmNxNshNpBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nshc._1.grouping.NxmNxNshc1Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsi.grouping.NxmNxNsiBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.gpe.np.grouping.NxmNxTunGpeNpBuilder; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class SfcOpenflowUtils { public static final int ETHERTYPE_IPV4 = 0x0800; public static final int ETHERTYPE_VLAN = 0x8100; public static final int ETHERTYPE_IPV6 = 0x86dd; public static final int ETHERTYPE_MPLS_UCAST = 0x8847; public static final int ETHERTYPE_MPLS_MCAST = 0x8848; public static final int ETHERTYPE_ARP = 0x0806; public static final int ETHERTYPE_NSH = 0x894f; public static final short IP_PROTOCOL_ICMP = (short) 1; public static final short IP_PROTOCOL_TCP = (short) 6; public static final short IP_PROTOCOL_UDP = (short) 17; public static final short IP_PROTOCOL_SCTP = (short) 132; public static final int PKT_LENGTH_IP_HEADER = 20 + 14; // ether + IP header public static final int TCP_FLAG_SYN = 0x0002; public static final int ARP_REQUEST = 1; public static final int ARP_REPLY = 2; private static final int COOKIE_BIGINT_INT_RADIX = 10; private static AtomicLong flowIdInc = new AtomicLong(); private SfcOpenflowUtils() { } public static FlowBuilder createFlowBuilder(final short table, final int priority, final BigInteger cookieValue, final String flowName, MatchBuilder match, InstructionsBuilder isb) { FlowBuilder flow = new FlowBuilder(); String idStr = String.valueOf(flowIdInc.getAndIncrement()); flow.setId(new FlowId(idStr)); flow.setKey(new FlowKey(new FlowId(idStr))); flow.setTableId(table); flow.setFlowName(flowName); flow.setCookie(new FlowCookie(cookieValue)); flow.setCookieMask(new FlowCookie(cookieValue)); flow.setContainerName(null); flow.setStrict(false); flow.setMatch(match.build()); flow.setInstructions(isb.build()); flow.setPriority(priority); flow.setHardTimeout(0); flow.setIdleTimeout(0); flow.setFlags(new FlowModFlags(false, false, false, false, false)); if (null == flow.isBarrier()) { flow.setBarrier(Boolean.FALSE); } return flow; } public static FlowBuilder createFlowBuilder(final short table, final int priority, final String flowName, MatchBuilder match, InstructionsBuilder isb) { return createFlowBuilder(table, priority, new BigInteger("20", COOKIE_BIGINT_INT_RADIX), flowName, match, isb); } // // Add Match methods // // If we call multiple ethernet match methods, the MatchBuilder // EthernetMatch object gets overwritten each time, when we actually // want to set additional fields on the existing EthernetMatch object private static EthernetMatch mergeEthernetMatch(MatchBuilder match, EthernetMatchBuilder ethMatchBuilder) { EthernetMatch ethMatch = match.getEthernetMatch(); if (ethMatch == null) { return ethMatchBuilder.build(); } if (ethMatch.getEthernetDestination() != null) { ethMatchBuilder.setEthernetDestination(ethMatch.getEthernetDestination()); } if (ethMatch.getEthernetSource() != null) { ethMatchBuilder.setEthernetSource(ethMatch.getEthernetSource()); } if (ethMatch.getEthernetType() != null) { ethMatchBuilder.setEthernetType(ethMatch.getEthernetType()); } return ethMatchBuilder.build(); } // TODO will we need mergeIpMatch() for match.setLayer3Match() /** * Add an etherType match to an existing MatchBuilder. * * @param match * the Match object to which we want to add an EtherTypeMatch * @param etherType * the Ethernet type */ public static void addMatchEtherType(MatchBuilder match, final long etherType) { EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder(); EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder(); ethTypeBuilder.setType(new EtherType(etherType)); ethernetMatch.setEthernetType(ethTypeBuilder.build()); match.setEthernetMatch(mergeEthernetMatch(match, ethernetMatch)); } public static void addMatchSrcMac(MatchBuilder match, final String srcMac) { EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder(); EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder(); ethSourceBuilder.setAddress(new MacAddress(srcMac)); ethernetMatch.setEthernetSource(ethSourceBuilder.build()); match.setEthernetMatch(mergeEthernetMatch(match, ethernetMatch)); } public static void addMatchDstMac(MatchBuilder match, final String dstMac) { EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder(); EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder(); ethDestinationBuilder.setAddress(new MacAddress(dstMac)); ethernetMatch.setEthernetDestination(ethDestinationBuilder.build()); match.setEthernetMatch(mergeEthernetMatch(match, ethernetMatch)); } // If we call multiple IpMatch match methods, the MatchBuilder // IpMatch object gets overwritten each time, when we actually // want to set additional fields on the existing IpMatch object private static IpMatch mergeIpMatch(MatchBuilder match, IpMatchBuilder ipMatchBuilder) { IpMatch ipMatch = match.getIpMatch(); if (ipMatch == null) { return ipMatchBuilder.build(); } if (ipMatch.getIpDscp() != null) { ipMatchBuilder.setIpDscp(ipMatch.getIpDscp()); } if (ipMatch.getIpEcn() != null) { ipMatchBuilder.setIpEcn(ipMatch.getIpEcn()); } if (ipMatch.getIpProto() != null) { ipMatchBuilder.setIpProto(ipMatch.getIpProto()); } if (ipMatch.getIpProtocol() != null) { ipMatchBuilder.setIpProtocol(ipMatch.getIpProtocol()); } return ipMatchBuilder.build(); } public static void addMatchIpProtocol(MatchBuilder match, final short ipProtocol) { IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version ipMatch.setIpProtocol(ipProtocol); match.setIpMatch(mergeIpMatch(match, ipMatch)); } public static void addMatchTcpSyn(MatchBuilder match) { IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version ipMatch.setIpProtocol(IP_PROTOCOL_TCP); match.setIpMatch(mergeIpMatch(match, ipMatch)); TcpFlagsMatchBuilder tcpFlagMatch = new TcpFlagsMatchBuilder(); tcpFlagMatch.setTcpFlags(TCP_FLAG_SYN); match.setTcpFlagsMatch(tcpFlagMatch.build()); } public static void addMatchDscp(MatchBuilder match, short dscpVal) { addMatchEtherType(match, ETHERTYPE_IPV4); IpMatchBuilder ipMatch = new IpMatchBuilder(); Dscp dscp = new Dscp(dscpVal); ipMatch.setIpDscp(dscp); match.setIpMatch(mergeIpMatch(match, ipMatch)); } public static void addMatchSrcUdpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); UdpMatchBuilder udpMatch = new UdpMatchBuilder(); udpMatch.setUdpSourcePort(port); match.setLayer4Match(udpMatch.build()); } public static void addMatchDstUdpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); UdpMatchBuilder udpMatch = new UdpMatchBuilder(); udpMatch.setUdpDestinationPort(port); match.setLayer4Match(udpMatch.build()); } public static void addMatchSrcTcpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); TcpMatchBuilder tcpMatch = new TcpMatchBuilder(); tcpMatch.setTcpSourcePort(port); match.setLayer4Match(tcpMatch.build()); } public static void addMatchDstTcpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); TcpMatchBuilder tcpMatch = new TcpMatchBuilder(); tcpMatch.setTcpDestinationPort(port); match.setLayer4Match(tcpMatch.build()); } public static void addMatchSrcSctpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); SctpMatchBuilder sctpMatch = new SctpMatchBuilder(); sctpMatch.setSctpSourcePort(port); match.setLayer4Match(sctpMatch.build()); } public static void addMatchDstSctpPort(MatchBuilder match, int portNum) { PortNumber port = new PortNumber(portNum); SctpMatchBuilder sctpMatch = new SctpMatchBuilder(); sctpMatch.setSctpDestinationPort(port); match.setLayer4Match(sctpMatch.build()); } public static void addMatchMplsLabel(MatchBuilder match, long label) { EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder(); ethTypeBuilder.setType(new EtherType((long) ETHERTYPE_MPLS_UCAST)); EthernetMatchBuilder eth = new EthernetMatchBuilder(); eth.setEthernetType(ethTypeBuilder.build()); match.setEthernetMatch(eth.build()); ProtocolMatchFieldsBuilder protomatch = new ProtocolMatchFieldsBuilder(); protomatch.setMplsLabel(label); match.setProtocolMatchFields(protomatch.build()); } public static void addMatchVlan(MatchBuilder match, int vlan) { VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder(); VlanIdBuilder vlanIdBuilder = new VlanIdBuilder(); VlanId vlanId = new VlanId(vlan); vlanIdBuilder.setVlanId(vlanId); vlanIdBuilder.setVlanIdPresent(true); vlanMatchBuilder.setVlanId(vlanIdBuilder.build()); match.setVlanMatch(vlanMatchBuilder.build()); } public static void addMatchArpRequest(MatchBuilder match) { ArpMatchBuilder arpmatch = new ArpMatchBuilder(); arpmatch.setArpOp(ARP_REQUEST); match.setLayer3Match(arpmatch.build()); } public static void addMatchArpRequestAndTpa(MatchBuilder match, String requestedIp) { ArpMatchBuilder arpmatch = new ArpMatchBuilder(); arpmatch.setArpOp(ARP_REQUEST); arpmatch.setArpTargetTransportAddress(new Ipv4Prefix(requestedIp + "/32")); match.setLayer3Match(arpmatch.build()); } // If we call multiple Layer3 match methods, the MatchBuilder // Ipv4Match object gets overwritten each time, when we actually // want to set additional fields on the existing Ipv4Match object private static Ipv4Match mergeIpv4Match(MatchBuilder match, Ipv4MatchBuilder ipMatchBuilder) { Ipv4Match ipv4Match = (Ipv4Match) match.getLayer3Match(); if (ipv4Match == null) { return ipMatchBuilder.build(); } if (ipv4Match.getIpv4Destination() != null) { ipMatchBuilder.setIpv4Destination(ipv4Match.getIpv4Destination()); } if (ipv4Match.getIpv4Source() != null) { ipMatchBuilder.setIpv4Source(ipv4Match.getIpv4Source()); } return ipMatchBuilder.build(); } public static void addMatchSrcIpv4(MatchBuilder match, String srcIpStr, int netmask) { addMatchSrcIpv4(match, new Ipv4Prefix(srcIpStr + "/" + netmask)); } public static void addMatchSrcIpv4(MatchBuilder match, Ipv4Prefix srcIp) { Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder(); ipv4match.setIpv4Source(srcIp); match.setLayer3Match(mergeIpv4Match(match, ipv4match)); } public static void addMatchDstIpv4(MatchBuilder match, String dstIpStr, int netmask) { addMatchDstIpv4(match, new Ipv4Prefix(dstIpStr + "/" + netmask)); } public static void addMatchDstIpv4(MatchBuilder match, Ipv4Prefix dstIp) { Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder(); ipv4match.setIpv4Destination(dstIp); match.setLayer3Match(mergeIpv4Match(match, ipv4match)); } // If we call multiple Layer3 match methods, the MatchBuilder // Ipv6Match object gets overwritten each time, when we actually // want to set additional fields on the existing Ipv6Match object private static Ipv6Match mergeIpv6Match(MatchBuilder match, Ipv6MatchBuilder ipMatchBuilder) { Ipv6Match ipv6Match = (Ipv6Match) match.getLayer3Match(); if (ipv6Match == null) { return ipMatchBuilder.build(); } if (ipv6Match.getIpv6Destination() != null) { ipMatchBuilder.setIpv6Destination(ipv6Match.getIpv6Destination()); } if (ipv6Match.getIpv6Source() != null) { ipMatchBuilder.setIpv6Source(ipv6Match.getIpv6Source()); } return ipMatchBuilder.build(); } public static void addMatchSrcIpv6(MatchBuilder match, String srcIpStr, int netmask) { addMatchSrcIpv6(match, new Ipv6Prefix(srcIpStr + "/" + netmask)); } public static void addMatchSrcIpv6(MatchBuilder match, Ipv6Prefix srcIp) { Ipv6MatchBuilder ipv6match = new Ipv6MatchBuilder(); ipv6match.setIpv6Source(srcIp); match.setLayer3Match(mergeIpv6Match(match, ipv6match)); } public static void addMatchDstIpv6(MatchBuilder match, String dstIpStr, int netmask) { addMatchDstIpv6(match, new Ipv6Prefix(dstIpStr + "/" + netmask)); } public static void addMatchDstIpv6(MatchBuilder match, Ipv6Prefix dstIp) { Ipv6MatchBuilder ipv6match = new Ipv6MatchBuilder(); ipv6match.setIpv6Destination(dstIp); match.setLayer3Match(mergeIpv6Match(match, ipv6match)); } public static void addMatchMetada(MatchBuilder match, BigInteger metadataValue, BigInteger metadataMask) { MetadataBuilder metadata = new MetadataBuilder(); metadata.setMetadata(metadataValue); metadata.setMetadataMask(metadataMask); match.setMetadata(metadata.build()); } private static void addExtension(MatchBuilder match, Class<? extends ExtensionKey> extensionKey, NxAugMatchNodesNodeTableFlow am) { GeneralAugMatchNodesNodeTableFlow existingAugmentations = match .getAugmentation(GeneralAugMatchNodesNodeTableFlow.class); List<ExtensionList> extensions = null; if (existingAugmentations != null) { extensions = existingAugmentations.getExtensionList(); } if (extensions == null) { extensions = Lists.newArrayList(); } extensions.add(new ExtensionListBuilder().setExtensionKey(extensionKey) .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build()) .build()); GeneralAugMatchNodesNodeTableFlow generalAugMatchNodesNode = new GeneralAugMatchNodesNodeTableFlowBuilder() .setExtensionList(extensions).build(); match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, generalAugMatchNodesNode); } public static void addMatchNshNsp(MatchBuilder match, long nsp) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxNsp(new NxmNxNspBuilder().setValue(nsp).build()).build(); addExtension(match, NxmNxNspKey.class, am); } public static void addMatchNshNsi(MatchBuilder match, short nsi) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxNsi(new NxmNxNsiBuilder().setNsi(nsi).build()).build(); addExtension(match, NxmNxNsiKey.class, am); } public static void addMatchNshNsc1(MatchBuilder match, long nsc) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxNshc1(new NxmNxNshc1Builder().setValue(nsc).build()).build(); addExtension(match, NxmNxNshc1Key.class, am); } public static void addMatchInPort(MatchBuilder match, NodeId nodeId, long inPort) { match.setInPort(new NodeConnectorId(nodeId + ":" + inPort)); } public static void addMatchInPort(MatchBuilder match, NodeConnectorId nodeConnId) { match.setInPort(nodeConnId); } public static void addMatchInPort(MatchBuilder match, String nodeName, int value) { match.setInPort(new NodeConnectorId(nodeName + ":" + String.valueOf(value))); } // // Create Action methods // // Internal method to create an ActionBuilder private static ActionBuilder createActionBuilder(int order) { ActionBuilder ab = new ActionBuilder(); ab.setOrder(order); ab.setKey(new ActionKey(order)); return ab; } public static GoToTableBuilder createActionGotoTable(final short toTable) { GoToTableBuilder gotoTb = new GoToTableBuilder(); gotoTb.setTableId(toTable); return gotoTb; } @SuppressWarnings("checkstyle:linelength") public static Action createActionResubmitTable(final short toTable, int order) { NxActionResubmitBuilder resubmit = new NxActionResubmitBuilder(); resubmit.setTable(toTable); ActionResubmitBuilder actionResubmitBuilder = new ActionResubmitBuilder(); actionResubmitBuilder.setNxActionResubmit(resubmit.build()); ResubmitConvertor convertor = new ResubmitConvertor(); ActionBuilder ab = createActionBuilder(order); ab.setAction(convertor.convert(ActionUtil.createAction(actionResubmitBuilder.build()), ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION)); return ab.build(); } public static GroupActionBuilder createGroupAction(final long groupId) { GroupActionBuilder gab = new GroupActionBuilder(); gab.setGroupId(groupId); return gab; } public static Action createActionOutPort(final int portUri, final int order) { return createActionOutPort(String.valueOf(portUri), order); } public static Action createActionOutPort(final String portUri, final int order) { OutputActionBuilder output = new OutputActionBuilder(); Uri value = new Uri(portUri); output.setOutputNodeConnector(value); ActionBuilder ab = createActionBuilder(order); ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build()); return ab.build(); } public static Action createActionSetEtherType(final long etherType, final int order) { SetDlTypeActionBuilder setDlTypeActionBuilder = new SetDlTypeActionBuilder(); setDlTypeActionBuilder.setDlType(new EtherType(etherType)); ActionBuilder ab = createActionBuilder(order); ab.setAction(new SetDlTypeActionCaseBuilder().setSetDlTypeAction(setDlTypeActionBuilder.build()).build()); return ab.build(); } public static Action createActionWriteDscp(short dscpVal, final int order) { IpMatchBuilder ipMatch = new IpMatchBuilder(); Dscp dscp = new Dscp(dscpVal); ipMatch.setIpDscp(dscp); SetFieldCaseBuilder setFieldCase = new SetFieldCaseBuilder(); setFieldCase.setSetField(new SetFieldBuilder().setIpMatch(ipMatch.build()).build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(setFieldCase.build()); return ab.build(); } public static Action createActionPktIn(final int pktLength, final int order) { OutputActionBuilder output = new OutputActionBuilder(); output.setMaxLength(0xffff); Uri controllerPort = new Uri(OutputPortValues.CONTROLLER.toString()); output.setOutputNodeConnector(controllerPort); ActionBuilder ab = createActionBuilder(order); ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build()); return ab.build(); } public static Action createActionNormal(final int order) { OutputActionBuilder output = new OutputActionBuilder(); output.setMaxLength(30); Uri normal = new Uri(OutputPortValues.NORMAL.toString()); output.setOutputNodeConnector(normal); ActionBuilder ab = createActionBuilder(order); ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build()); return ab.build(); } public static Action createActionSetDlSrc(String srcMac, int order) { EthernetSourceBuilder ethSrc = new EthernetSourceBuilder(); ethSrc.setAddress(new MacAddress(srcMac)); EthernetMatchBuilder ethMatchBuilder = new EthernetMatchBuilder(); ethMatchBuilder.setEthernetSource(ethSrc.build()); SetFieldCaseBuilder setFieldCase = new SetFieldCaseBuilder(); setFieldCase.setSetField(new SetFieldBuilder().setEthernetMatch(ethMatchBuilder.build()).build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(setFieldCase.build()); return ab.build(); } public static Action createActionSetDlDst(String dstMac, int order) { EthernetDestinationBuilder ethDst = new EthernetDestinationBuilder(); ethDst.setAddress(new MacAddress(dstMac)); EthernetMatchBuilder ethMatchBuilder = new EthernetMatchBuilder(); ethMatchBuilder.setEthernetDestination(ethDst.build()); SetFieldCaseBuilder setFieldCase = new SetFieldCaseBuilder(); setFieldCase.setSetField(new SetFieldBuilder().setEthernetMatch(ethMatchBuilder.build()).build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(setFieldCase.build()); return ab.build(); } public static Action createActionSetNwDst(String ipStr, int netmask, int order) { Ipv4Prefix prefixdst = new Ipv4Prefix(ipStr + "/" + netmask); Ipv4Builder ipdst = new Ipv4Builder(); ipdst.setIpv4Address(prefixdst); SetNwDstActionBuilder nwDstBuilder = new SetNwDstActionBuilder(); nwDstBuilder.setAddress(ipdst.build()); SetNwDstActionCaseBuilder nwDstCaseBuilder = new SetNwDstActionCaseBuilder(); nwDstCaseBuilder.setSetNwDstAction(nwDstBuilder.build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(nwDstCaseBuilder.build()); return ab.build(); } public static Action createActionPopVlan(int order) { PopVlanActionCaseBuilder popVlanBuilder = new PopVlanActionCaseBuilder(); popVlanBuilder.setPopVlanAction(new PopVlanActionBuilder().build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(popVlanBuilder.build()); return ab.build(); } public static Action createActionPushVlan(int order) { PushVlanActionBuilder pushVlanBuilder = new PushVlanActionBuilder(); pushVlanBuilder.setEthernetType(ETHERTYPE_VLAN); PushVlanActionCaseBuilder pushVlanActionCase = new PushVlanActionCaseBuilder(); pushVlanActionCase.setPushVlanAction(pushVlanBuilder.build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(pushVlanActionCase.build()); return ab.build(); } public static Action createActionSetVlanId(int vlan, int order) { VlanIdBuilder vlanBuilder = new VlanIdBuilder(); vlanBuilder.setVlanId(new VlanId(vlan)); vlanBuilder.setVlanIdPresent(true); VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder(); vlanMatchBuilder.setVlanId(vlanBuilder.build()); SetFieldCaseBuilder setFieldCase = new SetFieldCaseBuilder(); setFieldCase.setSetField(new SetFieldBuilder().setVlanMatch(vlanMatchBuilder.build()).build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(setFieldCase.build()); return ab.build(); } public static Action createActionPushMpls(int order) { PushMplsActionBuilder push = new PushMplsActionBuilder(); push.setEthernetType(ETHERTYPE_MPLS_UCAST); PushMplsActionCaseBuilder pushMplsCase = new PushMplsActionCaseBuilder(); pushMplsCase.setPushMplsAction(push.build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(pushMplsCase.build()); return ab.build(); } public static Action createActionSetMplsLabel(long label, int order) { ProtocolMatchFieldsBuilder protomatch = new ProtocolMatchFieldsBuilder(); protomatch.setMplsLabel(label); SetFieldBuilder setFieldBuilder = new SetFieldBuilder(); setFieldBuilder.setProtocolMatchFields(protomatch.build()); SetFieldCaseBuilder setFieldCase = new SetFieldCaseBuilder(); setFieldCase.setSetField(setFieldBuilder.build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(setFieldCase.build()); return ab.build(); } public static Action createActionPopMpls(int order) { PopMplsActionBuilder popMplsActionBuilder = new PopMplsActionBuilder(); // TODO, is this ethertype correct? popMplsActionBuilder.setEthernetType(0XB); ActionBuilder ab = createActionBuilder(order); ab.setAction(new PopMplsActionCaseBuilder().setPopMplsAction(popMplsActionBuilder.build()).build()); return ab.build(); } public static Action createActionDropPacket(int order) { DropActionBuilder dab = new DropActionBuilder(); DropAction dropAction = dab.build(); DropActionCaseBuilder dac = new DropActionCaseBuilder(); dac.setDropAction(dropAction); ActionBuilder ab = createActionBuilder(order); ab.setAction(dac.build()); return ab.build(); } public static Action createActionDecNwTtl(int order) { DecNwTtlBuilder builder = new DecNwTtlBuilder(); DecNwTtlCaseBuilder caseBuilder = new DecNwTtlCaseBuilder(); caseBuilder.setDecNwTtl(builder.build()); ActionBuilder ab = createActionBuilder(order); ab.setAction(caseBuilder.build()); return ab.build(); } public static Action createActionNxPushNsh(int order) { NxPushNshBuilder builder = new NxPushNshBuilder(); NxPushNsh nxPushNsh = builder.build(); ActionBuilder ab = createActionBuilder(order); ab.setAction(new NxActionPushNshNodesNodeTableFlowApplyActionsCaseBuilder().setNxPushNsh(nxPushNsh).build()); return ab.build(); } public static Action createActionNxPopNsh(int order) { NxPopNshBuilder builder = new NxPopNshBuilder(); NxPopNsh nxPopNsh = builder.build(); ActionBuilder ab = createActionBuilder(order); ab.setAction(new NxActionPopNshNodesNodeTableFlowApplyActionsCaseBuilder().setNxPopNsh(nxPopNsh).build()); return ab.build(); } public static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nxLoadRegAction( DstChoice dstChoice, BigInteger value, int endOffset, boolean groupBucket) { NxRegLoad regLoad = new NxRegLoadBuilder() .setDst(new DstBuilder().setDstChoice(dstChoice).setStart(0).setEnd(endOffset).build()).setValue(value) .build(); if (groupBucket) { return new NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder().setNxRegLoad(regLoad).build(); } else { return new NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder().setNxRegLoad(regLoad).build(); } } public static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nxMoveRegAction( SrcChoice srcChoice, DstChoice dstChoice, int endOffset, boolean groupBucket) { NxRegMove nxRegMove = new NxRegMoveBuilder() .setSrc(new SrcBuilder().setSrcChoice(srcChoice).setStart(0).setEnd(endOffset).build()) .setDst(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira .action.rev140714.nx.action.reg.move.grouping.nx.reg.move.DstBuilder() .setDstChoice(dstChoice).setStart(0).setEnd(endOffset).build()) .build(); if (groupBucket) { return new NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder().setNxRegMove(nxRegMove).build(); } else { return new NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder().setNxRegMove(nxRegMove).build(); } } // Used by NSH to set the destination tunnel IP when forwarding NSH packets public static Action createActionNxSetTunIpv4Dst(String ipStr, int order) { int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipStr)); long ipl = ip & 0xffffffffL; ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(), BigInteger.valueOf(ipl), 31, false)); return ab.build(); } // Used by NSH to move the VxLAN Network ID (VNID) from the source to the // dest tunnel public static Action createActionNxMoveTunIdRegister(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(), new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxMoveTunIpv4Dst(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(), new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxMoveNsc1(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxMoveNsc2(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } /** * Create action to move NSH C3. * * @param order * the order in which we want to execute this action * @return the MoveNsc3 action */ public static Action createActionNxMoveNsc3(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc3CaseBuilder().setNxNshc3Dst(Boolean.TRUE).build(), new DstNxNshc3CaseBuilder().setNxNshc3Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } /** * Create action to move NSH C4. * * @param order * the order in which we want to execute this action * @return the MoveNsc4 action */ public static Action createActionNxMoveNsc4(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc4CaseBuilder().setNxNshc4Dst(Boolean.TRUE).build(), new DstNxNshc4CaseBuilder().setNxNshc4Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxMoveNsi(int order) { ActionBuilder ab = createActionBuilder(order); // Service Index is 8 bits, moving bits 0-7 ab.setAction(nxMoveRegAction(new SrcNxNsiCaseBuilder().setNxNsiDst(Boolean.TRUE).build(), new DstNxNsiCaseBuilder().setNxNsiDst(Boolean.TRUE).build(), 7, false)); return ab.build(); } public static Action createActionNxMoveNsp(int order) { ActionBuilder ab = createActionBuilder(order); // Service Index is 24 bits, moving bits 0-23 ab.setAction(nxMoveRegAction(new SrcNxNspCaseBuilder().setNxNspDst(Boolean.TRUE).build(), new DstNxNspCaseBuilder().setNxNspDst(Boolean.TRUE).build(), 23, false)); return ab.build(); } public static Action createActionNxMoveTunGpeNp(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxTunGpeNpCaseBuilder().setNxTunGpeNp(Boolean.TRUE).build(), new DstNxTunGpeNpCaseBuilder().setNxTunGpeNp(Boolean.TRUE).build(), 7, false)); return ab.build(); } public static Action createActionNxMoveNshMdtype(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshMdtypeCaseBuilder().setNxNshMdtype(Boolean.TRUE).build(), new DstNxNshMdtypeCaseBuilder().setNxNshMdtype(Boolean.TRUE).build(), 7, false)); return ab.build(); } public static Action createActionNxMoveNshNp(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshNpCaseBuilder().setNxNshNp(Boolean.TRUE).build(), new DstNxNshNpCaseBuilder().setNxNshNp(Boolean.TRUE).build(), 7, false)); return ab.build(); } // Used by NSH to move one of the NSH Context registers (NSC) to // the Tunnel Id (VNID) Register. This is for the RSP NSH egress tunnel. // GBP will set the Tunnel ID (VNID) in NSC2 and pass it along the // chain, and in the last SFF, we will use it to set the VNID // This will only work with this patch: // https://git.opendaylight.org/gerrit/#/c/19478 public static Action createActionNxMoveNsc2ToTunIdRegister(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(), 31, false)); return ab.build(); } // This will only work with this patch: // https://git.opendaylight.org/gerrit/#/c/19478 public static Action createActionNxMoveNsc1ToTunIpv4DstRegister(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxLoadArpOpAction(int value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstOfArpOpCaseBuilder().setOfArpOp(Boolean.TRUE).build(), BigInteger.valueOf(value), 15, false)); return ab.build(); } // Used for ARP to move the Source HW Address (SHA) to the Target HW address // (THA) public static Action createActionNxMoveArpShaToArpThaAction(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxArpShaCaseBuilder().setNxArpSha(Boolean.TRUE).build(), new DstNxArpThaCaseBuilder().setNxArpTha(Boolean.TRUE).build(), 47, false)); return ab.build(); } public static Action createActionNxMoveEthSrcToEthDstAction(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build(), new DstOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build(), 47, false)); return ab.build(); } public static Action createActionNxLoadNshMdtype(short value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshMdtypeCaseBuilder().setNxNshMdtype(Boolean.TRUE).build(), BigInteger.valueOf(value), 7, false)); return ab.build(); } public static Action createActionNxLoadNshNp(short value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshNpCaseBuilder().setNxNshNp(Boolean.TRUE).build(), BigInteger.valueOf(value), 7, false)); return ab.build(); } public static Action createActionNxLoadTunGpeNp(short value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxTunGpeNpCaseBuilder().setNxTunGpeNp(Boolean.TRUE).build(), BigInteger.valueOf(value), 7, false)); return ab.build(); } public static Action createActionNxLoadNsp(int value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNspCaseBuilder().setNxNspDst(Boolean.TRUE).build(), BigInteger.valueOf(value), 23, false)); return ab.build(); } public static Action createActionNxLoadNsi(short value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNsiCaseBuilder().setNxNsiDst(Boolean.TRUE).build(), BigInteger.valueOf(value), 7, false)); return ab.build(); } public static Action createActionNxLoadNshc1(long value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshc1CaseBuilder().setNxNshc1Dst(Boolean.TRUE).build(), BigInteger.valueOf(value), 31, false)); return ab.build(); } public static Action createActionNxLoadNshc2(long value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshc2CaseBuilder().setNxNshc2Dst(Boolean.TRUE).build(), BigInteger.valueOf(value), 31, false)); return ab.build(); } public static Action createActionNxLoadNshc3(long value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshc3CaseBuilder().setNxNshc3Dst(Boolean.TRUE).build(), BigInteger.valueOf(value), 31, false)); return ab.build(); } public static Action createActionNxLoadNshc4(long value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxNshc4CaseBuilder().setNxNshc4Dst(Boolean.TRUE).build(), BigInteger.valueOf(value), 31, false)); return ab.build(); } static byte[] bytesFromHexString(String values) { String target = ""; if (values != null) { target = values; } String[] octets = target.split(":"); byte[] ret = new byte[octets.length]; for (int i = 0; i < octets.length; i++) { ret[i] = Integer.valueOf(octets[i], 16).byteValue(); } return ret; } static byte[] convertIPAdressToBytes(String ip) { String[] ipStr = ip.split("\\."); byte[] bytes = new byte[ipStr.length]; for (int i = 0; i < ipStr.length; i++) { bytes[i] = Integer.valueOf(ipStr[i], 10).byteValue(); } return bytes; } public static Action createActionNxLoadEncapEthSrc(String value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxEncapEthSrcCaseBuilder().setNxEncapEthSrc(Boolean.TRUE).build(), new BigInteger(1, bytesFromHexString(new MacAddress(value).getValue())), 47, false)); return ab.build(); } public static Action createActionNxLoadEncapEthDst(String mac, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxEncapEthDstCaseBuilder().setNxEncapEthDst(Boolean.TRUE).build(), new BigInteger(1, bytesFromHexString(new MacAddress(mac).getValue())), 47, false)); return ab.build(); } public static Action createActionNxLoadTunId(long value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxTunIdCaseBuilder().setNxTunId(Boolean.TRUE).build(), BigInteger.valueOf(value), 63, false)); return ab.build(); } public static Action createActionNxLoadTunIpv4Dst(String ipStr, int order) { int ip = InetAddresses.coerceToInteger(InetAddresses.forString(ipStr)); long ipl = ip & 0xffffffffL; ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxTunIpv4DstCaseBuilder().setNxTunIpv4Dst(Boolean.TRUE).build(), BigInteger.valueOf(ipl), 31, false)); return ab.build(); } public static Action createActionNxResubmit(int inPort, short table, int order) { NxResubmitBuilder nxResubmitBuilder = new NxResubmitBuilder(); nxResubmitBuilder.setTable(Short.valueOf(table)); if (inPort >= 0) { nxResubmitBuilder.setInPort(Integer.valueOf(inPort)); } NxResubmit nxResubmit = nxResubmitBuilder.build(); ActionBuilder ab = createActionBuilder(order); ab.setAction(new NxActionResubmitNodesNodeTableFlowApplyActionsCaseBuilder().setNxResubmit(nxResubmit).build()); return ab.build(); } public static Action createActionNxMoveEthSrcToEncapEthSrc(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcOfEthSrcCaseBuilder().setOfEthSrc(Boolean.TRUE).build(), new DstNxEncapEthSrcCaseBuilder().setNxEncapEthSrc(Boolean.TRUE).build(), 47, false)); return ab.build(); } public static Action createActionNxMoveEthDstToEncapEthDst(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcOfEthDstCaseBuilder().setOfEthDst(Boolean.TRUE).build(), new DstNxEncapEthDstCaseBuilder().setNxEncapEthDst(Boolean.TRUE).build(), 47, false)); return ab.build(); } public static Action createActionNxLoadArpShaAction(String mac, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxArpShaCaseBuilder().setNxArpSha(Boolean.TRUE).build(), new BigInteger(1, bytesFromHexString(new MacAddress(mac).getValue())), 47, false)); return ab.build(); } public static Action createActionNxMoveArpTpaToRegAction(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build(), new DstNxRegCaseBuilder().setNxReg(NxmNxReg0.class).build(), 31, false)); return ab.build(); } public static Action createActionNxLoadArpSpaAction(String ip, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(), new BigInteger(1, convertIPAdressToBytes(ip)), 31, false)); return ab.build(); } public static void addMatchEncapEthType(MatchBuilder match, int ethType) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxEncapEthType(new NxmNxEncapEthTypeBuilder().setValue(ethType).build()).build(); addExtension(match, NxmNxEncapEthTypeKey.class, am); } public static void addMatchEncapEthSrc(MatchBuilder match, String mac) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxEncapEthSrc(new NxmNxEncapEthSrcBuilder().setMacAddress(new MacAddress(mac)).build()).build(); addExtension(match, NxmNxEncapEthSrcKey.class, am); } public static void addMatchEncapEthDst(MatchBuilder match, String mac) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxEncapEthDst(new NxmNxEncapEthDstBuilder().setMacAddress(new MacAddress(mac)).build()).build(); addExtension(match, NxmNxEncapEthDstKey.class, am); } public static void addMatchNshMdtype(MatchBuilder match, short nshMdtype) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxNshMdtype(new NxmNxNshMdtypeBuilder().setValue(Short.valueOf(nshMdtype)).build()).build(); addExtension(match, NxmNxNshMdtypeKey.class, am); } public static void addMatchNshNp(MatchBuilder match, short nshNp) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxNshNp(new NxmNxNshNpBuilder().setValue(Short.valueOf(nshNp)).build()).build(); addExtension(match, NxmNxNshNpKey.class, am); } public static void addMatchTunGpeNp(MatchBuilder match, short tunGpeNp) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxTunGpeNp(new NxmNxTunGpeNpBuilder().setValue(Short.valueOf(tunGpeNp)).build()).build(); addExtension(match, NxmNxTunGpeNpKey.class, am); } public static void addMatchReg0(MatchBuilder match, int value) { NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder() .setNxmNxReg(new NxmNxRegBuilder().setReg(NxmNxReg0.class).setValue(Long.valueOf(value)).build()) .build(); addExtension(match, NxmNxReg0Key.class, am); } public static Action createActionNxMoveArpSpaToArpTpaAction(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(), new DstOfArpTpaCaseBuilder().setOfArpTpa(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxMoveRegToArpSpaAction(int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxMoveRegAction(new SrcNxRegCaseBuilder().setNxReg(NxmNxReg0.class).build(), new DstOfArpSpaCaseBuilder().setOfArpSpa(Boolean.TRUE).build(), 31, false)); return ab.build(); } public static Action createActionNxLoadReg0(int value, int order) { ActionBuilder ab = createActionBuilder(order); ab.setAction(nxLoadRegAction(new DstNxRegCaseBuilder().setNxReg(NxmNxReg0.class).build(), BigInteger.valueOf(value), 31, false)); return ab.build(); } public static Action createActionNxSetNsp(Long nsp, int order) { return createActionNxLoadNsp(nsp.intValue(), order); } public static Action createActionNxSetNsi(Short nsi, int order) { return createActionNxLoadNsi(nsi.shortValue(), order); } public static Action createActionNxSetNshc1(Long c1, int order) { return createActionNxLoadNshc1(c1.longValue(), order); } public static Action createActionNxSetNshc2(Long c2, int order) { return createActionNxLoadNshc2(c2.longValue(), order); } public static Action createActionNxSetNshc3(Long c3, int order) { return createActionNxLoadNshc3(c3.longValue(), order); } public static Action createActionNxSetNshc4(Long c4, int order) { return createActionNxLoadNshc4(c4.longValue(), order); } public static WriteMetadataCase createInstructionMetadata(int order, BigInteger metadataVal, BigInteger metadataMask) { WriteMetadataBuilder wmb = new WriteMetadataBuilder(); wmb.setMetadata(metadataVal); wmb.setMetadataMask(metadataMask); WriteMetadataCaseBuilder wmcb = new WriteMetadataCaseBuilder().setWriteMetadata(wmb.build()); return wmcb.build(); } public static InstructionsBuilder createInstructionsBuilder(InstructionBuilder ib) { InstructionsBuilder isb = new InstructionsBuilder(); List<Instruction> instructions = new ArrayList<>(); instructions.add(ib.build()); isb.setInstruction(instructions); return isb; } public static InstructionsBuilder createInstructionsBuilder(InstructionBuilder... ibs) { InstructionsBuilder isb = new InstructionsBuilder(); List<Instruction> instructions = new ArrayList<>(); for (InstructionBuilder ib : ibs) { instructions.add(ib.build()); } isb.setInstruction(instructions); return isb; } public static InstructionBuilder createActionsInstructionBuilder(Action... actions) { InstructionBuilder actionsIb = new InstructionBuilder(); ArrayList<Action> alist = new ArrayList<>(); ApplyActionsBuilder aab = new ApplyActionsBuilder(); for (Action action : actions) { alist.add(action); } aab.setAction(alist); actionsIb.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); actionsIb.setKey(new InstructionKey(0)); actionsIb.setOrder(0); return actionsIb; } /** * Write a flow to the DataStore. * * @param nodeName * which node to write the flow to * @param flow * details of the flow to be written * @return true if the flow was written to the DS, false otherwise */ public static boolean writeFlowToDataStore(final String nodeName, FlowBuilder flow) { // Create the NodeBuilder NodeBuilder nodeBuilder = new NodeBuilder(); nodeBuilder.setId(new NodeId(nodeName)); nodeBuilder.setKey(new NodeKey(nodeBuilder.getId())); // Create the flow path, which will include the Node, Table, and Flow InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(flow.getTableId())).child(Flow.class, flow.getKey()).build(); return SfcDataStoreAPI.writePutTransactionAPI(flowInstanceId, flow.build(), LogicalDatastoreType.CONFIGURATION); } /** * remove a flow from the DataStore. * * @param nodeName * which node to write the flow to * @param tableKey * table Key * @param flowKey * flow key * @return true if the flow was removed from the DS, false otherwise */ public static boolean removeFlowFromDataStore(final String nodeName, TableKey tableKey, FlowKey flowKey) { NodeBuilder nodeBuilder = new NodeBuilder(); nodeBuilder.setId(new NodeId(nodeName)); nodeBuilder.setKey(new NodeKey(nodeBuilder.getId())); // Create the flow path InstanceIdentifier<Flow> flowInstanceId = InstanceIdentifier.builder(Nodes.class) .child(Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class) .child(Table.class, tableKey).child(Flow.class, flowKey).build(); return SfcDataStoreAPI.deleteTransactionAPI(flowInstanceId, LogicalDatastoreType.CONFIGURATION); } // Only configure OpenFlow Capable SFFs public static boolean isSffOpenFlowCapable(final String sffName) { InstanceIdentifier<FlowCapableNode> nodeInstancIdentifier = InstanceIdentifier.builder(Nodes.class) .child(Node.class, new NodeKey(new NodeId(sffName))).augmentation(FlowCapableNode.class).build(); // If its not a Flow Capable Node, this should return NULL // TODO need to verify this, once SFC can connect to simple OVS nodes // that arent flow capable FlowCapableNode node = SfcDataStoreAPI.readTransactionAPI(nodeInstancIdentifier, LogicalDatastoreType.OPERATIONAL); if (node != null) { return true; } return false; } /** * Creates an Instance Identifier (path) for node with specified id. * * @param nodeId * the ID of the node * @return the {@link InstanceIdentifier} */ public static final InstanceIdentifier<Node> createNodePath(final NodeId nodeId) { return InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(nodeId)).build(); } /** * Creates a table path from a node ID and table ID. * * @param nodeId * the ID of the node * @param tableId * the ID of the table * @return the {@link InstanceIdentifier} */ public static final InstanceIdentifier<Table> createTablePath(final NodeId nodeId, final short tableId) { return createNodePath(nodeId).builder().augmentation(FlowCapableNode.class) .child(Table.class, new TableKey(tableId)).build(); } /** * Creates a path for particular flow, by appending flow-specific * information to table path. * * @param table * the table iid * @param flowKey * the flow key * @return the {@link InstanceIdentifier} */ public static InstanceIdentifier<Flow> createFlowPath(final InstanceIdentifier<Table> table, final FlowKey flowKey) { return table.child(Flow.class, flowKey); } /** * Creates a path for particular flow, by appending flow-specific * information to table path. * * @param table * the table iid * @param flowId * the flow id * @return the {@link InstanceIdentifier} */ public static InstanceIdentifier<Flow> createFlowPath(final InstanceIdentifier<Table> table, final FlowId flowId) { return createFlowPath(table, new FlowKey(flowId)); } /** * Wrap the supplied actions in an apply-actions instruction. Since * apply-actions instructions are executed instantly, the 'order' parameter * of the instruction is set to 0. * * @param theActions * a list of actions * @return an InstructionsBuilder object, encapsulating the list of actions * in an appy-actions instruction */ public static InstructionsBuilder wrapActionsIntoApplyActionsInstruction(List<Action> theActions) { // Create an Apply Action ApplyActionsBuilder aab = new ApplyActionsBuilder(); aab.setAction(theActions); // Wrap our Apply Action in an Instruction InstructionBuilder ib = new InstructionBuilder(); ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); ib.setOrder(0); ib.setKey(new InstructionKey(0)); // Put our Instruction in a list of Instructions List<Instruction> instructions = new ArrayList<>(); instructions.add(ib.build()); return new InstructionsBuilder().setInstruction(instructions); } /** * Create a MatchBuilder object that builds matches for the given NSP and * NSI. * * @param nsp * the network service path we want to match * @param nsi * the network service index we want to match * @return Matches for the given NSP and NSI */ public static MatchBuilder getNshMatches(long nsp, short nsi) { MatchBuilder theMatch = new MatchBuilder(); SfcOpenflowUtils.addMatchNshNsp(theMatch, nsp); SfcOpenflowUtils.addMatchNshNsi(theMatch, nsi); return theMatch; } /** * Create a MatchBuilder object that builds matches for the given NSP. * * @param nsp * the network service path we want to match * @return the MatchBuilder object, that will match the given NSP */ public static MatchBuilder getNshMatches(long nsp) { MatchBuilder theMatch = new MatchBuilder(); SfcOpenflowUtils.addMatchNshNsp(theMatch, nsp); return theMatch; } /** * Creates a GotoTable instruction, and appends it to the supplied * InstructionsBuilder object. * * @param isb * an InstructionsBuilder object, to which we will append a * GotoTable instruction * @param nextTableId * the table that will feature in the GotoTable instruction * @return an InstructionsBuilder object, having the created GotoTable * instruction as the last instruction */ public static InstructionsBuilder appendGotoTableInstruction(InstructionsBuilder isb, short nextTableId) { if (isb.getInstruction() == null) { isb.setInstruction(new ArrayList<>()); } isb.getInstruction().add(createGotoTableInstruction(nextTableId, isb.getInstruction().size())); return isb; } /** * Create a GotoTable instruction. * * @param nextTableId * the table to which we want to go to * @param order * the order in which the instruction will be executed * @return the GotoTable instruction */ public static Instruction createGotoTableInstruction(short nextTableId, int order) { GoToTableBuilder gotoIngress = SfcOpenflowUtils.createActionGotoTable(nextTableId); return new InstructionBuilder().setKey(new InstructionKey(order)).setOrder(order) .setInstruction(new GoToTableCaseBuilder().setGoToTable(gotoIngress.build()).build()).build(); } /** * Creates a WriteMetadata instruction, and appends it to the supplied * InstructionsBuilder object. * * @param isb * an InstructionsBuilder object, to which we will append a * WriteMetadata instruction * @param theMetadata * the metadata that we want to write * @param metadataMask * the metadata mask, specifying the relevant bits of theMetadata * @return the WriteMetadata instruction */ public static InstructionsBuilder appendMetadataInstruction(InstructionsBuilder isb, BigInteger theMetadata, BigInteger metadataMask) { if (isb.getInstruction() == null) { isb.setInstruction(new ArrayList<>()); } isb.getInstruction().add(createAddMetadataInstruction(theMetadata, metadataMask, isb.getInstruction().size())); return isb; } /** * Create a WriteMetadata instruction. * * @param theMetadata * the metadata that we want to write * @param metadataMask * the metadata mask, specifying the relevant bits of theMetadata * @param order * the order in which the instruction will be executed * @return the WriteMetadata instruction */ public static Instruction createAddMetadataInstruction(BigInteger theMetadata, BigInteger metadataMask, int order) { return new InstructionBuilder() .setInstruction(SfcOpenflowUtils.createInstructionMetadata(order, theMetadata, metadataMask)) .setKey(new InstructionKey(order)).setOrder(order).build(); } /* * Returns the string representation for a given {@link BigInteger) * representing a MAC address. (e.g. for the value 257, it returns * "00:00:00:00:01:01") * * @param value The BigInteger representation for the mac address * * @return The string (i.e. 6 hex-formatted bytes separated with ":") * representation */ public static String macStringFromBigInteger(BigInteger value) { // a mac (48 bytes max) always fits into a 64 bit integer long macAddressLong = value.longValue(); byte[] macAddressComplete = new byte[6]; for (int i = 5; i >= 0; i--) { macAddressComplete[i] = (byte) (macAddressLong % 256); macAddressLong = macAddressLong >> 8L; } StringBuilder sb = new StringBuilder(18); for (int i = 0; i <= 5; i++) { byte macByte = macAddressComplete[i]; if (sb.length() > 0) { sb.append(':'); } sb.append(String.format("%02x", macByte)); } return sb.toString(); } }