alshabib
Committed by Gerrit Code Review

adding a criterion for inner vlans

used by olt to match on the inner vlan

Change-Id: I7671b68d9860d598395cba134a589ca23f264c7e
...@@ -147,7 +147,13 @@ public class Olt ...@@ -147,7 +147,13 @@ public class Olt
147 } 147 }
148 148
149 provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(), 149 provisionVlans(olt.deviceId(), olt.uplink(), port.port(), vlan, olt.vlan(),
150 - olt.defaultVlan()); 150 + olt.defaultVlan());
151 + }
152 +
153 + @Override
154 + public void removeSubscriber(ConnectPoint port) {
155 + throw new UnsupportedOperationException();
156 +
151 } 157 }
152 158
153 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort, 159 private void provisionVlans(DeviceId deviceId, PortNumber uplinkPort,
...@@ -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
......