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.openflow.protocol.OFMatch;
20 import org.openflow.util.U16;
21 import org.openflow.util.U8;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
26 * This Class forms the vendor specific IPv6 Flow Match messages as well as
27 * processes the vendor specific IPv6 Stats Reply message.
29 * For message creation, it parses the user entered IPv6 match fields, creates
30 * a sub-message for each field which are later used to form the complete
33 * For message processing, it parses the incoming message and reads each field
34 * of the message and stores in appropriate field of V6Match object.
38 public class V6Match extends OFMatch implements Cloneable {
39 private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
40 private static final long serialVersionUID = 1L;
41 protected InetAddress nwSrc;
42 protected InetAddress nwDst;
43 protected short inputPortMask;
44 protected byte[] dataLayerSourceMask;
45 protected byte[] dataLayerDestinationMask;
46 protected short dataLayerVirtualLanMask;
47 protected byte dataLayerVirtualLanPriorityCodePointMask;
48 protected short dataLayerTypeMask;
49 protected byte networkTypeOfServiceMask;
50 protected byte networkProtocolMask;
51 protected InetAddress networkSourceMask;
52 protected InetAddress networkDestinationMask;
53 protected short transportSourceMask;
54 protected short transportDestinationMask;
55 protected short srcIPv6SubnetMaskbits;
56 protected short dstIPv6SubnetMaskbits;
58 protected MatchFieldState inputPortState;
59 protected MatchFieldState dlSourceState;
60 protected MatchFieldState dlDestState;
61 protected MatchFieldState dlVlanState;
62 protected MatchFieldState ethTypeState;
63 protected MatchFieldState nwTosState;
64 protected MatchFieldState nwProtoState;
65 protected MatchFieldState nwSrcState;
66 protected MatchFieldState nwDstState;
67 protected MatchFieldState tpSrcState;
68 protected MatchFieldState tpDstState;
69 protected short match_len = 0;
70 protected short pad_size = 0;
72 private static int IPV6_EXT_MIN_HDR_LEN = 36;
74 private enum MatchFieldState {
75 MATCH_ABSENT, MATCH_FIELD_ONLY, MATCH_FIELD_WITH_MASK
78 private enum OF_Match_Types {
79 MATCH_OF_IN_PORT(0), MATCH_OF_ETH_DST(1), MATCH_OF_ETH_SRC(2), MATCH_OF_ETH_TYPE(
80 3), MATCH_OF_VLAN_TCI(4), MATCH_OF_IP_TOS(5), MATCH_OF_IP_PROTO(
81 6), MATCH_OF_IP_SRC(7), MATCH_OF_IP_DST(8), MATCH_OF_TCP_SRC(9), MATCH_OF_TCP_DST(
82 10), MATCH_OF_UDP_SRC(11), MATCH_OF_UDP_DST(12), MATCH_OF_ICMTP_TYPE(
83 13), MATCH_OF_ICMP_CODE(14), MATCH_OF_ARP_OP(15);
87 private OF_Match_Types(int value) {
91 public int getValue() {
96 private enum IPv6Extension_Match_Types {
97 MATCH_IPV6EXT_TUN_ID(16), MATCH_IPV6EXT_ARP_SHA(17), MATCH_IPV6EXT_ARP_THA(
98 18), MATCH_IPV6EXT_IPV6_SRC(19), MATCH_IPV6EXT_IPV6_DST(20);
102 private IPv6Extension_Match_Types(int value) {
106 public int getValue() {
111 public enum Extension_Types {
112 OF_10(0), IPV6EXT(1);
116 private Extension_Types(int value) {
120 public int getValue() {
131 this.inputPortMask = 0;
132 this.dataLayerSourceMask = null;
133 this.dataLayerDestinationMask = null;
134 this.dataLayerTypeMask = 0;
135 this.dataLayerVirtualLanMask = 0;
136 this.dataLayerVirtualLanPriorityCodePointMask = 0;
137 this.networkDestinationMask = null;
138 this.networkSourceMask = null;
139 this.networkTypeOfServiceMask = 0;
140 this.networkProtocolMask = 0;
141 this.transportSourceMask = 0;
142 this.transportDestinationMask = 0;
144 this.inputPortState = MatchFieldState.MATCH_ABSENT;
145 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
146 this.dlDestState = MatchFieldState.MATCH_ABSENT;
147 this.dlVlanState = MatchFieldState.MATCH_ABSENT;
148 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
149 this.nwTosState = MatchFieldState.MATCH_ABSENT;
150 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
151 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
152 this.nwDstState = MatchFieldState.MATCH_ABSENT;
153 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
154 this.tpDstState = MatchFieldState.MATCH_ABSENT;
160 public V6Match(OFMatch match) {
165 this.networkSourceMask = null;
166 if (match.getNetworkSource() != 0) {
167 InetAddress address = null;
169 address = InetAddress.getByAddress(ByteBuffer.allocate(4)
170 .putInt(match.getNetworkSource()).array());
171 } catch (UnknownHostException e) {
174 this.setNetworkSource(address, null);
177 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
180 this.networkDestinationMask = null;
181 if (match.getNetworkDestination() != 0) {
182 InetAddress address = null;
184 address = InetAddress.getByAddress(ByteBuffer.allocate(4)
185 .putInt(match.getNetworkDestination()).array());
186 } catch (UnknownHostException e) {
189 this.setNetworkDestination(address, null);
192 this.nwDstState = MatchFieldState.MATCH_ABSENT;
195 this.inputPortMask = 0;
196 if (match.getInputPort() != 0) {
197 this.setInputPort(match.getInputPort(), (short) 0);
199 this.inputPortMask = 0;
200 this.inputPortState = MatchFieldState.MATCH_ABSENT;
203 this.dataLayerSourceMask = null;
204 if (match.getDataLayerSource() != null) {
205 this.setDataLayerSource(match.getDataLayerSource(), null);
207 this.dataLayerSource = null;
208 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
210 this.dataLayerDestinationMask = null;
211 if (match.getDataLayerDestination() != null) {
212 this.setDataLayerDestination(match.getDataLayerDestination(), null);
214 this.dataLayerDestination = null;
215 this.dlDestState = MatchFieldState.MATCH_ABSENT;
218 this.dataLayerTypeMask = 0;
219 if (match.getDataLayerType() != 0) {
220 this.setDataLayerType(match.getDataLayerType(), (short) 0);
222 this.dataLayerType = 0;
223 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
226 this.dataLayerVirtualLanMask = 0;
227 if (match.getDataLayerVirtualLan() != 0) {
228 this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
231 this.dataLayerVirtualLan = 0;
232 this.dlVlanState = MatchFieldState.MATCH_ABSENT;
235 this.dataLayerVirtualLanPriorityCodePointMask = 0;
236 if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
237 this.setDataLayerVirtualLanPriorityCodePoint(match
238 .getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
240 this.dataLayerVirtualLanPriorityCodePoint = 0;
243 this.networkProtocolMask = 0;
244 if (match.getNetworkProtocol() != 0) {
245 this.setNetworkProtocol(this.networkProtocol = match
246 .getNetworkProtocol(), (byte) 0);
248 this.networkProtocol = 0;
249 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
252 this.networkTypeOfServiceMask = 0;
253 if (match.getNetworkTypeOfService() != 0) {
254 this.setNetworkTypeOfService(this.networkTypeOfService = match
255 .getNetworkTypeOfService(), (byte) 0);
257 this.networkTypeOfService = match.getNetworkTypeOfService();
258 this.nwTosState = MatchFieldState.MATCH_ABSENT;
261 this.transportSourceMask = 0;
262 if (match.getTransportSource() != 0) {
263 this.setTransportSource(match.getTransportSource(), (short) 0);
265 this.transportSource = 0;
266 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
269 this.transportDestinationMask = 0;
270 if (match.getTransportDestination() != 0) {
271 this.setTransportDestination(match.getTransportDestination(),
274 this.transportDestination = 0;
275 this.tpDstState = MatchFieldState.MATCH_ABSENT;
278 this.setWildcards(match.getWildcards());
281 private enum IPProtocols {
282 ICMP(1), TCP(6), UDP(17), ICMPV6(58);
284 private int protocol;
286 private IPProtocols(int value) {
287 this.protocol = value;
290 private byte getValue() {
291 return (byte) this.protocol;
295 public short getIPv6MatchLen() {
299 public int getIPv6ExtMinHdrLen() {
300 return IPV6_EXT_MIN_HDR_LEN;
303 public short getPadSize() {
304 return (short) (((match_len + 7) / 8) * 8 - match_len);
307 private int getIPv6ExtensionMatchHeader(Extension_Types extType, int field,
308 int has_mask, int length) {
309 return (((extType.getValue() & 0x0000ffff) << 16)
310 | ((field & 0x0000007f) << 9) | ((has_mask & 0x00000001) << 8) | (length & 0x000000ff));
313 private byte[] getIPv6ExtensionPortMatchMsg(short port) {
314 ByteBuffer ipv6ext_port_msg = ByteBuffer.allocate(6);
315 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
316 OF_Match_Types.MATCH_OF_IN_PORT.getValue(), 0, 2);
317 ipv6ext_port_msg.putInt(nxm_header);
318 ipv6ext_port_msg.putShort(port);
319 return (ipv6ext_port_msg.array());
322 private byte[] getIPv6ExtensionDestMacMatchMsg(byte[] destMac) {
323 ByteBuffer ipv6ext_destmac_msg = ByteBuffer.allocate(10);
324 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
325 OF_Match_Types.MATCH_OF_ETH_DST.getValue(), 0, 6);
326 ipv6ext_destmac_msg.putInt(nxm_header);
327 ipv6ext_destmac_msg.put(destMac);
328 return (ipv6ext_destmac_msg.array());
331 private byte[] getIPv6ExtensionSrcMacMatchMsg(byte[] srcMac) {
332 ByteBuffer ipv6ext_srcmac_msg = ByteBuffer.allocate(10);
333 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
334 OF_Match_Types.MATCH_OF_ETH_SRC.getValue(), 0, 6);
335 ipv6ext_srcmac_msg.putInt(nxm_header);
336 ipv6ext_srcmac_msg.put(srcMac);
337 return (ipv6ext_srcmac_msg.array());
340 private byte[] getIPv6ExtensionEtherTypeMatchMsg(short EtherType) {
341 ByteBuffer ipv6ext_etype_msg = ByteBuffer.allocate(6);
342 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
343 OF_Match_Types.MATCH_OF_ETH_TYPE.getValue(), 0, 2);
344 ipv6ext_etype_msg.putInt(nxm_header);
345 ipv6ext_etype_msg.putShort(EtherType);
346 return (ipv6ext_etype_msg.array());
349 private byte[] getIPv6ExtensionVlanIDMatchMsg(short VLAN) {
350 ByteBuffer ipv6ext_vlanid_msg = ByteBuffer.allocate(6);
351 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
352 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
353 ipv6ext_vlanid_msg.putInt(nxm_header);
354 ipv6ext_vlanid_msg.putShort(VLAN);
355 return (ipv6ext_vlanid_msg.array());
358 private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
359 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
360 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
361 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 0,
363 ipv6ext_ipv6_msg.putInt(nxm_header);
364 ipv6ext_ipv6_msg.put(srcIpv6);
365 return (ipv6ext_ipv6_msg.array());
368 private byte[] getIPv6ExtensionSrcIPv6MatchwithMaskMsg(byte[] srcIpv6,
370 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
371 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
372 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 1,
374 ipv6ext_ipv6_msg.putInt(nxm_header);
375 ipv6ext_ipv6_msg.put(srcIpv6);
376 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
377 ipv6ext_ipv6_msg.put(ipv6_mask);
378 return (ipv6ext_ipv6_msg.array());
381 private byte[] getIPv6ExtensionDstIPv6MatchMsg(byte[] dstIpv6) {
382 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
383 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
384 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 0,
386 ipv6ext_ipv6_msg.putInt(nxm_header);
387 ipv6ext_ipv6_msg.put(dstIpv6);
388 return (ipv6ext_ipv6_msg.array());
391 private byte[] getIPv6ExtensionDstIPv6MatchwithMaskMsg(byte[] dstIpv6,
393 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
394 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
395 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 1,
397 ipv6ext_ipv6_msg.putInt(nxm_header);
398 ipv6ext_ipv6_msg.put(dstIpv6);
399 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
400 ipv6ext_ipv6_msg.put(ipv6_mask);
401 return (ipv6ext_ipv6_msg.array());
404 private byte[] getIPv6ExtensionProtocolMatchMsg(byte protocol) {
405 ByteBuffer ipv6ext_proto_msg = ByteBuffer.allocate(5);
406 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
407 OF_Match_Types.MATCH_OF_IP_PROTO.getValue(), 0, 1);
411 ipv6ext_proto_msg.putInt(nxm_header);
412 if (protocol == IPProtocols.ICMP.getValue()) {
414 * The front end passes the same protocol type values for IPv4
415 * and IPv6 flows. For the Protocol types we allow in our GUI
416 * (ICMP, TCP, UDP), ICMP is the only one which is different for
417 * IPv6. It is 1 for v4 and 58 for v6 Therefore, we overwrite it
420 protocol = IPProtocols.ICMPV6.getValue();
422 ipv6ext_proto_msg.put(protocol);
423 return (ipv6ext_proto_msg.array());
426 private byte[] getIPv6ExtensionTOSMatchMsg(byte tos) {
427 ByteBuffer ipv6ext_tos_msg = ByteBuffer.allocate(5);
428 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
429 OF_Match_Types.MATCH_OF_IP_TOS.getValue(), 0, 1);
430 ipv6ext_tos_msg.putInt(nxm_header);
431 ipv6ext_tos_msg.put(tos);
432 return (ipv6ext_tos_msg.array());
435 private byte[] getIPv6ExtensionTCPSrcPortMatchMsg(short src_port) {
436 ByteBuffer ipv6ext_tcp_srcport_msg = ByteBuffer.allocate(6);
437 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
438 OF_Match_Types.MATCH_OF_TCP_SRC.getValue(), 0, 2);
439 ipv6ext_tcp_srcport_msg.putInt(nxm_header);
440 ipv6ext_tcp_srcport_msg.putShort(src_port);
441 return (ipv6ext_tcp_srcport_msg.array());
444 private byte[] getIPv6ExtensionTCPDstPortMatchMsg(short dst_port) {
445 ByteBuffer ipv6ext_tcp_dstport_msg = ByteBuffer.allocate(6);
446 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
447 OF_Match_Types.MATCH_OF_TCP_DST.getValue(), 0, 2);
448 ipv6ext_tcp_dstport_msg.putInt(nxm_header);
449 ipv6ext_tcp_dstport_msg.putShort(dst_port);
450 return (ipv6ext_tcp_dstport_msg.array());
453 private byte[] getIPv6ExtensionUDPSrcPortMatchMsg(short src_port) {
454 ByteBuffer ipv6ext_udp_srcport_msg = ByteBuffer.allocate(6);
455 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
456 OF_Match_Types.MATCH_OF_UDP_SRC.getValue(), 0, 2);
457 ipv6ext_udp_srcport_msg.putInt(nxm_header);
458 ipv6ext_udp_srcport_msg.putShort(src_port);
459 return (ipv6ext_udp_srcport_msg.array());
462 private byte[] getIPv6ExtensionUDPDstPortMatchMsg(short dst_port) {
463 ByteBuffer ipv6ext_udp_dstport_msg = ByteBuffer.allocate(6);
464 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
465 OF_Match_Types.MATCH_OF_UDP_DST.getValue(), 0, 2);
466 ipv6ext_udp_dstport_msg.putInt(nxm_header);
467 ipv6ext_udp_dstport_msg.putShort(dst_port);
468 return (ipv6ext_udp_dstport_msg.array());
472 * Sets this (V6Match) object's member variables based on a comma-separated key=value pair similar to OFMatch's fromString.
474 * @param match a key=value comma separated string.
477 public void fromString(String match) throws IllegalArgumentException {
478 if (match.equals("") || match.equalsIgnoreCase("any")
479 || match.equalsIgnoreCase("all") || match.equals("[]"))
481 String[] tokens = match.split("[\\[,\\]]");
484 if (tokens[0].equals("OFMatch"))
486 this.wildcards = OFPFW_ALL;
488 for (i = initArg; i < tokens.length; i++) {
489 values = tokens[i].split("=");
490 if (values.length != 2)
491 throw new IllegalArgumentException("Token " + tokens[i]
492 + " does not have form 'key=value' parsing " + match);
493 values[0] = values[0].toLowerCase(); // try to make this case insens
494 if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
495 this.inputPort = U16.t(Integer.valueOf(values[1]));
496 inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
498 } else if (values[0].equals(STR_DL_DST)
499 || values[0].equals("eth_dst")) {
500 this.dataLayerDestination = HexEncode
501 .bytesFromHexString(values[1]);
502 dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
504 } else if (values[0].equals(STR_DL_SRC)
505 || values[0].equals("eth_src")) {
506 this.dataLayerSource = HexEncode.bytesFromHexString(values[1]);
507 dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
509 this.wildcards &= ~OFPFW_DL_SRC;
510 } else if (values[0].equals(STR_DL_TYPE)
511 || values[0].equals("eth_type")) {
512 if (values[1].startsWith("0x"))
513 this.dataLayerType = U16.t(Integer.valueOf(values[1]
514 .replaceFirst("0x", ""), 16));
516 this.dataLayerType = U16.t(Integer.valueOf(values[1]));
517 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
519 } else if (values[0].equals(STR_DL_VLAN)) {
520 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
521 dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
523 } else if (values[0].equals(STR_DL_VLAN_PCP)) {
524 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
525 .valueOf(values[1]));
526 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
527 } else if (values[0].equals(STR_NW_DST)
528 || values[0].equals("ip_dst")) {
530 if (values[1].contains("/")) {
531 String ipv6addr_wmask[] = values[1].split("/");
532 this.nwDst = InetAddress.getByName(ipv6addr_wmask[0]);
533 this.dstIPv6SubnetMaskbits = Short
534 .valueOf(ipv6addr_wmask[1]);
535 nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
538 this.nwDst = InetAddress.getByName(values[1]);
539 nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
542 } catch (UnknownHostException e) {
545 } else if (values[0].equals(STR_NW_SRC)
546 || values[0].equals("ip_src")) {
548 if (values[1].contains("/")) {
549 String ipv6addr_wmask[] = values[1].split("/");
550 this.nwSrc = InetAddress.getByName(ipv6addr_wmask[0]);
551 this.srcIPv6SubnetMaskbits = Short
552 .valueOf(ipv6addr_wmask[1]);
553 nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
556 this.nwSrc = InetAddress.getByName(values[1]);
557 nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
560 } catch (UnknownHostException e) {
563 } else if (values[0].equals(STR_NW_PROTO)) {
564 this.networkProtocol = U8.t(Short.valueOf(values[1]));
565 if (!(this.networkProtocol == 0)) {
567 * if user selects proto 0, don't use it
569 nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
572 } else if (values[0].equals(STR_NW_TOS)) {
573 this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
574 nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
576 } else if (values[0].equals(STR_TP_DST)) {
577 this.transportDestination = U16.t(Integer.valueOf(values[1]));
578 tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
580 } else if (values[0].equals(STR_TP_SRC)) {
581 this.transportSource = U16.t(Integer.valueOf(values[1]));
582 tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
585 throw new IllegalArgumentException("unknown token " + tokens[i]
586 + " parsing " + match);
590 * In a V6 extension message action list should be preceded by a padding of 0 to
591 * 7 bytes based upon following formula.
594 pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
599 * Write this message's binary format to the specified ByteBuffer
604 public void writeTo(ByteBuffer data) {
605 if (inputPortState == MatchFieldState.MATCH_FIELD_ONLY) {
606 byte[] ipv6ext_ingress_port_msg = getIPv6ExtensionPortMatchMsg(this.inputPort);
607 data.put(ipv6ext_ingress_port_msg);
609 if (ethTypeState == MatchFieldState.MATCH_FIELD_ONLY) {
610 byte[] ipv6ext_ether_type_msg = getIPv6ExtensionEtherTypeMatchMsg(this.dataLayerType);
611 data.put(ipv6ext_ether_type_msg);
613 if (dlDestState == MatchFieldState.MATCH_FIELD_ONLY) {
614 byte[] ipv6ext_destmac_msg = getIPv6ExtensionDestMacMatchMsg(this.dataLayerDestination);
615 data.put(ipv6ext_destmac_msg);
617 if (dlSourceState == MatchFieldState.MATCH_FIELD_ONLY) {
618 byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
619 data.put(ipv6ext_srcmac_msg);
621 if (dlVlanState == MatchFieldState.MATCH_FIELD_ONLY) {
622 byte[] ipv6ext_vlan_id_msg = getIPv6ExtensionVlanIDMatchMsg(this.dataLayerVirtualLan);
623 data.put(ipv6ext_vlan_id_msg);
625 if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
626 byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
628 data.put(ipv6ext_src_ipv6_msg);
629 } else if (nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
630 byte[] ipv6ext_src_ipv6_with_mask_msg = getIPv6ExtensionSrcIPv6MatchwithMaskMsg(
631 this.nwSrc.getAddress(), this.srcIPv6SubnetMaskbits);
632 data.put(ipv6ext_src_ipv6_with_mask_msg);
634 if (nwDstState == MatchFieldState.MATCH_FIELD_ONLY) {
635 byte[] ipv6ext_dst_ipv6_msg = getIPv6ExtensionDstIPv6MatchMsg(this.nwDst
637 data.put(ipv6ext_dst_ipv6_msg);
638 } else if (nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
639 byte[] ipv6ext_dst_ipv6_with_mask_msg = getIPv6ExtensionDstIPv6MatchwithMaskMsg(
640 this.nwDst.getAddress(), this.dstIPv6SubnetMaskbits);
641 data.put(ipv6ext_dst_ipv6_with_mask_msg);
643 if (nwProtoState == MatchFieldState.MATCH_FIELD_ONLY) {
644 byte[] ipv6ext_protocol_msg = getIPv6ExtensionProtocolMatchMsg(this.networkProtocol);
645 if (ipv6ext_protocol_msg != null) {
646 data.put(ipv6ext_protocol_msg);
649 if (nwTosState == MatchFieldState.MATCH_FIELD_ONLY) {
650 byte[] ipv6ext_tos_msg = getIPv6ExtensionTOSMatchMsg(this.networkTypeOfService);
651 data.put(ipv6ext_tos_msg);
653 if (tpSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
654 byte[] ipv6ext_srcport_msg = null;
655 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
656 ipv6ext_srcport_msg = getIPv6ExtensionTCPSrcPortMatchMsg(this.transportSource);
657 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
658 ipv6ext_srcport_msg = getIPv6ExtensionUDPSrcPortMatchMsg(this.transportSource);
660 if (ipv6ext_srcport_msg != null) {
661 data.put(ipv6ext_srcport_msg);
664 if (tpDstState == MatchFieldState.MATCH_FIELD_ONLY) {
665 byte[] ipv6ext_dstport_msg = null;
666 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
667 ipv6ext_dstport_msg = getIPv6ExtensionTCPDstPortMatchMsg(this.transportDestination);
668 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
669 ipv6ext_dstport_msg = getIPv6ExtensionUDPDstPortMatchMsg(this.transportDestination);
671 if (ipv6ext_dstport_msg != null) {
672 data.put(ipv6ext_dstport_msg);
675 logger.trace("{}", this);
678 private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
679 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
681 * mask is not allowed for inport port
684 super.setInputPort(data.getShort());
685 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
686 this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
690 private void readDataLinkDestination(ByteBuffer data, int nxmLen,
693 if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6))
696 byte[] bytes = new byte[6];
698 super.setDataLayerDestination(bytes);
699 this.dataLayerDestinationMask = new byte[6];
700 data.get(this.dataLayerDestinationMask);
701 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
702 this.match_len += 16;
705 if ((nxmLen != 6) || (data.remaining() < 6))
708 byte[] bytes = new byte[6];
710 super.setDataLayerDestination(bytes);
711 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
712 this.match_len += 10;
715 this.wildcards ^= (1 << 3); // Sync with 0F 1.0 Match
718 private void readDataLinkSource(ByteBuffer data, int nxmLen, boolean hasMask) {
720 * mask is not allowed in data link source
722 if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask))
724 byte[] bytes = new byte[6];
726 super.setDataLayerSource(bytes);
727 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
728 this.match_len += 10;
729 this.wildcards ^= (1 << 2); // Sync with 0F 1.0 Match
732 private void readEtherType(ByteBuffer data, int nxmLen, boolean hasMask) {
734 * mask is not allowed in ethertype
736 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
738 super.setDataLayerType(data.getShort());
739 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
740 this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
744 private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
745 short vlan_mask = 0xfff;
747 if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2))
750 short vlan = data.getShort();
752 super.setDataLayerVirtualLan(vlan);
753 this.dataLayerVirtualLanMask = data.getShort();
754 this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
756 this.wildcards ^= (1 << 20);
759 if ((nxmLen != 2) || (data.remaining() < 2))
762 short vlan = data.getShort();
764 super.setDataLayerVirtualLan(vlan);
765 this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
770 this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
773 private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
775 * mask is not allowed in IP TOS
777 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
779 super.setNetworkTypeOfService(data.get());
780 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
782 this.wildcards ^= (1 << 21); // Sync with 0F 1.0 Match
785 private void readIpProto(ByteBuffer data, int nxmLen, boolean hasMask) {
787 * mask is not allowed in IP protocol
789 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask))
791 super.setNetworkProtocol(data.get());
792 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
794 this.wildcards ^= (1 << 5); // Sync with 0F 1.0 Match
797 private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
799 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
802 byte[] sbytes = new byte[4];
805 this.nwSrc = InetAddress.getByAddress(sbytes);
806 } catch (UnknownHostException e) {
809 byte[] mbytes = new byte[4];
812 this.networkSourceMask = InetAddress.getByAddress(mbytes);
813 } catch (UnknownHostException e) {
816 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
817 this.match_len += 12;
818 int prefixlen = getNetworkMaskPrefixLength(mbytes);
819 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
820 this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
824 if ((nxmLen != 4) || (data.remaining() < 4))
827 byte[] sbytes = new byte[4];
830 this.nwSrc = InetAddress.getByAddress(sbytes);
831 } catch (UnknownHostException e) {
834 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
836 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
841 private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
843 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4))
846 byte[] dbytes = new byte[4];
849 this.nwDst = InetAddress.getByAddress(dbytes);
850 } catch (UnknownHostException e) {
853 byte[] mbytes = new byte[4];
856 this.networkDestinationMask = InetAddress
857 .getByAddress(mbytes);
858 } catch (UnknownHostException e) {
861 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
862 this.match_len += 12;
863 int prefixlen = getNetworkMaskPrefixLength(mbytes);
864 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
865 this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
868 if ((nxmLen != 4) || (data.remaining() < 4))
871 byte[] dbytes = new byte[4];
874 this.nwDst = InetAddress.getByAddress(dbytes);
875 } catch (UnknownHostException e) {
878 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
879 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
885 private void readTcpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
887 * mask is not allowed in TCP SRC
889 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
891 super.setTransportSource(data.getShort());
892 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
894 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
897 private void readTcpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
899 * mask is not allowed in TCP DST
901 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
903 super.setTransportDestination(data.getShort());
904 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
906 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
909 private void readUdpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
911 * mask is not allowed in UDP SRC
913 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
915 super.setTransportSource(data.getShort());
916 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
918 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
921 private void readUdpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
923 * mask is not allowed in UDP DST
925 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask))
927 super.setTransportDestination(data.getShort());
928 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
930 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
933 private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
935 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
938 byte[] sbytes = new byte[16];
941 this.nwSrc = InetAddress.getByAddress(sbytes);
942 } catch (UnknownHostException e) {
945 byte[] mbytes = new byte[16];
948 this.networkSourceMask = InetAddress.getByAddress(mbytes);
949 } catch (UnknownHostException e) {
952 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
953 this.match_len += 36;
956 if ((nxmLen != 16) || (data.remaining() < 16))
959 byte[] sbytes = new byte[16];
962 this.nwSrc = InetAddress.getByAddress(sbytes);
963 } catch (UnknownHostException e) {
966 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
967 this.match_len += 20;
972 private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
974 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16))
977 byte[] dbytes = new byte[16];
980 this.nwDst = InetAddress.getByAddress(dbytes);
981 } catch (UnknownHostException e) {
984 byte[] mbytes = new byte[16];
987 this.networkDestinationMask = InetAddress
988 .getByAddress(mbytes);
989 } catch (UnknownHostException e) {
992 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
993 this.match_len += 36;
996 if ((nxmLen != 16) || (data.remaining() < 16))
999 byte[] dbytes = new byte[16];
1002 this.nwDst = InetAddress.getByAddress(dbytes);
1003 } catch (UnknownHostException e) {
1006 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1007 this.match_len += 20;
1013 public String toString() {
1014 return "V6Match [nwSrc=" + nwSrc + ", nwDst=" + nwDst
1015 + ", inputPortMask=" + inputPortMask + ", dataLayerSourceMask="
1016 + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
1017 + ", dataLayerDestinationMask="
1018 + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
1019 + ", dataLayerVirtualLanMask=" + dataLayerVirtualLanMask
1020 + ", dataLayerVirtualLanPriorityCodePointMask="
1021 + dataLayerVirtualLanPriorityCodePointMask
1022 + ", dataLayerTypeMask=" + dataLayerTypeMask
1023 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
1024 + ", networkProtocolMask=" + networkProtocolMask
1025 + ", networkSourceMask=" + networkSourceMask
1026 + ", networkDestinationMask=" + networkDestinationMask
1027 + ", transportSourceMask=" + transportSourceMask
1028 + ", transportDestinationMask=" + transportDestinationMask
1029 + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
1030 + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
1031 + ", inputPortState=" + inputPortState + ", dlSourceState="
1032 + dlSourceState + ", dlDestState=" + dlDestState
1033 + ", dlVlanState=" + dlVlanState + ", ethTypeState="
1034 + ethTypeState + ", nwTosState=" + nwTosState
1035 + ", nwProtoState=" + nwProtoState + ", nwSrcState="
1036 + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
1037 + tpSrcState + ", tpDstState=" + tpDstState + ", match_len="
1038 + match_len + ", pad_size=" + pad_size + "]";
1042 * Read the data corresponding to the match field (received from the wire)
1043 * Input: data: match field(s). Since match field is of variable length, the whole data that are passed in
1044 * are assumed to fem0tbd.be the match fields.
1048 public void readFrom(ByteBuffer data) {
1049 readFromInternal(data);
1050 postprocessWildCardInfo();
1053 private void readFromInternal(ByteBuffer data) {
1055 while (data.remaining() > 0) {
1056 if (data.remaining() < 4) {
1058 * at least 4 bytes for each match header
1060 logger.error("Invalid Vendor Extension Header. Size {}", data
1065 * read the 4 byte match header
1067 int nxmVendor = data.getShort();
1069 int nxmField = b >> 1;
1070 boolean hasMask = ((b & 0x01) == 1) ? true : false;
1071 int nxmLen = data.get();
1072 if (nxmVendor == Extension_Types.OF_10.getValue()) {
1073 if (nxmField == OF_Match_Types.MATCH_OF_IN_PORT.getValue()) {
1074 readInPort(data, nxmLen, hasMask);
1075 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_DST
1077 readDataLinkDestination(data, nxmLen, hasMask);
1078 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_SRC
1080 readDataLinkSource(data, nxmLen, hasMask);
1081 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_TYPE
1083 readEtherType(data, nxmLen, hasMask);
1084 } else if (nxmField == OF_Match_Types.MATCH_OF_VLAN_TCI
1086 readVlanTci(data, nxmLen, hasMask);
1087 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_TOS
1089 readIpTos(data, nxmLen, hasMask);
1090 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_PROTO
1092 readIpProto(data, nxmLen, hasMask);
1093 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_SRC
1095 readIpv4Src(data, nxmLen, hasMask);
1096 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_DST
1098 readIpv4Dst(data, nxmLen, hasMask);
1099 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_SRC
1101 readTcpSrc(data, nxmLen, hasMask);
1102 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_DST
1104 readTcpDst(data, nxmLen, hasMask);
1105 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_SRC
1107 readUdpSrc(data, nxmLen, hasMask);
1108 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_DST
1110 readUdpDst(data, nxmLen, hasMask);
1112 // unexpected nxmField
1115 } else if (nxmVendor == Extension_Types.IPV6EXT.getValue()) {
1116 if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC
1118 readIpv6Src(data, nxmLen, hasMask);
1119 } else if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST
1121 readIpv6Dst(data, nxmLen, hasMask);
1123 // unexpected nxmField
1127 // invalid nxmVendor
1133 private void postprocessWildCardInfo() {
1134 // Sync with 0F 1.0 Match
1135 if (super.getDataLayerType() == 0x800) {
1136 if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
1137 //ipv4 src processing
1138 this.wildcards ^= (((1 << 5) - 1) << 8);
1140 if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
1141 //ipv4 dest processing
1142 this.wildcards ^= (((1 << 5) - 1) << 14);
1150 public V6Match clone() {
1152 V6Match ret = (V6Match) super.clone();
1154 if (this.nwSrc != null) {
1155 ret.nwSrc = InetAddress.getByAddress(this.nwSrc.getAddress());
1157 if (this.nwDst != null) {
1158 ret.nwDst = InetAddress.getByAddress(this.nwDst.getAddress());
1161 } catch (UnknownHostException e) {
1162 throw new RuntimeException(e);
1172 public InetAddress getNetworkDest() {
1182 public void setNetworkSrc(InetAddress address) {
1192 public void setNetworkDest(InetAddress address) {
1202 public InetAddress getNetworkSrc() {
1206 private int getNetworkMaskPrefixLength(byte[] netMask) {
1207 ByteBuffer nm = ByteBuffer.wrap(netMask);
1208 int trailingZeros = Integer.numberOfTrailingZeros(nm.getInt());
1209 return 32 - trailingZeros;
1212 public short getInputPortMask() {
1213 return inputPortMask;
1216 public void setInputPort(short port, short mask) {
1217 super.inputPort = port;
1218 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
1220 // Looks like mask is not allowed for input port. Will discard it
1223 public byte[] getDataLayerSourceMask() {
1224 return dataLayerSourceMask;
1227 public void setDataLayerSource(byte[] mac, byte[] mask) {
1229 System.arraycopy(mac, 0, super.dataLayerSource, 0, mac.length);
1232 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
1233 this.match_len += 10;
1235 if (this.dataLayerSourceMask == null) {
1236 this.dataLayerSourceMask = new byte[mask.length];
1238 System.arraycopy(mask, 0, this.dataLayerSourceMask, 0, mask.length);
1239 this.dlSourceState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1240 this.match_len += 16;
1244 public byte[] getDataLayerDestinationMask() {
1245 return dataLayerDestinationMask;
1248 public void setDataLayerDestination(byte[] mac, byte[] mask) {
1250 System.arraycopy(mac, 0, super.dataLayerDestination, 0, mac.length);
1253 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
1254 this.match_len += 10;
1256 if (this.dataLayerDestinationMask == null) {
1257 this.dataLayerDestinationMask = new byte[mask.length];
1259 System.arraycopy(mask, 0, this.dataLayerDestinationMask, 0,
1261 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1262 this.match_len += 16;
1266 public short getDataLayerVirtualLanMask() {
1267 return dataLayerVirtualLanMask;
1270 public void setDataLayerVirtualLan(short vlan, short mask) {
1271 super.dataLayerVirtualLan = vlan;
1273 this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
1274 this.match_len += 6;
1276 this.dataLayerVirtualLanMask = mask;
1277 this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1278 this.match_len += 8;
1282 public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
1283 super.dataLayerVirtualLanPriorityCodePoint = pcp;
1286 public void setDataLayerType(short ethType, short mask) {
1288 super.dataLayerType = ethType;
1289 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
1290 this.match_len += 6;
1293 public void setNetworkTypeOfService(byte tos, byte mask) {
1295 super.networkTypeOfService = tos;
1296 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
1300 public void setNetworkProtocol(byte ipProto, byte mask) {
1302 super.networkProtocol = ipProto;
1303 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
1304 this.match_len += 5;
1307 public InetAddress getNetworkSourceMask() {
1308 return networkSourceMask;
1311 public void setNetworkSource(InetAddress address, InetAddress mask) {
1312 this.nwSrc = address;
1314 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1315 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1317 this.networkSourceMask = mask;
1318 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1319 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1323 public InetAddress getNetworkDestinationMask() {
1324 return networkDestinationMask;
1327 public void setNetworkDestination(InetAddress address, InetAddress mask) {
1328 this.nwDst = address;
1330 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1331 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1333 this.networkDestinationMask = mask;
1334 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1335 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1339 public void setTransportSource(short tpSrc, short mask) {
1341 super.transportSource = tpSrc;
1342 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1343 this.match_len += 6;
1346 public short getTransportDestinationMask() {
1347 return transportDestinationMask;
1350 public void setTransportDestination(short tpDst, short mask) {
1352 super.transportDestination = tpDst;
1353 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1354 this.match_len += 6;
1357 private byte[] getIPv6NetworkMaskinBytes(short num) {
1358 byte[] nbytes = new byte[16];
1363 for (i = 0; i < quot; i++) {
1364 nbytes[i] = (byte) 0xff;
1368 nbytes[i] = (byte) 0xff;
1369 nbytes[i] <<= 8 - bits;