3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension;
12 import java.net.Inet6Address;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import java.nio.ByteBuffer;
16 import java.util.Arrays;
18 import org.opendaylight.controller.sal.utils.HexEncode;
19 import org.opendaylight.controller.sal.utils.NetUtils;
20 import org.openflow.protocol.OFMatch;
21 import org.openflow.util.U16;
22 import org.openflow.util.U8;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * This Class forms the vendor specific IPv6 Flow Match messages as well as
28 * processes the vendor specific IPv6 Stats Reply message.
30 * For message creation, it parses the user entered IPv6 match fields, creates
31 * a sub-message for each field which are later used to form the complete
34 * For message processing, it parses the incoming message and reads each field
35 * of the message and stores in appropriate field of V6Match object.
39 public class V6Match extends OFMatch implements Cloneable {
40 private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
41 private static final long serialVersionUID = 1L;
42 protected Inet6Address nwSrc;
43 protected Inet6Address nwDst;
44 protected short inputPortMask;
45 protected byte[] dataLayerSourceMask;
46 protected byte[] dataLayerDestinationMask;
47 protected short dataLayerVirtualLanMask;
48 protected byte dataLayerVirtualLanPriorityCodePointMask;
49 protected short dataLayerTypeMask;
50 protected byte networkTypeOfServiceMask;
51 protected byte networkProtocolMask;
52 protected short transportSourceMask;
53 protected short transportDestinationMask;
54 protected short srcIPv6SubnetMaskbits;
55 protected short dstIPv6SubnetMaskbits;
57 protected MatchFieldState inputPortState;
58 protected MatchFieldState dlSourceState;
59 protected MatchFieldState dlDestState;
60 protected MatchFieldState dlVlanState;
61 protected MatchFieldState ethTypeState;
62 protected MatchFieldState nwTosState;
63 protected MatchFieldState nwProtoState;
64 protected MatchFieldState nwSrcState;
65 protected MatchFieldState nwDstState;
66 protected MatchFieldState tpSrcState;
67 protected MatchFieldState tpDstState;
68 protected short match_len = 0;
69 protected short pad_size = 0;
71 private static int IPV6_EXT_MIN_HDR_LEN = 36;
73 private enum MatchFieldState {
74 MATCH_ABSENT, MATCH_FIELD_ONLY, MATCH_FIELD_WITH_MASK
77 private enum OF_Match_Types {
78 MATCH_OF_IN_PORT(0), MATCH_OF_ETH_DST(1), MATCH_OF_ETH_SRC(2), MATCH_OF_ETH_TYPE(
79 3), MATCH_OF_VLAN_TCI(4), MATCH_OF_IP_TOS(5), MATCH_OF_IP_PROTO(
80 6), MATCH_OF_IP_SRC(7), MATCH_OF_IP_DST(8), MATCH_OF_TCP_SRC(9), MATCH_OF_TCP_DST(
81 10), MATCH_OF_UDP_SRC(11), MATCH_OF_UDP_DST(12), MATCH_OF_ICMTP_TYPE(
82 13), MATCH_OF_ICMP_CODE(14), MATCH_OF_ARP_OP(15);
86 private OF_Match_Types(int value) {
90 public int getValue() {
95 private enum IPv6Extension_Match_Types {
96 MATCH_IPV6EXT_TUN_ID(16), MATCH_IPV6EXT_ARP_SHA(17), MATCH_IPV6EXT_ARP_THA(
97 18), MATCH_IPV6EXT_IPV6_SRC(19), MATCH_IPV6EXT_IPV6_DST(20);
101 private IPv6Extension_Match_Types(int value) {
105 public int getValue() {
110 public enum Extension_Types {
111 OF_10(0), IPV6EXT(1);
115 private Extension_Types(int value) {
119 public int getValue() {
130 this.inputPortMask = 0;
131 this.dataLayerSourceMask = null;
132 this.dataLayerDestinationMask = null;
133 this.dataLayerTypeMask = 0;
134 this.dataLayerVirtualLanMask = 0;
135 this.dataLayerVirtualLanPriorityCodePointMask = 0;
136 this.networkTypeOfServiceMask = 0;
137 this.networkProtocolMask = 0;
138 this.transportSourceMask = 0;
139 this.transportDestinationMask = 0;
141 this.inputPortState = MatchFieldState.MATCH_ABSENT;
142 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
143 this.dlDestState = MatchFieldState.MATCH_ABSENT;
144 this.dlVlanState = MatchFieldState.MATCH_ABSENT;
145 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
146 this.nwTosState = MatchFieldState.MATCH_ABSENT;
147 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
148 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
149 this.nwDstState = MatchFieldState.MATCH_ABSENT;
150 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
151 this.tpDstState = MatchFieldState.MATCH_ABSENT;
157 public V6Match(OFMatch match) {
162 if (match.getNetworkSource() != 0) {
163 InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
164 InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
165 this.setNetworkDestination(address, mask);
167 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
170 if (match.getNetworkDestination() != 0) {
171 InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination());
172 InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false);
173 this.setNetworkDestination(address, mask);
175 this.nwDstState = MatchFieldState.MATCH_ABSENT;
178 this.inputPortMask = 0;
179 if (match.getInputPort() != 0) {
180 this.setInputPort(match.getInputPort(), (short) 0);
182 this.inputPortMask = 0;
183 this.inputPortState = MatchFieldState.MATCH_ABSENT;
186 this.dataLayerSourceMask = null;
187 if (match.getDataLayerSource() != null && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
188 this.setDataLayerSource(match.getDataLayerSource(), null);
190 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
192 this.dataLayerDestinationMask = null;
193 if (match.getDataLayerDestination() != null && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
194 this.setDataLayerDestination(match.getDataLayerDestination(), null);
196 this.dlDestState = MatchFieldState.MATCH_ABSENT;
199 this.dataLayerTypeMask = 0;
200 if (match.getDataLayerType() != 0) {
201 this.setDataLayerType(match.getDataLayerType(), (short) 0);
203 this.dataLayerType = 0;
204 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
207 this.dataLayerVirtualLanMask = 0;
208 if (match.getDataLayerVirtualLan() != 0) {
209 this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
212 this.dataLayerVirtualLan = 0;
213 this.dlVlanState = MatchFieldState.MATCH_ABSENT;
216 this.dataLayerVirtualLanPriorityCodePointMask = 0;
217 if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
218 this.setDataLayerVirtualLanPriorityCodePoint(match
219 .getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
221 this.dataLayerVirtualLanPriorityCodePoint = 0;
224 this.networkProtocolMask = 0;
225 if (match.getNetworkProtocol() != 0) {
226 this.setNetworkProtocol(this.networkProtocol = match
227 .getNetworkProtocol(), (byte) 0);
229 this.networkProtocol = 0;
230 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
233 this.networkTypeOfServiceMask = 0;
234 if (match.getNetworkTypeOfService() != 0) {
235 this.setNetworkTypeOfService(this.networkTypeOfService = match
236 .getNetworkTypeOfService(), (byte) 0);
238 this.networkTypeOfService = match.getNetworkTypeOfService();
239 this.nwTosState = MatchFieldState.MATCH_ABSENT;
242 this.transportSourceMask = 0;
243 if (match.getTransportSource() != 0) {
244 this.setTransportSource(match.getTransportSource(), (short) 0);
246 this.transportSource = 0;
247 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
250 this.transportDestinationMask = 0;
251 if (match.getTransportDestination() != 0) {
252 this.setTransportDestination(match.getTransportDestination(),
255 this.transportDestination = 0;
256 this.tpDstState = MatchFieldState.MATCH_ABSENT;
259 this.setWildcards(match.getWildcards());
262 private enum IPProtocols {
263 ICMP(1), TCP(6), UDP(17), ICMPV6(58);
265 private int protocol;
267 private IPProtocols(int value) {
268 this.protocol = value;
271 private byte getValue() {
272 return (byte) this.protocol;
276 public short getIPv6MatchLen() {
280 public int getIPv6ExtMinHdrLen() {
281 return IPV6_EXT_MIN_HDR_LEN;
284 public short getPadSize() {
285 return (short) (((match_len + 7) / 8) * 8 - match_len);
288 private int getIPv6ExtensionMatchHeader(Extension_Types extType, int field,
289 int has_mask, int length) {
290 return (((extType.getValue() & 0x0000ffff) << 16)
291 | ((field & 0x0000007f) << 9) | ((has_mask & 0x00000001) << 8) | (length & 0x000000ff));
294 private byte[] getIPv6ExtensionPortMatchMsg(short port) {
295 ByteBuffer ipv6ext_port_msg = ByteBuffer.allocate(6);
296 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
297 OF_Match_Types.MATCH_OF_IN_PORT.getValue(), 0, 2);
298 ipv6ext_port_msg.putInt(nxm_header);
299 ipv6ext_port_msg.putShort(port);
300 return (ipv6ext_port_msg.array());
303 private byte[] getIPv6ExtensionDestMacMatchMsg(byte[] destMac) {
304 ByteBuffer ipv6ext_destmac_msg = ByteBuffer.allocate(10);
305 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
306 OF_Match_Types.MATCH_OF_ETH_DST.getValue(), 0, 6);
307 ipv6ext_destmac_msg.putInt(nxm_header);
308 ipv6ext_destmac_msg.put(destMac);
309 return (ipv6ext_destmac_msg.array());
312 private byte[] getIPv6ExtensionSrcMacMatchMsg(byte[] srcMac) {
313 ByteBuffer ipv6ext_srcmac_msg = ByteBuffer.allocate(10);
314 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
315 OF_Match_Types.MATCH_OF_ETH_SRC.getValue(), 0, 6);
316 ipv6ext_srcmac_msg.putInt(nxm_header);
317 ipv6ext_srcmac_msg.put(srcMac);
318 return (ipv6ext_srcmac_msg.array());
321 private byte[] getIPv6ExtensionEtherTypeMatchMsg(short EtherType) {
322 ByteBuffer ipv6ext_etype_msg = ByteBuffer.allocate(6);
323 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
324 OF_Match_Types.MATCH_OF_ETH_TYPE.getValue(), 0, 2);
325 ipv6ext_etype_msg.putInt(nxm_header);
326 ipv6ext_etype_msg.putShort(EtherType);
327 return (ipv6ext_etype_msg.array());
330 private byte[] getIPv6ExtensionVlanIDMatchMsg(short VLAN) {
331 ByteBuffer ipv6ext_vlanid_msg = ByteBuffer.allocate(6);
332 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
333 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
334 ipv6ext_vlanid_msg.putInt(nxm_header);
335 ipv6ext_vlanid_msg.putShort(VLAN);
336 return (ipv6ext_vlanid_msg.array());
339 private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
340 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
341 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
342 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 0,
344 ipv6ext_ipv6_msg.putInt(nxm_header);
345 ipv6ext_ipv6_msg.put(srcIpv6);
346 return (ipv6ext_ipv6_msg.array());
349 private byte[] getIPv6ExtensionSrcIPv6MatchwithMaskMsg(byte[] srcIpv6,
351 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
352 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
353 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 1,
355 ipv6ext_ipv6_msg.putInt(nxm_header);
356 ipv6ext_ipv6_msg.put(srcIpv6);
357 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
358 ipv6ext_ipv6_msg.put(ipv6_mask);
359 return (ipv6ext_ipv6_msg.array());
362 private byte[] getIPv6ExtensionDstIPv6MatchMsg(byte[] dstIpv6) {
363 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
364 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
365 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 0,
367 ipv6ext_ipv6_msg.putInt(nxm_header);
368 ipv6ext_ipv6_msg.put(dstIpv6);
369 return (ipv6ext_ipv6_msg.array());
372 private byte[] getIPv6ExtensionDstIPv6MatchwithMaskMsg(byte[] dstIpv6,
374 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
375 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
376 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 1,
378 ipv6ext_ipv6_msg.putInt(nxm_header);
379 ipv6ext_ipv6_msg.put(dstIpv6);
380 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
381 ipv6ext_ipv6_msg.put(ipv6_mask);
382 return (ipv6ext_ipv6_msg.array());
385 private byte[] getIPv6ExtensionProtocolMatchMsg(byte protocol) {
386 ByteBuffer ipv6ext_proto_msg = ByteBuffer.allocate(5);
387 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
388 OF_Match_Types.MATCH_OF_IP_PROTO.getValue(), 0, 1);
392 ipv6ext_proto_msg.putInt(nxm_header);
393 if (protocol == IPProtocols.ICMP.getValue()) {
395 * The front end passes the same protocol type values for IPv4
396 * and IPv6 flows. For the Protocol types we allow in our GUI
397 * (ICMP, TCP, UDP), ICMP is the only one which is different for
398 * IPv6. It is 1 for v4 and 58 for v6 Therefore, we overwrite it
401 protocol = IPProtocols.ICMPV6.getValue();
403 ipv6ext_proto_msg.put(protocol);
404 return (ipv6ext_proto_msg.array());
407 private byte[] getIPv6ExtensionTOSMatchMsg(byte tos) {
408 ByteBuffer ipv6ext_tos_msg = ByteBuffer.allocate(5);
409 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
410 OF_Match_Types.MATCH_OF_IP_TOS.getValue(), 0, 1);
411 ipv6ext_tos_msg.putInt(nxm_header);
412 ipv6ext_tos_msg.put(tos);
413 return (ipv6ext_tos_msg.array());
416 private byte[] getIPv6ExtensionTCPSrcPortMatchMsg(short src_port) {
417 ByteBuffer ipv6ext_tcp_srcport_msg = ByteBuffer.allocate(6);
418 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
419 OF_Match_Types.MATCH_OF_TCP_SRC.getValue(), 0, 2);
420 ipv6ext_tcp_srcport_msg.putInt(nxm_header);
421 ipv6ext_tcp_srcport_msg.putShort(src_port);
422 return (ipv6ext_tcp_srcport_msg.array());
425 private byte[] getIPv6ExtensionTCPDstPortMatchMsg(short dst_port) {
426 ByteBuffer ipv6ext_tcp_dstport_msg = ByteBuffer.allocate(6);
427 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
428 OF_Match_Types.MATCH_OF_TCP_DST.getValue(), 0, 2);
429 ipv6ext_tcp_dstport_msg.putInt(nxm_header);
430 ipv6ext_tcp_dstport_msg.putShort(dst_port);
431 return (ipv6ext_tcp_dstport_msg.array());
434 private byte[] getIPv6ExtensionUDPSrcPortMatchMsg(short src_port) {
435 ByteBuffer ipv6ext_udp_srcport_msg = ByteBuffer.allocate(6);
436 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
437 OF_Match_Types.MATCH_OF_UDP_SRC.getValue(), 0, 2);
438 ipv6ext_udp_srcport_msg.putInt(nxm_header);
439 ipv6ext_udp_srcport_msg.putShort(src_port);
440 return (ipv6ext_udp_srcport_msg.array());
443 private byte[] getIPv6ExtensionUDPDstPortMatchMsg(short dst_port) {
444 ByteBuffer ipv6ext_udp_dstport_msg = ByteBuffer.allocate(6);
445 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
446 OF_Match_Types.MATCH_OF_UDP_DST.getValue(), 0, 2);
447 ipv6ext_udp_dstport_msg.putInt(nxm_header);
448 ipv6ext_udp_dstport_msg.putShort(dst_port);
449 return (ipv6ext_udp_dstport_msg.array());
453 * Sets this (V6Match) object's member variables based on a comma-separated key=value pair similar to OFMatch's fromString.
455 * @param match a key=value comma separated string.
458 public void fromString(String match) throws IllegalArgumentException {
459 if (match.equals("") || match.equalsIgnoreCase("any")
460 || match.equalsIgnoreCase("all") || match.equals("[]")) {
463 String[] tokens = match.split("[\\[,\\]]");
466 if (tokens[0].equals("OFMatch")) {
469 this.wildcards = OFPFW_ALL;
471 for (i = initArg; i < tokens.length; i++) {
472 values = tokens[i].split("=");
473 if (values.length != 2) {
474 throw new IllegalArgumentException("Token " + tokens[i]
475 + " does not have form 'key=value' parsing " + match);
477 values[0] = values[0].toLowerCase(); // try to make this case insens
478 if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
479 this.inputPort = U16.t(Integer.valueOf(values[1]));
480 inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
482 } else if (values[0].equals(STR_DL_DST)
483 || values[0].equals("eth_dst")) {
484 this.dataLayerDestination = HexEncode
485 .bytesFromHexString(values[1]);
486 dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
488 } else if (values[0].equals(STR_DL_SRC)
489 || values[0].equals("eth_src")) {
490 this.dataLayerSource = HexEncode.bytesFromHexString(values[1]);
491 dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
493 this.wildcards &= ~OFPFW_DL_SRC;
494 } else if (values[0].equals(STR_DL_TYPE)
495 || values[0].equals("eth_type")) {
496 if (values[1].startsWith("0x")) {
497 this.dataLayerType = U16.t(Integer.valueOf(values[1]
498 .replaceFirst("0x", ""), 16));
500 this.dataLayerType = U16.t(Integer.valueOf(values[1]));
502 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
504 } else if (values[0].equals(STR_DL_VLAN)) {
505 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
506 dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
508 } else if (values[0].equals(STR_DL_VLAN_PCP)) {
509 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
510 .valueOf(values[1]));
511 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
512 } else if (values[0].equals(STR_NW_DST)
513 || values[0].equals("ip_dst")) {
515 InetAddress address = null;
516 InetAddress mask = null;
517 if (values[1].contains("/")) {
518 String addressString[] = values[1].split("/");
519 address = InetAddress.getByName(addressString[0]);
520 int masklen = Integer.valueOf(addressString[1]);
521 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
523 address = InetAddress.getByName(values[1]);
525 this.setNetworkDestination(address, mask);
526 } catch (UnknownHostException e) {
529 } else if (values[0].equals(STR_NW_SRC)
530 || values[0].equals("ip_src")) {
532 InetAddress address = null;
533 InetAddress mask = null;
534 if (values[1].contains("/")) {
535 String addressString[] = values[1].split("/");
536 address = InetAddress.getByName(addressString[0]);
537 int masklen = Integer.valueOf(addressString[1]);
538 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
540 address = InetAddress.getByName(values[1]);
542 this.setNetworkSource(address, mask);
543 } catch (UnknownHostException e) {
546 } else if (values[0].equals(STR_NW_PROTO)) {
547 this.networkProtocol = U8.t(Short.valueOf(values[1]));
548 if (!(this.networkProtocol == 0)) {
550 * if user selects proto 0, don't use it
552 nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
555 } else if (values[0].equals(STR_NW_TOS)) {
556 this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
557 nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
559 } else if (values[0].equals(STR_TP_DST)) {
560 this.transportDestination = U16.t(Integer.valueOf(values[1]));
561 tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
563 } else if (values[0].equals(STR_TP_SRC)) {
564 this.transportSource = U16.t(Integer.valueOf(values[1]));
565 tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
568 throw new IllegalArgumentException("unknown token " + tokens[i]
569 + " parsing " + match);
574 * In a V6 extension message action list should be preceded by a padding of 0 to
575 * 7 bytes based upon following formula.
578 pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
583 * Write this message's binary format to the specified ByteBuffer
588 public void writeTo(ByteBuffer data) {
589 if (inputPortState == MatchFieldState.MATCH_FIELD_ONLY) {
590 byte[] ipv6ext_ingress_port_msg = getIPv6ExtensionPortMatchMsg(this.inputPort);
591 data.put(ipv6ext_ingress_port_msg);
593 if (ethTypeState == MatchFieldState.MATCH_FIELD_ONLY) {
594 byte[] ipv6ext_ether_type_msg = getIPv6ExtensionEtherTypeMatchMsg(this.dataLayerType);
595 data.put(ipv6ext_ether_type_msg);
597 if (dlDestState == MatchFieldState.MATCH_FIELD_ONLY) {
598 byte[] ipv6ext_destmac_msg = getIPv6ExtensionDestMacMatchMsg(this.dataLayerDestination);
599 data.put(ipv6ext_destmac_msg);
601 if (dlSourceState == MatchFieldState.MATCH_FIELD_ONLY) {
602 byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
603 data.put(ipv6ext_srcmac_msg);
605 if (dlVlanState == MatchFieldState.MATCH_FIELD_ONLY) {
606 byte[] ipv6ext_vlan_id_msg = getIPv6ExtensionVlanIDMatchMsg(this.dataLayerVirtualLan);
607 data.put(ipv6ext_vlan_id_msg);
609 if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
610 byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
612 data.put(ipv6ext_src_ipv6_msg);
613 } else if (nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
614 byte[] ipv6ext_src_ipv6_with_mask_msg = getIPv6ExtensionSrcIPv6MatchwithMaskMsg(
615 this.nwSrc.getAddress(), this.srcIPv6SubnetMaskbits);
616 data.put(ipv6ext_src_ipv6_with_mask_msg);
618 if (nwDstState == MatchFieldState.MATCH_FIELD_ONLY) {
619 byte[] ipv6ext_dst_ipv6_msg = getIPv6ExtensionDstIPv6MatchMsg(this.nwDst
621 data.put(ipv6ext_dst_ipv6_msg);
622 } else if (nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
623 byte[] ipv6ext_dst_ipv6_with_mask_msg = getIPv6ExtensionDstIPv6MatchwithMaskMsg(
624 this.nwDst.getAddress(), this.dstIPv6SubnetMaskbits);
625 data.put(ipv6ext_dst_ipv6_with_mask_msg);
627 if (nwProtoState == MatchFieldState.MATCH_FIELD_ONLY) {
628 byte[] ipv6ext_protocol_msg = getIPv6ExtensionProtocolMatchMsg(this.networkProtocol);
629 if (ipv6ext_protocol_msg != null) {
630 data.put(ipv6ext_protocol_msg);
633 if (nwTosState == MatchFieldState.MATCH_FIELD_ONLY) {
634 byte[] ipv6ext_tos_msg = getIPv6ExtensionTOSMatchMsg(this.networkTypeOfService);
635 data.put(ipv6ext_tos_msg);
637 if (tpSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
638 byte[] ipv6ext_srcport_msg = null;
639 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
640 ipv6ext_srcport_msg = getIPv6ExtensionTCPSrcPortMatchMsg(this.transportSource);
641 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
642 ipv6ext_srcport_msg = getIPv6ExtensionUDPSrcPortMatchMsg(this.transportSource);
644 if (ipv6ext_srcport_msg != null) {
645 data.put(ipv6ext_srcport_msg);
648 if (tpDstState == MatchFieldState.MATCH_FIELD_ONLY) {
649 byte[] ipv6ext_dstport_msg = null;
650 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
651 ipv6ext_dstport_msg = getIPv6ExtensionTCPDstPortMatchMsg(this.transportDestination);
652 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
653 ipv6ext_dstport_msg = getIPv6ExtensionUDPDstPortMatchMsg(this.transportDestination);
655 if (ipv6ext_dstport_msg != null) {
656 data.put(ipv6ext_dstport_msg);
659 logger.trace("{}", this);
662 private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
663 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
665 * mask is not allowed for inport port
669 super.setInputPort(data.getShort());
670 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
671 this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
675 private void readDataLinkDestination(ByteBuffer data, int nxmLen,
678 if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
681 byte[] bytes = new byte[6];
683 super.setDataLayerDestination(bytes);
684 this.dataLayerDestinationMask = new byte[6];
685 data.get(this.dataLayerDestinationMask);
686 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
687 this.match_len += 16;
690 if ((nxmLen != 6) || (data.remaining() < 6)) {
693 byte[] bytes = new byte[6];
695 super.setDataLayerDestination(bytes);
696 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
697 this.match_len += 10;
700 this.wildcards ^= (1 << 3); // Sync with 0F 1.0 Match
703 private void readDataLinkSource(ByteBuffer data, int nxmLen, boolean hasMask) {
705 * mask is not allowed in data link source
707 if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
710 byte[] bytes = new byte[6];
712 super.setDataLayerSource(bytes);
713 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
714 this.match_len += 10;
715 this.wildcards ^= (1 << 2); // Sync with 0F 1.0 Match
718 private void readEtherType(ByteBuffer data, int nxmLen, boolean hasMask) {
720 * mask is not allowed in ethertype
722 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
725 super.setDataLayerType(data.getShort());
726 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
727 this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
731 private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
732 short vlan_mask = 0xfff;
734 if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
737 short vlan = data.getShort();
739 super.setDataLayerVirtualLan(vlan);
740 this.dataLayerVirtualLanMask = data.getShort();
741 this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
743 this.wildcards ^= (1 << 20);
746 if ((nxmLen != 2) || (data.remaining() < 2)) {
749 short vlan = data.getShort();
751 super.setDataLayerVirtualLan(vlan);
752 this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
757 this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
760 private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
762 * mask is not allowed in IP TOS
764 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
767 super.setNetworkTypeOfService(data.get());
768 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
770 this.wildcards ^= (1 << 21); // Sync with 0F 1.0 Match
773 private void readIpProto(ByteBuffer data, int nxmLen, boolean hasMask) {
775 * mask is not allowed in IP protocol
777 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
780 super.setNetworkProtocol(data.get());
781 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
783 this.wildcards ^= (1 << 5); // Sync with 0F 1.0 Match
786 private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
788 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
791 byte[] sbytes = new byte[4];
793 // For compatibility, let's set the IPv4 in the parent OFMatch
794 int address = NetUtils.byteArray4ToInt(sbytes);
795 super.setNetworkSource(address);
796 byte[] mbytes = new byte[4];
798 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
799 this.match_len += 12;
800 int prefixlen = getNetworkMaskPrefixLength(mbytes);
801 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
802 this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
805 if ((nxmLen != 4) || (data.remaining() < 4)) {
808 byte[] sbytes = new byte[4];
810 // For compatibility, let's also set the IPv4 in the parent OFMatch
811 int address = NetUtils.byteArray4ToInt(sbytes);
812 super.setNetworkSource(address);
813 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
815 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
820 private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
822 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
825 byte[] dbytes = new byte[4];
827 // For compatibility, let's also set the IPv4 in the parent OFMatch
828 int address = NetUtils.byteArray4ToInt(dbytes);
829 super.setNetworkDestination(address);
830 byte[] mbytes = new byte[4];
832 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
833 this.match_len += 12;
834 int prefixlen = getNetworkMaskPrefixLength(mbytes);
835 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
836 this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
839 if ((nxmLen != 4) || (data.remaining() < 4)) {
842 byte[] dbytes = new byte[4];
844 int address = NetUtils.byteArray4ToInt(dbytes);
845 super.setNetworkDestination(address);
846 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
847 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
853 private void readTcpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
855 * mask is not allowed in TCP SRC
857 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
860 super.setTransportSource(data.getShort());
861 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
863 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
866 private void readTcpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
868 * mask is not allowed in TCP DST
870 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
873 super.setTransportDestination(data.getShort());
874 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
876 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
879 private void readUdpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
881 * mask is not allowed in UDP SRC
883 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
886 super.setTransportSource(data.getShort());
887 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
889 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
892 private void readUdpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
894 * mask is not allowed in UDP DST
896 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
899 super.setTransportDestination(data.getShort());
900 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
902 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
905 private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
907 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
910 byte[] sbytes = new byte[16];
913 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
914 } catch (UnknownHostException e) {
917 byte[] mbytes = new byte[16];
919 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
920 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
921 this.match_len += 36;
924 if ((nxmLen != 16) || (data.remaining() < 16)) {
927 byte[] sbytes = new byte[16];
930 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
931 } catch (UnknownHostException e) {
934 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
935 this.match_len += 20;
940 private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
942 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
945 byte[] dbytes = new byte[16];
948 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
949 } catch (UnknownHostException e) {
952 byte[] mbytes = new byte[16];
954 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
955 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
956 this.match_len += 36;
959 if ((nxmLen != 16) || (data.remaining() < 16)) {
962 byte[] dbytes = new byte[16];
965 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
966 } catch (UnknownHostException e) {
969 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
970 this.match_len += 20;
976 public String toString() {
977 return "V6Match [nwSrc=" + nwSrc + ", nwDst=" + nwDst
978 + ", inputPortMask=" + inputPortMask + ", dataLayerSourceMask="
979 + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
980 + ", dataLayerDestinationMask="
981 + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
982 + ", dataLayerVirtualLanMask=" + dataLayerVirtualLanMask
983 + ", dataLayerVirtualLanPriorityCodePointMask="
984 + dataLayerVirtualLanPriorityCodePointMask
985 + ", dataLayerTypeMask=" + dataLayerTypeMask
986 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
987 + ", networkProtocolMask=" + networkProtocolMask
988 + ", transportSourceMask=" + transportSourceMask
989 + ", transportDestinationMask=" + transportDestinationMask
990 + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
991 + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
992 + ", inputPortState=" + inputPortState + ", dlSourceState="
993 + dlSourceState + ", dlDestState=" + dlDestState
994 + ", dlVlanState=" + dlVlanState + ", ethTypeState="
995 + ethTypeState + ", nwTosState=" + nwTosState
996 + ", nwProtoState=" + nwProtoState + ", nwSrcState="
997 + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
998 + tpSrcState + ", tpDstState=" + tpDstState + ", match_len="
999 + match_len + ", pad_size=" + pad_size + "]";
1003 * Read the data corresponding to the match field (received from the wire)
1004 * Input: data: match field(s). Since match field is of variable length, the whole data that are passed in
1005 * are assumed to fem0tbd.be the match fields.
1009 public void readFrom(ByteBuffer data) {
1010 readFromInternal(data);
1011 postprocessWildCardInfo();
1014 private void readFromInternal(ByteBuffer data) {
1016 while (data.remaining() > 0) {
1017 if (data.remaining() < 4) {
1019 * at least 4 bytes for each match header
1021 logger.error("Invalid Vendor Extension Header. Size {}", data
1026 * read the 4 byte match header
1028 int nxmVendor = data.getShort();
1030 int nxmField = b >> 1;
1031 boolean hasMask = ((b & 0x01) == 1) ? true : false;
1032 int nxmLen = data.get();
1033 if (nxmVendor == Extension_Types.OF_10.getValue()) {
1034 if (nxmField == OF_Match_Types.MATCH_OF_IN_PORT.getValue()) {
1035 readInPort(data, nxmLen, hasMask);
1036 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_DST
1038 readDataLinkDestination(data, nxmLen, hasMask);
1039 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_SRC
1041 readDataLinkSource(data, nxmLen, hasMask);
1042 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_TYPE
1044 readEtherType(data, nxmLen, hasMask);
1045 } else if (nxmField == OF_Match_Types.MATCH_OF_VLAN_TCI
1047 readVlanTci(data, nxmLen, hasMask);
1048 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_TOS
1050 readIpTos(data, nxmLen, hasMask);
1051 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_PROTO
1053 readIpProto(data, nxmLen, hasMask);
1054 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_SRC
1056 readIpv4Src(data, nxmLen, hasMask);
1057 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_DST
1059 readIpv4Dst(data, nxmLen, hasMask);
1060 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_SRC
1062 readTcpSrc(data, nxmLen, hasMask);
1063 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_DST
1065 readTcpDst(data, nxmLen, hasMask);
1066 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_SRC
1068 readUdpSrc(data, nxmLen, hasMask);
1069 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_DST
1071 readUdpDst(data, nxmLen, hasMask);
1073 // unexpected nxmField
1076 } else if (nxmVendor == Extension_Types.IPV6EXT.getValue()) {
1077 if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC
1079 readIpv6Src(data, nxmLen, hasMask);
1080 } else if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST
1082 readIpv6Dst(data, nxmLen, hasMask);
1084 // unexpected nxmField
1088 // invalid nxmVendor
1094 private void postprocessWildCardInfo() {
1095 // Sync with 0F 1.0 Match
1096 if (super.getDataLayerType() == 0x800) {
1097 if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
1098 //ipv4 src processing
1099 this.wildcards ^= (((1 << 5) - 1) << 8);
1101 if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
1102 //ipv4 dest processing
1103 this.wildcards ^= (((1 << 5) - 1) << 14);
1111 public V6Match clone() {
1113 V6Match ret = (V6Match) super.clone();
1115 if (this.nwSrc != null) {
1116 ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
1118 if (this.nwDst != null) {
1119 ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
1122 } catch (UnknownHostException e) {
1123 throw new RuntimeException(e);
1133 public Inet6Address getNetworkDest() {
1143 public Inet6Address getNetworkSrc() {
1147 private int getNetworkMaskPrefixLength(byte[] netMask) {
1148 ByteBuffer nm = ByteBuffer.wrap(netMask);
1149 int trailingZeros = Integer.numberOfTrailingZeros(nm.getInt());
1150 return 32 - trailingZeros;
1153 public short getInputPortMask() {
1154 return inputPortMask;
1157 public void setInputPort(short port, short mask) {
1158 super.inputPort = port;
1159 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
1161 // Looks like mask is not allowed for input port. Will discard it
1164 public byte[] getDataLayerSourceMask() {
1165 return dataLayerSourceMask;
1168 public void setDataLayerSource(byte[] mac, byte[] mask) {
1170 System.arraycopy(mac, 0, super.dataLayerSource, 0, mac.length);
1173 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
1174 this.match_len += 10;
1176 if (this.dataLayerSourceMask == null) {
1177 this.dataLayerSourceMask = new byte[mask.length];
1179 System.arraycopy(mask, 0, this.dataLayerSourceMask, 0, mask.length);
1180 this.dlSourceState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1181 this.match_len += 16;
1185 public byte[] getDataLayerDestinationMask() {
1186 return dataLayerDestinationMask;
1189 public void setDataLayerDestination(byte[] mac, byte[] mask) {
1191 System.arraycopy(mac, 0, super.dataLayerDestination, 0, mac.length);
1194 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
1195 this.match_len += 10;
1197 if (this.dataLayerDestinationMask == null) {
1198 this.dataLayerDestinationMask = new byte[mask.length];
1200 System.arraycopy(mask, 0, this.dataLayerDestinationMask, 0,
1202 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1203 this.match_len += 16;
1207 public short getDataLayerVirtualLanMask() {
1208 return dataLayerVirtualLanMask;
1211 public void setDataLayerVirtualLan(short vlan, short mask) {
1212 super.dataLayerVirtualLan = vlan;
1214 this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
1215 this.match_len += 6;
1217 this.dataLayerVirtualLanMask = mask;
1218 this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1219 this.match_len += 8;
1223 public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
1224 super.dataLayerVirtualLanPriorityCodePoint = pcp;
1227 public void setDataLayerType(short ethType, short mask) {
1229 super.dataLayerType = ethType;
1230 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
1231 this.match_len += 6;
1234 public void setNetworkTypeOfService(byte tos, byte mask) {
1236 super.networkTypeOfService = tos;
1237 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
1241 public void setNetworkProtocol(byte ipProto, byte mask) {
1243 super.networkProtocol = ipProto;
1244 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
1245 this.match_len += 5;
1248 public Inet6Address getNetworkSourceMask() {
1249 return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1250 this.srcIPv6SubnetMaskbits, true) : null;
1253 public void setNetworkSource(InetAddress address, InetAddress mask) {
1254 if (address instanceof Inet6Address) {
1255 this.nwSrc = (Inet6Address) address;
1257 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1258 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1260 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1261 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1262 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1265 super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
1266 this.wildcards ^= (((1 << 6) - 1) << 8);
1268 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1269 this.match_len += 8;
1271 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1272 this.match_len += 12;
1273 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
1278 public Inet6Address getNetworkDestinationMask() {
1279 return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1280 this.dstIPv6SubnetMaskbits, true) : null;
1283 public void setNetworkDestination(InetAddress address, InetAddress mask) {
1284 if (address instanceof Inet6Address) {
1285 this.nwDst = (Inet6Address) address;
1287 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1288 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1290 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1291 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1292 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1295 this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
1296 this.wildcards ^= (((1 << 6) - 1) << 14);
1298 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1299 this.match_len += 8;
1301 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1302 this.match_len += 12;
1303 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
1308 public void setTransportSource(short tpSrc, short mask) {
1310 super.transportSource = tpSrc;
1311 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1312 this.match_len += 6;
1315 public short getTransportDestinationMask() {
1316 return transportDestinationMask;
1319 public void setTransportDestination(short tpDst, short mask) {
1321 super.transportDestination = tpDst;
1322 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1323 this.match_len += 6;
1326 private byte[] getIPv6NetworkMaskinBytes(short num) {
1327 byte[] nbytes = new byte[16];
1332 for (i = 0; i < quot; i++) {
1333 nbytes[i] = (byte) 0xff;
1337 nbytes[i] = (byte) 0xff;
1338 nbytes[i] <<= 8 - bits;
1344 public int hashCode() {
1345 final int prime = 31;
1346 int result = super.hashCode();
1347 result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
1348 result = prime * result + Arrays.hashCode(dataLayerSourceMask);
1349 result = prime * result + dataLayerTypeMask;
1350 result = prime * result + dataLayerVirtualLanMask;
1351 result = prime * result + dataLayerVirtualLanPriorityCodePointMask;
1352 result = prime * result + ((dlDestState == null) ? 0 : dlDestState.hashCode());
1353 result = prime * result + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
1354 result = prime * result + ((dlVlanState == null) ? 0 : dlVlanState.hashCode());
1355 result = prime * result + dstIPv6SubnetMaskbits;
1356 result = prime * result + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
1357 result = prime * result + inputPortMask;
1358 result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode());
1359 result = prime * result + match_len;
1360 result = prime * result + networkProtocolMask;
1361 result = prime * result + networkTypeOfServiceMask;
1362 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
1363 result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode());
1364 result = prime * result + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
1365 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
1366 result = prime * result + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
1367 result = prime * result + ((nwTosState == null) ? 0 : nwTosState.hashCode());
1368 result = prime * result + pad_size;
1369 result = prime * result + srcIPv6SubnetMaskbits;
1370 result = prime * result + ((tpDstState == null) ? 0 : tpDstState.hashCode());
1371 result = prime * result + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
1372 result = prime * result + transportDestinationMask;
1373 result = prime * result + transportSourceMask;
1378 public boolean equals(Object obj) {
1382 if (!super.equals(obj)) {
1385 if (getClass() != obj.getClass()) {
1388 V6Match other = (V6Match) obj;
1389 if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
1392 if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
1395 if (dataLayerTypeMask != other.dataLayerTypeMask) {
1398 if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) {
1401 if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) {
1404 if (dlDestState != other.dlDestState) {
1407 if (dlSourceState != other.dlSourceState) {
1410 if (dlVlanState != other.dlVlanState) {
1413 if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
1416 if (ethTypeState != other.ethTypeState) {
1419 if (inputPortMask != other.inputPortMask) {
1422 if (inputPortState != other.inputPortState) {
1425 if (match_len != other.match_len) {
1428 if (networkProtocolMask != other.networkProtocolMask) {
1431 if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
1434 if (nwDst == null) {
1435 if (other.nwDst != null) {
1438 } else if (!nwDst.equals(other.nwDst)) {
1441 if (nwDstState != other.nwDstState) {
1444 if (nwProtoState != other.nwProtoState) {
1447 if (nwSrc == null) {
1448 if (other.nwSrc != null) {
1451 } else if (!nwSrc.equals(other.nwSrc)) {
1454 if (nwSrcState != other.nwSrcState) {
1457 if (nwTosState != other.nwTosState) {
1460 if (pad_size != other.pad_size) {
1463 if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
1466 if (tpDstState != other.tpDstState) {
1469 if (tpSrcState != other.tpSrcState) {
1472 if (transportDestinationMask != other.transportDestinationMask) {
1475 if (transportSourceMask != other.transportSourceMask) {