Committed by
Brian O'Connor
ONOS-631 #Initial MPLS intent implementation
Change-Id: I6f906b953f06f395cc67e612648802e333c0e581
Showing
39 changed files
with
1504 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,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 | +} |
| 1 | +package org.onosproject.net.intent.impl; | ||
| 2 | + | ||
| 3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
| 4 | + | ||
| 5 | +import java.util.Iterator; | ||
| 6 | +import java.util.List; | ||
| 7 | +import java.util.Set; | ||
| 8 | + | ||
| 9 | +import org.apache.felix.scr.annotations.Activate; | ||
| 10 | +import org.apache.felix.scr.annotations.Component; | ||
| 11 | +import org.apache.felix.scr.annotations.Deactivate; | ||
| 12 | +import org.apache.felix.scr.annotations.Reference; | ||
| 13 | +import org.apache.felix.scr.annotations.ReferenceCardinality; | ||
| 14 | +import org.onlab.packet.Ethernet; | ||
| 15 | +import org.onosproject.core.ApplicationId; | ||
| 16 | +import org.onosproject.core.CoreService; | ||
| 17 | +import org.onosproject.net.ConnectPoint; | ||
| 18 | +import org.onosproject.net.DeviceId; | ||
| 19 | +import org.onosproject.net.Link; | ||
| 20 | +import org.onosproject.net.PortNumber; | ||
| 21 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
| 22 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 23 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 24 | +import org.onosproject.net.flow.FlowRule; | ||
| 25 | +import org.onosproject.net.flow.FlowRuleBatchEntry; | ||
| 26 | +import org.onosproject.net.flow.FlowRuleBatchOperation; | ||
| 27 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 28 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 29 | +import org.onosproject.net.flow.FlowRuleBatchEntry.FlowRuleOperation; | ||
| 30 | +import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion; | ||
| 31 | +import org.onosproject.net.flow.criteria.Criterion; | ||
| 32 | +import org.onosproject.net.flow.criteria.Criterion.Type; | ||
| 33 | +import org.onosproject.net.intent.IntentExtensionService; | ||
| 34 | +import org.onosproject.net.intent.IntentInstaller; | ||
| 35 | +import org.onosproject.net.intent.MplsPathIntent; | ||
| 36 | +import org.onosproject.net.link.LinkStore; | ||
| 37 | +import org.onosproject.net.resource.DefaultLinkResourceRequest; | ||
| 38 | +import org.onosproject.net.resource.LinkResourceAllocations; | ||
| 39 | +import org.onosproject.net.resource.LinkResourceRequest; | ||
| 40 | +import org.onosproject.net.resource.LinkResourceService; | ||
| 41 | +import org.onosproject.net.resource.MplsLabel; | ||
| 42 | +import org.onosproject.net.resource.MplsLabelResourceAllocation; | ||
| 43 | +import org.onosproject.net.resource.ResourceAllocation; | ||
| 44 | +import org.onosproject.net.resource.ResourceType; | ||
| 45 | +import org.slf4j.Logger; | ||
| 46 | + | ||
| 47 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 48 | + | ||
| 49 | +import com.google.common.collect.Lists; | ||
| 50 | +import com.google.common.collect.Sets; | ||
| 51 | + | ||
| 52 | +/** | ||
| 53 | + * Installer for {@link MplsPathIntent packet path connectivity intents}. | ||
| 54 | + */ | ||
| 55 | +@Component(immediate = true) | ||
| 56 | +public class MplsPathIntentInstaller implements IntentInstaller<MplsPathIntent> { | ||
| 57 | + | ||
| 58 | + private final Logger log = getLogger(getClass()); | ||
| 59 | + | ||
| 60 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 61 | + protected IntentExtensionService intentManager; | ||
| 62 | + | ||
| 63 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 64 | + protected CoreService coreService; | ||
| 65 | + | ||
| 66 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 67 | + protected LinkResourceService resourceService; | ||
| 68 | + | ||
| 69 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 70 | + protected LinkStore linkStore; | ||
| 71 | + | ||
| 72 | + protected ApplicationId appId; | ||
| 73 | + | ||
| 74 | + @Activate | ||
| 75 | + public void activate() { | ||
| 76 | + appId = coreService.registerApplication("org.onosproject.net.intent"); | ||
| 77 | + intentManager.registerInstaller(MplsPathIntent.class, this); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + @Deactivate | ||
| 81 | + public void deactivate() { | ||
| 82 | + intentManager.unregisterInstaller(MplsPathIntent.class); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public List<FlowRuleBatchOperation> install(MplsPathIntent intent) { | ||
| 87 | + LinkResourceAllocations allocations = assignMplsLabel(intent); | ||
| 88 | + return generateRules(intent, allocations, FlowRuleOperation.ADD); | ||
| 89 | + | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + @Override | ||
| 93 | + public List<FlowRuleBatchOperation> uninstall(MplsPathIntent intent) { | ||
| 94 | + LinkResourceAllocations allocations = resourceService | ||
| 95 | + .getAllocations(intent.id()); | ||
| 96 | + resourceService.releaseResources(allocations); | ||
| 97 | + | ||
| 98 | + List<FlowRuleBatchOperation> rules = generateRules(intent, | ||
| 99 | + allocations, | ||
| 100 | + FlowRuleOperation.REMOVE); | ||
| 101 | + return rules; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + @Override | ||
| 105 | + public List<FlowRuleBatchOperation> replace(MplsPathIntent oldIntent, | ||
| 106 | + MplsPathIntent newIntent) { | ||
| 107 | + | ||
| 108 | + List<FlowRuleBatchOperation> batches = Lists.newArrayList(); | ||
| 109 | + batches.addAll(uninstall(oldIntent)); | ||
| 110 | + batches.addAll(install(newIntent)); | ||
| 111 | + return batches; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + private LinkResourceAllocations assignMplsLabel(MplsPathIntent intent) { | ||
| 115 | + | ||
| 116 | + // TODO: do it better... Suggestions? | ||
| 117 | + Set<Link> linkRequest = Sets.newHashSetWithExpectedSize(intent.path() | ||
| 118 | + .links().size() - 2); | ||
| 119 | + for (int i = 1; i <= intent.path().links().size() - 2; i++) { | ||
| 120 | + Link link = intent.path().links().get(i); | ||
| 121 | + linkRequest.add(link); | ||
| 122 | + // add the inverse link. I want that the label is reserved both for | ||
| 123 | + // the direct and inverse link | ||
| 124 | + linkRequest.add(linkStore.getLink(link.dst(), link.src())); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + LinkResourceRequest.Builder request = DefaultLinkResourceRequest | ||
| 128 | + .builder(intent.id(), linkRequest).addMplsRequest(); | ||
| 129 | + LinkResourceAllocations reqMpls = resourceService | ||
| 130 | + .requestResources(request.build()); | ||
| 131 | + return reqMpls; | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + private MplsLabel getMplsLabel(LinkResourceAllocations allocations, | ||
| 135 | + Link link) { | ||
| 136 | + | ||
| 137 | + for (ResourceAllocation allocation : allocations | ||
| 138 | + .getResourceAllocation(link)) { | ||
| 139 | + if (allocation.type() == ResourceType.MPLS_LABEL) { | ||
| 140 | + return ((MplsLabelResourceAllocation) allocation).mplsLabel(); | ||
| 141 | + | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + log.warn("MPLS label was not assigned successfully"); | ||
| 145 | + return null; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + private List<FlowRuleBatchOperation> generateRules(MplsPathIntent intent, | ||
| 149 | + LinkResourceAllocations allocations, | ||
| 150 | + FlowRuleOperation operation) { | ||
| 151 | + | ||
| 152 | + Iterator<Link> links = intent.path().links().iterator(); | ||
| 153 | + Link srcLink = links.next(); | ||
| 154 | + ConnectPoint prev = srcLink.dst(); | ||
| 155 | + | ||
| 156 | + Link link = links.next(); | ||
| 157 | + // List of flow rules to be installed | ||
| 158 | + List<FlowRuleBatchEntry> rules = Lists.newLinkedList(); | ||
| 159 | + | ||
| 160 | + // Ingress traffic | ||
| 161 | + // Get the new MPLS label | ||
| 162 | + MplsLabel mpls = getMplsLabel(allocations, link); | ||
| 163 | + checkNotNull(mpls); | ||
| 164 | + MplsLabel prevLabel = mpls; | ||
| 165 | + rules.add(ingressFlow(prev.port(), link, intent, mpls, operation)); | ||
| 166 | + | ||
| 167 | + prev = link.dst(); | ||
| 168 | + | ||
| 169 | + while (links.hasNext()) { | ||
| 170 | + | ||
| 171 | + link = links.next(); | ||
| 172 | + | ||
| 173 | + if (links.hasNext()) { | ||
| 174 | + // Transit traffic | ||
| 175 | + // Get the new MPLS label | ||
| 176 | + mpls = getMplsLabel(allocations, link); | ||
| 177 | + checkNotNull(mpls); | ||
| 178 | + rules.add(transitFlow(prev.port(), link, intent, | ||
| 179 | + prevLabel, mpls, operation)); | ||
| 180 | + prevLabel = mpls; | ||
| 181 | + | ||
| 182 | + } else { | ||
| 183 | + // Egress traffic | ||
| 184 | + rules.add(egressFlow(prev.port(), link, intent, | ||
| 185 | + prevLabel, operation)); | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + prev = link.dst(); | ||
| 189 | + } | ||
| 190 | + return Lists.newArrayList(new FlowRuleBatchOperation(rules, null, 0)); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + private FlowRuleBatchEntry ingressFlow(PortNumber inPort, Link link, | ||
| 194 | + MplsPathIntent intent, | ||
| 195 | + MplsLabel label, | ||
| 196 | + FlowRuleOperation operation) { | ||
| 197 | + | ||
| 198 | + TrafficSelector.Builder ingressSelector = DefaultTrafficSelector | ||
| 199 | + .builder(intent.selector()); | ||
| 200 | + TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | ||
| 201 | + ingressSelector.matchInPort(inPort); | ||
| 202 | + | ||
| 203 | + if (intent.ingressLabel().isPresent()) { | ||
| 204 | + ingressSelector.matchEthType(Ethernet.MPLS_UNICAST) | ||
| 205 | + .matchMplsLabel(intent.ingressLabel().get()); | ||
| 206 | + | ||
| 207 | + // Swap the MPLS label | ||
| 208 | + treat.setMpls(label.label()); | ||
| 209 | + } else { | ||
| 210 | + // Push and set the MPLS label | ||
| 211 | + treat.pushMpls().setMpls(label.label()); | ||
| 212 | + } | ||
| 213 | + // Add the output action | ||
| 214 | + treat.setOutput(link.src().port()); | ||
| 215 | + | ||
| 216 | + return flowRuleBatchEntry(intent, link.src().deviceId(), | ||
| 217 | + ingressSelector.build(), treat.build(), | ||
| 218 | + operation); | ||
| 219 | + } | ||
| 220 | + | ||
| 221 | + private FlowRuleBatchEntry transitFlow(PortNumber inPort, Link link, | ||
| 222 | + MplsPathIntent intent, | ||
| 223 | + MplsLabel prevLabel, | ||
| 224 | + MplsLabel outLabel, | ||
| 225 | + FlowRuleOperation operation) { | ||
| 226 | + | ||
| 227 | + // Ignore the ingress Traffic Selector and use only the MPLS label | ||
| 228 | + // assigned in the previous link | ||
| 229 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 230 | + selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST) | ||
| 231 | + .matchMplsLabel(prevLabel.label()); | ||
| 232 | + TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); | ||
| 233 | + | ||
| 234 | + // Set the new label only if the label on the packet is | ||
| 235 | + // different | ||
| 236 | + if (prevLabel.equals(outLabel)) { | ||
| 237 | + treat.setMpls(outLabel.label()); | ||
| 238 | + } | ||
| 239 | + | ||
| 240 | + treat.setOutput(link.src().port()); | ||
| 241 | + return flowRuleBatchEntry(intent, link.src().deviceId(), | ||
| 242 | + selector.build(), treat.build(), operation); | ||
| 243 | + } | ||
| 244 | + | ||
| 245 | + private FlowRuleBatchEntry egressFlow(PortNumber inPort, Link link, | ||
| 246 | + MplsPathIntent intent, | ||
| 247 | + MplsLabel prevLabel, | ||
| 248 | + FlowRuleOperation operation) { | ||
| 249 | + // egress point: either set the egress MPLS label or pop the | ||
| 250 | + // MPLS label based on the intent annotations | ||
| 251 | + | ||
| 252 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 253 | + selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST) | ||
| 254 | + .matchMplsLabel(prevLabel.label()); | ||
| 255 | + | ||
| 256 | + // apply the intent's treatments | ||
| 257 | + TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(intent | ||
| 258 | + .treatment()); | ||
| 259 | + | ||
| 260 | + if (intent.egressLabel().isPresent()) { | ||
| 261 | + treat.setMpls(intent.egressLabel().get()); | ||
| 262 | + } else { | ||
| 263 | + // if the ingress ethertype is defined, the egress traffic | ||
| 264 | + // will be use that value, otherwise the IPv4 ethertype is used. | ||
| 265 | + Criterion c = intent.selector().getCriterion(Type.ETH_TYPE); | ||
| 266 | + if (c != null && c instanceof EthTypeCriterion) { | ||
| 267 | + EthTypeCriterion ethertype = (EthTypeCriterion) c; | ||
| 268 | + treat.popMpls((short) ethertype.ethType()); | ||
| 269 | + } else { | ||
| 270 | + treat.popMpls(Ethernet.TYPE_IPV4); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + } | ||
| 274 | + treat.setOutput(link.src().port()); | ||
| 275 | + return flowRuleBatchEntry(intent, link.src().deviceId(), | ||
| 276 | + selector.build(), treat.build(), operation); | ||
| 277 | + } | ||
| 278 | + | ||
| 279 | + protected FlowRuleBatchEntry flowRuleBatchEntry(MplsPathIntent intent, | ||
| 280 | + DeviceId deviceId, | ||
| 281 | + TrafficSelector selector, | ||
| 282 | + TrafficTreatment treat, | ||
| 283 | + FlowRuleOperation operation) { | ||
| 284 | + FlowRule rule = new DefaultFlowRule( | ||
| 285 | + deviceId, | ||
| 286 | + selector, | ||
| 287 | + treat, | ||
| 288 | + 123, // FIXME 123 | ||
| 289 | + appId, | ||
| 290 | + 0, | ||
| 291 | + true); | ||
| 292 | + return new FlowRuleBatchEntry(operation, rule, intent.id() | ||
| 293 | + .fingerprint()); | ||
| 294 | + | ||
| 295 | + } | ||
| 296 | +} |
| ... | @@ -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(); | ... | ... |
-
Please register or login to post a comment