alshabib
Committed by Gerrit Code Review

adding a criterion for inner vlans

used by olt to match on the inner vlan

Change-Id: I7671b68d9860d598395cba134a589ca23f264c7e
...@@ -150,6 +150,12 @@ public class Olt ...@@ -150,6 +150,12 @@ public class Olt
150 olt.defaultVlan()); 150 olt.defaultVlan());
151 } 151 }
152 152
153 + @Override
154 + public void removeSubscriber(ConnectPoint port) {
155 + throw new UnsupportedOperationException();
156 +
157 + }
158 +
153 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort, 159 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort,
154 PortNumber subscriberPort, 160 PortNumber subscriberPort,
155 VlanId subscriberVlan, VlanId deviceVlan, 161 VlanId subscriberVlan, VlanId deviceVlan,
...@@ -166,6 +172,7 @@ public class Olt ...@@ -166,6 +172,7 @@ public class Olt
166 TrafficSelector downstream = DefaultTrafficSelector.builder() 172 TrafficSelector downstream = DefaultTrafficSelector.builder()
167 .matchVlanId(deviceVlan) 173 .matchVlanId(deviceVlan)
168 .matchInPort(uplinkPort) 174 .matchInPort(uplinkPort)
175 + .matchInnerVlanId(subscriberVlan)
169 .build(); 176 .build();
170 177
171 TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() 178 TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder()
...@@ -243,11 +250,6 @@ public class Olt ...@@ -243,11 +250,6 @@ public class Olt
243 250
244 } 251 }
245 252
246 - @Override
247 - public void removeSubscriber(ConnectPoint port) {
248 - throw new UnsupportedOperationException("Not yet implemented");
249 - }
250 -
251 private class InternalDeviceListener implements DeviceListener { 253 private class InternalDeviceListener implements DeviceListener {
252 @Override 254 @Override
253 public void event(DeviceEvent event) { 255 public void event(DeviceEvent event) {
......
...@@ -194,6 +194,16 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -194,6 +194,16 @@ public final class DefaultTrafficSelector implements TrafficSelector {
194 } 194 }
195 195
196 @Override 196 @Override
197 + public Builder matchInnerVlanId(VlanId vlanId) {
198 + return add(Criteria.matchInnerVlanId(vlanId));
199 + }
200 +
201 + @Override
202 + public Builder matchInnerVlanPcp(byte vlanPcp) {
203 + return add(Criteria.matchInnerVlanPcp(vlanPcp));
204 + }
205 +
206 + @Override
197 public Builder matchIPDscp(byte ipDscp) { 207 public Builder matchIPDscp(byte ipDscp) {
198 return add(Criteria.matchIPDscp(ipDscp)); 208 return add(Criteria.matchIPDscp(ipDscp));
199 } 209 }
......
...@@ -129,6 +129,22 @@ public interface TrafficSelector { ...@@ -129,6 +129,22 @@ public interface TrafficSelector {
129 Builder matchVlanPcp(byte vlanPcp); 129 Builder matchVlanPcp(byte vlanPcp);
130 130
131 /** 131 /**
132 + * Matches the inner vlan id.
133 + *
134 + * @param vlanId a vlan id
135 + * @return a selection builder
136 + */
137 + Builder matchInnerVlanId(VlanId vlanId);
138 +
139 + /**
140 + * Matches a vlan priority.
141 + *
142 + * @param vlanPcp a vlan priority
143 + * @return a selection builder
144 + */
145 + Builder matchInnerVlanPcp(byte vlanPcp);
146 +
147 + /**
132 * Matches an IP DSCP (6 bits in ToS field). 148 * Matches an IP DSCP (6 bits in ToS field).
133 * 149 *
134 * @param ipDscp an IP DSCP value 150 * @param ipDscp an IP DSCP value
......
...@@ -127,6 +127,16 @@ public final class Criteria { ...@@ -127,6 +127,16 @@ public final class Criteria {
127 } 127 }
128 128
129 /** 129 /**
130 + * Creates a match on the inner VLAN ID field using the specified value.
131 + *
132 + * @param vlanId vlan id value
133 + * @return match criterion
134 + */
135 + public static Criterion matchInnerVlanId(VlanId vlanId) {
136 + return new VlanIdCriterion(vlanId, Type.INNER_VLAN_VID);
137 + }
138 +
139 + /**
130 * Creates a match on VLAN PCP field using the specified value. 140 * Creates a match on VLAN PCP field using the specified value.
131 * 141 *
132 * @param vlanPcp vlan pcp value (3 bits) 142 * @param vlanPcp vlan pcp value (3 bits)
...@@ -137,6 +147,16 @@ public final class Criteria { ...@@ -137,6 +147,16 @@ public final class Criteria {
137 } 147 }
138 148
139 /** 149 /**
150 + * Creates a match on the inner VLAN PCP field using the specified value.
151 + *
152 + * @param vlanPcp vlan pcp value (3 bits)
153 + * @return match criterion
154 + */
155 + public static Criterion matchInnerVlanPcp(byte vlanPcp) {
156 + return new VlanPcpCriterion(vlanPcp, Type.INNER_VLAN_PCP);
157 + }
158 +
159 + /**
140 * Creates a match on IP DSCP field using the specified value. 160 * Creates a match on IP DSCP field using the specified value.
141 * 161 *
142 * @param ipDscp ip dscp value (6 bits) 162 * @param ipDscp ip dscp value (6 bits)
......
...@@ -50,6 +50,20 @@ public interface Criterion { ...@@ -50,6 +50,20 @@ public interface Criterion {
50 /** VLAN priority. */ 50 /** VLAN priority. */
51 VLAN_PCP, 51 VLAN_PCP,
52 52
53 + /**
54 + * Inner VLAN id.
55 + *
56 + * Note: Some drivers may not support this.
57 + */
58 + INNER_VLAN_VID,
59 +
60 + /**
61 + * Inner VLAN pcp.
62 + *
63 + * Note: Some drivers may not support this.
64 + */
65 + INNER_VLAN_PCP,
66 +
53 /** IP DSCP (6 bits in ToS field). */ 67 /** IP DSCP (6 bits in ToS field). */
54 IP_DSCP, 68 IP_DSCP,
55 69
......
...@@ -20,12 +20,14 @@ import org.onlab.packet.VlanId; ...@@ -20,12 +20,14 @@ import org.onlab.packet.VlanId;
20 import java.util.Objects; 20 import java.util.Objects;
21 21
22 import static com.google.common.base.MoreObjects.toStringHelper; 22 import static com.google.common.base.MoreObjects.toStringHelper;
23 +import static com.google.common.base.Preconditions.checkArgument;
23 24
24 /** 25 /**
25 * Implementation of VLAN ID criterion. 26 * Implementation of VLAN ID criterion.
26 */ 27 */
27 public final class VlanIdCriterion implements Criterion { 28 public final class VlanIdCriterion implements Criterion {
28 private final VlanId vlanId; 29 private final VlanId vlanId;
30 + private final Type type;
29 31
30 /** 32 /**
31 * Constructor. 33 * Constructor.
...@@ -34,11 +36,26 @@ public final class VlanIdCriterion implements Criterion { ...@@ -34,11 +36,26 @@ public final class VlanIdCriterion implements Criterion {
34 */ 36 */
35 VlanIdCriterion(VlanId vlanId) { 37 VlanIdCriterion(VlanId vlanId) {
36 this.vlanId = vlanId; 38 this.vlanId = vlanId;
39 + this.type = Type.VLAN_VID;
40 + }
41 +
42 + /**
43 + * Constructs a vlan criterion with a specific type.
44 + *
45 + * @param vlanId a vlan id to match
46 + * @param type a criterion type (only INNER_VLAN_VID and VLAN_ID are supported)
47 + */
48 + VlanIdCriterion(VlanId vlanId, Type type) {
49 + checkArgument(
50 + type == Type.INNER_VLAN_VID || type == Type.VLAN_VID,
51 + "Type can only be inner vlan or vlan");
52 + this.vlanId = vlanId;
53 + this.type = type;
37 } 54 }
38 55
39 @Override 56 @Override
40 public Type type() { 57 public Type type() {
41 - return Type.VLAN_VID; 58 + return type;
42 } 59 }
43 60
44 /** 61 /**
......
...@@ -18,6 +18,7 @@ package org.onosproject.net.flow.criteria; ...@@ -18,6 +18,7 @@ package org.onosproject.net.flow.criteria;
18 import java.util.Objects; 18 import java.util.Objects;
19 19
20 import static com.google.common.base.MoreObjects.toStringHelper; 20 import static com.google.common.base.MoreObjects.toStringHelper;
21 +import static com.google.common.base.Preconditions.checkArgument;
21 22
22 /** 23 /**
23 * Implementation of VLAN priority criterion (3 bits). 24 * Implementation of VLAN priority criterion (3 bits).
...@@ -25,6 +26,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -25,6 +26,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
25 public final class VlanPcpCriterion implements Criterion { 26 public final class VlanPcpCriterion implements Criterion {
26 private static final byte MASK = 0x7; 27 private static final byte MASK = 0x7;
27 private final byte vlanPcp; // VLAN pcp value: 3 bits 28 private final byte vlanPcp; // VLAN pcp value: 3 bits
29 + private final Type type;
28 30
29 /** 31 /**
30 * Constructor. 32 * Constructor.
...@@ -33,11 +35,26 @@ public final class VlanPcpCriterion implements Criterion { ...@@ -33,11 +35,26 @@ public final class VlanPcpCriterion implements Criterion {
33 */ 35 */
34 VlanPcpCriterion(byte vlanPcp) { 36 VlanPcpCriterion(byte vlanPcp) {
35 this.vlanPcp = (byte) (vlanPcp & MASK); 37 this.vlanPcp = (byte) (vlanPcp & MASK);
38 + this.type = Type.VLAN_PCP;
39 + }
40 +
41 + /**
42 + * Constructs a vlan priority criterion with a specific type.
43 + *
44 + * @param vlanPcp the VLAN priority to match (3 bits)
45 + * @param type a criterion type (only INNER_VLAN_PCP and VLAN_PCP are supported)
46 + */
47 + VlanPcpCriterion(byte vlanPcp, Type type) {
48 + checkArgument(
49 + type == Type.INNER_VLAN_PCP || type == Type.VLAN_PCP,
50 + "Type can only be inner vlan or vlan");
51 + this.vlanPcp = (byte) (vlanPcp & MASK);
52 + this.type = type;
36 } 53 }
37 54
38 @Override 55 @Override
39 public Type type() { 56 public Type type() {
40 - return Type.VLAN_PCP; 57 + return type;
41 } 58 }
42 59
43 /** 60 /**
......
...@@ -38,6 +38,8 @@ public final class CriterionCodec extends JsonCodec<Criterion> { ...@@ -38,6 +38,8 @@ public final class CriterionCodec extends JsonCodec<Criterion> {
38 protected static final String METADATA = "metadata"; 38 protected static final String METADATA = "metadata";
39 39
40 protected static final String VLAN_ID = "vlanId"; 40 protected static final String VLAN_ID = "vlanId";
41 + protected static final String INNER_VLAN_ID = "innerVlanId";
42 + protected static final String INNER_PRIORITY = "innerPriority";
41 protected static final String PRIORITY = "priority"; 43 protected static final String PRIORITY = "priority";
42 protected static final String IP_DSCP = "ipDscp"; 44 protected static final String IP_DSCP = "ipDscp";
43 protected static final String IP_ECN = "ipEcn"; 45 protected static final String IP_ECN = "ipEcn";
......
...@@ -72,6 +72,8 @@ public final class DecodeCriterionCodecHelper { ...@@ -72,6 +72,8 @@ public final class DecodeCriterionCodecHelper {
72 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder()); 72 decoderMap.put(Criterion.Type.ETH_TYPE.name(), new EthTypeDecoder());
73 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder()); 73 decoderMap.put(Criterion.Type.VLAN_VID.name(), new VlanVidDecoder());
74 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder()); 74 decoderMap.put(Criterion.Type.VLAN_PCP.name(), new VlanPcpDecoder());
75 + decoderMap.put(Criterion.Type.INNER_VLAN_VID.name(), new InnerVlanVidDecoder());
76 + decoderMap.put(Criterion.Type.INNER_VLAN_PCP.name(), new InnerVlanPcpDecoder());
75 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder()); 77 decoderMap.put(Criterion.Type.IP_DSCP.name(), new IpDscpDecoder());
76 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder()); 78 decoderMap.put(Criterion.Type.IP_ECN.name(), new IpEcnDecoder());
77 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder()); 79 decoderMap.put(Criterion.Type.IP_PROTO.name(), new IpProtoDecoder());
...@@ -139,7 +141,8 @@ public final class DecodeCriterionCodecHelper { ...@@ -139,7 +141,8 @@ public final class DecodeCriterionCodecHelper {
139 @Override 141 @Override
140 public Criterion decodeCriterion(ObjectNode json) { 142 public Criterion decodeCriterion(ObjectNode json) {
141 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT), 143 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
142 - CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong()); 144 + CriterionCodec.PORT +
145 + MISSING_MEMBER_MESSAGE).asLong());
143 146
144 return Criteria.matchInPort(port); 147 return Criteria.matchInPort(port);
145 } 148 }
...@@ -149,7 +152,8 @@ public final class DecodeCriterionCodecHelper { ...@@ -149,7 +152,8 @@ public final class DecodeCriterionCodecHelper {
149 @Override 152 @Override
150 public Criterion decodeCriterion(ObjectNode json) { 153 public Criterion decodeCriterion(ObjectNode json) {
151 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT), 154 PortNumber port = PortNumber.portNumber(nullIsIllegal(json.get(CriterionCodec.PORT),
152 - CriterionCodec.PORT + MISSING_MEMBER_MESSAGE).asLong()); 155 + CriterionCodec.PORT +
156 + MISSING_MEMBER_MESSAGE).asLong());
153 157
154 return Criteria.matchInPhyPort(port); 158 return Criteria.matchInPhyPort(port);
155 } 159 }
...@@ -179,12 +183,34 @@ public final class DecodeCriterionCodecHelper { ...@@ -179,12 +183,34 @@ public final class DecodeCriterionCodecHelper {
179 @Override 183 @Override
180 public Criterion decodeCriterion(ObjectNode json) { 184 public Criterion decodeCriterion(ObjectNode json) {
181 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY), 185 byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.PRIORITY),
182 - CriterionCodec.VLAN_ID + MISSING_MEMBER_MESSAGE).asInt(); 186 + CriterionCodec.PRIORITY + MISSING_MEMBER_MESSAGE).asInt();
183 187
184 return Criteria.matchVlanPcp(priority); 188 return Criteria.matchVlanPcp(priority);
185 } 189 }
186 } 190 }
187 191
192 + private class InnerVlanVidDecoder implements CriterionDecoder {
193 + @Override
194 + public Criterion decodeCriterion(ObjectNode json) {
195 + short vlanId = (short) nullIsIllegal(json.get(CriterionCodec.INNER_VLAN_ID),
196 + CriterionCodec.INNER_VLAN_ID +
197 + MISSING_MEMBER_MESSAGE).asInt();
198 +
199 + return Criteria.matchInnerVlanId(VlanId.vlanId(vlanId));
200 + }
201 + }
202 +
203 + private class InnerVlanPcpDecoder implements CriterionDecoder {
204 + @Override
205 + public Criterion decodeCriterion(ObjectNode json) {
206 + byte priority = (byte) nullIsIllegal(json.get(CriterionCodec.INNER_PRIORITY),
207 + CriterionCodec.INNER_PRIORITY +
208 + MISSING_MEMBER_MESSAGE).asInt();
209 +
210 + return Criteria.matchInnerVlanPcp(priority);
211 + }
212 + }
213 +
188 private class IpDscpDecoder implements CriterionDecoder { 214 private class IpDscpDecoder implements CriterionDecoder {
189 @Override 215 @Override
190 public Criterion decodeCriterion(ObjectNode json) { 216 public Criterion decodeCriterion(ObjectNode json) {
......
...@@ -84,6 +84,8 @@ public final class EncodeCriterionCodecHelper { ...@@ -84,6 +84,8 @@ public final class EncodeCriterionCodecHelper {
84 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType()); 84 formatMap.put(Criterion.Type.ETH_TYPE, new FormatEthType());
85 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid()); 85 formatMap.put(Criterion.Type.VLAN_VID, new FormatVlanVid());
86 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp()); 86 formatMap.put(Criterion.Type.VLAN_PCP, new FormatVlanPcp());
87 + formatMap.put(Criterion.Type.INNER_VLAN_VID, new FormatInnerVlanVid());
88 + formatMap.put(Criterion.Type.INNER_VLAN_PCP, new FormatInnerVlanPcp());
87 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp()); 89 formatMap.put(Criterion.Type.IP_DSCP, new FormatIpDscp());
88 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn()); 90 formatMap.put(Criterion.Type.IP_ECN, new FormatIpEcn());
89 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto()); 91 formatMap.put(Criterion.Type.IP_PROTO, new FormatIpProto());
...@@ -194,6 +196,24 @@ public final class EncodeCriterionCodecHelper { ...@@ -194,6 +196,24 @@ public final class EncodeCriterionCodecHelper {
194 } 196 }
195 } 197 }
196 198
199 + private static class FormatInnerVlanVid implements CriterionTypeFormatter {
200 + @Override
201 + public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
202 + final VlanIdCriterion vlanIdCriterion =
203 + (VlanIdCriterion) criterion;
204 + return root.put(CriterionCodec.INNER_VLAN_ID, vlanIdCriterion.vlanId().toShort());
205 + }
206 + }
207 +
208 + private static class FormatInnerVlanPcp implements CriterionTypeFormatter {
209 + @Override
210 + public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
211 + final VlanPcpCriterion vlanPcpCriterion =
212 + (VlanPcpCriterion) criterion;
213 + return root.put(CriterionCodec.INNER_PRIORITY, vlanPcpCriterion.priority());
214 + }
215 + }
216 +
197 private static class FormatIpDscp implements CriterionTypeFormatter { 217 private static class FormatIpDscp implements CriterionTypeFormatter {
198 @Override 218 @Override
199 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) { 219 public ObjectNode encodeCriterion(ObjectNode root, Criterion criterion) {
......
...@@ -214,24 +214,34 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner { ...@@ -214,24 +214,34 @@ public class OltPipeline extends AbstractHandlerBehaviour implements Pipeliner {
214 214
215 Pair<Instruction, Instruction> popAndRewrite = vlanOps.remove(0); 215 Pair<Instruction, Instruction> popAndRewrite = vlanOps.remove(0);
216 216
217 - FlowRule.Builder inner = DefaultFlowRule.builder() 217 + TrafficSelector selector = fwd.selector();
218 +
219 + Criterion outerVlan = selector.getCriterion(Criterion.Type.VLAN_VID);
220 + Criterion innerVlan = selector.getCriterion(Criterion.Type.INNER_VLAN_VID);
221 + Criterion inport = selector.getCriterion(Criterion.Type.IN_PORT);
222 +
223 + if (outerVlan == null || innerVlan == null || inport == null) {
224 + log.error("Forwarding objective is underspecified: {}", fwd);
225 + fail(fwd, ObjectiveError.BADPARAMS);
226 + return;
227 + }
228 +
229 + FlowRule.Builder outer = DefaultFlowRule.builder()
218 .forDevice(deviceId) 230 .forDevice(deviceId)
219 .fromApp(appId) 231 .fromApp(appId)
220 .makePermanent() 232 .makePermanent()
221 .withPriority(fwd.priority()) 233 .withPriority(fwd.priority())
222 - .withSelector(fwd.selector()) 234 + .withSelector(buildSelector(inport, outerVlan))
223 .withTreatment(buildTreatment(popAndRewrite.getLeft(), 235 .withTreatment(buildTreatment(popAndRewrite.getLeft(),
224 Instructions.transition(QQ_TABLE))); 236 Instructions.transition(QQ_TABLE)));
225 - PortCriterion inPort = (PortCriterion)
226 - fwd.selector().getCriterion(Criterion.Type.IN_PORT);
227 237
228 - FlowRule.Builder outer = DefaultFlowRule.builder() 238 + FlowRule.Builder inner = DefaultFlowRule.builder()
229 .forDevice(deviceId) 239 .forDevice(deviceId)
230 .fromApp(appId) 240 .fromApp(appId)
231 .forTable(QQ_TABLE) 241 .forTable(QQ_TABLE)
232 .makePermanent() 242 .makePermanent()
233 .withPriority(fwd.priority()) 243 .withPriority(fwd.priority())
234 - .withSelector(buildSelector(inPort)) 244 + .withSelector(buildSelector(inport, innerVlan))
235 .withTreatment(buildTreatment(popAndRewrite.getRight(), 245 .withTreatment(buildTreatment(popAndRewrite.getRight(),
236 output)); 246 output));
237 247
......