d12e4ad81ffe5fcc99d382fdbadba39e9e7b6fa0
[onosfw.git] /
1 /*
2  * Copyright 2015 Open Networking Laboratory
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onosproject.codec.impl;
17
18 import org.onosproject.codec.CodecContext;
19 import org.onosproject.net.OchSignal;
20 import org.onosproject.net.flow.instructions.Instruction;
21 import org.onosproject.net.flow.instructions.Instructions;
22 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
23 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
24 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
25 import org.onosproject.net.flow.instructions.L4ModificationInstruction;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import com.fasterxml.jackson.databind.node.ObjectNode;
30
31 /**
32  * JSON encoding of Instructions.
33  */
34 public final class EncodeInstructionCodecHelper {
35     protected static final Logger log = LoggerFactory.getLogger(EncodeInstructionCodecHelper.class);
36     private final Instruction instruction;
37     private final CodecContext context;
38
39     /**
40      * Creates an instruction object encoder.
41      *
42      * @param instruction instruction to encode
43      * @param context codec context for the encoding
44      */
45     public EncodeInstructionCodecHelper(Instruction instruction, CodecContext context) {
46         this.instruction = instruction;
47         this.context = context;
48     }
49
50
51     /**
52      * Encode an L0 modification instruction.
53      *
54      * @param result json node that the instruction attributes are added to
55      */
56     private void encodeL0(ObjectNode result) {
57         L0ModificationInstruction instruction =
58                 (L0ModificationInstruction) this.instruction;
59         result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
60
61         switch (instruction.subtype()) {
62             case LAMBDA:
63                 final L0ModificationInstruction.ModLambdaInstruction modLambdaInstruction =
64                         (L0ModificationInstruction.ModLambdaInstruction) instruction;
65                 result.put(InstructionCodec.LAMBDA, modLambdaInstruction.lambda());
66                 break;
67
68             case OCH:
69                 L0ModificationInstruction.ModOchSignalInstruction ochSignalInstruction =
70                         (L0ModificationInstruction.ModOchSignalInstruction) instruction;
71                 OchSignal ochSignal = ochSignalInstruction.lambda();
72                 result.put(InstructionCodec.GRID_TYPE, ochSignal.gridType().name());
73                 result.put(InstructionCodec.CHANNEL_SPACING, ochSignal.channelSpacing().name());
74                 result.put(InstructionCodec.SPACING_MULTIPLIER, ochSignal.spacingMultiplier());
75                 result.put(InstructionCodec.SLOT_GRANULARITY, ochSignal.slotGranularity());
76                 break;
77
78             default:
79                 log.info("Cannot convert L0 subtype of {}", instruction.subtype());
80         }
81     }
82
83     /**
84      * Encode an L2 modification instruction.
85      *
86      * @param result json node that the instruction attributes are added to
87      */
88     private void encodeL2(ObjectNode result) {
89         L2ModificationInstruction instruction =
90                 (L2ModificationInstruction) this.instruction;
91         result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
92
93         switch (instruction.subtype()) {
94             case ETH_SRC:
95             case ETH_DST:
96                 final L2ModificationInstruction.ModEtherInstruction modEtherInstruction =
97                         (L2ModificationInstruction.ModEtherInstruction) instruction;
98                 result.put(InstructionCodec.MAC, modEtherInstruction.mac().toString());
99                 break;
100
101             case VLAN_ID:
102                 final L2ModificationInstruction.ModVlanIdInstruction modVlanIdInstruction =
103                         (L2ModificationInstruction.ModVlanIdInstruction) instruction;
104                 result.put(InstructionCodec.VLAN_ID, modVlanIdInstruction.vlanId().toShort());
105                 break;
106
107             case VLAN_PCP:
108                 final L2ModificationInstruction.ModVlanPcpInstruction modVlanPcpInstruction =
109                         (L2ModificationInstruction.ModVlanPcpInstruction) instruction;
110                 result.put(InstructionCodec.VLAN_PCP, modVlanPcpInstruction.vlanPcp());
111                 break;
112
113             case MPLS_LABEL:
114                 final L2ModificationInstruction.ModMplsLabelInstruction modMplsLabelInstruction =
115                         (L2ModificationInstruction.ModMplsLabelInstruction) instruction;
116                 result.put(InstructionCodec.MPLS_LABEL, modMplsLabelInstruction.mplsLabel().toInt());
117                 break;
118
119             case MPLS_PUSH:
120                 final L2ModificationInstruction.PushHeaderInstructions pushHeaderInstructions =
121                         (L2ModificationInstruction.PushHeaderInstructions) instruction;
122
123                 result.put(InstructionCodec.ETHERNET_TYPE,
124                            pushHeaderInstructions.ethernetType().toShort());
125                 break;
126
127             case TUNNEL_ID:
128                 final L2ModificationInstruction.ModTunnelIdInstruction modTunnelIdInstruction =
129                         (L2ModificationInstruction.ModTunnelIdInstruction) instruction;
130                 result.put(InstructionCodec.TUNNEL_ID, modTunnelIdInstruction.tunnelId());
131                 break;
132
133             default:
134                 log.info("Cannot convert L2 subtype of {}", instruction.subtype());
135                 break;
136         }
137     }
138
139     /**
140      * Encode an L3 modification instruction.
141      *
142      * @param result json node that the instruction attributes are added to
143      */
144     private void encodeL3(ObjectNode result) {
145         L3ModificationInstruction instruction =
146                 (L3ModificationInstruction) this.instruction;
147         result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
148         switch (instruction.subtype()) {
149             case IPV4_SRC:
150             case IPV4_DST:
151             case IPV6_SRC:
152             case IPV6_DST:
153                 final L3ModificationInstruction.ModIPInstruction modIPInstruction =
154                         (L3ModificationInstruction.ModIPInstruction) instruction;
155                 result.put(InstructionCodec.IP, modIPInstruction.ip().toString());
156                 break;
157
158             case IPV6_FLABEL:
159                 final L3ModificationInstruction.ModIPv6FlowLabelInstruction
160                         modFlowLabelInstruction =
161                         (L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction;
162                 result.put(InstructionCodec.FLOW_LABEL, modFlowLabelInstruction.flowLabel());
163                 break;
164
165             default:
166                 log.info("Cannot convert L3 subtype of {}", instruction.subtype());
167                 break;
168         }
169     }
170
171     /**
172      * Encode a L4 modification instruction.
173      *
174      * @param result json node that the instruction attributes are added to
175      */
176     private void encodeL4(ObjectNode result) {
177         L4ModificationInstruction instruction =
178                 (L4ModificationInstruction) this.instruction;
179         result.put(InstructionCodec.SUBTYPE, instruction.subtype().name());
180         switch (instruction.subtype()) {
181             case TCP_DST:
182             case TCP_SRC:
183                 final L4ModificationInstruction.ModTransportPortInstruction modTcpPortInstruction =
184                         (L4ModificationInstruction.ModTransportPortInstruction) instruction;
185                 result.put(InstructionCodec.TCP_PORT, modTcpPortInstruction.port().toInt());
186                 break;
187
188             case UDP_DST:
189             case UDP_SRC:
190                 final L4ModificationInstruction.ModTransportPortInstruction modUdpPortInstruction =
191                         (L4ModificationInstruction.ModTransportPortInstruction) instruction;
192                 result.put(InstructionCodec.UDP_PORT, modUdpPortInstruction.port().toInt());
193                 break;
194
195             default:
196                 log.info("Cannot convert L4 subtype of {}", instruction.subtype());
197                 break;
198         }
199     }
200
201     /**
202      * Encodes the given instruction into JSON.
203      *
204      * @return JSON object node representing the instruction
205      */
206     public ObjectNode encode() {
207         final ObjectNode result = context.mapper().createObjectNode()
208                 .put(InstructionCodec.TYPE, instruction.type().toString());
209
210         switch (instruction.type()) {
211             case OUTPUT:
212                 final Instructions.OutputInstruction outputInstruction =
213                         (Instructions.OutputInstruction) instruction;
214                 result.put(InstructionCodec.PORT, outputInstruction.port().toLong());
215                 break;
216
217             case DROP:
218             case NOACTION:
219                 break;
220
221             case L0MODIFICATION:
222                 encodeL0(result);
223                 break;
224
225             case L2MODIFICATION:
226                 encodeL2(result);
227                 break;
228
229             case L3MODIFICATION:
230                 encodeL3(result);
231                 break;
232
233             case L4MODIFICATION:
234                 encodeL4(result);
235                 break;
236
237             default:
238                 log.info("Cannot convert instruction type of {}", instruction.type());
239                 break;
240         }
241         return result;
242     }
243
244 }