Pavlin Radoslavov

Implement some of the missing IPv6 flowmod treatments

Work toward ONOS-509

The following treatments are added/implemented:
  - IPV6_SRC
  - IPV6_DST
  - IPV6_FLABEL

Also:
 - Renamed L3ModificationInstruction.L3SubType.IP_SRC and IP_DST
   to IPV4_SRC and IPV4_DST (for naming consistency).
 - Few minor fixes in related code: Javadocs, comments, log messages,
   and IP address usage.

Change-Id: I551056f767a37e7cb6ae7d79f4a3929183500b57
...@@ -120,7 +120,7 @@ public interface TrafficTreatment { ...@@ -120,7 +120,7 @@ public interface TrafficTreatment {
120 public Builder setIpDst(IpAddress addr); 120 public Builder setIpDst(IpAddress addr);
121 121
122 /** 122 /**
123 - * Decrease the TTL in IP header by one. 123 + * Decrement the TTL in IP header by one.
124 * 124 *
125 * @return a treatment builder 125 * @return a treatment builder
126 */ 126 */
......
...@@ -29,6 +29,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType ...@@ -29,6 +29,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType
29 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction; 29 import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
30 import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType; 30 import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
31 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 31 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
32 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
32 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction; 33 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModTtlInstruction;
33 34
34 import org.onlab.packet.Ethernet; 35 import org.onlab.packet.Ethernet;
...@@ -144,24 +145,59 @@ public final class Instructions { ...@@ -144,24 +145,59 @@ public final class Instructions {
144 public static L2ModificationInstruction decMplsTtl() { 145 public static L2ModificationInstruction decMplsTtl() {
145 return new ModMplsTtlInstruction(); 146 return new ModMplsTtlInstruction();
146 } 147 }
148 +
147 /** 149 /**
148 - * Creates a L3 src modification. 150 + * Creates a L3 IPv4 src modification.
149 - * @param addr the ip address to modify to. 151 + *
152 + * @param addr the IPv4 address to modify to
150 * @return a L3 modification 153 * @return a L3 modification
151 */ 154 */
152 public static L3ModificationInstruction modL3Src(IpAddress addr) { 155 public static L3ModificationInstruction modL3Src(IpAddress addr) {
153 - checkNotNull(addr, "Src l3 address cannot be null"); 156 + checkNotNull(addr, "Src l3 IPv4 address cannot be null");
154 - return new ModIPInstruction(L3SubType.IP_SRC, addr); 157 + return new ModIPInstruction(L3SubType.IPV4_SRC, addr);
155 } 158 }
156 159
157 /** 160 /**
158 - * Creates a L3 dst modification. 161 + * Creates a L3 IPv4 dst modification.
159 - * @param addr the ip address to modify to. 162 + *
163 + * @param addr the IPv4 address to modify to
160 * @return a L3 modification 164 * @return a L3 modification
161 */ 165 */
162 public static L3ModificationInstruction modL3Dst(IpAddress addr) { 166 public static L3ModificationInstruction modL3Dst(IpAddress addr) {
163 - checkNotNull(addr, "Dst l3 address cannot be null"); 167 + checkNotNull(addr, "Dst l3 IPv4 address cannot be null");
164 - return new ModIPInstruction(L3SubType.IP_DST, addr); 168 + return new ModIPInstruction(L3SubType.IPV4_DST, addr);
169 + }
170 +
171 + /**
172 + * Creates a L3 IPv6 src modification.
173 + *
174 + * @param addr the IPv6 address to modify to
175 + * @return a L3 modification
176 + */
177 + public static L3ModificationInstruction modL3IPv6Src(IpAddress addr) {
178 + checkNotNull(addr, "Src l3 IPv6 address cannot be null");
179 + return new ModIPInstruction(L3SubType.IPV6_SRC, addr);
180 + }
181 +
182 + /**
183 + * Creates a L3 IPv6 dst modification.
184 + *
185 + * @param addr the IPv6 address to modify to
186 + * @return a L3 modification
187 + */
188 + public static L3ModificationInstruction modL3IPv6Dst(IpAddress addr) {
189 + checkNotNull(addr, "Dst l3 IPv6 address cannot be null");
190 + return new ModIPInstruction(L3SubType.IPV6_DST, addr);
191 + }
192 +
193 + /**
194 + * Creates a L3 IPv6 Flow Label modification.
195 + *
196 + * @param flowLabel the IPv6 flow label to modify to (20 bits)
197 + * @return a L3 modification
198 + */
199 + public static L3ModificationInstruction modL3IPv6FlowLabel(int flowLabel) {
200 + return new ModIPv6FlowLabelInstruction(flowLabel);
165 } 201 }
166 202
167 /** 203 /**
......
...@@ -31,17 +31,32 @@ public abstract class L3ModificationInstruction implements Instruction { ...@@ -31,17 +31,32 @@ public abstract class L3ModificationInstruction implements Instruction {
31 */ 31 */
32 public enum L3SubType { 32 public enum L3SubType {
33 /** 33 /**
34 - * Ether src modification. 34 + * IPv4 src modification.
35 */ 35 */
36 - IP_SRC, 36 + IPV4_SRC,
37 37
38 /** 38 /**
39 - * Ether dst modification. 39 + * IPv4 dst modification.
40 */ 40 */
41 - IP_DST, 41 + IPV4_DST,
42 42
43 /** 43 /**
44 - * Decrease TTL. 44 + * IPv6 src modification.
45 + */
46 + IPV6_SRC,
47 +
48 + /**
49 + * IPv6 dst modification.
50 + */
51 + IPV6_DST,
52 +
53 + /**
54 + * IPv6 flow label modification.
55 + */
56 + IPV6_FLABEL,
57 +
58 + /**
59 + * Decrement TTL.
45 */ 60 */
46 DEC_TTL, 61 DEC_TTL,
47 62
...@@ -120,6 +135,65 @@ public abstract class L3ModificationInstruction implements Instruction { ...@@ -120,6 +135,65 @@ public abstract class L3ModificationInstruction implements Instruction {
120 } 135 }
121 136
122 /** 137 /**
138 + * Represents a L3 IPv6 Flow Label (RFC 6437) modification instruction
139 + * (20 bits unsigned integer).
140 + */
141 + public static final class ModIPv6FlowLabelInstruction
142 + extends L3ModificationInstruction {
143 + private static final int MASK = 0xfffff;
144 + private final int flowLabel; // IPv6 flow label: 20 bits
145 +
146 + /**
147 + * Constructor.
148 + *
149 + * flowLabel the IPv6 flow label to set in the treatment (20 bits)
150 + */
151 + public ModIPv6FlowLabelInstruction(int flowLabel) {
152 + this.flowLabel = flowLabel & MASK;
153 + }
154 +
155 + @Override
156 + public L3SubType subtype() {
157 + return L3SubType.IPV6_FLABEL;
158 + }
159 +
160 + /**
161 + * Gets the IPv6 flow label to set in the treatment.
162 + *
163 + * @return the IPv6 flow label to set in the treatment (20 bits)
164 + */
165 + public int flowLabel() {
166 + return this.flowLabel;
167 + }
168 +
169 + @Override
170 + public String toString() {
171 + return toStringHelper(subtype().toString())
172 + .add("flowLabel", Long.toHexString(flowLabel)).toString();
173 + }
174 +
175 + @Override
176 + public int hashCode() {
177 + return Objects.hash(type(), subtype(), flowLabel);
178 + }
179 +
180 + @Override
181 + public boolean equals(Object obj) {
182 + if (this == obj) {
183 + return true;
184 + }
185 + if (obj instanceof ModIPv6FlowLabelInstruction) {
186 + ModIPv6FlowLabelInstruction that =
187 + (ModIPv6FlowLabelInstruction) obj;
188 + return Objects.equals(flowLabel, that.flowLabel) &&
189 + Objects.equals(this.type(), that.type()) &&
190 + Objects.equals(this.subtype(), that.subtype());
191 + }
192 + return false;
193 + }
194 + }
195 +
196 + /**
123 * Represents a L3 TTL modification instruction. 197 * Represents a L3 TTL modification instruction.
124 */ 198 */
125 public static final class ModTtlInstruction extends L3ModificationInstruction { 199 public static final class ModTtlInstruction extends L3ModificationInstruction {
......
...@@ -18,7 +18,6 @@ package org.onosproject.net.flow.instructions; ...@@ -18,7 +18,6 @@ package org.onosproject.net.flow.instructions;
18 import org.junit.Test; 18 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.IpPrefix;
22 import org.onlab.packet.MacAddress; 21 import org.onlab.packet.MacAddress;
23 import org.onlab.packet.VlanId; 22 import org.onlab.packet.VlanId;
24 23
...@@ -94,6 +93,7 @@ public class InstructionsTest { ...@@ -94,6 +93,7 @@ public class InstructionsTest {
94 assertThatClassIsImmutable(L2ModificationInstruction.ModVlanIdInstruction.class); 93 assertThatClassIsImmutable(L2ModificationInstruction.ModVlanIdInstruction.class);
95 assertThatClassIsImmutable(L2ModificationInstruction.ModVlanPcpInstruction.class); 94 assertThatClassIsImmutable(L2ModificationInstruction.ModVlanPcpInstruction.class);
96 assertThatClassIsImmutable(L3ModificationInstruction.ModIPInstruction.class); 95 assertThatClassIsImmutable(L3ModificationInstruction.ModIPInstruction.class);
96 + assertThatClassIsImmutable(L3ModificationInstruction.ModIPv6FlowLabelInstruction.class);
97 assertThatClassIsImmutable(L2ModificationInstruction.ModMplsLabelInstruction.class); 97 assertThatClassIsImmutable(L2ModificationInstruction.ModMplsLabelInstruction.class);
98 assertThatClassIsImmutable(L2ModificationInstruction.PushHeaderInstructions.class); 98 assertThatClassIsImmutable(L2ModificationInstruction.PushHeaderInstructions.class);
99 } 99 }
...@@ -377,29 +377,40 @@ public class InstructionsTest { ...@@ -377,29 +377,40 @@ public class InstructionsTest {
377 is(not(equalTo(modVlanPcp2.hashCode())))); 377 is(not(equalTo(modVlanPcp2.hashCode()))));
378 } 378 }
379 379
380 - // ModIPerInstruction 380 + // ModIPInstruction
381 - 381 +
382 - private static final String IP1 = "1.2.3.4/24"; 382 + private static final String IP41 = "1.2.3.4";
383 - private static final String IP2 = "5.6.7.8/24"; 383 + private static final String IP42 = "5.6.7.8";
384 - private IpAddress ip1 = IpPrefix.valueOf(IP1).address(); 384 + private IpAddress ip41 = IpAddress.valueOf(IP41);
385 - private IpAddress ip2 = IpPrefix.valueOf(IP2).address(); 385 + private IpAddress ip42 = IpAddress.valueOf(IP42);
386 - private final Instruction modIPInstruction1 = Instructions.modL3Src(ip1); 386 + private final Instruction modIPInstruction1 = Instructions.modL3Src(ip41);
387 - private final Instruction sameAsModIPInstruction1 = Instructions.modL3Src(ip1); 387 + private final Instruction sameAsModIPInstruction1 = Instructions.modL3Src(ip41);
388 - private final Instruction modIPInstruction2 = Instructions.modL3Src(ip2); 388 + private final Instruction modIPInstruction2 = Instructions.modL3Src(ip42);
389 +
390 + private static final String IP61 = "1111::2222";
391 + private static final String IP62 = "3333::4444";
392 + private IpAddress ip61 = IpAddress.valueOf(IP61);
393 + private IpAddress ip62 = IpAddress.valueOf(IP62);
394 + private final Instruction modIPv6Instruction1 =
395 + Instructions.modL3IPv6Src(ip61);
396 + private final Instruction sameAsModIPv6Instruction1 =
397 + Instructions.modL3IPv6Src(ip61);
398 + private final Instruction modIPv6Instruction2 =
399 + Instructions.modL3IPv6Src(ip62);
389 400
390 /** 401 /**
391 * Test the modL3Src method. 402 * Test the modL3Src method.
392 */ 403 */
393 @Test 404 @Test
394 public void testModL3SrcMethod() { 405 public void testModL3SrcMethod() {
395 - final Instruction instruction = Instructions.modL3Src(ip1); 406 + final Instruction instruction = Instructions.modL3Src(ip41);
396 final L3ModificationInstruction.ModIPInstruction modIPInstruction = 407 final L3ModificationInstruction.ModIPInstruction modIPInstruction =
397 checkAndConvert(instruction, 408 checkAndConvert(instruction,
398 Instruction.Type.L3MODIFICATION, 409 Instruction.Type.L3MODIFICATION,
399 L3ModificationInstruction.ModIPInstruction.class); 410 L3ModificationInstruction.ModIPInstruction.class);
400 - assertThat(modIPInstruction.ip(), is(equalTo(ip1))); 411 + assertThat(modIPInstruction.ip(), is(equalTo(ip41)));
401 assertThat(modIPInstruction.subtype(), 412 assertThat(modIPInstruction.subtype(),
402 - is(equalTo(L3ModificationInstruction.L3SubType.IP_SRC))); 413 + is(equalTo(L3ModificationInstruction.L3SubType.IPV4_SRC)));
403 } 414 }
404 415
405 /** 416 /**
...@@ -407,20 +418,49 @@ public class InstructionsTest { ...@@ -407,20 +418,49 @@ public class InstructionsTest {
407 */ 418 */
408 @Test 419 @Test
409 public void testModL3DstMethod() { 420 public void testModL3DstMethod() {
410 - final Instruction instruction = Instructions.modL3Dst(ip1); 421 + final Instruction instruction = Instructions.modL3Dst(ip41);
411 final L3ModificationInstruction.ModIPInstruction modIPInstruction = 422 final L3ModificationInstruction.ModIPInstruction modIPInstruction =
412 checkAndConvert(instruction, 423 checkAndConvert(instruction,
413 Instruction.Type.L3MODIFICATION, 424 Instruction.Type.L3MODIFICATION,
414 L3ModificationInstruction.ModIPInstruction.class); 425 L3ModificationInstruction.ModIPInstruction.class);
415 - assertThat(modIPInstruction.ip(), is(equalTo(ip1))); 426 + assertThat(modIPInstruction.ip(), is(equalTo(ip41)));
416 assertThat(modIPInstruction.subtype(), 427 assertThat(modIPInstruction.subtype(),
417 - is(equalTo(L3ModificationInstruction.L3SubType.IP_DST))); 428 + is(equalTo(L3ModificationInstruction.L3SubType.IPV4_DST)));
418 } 429 }
419 430
420 /** 431 /**
421 - * Test the equals() method of the ModEtherInstruction class. 432 + * Test the modL3IPv6Src method.
422 */ 433 */
434 + @Test
435 + public void testModL3IPv6SrcMethod() {
436 + final Instruction instruction = Instructions.modL3IPv6Src(ip61);
437 + final L3ModificationInstruction.ModIPInstruction modIPInstruction =
438 + checkAndConvert(instruction,
439 + Instruction.Type.L3MODIFICATION,
440 + L3ModificationInstruction.ModIPInstruction.class);
441 + assertThat(modIPInstruction.ip(), is(equalTo(ip61)));
442 + assertThat(modIPInstruction.subtype(),
443 + is(equalTo(L3ModificationInstruction.L3SubType.IPV6_SRC)));
444 + }
423 445
446 + /**
447 + * Test the modL3IPv6Dst method.
448 + */
449 + @Test
450 + public void testModL3IPv6DstMethod() {
451 + final Instruction instruction = Instructions.modL3IPv6Dst(ip61);
452 + final L3ModificationInstruction.ModIPInstruction modIPInstruction =
453 + checkAndConvert(instruction,
454 + Instruction.Type.L3MODIFICATION,
455 + L3ModificationInstruction.ModIPInstruction.class);
456 + assertThat(modIPInstruction.ip(), is(equalTo(ip61)));
457 + assertThat(modIPInstruction.subtype(),
458 + is(equalTo(L3ModificationInstruction.L3SubType.IPV6_DST)));
459 + }
460 +
461 + /**
462 + * Test the equals() method of the ModIPInstruction class.
463 + */
424 @Test 464 @Test
425 public void testModIPInstructionEquals() throws Exception { 465 public void testModIPInstructionEquals() throws Exception {
426 checkEqualsAndToString(modIPInstruction1, 466 checkEqualsAndToString(modIPInstruction1,
...@@ -429,9 +469,8 @@ public class InstructionsTest { ...@@ -429,9 +469,8 @@ public class InstructionsTest {
429 } 469 }
430 470
431 /** 471 /**
432 - * Test the hashCode() method of the ModEtherInstruction class. 472 + * Test the hashCode() method of the ModIPInstruction class.
433 */ 473 */
434 -
435 @Test 474 @Test
436 public void testModIPInstructionHashCode() { 475 public void testModIPInstructionHashCode() {
437 assertThat(modIPInstruction1.hashCode(), 476 assertThat(modIPInstruction1.hashCode(),
...@@ -440,6 +479,54 @@ public class InstructionsTest { ...@@ -440,6 +479,54 @@ public class InstructionsTest {
440 is(not(equalTo(modIPInstruction2.hashCode())))); 479 is(not(equalTo(modIPInstruction2.hashCode()))));
441 } 480 }
442 481
482 + private final int flowLabel1 = 0x11111;
483 + private final int flowLabel2 = 0x22222;
484 + private final Instruction modIPv6FlowLabelInstruction1 =
485 + Instructions.modL3IPv6FlowLabel(flowLabel1);
486 + private final Instruction sameAsModIPv6FlowLabelInstruction1 =
487 + Instructions.modL3IPv6FlowLabel(flowLabel1);
488 + private final Instruction modIPv6FlowLabelInstruction2 =
489 + Instructions.modL3IPv6FlowLabel(flowLabel2);
490 +
491 + /**
492 + * Test the modL3IPv6FlowLabel method.
493 + */
494 + @Test
495 + public void testModL3IPv6FlowLabelMethod() {
496 + final Instruction instruction =
497 + Instructions.modL3IPv6FlowLabel(flowLabel1);
498 + final L3ModificationInstruction.ModIPv6FlowLabelInstruction
499 + modIPv6FlowLabelInstruction =
500 + checkAndConvert(instruction,
501 + Instruction.Type.L3MODIFICATION,
502 + L3ModificationInstruction.ModIPv6FlowLabelInstruction.class);
503 + assertThat(modIPv6FlowLabelInstruction.flowLabel(),
504 + is(equalTo(flowLabel1)));
505 + assertThat(modIPv6FlowLabelInstruction.subtype(),
506 + is(equalTo(L3ModificationInstruction.L3SubType.IPV6_FLABEL)));
507 + }
508 +
509 + /**
510 + * Test the equals() method of the ModIPv6FlowLabelInstruction class.
511 + */
512 + @Test
513 + public void testModIPv6FlowLabelInstructionEquals() throws Exception {
514 + checkEqualsAndToString(modIPv6FlowLabelInstruction1,
515 + sameAsModIPv6FlowLabelInstruction1,
516 + modIPv6FlowLabelInstruction2);
517 + }
518 +
519 + /**
520 + * Test the hashCode() method of the ModIPv6FlowLabelInstruction class.
521 + */
522 + @Test
523 + public void testModIPv6FlowLabelInstructionHashCode() {
524 + assertThat(modIPv6FlowLabelInstruction1.hashCode(),
525 + is(equalTo(sameAsModIPv6FlowLabelInstruction1.hashCode())));
526 + assertThat(modIPv6FlowLabelInstruction1.hashCode(),
527 + is(not(equalTo(modIPv6FlowLabelInstruction2.hashCode()))));
528 + }
529 +
443 private Instruction modMplsLabelInstruction1 = Instructions.modMplsLabel(1); 530 private Instruction modMplsLabelInstruction1 = Instructions.modMplsLabel(1);
444 private Instruction sameAsModMplsLabelInstruction1 = Instructions.modMplsLabel(1); 531 private Instruction sameAsModMplsLabelInstruction1 = Instructions.modMplsLabel(1);
445 private Instruction modMplsLabelInstruction2 = Instructions.modMplsLabel(2); 532 private Instruction modMplsLabelInstruction2 = Instructions.modMplsLabel(2);
...@@ -463,7 +550,6 @@ public class InstructionsTest { ...@@ -463,7 +550,6 @@ public class InstructionsTest {
463 * Test the equals(), hashCode and toString() methods of the 550 * Test the equals(), hashCode and toString() methods of the
464 * ModMplsLabelInstruction class. 551 * ModMplsLabelInstruction class.
465 */ 552 */
466 -
467 @Test 553 @Test
468 public void testModMplsLabelInstructionEquals() throws Exception { 554 public void testModMplsLabelInstructionEquals() throws Exception {
469 checkEqualsAndToString(modMplsLabelInstruction1, 555 checkEqualsAndToString(modMplsLabelInstruction1,
......
...@@ -257,6 +257,7 @@ public final class KryoNamespaces { ...@@ -257,6 +257,7 @@ public final class KryoNamespaces {
257 L3ModificationInstruction.class, 257 L3ModificationInstruction.class,
258 L3ModificationInstruction.L3SubType.class, 258 L3ModificationInstruction.L3SubType.class,
259 L3ModificationInstruction.ModIPInstruction.class, 259 L3ModificationInstruction.ModIPInstruction.class,
260 + L3ModificationInstruction.ModIPv6FlowLabelInstruction.class,
260 RoleInfo.class, 261 RoleInfo.class,
261 FlowRuleBatchEvent.class, 262 FlowRuleBatchEvent.class,
262 FlowRuleBatchEvent.Type.class, 263 FlowRuleBatchEvent.Type.class,
......
...@@ -176,14 +176,14 @@ public class FlowModBuilderVer10 extends FlowModBuilder { ...@@ -176,14 +176,14 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
176 ModIPInstruction ip; 176 ModIPInstruction ip;
177 Ip4Address ip4; 177 Ip4Address ip4;
178 switch (l3m.subtype()) { 178 switch (l3m.subtype()) {
179 - case IP_DST: 179 + case IPV4_SRC:
180 ip = (ModIPInstruction) i; 180 ip = (ModIPInstruction) i;
181 ip4 = ip.ip().getIp4Address(); 181 ip4 = ip.ip().getIp4Address();
182 - return factory().actions().setNwDst(IPv4Address.of(ip4.toInt())); 182 + return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt()));
183 - case IP_SRC: 183 + case IPV4_DST:
184 ip = (ModIPInstruction) i; 184 ip = (ModIPInstruction) i;
185 ip4 = ip.ip().getIp4Address(); 185 ip4 = ip.ip().getIp4Address();
186 - return factory().actions().setNwSrc(IPv4Address.of(ip4.toInt())); 186 + return factory().actions().setNwDst(IPv4Address.of(ip4.toInt()));
187 default: 187 default:
188 log.warn("Unimplemented action type {}.", l3m.subtype()); 188 log.warn("Unimplemented action type {}.", l3m.subtype());
189 break; 189 break;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.provider.of.flow.impl; 16 package org.onosproject.provider.of.flow.impl;
17 17
18 import org.onlab.packet.Ip4Address; 18 import org.onlab.packet.Ip4Address;
19 +import org.onlab.packet.Ip6Address;
19 import org.onosproject.net.PortNumber; 20 import org.onosproject.net.PortNumber;
20 import org.onosproject.net.flow.FlowRule; 21 import org.onosproject.net.flow.FlowRule;
21 import org.onosproject.net.flow.TrafficTreatment; 22 import org.onosproject.net.flow.TrafficTreatment;
...@@ -32,6 +33,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPc ...@@ -32,6 +33,7 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPc
32 import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions; 33 import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
33 import org.onosproject.net.flow.instructions.L3ModificationInstruction; 34 import org.onosproject.net.flow.instructions.L3ModificationInstruction;
34 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction; 35 import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
36 +import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
35 import org.projectfloodlight.openflow.protocol.OFFactory; 37 import org.projectfloodlight.openflow.protocol.OFFactory;
36 import org.projectfloodlight.openflow.protocol.OFFlowAdd; 38 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
37 import org.projectfloodlight.openflow.protocol.OFFlowDelete; 39 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
...@@ -45,6 +47,8 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxm; ...@@ -45,6 +47,8 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
45 import org.projectfloodlight.openflow.types.CircuitSignalID; 47 import org.projectfloodlight.openflow.types.CircuitSignalID;
46 import org.projectfloodlight.openflow.types.EthType; 48 import org.projectfloodlight.openflow.types.EthType;
47 import org.projectfloodlight.openflow.types.IPv4Address; 49 import org.projectfloodlight.openflow.types.IPv4Address;
50 +import org.projectfloodlight.openflow.types.IPv6Address;
51 +import org.projectfloodlight.openflow.types.IPv6FlowLabel;
48 import org.projectfloodlight.openflow.types.MacAddress; 52 import org.projectfloodlight.openflow.types.MacAddress;
49 import org.projectfloodlight.openflow.types.OFBufferId; 53 import org.projectfloodlight.openflow.types.OFBufferId;
50 import org.projectfloodlight.openflow.types.OFGroup; 54 import org.projectfloodlight.openflow.types.OFGroup;
...@@ -267,17 +271,34 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -267,17 +271,34 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
267 L3ModificationInstruction l3m = (L3ModificationInstruction) i; 271 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
268 ModIPInstruction ip; 272 ModIPInstruction ip;
269 Ip4Address ip4; 273 Ip4Address ip4;
274 + Ip6Address ip6;
270 OFOxm<?> oxm = null; 275 OFOxm<?> oxm = null;
271 switch (l3m.subtype()) { 276 switch (l3m.subtype()) {
272 - case IP_DST: 277 + case IPV4_SRC:
273 ip = (ModIPInstruction) i; 278 ip = (ModIPInstruction) i;
274 ip4 = ip.ip().getIp4Address(); 279 ip4 = ip.ip().getIp4Address();
275 - oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt())); 280 + oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
276 break; 281 break;
277 - case IP_SRC: 282 + case IPV4_DST:
278 ip = (ModIPInstruction) i; 283 ip = (ModIPInstruction) i;
279 ip4 = ip.ip().getIp4Address(); 284 ip4 = ip.ip().getIp4Address();
280 - oxm = factory().oxms().ipv4Src(IPv4Address.of(ip4.toInt())); 285 + oxm = factory().oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
286 + break;
287 + case IPV6_SRC:
288 + ip = (ModIPInstruction) i;
289 + ip6 = ip.ip().getIp6Address();
290 + oxm = factory().oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
291 + break;
292 + case IPV6_DST:
293 + ip = (ModIPInstruction) i;
294 + ip6 = ip.ip().getIp6Address();
295 + oxm = factory().oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
296 + break;
297 + case IPV6_FLABEL:
298 + ModIPv6FlowLabelInstruction flowLabelInstruction =
299 + (ModIPv6FlowLabelInstruction) i;
300 + int flowLabel = flowLabelInstruction.flowLabel();
301 + oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
281 break; 302 break;
282 case DEC_TTL: 303 case DEC_TTL:
283 return factory().actions().decNwTtl(); 304 return factory().actions().decNwTtl();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 package org.onosproject.provider.of.group.impl; 16 package org.onosproject.provider.of.group.impl;
17 17
18 import org.onlab.packet.Ip4Address; 18 import org.onlab.packet.Ip4Address;
19 +import org.onlab.packet.Ip6Address;
19 import org.onosproject.core.GroupId; 20 import org.onosproject.core.GroupId;
20 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
21 import org.onosproject.net.flow.TrafficTreatment; 22 import org.onosproject.net.flow.TrafficTreatment;
...@@ -39,6 +40,8 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxm; ...@@ -39,6 +40,8 @@ import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
39 import org.projectfloodlight.openflow.types.CircuitSignalID; 40 import org.projectfloodlight.openflow.types.CircuitSignalID;
40 import org.projectfloodlight.openflow.types.EthType; 41 import org.projectfloodlight.openflow.types.EthType;
41 import org.projectfloodlight.openflow.types.IPv4Address; 42 import org.projectfloodlight.openflow.types.IPv4Address;
43 +import org.projectfloodlight.openflow.types.IPv6Address;
44 +import org.projectfloodlight.openflow.types.IPv6FlowLabel;
42 import org.projectfloodlight.openflow.types.MacAddress; 45 import org.projectfloodlight.openflow.types.MacAddress;
43 import org.projectfloodlight.openflow.types.OFGroup; 46 import org.projectfloodlight.openflow.types.OFGroup;
44 import org.projectfloodlight.openflow.types.OFPort; 47 import org.projectfloodlight.openflow.types.OFPort;
...@@ -284,17 +287,34 @@ public final class GroupModBuilder { ...@@ -284,17 +287,34 @@ public final class GroupModBuilder {
284 L3ModificationInstruction l3m = (L3ModificationInstruction) i; 287 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
285 L3ModificationInstruction.ModIPInstruction ip; 288 L3ModificationInstruction.ModIPInstruction ip;
286 Ip4Address ip4; 289 Ip4Address ip4;
290 + Ip6Address ip6;
287 OFOxm<?> oxm = null; 291 OFOxm<?> oxm = null;
288 switch (l3m.subtype()) { 292 switch (l3m.subtype()) {
289 - case IP_DST: 293 + case IPV4_SRC:
290 ip = (L3ModificationInstruction.ModIPInstruction) i; 294 ip = (L3ModificationInstruction.ModIPInstruction) i;
291 ip4 = ip.ip().getIp4Address(); 295 ip4 = ip.ip().getIp4Address();
292 - oxm = factory.oxms().ipv4Dst(IPv4Address.of(ip4.toInt())); 296 + oxm = factory.oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
293 break; 297 break;
294 - case IP_SRC: 298 + case IPV4_DST:
295 ip = (L3ModificationInstruction.ModIPInstruction) i; 299 ip = (L3ModificationInstruction.ModIPInstruction) i;
296 ip4 = ip.ip().getIp4Address(); 300 ip4 = ip.ip().getIp4Address();
297 - oxm = factory.oxms().ipv4Src(IPv4Address.of(ip4.toInt())); 301 + oxm = factory.oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
302 + break;
303 + case IPV6_SRC:
304 + ip = (L3ModificationInstruction.ModIPInstruction) i;
305 + ip6 = ip.ip().getIp6Address();
306 + oxm = factory.oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
307 + break;
308 + case IPV6_DST:
309 + ip = (L3ModificationInstruction.ModIPInstruction) i;
310 + ip6 = ip.ip().getIp6Address();
311 + oxm = factory.oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
312 + break;
313 + case IPV6_FLABEL:
314 + L3ModificationInstruction.ModIPv6FlowLabelInstruction flowLabelInstruction =
315 + (L3ModificationInstruction.ModIPv6FlowLabelInstruction) i;
316 + int flowLabel = flowLabelInstruction.flowLabel();
317 + oxm = factory.oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
298 break; 318 break;
299 case DEC_TTL: 319 case DEC_TTL:
300 return factory.actions().decNwTtl(); 320 return factory.actions().decNwTtl();
......
...@@ -117,13 +117,22 @@ public final class InstructionCodec extends JsonCodec<Instruction> { ...@@ -117,13 +117,22 @@ public final class InstructionCodec extends JsonCodec<Instruction> {
117 private void encodeL3(ObjectNode result, L3ModificationInstruction instruction) { 117 private void encodeL3(ObjectNode result, L3ModificationInstruction instruction) {
118 result.put("subtype", instruction.subtype().name()); 118 result.put("subtype", instruction.subtype().name());
119 switch (instruction.subtype()) { 119 switch (instruction.subtype()) {
120 - case IP_SRC: 120 + case IPV4_SRC:
121 - case IP_DST: 121 + case IPV4_DST:
122 + case IPV6_SRC:
123 + case IPV6_DST:
122 final L3ModificationInstruction.ModIPInstruction modIPInstruction = 124 final L3ModificationInstruction.ModIPInstruction modIPInstruction =
123 (L3ModificationInstruction.ModIPInstruction) instruction; 125 (L3ModificationInstruction.ModIPInstruction) instruction;
124 result.put("ip", modIPInstruction.ip().toString()); 126 result.put("ip", modIPInstruction.ip().toString());
125 break; 127 break;
126 128
129 + case IPV6_FLABEL:
130 + final L3ModificationInstruction.ModIPv6FlowLabelInstruction
131 + modFlowLabelInstruction =
132 + (L3ModificationInstruction.ModIPv6FlowLabelInstruction) instruction;
133 + result.put("flowLabel", modFlowLabelInstruction.flowLabel());
134 + break;
135 +
127 default: 136 default:
128 log.info("Cannot convert L3 subtype of {}", instruction.subtype()); 137 log.info("Cannot convert L3 subtype of {}", instruction.subtype());
129 break; 138 break;
......
...@@ -17,8 +17,8 @@ package org.onosproject.codec.impl; ...@@ -17,8 +17,8 @@ package org.onosproject.codec.impl;
17 17
18 import org.junit.Before; 18 import org.junit.Before;
19 import org.junit.Test; 19 import org.junit.Test;
20 -import org.onlab.packet.IpAddress; 20 +import org.onlab.packet.Ip4Address;
21 -import org.onlab.packet.IpPrefix; 21 +import org.onlab.packet.Ip6Address;
22 import org.onlab.packet.MacAddress; 22 import org.onlab.packet.MacAddress;
23 import org.onlab.packet.VlanId; 23 import org.onlab.packet.VlanId;
24 import org.onosproject.codec.CodecContext; 24 import org.onosproject.codec.CodecContext;
...@@ -144,11 +144,11 @@ public class InstructionCodecTest { ...@@ -144,11 +144,11 @@ public class InstructionCodecTest {
144 } 144 }
145 145
146 /** 146 /**
147 - * Tests the encoding of mod ip instructions. 147 + * Tests the encoding of mod IPv4 src instructions.
148 */ 148 */
149 @Test 149 @Test
150 - public void modIPInstructionTest() { 150 + public void modIPSrcInstructionTest() {
151 - final IpAddress ip = IpPrefix.valueOf("1.2.3.4/24").address(); 151 + final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
152 final L3ModificationInstruction.ModIPInstruction instruction = 152 final L3ModificationInstruction.ModIPInstruction instruction =
153 (L3ModificationInstruction.ModIPInstruction) 153 (L3ModificationInstruction.ModIPInstruction)
154 Instructions.modL3Src(ip); 154 Instructions.modL3Src(ip);
...@@ -158,6 +158,62 @@ public class InstructionCodecTest { ...@@ -158,6 +158,62 @@ public class InstructionCodecTest {
158 } 158 }
159 159
160 /** 160 /**
161 + * Tests the encoding of mod IPv4 dst instructions.
162 + */
163 + @Test
164 + public void modIPDstInstructionTest() {
165 + final Ip4Address ip = Ip4Address.valueOf("1.2.3.4");
166 + final L3ModificationInstruction.ModIPInstruction instruction =
167 + (L3ModificationInstruction.ModIPInstruction)
168 + Instructions.modL3Dst(ip);
169 + final ObjectNode instructionJson =
170 + instructionCodec.encode(instruction, context);
171 + assertThat(instructionJson, matchesInstruction(instruction));
172 + }
173 +
174 + /**
175 + * Tests the encoding of mod IPv6 src instructions.
176 + */
177 + @Test
178 + public void modIPv6SrcInstructionTest() {
179 + final Ip6Address ip = Ip6Address.valueOf("1111::2222");
180 + final L3ModificationInstruction.ModIPInstruction instruction =
181 + (L3ModificationInstruction.ModIPInstruction)
182 + Instructions.modL3IPv6Src(ip);
183 + final ObjectNode instructionJson =
184 + instructionCodec.encode(instruction, context);
185 + assertThat(instructionJson, matchesInstruction(instruction));
186 + }
187 +
188 + /**
189 + * Tests the encoding of mod IPv6 dst instructions.
190 + */
191 + @Test
192 + public void modIPv6DstInstructionTest() {
193 + final Ip6Address ip = Ip6Address.valueOf("1111::2222");
194 + final L3ModificationInstruction.ModIPInstruction instruction =
195 + (L3ModificationInstruction.ModIPInstruction)
196 + Instructions.modL3IPv6Dst(ip);
197 + final ObjectNode instructionJson =
198 + instructionCodec.encode(instruction, context);
199 + assertThat(instructionJson, matchesInstruction(instruction));
200 + }
201 +
202 + /**
203 + * Tests the encoding of mod IPv6 flow label instructions.
204 + */
205 + @Test
206 + public void modIPv6FlowLabelInstructionTest() {
207 + final int flowLabel = 0xfffff;
208 + final L3ModificationInstruction.ModIPv6FlowLabelInstruction instruction =
209 + (L3ModificationInstruction.ModIPv6FlowLabelInstruction)
210 + Instructions.modL3IPv6FlowLabel(flowLabel);
211 + final ObjectNode instructionJson =
212 + instructionCodec.encode(instruction, context);
213 + assertThat(instructionJson, matchesInstruction(instruction));
214 + }
215 +
216 + /**
161 * Tests the encoding of mod MPLS label instructions. 217 * Tests the encoding of mod MPLS label instructions.
162 */ 218 */
163 @Test 219 @Test
......
...@@ -41,6 +41,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -41,6 +41,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
41 * Matches the contents of a push header instruction. 41 * Matches the contents of a push header instruction.
42 * 42 *
43 * @param instructionJson JSON instruction to match 43 * @param instructionJson JSON instruction to match
44 + * @param description Description object used for recording errors
44 * @return true if contents match, false otherwise 45 * @return true if contents match, false otherwise
45 */ 46 */
46 private boolean matchPushHeaderInstruction(JsonNode instructionJson, 47 private boolean matchPushHeaderInstruction(JsonNode instructionJson,
...@@ -77,6 +78,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -77,6 +78,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
77 * Matches the contents of an output instruction. 78 * Matches the contents of an output instruction.
78 * 79 *
79 * @param instructionJson JSON instruction to match 80 * @param instructionJson JSON instruction to match
81 + * @param description Description object used for recording errors
80 * @return true if contents match, false otherwise 82 * @return true if contents match, false otherwise
81 */ 83 */
82 private boolean matchOutputInstruction(JsonNode instructionJson, 84 private boolean matchOutputInstruction(JsonNode instructionJson,
...@@ -102,6 +104,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -102,6 +104,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
102 * Matches the contents of a mod lambda instruction. 104 * Matches the contents of a mod lambda instruction.
103 * 105 *
104 * @param instructionJson JSON instruction to match 106 * @param instructionJson JSON instruction to match
107 + * @param description Description object used for recording errors
105 * @return true if contents match, false otherwise 108 * @return true if contents match, false otherwise
106 */ 109 */
107 private boolean matchModLambdaInstruction(JsonNode instructionJson, 110 private boolean matchModLambdaInstruction(JsonNode instructionJson,
...@@ -133,6 +136,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -133,6 +136,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
133 * Matches the contents of a mod Ethernet instruction. 136 * Matches the contents of a mod Ethernet instruction.
134 * 137 *
135 * @param instructionJson JSON instruction to match 138 * @param instructionJson JSON instruction to match
139 + * @param description Description object used for recording errors
136 * @return true if contents match, false otherwise 140 * @return true if contents match, false otherwise
137 */ 141 */
138 private boolean matchModEtherInstruction(JsonNode instructionJson, 142 private boolean matchModEtherInstruction(JsonNode instructionJson,
...@@ -165,6 +169,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -165,6 +169,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
165 * Matches the contents of a mod vlan id instruction. 169 * Matches the contents of a mod vlan id instruction.
166 * 170 *
167 * @param instructionJson JSON instruction to match 171 * @param instructionJson JSON instruction to match
172 + * @param description Description object used for recording errors
168 * @return true if contents match, false otherwise 173 * @return true if contents match, false otherwise
169 */ 174 */
170 private boolean matchModVlanIdInstruction(JsonNode instructionJson, 175 private boolean matchModVlanIdInstruction(JsonNode instructionJson,
...@@ -197,6 +202,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -197,6 +202,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
197 * Matches the contents of a mod vlan pcp instruction. 202 * Matches the contents of a mod vlan pcp instruction.
198 * 203 *
199 * @param instructionJson JSON instruction to match 204 * @param instructionJson JSON instruction to match
205 + * @param description Description object used for recording errors
200 * @return true if contents match, false otherwise 206 * @return true if contents match, false otherwise
201 */ 207 */
202 private boolean matchModVlanPcpInstruction(JsonNode instructionJson, 208 private boolean matchModVlanPcpInstruction(JsonNode instructionJson,
...@@ -229,6 +235,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -229,6 +235,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
229 * Matches the contents of a mod ip instruction. 235 * Matches the contents of a mod ip instruction.
230 * 236 *
231 * @param instructionJson JSON instruction to match 237 * @param instructionJson JSON instruction to match
238 + * @param description Description object used for recording errors
232 * @return true if contents match, false otherwise 239 * @return true if contents match, false otherwise
233 */ 240 */
234 private boolean matchModIpInstruction(JsonNode instructionJson, 241 private boolean matchModIpInstruction(JsonNode instructionJson,
...@@ -258,9 +265,43 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -258,9 +265,43 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
258 } 265 }
259 266
260 /** 267 /**
268 + * Matches the contents of a mod IPv6 Flow Label instruction.
269 + *
270 + * @param instructionJson JSON instruction to match
271 + * @param description Description object used for recording errors
272 + * @return true if contents match, false otherwise
273 + */
274 + private boolean matchModIPv6FlowLabelInstruction(JsonNode instructionJson,
275 + Description description) {
276 + ModIPv6FlowLabelInstruction instructionToMatch =
277 + (ModIPv6FlowLabelInstruction) instruction;
278 + final String jsonSubtype = instructionJson.get("subtype").textValue();
279 + if (!instructionToMatch.subtype().name().equals(jsonSubtype)) {
280 + description.appendText("subtype was " + jsonSubtype);
281 + return false;
282 + }
283 +
284 + final String jsonType = instructionJson.get("type").textValue();
285 + if (!instructionToMatch.type().name().equals(jsonType)) {
286 + description.appendText("type was " + jsonType);
287 + return false;
288 + }
289 +
290 + final int jsonFlowLabel = instructionJson.get("flowLabel").intValue();
291 + final int flowLabel = instructionToMatch.flowLabel();
292 + if (flowLabel != jsonFlowLabel) {
293 + description.appendText("IPv6 flow label was " + jsonFlowLabel);
294 + return false;
295 + }
296 +
297 + return true;
298 + }
299 +
300 + /**
261 * Matches the contents of a mod MPLS label instruction. 301 * Matches the contents of a mod MPLS label instruction.
262 * 302 *
263 * @param instructionJson JSON instruction to match 303 * @param instructionJson JSON instruction to match
304 + * @param description Description object used for recording errors
264 * @return true if contents match, false otherwise 305 * @return true if contents match, false otherwise
265 */ 306 */
266 private boolean matchModMplsLabelInstruction(JsonNode instructionJson, 307 private boolean matchModMplsLabelInstruction(JsonNode instructionJson,
...@@ -282,7 +323,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -282,7 +323,7 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
282 final int jsonLabel = instructionJson.get("label").intValue(); 323 final int jsonLabel = instructionJson.get("label").intValue();
283 final int label = instructionToMatch.label(); 324 final int label = instructionToMatch.label();
284 if (label != jsonLabel) { 325 if (label != jsonLabel) {
285 - description.appendText("ip was " + jsonLabel); 326 + description.appendText("MPLS label was " + jsonLabel);
286 return false; 327 return false;
287 } 328 }
288 329
...@@ -317,6 +358,9 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json ...@@ -317,6 +358,9 @@ public final class InstructionJsonMatcher extends TypeSafeDiagnosingMatcher<Json
317 return matchModVlanPcpInstruction(jsonInstruction, description); 358 return matchModVlanPcpInstruction(jsonInstruction, description);
318 } else if (instruction instanceof ModIPInstruction) { 359 } else if (instruction instanceof ModIPInstruction) {
319 return matchModIpInstruction(jsonInstruction, description); 360 return matchModIpInstruction(jsonInstruction, description);
361 + } else if (instruction instanceof ModIPv6FlowLabelInstruction) {
362 + return matchModIPv6FlowLabelInstruction(jsonInstruction,
363 + description);
320 } else if (instruction instanceof ModMplsLabelInstruction) { 364 } else if (instruction instanceof ModMplsLabelInstruction) {
321 return matchModMplsLabelInstruction(jsonInstruction, description); 365 return matchModMplsLabelInstruction(jsonInstruction, description);
322 } 366 }
......