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