2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
10 import com.google.common.collect.Iterables;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.controller.sal.common.util.Arguments;
15 import org.opendaylight.openflowplugin.api.OFConstants;
16 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
17 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
18 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 public final class PacketOutConvertor {
35 private static final Logger LOG = LoggerFactory.getLogger(PacketOutConvertor.class);
37 private PacketOutConvertor() {
41 // Get all the data for the PacketOut from the Yang/SAL-Layer
44 * @param version openflow version
45 * @param inputPacket input packet
46 * @param datapathid datapath id
48 * @return PacketOutInput required by OF Library
50 public static PacketOutInput toPacketOutInput(final TransmitPacketInput inputPacket, final short version, final Long xid,
51 final BigInteger datapathid) {
53 LOG.trace("toPacketOutInput for datapathId:{}, xid:{}", datapathid, xid);
54 // Build Port ID from TransmitPacketInput.Ingress
55 PortNumber inPortNr = null;
56 Long bufferId = OFConstants.OFP_NO_BUFFER;
57 Iterable<PathArgument> inArgs = null;
58 PacketOutInputBuilder builder = new PacketOutInputBuilder();
59 if (inputPacket.getIngress() != null) {
60 inArgs = inputPacket.getIngress().getValue().getPathArguments();
62 if (inArgs != null && Iterables.size(inArgs) >= 3) {
63 inPortNr = getPortNumber(Iterables.get(inArgs, 2), version);
65 // The packetOut originated from the controller
66 inPortNr = new PortNumber(0xfffffffdL);
69 // Build Buffer ID to be NO_OFP_NO_BUFFER
70 if (inputPacket.getBufferId() != null) {
71 bufferId = inputPacket.getBufferId();
74 PortNumber outPort = null;
75 NodeConnectorRef outRef = inputPacket.getEgress();
76 Iterable<PathArgument> outArgs = outRef.getValue().getPathArguments();
77 if (Iterables.size(outArgs) >= 3) {
78 outPort = getPortNumber(Iterables.get(outArgs, 2), version);
80 // TODO : P4 search for some normal exception
81 new Exception("PORT NR not exist in Egress");
84 List<Action> actions = null;
85 List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> inputActions =
86 inputPacket.getAction();
87 if (inputActions != null) {
88 actions = ActionConvertor.getActions(inputActions, version, datapathid, null);
91 actions = new ArrayList<>();
92 // TODO VD P! wait for way to move Actions (e.g. augmentation)
93 ActionBuilder aBuild = new ActionBuilder();
95 OutputActionCaseBuilder outputActionCaseBuilder =
96 new OutputActionCaseBuilder();
98 OutputActionBuilder outputActionBuilder =
99 new OutputActionBuilder();
101 outputActionBuilder.setPort(outPort);
102 outputActionBuilder.setMaxLength(OFConstants.OFPCML_NO_BUFFER);
104 outputActionCaseBuilder.setOutputAction(outputActionBuilder.build());
106 aBuild.setActionChoice(outputActionCaseBuilder.build());
108 actions.add(aBuild.build());
111 builder.setAction(actions);
112 builder.setData(inputPacket.getPayload());
113 builder.setVersion(version);
115 builder.setInPort(inPortNr);
116 builder.setBufferId(bufferId);
117 // --------------------------------------------------------
119 return builder.build();
122 private static PortNumber getPortNumber(final PathArgument pathArgument, final Short ofVersion) {
123 // FIXME VD P! find InstanceIdentifier helper
124 InstanceIdentifier.IdentifiableItem<?, ?> item = Arguments.checkInstanceOf(pathArgument,
125 InstanceIdentifier.IdentifiableItem.class);
126 NodeConnectorKey key = Arguments.checkInstanceOf(item.getKey(), NodeConnectorKey.class);
127 Long port = InventoryDataServiceUtil.portNumberfromNodeConnectorId(
128 OpenflowVersion.get(ofVersion), key.getId());
129 return new PortNumber(port);