Michele Santuari
Committed by Brian O'Connor

ONOS-631 #Initial MPLS intent implementation

Change-Id: I6f906b953f06f395cc67e612648802e333c0e581
Showing 39 changed files with 1208 additions and 103 deletions
...@@ -40,6 +40,7 @@ import org.onosproject.net.flow.FlowRuleService; ...@@ -40,6 +40,7 @@ import org.onosproject.net.flow.FlowRuleService;
40 import org.onosproject.net.flow.TrafficSelector; 40 import org.onosproject.net.flow.TrafficSelector;
41 import org.onosproject.net.flow.TrafficTreatment; 41 import org.onosproject.net.flow.TrafficTreatment;
42 import org.onlab.packet.Ethernet; 42 import org.onlab.packet.Ethernet;
43 +import org.onlab.packet.MplsLabel;
43 import org.slf4j.Logger; 44 import org.slf4j.Logger;
44 45
45 /** 46 /**
...@@ -98,7 +99,7 @@ public class MPLSForwarding { ...@@ -98,7 +99,7 @@ public class MPLSForwarding {
98 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); 99 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
99 int inport = 1; 100 int inport = 1;
100 int outport = 2; 101 int outport = 2;
101 - Integer mplsLabel = 101; 102 + MplsLabel mplsLabel = MplsLabel.mplsLabel(101);
102 Integer switchNumber = uglyMap.get(device.id()); 103 Integer switchNumber = uglyMap.get(device.id());
103 if (switchNumber == null) { 104 if (switchNumber == null) {
104 return; 105 return;
......
1 +package org.onosproject.cli.net;
2 +
3 +import static org.onosproject.net.DeviceId.deviceId;
4 +import static org.onosproject.net.PortNumber.portNumber;
5 +
6 +import java.util.List;
7 +import java.util.Optional;
8 +
9 +import org.apache.karaf.shell.commands.Argument;
10 +import org.apache.karaf.shell.commands.Command;
11 +import org.apache.karaf.shell.commands.Option;
12 +
13 +import org.onlab.packet.MplsLabel;
14 +import org.onosproject.net.ConnectPoint;
15 +import org.onosproject.net.DeviceId;
16 +import org.onosproject.net.PortNumber;
17 +import org.onosproject.net.flow.TrafficSelector;
18 +import org.onosproject.net.flow.TrafficTreatment;
19 +import org.onosproject.net.intent.Constraint;
20 +import org.onosproject.net.intent.IntentService;
21 +import org.onosproject.net.intent.MplsIntent;
22 +
23 +@Command(scope = "onos", name = "add-mpls-intent", description = "Installs mpls connectivity intent")
24 +public class AddMplsIntent extends ConnectivityIntentCommand {
25 +
26 + @Argument(index = 0, name = "ingressDevice",
27 + description = "Ingress Device/Port Description",
28 + required = true,
29 + multiValued = false)
30 + private String ingressDeviceString = null;
31 +
32 + @Option(name = "--ingressLabel",
33 + description = "Ingress Mpls label",
34 + required = false,
35 + multiValued = false)
36 + private String ingressLabelString = "";
37 +
38 + @Argument(index = 1, name = "egressDevice",
39 + description = "Egress Device/Port Description",
40 + required = true,
41 + multiValued = false)
42 + private String egressDeviceString = null;
43 +
44 + @Option(name = "--egressLabel",
45 + description = "Egress Mpls label",
46 + required = false,
47 + multiValued = false)
48 + private String egressLabelString = "";
49 +
50 + @Override
51 + protected void execute() {
52 + IntentService service = get(IntentService.class);
53 +
54 + DeviceId ingressDeviceId = deviceId(getDeviceId(ingressDeviceString));
55 + PortNumber ingressPortNumber = portNumber(getPortNumber(ingressDeviceString));
56 + ConnectPoint ingress = new ConnectPoint(ingressDeviceId,
57 + ingressPortNumber);
58 + Optional<MplsLabel> ingressLabel = Optional.empty();
59 + if (!ingressLabelString.isEmpty()) {
60 + ingressLabel = Optional
61 + .ofNullable(MplsLabel.mplsLabel(parseInt(ingressLabelString)));
62 + }
63 +
64 + DeviceId egressDeviceId = deviceId(getDeviceId(egressDeviceString));
65 + PortNumber egressPortNumber = portNumber(getPortNumber(egressDeviceString));
66 + ConnectPoint egress = new ConnectPoint(egressDeviceId, egressPortNumber);
67 +
68 + Optional<MplsLabel> egressLabel = Optional.empty();
69 + if (!ingressLabelString.isEmpty()) {
70 + egressLabel = Optional
71 + .ofNullable(MplsLabel.mplsLabel(parseInt(egressLabelString)));
72 + }
73 +
74 + TrafficSelector selector = buildTrafficSelector();
75 + TrafficTreatment treatment = buildTrafficTreatment();
76 +
77 + List<Constraint> constraints = buildConstraints();
78 +
79 + MplsIntent intent = new MplsIntent(appId(), selector, treatment,
80 + ingress, ingressLabel, egress,
81 + egressLabel, constraints);
82 + service.submit(intent);
83 + }
84 +
85 + /**
86 + * Extracts the port number portion of the ConnectPoint.
87 + *
88 + * @param deviceString string representing the device/port
89 + * @return port number as a string, empty string if the port is not found
90 + */
91 + public static String getPortNumber(String deviceString) {
92 + int slash = deviceString.indexOf('/');
93 + if (slash <= 0) {
94 + return "";
95 + }
96 + return deviceString.substring(slash + 1, deviceString.length());
97 + }
98 +
99 + /**
100 + * Extracts the device ID portion of the ConnectPoint.
101 + *
102 + * @param deviceString string representing the device/port
103 + * @return device ID string
104 + */
105 + public static String getDeviceId(String deviceString) {
106 + int slash = deviceString.indexOf('/');
107 + if (slash <= 0) {
108 + return "";
109 + }
110 + return deviceString.substring(0, slash);
111 + }
112 +
113 + protected Integer parseInt(String value) {
114 + try {
115 + return Integer.parseInt(value);
116 + } catch (NumberFormatException nfe) {
117 + return null;
118 + }
119 + }
120 +}
...@@ -297,6 +297,12 @@ ...@@ -297,6 +297,12 @@
297 <command> 297 <command>
298 <action class="org.onosproject.cli.net.WipeOutCommand"/> 298 <action class="org.onosproject.cli.net.WipeOutCommand"/>
299 </command> 299 </command>
300 + <command>
301 + <action class="org.onosproject.cli.net.AddMplsIntent" />
302 + <completers>
303 + <ref component-id="connectPointCompleter" />
304 + </completers>
305 + </command>
300 </command-bundle> 306 </command-bundle>
301 307
302 <bean id="appNameCompleter" class="org.onosproject.cli.app.ApplicationNameCompleter"/> 308 <bean id="appNameCompleter" class="org.onosproject.cli.app.ApplicationNameCompleter"/>
......
...@@ -26,6 +26,7 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -26,6 +26,7 @@ import org.onosproject.net.flow.criteria.Criterion;
26 import org.onlab.packet.IpPrefix; 26 import org.onlab.packet.IpPrefix;
27 import org.onlab.packet.Ip6Address; 27 import org.onlab.packet.Ip6Address;
28 import org.onlab.packet.MacAddress; 28 import org.onlab.packet.MacAddress;
29 +import org.onlab.packet.MplsLabel;
29 import org.onlab.packet.VlanId; 30 import org.onlab.packet.VlanId;
30 31
31 import com.google.common.base.MoreObjects; 32 import com.google.common.base.MoreObjects;
...@@ -275,7 +276,7 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -275,7 +276,7 @@ public final class DefaultTrafficSelector implements TrafficSelector {
275 } 276 }
276 277
277 @Override 278 @Override
278 - public Builder matchMplsLabel(Integer mplsLabel) { 279 + public Builder matchMplsLabel(MplsLabel mplsLabel) {
279 return add(Criteria.matchMplsLabel(mplsLabel)); 280 return add(Criteria.matchMplsLabel(mplsLabel));
280 } 281 }
281 282
......
...@@ -17,8 +17,10 @@ package org.onosproject.net.flow; ...@@ -17,8 +17,10 @@ package org.onosproject.net.flow;
17 17
18 import com.google.common.base.MoreObjects; 18 import com.google.common.base.MoreObjects;
19 import com.google.common.collect.ImmutableList; 19 import com.google.common.collect.ImmutableList;
20 +
20 import org.onlab.packet.IpAddress; 21 import org.onlab.packet.IpAddress;
21 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.MplsLabel;
22 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
23 import org.onosproject.core.GroupId; 25 import org.onosproject.core.GroupId;
24 import org.onosproject.net.PortNumber; 26 import org.onosproject.net.PortNumber;
...@@ -222,12 +224,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -222,12 +224,12 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
222 } 224 }
223 225
224 @Override 226 @Override
225 - public Builder popMpls(short etherType) { 227 + public Builder popMpls(Short etherType) {
226 return add(Instructions.popMpls(etherType)); 228 return add(Instructions.popMpls(etherType));
227 } 229 }
228 230
229 @Override 231 @Override
230 - public Builder setMpls(Integer mplsLabel) { 232 + public Builder setMpls(MplsLabel mplsLabel) {
231 return add(Instructions.modMplsLabel(mplsLabel)); 233 return add(Instructions.modMplsLabel(mplsLabel));
232 } 234 }
233 235
......
...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -22,6 +22,7 @@ import org.onosproject.net.flow.criteria.Criterion;
22 import org.onlab.packet.IpPrefix; 22 import org.onlab.packet.IpPrefix;
23 import org.onlab.packet.Ip6Address; 23 import org.onlab.packet.Ip6Address;
24 import org.onlab.packet.MacAddress; 24 import org.onlab.packet.MacAddress;
25 +import org.onlab.packet.MplsLabel;
25 import org.onlab.packet.VlanId; 26 import org.onlab.packet.VlanId;
26 27
27 /** 28 /**
...@@ -297,7 +298,7 @@ public interface TrafficSelector { ...@@ -297,7 +298,7 @@ public interface TrafficSelector {
297 * @param mplsLabel a MPLS label. 298 * @param mplsLabel a MPLS label.
298 * @return a selection builder 299 * @return a selection builder
299 */ 300 */
300 - public Builder matchMplsLabel(Integer mplsLabel); 301 + public Builder matchMplsLabel(MplsLabel mplsLabel);
301 302
302 /** 303 /**
303 * Matches on IPv6 Extension Header pseudo-field fiags. 304 * Matches on IPv6 Extension Header pseudo-field fiags.
......
...@@ -19,9 +19,11 @@ import java.util.List; ...@@ -19,9 +19,11 @@ import java.util.List;
19 19
20 import org.onosproject.core.GroupId; 20 import org.onosproject.core.GroupId;
21 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
22 +import org.onosproject.net.flow.DefaultTrafficTreatment.Builder;
22 import org.onosproject.net.flow.instructions.Instruction; 23 import org.onosproject.net.flow.instructions.Instruction;
23 import org.onlab.packet.IpAddress; 24 import org.onlab.packet.IpAddress;
24 import org.onlab.packet.MacAddress; 25 import org.onlab.packet.MacAddress;
26 +import org.onlab.packet.MplsLabel;
25 import org.onlab.packet.VlanId; 27 import org.onlab.packet.VlanId;
26 28
27 /** 29 /**
...@@ -155,12 +157,12 @@ public interface TrafficTreatment { ...@@ -155,12 +157,12 @@ public interface TrafficTreatment {
155 public Builder popMpls(); 157 public Builder popMpls();
156 158
157 /** 159 /**
158 - * Pops MPLS ether type. 160 + * Pops MPLS ether type and set the new ethertype.
159 * 161 *
160 - * @param ethType Ethernet type to set 162 + * @param etherType an ether type
161 * @return a treatment builder. 163 * @return a treatment builder.
162 */ 164 */
163 - public Builder popMpls(short ethType); 165 + public Builder popMpls(Short etherType);
164 166
165 /** 167 /**
166 * Sets the mpls label. 168 * Sets the mpls label.
...@@ -168,7 +170,7 @@ public interface TrafficTreatment { ...@@ -168,7 +170,7 @@ public interface TrafficTreatment {
168 * @param mplsLabel MPLS label. 170 * @param mplsLabel MPLS label.
169 * @return a treatment builder. 171 * @return a treatment builder.
170 */ 172 */
171 - public Builder setMpls(Integer mplsLabel); 173 + public Builder setMpls(MplsLabel mplsLabel);
172 174
173 /** 175 /**
174 * Decrement MPLS TTL. 176 * Decrement MPLS TTL.
...@@ -199,6 +201,8 @@ public interface TrafficTreatment { ...@@ -199,6 +201,8 @@ public interface TrafficTreatment {
199 * @return traffic treatment 201 * @return traffic treatment
200 */ 202 */
201 TrafficTreatment build(); 203 TrafficTreatment build();
204 +
205 +
202 } 206 }
203 207
204 } 208 }
......
...@@ -18,11 +18,13 @@ package org.onosproject.net.flow.criteria; ...@@ -18,11 +18,13 @@ package org.onosproject.net.flow.criteria;
18 import static com.google.common.base.MoreObjects.toStringHelper; 18 import static com.google.common.base.MoreObjects.toStringHelper;
19 19
20 import java.util.Objects; 20 import java.util.Objects;
21 +
21 import org.onosproject.net.PortNumber; 22 import org.onosproject.net.PortNumber;
22 import org.onosproject.net.flow.criteria.Criterion.Type; 23 import org.onosproject.net.flow.criteria.Criterion.Type;
23 import org.onlab.packet.IpPrefix; 24 import org.onlab.packet.IpPrefix;
24 import org.onlab.packet.Ip6Address; 25 import org.onlab.packet.Ip6Address;
25 import org.onlab.packet.MacAddress; 26 import org.onlab.packet.MacAddress;
27 +import org.onlab.packet.MplsLabel;
26 import org.onlab.packet.VlanId; 28 import org.onlab.packet.VlanId;
27 29
28 /** 30 /**
...@@ -338,7 +340,7 @@ public final class Criteria { ...@@ -338,7 +340,7 @@ public final class Criteria {
338 * @param mplsLabel MPLS label (20 bits) 340 * @param mplsLabel MPLS label (20 bits)
339 * @return match criterion 341 * @return match criterion
340 */ 342 */
341 - public static Criterion matchMplsLabel(int mplsLabel) { 343 + public static Criterion matchMplsLabel(MplsLabel mplsLabel) {
342 return new MplsCriterion(mplsLabel); 344 return new MplsCriterion(mplsLabel);
343 } 345 }
344 346
...@@ -1510,15 +1512,10 @@ public final class Criteria { ...@@ -1510,15 +1512,10 @@ public final class Criteria {
1510 */ 1512 */
1511 public static final class MplsCriterion implements Criterion { 1513 public static final class MplsCriterion implements Criterion {
1512 private static final int MASK = 0xfffff; 1514 private static final int MASK = 0xfffff;
1513 - private final int mplsLabel; // MPLS label: 20 bits 1515 + private final MplsLabel mplsLabel;
1514 1516
1515 - /** 1517 + public MplsCriterion(MplsLabel mplsLabel) {
1516 - * Constructor. 1518 + this.mplsLabel = mplsLabel;
1517 - *
1518 - * @param mplsLabel the MPLS label to match (20 bits)
1519 - */
1520 - public MplsCriterion(int mplsLabel) {
1521 - this.mplsLabel = mplsLabel & MASK;
1522 } 1519 }
1523 1520
1524 @Override 1521 @Override
...@@ -1526,19 +1523,14 @@ public final class Criteria { ...@@ -1526,19 +1523,14 @@ public final class Criteria {
1526 return Type.MPLS_LABEL; 1523 return Type.MPLS_LABEL;
1527 } 1524 }
1528 1525
1529 - /** 1526 + public MplsLabel label() {
1530 - * Gets the MPLS label to match.
1531 - *
1532 - * @return the MPLS label to match (20 bits)
1533 - */
1534 - public int label() {
1535 return mplsLabel; 1527 return mplsLabel;
1536 } 1528 }
1537 1529
1538 @Override 1530 @Override
1539 public String toString() { 1531 public String toString() {
1540 return toStringHelper(type().toString()) 1532 return toStringHelper(type().toString())
1541 - .add("label", Long.toHexString(mplsLabel)).toString(); 1533 + .add("mpls", mplsLabel).toString();
1542 } 1534 }
1543 1535
1544 @Override 1536 @Override
......
...@@ -35,6 +35,7 @@ import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlIns ...@@ -35,6 +35,7 @@ import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlIns
35 import org.onlab.packet.Ethernet; 35 import org.onlab.packet.Ethernet;
36 import org.onlab.packet.IpAddress; 36 import org.onlab.packet.IpAddress;
37 import org.onlab.packet.MacAddress; 37 import org.onlab.packet.MacAddress;
38 +import org.onlab.packet.MplsLabel;
38 import org.onlab.packet.VlanId; 39 import org.onlab.packet.VlanId;
39 40
40 /** 41 /**
...@@ -132,7 +133,7 @@ public final class Instructions { ...@@ -132,7 +133,7 @@ public final class Instructions {
132 * @param mplsLabel to set. 133 * @param mplsLabel to set.
133 * @return a L2 Modification 134 * @return a L2 Modification
134 */ 135 */
135 - public static L2ModificationInstruction modMplsLabel(Integer mplsLabel) { 136 + public static L2ModificationInstruction modMplsLabel(MplsLabel mplsLabel) {
136 checkNotNull(mplsLabel, "MPLS label cannot be null"); 137 checkNotNull(mplsLabel, "MPLS label cannot be null");
137 return new ModMplsLabelInstruction(mplsLabel); 138 return new ModMplsLabelInstruction(mplsLabel);
138 } 139 }
......
...@@ -20,6 +20,7 @@ import static com.google.common.base.MoreObjects.toStringHelper; ...@@ -20,6 +20,7 @@ import static com.google.common.base.MoreObjects.toStringHelper;
20 import java.util.Objects; 20 import java.util.Objects;
21 21
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.MplsLabel;
23 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
24 25
25 /** 26 /**
...@@ -287,14 +288,14 @@ public abstract class L2ModificationInstruction implements Instruction { ...@@ -287,14 +288,14 @@ public abstract class L2ModificationInstruction implements Instruction {
287 public static final class ModMplsLabelInstruction extends 288 public static final class ModMplsLabelInstruction extends
288 L2ModificationInstruction { 289 L2ModificationInstruction {
289 290
290 - private final Integer mplsLabel; 291 + private final MplsLabel mplsLabel;
291 292
292 - public ModMplsLabelInstruction(Integer mplsLabel) { 293 + public ModMplsLabelInstruction(MplsLabel mplsLabel) {
293 this.mplsLabel = mplsLabel; 294 this.mplsLabel = mplsLabel;
294 } 295 }
295 296
296 public Integer label() { 297 public Integer label() {
297 - return mplsLabel; 298 + return mplsLabel.toInt();
298 } 299 }
299 300
300 @Override 301 @Override
...@@ -304,8 +305,8 @@ public abstract class L2ModificationInstruction implements Instruction { ...@@ -304,8 +305,8 @@ public abstract class L2ModificationInstruction implements Instruction {
304 305
305 @Override 306 @Override
306 public String toString() { 307 public String toString() {
307 - return toStringHelper(subtype().toString()) 308 + return toStringHelper(type().toString())
308 - .add("mpls", mplsLabel.intValue()).toString(); 309 + .add("mpls", mplsLabel).toString();
309 } 310 }
310 311
311 @Override 312 @Override
......
1 +package org.onosproject.net.intent;
2 +
3 +import static com.google.common.base.Preconditions.checkArgument;
4 +import static com.google.common.base.Preconditions.checkNotNull;
5 +
6 +import java.util.Collections;
7 +import java.util.List;
8 +import java.util.Optional;
9 +
10 +import org.onlab.packet.MplsLabel;
11 +import org.onosproject.core.ApplicationId;
12 +import org.onosproject.net.ConnectPoint;
13 +import org.onosproject.net.Link;
14 +import org.onosproject.net.flow.TrafficSelector;
15 +import org.onosproject.net.flow.TrafficTreatment;
16 +import org.onosproject.net.intent.constraint.LinkTypeConstraint;
17 +
18 +import com.google.common.base.MoreObjects;
19 +import com.google.common.collect.ImmutableList;
20 +
21 +
22 +/**
23 + * Abstraction of MPLS label-switched connectivity.
24 + */
25 +public class MplsIntent extends ConnectivityIntent {
26 +
27 + private final ConnectPoint ingressPoint;
28 + private final Optional<MplsLabel> ingressLabel;
29 + private final ConnectPoint egressPoint;
30 + private final Optional<MplsLabel> egressLabel;
31 +
32 + /**
33 + * Creates a new MPLS intent with the supplied ingress/egress
34 + * ports and labels and with built-in link type constraint to avoid optical links.
35 + *
36 + * @param appId application identifier
37 + * @param selector traffic selector
38 + * @param treatment treatment
39 + * @param ingressPoint ingress port
40 + * @param ingressLabel ingress MPLS label
41 + * @param egressPoint egress port
42 + * @param egressLabel egress MPLS label
43 + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
44 + */
45 + public MplsIntent(ApplicationId appId, TrafficSelector selector,
46 + TrafficTreatment treatment,
47 + ConnectPoint ingressPoint,
48 + Optional<MplsLabel> ingressLabel,
49 + ConnectPoint egressPoint,
50 + Optional<MplsLabel> egressLabel) {
51 + this(appId, selector, treatment, ingressPoint, ingressLabel, egressPoint, egressLabel,
52 + ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)));
53 + }
54 +
55 + /**
56 + * Creates a new point-to-point intent with the supplied ingress/egress
57 + * ports, labels and constraints.
58 + *
59 + * @param appId application identifier
60 + * @param selector traffic selector
61 + * @param treatment treatment
62 + * @param ingressPoint ingress port
63 + * @param ingressLabel ingress MPLS label
64 + * @param egressPoint egress port
65 + * @param egressLabel egress MPLS label
66 + * @param constraints optional list of constraints
67 + * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
68 + */
69 + public MplsIntent(ApplicationId appId, TrafficSelector selector,
70 + TrafficTreatment treatment,
71 + ConnectPoint ingressPoint,
72 + Optional<MplsLabel> ingressLabel,
73 + ConnectPoint egressPoint,
74 + Optional<MplsLabel> egressLabel,
75 + List<Constraint> constraints) {
76 +
77 + super(appId, Collections.emptyList(), selector, treatment, constraints);
78 +
79 + checkNotNull(ingressPoint);
80 + checkNotNull(egressPoint);
81 + checkArgument(!ingressPoint.equals(egressPoint),
82 + "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
83 + checkNotNull(ingressLabel);
84 + checkNotNull(egressLabel);
85 + this.ingressPoint = ingressPoint;
86 + this.ingressLabel = ingressLabel;
87 + this.egressPoint = egressPoint;
88 + this.egressLabel = egressLabel;
89 +
90 + }
91 +
92 + /**
93 + * Constructor for serializer.
94 + */
95 + protected MplsIntent() {
96 + super();
97 + this.ingressPoint = null;
98 + this.ingressLabel = null;
99 + this.egressPoint = null;
100 + this.egressLabel = null;
101 +
102 + }
103 +
104 + /**
105 + * Returns the port on which the ingress traffic should be connected to
106 + * the egress.
107 + *
108 + * @return ingress switch port
109 + */
110 + public ConnectPoint ingressPoint() {
111 + return ingressPoint;
112 + }
113 +
114 + /**
115 + * Returns the port on which the traffic should egress.
116 + *
117 + * @return egress switch port
118 + */
119 + public ConnectPoint egressPoint() {
120 + return egressPoint;
121 + }
122 +
123 +
124 + /**
125 + * Returns the MPLS label which the ingress traffic should tagged.
126 + *
127 + * @return ingress MPLS label
128 + */
129 + public Optional<MplsLabel> ingressLabel() {
130 + return ingressLabel;
131 + }
132 +
133 + /**
134 + * Returns the MPLS label which the egress traffic should tagged.
135 + *
136 + * @return egress MPLS label
137 + */
138 + public Optional<MplsLabel> egressLabel() {
139 + return egressLabel;
140 + }
141 +
142 + @Override
143 + public String toString() {
144 + return MoreObjects.toStringHelper(getClass())
145 + .add("id", id())
146 + .add("appId", appId())
147 + .add("selector", selector())
148 + .add("treatment", treatment())
149 + .add("ingressPoint", ingressPoint)
150 + .add("ingressLabel", ingressLabel)
151 + .add("egressPoint", egressPoint)
152 + .add("egressLabel", egressLabel)
153 + .add("constraints", constraints())
154 + .toString();
155 + }
156 +
157 +
158 +
159 +}
1 +package org.onosproject.net.intent;
2 +
3 +import static com.google.common.base.Preconditions.checkNotNull;
4 +
5 +import java.util.Collections;
6 +import java.util.List;
7 +import java.util.Optional;
8 +
9 +
10 +import org.onlab.packet.MplsLabel;
11 +import org.onosproject.core.ApplicationId;
12 +import org.onosproject.net.Path;
13 +import org.onosproject.net.flow.TrafficSelector;
14 +import org.onosproject.net.flow.TrafficTreatment;
15 +
16 +
17 +/**
18 + * Abstraction of explicit MPLS label-switched path.
19 + */
20 +
21 +public class MplsPathIntent extends PathIntent {
22 +
23 + private Optional<MplsLabel> ingressLabel;
24 + private Optional<MplsLabel> egressLabel;
25 +
26 + /**
27 + * Creates a new point-to-point intent with the supplied ingress/egress
28 + * ports and using the specified explicit path.
29 + *
30 + * @param appId application identifier
31 + * @param selector traffic selector
32 + * @param treatment treatment
33 + * @param path traversed links
34 + * @param ingressLabel MPLS egress label
35 + * @param egressLabel MPLS ingress label
36 + * @throws NullPointerException {@code path} is null
37 + */
38 + public MplsPathIntent(ApplicationId appId, TrafficSelector selector,
39 + TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel,
40 + Optional<MplsLabel> egressLabel) {
41 + this(appId, selector, treatment, path, ingressLabel, egressLabel,
42 + Collections.emptyList());
43 +
44 + }
45 +
46 + /**
47 + * Creates a new point-to-point intent with the supplied ingress/egress
48 + * ports and using the specified explicit path.
49 + *
50 + * @param appId application identifier
51 + * @param selector traffic selector
52 + * @param treatment treatment
53 + * @param path traversed links
54 + * @param ingressLabel MPLS egress label
55 + * @param egressLabel MPLS ingress label
56 + * @param constraints optional list of constraints
57 + * @throws NullPointerException {@code path} is null
58 + */
59 + public MplsPathIntent(ApplicationId appId, TrafficSelector selector,
60 + TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel,
61 + Optional<MplsLabel> egressLabel, List<Constraint> constraints) {
62 + super(appId, selector, treatment, path, constraints);
63 +
64 + checkNotNull(ingressLabel);
65 + checkNotNull(egressLabel);
66 + this.ingressLabel = ingressLabel;
67 + this.egressLabel = egressLabel;
68 + }
69 +
70 + /**
71 + * Returns the MPLS label which the ingress traffic should tagged.
72 + *
73 + * @return ingress MPLS label
74 + */
75 + public Optional<MplsLabel> ingressLabel() {
76 + return ingressLabel;
77 + }
78 +
79 + /**
80 + * Returns the MPLS label which the egress traffic should tagged.
81 + *
82 + * @return egress MPLS label
83 + */
84 + public Optional<MplsLabel> egressLabel() {
85 + return egressLabel;
86 + }
87 +
88 +}
...@@ -117,6 +117,17 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest { ...@@ -117,6 +117,17 @@ public final class DefaultLinkResourceRequest implements LinkResourceRequest {
117 } 117 }
118 118
119 /** 119 /**
120 + * Adds Mpls request.
121 + *
122 + * @return self
123 + */
124 + @Override
125 + public Builder addMplsRequest() {
126 + resources.add(new MplsLabelResourceRequest());
127 + return this;
128 + }
129 +
130 + /**
120 * Adds bandwidth request with bandwidth value. 131 * Adds bandwidth request with bandwidth value.
121 * 132 *
122 * @param bandwidth bandwidth value to be requested 133 * @param bandwidth bandwidth value to be requested
......
...@@ -60,6 +60,13 @@ public interface LinkResourceRequest extends ResourceRequest { ...@@ -60,6 +60,13 @@ public interface LinkResourceRequest extends ResourceRequest {
60 public Builder addLambdaRequest(); 60 public Builder addLambdaRequest();
61 61
62 /** 62 /**
63 + * Adds MPLS request.
64 + *
65 + * @return self
66 + */
67 + public Builder addMplsRequest();
68 +
69 + /**
63 * Adds bandwidth request with bandwidth value. 70 * Adds bandwidth request with bandwidth value.
64 * 71 *
65 * @param bandwidth bandwidth value to be requested 72 * @param bandwidth bandwidth value to be requested
......
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 +
17 +package org.onosproject.net.resource;
18 +
19 +import java.util.Objects;
20 +
21 +/**
22 + * Representation of MPLS label resource.
23 + */
24 +public final class MplsLabel extends LinkResource {
25 +
26 + private final org.onlab.packet.MplsLabel mplsLabel;
27 +
28 +
29 + /**
30 + * Creates a new instance with given MPLS label.
31 + *
32 + * @param mplsLabel MPLS Label value to be assigned
33 + */
34 + public MplsLabel(int mplsLabel) {
35 + this.mplsLabel = org.onlab.packet.MplsLabel.mplsLabel(mplsLabel);
36 + }
37 +
38 + /**
39 + * Creates a new instance with given MPLS label.
40 + *
41 + * @param mplsLabel mplsLabel value to be assigned
42 + * @return {@link MplsLabel} instance with given bandwidth
43 + */
44 + public static MplsLabel valueOf(int mplsLabel) {
45 + return new MplsLabel(mplsLabel);
46 + }
47 +
48 + /**
49 + * Returns MPLS Label as an MPLS Label Object.
50 + *
51 + * @return MPLS label as an MPLS Label Object.
52 + */
53 + public org.onlab.packet.MplsLabel label() {
54 + return mplsLabel;
55 + }
56 +
57 + @Override
58 + public boolean equals(Object obj) {
59 + if (obj instanceof MplsLabel) {
60 + MplsLabel that = (MplsLabel) obj;
61 + return Objects.equals(this.mplsLabel, that.mplsLabel);
62 + }
63 + return false;
64 + }
65 +
66 + @Override
67 + public int hashCode() {
68 + return Objects.hashCode(this.mplsLabel);
69 + }
70 +
71 + @Override
72 + public String toString() {
73 + return String.valueOf(this.mplsLabel);
74 + }
75 +}
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 +
17 +package org.onosproject.net.resource;
18 +
19 +import com.google.common.base.MoreObjects;
20 +
21 +import java.util.Objects;
22 +
23 +/**
24 + * Representation of allocated MPLS label resource.
25 + */
26 +public class MplsLabelResourceAllocation extends MplsLabelResourceRequest
27 + implements ResourceAllocation {
28 + private final MplsLabel mplsLabel;
29 +
30 + @Override
31 + public ResourceType type() {
32 + return ResourceType.MPLS_LABEL;
33 + }
34 +
35 + /**
36 + * Creates a new {@link MplsLabelResourceAllocation} with {@link MplsLabel}
37 + * object.
38 + *
39 + * @param mplsLabel allocated MPLS Label
40 + */
41 + public MplsLabelResourceAllocation(MplsLabel mplsLabel) {
42 + this.mplsLabel = mplsLabel;
43 + }
44 +
45 + /**
46 + * Returns the MPLS label resource.
47 + *
48 + * @return the MPLS label resource
49 + */
50 + public MplsLabel mplsLabel() {
51 + return mplsLabel;
52 + }
53 +
54 + @Override
55 + public int hashCode() {
56 + return Objects.hash(mplsLabel);
57 + }
58 +
59 + @Override
60 + public boolean equals(Object obj) {
61 + if (this == obj) {
62 + return true;
63 + }
64 + if (obj == null || getClass() != obj.getClass()) {
65 + return false;
66 + }
67 + final MplsLabelResourceAllocation other = (MplsLabelResourceAllocation) obj;
68 + return Objects.equals(this.mplsLabel, other.mplsLabel);
69 + }
70 +
71 + @Override
72 + public String toString() {
73 + return MoreObjects.toStringHelper(this)
74 + .add("mplsLabel", mplsLabel)
75 + .toString();
76 + }
77 +}
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.onosproject.net.resource;
17 +
18 +import com.google.common.base.MoreObjects;
19 +
20 +/**
21 + * Representation of a request for lambda resource.
22 + */
23 +public class MplsLabelResourceRequest implements ResourceRequest {
24 +
25 + @Override
26 + public ResourceType type() {
27 + return ResourceType.MPLS_LABEL;
28 + }
29 +
30 + @Override
31 + public String toString() {
32 + return MoreObjects.toStringHelper(this)
33 + .toString();
34 + }
35 +}
...@@ -28,4 +28,9 @@ public enum ResourceType { ...@@ -28,4 +28,9 @@ public enum ResourceType {
28 * Bandwidth resource type. 28 * Bandwidth resource type.
29 */ 29 */
30 BANDWIDTH, 30 BANDWIDTH,
31 +
32 + /**
33 + * MPLS label resource type.
34 + */
35 + MPLS_LABEL,
31 } 36 }
......
...@@ -28,6 +28,7 @@ import org.onosproject.net.flow.criteria.Criterion; ...@@ -28,6 +28,7 @@ import org.onosproject.net.flow.criteria.Criterion;
28 import org.onlab.packet.Ip6Address; 28 import org.onlab.packet.Ip6Address;
29 import org.onlab.packet.IpPrefix; 29 import org.onlab.packet.IpPrefix;
30 import org.onlab.packet.MacAddress; 30 import org.onlab.packet.MacAddress;
31 +import org.onlab.packet.MplsLabel;
31 import org.onlab.packet.VlanId; 32 import org.onlab.packet.VlanId;
32 33
33 import com.google.common.testing.EqualsTester; 34 import com.google.common.testing.EqualsTester;
...@@ -251,7 +252,7 @@ public class DefaultTrafficSelectorTest { ...@@ -251,7 +252,7 @@ public class DefaultTrafficSelectorTest {
251 assertThat(selector, hasCriterionWithType(Type.IPV6_ND_TLL)); 252 assertThat(selector, hasCriterionWithType(Type.IPV6_ND_TLL));
252 253
253 selector = DefaultTrafficSelector.builder() 254 selector = DefaultTrafficSelector.builder()
254 - .matchMplsLabel(3).build(); 255 + .matchMplsLabel(MplsLabel.mplsLabel(3)).build();
255 assertThat(selector, hasCriterionWithType(Type.MPLS_LABEL)); 256 assertThat(selector, hasCriterionWithType(Type.MPLS_LABEL));
256 257
257 selector = DefaultTrafficSelector.builder() 258 selector = DefaultTrafficSelector.builder()
......
...@@ -20,6 +20,7 @@ import org.onosproject.net.PortNumber; ...@@ -20,6 +20,7 @@ import org.onosproject.net.PortNumber;
20 import org.onlab.packet.IpPrefix; 20 import org.onlab.packet.IpPrefix;
21 import org.onlab.packet.Ip6Address; 21 import org.onlab.packet.Ip6Address;
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.MplsLabel;
23 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
24 25
25 import com.google.common.testing.EqualsTester; 26 import com.google.common.testing.EqualsTester;
...@@ -186,8 +187,8 @@ public class CriteriaTest { ...@@ -186,8 +187,8 @@ public class CriteriaTest {
186 Criterion matchTargetLlAddr2 = 187 Criterion matchTargetLlAddr2 =
187 Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2); 188 Criteria.matchIPv6NDTargetLinkLayerAddress(llMac2);
188 189
189 - int mpls1 = 1; 190 + MplsLabel mpls1 = MplsLabel.mplsLabel(1);
190 - int mpls2 = 2; 191 + MplsLabel mpls2 = MplsLabel.mplsLabel(2);
191 Criterion matchMpls1 = Criteria.matchMplsLabel(mpls1); 192 Criterion matchMpls1 = Criteria.matchMplsLabel(mpls1);
192 Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1); 193 Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1);
193 Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2); 194 Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2);
......
...@@ -19,6 +19,7 @@ import org.junit.Test; ...@@ -19,6 +19,7 @@ import org.junit.Test;
19 import org.onosproject.net.PortNumber; 19 import org.onosproject.net.PortNumber;
20 import org.onlab.packet.IpAddress; 20 import org.onlab.packet.IpAddress;
21 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
22 +import org.onlab.packet.MplsLabel;
22 import org.onlab.packet.VlanId; 23 import org.onlab.packet.VlanId;
23 24
24 import com.google.common.testing.EqualsTester; 25 import com.google.common.testing.EqualsTester;
...@@ -527,16 +528,16 @@ public class InstructionsTest { ...@@ -527,16 +528,16 @@ public class InstructionsTest {
527 is(not(equalTo(modIPv6FlowLabelInstruction2.hashCode())))); 528 is(not(equalTo(modIPv6FlowLabelInstruction2.hashCode()))));
528 } 529 }
529 530
530 - private Instruction modMplsLabelInstruction1 = Instructions.modMplsLabel(1); 531 + private Instruction modMplsLabelInstruction1 = Instructions.modMplsLabel(MplsLabel.mplsLabel(1));
531 - private Instruction sameAsModMplsLabelInstruction1 = Instructions.modMplsLabel(1); 532 + private Instruction sameAsModMplsLabelInstruction1 = Instructions.modMplsLabel(MplsLabel.mplsLabel(1));
532 - private Instruction modMplsLabelInstruction2 = Instructions.modMplsLabel(2); 533 + private Instruction modMplsLabelInstruction2 = Instructions.modMplsLabel(MplsLabel.mplsLabel(2));
533 534
534 /** 535 /**
535 * Test the modMplsLabel method. 536 * Test the modMplsLabel method.
536 */ 537 */
537 @Test 538 @Test
538 public void testModMplsMethod() { 539 public void testModMplsMethod() {
539 - final Instruction instruction = Instructions.modMplsLabel(33); 540 + final Instruction instruction = Instructions.modMplsLabel(MplsLabel.mplsLabel(33));
540 final L2ModificationInstruction.ModMplsLabelInstruction modMplsLabelInstruction = 541 final L2ModificationInstruction.ModMplsLabelInstruction modMplsLabelInstruction =
541 checkAndConvert(instruction, 542 checkAndConvert(instruction,
542 Instruction.Type.L2MODIFICATION, 543 Instruction.Type.L2MODIFICATION,
......
1 +package org.onosproject.net.intent.impl;
2 +
3 +import static java.util.Arrays.asList;
4 +import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
5 +
6 +import java.util.ArrayList;
7 +import java.util.List;
8 +import java.util.Set;
9 +
10 +
11 +import org.apache.felix.scr.annotations.Activate;
12 +import org.apache.felix.scr.annotations.Component;
13 +import org.apache.felix.scr.annotations.Deactivate;
14 +import org.onosproject.net.ConnectPoint;
15 +import org.onosproject.net.DefaultPath;
16 +import org.onosproject.net.Link;
17 +import org.onosproject.net.Path;
18 +import org.onosproject.net.intent.Intent;
19 +import org.onosproject.net.intent.MplsIntent;
20 +import org.onosproject.net.intent.MplsPathIntent;
21 +import org.onosproject.net.provider.ProviderId;
22 +import org.onosproject.net.resource.LinkResourceAllocations;
23 +
24 +
25 +@Component(immediate = true)
26 +public class MplsIntentCompiler extends ConnectivityIntentCompiler<MplsIntent> {
27 +
28 + // TODO: use off-the-shell core provider ID
29 + private static final ProviderId PID =
30 + new ProviderId("core", "org.onosproject.core", true);
31 + // TODO: consider whether the default cost is appropriate or not
32 + public static final int DEFAULT_COST = 1;
33 +
34 +
35 + @Activate
36 + public void activate() {
37 + intentManager.registerCompiler(MplsIntent.class, this);
38 + }
39 +
40 + @Deactivate
41 + public void deactivate() {
42 + intentManager.unregisterCompiler(MplsIntent.class);
43 + }
44 +
45 + @Override
46 + public List<Intent> compile(MplsIntent intent, List<Intent> installable,
47 + Set<LinkResourceAllocations> resources) {
48 + ConnectPoint ingressPoint = intent.ingressPoint();
49 + ConnectPoint egressPoint = intent.egressPoint();
50 +
51 + if (ingressPoint.deviceId().equals(egressPoint.deviceId())) {
52 + List<Link> links = asList(createEdgeLink(ingressPoint, true), createEdgeLink(egressPoint, false));
53 + return asList(createPathIntent(new DefaultPath(PID, links, DEFAULT_COST), intent));
54 + }
55 +
56 + List<Link> links = new ArrayList<>();
57 + Path path = getPath(intent, ingressPoint.deviceId(),
58 + egressPoint.deviceId());
59 +
60 + links.add(createEdgeLink(ingressPoint, true));
61 + links.addAll(path.links());
62 +
63 + links.add(createEdgeLink(egressPoint, false));
64 +
65 + return asList(createPathIntent(new DefaultPath(PID, links, path.cost(),
66 + path.annotations()), intent));
67 + }
68 +
69 + /**
70 + * Creates a path intent from the specified path and original
71 + * connectivity intent.
72 + *
73 + * @param path path to create an intent for
74 + * @param intent original intent
75 + */
76 + private Intent createPathIntent(Path path,
77 + MplsIntent intent) {
78 + return new MplsPathIntent(intent.appId(),
79 + intent.selector(), intent.treatment(), path,
80 + intent.ingressLabel(), intent.egressLabel(),
81 + intent.constraints());
82 + }
83 +
84 +
85 +}
...@@ -49,6 +49,9 @@ import org.onosproject.net.resource.LinkResourceRequest; ...@@ -49,6 +49,9 @@ import org.onosproject.net.resource.LinkResourceRequest;
49 import org.onosproject.net.resource.LinkResourceService; 49 import org.onosproject.net.resource.LinkResourceService;
50 import org.onosproject.net.resource.LinkResourceStore; 50 import org.onosproject.net.resource.LinkResourceStore;
51 import org.onosproject.net.resource.LinkResourceStoreDelegate; 51 import org.onosproject.net.resource.LinkResourceStoreDelegate;
52 +import org.onosproject.net.resource.MplsLabel;
53 +import org.onosproject.net.resource.MplsLabelResourceAllocation;
54 +import org.onosproject.net.resource.MplsLabelResourceRequest;
52 import org.onosproject.net.resource.ResourceAllocation; 55 import org.onosproject.net.resource.ResourceAllocation;
53 import org.onosproject.net.resource.ResourceRequest; 56 import org.onosproject.net.resource.ResourceRequest;
54 import org.onosproject.net.resource.ResourceType; 57 import org.onosproject.net.resource.ResourceType;
...@@ -104,6 +107,7 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -104,6 +107,7 @@ public class LinkResourceManager implements LinkResourceService {
104 return lambdas; 107 return lambdas;
105 } 108 }
106 109
110 +
107 /** 111 /**
108 * Returns available lambdas on specified links. 112 * Returns available lambdas on specified links.
109 * 113 *
...@@ -121,13 +125,36 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -121,13 +125,36 @@ public class LinkResourceManager implements LinkResourceService {
121 return lambdas; 125 return lambdas;
122 } 126 }
123 127
128 +
129 + /**
130 + * Returns available MPLS label on specified link.
131 + *
132 + * @param link the link
133 + * @return available MPLS labels on specified link
134 + */
135 + private Iterable<MplsLabel> getAvailableMplsLabels(Link link) {
136 + Set<ResourceAllocation> resAllocs = store.getFreeResources(link);
137 + if (resAllocs == null) {
138 + return Collections.emptySet();
139 + }
140 + Set<MplsLabel> mplsLabels = new HashSet<>();
141 + for (ResourceAllocation res : resAllocs) {
142 + if (res.type() == ResourceType.MPLS_LABEL) {
143 +
144 + mplsLabels.add(((MplsLabelResourceAllocation) res).mplsLabel());
145 + }
146 + }
147 +
148 + return mplsLabels;
149 + }
150 +
124 @Override 151 @Override
125 public LinkResourceAllocations requestResources(LinkResourceRequest req) { 152 public LinkResourceAllocations requestResources(LinkResourceRequest req) {
126 // TODO Concatenate multiple bandwidth requests. 153 // TODO Concatenate multiple bandwidth requests.
127 // TODO Support multiple lambda resource requests. 154 // TODO Support multiple lambda resource requests.
128 // TODO Throw appropriate exception. 155 // TODO Throw appropriate exception.
129 -
130 Set<ResourceAllocation> allocs = new HashSet<>(); 156 Set<ResourceAllocation> allocs = new HashSet<>();
157 + Map<Link, Set<ResourceAllocation>> allocsPerLink = new HashMap<>();
131 for (ResourceRequest r : req.resources()) { 158 for (ResourceRequest r : req.resources()) {
132 switch (r.type()) { 159 switch (r.type()) {
133 case BANDWIDTH: 160 case BANDWIDTH:
...@@ -144,6 +171,24 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -144,6 +171,24 @@ public class LinkResourceManager implements LinkResourceService {
144 return null; 171 return null;
145 } 172 }
146 break; 173 break;
174 + case MPLS_LABEL:
175 + for (Link link : req.links()) {
176 + if (allocsPerLink.get(link) == null) {
177 + allocsPerLink.put(link,
178 + new HashSet<ResourceAllocation>());
179 + }
180 + Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link)
181 + .iterator();
182 + if (mplsIter.hasNext()) {
183 + allocsPerLink.get(link)
184 + .add(new MplsLabelResourceAllocation(mplsIter
185 + .next()));
186 + } else {
187 + log.info("Failed to allocate MPLS resource.");
188 + break;
189 + }
190 + }
191 + break;
147 default: 192 default:
148 break; 193 break;
149 } 194 }
...@@ -151,7 +196,8 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -151,7 +196,8 @@ public class LinkResourceManager implements LinkResourceService {
151 196
152 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>(); 197 Map<Link, Set<ResourceAllocation>> allocations = new HashMap<>();
153 for (Link link : req.links()) { 198 for (Link link : req.links()) {
154 - allocations.put(link, allocs); 199 + allocations.put(link, new HashSet<ResourceAllocation>(allocs));
200 + allocations.get(link).addAll(allocsPerLink.get(link));
155 } 201 }
156 LinkResourceAllocations result = 202 LinkResourceAllocations result =
157 new DefaultLinkResourceAllocations(req, allocations); 203 new DefaultLinkResourceAllocations(req, allocations);
...@@ -203,6 +249,8 @@ public class LinkResourceManager implements LinkResourceService { ...@@ -203,6 +249,8 @@ public class LinkResourceManager implements LinkResourceService {
203 case LAMBDA: 249 case LAMBDA:
204 result.add(new LambdaResourceRequest()); 250 result.add(new LambdaResourceRequest());
205 break; 251 break;
252 + case MPLS_LABEL:
253 + result.add(new MplsLabelResourceRequest());
206 default: 254 default:
207 break; 255 break;
208 } 256 }
......
...@@ -24,6 +24,7 @@ import org.junit.After; ...@@ -24,6 +24,7 @@ import org.junit.After;
24 import org.junit.Before; 24 import org.junit.Before;
25 import org.junit.Test; 25 import org.junit.Test;
26 import org.onlab.packet.MacAddress; 26 import org.onlab.packet.MacAddress;
27 +import org.onlab.packet.MplsLabel;
27 import org.onosproject.core.ApplicationId; 28 import org.onosproject.core.ApplicationId;
28 import org.onosproject.core.DefaultApplicationId; 29 import org.onosproject.core.DefaultApplicationId;
29 import org.onosproject.core.DefaultGroupId; 30 import org.onosproject.core.DefaultGroupId;
...@@ -162,7 +163,7 @@ public class GroupManagerTest { ...@@ -162,7 +163,7 @@ public class GroupManagerTest {
162 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 163 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
163 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 164 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
164 .pushMpls() 165 .pushMpls()
165 - .setMpls(106); 166 + .setMpls(MplsLabel.mplsLabel(106));
166 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 167 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
167 tBuilder.build())); 168 tBuilder.build()));
168 } 169 }
...@@ -244,7 +245,7 @@ public class GroupManagerTest { ...@@ -244,7 +245,7 @@ public class GroupManagerTest {
244 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 245 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
245 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 246 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
246 .pushMpls() 247 .pushMpls()
247 - .setMpls(106); 248 + .setMpls(MplsLabel.mplsLabel(106));
248 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket( 249 addBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
249 tBuilder.build())); 250 tBuilder.build()));
250 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 251 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
...@@ -280,7 +281,7 @@ public class GroupManagerTest { ...@@ -280,7 +281,7 @@ public class GroupManagerTest {
280 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 281 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
281 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 282 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
282 .pushMpls() 283 .pushMpls()
283 - .setMpls(106); 284 + .setMpls(MplsLabel.mplsLabel(106));
284 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket( 285 removeBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
285 tBuilder.build())); 286 tBuilder.build()));
286 buckets.remove(DefaultGroupBucket.createSelectGroupBucket( 287 buckets.remove(DefaultGroupBucket.createSelectGroupBucket(
...@@ -338,7 +339,7 @@ public class GroupManagerTest { ...@@ -338,7 +339,7 @@ public class GroupManagerTest {
338 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 339 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
339 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 340 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
340 .pushMpls() 341 .pushMpls()
341 - .setMpls(106); 342 + .setMpls(MplsLabel.mplsLabel(106));
342 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 343 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
343 tBuilder.build())); 344 tBuilder.build()));
344 } 345 }
...@@ -411,7 +412,7 @@ public class GroupManagerTest { ...@@ -411,7 +412,7 @@ public class GroupManagerTest {
411 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 412 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
412 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 413 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
413 .pushMpls() 414 .pushMpls()
414 - .setMpls(106); 415 + .setMpls(MplsLabel.mplsLabel(106));
415 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 416 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
416 tBuilder.build())); 417 tBuilder.build()));
417 } 418 }
......
1 +package org.onosproject.net.intent.impl;
2 +
3 +import java.util.List;
4 +import java.util.Optional;
5 +
6 +import org.hamcrest.Matchers;
7 +import org.junit.Test;
8 +
9 +import static org.junit.Assert.assertEquals;
10 +
11 +
12 +import org.onlab.packet.MplsLabel;
13 +import org.onosproject.TestApplicationId;
14 +import org.onosproject.core.ApplicationId;
15 +import org.onosproject.net.ConnectPoint;
16 +import org.onosproject.net.Link;
17 +import org.onosproject.net.Path;
18 +import org.onosproject.net.flow.TrafficSelector;
19 +import org.onosproject.net.flow.TrafficTreatment;
20 +import org.onosproject.net.intent.AbstractIntentTest;
21 +import org.onosproject.net.intent.Intent;
22 +import org.onosproject.net.intent.IntentTestsMocks;
23 +import org.onosproject.net.intent.MplsIntent;
24 +import org.onosproject.net.intent.MplsPathIntent;
25 +
26 +import static org.hamcrest.CoreMatchers.instanceOf;
27 +import static org.hamcrest.CoreMatchers.notNullValue;
28 +import static org.hamcrest.MatcherAssert.assertThat;
29 +import static org.hamcrest.Matchers.hasSize;
30 +import static org.hamcrest.Matchers.is;
31 +import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
32 +import static org.onosproject.net.DeviceId.deviceId;
33 +import static org.onosproject.net.NetTestTools.APP_ID;
34 +import static org.onosproject.net.NetTestTools.connectPoint;
35 +import static org.onosproject.net.PortNumber.portNumber;
36 +import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
37 +
38 +/**
39 + * Unit tests for the HostToHost intent compiler.
40 + */
41 +public class MplsIntentCompilerTest extends AbstractIntentTest {
42 +
43 + private static final ApplicationId APPID = new TestApplicationId("foo");
44 +
45 + private TrafficSelector selector = new IntentTestsMocks.MockSelector();
46 + private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
47 +
48 + /**
49 + * Creates a PointToPoint intent based on ingress and egress device Ids.
50 + *
51 + * @param ingressIdString string for id of ingress device
52 + * @param egressIdString string for id of egress device
53 + * @return PointToPointIntent for the two devices
54 + */
55 + private MplsIntent makeIntent(String ingressIdString, Optional<MplsLabel> ingressLabel,
56 + String egressIdString, Optional<MplsLabel> egressLabel) {
57 +
58 + return new MplsIntent(APPID, selector, treatment,
59 + connectPoint(ingressIdString, 1),
60 + ingressLabel,
61 + connectPoint(egressIdString, 1),
62 + egressLabel);
63 + }
64 + /**
65 + * Creates a compiler for HostToHost intents.
66 + *
67 + * @param hops string array describing the path hops to use when compiling
68 + * @return HostToHost intent compiler
69 + */
70 + private MplsIntentCompiler makeCompiler(String[] hops) {
71 + MplsIntentCompiler compiler =
72 + new MplsIntentCompiler();
73 + compiler.pathService = new IntentTestsMocks.MockPathService(hops);
74 + return compiler;
75 + }
76 +
77 +
78 + /**
79 + * Tests a pair of devices in an 8 hop path, forward direction.
80 + */
81 + @Test
82 + public void testForwardPathCompilation() {
83 + Optional<MplsLabel> ingressLabel = Optional.ofNullable(MplsLabel.mplsLabel(10));
84 + Optional<MplsLabel> egressLabel = Optional.ofNullable(MplsLabel.mplsLabel(20));
85 +
86 + MplsIntent intent = makeIntent("d1", ingressLabel, "d8", egressLabel);
87 + assertThat(intent, is(notNullValue()));
88 +
89 + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
90 + MplsIntentCompiler compiler = makeCompiler(hops);
91 + assertThat(compiler, is(notNullValue()));
92 +
93 + List<Intent> result = compiler.compile(intent, null, null);
94 + assertThat(result, is(Matchers.notNullValue()));
95 + assertThat(result, hasSize(1));
96 + Intent forwardResultIntent = result.get(0);
97 + assertThat(forwardResultIntent instanceof MplsPathIntent, is(true));
98 +
99 + if (forwardResultIntent instanceof MplsIntent) {
100 + MplsPathIntent forwardPathIntent = (MplsPathIntent) forwardResultIntent;
101 + // 7 links for the hops, plus one default lnk on ingress and egress
102 + assertThat(forwardPathIntent.path().links(), hasSize(hops.length + 1));
103 + assertThat(forwardPathIntent.path().links(), linksHasPath("d1", "d2"));
104 + assertThat(forwardPathIntent.path().links(), linksHasPath("d2", "d3"));
105 + assertThat(forwardPathIntent.path().links(), linksHasPath("d3", "d4"));
106 + assertThat(forwardPathIntent.path().links(), linksHasPath("d4", "d5"));
107 + assertThat(forwardPathIntent.path().links(), linksHasPath("d5", "d6"));
108 + assertThat(forwardPathIntent.path().links(), linksHasPath("d6", "d7"));
109 + assertThat(forwardPathIntent.path().links(), linksHasPath("d7", "d8"));
110 + assertEquals(forwardPathIntent.egressLabel(), egressLabel);
111 + assertEquals(forwardPathIntent.ingressLabel(), ingressLabel);
112 + }
113 + }
114 +
115 + /**
116 + * Tests a pair of devices in an 8 hop path, forward direction.
117 + */
118 + @Test
119 + public void testReversePathCompilation() {
120 + Optional<MplsLabel> ingressLabel = Optional.ofNullable(MplsLabel.mplsLabel(10));
121 + Optional<MplsLabel> egressLabel = Optional.ofNullable(MplsLabel.mplsLabel(20));
122 +
123 + MplsIntent intent = makeIntent("d8", ingressLabel, "d1", egressLabel);
124 + assertThat(intent, is(notNullValue()));
125 +
126 + String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
127 + MplsIntentCompiler compiler = makeCompiler(hops);
128 + assertThat(compiler, is(notNullValue()));
129 +
130 + List<Intent> result = compiler.compile(intent, null, null);
131 + assertThat(result, is(Matchers.notNullValue()));
132 + assertThat(result, hasSize(1));
133 + Intent reverseResultIntent = result.get(0);
134 + assertThat(reverseResultIntent instanceof MplsPathIntent, is(true));
135 +
136 + if (reverseResultIntent instanceof MplsIntent) {
137 + MplsPathIntent reversePathIntent = (MplsPathIntent) reverseResultIntent;
138 + assertThat(reversePathIntent.path().links(), hasSize(hops.length + 1));
139 + assertThat(reversePathIntent.path().links(), linksHasPath("d2", "d1"));
140 + assertThat(reversePathIntent.path().links(), linksHasPath("d3", "d2"));
141 + assertThat(reversePathIntent.path().links(), linksHasPath("d4", "d3"));
142 + assertThat(reversePathIntent.path().links(), linksHasPath("d5", "d4"));
143 + assertThat(reversePathIntent.path().links(), linksHasPath("d6", "d5"));
144 + assertThat(reversePathIntent.path().links(), linksHasPath("d7", "d6"));
145 + assertThat(reversePathIntent.path().links(), linksHasPath("d8", "d7"));
146 + assertEquals(reversePathIntent.egressLabel(), egressLabel);
147 + assertEquals(reversePathIntent.ingressLabel(), ingressLabel);
148 + }
149 + }
150 +
151 + /**
152 + * Tests compilation of the intent which designates two different ports on the same switch.
153 + */
154 + @Test
155 + public void testSameSwitchDifferentPortsIntentCompilation() {
156 + ConnectPoint src = new ConnectPoint(deviceId("1"), portNumber(1));
157 + ConnectPoint dst = new ConnectPoint(deviceId("1"), portNumber(2));
158 + MplsIntent intent = new MplsIntent(APP_ID, selector, treatment, src, Optional.empty(), dst, Optional.empty());
159 +
160 + String[] hops = {"1"};
161 + MplsIntentCompiler sut = makeCompiler(hops);
162 +
163 + List<Intent> compiled = sut.compile(intent, null, null);
164 +
165 + assertThat(compiled, hasSize(1));
166 + assertThat(compiled.get(0), is(instanceOf(MplsPathIntent.class)));
167 + Path path = ((MplsPathIntent) compiled.get(0)).path();
168 +
169 + assertThat(path.links(), hasSize(2));
170 + Link firstLink = path.links().get(0);
171 + assertThat(firstLink, is(createEdgeLink(src, true)));
172 + Link secondLink = path.links().get(1);
173 + assertThat(secondLink, is(createEdgeLink(dst, false)));
174 + }
175 +}
...@@ -42,6 +42,8 @@ import org.onosproject.net.resource.LambdaResourceAllocation; ...@@ -42,6 +42,8 @@ import org.onosproject.net.resource.LambdaResourceAllocation;
42 import org.onosproject.net.resource.LinkResourceAllocations; 42 import org.onosproject.net.resource.LinkResourceAllocations;
43 import org.onosproject.net.resource.LinkResourceEvent; 43 import org.onosproject.net.resource.LinkResourceEvent;
44 import org.onosproject.net.resource.LinkResourceStore; 44 import org.onosproject.net.resource.LinkResourceStore;
45 +import org.onosproject.net.resource.MplsLabel;
46 +import org.onosproject.net.resource.MplsLabelResourceAllocation;
45 import org.onosproject.net.resource.ResourceAllocation; 47 import org.onosproject.net.resource.ResourceAllocation;
46 import org.onosproject.net.resource.ResourceAllocationException; 48 import org.onosproject.net.resource.ResourceAllocationException;
47 import org.onosproject.net.resource.ResourceType; 49 import org.onosproject.net.resource.ResourceType;
...@@ -105,9 +107,10 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -105,9 +107,10 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
105 // Link annotation key name to use as max lambda 107 // Link annotation key name to use as max lambda
106 private String wavesAnnotation = AnnotationKeys.OPTICAL_WAVES; 108 private String wavesAnnotation = AnnotationKeys.OPTICAL_WAVES;
107 109
110 + // Max MPLS labels: 2^20 – 1
111 + private int maxMplsLabel = 0xFFFFF;
108 private StoreSerializer serializer; 112 private StoreSerializer serializer;
109 113
110 -
111 void createTable(String tableName) { 114 void createTable(String tableName) {
112 boolean tableReady = false; 115 boolean tableReady = false;
113 do { 116 do {
...@@ -150,6 +153,9 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -150,6 +153,9 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
150 if (type == ResourceType.LAMBDA) { 153 if (type == ResourceType.LAMBDA) {
151 return getLambdaResourceCapacity(link); 154 return getLambdaResourceCapacity(link);
152 } 155 }
156 + if (type == ResourceType.MPLS_LABEL) {
157 + return getMplsResourceCapacity();
158 + }
153 return null; 159 return null;
154 } 160 }
155 161
...@@ -189,6 +195,17 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -189,6 +195,17 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
189 return new BandwidthResourceAllocation(bandwidth); 195 return new BandwidthResourceAllocation(bandwidth);
190 } 196 }
191 197
198 + private Set<MplsLabelResourceAllocation> getMplsResourceCapacity() {
199 + Set<MplsLabelResourceAllocation> allocations = new HashSet<>();
200 + //Ignoring reserved labels of 0 through 15
201 + for (int i = 16; i <= maxMplsLabel; i++) {
202 + allocations.add(new MplsLabelResourceAllocation(MplsLabel
203 + .valueOf(i)));
204 +
205 + }
206 + return allocations;
207 + }
208 +
192 private Map<ResourceType, Set<? extends ResourceAllocation>> getResourceCapacity(Link link) { 209 private Map<ResourceType, Set<? extends ResourceAllocation>> getResourceCapacity(Link link) {
193 Map<ResourceType, Set<? extends ResourceAllocation>> caps = new HashMap<>(); 210 Map<ResourceType, Set<? extends ResourceAllocation>> caps = new HashMap<>();
194 for (ResourceType type : ResourceType.values()) { 211 for (ResourceType type : ResourceType.values()) {
...@@ -273,6 +290,34 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -273,6 +290,34 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
273 free.put(type, freeL); 290 free.put(type, freeL);
274 break; 291 break;
275 } 292 }
293 + case MPLS_LABEL:
294 + {
295 + Set<? extends ResourceAllocation> mpls = caps.get(type);
296 + if (mpls == null || mpls.isEmpty()) {
297 + // nothing left
298 + break;
299 + }
300 + Set<MplsLabelResourceAllocation> freeLabel = new HashSet<>();
301 + for (ResourceAllocation r : mpls) {
302 + if (r instanceof MplsLabelResourceAllocation) {
303 + freeLabel.add((MplsLabelResourceAllocation) r);
304 + }
305 + }
306 +
307 + // enumerate current allocations, removing resources
308 + for (LinkResourceAllocations alloc : allocations) {
309 + Set<ResourceAllocation> types = alloc
310 + .getResourceAllocation(link);
311 + for (ResourceAllocation a : types) {
312 + if (a instanceof MplsLabelResourceAllocation) {
313 + freeLabel.remove(a);
314 + }
315 + }
316 + }
317 +
318 + free.put(type, freeLabel);
319 + break;
320 + }
276 321
277 default: 322 default:
278 break; 323 break;
...@@ -298,7 +343,6 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -298,7 +343,6 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
298 encodeIntentAllocations(alloc)); 343 encodeIntentAllocations(alloc));
299 } 344 }
300 345
301 -
302 @Override 346 @Override
303 public void allocateResources(LinkResourceAllocations allocations) { 347 public void allocateResources(LinkResourceAllocations allocations) {
304 checkNotNull(allocations); 348 checkNotNull(allocations);
...@@ -313,8 +357,9 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -313,8 +357,9 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
313 } 357 }
314 358
315 BatchWriteRequest batch = tx.build(); 359 BatchWriteRequest batch = tx.build();
316 -// log.info("Intent: {}", databaseService.getAll(INTENT_ALLOCATIONS)); 360 +// log.info("Intent: {}", databaseService.getAll(INTENT_ALLOCATIONS));
317 -// log.info("Link: {}", databaseService.getAll(LINK_RESOURCE_ALLOCATIONS)); 361 +// log.info("Link: {}",
362 + // databaseService.getAll(LINK_RESOURCE_ALLOCATIONS));
318 363
319 BatchWriteResult result = databaseService.batchWrite(batch); 364 BatchWriteResult result = databaseService.batchWrite(batch);
320 if (!result.isSuccessful()) { 365 if (!result.isSuccessful()) {
...@@ -407,6 +452,21 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -407,6 +452,21 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
407 link, 452 link,
408 lambdaAllocation.lambda().toInt())); 453 lambdaAllocation.lambda().toInt()));
409 } 454 }
455 + } else if (req instanceof MplsLabelResourceAllocation) {
456 +
457 + final MplsLabelResourceAllocation mplsAllocation = (MplsLabelResourceAllocation) req;
458 + // check if allocation should be accepted
459 + if (!avail.contains(req)) {
460 + // requested mpls label was not available
461 + throw new ResourceAllocationException(
462 + PositionalParameterStringFormatter
463 + .format("Unable to allocate MPLS label for "
464 + + "link {} MPLS label is {}",
465 + link,
466 + mplsAllocation
467 + .mplsLabel()
468 + .toString()));
469 + }
410 } 470 }
411 } 471 }
412 // all requests allocatable => add allocation 472 // all requests allocatable => add allocation
...@@ -466,8 +526,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -466,8 +526,7 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
466 526
467 // Issue events to force recompilation of intents. 527 // Issue events to force recompilation of intents.
468 528
469 - final List<LinkResourceAllocations> releasedResources = 529 + final List<LinkResourceAllocations> releasedResources = ImmutableList.of(allocations);
470 - ImmutableList.of(allocations);
471 return new LinkResourceEvent( 530 return new LinkResourceEvent(
472 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE, 531 LinkResourceEvent.Type.ADDITIONAL_RESOURCES_AVAILABLE,
473 releasedResources); 532 releasedResources);
...@@ -485,32 +544,32 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -485,32 +544,32 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
485 } 544 }
486 545
487 private String toLinkDbKey(LinkKey linkid) { 546 private String toLinkDbKey(LinkKey linkid) {
488 - // introduce cache if necessary 547 +// introduce cache if necessary
489 return linkid.toString(); 548 return linkid.toString();
490 - // Note: Above is irreversible, if we need reverse conversion 549 +// Note: Above is irreversible, if we need reverse conversion
491 - // we may need something like below, due to String only limitation 550 +// we may need something like below, due to String only limitation
492 -// byte[] bytes = serializer.encode(linkid); 551 +// byte[] bytes = serializer.encode(linkid);
493 -// StringBuilder builder = new StringBuilder(bytes.length * 4); 552 +// StringBuilder builder = new StringBuilder(bytes.length * 4);
494 -// boolean isFirst = true; 553 +// boolean isFirst = true;
495 -// for (byte b : bytes) { 554 +// for (byte b : bytes) {
496 -// if (!isFirst) { 555 +// if (!isFirst) {
497 -// builder.append(','); 556 +// builder.append(',');
498 -// } 557 +// }
499 -// builder.append(b); 558 +// builder.append(b);
500 -// isFirst = false; 559 +// isFirst = false;
501 -// } 560 +// }
502 -// return builder.toString(); 561 +// return builder.toString();
503 } 562 }
504 563
505 -// private LinkKey toLinkKey(String linkKey) { 564 +// private LinkKey toLinkKey(String linkKey) {
506 -// String[] bytes = linkKey.split(","); 565 +// String[] bytes = linkKey.split(",");
507 -// ByteBuffer buf = ByteBuffer.allocate(bytes.length); 566 +// ByteBuffer buf = ByteBuffer.allocate(bytes.length);
508 -// for (String bs : bytes) { 567 +// for (String bs : bytes) {
509 -// buf.put(Byte.parseByte(bs)); 568 +// buf.put(Byte.parseByte(bs));
510 -// } 569 +// }
511 -// buf.flip(); 570 +// buf.flip();
512 -// return serializer.decode(buf); 571 +// return serializer.decode(buf);
513 -// } 572 +// }
514 573
515 private String toIntentDbKey(IntentId intentid) { 574 private String toIntentDbKey(IntentId intentid) {
516 return intentid.toString(); 575 return intentid.toString();
...@@ -565,16 +624,16 @@ public class DistributedLinkResourceStore implements LinkResourceStore { ...@@ -565,16 +624,16 @@ public class DistributedLinkResourceStore implements LinkResourceStore {
565 Map<String, VersionedValue> all = databaseService.getAll(INTENT_ALLOCATIONS); 624 Map<String, VersionedValue> all = databaseService.getAll(INTENT_ALLOCATIONS);
566 625
567 return FluentIterable.from(all.values()) 626 return FluentIterable.from(all.values())
568 - .transform(new Function<VersionedValue, LinkResourceAllocations>() { 627 + .transform(new Function<VersionedValue, LinkResourceAllocations>() {
569 - 628 +
570 - @Override 629 + @Override
571 - public LinkResourceAllocations apply(VersionedValue input) { 630 + public LinkResourceAllocations apply(VersionedValue input) {
572 - if (input == null || input.value() == null) { 631 + if (input == null || input.value() == null) {
573 - return null; 632 + return null;
574 - } 633 + }
575 - return decodeIntentAllocations(input.value()); 634 + return decodeIntentAllocations(input.value());
576 - } 635 + }
577 - }) 636 + })
578 - .filter(notNull()); 637 + .filter(notNull());
579 } 638 }
580 } 639 }
......
...@@ -43,6 +43,8 @@ import org.onosproject.net.resource.LambdaResourceAllocation; ...@@ -43,6 +43,8 @@ import org.onosproject.net.resource.LambdaResourceAllocation;
43 import org.onosproject.net.resource.LinkResourceAllocations; 43 import org.onosproject.net.resource.LinkResourceAllocations;
44 import org.onosproject.net.resource.LinkResourceEvent; 44 import org.onosproject.net.resource.LinkResourceEvent;
45 import org.onosproject.net.resource.LinkResourceStore; 45 import org.onosproject.net.resource.LinkResourceStore;
46 +import org.onosproject.net.resource.MplsLabel;
47 +import org.onosproject.net.resource.MplsLabelResourceAllocation;
46 import org.onosproject.net.resource.ResourceAllocation; 48 import org.onosproject.net.resource.ResourceAllocation;
47 import org.onosproject.net.resource.ResourceAllocationException; 49 import org.onosproject.net.resource.ResourceAllocationException;
48 import org.onosproject.net.resource.ResourceType; 50 import org.onosproject.net.resource.ResourceType;
...@@ -103,6 +105,9 @@ public class HazelcastLinkResourceStore ...@@ -103,6 +105,9 @@ public class HazelcastLinkResourceStore
103 // Link annotation key name to use as max lambda 105 // Link annotation key name to use as max lambda
104 private String wavesAnnotation = AnnotationKeys.OPTICAL_WAVES; 106 private String wavesAnnotation = AnnotationKeys.OPTICAL_WAVES;
105 107
108 + // Max MPLS labels: 2^20 – 1
109 + private int maxMplsLabel = 0xFFFFF;
110 +
106 @Override 111 @Override
107 @Activate 112 @Activate
108 public void activate() { 113 public void activate() {
...@@ -141,6 +146,9 @@ public class HazelcastLinkResourceStore ...@@ -141,6 +146,9 @@ public class HazelcastLinkResourceStore
141 if (type == ResourceType.LAMBDA) { 146 if (type == ResourceType.LAMBDA) {
142 return getLambdaResourceCapacity(link); 147 return getLambdaResourceCapacity(link);
143 } 148 }
149 + if (type == ResourceType.MPLS_LABEL) {
150 + return getMplsResourceCapacity();
151 + }
144 return null; 152 return null;
145 } 153 }
146 154
...@@ -180,6 +188,17 @@ public class HazelcastLinkResourceStore ...@@ -180,6 +188,17 @@ public class HazelcastLinkResourceStore
180 return new BandwidthResourceAllocation(bandwidth); 188 return new BandwidthResourceAllocation(bandwidth);
181 } 189 }
182 190
191 + private Set<MplsLabelResourceAllocation> getMplsResourceCapacity() {
192 + Set<MplsLabelResourceAllocation> allocations = new HashSet<>();
193 + //Ignoring reserved labels of 0 through 15
194 + for (int i = 16; i <= maxMplsLabel; i++) {
195 + allocations.add(new MplsLabelResourceAllocation(MplsLabel
196 + .valueOf(i)));
197 +
198 + }
199 + return allocations;
200 + }
201 +
183 private Map<ResourceType, Set<? extends ResourceAllocation>> getResourceCapacity(Link link) { 202 private Map<ResourceType, Set<? extends ResourceAllocation>> getResourceCapacity(Link link) {
184 Map<ResourceType, Set<? extends ResourceAllocation>> caps = new HashMap<>(); 203 Map<ResourceType, Set<? extends ResourceAllocation>> caps = new HashMap<>();
185 for (ResourceType type : ResourceType.values()) { 204 for (ResourceType type : ResourceType.values()) {
...@@ -275,6 +294,33 @@ public class HazelcastLinkResourceStore ...@@ -275,6 +294,33 @@ public class HazelcastLinkResourceStore
275 break; 294 break;
276 } 295 }
277 296
297 + case MPLS_LABEL:
298 + Set<? extends ResourceAllocation> mpls = caps.get(type);
299 + if (mpls == null || mpls.isEmpty()) {
300 + // nothing left
301 + break;
302 + }
303 + Set<MplsLabelResourceAllocation> freeLabel = new HashSet<>();
304 + for (ResourceAllocation r : mpls) {
305 + if (r instanceof MplsLabelResourceAllocation) {
306 + freeLabel.add((MplsLabelResourceAllocation) r);
307 + }
308 + }
309 +
310 + // enumerate current allocations, removing resources
311 + for (LinkResourceAllocations alloc : allocations) {
312 + Set<ResourceAllocation> types = alloc
313 + .getResourceAllocation(link);
314 + for (ResourceAllocation a : types) {
315 + if (a instanceof MplsLabelResourceAllocation) {
316 + freeLabel.remove(a);
317 + }
318 + }
319 + }
320 +
321 + free.put(type, freeLabel);
322 + break;
323 +
278 default: 324 default:
279 break; 325 break;
280 } 326 }
...@@ -354,6 +400,18 @@ public class HazelcastLinkResourceStore ...@@ -354,6 +400,18 @@ public class HazelcastLinkResourceStore
354 link, 400 link,
355 lambdaAllocation.lambda().toInt())); 401 lambdaAllocation.lambda().toInt()));
356 } 402 }
403 + } else if (req instanceof MplsLabelResourceAllocation) {
404 + MplsLabelResourceAllocation mplsAllocation = (MplsLabelResourceAllocation) req;
405 + if (!avail.contains(req)) {
406 + throw new ResourceAllocationException(
407 + PositionalParameterStringFormatter
408 + .format("Unable to allocate MPLS label for link "
409 + + "{} MPLS label is {}",
410 + link,
411 + mplsAllocation
412 + .mplsLabel()
413 + .toString()));
414 + }
357 } 415 }
358 } 416 }
359 // all requests allocatable => add allocation 417 // all requests allocatable => add allocation
......
...@@ -87,6 +87,8 @@ import org.onosproject.net.intent.IntentOperation; ...@@ -87,6 +87,8 @@ import org.onosproject.net.intent.IntentOperation;
87 import org.onosproject.net.intent.IntentState; 87 import org.onosproject.net.intent.IntentState;
88 import org.onosproject.net.intent.Key; 88 import org.onosproject.net.intent.Key;
89 import org.onosproject.net.intent.LinkCollectionIntent; 89 import org.onosproject.net.intent.LinkCollectionIntent;
90 +import org.onosproject.net.intent.MplsIntent;
91 +import org.onosproject.net.intent.MplsPathIntent;
90 import org.onosproject.net.intent.MultiPointToSinglePointIntent; 92 import org.onosproject.net.intent.MultiPointToSinglePointIntent;
91 import org.onosproject.net.intent.OpticalConnectivityIntent; 93 import org.onosproject.net.intent.OpticalConnectivityIntent;
92 import org.onosproject.net.intent.OpticalPathIntent; 94 import org.onosproject.net.intent.OpticalPathIntent;
...@@ -113,6 +115,9 @@ import org.onosproject.net.resource.Lambda; ...@@ -113,6 +115,9 @@ import org.onosproject.net.resource.Lambda;
113 import org.onosproject.net.resource.LambdaResourceAllocation; 115 import org.onosproject.net.resource.LambdaResourceAllocation;
114 import org.onosproject.net.resource.LambdaResourceRequest; 116 import org.onosproject.net.resource.LambdaResourceRequest;
115 import org.onosproject.net.resource.LinkResourceRequest; 117 import org.onosproject.net.resource.LinkResourceRequest;
118 +import org.onosproject.net.resource.MplsLabel;
119 +import org.onosproject.net.resource.MplsLabelResourceAllocation;
120 +import org.onosproject.net.resource.MplsLabelResourceRequest;
116 import org.onosproject.store.Timestamp; 121 import org.onosproject.store.Timestamp;
117 import org.onosproject.store.service.BatchReadRequest; 122 import org.onosproject.store.service.BatchReadRequest;
118 import org.onosproject.store.service.BatchWriteRequest; 123 import org.onosproject.store.service.BatchWriteRequest;
...@@ -345,6 +350,14 @@ public final class KryoNamespaces { ...@@ -345,6 +350,14 @@ public final class KryoNamespaces {
345 .register(WriteStatus.class) 350 .register(WriteStatus.class)
346 .register(VersionedValue.class) 351 .register(VersionedValue.class)
347 .register(DefaultGroupId.class) 352 .register(DefaultGroupId.class)
353 + .register(
354 + MplsIntent.class,
355 + MplsPathIntent.class,
356 + MplsLabelResourceAllocation.class,
357 + MplsLabelResourceRequest.class,
358 + MplsLabel.class,
359 + org.onlab.packet.MplsLabel.class
360 + )
348 361
349 .build(); 362 .build();
350 363
......
...@@ -25,6 +25,7 @@ import org.junit.After; ...@@ -25,6 +25,7 @@ import org.junit.After;
25 import org.junit.Before; 25 import org.junit.Before;
26 import org.junit.Test; 26 import org.junit.Test;
27 import org.onlab.packet.MacAddress; 27 import org.onlab.packet.MacAddress;
28 +import org.onlab.packet.MplsLabel;
28 import org.onosproject.core.ApplicationId; 29 import org.onosproject.core.ApplicationId;
29 import org.onosproject.core.DefaultApplicationId; 30 import org.onosproject.core.DefaultApplicationId;
30 import org.onosproject.core.GroupId; 31 import org.onosproject.core.GroupId;
...@@ -184,7 +185,7 @@ public class SimpleGroupStoreTest { ...@@ -184,7 +185,7 @@ public class SimpleGroupStoreTest {
184 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 185 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
185 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 186 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
186 .pushMpls() 187 .pushMpls()
187 - .setMpls(106); 188 + .setMpls(MplsLabel.mplsLabel(106));
188 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 189 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
189 tBuilder.build())); 190 tBuilder.build()));
190 } 191 }
...@@ -244,7 +245,7 @@ public class SimpleGroupStoreTest { ...@@ -244,7 +245,7 @@ public class SimpleGroupStoreTest {
244 .setEthDst(MacAddress.valueOf("00:00:00:00:00:03")) 245 .setEthDst(MacAddress.valueOf("00:00:00:00:00:03"))
245 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 246 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
246 .pushMpls() 247 .pushMpls()
247 - .setMpls(106); 248 + .setMpls(MplsLabel.mplsLabel(106));
248 toAddBuckets.add(DefaultGroupBucket.createSelectGroupBucket( 249 toAddBuckets.add(DefaultGroupBucket.createSelectGroupBucket(
249 tBuilder.build())); 250 tBuilder.build()));
250 } 251 }
...@@ -347,7 +348,7 @@ public class SimpleGroupStoreTest { ...@@ -347,7 +348,7 @@ public class SimpleGroupStoreTest {
347 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02")) 348 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
348 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01")) 349 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
349 .pushMpls() 350 .pushMpls()
350 - .setMpls(106); 351 + .setMpls(MplsLabel.mplsLabel(106));
351 buckets.add(DefaultGroupBucket.createSelectGroupBucket( 352 buckets.add(DefaultGroupBucket.createSelectGroupBucket(
352 tBuilder.build())); 353 tBuilder.build()));
353 } 354 }
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
16 package org.onosproject.provider.of.flow.impl; 16 package org.onosproject.provider.of.flow.impl;
17 17
18 import com.google.common.collect.Lists; 18 import com.google.common.collect.Lists;
19 +
19 import org.onlab.packet.Ip4Address; 20 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.Ip4Prefix; 21 import org.onlab.packet.Ip4Prefix;
21 import org.onlab.packet.Ip6Address; 22 import org.onlab.packet.Ip6Address;
22 import org.onlab.packet.Ip6Prefix; 23 import org.onlab.packet.Ip6Prefix;
23 import org.onlab.packet.MacAddress; 24 import org.onlab.packet.MacAddress;
25 +import org.onlab.packet.MplsLabel;
24 import org.onlab.packet.VlanId; 26 import org.onlab.packet.VlanId;
25 import org.onosproject.core.DefaultGroupId; 27 import org.onosproject.core.DefaultGroupId;
26 import org.onosproject.net.DeviceId; 28 import org.onosproject.net.DeviceId;
...@@ -309,7 +311,7 @@ public class FlowEntryBuilder { ...@@ -309,7 +311,7 @@ public class FlowEntryBuilder {
309 case MPLS_LABEL: 311 case MPLS_LABEL:
310 @SuppressWarnings("unchecked") 312 @SuppressWarnings("unchecked")
311 OFOxm<U32> labelId = (OFOxm<U32>) oxm; 313 OFOxm<U32> labelId = (OFOxm<U32>) oxm;
312 - builder.setMpls((int) labelId.getValue().getValue()); 314 + builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
313 break; 315 break;
314 case ARP_OP: 316 case ARP_OP:
315 case ARP_SHA: 317 case ARP_SHA:
...@@ -471,6 +473,9 @@ public class FlowEntryBuilder { ...@@ -471,6 +473,9 @@ public class FlowEntryBuilder {
471 break; 473 break;
472 case UDP_DST: 474 case UDP_DST:
473 builder.matchUdpDst((short) match.get(MatchField.UDP_DST).getPort()); 475 builder.matchUdpDst((short) match.get(MatchField.UDP_DST).getPort());
476 + case MPLS_LABEL:
477 + builder.matchMplsLabel(MplsLabel.mplsLabel((int) match.get(MatchField.MPLS_LABEL)
478 + .getValue()));
474 break; 479 break;
475 case SCTP_SRC: 480 case SCTP_SRC:
476 builder.matchSctpSrc((short) match.get(MatchField.SCTP_SRC).getPort()); 481 builder.matchSctpSrc((short) match.get(MatchField.SCTP_SRC).getPort());
...@@ -538,10 +543,6 @@ public class FlowEntryBuilder { ...@@ -538,10 +543,6 @@ public class FlowEntryBuilder {
538 mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_TLL).getLong()); 543 mac = MacAddress.valueOf(match.get(MatchField.IPV6_ND_TLL).getLong());
539 builder.matchIPv6NDTargetLinkLayerAddress(mac); 544 builder.matchIPv6NDTargetLinkLayerAddress(mac);
540 break; 545 break;
541 - case MPLS_LABEL:
542 - builder.matchMplsLabel((int) match.get(MatchField.MPLS_LABEL)
543 - .getValue());
544 - break;
545 case IPV6_EXTHDR: 546 case IPV6_EXTHDR:
546 builder.matchIPv6ExthdrFlags((int) match.get(MatchField.IPV6_EXTHDR) 547 builder.matchIPv6ExthdrFlags((int) match.get(MatchField.IPV6_EXTHDR)
547 .getValue()); 548 .getValue());
......
...@@ -362,7 +362,7 @@ public abstract class FlowModBuilder { ...@@ -362,7 +362,7 @@ public abstract class FlowModBuilder {
362 break; 362 break;
363 case MPLS_LABEL: 363 case MPLS_LABEL:
364 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c; 364 Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
365 - mBuilder.setExact(MatchField.MPLS_LABEL, U32.of(mp.label())); 365 + mBuilder.setExact(MatchField.MPLS_LABEL, U32.of(mp.label().toInt()));
366 break; 366 break;
367 case IPV6_EXTHDR: 367 case IPV6_EXTHDR:
368 Criteria.IPv6ExthdrFlagsCriterion exthdrFlagsCriterion = 368 Criteria.IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
......
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
16 package org.onosproject.provider.of.group.impl; 16 package org.onosproject.provider.of.group.impl;
17 17
18 import com.google.common.collect.Lists; 18 import com.google.common.collect.Lists;
19 +
19 import org.onlab.packet.Ip4Address; 20 import org.onlab.packet.Ip4Address;
20 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
22 +import org.onlab.packet.MplsLabel;
21 import org.onlab.packet.VlanId; 23 import org.onlab.packet.VlanId;
22 import org.onosproject.core.DefaultGroupId; 24 import org.onosproject.core.DefaultGroupId;
23 import org.onosproject.core.GroupId; 25 import org.onosproject.core.GroupId;
...@@ -263,7 +265,7 @@ public class GroupBucketEntryBuilder { ...@@ -263,7 +265,7 @@ public class GroupBucketEntryBuilder {
263 case MPLS_LABEL: 265 case MPLS_LABEL:
264 @SuppressWarnings("unchecked") 266 @SuppressWarnings("unchecked")
265 OFOxm<U32> labelId = (OFOxm<U32>) oxm; 267 OFOxm<U32> labelId = (OFOxm<U32>) oxm;
266 - builder.setMpls((int) labelId.getValue().getValue()); 268 + builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
267 break; 269 break;
268 case ARP_OP: 270 case ARP_OP:
269 case ARP_SHA: 271 case ARP_SHA:
......
1 +package org.onlab.packet;
2 +
3 +/*
4 + * Copyright 2014 Open Networking Laboratory
5 + *
6 + * Licensed under the Apache License, Version 2.0 (the "License");
7 + * you may not use this file except in compliance with the License.
8 + * You may obtain a copy of the License at
9 + *
10 + * http://www.apache.org/licenses/LICENSE-2.0
11 + *
12 + * Unless required by applicable law or agreed to in writing, software
13 + * distributed under the License is distributed on an "AS IS" BASIS,
14 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 + * See the License for the specific language governing permissions and
16 + * limitations under the License.
17 + */
18 +
19 +/**
20 + * Representation of a MPLS label.
21 + */
22 +public class MplsLabel {
23 +
24 + private final int mplsLabel;
25 +
26 + // An MPLS Label maximum 20 bits.
27 + public static final int MAX_MPLS = 0xFFFFF;
28 +
29 + protected MplsLabel(int value) {
30 + this.mplsLabel = value;
31 + }
32 +
33 + public static MplsLabel mplsLabel(int value) {
34 +
35 + if (value > MAX_MPLS) {
36 + throw new IllegalArgumentException("value exceeds allowed maximum MPLS label value (0xFFFFF)");
37 + }
38 + return new MplsLabel(value);
39 + }
40 +
41 + public int toInt() {
42 + return this.mplsLabel;
43 + }
44 +
45 + @Override
46 + public boolean equals(Object obj) {
47 + if (this == obj) {
48 + return true;
49 + }
50 +
51 + if (obj instanceof MplsLabel) {
52 +
53 + MplsLabel other = (MplsLabel) obj;
54 +
55 + if (this.mplsLabel == other.mplsLabel) {
56 + return true;
57 + }
58 + }
59 +
60 + return false;
61 + }
62 +
63 + @Override
64 + public int hashCode() {
65 + return this.mplsLabel;
66 + }
67 +
68 + @Override
69 + public String toString() {
70 + return String.valueOf(this.mplsLabel);
71 + }
72 +}
...@@ -285,7 +285,7 @@ public final class CriterionCodec extends JsonCodec<Criterion> { ...@@ -285,7 +285,7 @@ public final class CriterionCodec extends JsonCodec<Criterion> {
285 public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) { 285 public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
286 final Criteria.MplsCriterion mplsCriterion = 286 final Criteria.MplsCriterion mplsCriterion =
287 (Criteria.MplsCriterion) criterion; 287 (Criteria.MplsCriterion) criterion;
288 - return root.put("label", mplsCriterion.label()); 288 + return root.put("label", mplsCriterion.label().toInt());
289 } 289 }
290 } 290 }
291 291
......
...@@ -22,6 +22,7 @@ import org.junit.Test; ...@@ -22,6 +22,7 @@ import org.junit.Test;
22 import org.onlab.packet.Ip6Address; 22 import org.onlab.packet.Ip6Address;
23 import org.onlab.packet.IpPrefix; 23 import org.onlab.packet.IpPrefix;
24 import org.onlab.packet.MacAddress; 24 import org.onlab.packet.MacAddress;
25 +import org.onlab.packet.MplsLabel;
25 import org.onlab.packet.VlanId; 26 import org.onlab.packet.VlanId;
26 import org.onosproject.codec.CodecContext; 27 import org.onosproject.codec.CodecContext;
27 import org.onosproject.codec.JsonCodec; 28 import org.onosproject.codec.JsonCodec;
...@@ -374,7 +375,7 @@ public class CriterionCodecTest { ...@@ -374,7 +375,7 @@ public class CriterionCodecTest {
374 */ 375 */
375 @Test 376 @Test
376 public void matchMplsLabelTest() { 377 public void matchMplsLabelTest() {
377 - Criterion criterion = Criteria.matchMplsLabel(0xffffe); 378 + Criterion criterion = Criteria.matchMplsLabel(MplsLabel.mplsLabel(0xffffe));
378 ObjectNode result = criterionCodec.encode(criterion, context); 379 ObjectNode result = criterionCodec.encode(criterion, context);
379 assertThat(result, matchesCriterion(criterion)); 380 assertThat(result, matchesCriterion(criterion));
380 } 381 }
......
...@@ -397,7 +397,7 @@ public final class CriterionJsonMatcher extends ...@@ -397,7 +397,7 @@ public final class CriterionJsonMatcher extends
397 * @return true if the JSON matches the criterion, false otherwise. 397 * @return true if the JSON matches the criterion, false otherwise.
398 */ 398 */
399 private boolean matchCriterion(Criteria.MplsCriterion criterion) { 399 private boolean matchCriterion(Criteria.MplsCriterion criterion) {
400 - final int label = criterion.label(); 400 + final int label = criterion.label().toInt();
401 final int jsonLabel = jsonCriterion.get("label").intValue(); 401 final int jsonLabel = jsonCriterion.get("label").intValue();
402 if (label != jsonLabel) { 402 if (label != jsonLabel) {
403 description.appendText("label was " + Integer.toString(jsonLabel)); 403 description.appendText("label was " + Integer.toString(jsonLabel));
......
...@@ -20,6 +20,7 @@ import org.junit.Test; ...@@ -20,6 +20,7 @@ import org.junit.Test;
20 import org.onlab.packet.Ip4Address; 20 import org.onlab.packet.Ip4Address;
21 import org.onlab.packet.Ip6Address; 21 import org.onlab.packet.Ip6Address;
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 +import org.onlab.packet.MplsLabel;
23 import org.onlab.packet.VlanId; 24 import org.onlab.packet.VlanId;
24 import org.onosproject.codec.CodecContext; 25 import org.onosproject.codec.CodecContext;
25 import org.onosproject.codec.JsonCodec; 26 import org.onosproject.codec.JsonCodec;
...@@ -220,7 +221,7 @@ public class InstructionCodecTest { ...@@ -220,7 +221,7 @@ public class InstructionCodecTest {
220 public void modMplsLabelInstructionTest() { 221 public void modMplsLabelInstructionTest() {
221 final L2ModificationInstruction.ModMplsLabelInstruction instruction = 222 final L2ModificationInstruction.ModMplsLabelInstruction instruction =
222 (L2ModificationInstruction.ModMplsLabelInstruction) 223 (L2ModificationInstruction.ModMplsLabelInstruction)
223 - Instructions.modMplsLabel(99); 224 + Instructions.modMplsLabel(MplsLabel.mplsLabel(99));
224 final ObjectNode instructionJson = 225 final ObjectNode instructionJson =
225 instructionCodec.encode(instruction, context); 226 instructionCodec.encode(instruction, context);
226 assertThat(instructionJson, matchesInstruction(instruction)); 227 assertThat(instructionJson, matchesInstruction(instruction));
......
...@@ -21,6 +21,7 @@ import java.util.List; ...@@ -21,6 +21,7 @@ import java.util.List;
21 import org.junit.Test; 21 import org.junit.Test;
22 import org.onlab.packet.IpPrefix; 22 import org.onlab.packet.IpPrefix;
23 import org.onlab.packet.MacAddress; 23 import org.onlab.packet.MacAddress;
24 +import org.onlab.packet.MplsLabel;
24 import org.onosproject.codec.CodecContext; 25 import org.onosproject.codec.CodecContext;
25 import org.onosproject.codec.JsonCodec; 26 import org.onosproject.codec.JsonCodec;
26 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
...@@ -54,8 +55,6 @@ import com.google.common.collect.ImmutableList; ...@@ -54,8 +55,6 @@ import com.google.common.collect.ImmutableList;
54 import static org.onosproject.codec.impl.IntentJsonMatcher.matchesIntent; 55 import static org.onosproject.codec.impl.IntentJsonMatcher.matchesIntent;
55 import static org.onosproject.net.NetTestTools.did; 56 import static org.onosproject.net.NetTestTools.did;
56 import static org.onosproject.net.NetTestTools.hid; 57 import static org.onosproject.net.NetTestTools.hid;
57 -
58 -
59 import static org.hamcrest.MatcherAssert.assertThat; 58 import static org.hamcrest.MatcherAssert.assertThat;
60 import static org.hamcrest.Matchers.notNullValue; 59 import static org.hamcrest.Matchers.notNullValue;
61 60
...@@ -123,7 +122,7 @@ public class IntentCodecTest extends AbstractIntentTest { ...@@ -123,7 +122,7 @@ public class IntentCodecTest extends AbstractIntentTest {
123 DeviceId did3 = did("device3"); 122 DeviceId did3 = did("device3");
124 final TrafficSelector selector = DefaultTrafficSelector.builder() 123 final TrafficSelector selector = DefaultTrafficSelector.builder()
125 .matchIPProtocol((byte) 3) 124 .matchIPProtocol((byte) 3)
126 - .matchMplsLabel(4) 125 + .matchMplsLabel(MplsLabel.mplsLabel(4))
127 .matchOpticalSignalType((short) 5) 126 .matchOpticalSignalType((short) 5)
128 .matchLambda((short) 6) 127 .matchLambda((short) 6)
129 .matchEthDst(MacAddress.BROADCAST) 128 .matchEthDst(MacAddress.BROADCAST)
...@@ -131,7 +130,7 @@ public class IntentCodecTest extends AbstractIntentTest { ...@@ -131,7 +130,7 @@ public class IntentCodecTest extends AbstractIntentTest {
131 .build(); 130 .build();
132 final TrafficTreatment treatment = DefaultTrafficTreatment.builder() 131 final TrafficTreatment treatment = DefaultTrafficTreatment.builder()
133 .setLambda((short) 33) 132 .setLambda((short) 33)
134 - .setMpls(44) 133 + .setMpls(MplsLabel.mplsLabel(44))
135 .setOutput(PortNumber.CONTROLLER) 134 .setOutput(PortNumber.CONTROLLER)
136 .setEthDst(MacAddress.BROADCAST) 135 .setEthDst(MacAddress.BROADCAST)
137 .build(); 136 .build();
......