Bug 1588 - OFConstants.java moved to openflowplugin-api module
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / PacketOutConvertor.java
1 /**
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor;
9
10 import org.opendaylight.controller.sal.common.util.Arguments;
11 import org.opendaylight.openflowplugin.api.OFConstants;
12 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
13 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowVersion;
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthAction;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaxLengthActionBuilder;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortAction;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortActionBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.ActionBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.TransmitPacketInput;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 import java.math.BigInteger;
32 import java.util.ArrayList;
33 import java.util.List;
34
35 public class PacketOutConvertor {
36     private static final Logger logger = LoggerFactory.getLogger(MeterConvertor.class);
37     private static final String PREFIX_SEPARATOR = "/";
38
39     private PacketOutConvertor() {
40
41     }
42
43     // Get all the data for the PacketOut from the Yang/SAL-Layer
44     /**
45      * @param version
46      * @param Yang
47      *            Data source
48      * @return PacketOutInput required by OF Library
49      */
50     public static PacketOutInput toPacketOutInput(TransmitPacketInput inputPacket, short version, Long xid,
51             BigInteger datapathid) {
52
53         // Build Port ID from TransmitPacketInput.Ingress
54         PortNumber inPortNr = null;
55         Long bufferId = OFConstants.OFP_NO_BUFFER;
56         List<Action> actions = new ArrayList<>();
57         List<PathArgument> inArgs = null;
58         PacketOutInputBuilder builder = new PacketOutInputBuilder();
59         if (inputPacket.getIngress() != null) {
60             inArgs = inputPacket.getIngress().getValue().getPath();
61         }
62         if (inArgs != null && inArgs.size() >= 3) {
63             inPortNr = getPortNumber(inArgs.get(2), version);
64         } else {
65             // The packetOut originated from the controller
66             inPortNr = new PortNumber(0xfffffffdL);
67         }
68
69         // Build Buffer ID to be NO_OFP_NO_BUFFER
70         if (inputPacket.getBufferId() != null) {
71             bufferId = inputPacket.getBufferId();
72         }
73
74         PortNumber outPort = null;
75         NodeConnectorRef outRef = inputPacket.getEgress();
76         List<PathArgument> outArgs = outRef.getValue().getPath();
77         if (outArgs.size() >= 3) {
78             outPort = getPortNumber(outArgs.get(2), version);
79         } else {
80             new Exception("PORT NR not exist in Egress"); // TODO : P4 search
81                                                           // for some normal
82                                                           // exception
83         }
84
85         // TODO VD P! wait for way to move Actions (e.g. augmentation)
86
87         // FIXME VD implementation for testing PacketIn (REMOVE IT)
88         if (inputPacket.getAction() == null) {
89             ActionBuilder aBuild = new ActionBuilder();
90             aBuild.setType(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Output.class);
91             PortActionBuilder paBuild = new PortActionBuilder();
92             paBuild.setPort(outPort);
93             aBuild.addAugmentation(PortAction.class, paBuild.build());
94             MaxLengthActionBuilder mlBuild = new MaxLengthActionBuilder();
95             mlBuild.setMaxLength(0xffff);
96             aBuild.addAugmentation(MaxLengthAction.class, mlBuild.build());
97             actions.add(aBuild.build());
98             builder.setAction(actions);
99         } else {
100             builder.setAction(ActionConvertor.getActions(inputPacket.getAction(), version, datapathid));
101         }
102
103         builder.setData(inputPacket.getPayload());
104         builder.setVersion(version);
105         builder.setXid(xid);
106         builder.setInPort(inPortNr);
107         builder.setBufferId(bufferId);
108         // --------------------------------------------------------
109
110         return builder.build();
111     }
112
113     private static PortNumber getPortNumber(PathArgument pathArgument, Short ofVersion) {
114         // FIXME VD P! find InstanceIdentifier helper
115         InstanceIdentifier.IdentifiableItem item = Arguments.checkInstanceOf(pathArgument,
116                 InstanceIdentifier.IdentifiableItem.class);
117         NodeConnectorKey key = Arguments.checkInstanceOf(item.getKey(), NodeConnectorKey.class);
118         String[] split = key.getId().getValue().split(":");
119         Long port = OpenflowPortsUtil.getPortFromLogicalName(OpenflowVersion.get(ofVersion), split[split.length - 1]);
120         return new PortNumber(port);
121     }
122 }