Charles M.C. Chan
Committed by Pavlin Radoslavov

ONOS-509: Match IPV6_SRC, IPV6_DST criteria

* Following classes have been extended to match IPV6_SRC and IPV6_DST criteria:
    - Criteria
    - DefaultTrafficSelector
    - FlowEntryBuilder
    - FlowModBuilder

* Not included in this submission
    - Match of other IPv6-related criteria
    - Set of all IPv6-related criteria (action)

Change-Id: I115829a480356d2037e0fc809595f7a5eec25874
...@@ -184,6 +184,16 @@ public final class DefaultTrafficSelector implements TrafficSelector { ...@@ -184,6 +184,16 @@ public final class DefaultTrafficSelector implements TrafficSelector {
184 } 184 }
185 185
186 @Override 186 @Override
187 + public Builder matchIPv6Src(IpPrefix ip) {
188 + return add(Criteria.matchIPv6Src(ip));
189 + }
190 +
191 + @Override
192 + public Builder matchIPv6Dst(IpPrefix ip) {
193 + return add(Criteria.matchIPv6Dst(ip));
194 + }
195 +
196 + @Override
187 public Builder matchMplsLabel(Integer mplsLabel) { 197 public Builder matchMplsLabel(Integer mplsLabel) {
188 return add(Criteria.matchMplsLabel(mplsLabel)); 198 return add(Criteria.matchMplsLabel(mplsLabel));
189 } 199 }
......
...@@ -115,7 +115,7 @@ public interface TrafficSelector { ...@@ -115,7 +115,7 @@ public interface TrafficSelector {
115 public Builder matchIPProtocol(Byte proto); 115 public Builder matchIPProtocol(Byte proto);
116 116
117 /** 117 /**
118 - * Matches a l3 address. 118 + * Matches a l3 IPv4 address.
119 * 119 *
120 * @param ip a l3 address 120 * @param ip a l3 address
121 * @return a selection builder 121 * @return a selection builder
...@@ -123,7 +123,7 @@ public interface TrafficSelector { ...@@ -123,7 +123,7 @@ public interface TrafficSelector {
123 public Builder matchIPSrc(IpPrefix ip); 123 public Builder matchIPSrc(IpPrefix ip);
124 124
125 /** 125 /**
126 - * Matches a l3 address. 126 + * Matches a l3 IPv4 address.
127 * 127 *
128 * @param ip a l3 address 128 * @param ip a l3 address
129 * @return a selection builder 129 * @return a selection builder
...@@ -146,6 +146,21 @@ public interface TrafficSelector { ...@@ -146,6 +146,21 @@ public interface TrafficSelector {
146 */ 146 */
147 public Builder matchTcpDst(Short tcpPort); 147 public Builder matchTcpDst(Short tcpPort);
148 148
149 + /**
150 + * Matches a l3 IPv6 address.
151 + *
152 + * @param ip a l3 IPv6 address
153 + * @return a selection builder
154 + */
155 + public Builder matchIPv6Src(IpPrefix ip);
156 +
157 + /**
158 + * Matches a l3 IPv6 address.
159 + *
160 + * @param ip a l3 IPv6 address
161 + * @return a selection builder
162 + */
163 + public Builder matchIPv6Dst(IpPrefix ip);
149 164
150 /** 165 /**
151 * Matches on a MPLS label . 166 * Matches on a MPLS label .
......
...@@ -18,7 +18,6 @@ package org.onosproject.net.flow.criteria; ...@@ -18,7 +18,6 @@ package org.onosproject.net.flow.criteria;
18 import static com.google.common.base.MoreObjects.toStringHelper; 18 import static com.google.common.base.MoreObjects.toStringHelper;
19 19
20 import java.util.Objects; 20 import java.util.Objects;
21 -
22 import org.onosproject.net.PortNumber; 21 import org.onosproject.net.PortNumber;
23 import org.onosproject.net.flow.criteria.Criterion.Type; 22 import org.onosproject.net.flow.criteria.Criterion.Type;
24 import org.onlab.packet.IpPrefix; 23 import org.onlab.packet.IpPrefix;
...@@ -109,9 +108,9 @@ public final class Criteria { ...@@ -109,9 +108,9 @@ public final class Criteria {
109 } 108 }
110 109
111 /** 110 /**
112 - * Creates a match on IP source field using the specified value. 111 + * Creates a match on IPv4 source field using the specified value.
113 * 112 *
114 - * @param ip ip source value 113 + * @param ip ipv4 source value
115 * @return match criterion 114 * @return match criterion
116 */ 115 */
117 public static Criterion matchIPSrc(IpPrefix ip) { 116 public static Criterion matchIPSrc(IpPrefix ip) {
...@@ -119,9 +118,9 @@ public final class Criteria { ...@@ -119,9 +118,9 @@ public final class Criteria {
119 } 118 }
120 119
121 /** 120 /**
122 - * Creates a match on IP destination field using the specified value. 121 + * Creates a match on IPv4 destination field using the specified value.
123 * 122 *
124 - * @param ip ip source value 123 + * @param ip ipv4 source value
125 * @return match criterion 124 * @return match criterion
126 */ 125 */
127 public static Criterion matchIPDst(IpPrefix ip) { 126 public static Criterion matchIPDst(IpPrefix ip) {
...@@ -149,6 +148,26 @@ public final class Criteria { ...@@ -149,6 +148,26 @@ public final class Criteria {
149 } 148 }
150 149
151 /** 150 /**
151 + * Creates a match on IPv6 source field using the specified value.
152 + *
153 + * @param ip ipv6 source value
154 + * @return match criterion
155 + */
156 + public static Criterion matchIPv6Src(IpPrefix ip) {
157 + return new IPCriterion(ip, Type.IPV6_SRC);
158 + }
159 +
160 + /**
161 + * Creates a match on IPv6 destination field using the specified value.
162 + *
163 + * @param ip ipv6 source value
164 + * @return match criterion
165 + */
166 + public static Criterion matchIPv6Dst(IpPrefix ip) {
167 + return new IPCriterion(ip, Type.IPV6_DST);
168 + }
169 +
170 + /**
152 * Creates a match on MPLS label. 171 * Creates a match on MPLS label.
153 * @param mplsLabel MPLS label 172 * @param mplsLabel MPLS label
154 * @return match criterion 173 * @return match criterion
......
...@@ -129,6 +129,7 @@ public class DefaultTrafficSelectorTest { ...@@ -129,6 +129,7 @@ public class DefaultTrafficSelectorTest {
129 final short shortValue = 33; 129 final short shortValue = 33;
130 final byte byteValue = 44; 130 final byte byteValue = 44;
131 final IpPrefix ipPrefixValue = IpPrefix.valueOf("192.168.1.0/24"); 131 final IpPrefix ipPrefixValue = IpPrefix.valueOf("192.168.1.0/24");
132 + final IpPrefix ipv6PrefixValue = IpPrefix.valueOf("fe80::1/64");
132 133
133 selector = DefaultTrafficSelector.builder() 134 selector = DefaultTrafficSelector.builder()
134 .matchInport(PortNumber.portNumber(11)).build(); 135 .matchInport(PortNumber.portNumber(11)).build();
...@@ -175,6 +176,14 @@ public class DefaultTrafficSelectorTest { ...@@ -175,6 +176,14 @@ public class DefaultTrafficSelectorTest {
175 assertThat(selector, hasCriterionWithType(Type.TCP_DST)); 176 assertThat(selector, hasCriterionWithType(Type.TCP_DST));
176 177
177 selector = DefaultTrafficSelector.builder() 178 selector = DefaultTrafficSelector.builder()
179 + .matchIPv6Src(ipv6PrefixValue).build();
180 + assertThat(selector, hasCriterionWithType(Type.IPV6_SRC));
181 +
182 + selector = DefaultTrafficSelector.builder()
183 + .matchIPv6Dst(ipv6PrefixValue).build();
184 + assertThat(selector, hasCriterionWithType(Type.IPV6_DST));
185 +
186 + selector = DefaultTrafficSelector.builder()
178 .matchMplsLabel(3).build(); 187 .matchMplsLabel(3).build();
179 assertThat(selector, hasCriterionWithType(Type.MPLS_LABEL)); 188 assertThat(selector, hasCriterionWithType(Type.MPLS_LABEL));
180 189
......
...@@ -84,11 +84,18 @@ public class CriteriaTest { ...@@ -84,11 +84,18 @@ public class CriteriaTest {
84 84
85 private static final String IP1 = "1.2.3.4/24"; 85 private static final String IP1 = "1.2.3.4/24";
86 private static final String IP2 = "5.6.7.8/24"; 86 private static final String IP2 = "5.6.7.8/24";
87 + private static final String IPV61 = "fe80::1/64";
88 + private static final String IPV62 = "fc80::2/64";
87 private IpPrefix ip1 = IpPrefix.valueOf(IP1); 89 private IpPrefix ip1 = IpPrefix.valueOf(IP1);
88 private IpPrefix ip2 = IpPrefix.valueOf(IP2); 90 private IpPrefix ip2 = IpPrefix.valueOf(IP2);
91 + private IpPrefix ipv61 = IpPrefix.valueOf(IPV61);
92 + private IpPrefix ipv62 = IpPrefix.valueOf(IPV62);
89 Criterion matchIp1 = Criteria.matchIPSrc(ip1); 93 Criterion matchIp1 = Criteria.matchIPSrc(ip1);
90 Criterion sameAsMatchIp1 = Criteria.matchIPSrc(ip1); 94 Criterion sameAsMatchIp1 = Criteria.matchIPSrc(ip1);
91 Criterion matchIp2 = Criteria.matchIPSrc(ip2); 95 Criterion matchIp2 = Criteria.matchIPSrc(ip2);
96 + Criterion matchIpv61 = Criteria.matchIPSrc(ipv61);
97 + Criterion sameAsMatchIpv61 = Criteria.matchIPSrc(ipv61);
98 + Criterion matchIpv62 = Criteria.matchIPSrc(ipv62);
92 99
93 short lambda1 = 1; 100 short lambda1 = 1;
94 short lambda2 = 2; 101 short lambda2 = 2;
...@@ -384,6 +391,32 @@ public class CriteriaTest { ...@@ -384,6 +391,32 @@ public class CriteriaTest {
384 } 391 }
385 392
386 /** 393 /**
394 + * Test the matchIPSrc method.
395 + */
396 + @Test
397 + public void testMatchIPv6SrcMethod() {
398 + Criterion matchIpv6Src = Criteria.matchIPv6Src(ipv61);
399 + Criteria.IPCriterion ipCriterion =
400 + checkAndConvert(matchIpv6Src,
401 + Criterion.Type.IPV6_SRC,
402 + Criteria.IPCriterion.class);
403 + assertThat(ipCriterion.ip(), is(ipv61));
404 + }
405 +
406 + /**
407 + * Test the matchIPDst method.
408 + */
409 + @Test
410 + public void testMatchIPv6DstMethod() {
411 + Criterion matchIPv6Dst = Criteria.matchIPv6Dst(ipv61);
412 + Criteria.IPCriterion ipCriterion =
413 + checkAndConvert(matchIPv6Dst,
414 + Criterion.Type.IPV6_DST,
415 + Criteria.IPCriterion.class);
416 + assertThat(ipCriterion.ip(), is(equalTo(ipv61)));
417 + }
418 +
419 + /**
387 * Test the equals() method of the IpCriterion class. 420 * Test the equals() method of the IpCriterion class.
388 */ 421 */
389 @Test 422 @Test
...@@ -392,6 +425,11 @@ public class CriteriaTest { ...@@ -392,6 +425,11 @@ public class CriteriaTest {
392 .addEqualityGroup(matchIp1, sameAsMatchIp1) 425 .addEqualityGroup(matchIp1, sameAsMatchIp1)
393 .addEqualityGroup(matchIp2) 426 .addEqualityGroup(matchIp2)
394 .testEquals(); 427 .testEquals();
428 +
429 + new EqualsTester()
430 + .addEqualityGroup(matchIpv61, sameAsMatchIpv61)
431 + .addEqualityGroup(matchIpv62)
432 + .testEquals();
395 } 433 }
396 434
397 // LambdaCriterion class 435 // LambdaCriterion class
......
...@@ -21,6 +21,7 @@ import java.util.List; ...@@ -21,6 +21,7 @@ import java.util.List;
21 21
22 import org.onlab.packet.Ip4Address; 22 import org.onlab.packet.Ip4Address;
23 import org.onlab.packet.Ip4Prefix; 23 import org.onlab.packet.Ip4Prefix;
24 +import org.onlab.packet.Ip6Prefix;
24 import org.onlab.packet.MacAddress; 25 import org.onlab.packet.MacAddress;
25 import org.onlab.packet.VlanId; 26 import org.onlab.packet.VlanId;
26 import org.onosproject.net.DeviceId; 27 import org.onosproject.net.DeviceId;
...@@ -56,6 +57,7 @@ import org.projectfloodlight.openflow.protocol.match.MatchField; ...@@ -56,6 +57,7 @@ import org.projectfloodlight.openflow.protocol.match.MatchField;
56 import org.projectfloodlight.openflow.protocol.oxm.OFOxm; 57 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
57 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic; 58 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
58 import org.projectfloodlight.openflow.types.IPv4Address; 59 import org.projectfloodlight.openflow.types.IPv4Address;
60 +import org.projectfloodlight.openflow.types.IPv6Address;
59 import org.projectfloodlight.openflow.types.Masked; 61 import org.projectfloodlight.openflow.types.Masked;
60 import org.projectfloodlight.openflow.types.OFVlanVidMatch; 62 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
61 import org.projectfloodlight.openflow.types.VlanPcp; 63 import org.projectfloodlight.openflow.types.VlanPcp;
...@@ -398,6 +400,34 @@ public class FlowEntryBuilder { ...@@ -398,6 +400,34 @@ public class FlowEntryBuilder {
398 builder.matchOpticalSignalType(match.get(MatchField 400 builder.matchOpticalSignalType(match.get(MatchField
399 .OCH_SIGTYPE).getValue()); 401 .OCH_SIGTYPE).getValue());
400 break; 402 break;
403 + case IPV6_DST:
404 + Ip6Prefix dipv6;
405 + if (match.isPartiallyMasked(MatchField.IPV6_DST)) {
406 + Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_DST);
407 + dipv6 = Ip6Prefix.valueOf(
408 + maskedIp.getValue().getBytes(),
409 + maskedIp.getMask().asCidrMaskLength());
410 + } else {
411 + dipv6 = Ip6Prefix.valueOf(
412 + match.get(MatchField.IPV6_DST).getBytes(),
413 + Ip6Prefix.MAX_MASK_LENGTH);
414 + }
415 + builder.matchIPv6Dst(dipv6);
416 + break;
417 + case IPV6_SRC:
418 + Ip6Prefix sipv6;
419 + if (match.isPartiallyMasked(MatchField.IPV6_SRC)) {
420 + Masked<IPv6Address> maskedIp = match.getMasked(MatchField.IPV6_SRC);
421 + sipv6 = Ip6Prefix.valueOf(
422 + maskedIp.getValue().getBytes(),
423 + maskedIp.getMask().asCidrMaskLength());
424 + } else {
425 + sipv6 = Ip6Prefix.valueOf(
426 + match.get(MatchField.IPV6_SRC).getBytes(),
427 + Ip6Prefix.MAX_MASK_LENGTH);
428 + }
429 + builder.matchIPv6Src(sipv6);
430 + break;
401 case ARP_OP: 431 case ARP_OP:
402 case ARP_SHA: 432 case ARP_SHA:
403 case ARP_SPA: 433 case ARP_SPA:
...@@ -408,12 +438,10 @@ public class FlowEntryBuilder { ...@@ -408,12 +438,10 @@ public class FlowEntryBuilder {
408 case ICMPV6_CODE: 438 case ICMPV6_CODE:
409 case ICMPV6_TYPE: 439 case ICMPV6_TYPE:
410 case IN_PHY_PORT: 440 case IN_PHY_PORT:
411 - case IPV6_DST:
412 case IPV6_FLABEL: 441 case IPV6_FLABEL:
413 case IPV6_ND_SLL: 442 case IPV6_ND_SLL:
414 case IPV6_ND_TARGET: 443 case IPV6_ND_TARGET:
415 case IPV6_ND_TLL: 444 case IPV6_ND_TLL:
416 - case IPV6_SRC:
417 case IP_DSCP: 445 case IP_DSCP:
418 case IP_ECN: 446 case IP_ECN:
419 case METADATA: 447 case METADATA:
...@@ -425,8 +453,6 @@ public class FlowEntryBuilder { ...@@ -425,8 +453,6 @@ public class FlowEntryBuilder {
425 case UDP_SRC: 453 case UDP_SRC:
426 default: 454 default:
427 log.warn("Match type {} not yet implemented.", field.id); 455 log.warn("Match type {} not yet implemented.", field.id);
428 -
429 -
430 } 456 }
431 } 457 }
432 return builder.build(); 458 return builder.build();
......
...@@ -17,6 +17,8 @@ package org.onosproject.provider.of.flow.impl; ...@@ -17,6 +17,8 @@ package org.onosproject.provider.of.flow.impl;
17 17
18 import static org.slf4j.LoggerFactory.getLogger; 18 import static org.slf4j.LoggerFactory.getLogger;
19 19
20 +import org.onlab.packet.Ip6Address;
21 +import org.onlab.packet.Ip6Prefix;
20 import org.onosproject.net.flow.FlowRule; 22 import org.onosproject.net.flow.FlowRule;
21 import org.onosproject.net.flow.TrafficSelector; 23 import org.onosproject.net.flow.TrafficSelector;
22 import org.onosproject.net.flow.criteria.Criteria; 24 import org.onosproject.net.flow.criteria.Criteria;
...@@ -41,6 +43,7 @@ import org.projectfloodlight.openflow.protocol.match.MatchField; ...@@ -41,6 +43,7 @@ import org.projectfloodlight.openflow.protocol.match.MatchField;
41 import org.projectfloodlight.openflow.types.CircuitSignalID; 43 import org.projectfloodlight.openflow.types.CircuitSignalID;
42 import org.projectfloodlight.openflow.types.EthType; 44 import org.projectfloodlight.openflow.types.EthType;
43 import org.projectfloodlight.openflow.types.IPv4Address; 45 import org.projectfloodlight.openflow.types.IPv4Address;
46 +import org.projectfloodlight.openflow.types.IPv6Address;
44 import org.projectfloodlight.openflow.types.IpProtocol; 47 import org.projectfloodlight.openflow.types.IpProtocol;
45 import org.projectfloodlight.openflow.types.MacAddress; 48 import org.projectfloodlight.openflow.types.MacAddress;
46 import org.projectfloodlight.openflow.types.Masked; 49 import org.projectfloodlight.openflow.types.Masked;
...@@ -134,6 +137,7 @@ public abstract class FlowModBuilder { ...@@ -134,6 +137,7 @@ public abstract class FlowModBuilder {
134 EthCriterion eth; 137 EthCriterion eth;
135 IPCriterion ip; 138 IPCriterion ip;
136 Ip4Prefix ip4Prefix; 139 Ip4Prefix ip4Prefix;
140 + Ip6Prefix ip6Prefix;
137 TcpPortCriterion tp; 141 TcpPortCriterion tp;
138 for (Criterion c : selector.criteria()) { 142 for (Criterion c : selector.criteria()) {
139 switch (c.type()) { 143 switch (c.type()) {
...@@ -220,6 +224,36 @@ public abstract class FlowModBuilder { ...@@ -220,6 +224,36 @@ public abstract class FlowModBuilder {
220 mBuilder.setExact(MatchField.OCH_SIGTYPE, 224 mBuilder.setExact(MatchField.OCH_SIGTYPE,
221 U8.of(sc.signalType())); 225 U8.of(sc.signalType()));
222 break; 226 break;
227 + case IPV6_DST:
228 + ip = (IPCriterion) c;
229 + ip6Prefix = ip.ip().getIp6Prefix();
230 + if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
231 + Ip6Address maskAddr =
232 + Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
233 + Masked<IPv6Address> maskedIp =
234 + Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
235 + IPv6Address.of(maskAddr.toString()));
236 + mBuilder.setMasked(MatchField.IPV6_DST, maskedIp);
237 + } else {
238 + mBuilder.setExact(MatchField.IPV6_DST,
239 + IPv6Address.of(ip6Prefix.address().toString()));
240 + }
241 + break;
242 + case IPV6_SRC:
243 + ip = (IPCriterion) c;
244 + ip6Prefix = ip.ip().getIp6Prefix();
245 + if (ip6Prefix.prefixLength() != Ip6Prefix.MAX_MASK_LENGTH) {
246 + Ip6Address maskAddr =
247 + Ip6Address.makeMaskPrefix(ip6Prefix.prefixLength());
248 + Masked<IPv6Address> maskedIp =
249 + Masked.of(IPv6Address.of(ip6Prefix.address().toString()),
250 + IPv6Address.of(maskAddr.toString()));
251 + mBuilder.setMasked(MatchField.IPV6_SRC, maskedIp);
252 + } else {
253 + mBuilder.setExact(MatchField.IPV6_SRC,
254 + IPv6Address.of(ip6Prefix.address().toString()));
255 + }
256 + break;
223 case ARP_OP: 257 case ARP_OP:
224 case ARP_SHA: 258 case ARP_SHA:
225 case ARP_SPA: 259 case ARP_SPA:
...@@ -230,13 +264,11 @@ public abstract class FlowModBuilder { ...@@ -230,13 +264,11 @@ public abstract class FlowModBuilder {
230 case ICMPV6_CODE: 264 case ICMPV6_CODE:
231 case ICMPV6_TYPE: 265 case ICMPV6_TYPE:
232 case IN_PHY_PORT: 266 case IN_PHY_PORT:
233 - case IPV6_DST:
234 case IPV6_EXTHDR: 267 case IPV6_EXTHDR:
235 case IPV6_FLABEL: 268 case IPV6_FLABEL:
236 case IPV6_ND_SLL: 269 case IPV6_ND_SLL:
237 case IPV6_ND_TARGET: 270 case IPV6_ND_TARGET:
238 case IPV6_ND_TLL: 271 case IPV6_ND_TLL:
239 - case IPV6_SRC:
240 case IP_DSCP: 272 case IP_DSCP:
241 case IP_ECN: 273 case IP_ECN:
242 case METADATA: 274 case METADATA:
......