blob: c906f6053ca4bf0ba111e5a461190218189371ec [file] [log] [blame]
Charles Chancad338a2016-09-16 18:03:11 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Charles Chancad338a2016-09-16 18:03:11 -07003 *
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
17package org.onosproject.driver.extensions;
18
Pier Ventre6f630052016-10-18 09:58:41 -070019import org.onlab.packet.VlanId;
Charles Chancad338a2016-09-16 18:03:11 -070020import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
21import org.onosproject.net.driver.AbstractHandlerBehaviour;
22import org.onosproject.net.flow.instructions.ExtensionTreatment;
23import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
24import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
25import org.projectfloodlight.openflow.protocol.OFActionType;
26import org.projectfloodlight.openflow.protocol.OFFactory;
27import org.projectfloodlight.openflow.protocol.action.OFAction;
Pier Ventreee4a8f22016-10-22 15:45:36 -070028import org.projectfloodlight.openflow.protocol.action.OFActionExperimenter;
29import org.projectfloodlight.openflow.protocol.action.OFActionOfdpa;
Charles Chancad338a2016-09-16 18:03:11 -070030import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
31import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
Pier Ventre9cf536b2016-10-21 13:30:18 -070032import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsL2Port;
Charles Chancad338a2016-09-16 18:03:11 -070033import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsType;
Pier Ventre6f630052016-10-18 09:58:41 -070034import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaOvid;
Pier Ventredb252cc2016-10-21 21:54:26 -070035import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaQosIndex;
Charles Chancad338a2016-09-16 18:03:11 -070036import org.projectfloodlight.openflow.types.U16;
Pier Ventre9cf536b2016-10-21 13:30:18 -070037import org.projectfloodlight.openflow.types.U32;
Pier Ventredb252cc2016-10-21 21:54:26 -070038import org.projectfloodlight.openflow.types.U8;
Pier Ventre6f630052016-10-18 09:58:41 -070039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
Charles Chancad338a2016-09-16 18:03:11 -070041
42/**
43 * Interpreter for OFDPA3 OpenFlow treatment extensions.
44 */
45public class Ofdpa3ExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
46 implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {
Pier Ventre6f630052016-10-18 09:58:41 -070047
Pier Ventreee4a8f22016-10-22 15:45:36 -070048 private static final int TYPE_OFDPA = 0x1018;
49 private static final int SUB_TYPE_PUSH_L2_HEADER = 1;
50 private static final int SUB_TYPE_POP_L2_HEADER = 2;
51 private static final int SUB_TYPE_PUSH_CW = 3;
52 private static final int SUB_TYPE_POP_CW = 4;
53
Pier Ventre6f630052016-10-18 09:58:41 -070054 private final Logger log = LoggerFactory.getLogger(getClass());
55
Charles Chancad338a2016-09-16 18:03:11 -070056 @Override
57 public boolean supported(ExtensionTreatmentType extensionTreatmentType) {
58 if (extensionTreatmentType.equals(
59 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
60 return true;
Pier Ventre6f630052016-10-18 09:58:41 -070061 } else if (extensionTreatmentType.equals(
62 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
63 return true;
Pier Ventre9cf536b2016-10-21 13:30:18 -070064 } else if (extensionTreatmentType.equals(
65 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
66 return true;
Pier Ventredb252cc2016-10-21 21:54:26 -070067 } else if (extensionTreatmentType.equals(
68 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
69 return true;
Pier Ventreee4a8f22016-10-22 15:45:36 -070070 } else if (extensionTreatmentType.equals(
71 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
72 return true;
73 } else if (extensionTreatmentType.equals(
74 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
75 return true;
76 } else if (extensionTreatmentType.equals(
77 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
78 return true;
79 } else if (extensionTreatmentType.equals(
80 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
81 return true;
Charles Chancad338a2016-09-16 18:03:11 -070082 }
83 return false;
84 }
85
86 @Override
87 public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) {
88 ExtensionTreatmentType type = extensionTreatment.type();
89 if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
90 short mplsType = ((Ofdpa3SetMplsType) extensionTreatment).mplsType();
91 return factory.actions().setField(factory.oxms().ofdpaMplsType(
92 U16.ofRaw(mplsType)));
Pier Ventre6f630052016-10-18 09:58:41 -070093 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
94 // OFDPA requires isPresent bit set to 1 for OVID.
95 VlanId vlanId = ((Ofdpa3SetOvid) extensionTreatment).vlanId();
96 short mask = (short) 0x1000;
97 short oVid = (short) (mask | vlanId.toShort());
98 return factory.actions().setField(factory.oxms().ofdpaOvid(
99 U16.ofRaw(oVid)));
Pier Ventre9cf536b2016-10-21 13:30:18 -0700100 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
101 Integer mplsL2Port = ((Ofdpa3SetMplsL2Port) extensionTreatment).mplsL2Port();
102 /*
103 * 0x0000XXXX UNI Interface.
104 * 0x0002XXXX NNI Interface
105 */
106 if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
107 (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
108 return factory.actions().setField(
109 factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port))
110 );
111 }
112 throw new UnsupportedOperationException(
113 "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
Pier Ventredb252cc2016-10-21 21:54:26 -0700114 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
115 Integer qosIndex = ((Ofdpa3SetQosIndex) extensionTreatment).qosIndex();
116 /*
117 * Qos index is a single byte [0...255]
118 */
119 if (qosIndex >= 0 && qosIndex <= 255) {
120 return factory.actions().setField(
121 factory.oxms().ofdpaQosIndex(U8.ofRaw((byte) (qosIndex & 0xFF)))
122 );
123 }
124 throw new UnsupportedOperationException(
125 "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
Pier Ventreee4a8f22016-10-22 15:45:36 -0700126 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
127 return factory.actions().ofdpaPushL2Header();
128 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
129 return factory.actions().ofdpaPushCw();
130 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
131 return factory.actions().ofdpaPopL2Header();
132 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
133 return factory.actions().ofdpaPopCw();
Charles Chancad338a2016-09-16 18:03:11 -0700134 }
135 throw new UnsupportedOperationException(
136 "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
137 }
138
139 @Override
140 public ExtensionTreatment mapAction(OFAction action) throws UnsupportedOperationException {
141 if (action.getType().equals(OFActionType.SET_FIELD)) {
142 OFActionSetField setFieldAction = (OFActionSetField) action;
143 OFOxm<?> oxm = setFieldAction.getField();
144 switch (oxm.getMatchField().id) {
145 case OFDPA_MPLS_TYPE:
146 OFOxmOfdpaMplsType mplsType = (OFOxmOfdpaMplsType) oxm;
147 return new Ofdpa3SetMplsType(mplsType.getValue().getRaw());
Pier Ventre6f630052016-10-18 09:58:41 -0700148 case OFDPA_OVID:
149 OFOxmOfdpaOvid ovid = ((OFOxmOfdpaOvid) oxm);
150 short mask = (short) 0x0FFF;
151 short oVid = (short) (mask & ovid.getValue().getRaw());
152 VlanId vlanId = VlanId.vlanId(oVid);
153 return new Ofdpa3SetOvid(vlanId);
Pier Ventre9cf536b2016-10-21 13:30:18 -0700154 case OFDPA_MPLS_L2_PORT:
155 OFOxmOfdpaMplsL2Port mplsl2Port = ((OFOxmOfdpaMplsL2Port) oxm);
156 Integer mplsL2Port = mplsl2Port.getValue().getRaw();
157 if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
158 (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
159 return new Ofdpa3SetMplsL2Port(mplsL2Port);
160 }
Pier Ventredb252cc2016-10-21 21:54:26 -0700161 break;
162 case OFDPA_QOS_INDEX:
163 OFOxmOfdpaQosIndex qosindex = ((OFOxmOfdpaQosIndex) oxm);
164 Integer qosIndex = (int) qosindex.getValue().getRaw();
165 if (qosIndex >= 0 && qosIndex <= 255) {
166 return new Ofdpa3SetQosIndex(qosIndex);
167 }
168 break;
Charles Chancad338a2016-09-16 18:03:11 -0700169 default:
170 throw new UnsupportedOperationException(
171 "Driver does not support extension type " + oxm.getMatchField().id);
172 }
Pier Ventreee4a8f22016-10-22 15:45:36 -0700173 } else if (action.getType().equals(OFActionType.EXPERIMENTER)) {
174 OFActionExperimenter experimenter = (OFActionExperimenter) action;
175 if (Long.valueOf(experimenter.getExperimenter()).intValue() == TYPE_OFDPA) {
176 OFActionOfdpa ofdpa = (OFActionOfdpa) experimenter;
177 switch (ofdpa.getExpType()) {
178 case SUB_TYPE_PUSH_L2_HEADER:
179 return new Ofdpa3PushL2Header();
180 case SUB_TYPE_POP_L2_HEADER:
181 return new Ofdpa3PopL2Header();
182 case SUB_TYPE_PUSH_CW:
183 return new Ofdpa3PushCw();
184 case SUB_TYPE_POP_CW:
185 return new Ofdpa3PopCw();
186 default:
187 throw new UnsupportedOperationException(
188 "Unexpected OFAction: " + action.toString());
189 }
190 }
191 throw new UnsupportedOperationException(
192 "Unexpected OFAction: " + action.toString());
Charles Chancad338a2016-09-16 18:03:11 -0700193 }
194 throw new UnsupportedOperationException(
195 "Unexpected OFAction: " + action.toString());
196 }
197
198 @Override
199 public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
200 if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
201 return new Ofdpa3SetMplsType();
Pier Ventre6f630052016-10-18 09:58:41 -0700202 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
203 return new Ofdpa3SetOvid();
Pier Ventre9cf536b2016-10-21 13:30:18 -0700204 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
205 return new Ofdpa3SetMplsL2Port();
Pier Ventredb252cc2016-10-21 21:54:26 -0700206 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_QOS_INDEX.type())) {
207 return new Ofdpa3SetQosIndex();
Pier Ventreee4a8f22016-10-22 15:45:36 -0700208 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_L2_HEADER.type())) {
209 return new Ofdpa3PushL2Header();
210 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_PUSH_CW.type())) {
211 return new Ofdpa3PushCw();
212 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_L2_HEADER.type())) {
213 return new Ofdpa3PopL2Header();
214 } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_POP_CW.type())) {
215 return new Ofdpa3PopCw();
Charles Chancad338a2016-09-16 18:03:11 -0700216 }
217 throw new UnsupportedOperationException(
218 "Driver does not support extension type " + type.toString());
219 }
220}