blob: 388d0e6262e287dd6b78bc47cc1bbab53ee61aaf [file] [log] [blame]
Pier Ventre6f630052016-10-18 09:58:41 -07001/*
2 * Copyright 2016-present 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
17package org.onosproject.driver.extensions;
18
19import org.onlab.packet.VlanId;
20import org.onosproject.net.behaviour.ExtensionSelectorResolver;
21import org.onosproject.net.driver.AbstractHandlerBehaviour;
22import org.onosproject.net.flow.criteria.ExtensionSelector;
23import org.onosproject.net.flow.criteria.ExtensionSelectorType;
24import org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes;
25import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
26import org.projectfloodlight.openflow.protocol.OFFactory;
27import org.projectfloodlight.openflow.protocol.match.MatchField;
28import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
Pier Ventre9cf536b2016-10-21 13:30:18 -070029import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsL2Port;
Pier Ventre6f630052016-10-18 09:58:41 -070030import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaOvid;
31import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
32import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVidMasked;
33import org.projectfloodlight.openflow.types.OFVlanVidMatch;
34import org.projectfloodlight.openflow.types.U16;
Pier Ventre9cf536b2016-10-21 13:30:18 -070035import org.projectfloodlight.openflow.types.U32;
Pier Ventre6f630052016-10-18 09:58:41 -070036import org.projectfloodlight.openflow.types.VlanVid;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
40/**
41 * Interpreter for OFDPA3 OpenFlow selector extensions.
42 */
43public class Ofdpa3ExtensionSelectorInterpreter extends AbstractHandlerBehaviour
44 implements ExtensionSelectorInterpreter, ExtensionSelectorResolver {
45
46 private final Logger log = LoggerFactory.getLogger(getClass());
47
48 @Override
49 public boolean supported(ExtensionSelectorType extensionSelectorType) {
50 if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
51 return true;
52 } else if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
53 return true;
Pier Ventre9cf536b2016-10-21 13:30:18 -070054 } else if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
55 return true;
Pier Ventre6f630052016-10-18 09:58:41 -070056 }
57 return false;
58 }
59
60 @Override
61 public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) {
62 ExtensionSelectorType type = extensionSelector.type();
63 if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
64 VlanId vlanId = ((OfdpaMatchVlanVid) extensionSelector).vlanId();
65 // Special VLAN 0x0000/0x1FFF required by OFDPA
66 if (vlanId.equals(VlanId.NONE)) {
67 OFVlanVidMatch vid = OFVlanVidMatch.ofRawVid((short) 0x0000);
68 OFVlanVidMatch mask = OFVlanVidMatch.ofRawVid((short) 0x1FFF);
69 return factory.oxms().vlanVidMasked(vid, mask);
70 // Normal case
71 } else if (vlanId.equals(VlanId.ANY)) {
72 return factory.oxms().vlanVidMasked(OFVlanVidMatch.PRESENT, OFVlanVidMatch.PRESENT);
73 } else {
74 return factory.oxms().vlanVid(OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vlanId.toShort())));
75 }
76 } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
77 VlanId vlanId = ((Ofdpa3MatchOvid) extensionSelector).vlanId();
78 if (vlanId.equals(VlanId.NONE)) {
79 throw new UnsupportedOperationException(
80 "Unexpected ExtensionSelector: " + extensionSelector.toString());
81 } else if (vlanId.equals(VlanId.ANY)) {
82 throw new UnsupportedOperationException(
83 "Unexpected ExtensionSelector: " + extensionSelector.toString());
84 } else {
85 short mask = (short) 0x1000;
86 short oVid = (short) (mask | vlanId.toShort());
87 return factory.oxms().ofdpaOvid(U16.ofRaw(oVid));
88 }
Pier Ventre9cf536b2016-10-21 13:30:18 -070089 } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
90 int mplsL2Port = ((Ofdpa3MatchMplsL2Port) extensionSelector).mplsL2Port();
91 /*
92 * 0x0000XXXX UNI Interface.
93 * 0x0002XXXX NNI Interface
94 */
95 if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
96 (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
97 return factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port));
98 }
99 throw new UnsupportedOperationException(
100 "Unexpected ExtensionSelector: " + extensionSelector.toString());
Pier Ventre6f630052016-10-18 09:58:41 -0700101 }
102 throw new UnsupportedOperationException(
103 "Unexpected ExtensionSelector: " + extensionSelector.toString());
104 }
105
106 @Override
107 public ExtensionSelector mapOxm(OFOxm<?> oxm) {
108
109 if (oxm.getMatchField().equals(MatchField.VLAN_VID)) {
110 VlanId vlanId;
111 if (oxm.isMasked()) {
112 OFVlanVidMatch vid = ((OFOxmVlanVidMasked) oxm).getValue();
113 OFVlanVidMatch mask = ((OFOxmVlanVidMasked) oxm).getMask();
114
115 if (vid.equals(OFVlanVidMatch.ofRawVid((short) 0))) {
116 vlanId = VlanId.NONE;
117 } else if (vid.equals(OFVlanVidMatch.PRESENT) &&
118 mask.equals(OFVlanVidMatch.PRESENT)) {
119 vlanId = VlanId.ANY;
120 } else {
121 vlanId = VlanId.vlanId(vid.getVlan());
122 }
123 } else {
124 OFVlanVidMatch vid = ((OFOxmVlanVid) oxm).getValue();
125
126 if (!vid.isPresentBitSet()) {
127 vlanId = VlanId.NONE;
128 } else {
129 vlanId = VlanId.vlanId(vid.getVlan());
130 }
131 }
132 return new OfdpaMatchVlanVid(vlanId);
133 } else if (oxm.getMatchField().equals(MatchField.OFDPA_OVID)) {
134 VlanId vlanId;
135 if (oxm.isMasked()) {
136 throw new UnsupportedOperationException(
137 "Unexpected OXM: " + oxm.toString());
138 } else {
139 OFOxmOfdpaOvid ovid = ((OFOxmOfdpaOvid) oxm);
140 short mask = (short) 0x0FFF;
141 short oVid = (short) (mask & ovid.getValue().getRaw());
142 vlanId = VlanId.vlanId(oVid);
143 }
144 return new Ofdpa3MatchOvid(vlanId);
Pier Ventre9cf536b2016-10-21 13:30:18 -0700145 } else if (oxm.getMatchField().equals(MatchField.OFDPA_MPLS_L2_PORT)) {
146 Integer mplsL2Port;
147 /*
148 * Supported but not used for now.
149 */
150 if (oxm.isMasked()) {
151 throw new UnsupportedOperationException(
152 "Unexpected OXM: " + oxm.toString());
153 } else {
154 OFOxmOfdpaMplsL2Port mplsl2port = ((OFOxmOfdpaMplsL2Port) oxm);
155 mplsL2Port = mplsl2port.getValue().getRaw();
156 /*
157 * 0x0000XXXX UNI Interface.
158 * 0x0002XXXX NNI Interface
159 */
160 if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
161 (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
162 return new Ofdpa3MatchMplsL2Port(mplsL2Port);
163 }
164 throw new UnsupportedOperationException(
165 "Unexpected OXM: " + oxm.toString());
166 }
Pier Ventre6f630052016-10-18 09:58:41 -0700167 }
168 throw new UnsupportedOperationException(
169 "Unexpected OXM: " + oxm.toString());
170 }
171
172 @Override
173 public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) {
174 if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
175 return new OfdpaMatchVlanVid();
176 } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
177 return new Ofdpa3MatchOvid();
Pier Ventre9cf536b2016-10-21 13:30:18 -0700178 } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
179 return new Ofdpa3MatchMplsL2Port();
Pier Ventre6f630052016-10-18 09:58:41 -0700180 }
181 throw new UnsupportedOperationException(
182 "Driver does not support extension type " + type.toString());
183 }
184}