Committed by
Gerrit Code Review
MPLS label selector and treatment
Change-Id: Id1fba1e04155e6d97de4c8fd95573641537f1b7a
Showing
12 changed files
with
474 additions
and
26 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; |
... | @@ -201,25 +205,42 @@ public class FlowModBuilderVer13 extends FlowModBuilder { | ... | @@ -201,25 +205,42 @@ public class FlowModBuilderVer13 extends FlowModBuilder { |
201 | ModEtherInstruction eth; | 205 | ModEtherInstruction eth; |
202 | OFOxm<?> oxm = null; | 206 | OFOxm<?> oxm = null; |
203 | switch (l2m.subtype()) { | 207 | switch (l2m.subtype()) { |
204 | - case ETH_DST: | 208 | + case ETH_DST: |
205 | - eth = (ModEtherInstruction) l2m; | 209 | + eth = (ModEtherInstruction) l2m; |
206 | - oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong())); | 210 | + oxm = factory().oxms().ethDst(MacAddress.of(eth.mac().toLong())); |
207 | - break; | 211 | + break; |
208 | - case ETH_SRC: | 212 | + case ETH_SRC: |
209 | - eth = (ModEtherInstruction) l2m; | 213 | + eth = (ModEtherInstruction) l2m; |
210 | - oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong())); | 214 | + oxm = factory().oxms().ethSrc(MacAddress.of(eth.mac().toLong())); |
211 | - break; | 215 | + break; |
212 | - case VLAN_ID: | 216 | + case VLAN_ID: |
213 | - ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m; | 217 | + ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m; |
214 | - oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort())); | 218 | + oxm = factory().oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort())); |
215 | - break; | 219 | + break; |
216 | - case VLAN_PCP: | 220 | + case VLAN_PCP: |
217 | - ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m; | 221 | + ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m; |
218 | - oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp())); | 222 | + oxm = factory().oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp())); |
219 | - break; | 223 | + break; |
220 | - default: | 224 | + case MPLS_PUSH: |
221 | - log.warn("Unimplemented action type {}.", l2m.subtype()); | 225 | + PushHeaderInstructions pushHeaderInstructions = |
222 | - break; | 226 | + (PushHeaderInstructions) l2m; |
227 | + return factory().actions().pushMpls(EthType.of(pushHeaderInstructions | ||
228 | + .ethernetType().getEtherType())); | ||
229 | + case MPLS_POP: | ||
230 | + PushHeaderInstructions popHeaderInstructions = | ||
231 | + (PushHeaderInstructions) l2m; | ||
232 | + return factory().actions().popMpls(EthType.of(popHeaderInstructions | ||
233 | + .ethernetType().getEtherType())); | ||
234 | + case MPLS_LABEL: | ||
235 | + ModMplsLabelInstruction mplsLabel = | ||
236 | + (ModMplsLabelInstruction) l2m; | ||
237 | + oxm = factory().oxms().mplsLabel(U32.of(mplsLabel.label() | ||
238 | + .longValue())); | ||
239 | + | ||
240 | + break; | ||
241 | + default: | ||
242 | + log.warn("Unimplemented action type {}.", l2m.subtype()); | ||
243 | + break; | ||
223 | } | 244 | } |
224 | 245 | ||
225 | if (oxm != null) { | 246 | if (oxm != null) { | ... | ... |
... | @@ -37,6 +37,8 @@ public class Ethernet extends BasePacket { | ... | @@ -37,6 +37,8 @@ public class Ethernet extends BasePacket { |
37 | public static final short TYPE_LLDP = (short) 0x88cc; | 37 | public static final short TYPE_LLDP = (short) 0x88cc; |
38 | public static final short TYPE_BSN = (short) 0x8942; | 38 | public static final short TYPE_BSN = (short) 0x8942; |
39 | public static final short VLAN_UNTAGGED = (short) 0xffff; | 39 | public static final short VLAN_UNTAGGED = (short) 0xffff; |
40 | + public static final short MPLS_UNICAST = (short) 0x8847; | ||
41 | + public static final short MPLS_MULTICAST = (short) 0x8848; | ||
40 | public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes | 42 | public static final short DATALAYER_ADDRESS_LENGTH = 6; // bytes |
41 | public static Map<Short, Class<? extends IPacket>> etherTypeClassMap; | 43 | public static Map<Short, Class<? extends IPacket>> etherTypeClassMap; |
42 | 44 | ... | ... |
-
Please register or login to post a comment