Praseed Balakrishnan
Committed by Gerrit Code Review

MPLS label selector and treatment

Change-Id: Id1fba1e04155e6d97de4c8fd95573641537f1b7a
1 +/*
2 + * Copyright 2014 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.onlab.onos.optical.testapp;
17 +
18 +import static org.slf4j.LoggerFactory.getLogger;
19 +
20 +import java.util.HashMap;
21 +import java.util.Map;
22 +
23 +import org.apache.felix.scr.annotations.Activate;
24 +import org.apache.felix.scr.annotations.Deactivate;
25 +import org.apache.felix.scr.annotations.Reference;
26 +import org.apache.felix.scr.annotations.ReferenceCardinality;
27 +import org.onlab.onos.core.ApplicationId;
28 +import org.onlab.onos.core.CoreService;
29 +import org.onlab.onos.net.Device;
30 +import org.onlab.onos.net.DeviceId;
31 +import org.onlab.onos.net.PortNumber;
32 +import org.onlab.onos.net.device.DeviceEvent;
33 +import org.onlab.onos.net.device.DeviceListener;
34 +import org.onlab.onos.net.device.DeviceService;
35 +import org.onlab.onos.net.flow.DefaultFlowRule;
36 +import org.onlab.onos.net.flow.DefaultTrafficSelector;
37 +import org.onlab.onos.net.flow.DefaultTrafficTreatment;
38 +import org.onlab.onos.net.flow.FlowRule;
39 +import org.onlab.onos.net.flow.FlowRuleService;
40 +import org.onlab.onos.net.flow.TrafficSelector;
41 +import org.onlab.onos.net.flow.TrafficTreatment;
42 +import org.onlab.packet.Ethernet;
43 +import org.slf4j.Logger;
44 +
45 +/**
46 + * Sample reactive forwarding application.
47 + */
48 +//@Component(immediate = true)
49 +public class MPLSForwarding {
50 +
51 + private final Logger log = getLogger(getClass());
52 +
53 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
54 + protected FlowRuleService flowRuleService;
55 +
56 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
57 + protected CoreService coreService;
58 +
59 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
60 + protected DeviceService deviceService;
61 +
62 + private ApplicationId appId;
63 +
64 + private final InternalDeviceListener listener = new InternalDeviceListener();
65 +
66 + private final Map<DeviceId, Integer> uglyMap = new HashMap<>();
67 +
68 + @Activate
69 + public void activate() {
70 + appId = coreService.registerApplication("org.onlab.onos.testapp" +
71 + ".mplsfwd");
72 +
73 + uglyMap.put(DeviceId.deviceId("of:0000000000000001"), 1);
74 + uglyMap.put(DeviceId.deviceId("of:0000000000000002"), 2);
75 + uglyMap.put(DeviceId.deviceId("of:0000000000000003"), 3);
76 +
77 + deviceService.addListener(listener);
78 +
79 + for (Device d : deviceService.getDevices()) {
80 + pushRules(d);
81 + }
82 +
83 +
84 + log.info("Started with Application ID {}", appId.id());
85 + }
86 +
87 + @Deactivate
88 + public void deactivate() {
89 + flowRuleService.removeFlowRulesById(appId);
90 +
91 + log.info("Stopped");
92 + }
93 +
94 +
95 + private void pushRules(Device device) {
96 +
97 + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
98 + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
99 + int inport = 1;
100 + int outport = 2;
101 + Integer mplsLabel = 101;
102 + Integer switchNumber = uglyMap.get(device.id());
103 + if (switchNumber == null) {
104 + return;
105 + }
106 +
107 + switch (switchNumber) {
108 + case 1:
109 + sbuilder.matchInport(PortNumber.portNumber(inport));
110 + tbuilder.setOutput(PortNumber.portNumber(outport))
111 + .pushMpls()
112 + .setMpls(mplsLabel);
113 + break;
114 + case 2:
115 + sbuilder.matchMplsLabel(mplsLabel)
116 + .matchEthType(Ethernet.MPLS_UNICAST)
117 + .matchInport(PortNumber.portNumber(inport));
118 + tbuilder.setOutput(PortNumber.portNumber(outport));
119 + break;
120 + case 3:
121 + sbuilder.matchMplsLabel(mplsLabel)
122 + .matchEthType(Ethernet.MPLS_UNICAST)
123 + .matchInport(PortNumber.portNumber(inport));
124 + tbuilder.popMpls().setOutput(PortNumber.portNumber(outport));
125 + break;
126 + default:
127 + }
128 +
129 + TrafficTreatment treatement = tbuilder.build();
130 + TrafficSelector selector = sbuilder.build();
131 +
132 + FlowRule f = new DefaultFlowRule(device.id(), selector,
133 + treatement, 100, appId, 600, false);
134 +
135 + flowRuleService.applyFlowRules(f);
136 + }
137 +
138 +
139 + public class InternalDeviceListener implements DeviceListener {
140 +
141 + @Override
142 + public void event(DeviceEvent event) {
143 + switch (event.type()) {
144 + case DEVICE_ADDED:
145 + pushRules(event.subject());
146 + break;
147 + case DEVICE_AVAILABILITY_CHANGED:
148 + break;
149 + case DEVICE_MASTERSHIP_CHANGED:
150 + break;
151 + case DEVICE_REMOVED:
152 + break;
153 + case DEVICE_SUSPENDED:
154 + break;
155 + case DEVICE_UPDATED:
156 + break;
157 + case PORT_ADDED:
158 + break;
159 + case PORT_REMOVED:
160 + break;
161 + case PORT_UPDATED:
162 + break;
163 + default:
164 + break;
165 +
166 + }
167 +
168 + }
169 +
170 + }
171 +
172 +
173 +}
174 +
175 +
...@@ -184,6 +184,11 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -184,6 +184,11 @@ public final class DefaultTrafficSelector implements TrafficSelector {
184 } 184 }
185 185
186 @Override 186 @Override
187 + public Builder matchMplsLabel(Integer mplsLabel) {
188 + return add(Criteria.matchMplsLabel(mplsLabel));
189 + }
190 +
191 + @Override
187 public Builder matchLambda(Short lambda) { 192 public Builder matchLambda(Short lambda) {
188 return add(Criteria.matchLambda(lambda)); 193 return add(Criteria.matchLambda(lambda));
189 } 194 }
...@@ -191,7 +196,6 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -191,7 +196,6 @@ public final class DefaultTrafficSelector implements TrafficSelector {
191 @Override 196 @Override
192 public Builder matchOpticalSignalType(Short signalType) { 197 public Builder matchOpticalSignalType(Short signalType) {
193 return add(Criteria.matchOpticalSignalType(signalType)); 198 return add(Criteria.matchOpticalSignalType(signalType));
194 -
195 } 199 }
196 200
197 @Override 201 @Override
......
...@@ -192,6 +192,22 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -192,6 +192,22 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
192 } 192 }
193 193
194 @Override 194 @Override
195 + public Builder pushMpls() {
196 + return add(Instructions.pushMpls());
197 + }
198 +
199 + @Override
200 + public Builder popMpls() {
201 + return add(Instructions.popMpls());
202 + }
203 +
204 +
205 + @Override
206 + public Builder setMpls(Integer mplsLabel) {
207 + return add(Instructions.modMplsLabel(mplsLabel));
208 + }
209 +
210 + @Override
195 public Builder setLambda(short lambda) { 211 public Builder setLambda(short lambda) {
196 return add(Instructions.modL0Lambda(lambda)); 212 return add(Instructions.modL0Lambda(lambda));
197 } 213 }
......
...@@ -146,6 +146,14 @@ public interface TrafficSelector { ...@@ -146,6 +146,14 @@ public interface TrafficSelector {
146 */ 146 */
147 public Builder matchTcpDst(Short tcpPort); 147 public Builder matchTcpDst(Short tcpPort);
148 148
149 +
150 + /**
151 + * Matches on a MPLS label .
152 + * @param mplsLabel a MPLS label.
153 + * @return a selection builder
154 + */
155 + public Builder matchMplsLabel(Integer mplsLabel);
156 +
149 /** 157 /**
150 * Matches an optical signal ID or lambda. 158 * Matches an optical signal ID or lambda.
151 * 159 *
......
...@@ -110,6 +110,25 @@ public interface TrafficTreatment { ...@@ -110,6 +110,25 @@ public interface TrafficTreatment {
110 public Builder setIpDst(IpAddress addr); 110 public Builder setIpDst(IpAddress addr);
111 111
112 /** 112 /**
113 + * Push MPLS ether type.
114 + * @return a treatment builder.
115 + */
116 + public Builder pushMpls();
117 +
118 + /**
119 + * Pops MPLS ether type.
120 + * @return a treatment builder.
121 + */
122 + public Builder popMpls();
123 +
124 + /**
125 + * Sets the mpls label.
126 + * @param mplsLabel MPLS label.
127 + * @return a treatment builder.
128 + */
129 + public Builder setMpls(Integer mplsLabel);
130 +
131 + /**
113 * Sets the optical channel ID or lambda. 132 * Sets the optical channel ID or lambda.
114 * 133 *
115 * @param lambda optical channel ID 134 * @param lambda optical channel ID
......
...@@ -149,6 +149,16 @@ public final class Criteria { ...@@ -149,6 +149,16 @@ public final class Criteria {
149 } 149 }
150 150
151 /** 151 /**
152 + * Creates a match on MPLS label.
153 + * @param mplsLabel MPLS label
154 + * @return match criterion
155 + */
156 +
157 + public static Criterion matchMplsLabel(Integer mplsLabel) {
158 + return new MplsCriterion(mplsLabel);
159 + }
160 +
161 + /**
152 * Creates a match on lambda field using the specified value. 162 * Creates a match on lambda field using the specified value.
153 * 163 *
154 * @param lambda lamda to match on 164 * @param lambda lamda to match on
...@@ -541,6 +551,52 @@ public final class Criteria { ...@@ -541,6 +551,52 @@ public final class Criteria {
541 } 551 }
542 } 552 }
543 553
554 + public static final class MplsCriterion implements Criterion {
555 +
556 + private final Integer mplsLabel;
557 +
558 + public MplsCriterion(Integer mplsLabel) {
559 + this.mplsLabel = mplsLabel;
560 + }
561 +
562 + @Override
563 + public Type type() {
564 + return Type.MPLS_LABEL;
565 + }
566 +
567 + public Integer label() {
568 + return mplsLabel;
569 + }
570 +
571 + @Override
572 + public String toString() {
573 + return toStringHelper(type().toString())
574 + .add("mpls", mplsLabel.intValue()).toString();
575 + }
576 +
577 + @Override
578 + public int hashCode() {
579 + return Objects.hash(mplsLabel, type());
580 + }
581 +
582 + @Override
583 + public boolean equals(Object obj) {
584 + if (this == obj) {
585 + return true;
586 + }
587 + if (obj instanceof MplsCriterion) {
588 + MplsCriterion that = (MplsCriterion) obj;
589 + return Objects.equals(mplsLabel, that.mplsLabel) &&
590 + Objects.equals(this.type(), that.type());
591 +
592 +
593 + }
594 + return false;
595 + }
596 +
597 + }
598 +
599 +
544 public static final class LambdaCriterion implements Criterion { 600 public static final class LambdaCriterion implements Criterion {
545 601
546 private final short lambda; 602 private final short lambda;
......
...@@ -17,6 +17,7 @@ package org.onlab.onos.net.flow.instructions; ...@@ -17,6 +17,7 @@ package org.onlab.onos.net.flow.instructions;
17 17
18 import static com.google.common.base.MoreObjects.toStringHelper; 18 import static com.google.common.base.MoreObjects.toStringHelper;
19 import static com.google.common.base.Preconditions.checkNotNull; 19 import static com.google.common.base.Preconditions.checkNotNull;
20 +import static org.onlab.onos.net.flow.instructions.L2ModificationInstruction.*;
20 21
21 import java.util.Objects; 22 import java.util.Objects;
22 23
...@@ -27,6 +28,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType; ...@@ -27,6 +28,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType;
27 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 28 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
28 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType; 29 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType;
29 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 30 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
31 +
32 +import org.onlab.packet.Ethernet;
30 import org.onlab.packet.IpAddress; 33 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.MacAddress; 34 import org.onlab.packet.MacAddress;
32 import org.onlab.packet.VlanId; 35 import org.onlab.packet.VlanId;
...@@ -87,7 +90,7 @@ public final class Instructions { ...@@ -87,7 +90,7 @@ public final class Instructions {
87 */ 90 */
88 public static L2ModificationInstruction modL2Dst(MacAddress addr) { 91 public static L2ModificationInstruction modL2Dst(MacAddress addr) {
89 checkNotNull(addr, "Dst l2 address cannot be null"); 92 checkNotNull(addr, "Dst l2 address cannot be null");
90 - return new L2ModificationInstruction.ModEtherInstruction(L2SubType.ETH_DST, addr); 93 + return new ModEtherInstruction(L2SubType.ETH_DST, addr);
91 } 94 }
92 95
93 /** 96 /**
...@@ -97,7 +100,7 @@ public final class Instructions { ...@@ -97,7 +100,7 @@ public final class Instructions {
97 */ 100 */
98 public static L2ModificationInstruction modVlanId(VlanId vlanId) { 101 public static L2ModificationInstruction modVlanId(VlanId vlanId) {
99 checkNotNull(vlanId, "VLAN id cannot be null"); 102 checkNotNull(vlanId, "VLAN id cannot be null");
100 - return new L2ModificationInstruction.ModVlanIdInstruction(vlanId); 103 + return new ModVlanIdInstruction(vlanId);
101 } 104 }
102 105
103 /** 106 /**
...@@ -107,10 +110,19 @@ public final class Instructions { ...@@ -107,10 +110,19 @@ public final class Instructions {
107 */ 110 */
108 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) { 111 public static L2ModificationInstruction modVlanPcp(Byte vlanPcp) {
109 checkNotNull(vlanPcp, "VLAN Pcp cannot be null"); 112 checkNotNull(vlanPcp, "VLAN Pcp cannot be null");
110 - return new L2ModificationInstruction.ModVlanPcpInstruction(vlanPcp); 113 + return new ModVlanPcpInstruction(vlanPcp);
111 } 114 }
112 115
113 /** 116 /**
117 + * Creates a MPLS label modification.
118 + * @param mplsLabel to set.
119 + * @return a L2 Modification
120 + */
121 + public static L2ModificationInstruction modMplsLabel(Integer mplsLabel) {
122 + checkNotNull(mplsLabel, "MPLS label cannot be null");
123 + return new ModMplsLabelInstruction(mplsLabel);
124 + }
125 + /**
114 * Creates a L3 src modification. 126 * Creates a L3 src modification.
115 * @param addr the ip address to modify to. 127 * @param addr the ip address to modify to.
116 * @return a L3 modification 128 * @return a L3 modification
...@@ -130,6 +142,23 @@ public final class Instructions { ...@@ -130,6 +142,23 @@ public final class Instructions {
130 return new ModIPInstruction(L3SubType.IP_DST, addr); 142 return new ModIPInstruction(L3SubType.IP_DST, addr);
131 } 143 }
132 144
145 + /**
146 + * Creates a mpls header instruction.
147 + * @return a L2 modification.
148 + */
149 + public static Instruction pushMpls() {
150 + return new PushHeaderInstructions(L2SubType.MPLS_PUSH,
151 + new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
152 + }
153 +
154 + /**
155 + * Creates a mpls header instruction.
156 + * @return a L2 modification.
157 + */
158 + public static Instruction popMpls() {
159 + return new PushHeaderInstructions(L2SubType.MPLS_POP,
160 + new Ethernet().setEtherType(Ethernet.MPLS_UNICAST));
161 + }
133 162
134 /* 163 /*
135 * Output instructions 164 * Output instructions
......
...@@ -19,6 +19,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -19,6 +19,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
19 19
20 import java.util.Objects; 20 import java.util.Objects;
21 21
22 +import org.onlab.packet.Ethernet;
22 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
23 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
24 25
...@@ -49,7 +50,22 @@ public abstract class L2ModificationInstruction implements Instruction { ...@@ -49,7 +50,22 @@ public abstract class L2ModificationInstruction implements Instruction {
49 /** 50 /**
50 * VLAN priority modification. 51 * VLAN priority modification.
51 */ 52 */
52 - VLAN_PCP 53 + VLAN_PCP,
54 +
55 + /**
56 + * MPLS Label modification.
57 + */
58 + MPLS_LABEL,
59 +
60 + /**
61 + * MPLS Push modification.
62 + */
63 + MPLS_PUSH,
64 +
65 + /**
66 + * MPLS Pop modification.
67 + */
68 + MPLS_POP
53 } 69 }
54 70
55 // TODO: Create factory class 'Instructions' that will have various factory 71 // TODO: Create factory class 'Instructions' that will have various factory
...@@ -114,6 +130,53 @@ public abstract class L2ModificationInstruction implements Instruction { ...@@ -114,6 +130,53 @@ public abstract class L2ModificationInstruction implements Instruction {
114 130
115 } 131 }
116 132
133 + public static final class PushHeaderInstructions extends
134 + L2ModificationInstruction {
135 +
136 + private final L2SubType subtype;
137 + private final Ethernet ethernetType;
138 +
139 + public PushHeaderInstructions(L2SubType subType, Ethernet ethernetType) {
140 + this.subtype = subType;
141 + this.ethernetType = ethernetType;
142 + }
143 +
144 + public Ethernet ethernetType() {
145 + return ethernetType;
146 + }
147 +
148 + @Override
149 + public L2SubType subtype() {
150 + return this.subtype;
151 + }
152 +
153 + @Override
154 + public String toString() {
155 + return toStringHelper(subtype().toString()).toString();
156 + }
157 +
158 + @Override
159 + public int hashCode() {
160 + return Objects.hash(type(), subtype);
161 + }
162 +
163 + @Override
164 + public boolean equals(Object obj) {
165 + if (this == obj) {
166 + return true;
167 + }
168 + if (obj instanceof PushHeaderInstructions) {
169 + PushHeaderInstructions that = (PushHeaderInstructions) obj;
170 + return Objects.equals(this.type(), that.type()) &&
171 + Objects.equals(subtype, that.subtype);
172 +
173 + }
174 + return false;
175 + }
176 + }
177 +
178 +
179 +
117 /** 180 /**
118 * Represents a VLAN id modification instruction. 181 * Represents a VLAN id modification instruction.
119 */ 182 */
...@@ -212,4 +275,51 @@ public abstract class L2ModificationInstruction implements Instruction { ...@@ -212,4 +275,51 @@ public abstract class L2ModificationInstruction implements Instruction {
212 } 275 }
213 276
214 277
278 + /**
279 + * Represents a MPLS label modification.
280 + */
281 + public static final class ModMplsLabelInstruction extends
282 + L2ModificationInstruction {
283 +
284 + private final Integer mplsLabel;
285 +
286 + public ModMplsLabelInstruction(Integer mplsLabel) {
287 + this.mplsLabel = mplsLabel;
288 + }
289 +
290 + public Integer label() {
291 + return mplsLabel;
292 + }
293 +
294 + @Override
295 + public L2SubType subtype() {
296 + return L2SubType.MPLS_LABEL;
297 + }
298 +
299 + @Override
300 + public String toString() {
301 + return toStringHelper(type().toString())
302 + .add("mpls", mplsLabel.intValue()).toString();
303 + }
304 +
305 + @Override
306 + public int hashCode() {
307 + return Objects.hash(mplsLabel);
308 + }
309 +
310 + @Override
311 + public boolean equals(Object obj) {
312 + if (this == obj) {
313 + return true;
314 + }
315 + if (obj instanceof ModMplsLabelInstruction) {
316 + ModMplsLabelInstruction that = (ModMplsLabelInstruction) obj;
317 + return Objects.equals(mplsLabel, that.mplsLabel) &&
318 + Objects.equals(this.type(), that.type());
319 +
320 +
321 + }
322 + return false;
323 + }
324 + }
215 } 325 }
......
...@@ -286,6 +286,10 @@ public class FlowEntryBuilder { ...@@ -286,6 +286,10 @@ public class FlowEntryBuilder {
286 case TCP_SRC: 286 case TCP_SRC:
287 builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort()); 287 builder.matchTcpSrc((short) match.get(MatchField.TCP_SRC).getPort());
288 break; 288 break;
289 + case MPLS_LABEL:
290 + builder.matchMplsLabel((int) match.get(MatchField.MPLS_LABEL)
291 + .getValue());
292 + break;
289 case OCH_SIGID: 293 case OCH_SIGID:
290 builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber()); 294 builder.matchLambda(match.get(MatchField.OCH_SIGID).getChannelNumber());
291 break; 295 break;
...@@ -312,7 +316,6 @@ public class FlowEntryBuilder { ...@@ -312,7 +316,6 @@ public class FlowEntryBuilder {
312 case IP_DSCP: 316 case IP_DSCP:
313 case IP_ECN: 317 case IP_ECN:
314 case METADATA: 318 case METADATA:
315 - case MPLS_LABEL:
316 case MPLS_TC: 319 case MPLS_TC:
317 case SCTP_DST: 320 case SCTP_DST:
318 case SCTP_SRC: 321 case SCTP_SRC:
......
...@@ -47,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked; ...@@ -47,6 +47,7 @@ import org.projectfloodlight.openflow.types.Masked;
47 import org.projectfloodlight.openflow.types.OFPort; 47 import org.projectfloodlight.openflow.types.OFPort;
48 import org.projectfloodlight.openflow.types.OFVlanVidMatch; 48 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
49 import org.projectfloodlight.openflow.types.TransportPort; 49 import org.projectfloodlight.openflow.types.TransportPort;
50 +import org.projectfloodlight.openflow.types.U32;
50 import org.projectfloodlight.openflow.types.U8; 51 import org.projectfloodlight.openflow.types.U8;
51 import org.projectfloodlight.openflow.types.VlanPcp; 52 import org.projectfloodlight.openflow.types.VlanPcp;
52 import org.projectfloodlight.openflow.types.VlanVid; 53 import org.projectfloodlight.openflow.types.VlanVid;
...@@ -195,6 +196,11 @@ public abstract class FlowModBuilder { ...@@ -195,6 +196,11 @@ public abstract class FlowModBuilder {
195 tp = (TcpPortCriterion) c; 196 tp = (TcpPortCriterion) c;
196 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort())); 197 mBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(tp.tcpPort()));
197 break; 198 break;
199 + case MPLS_LABEL:
200 + Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
201 + mBuilder.setExact(MatchField.MPLS_LABEL,
202 + U32.of(mp.label().intValue()));
203 + break;
198 case OCH_SIGID: 204 case OCH_SIGID:
199 LambdaCriterion lc = (LambdaCriterion) c; 205 LambdaCriterion lc = (LambdaCriterion) c;
200 mBuilder.setExact(MatchField.OCH_SIGID, 206 mBuilder.setExact(MatchField.OCH_SIGID,
...@@ -227,7 +233,6 @@ public abstract class FlowModBuilder { ...@@ -227,7 +233,6 @@ public abstract class FlowModBuilder {
227 case IP_ECN: 233 case IP_ECN:
228 case METADATA: 234 case METADATA:
229 case MPLS_BOS: 235 case MPLS_BOS:
230 - case MPLS_LABEL:
231 case MPLS_TC: 236 case MPLS_TC:
232 case PBB_ISID: 237 case PBB_ISID:
233 case SCTP_DST: 238 case SCTP_DST:
......
...@@ -29,6 +29,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction; ...@@ -29,6 +29,8 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
29 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 29 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
30 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction; 30 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
31 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction; 31 import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
32 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModMplsLabelInstruction;
33 +import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
32 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction; 34 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
33 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 35 import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
34 import org.onlab.packet.Ip4Address; 36 import org.onlab.packet.Ip4Address;
...@@ -41,11 +43,13 @@ import org.projectfloodlight.openflow.protocol.action.OFAction; ...@@ -41,11 +43,13 @@ import org.projectfloodlight.openflow.protocol.action.OFAction;
41 import org.projectfloodlight.openflow.protocol.match.Match; 43 import org.projectfloodlight.openflow.protocol.match.Match;
42 import org.projectfloodlight.openflow.protocol.oxm.OFOxm; 44 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
43 import org.projectfloodlight.openflow.types.CircuitSignalID; 45 import org.projectfloodlight.openflow.types.CircuitSignalID;
46 +import org.projectfloodlight.openflow.types.EthType;
44 import org.projectfloodlight.openflow.types.IPv4Address; 47 import org.projectfloodlight.openflow.types.IPv4Address;
45 import org.projectfloodlight.openflow.types.MacAddress; 48 import org.projectfloodlight.openflow.types.MacAddress;
46 import org.projectfloodlight.openflow.types.OFBufferId; 49 import org.projectfloodlight.openflow.types.OFBufferId;
47 import org.projectfloodlight.openflow.types.OFPort; 50 import org.projectfloodlight.openflow.types.OFPort;
48 import org.projectfloodlight.openflow.types.OFVlanVidMatch; 51 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
52 +import org.projectfloodlight.openflow.types.U32;
49 import org.projectfloodlight.openflow.types.U64; 53 import org.projectfloodlight.openflow.types.U64;
50 import org.projectfloodlight.openflow.types.VlanPcp; 54 import org.projectfloodlight.openflow.types.VlanPcp;
51 import org.slf4j.Logger; 55 import org.slf4j.Logger;
...@@ -201,25 +205,42 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -201,25 +205,42 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
201 ModEtherInstruction eth; 205 ModEtherInstruction eth;
202 OFOxm<?> oxm = null; 206 OFOxm<?> oxm = null;
203 switch (l2m.subtype()) { 207 switch (l2m.subtype()) {
204 - case ETH_DST: 208 + case ETH_DST:
205 - eth = (ModEtherInstruction) l2m; 209 + eth = (ModEtherInstruction) l2m;
206 - oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong())); 210 + oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong()));
207 - break; 211 + break;
208 - case ETH_SRC: 212 + case ETH_SRC:
209 - eth = (ModEtherInstruction) l2m; 213 + eth = (ModEtherInstruction) l2m;
210 - oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong())); 214 + oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
211 - break; 215 + break;
212 - case VLAN_ID: 216 + case VLAN_ID:
213 - ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m; 217 + ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
214 - oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort())); 218 + oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
215 - break; 219 + break;
216 - case VLAN_PCP: 220 + case VLAN_PCP:
217 - ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m; 221 + ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
218 - oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp())); 222 + oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
219 - break; 223 + break;
220 - default: 224 + case MPLS_PUSH:
221 - log.warn("Unimplemented action type {}.", l2m.subtype()); 225 + PushHeaderInstructions pushHeaderInstructions =
222 - break; 226 + (PushHeaderInstructions) l2m;
227 + return factory().actions().pushMpls(EthType.of(pushHeaderInstructions
228 + .ethernetType().getEtherType()));
229 + case MPLS_POP:
230 + PushHeaderInstructions popHeaderInstructions =
231 + (PushHeaderInstructions) l2m;
232 + return factory().actions().popMpls(EthType.of(popHeaderInstructions
233 + .ethernetType().getEtherType()));
234 + case MPLS_LABEL:
235 + ModMplsLabelInstruction mplsLabel =
236 + (ModMplsLabelInstruction) l2m;
237 + oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label()
238 + .longValue()));
239 +
240 + break;
241 + default:
242 + log.warn("Unimplemented action type {}.", l2m.subtype());
243 + break;
223 } 244 }
224 245
225 if (oxm != null) { 246 if (oxm != null) {
......
...@@ -37,6 +37,8 @@ public class Ethernet extends BasePacket { ...@@ -37,6 +37,8 @@ public class Ethernet extends BasePacket {
37 public static final short TYPE_LLDP = (short) 0x88cc; 37 public static final short TYPE_LLDP = (short) 0x88cc;
38 public static final short TYPE_BSN = (short) 0x8942; 38 public static final short TYPE_BSN = (short) 0x8942;
39 public static final short VLAN_UNTAGGED = (short) 0xffff; 39 public static final short VLAN_UNTAGGED = (short) 0xffff;
40 + public static final short MPLS_UNICAST = (short) 0x8847;
41 + public static final short MPLS_MULTICAST = (short) 0x8848;
40 public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes 42 public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes
41 public static Map<Short, Class<? extends IPacket>> etherTypeClassMap; 43 public static Map<Short, Class<? extends IPacket>> etherTypeClassMap;
42 44
......