2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension;
11 import java.net.Inet6Address;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.nio.ByteBuffer;
15 import java.util.Arrays;
17 import org.opendaylight.controller.sal.utils.HexEncode;
18 import org.opendaylight.controller.sal.utils.NetUtils;
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 a
30 * sub-message for each field which are later used to form the complete message.
32 * For message processing, it parses the incoming message and reads each field
33 * of the message and stores in appropriate field of V6Match object.
37 public class V6Match extends OFMatch implements Cloneable {
38 private static final Logger logger = LoggerFactory.getLogger(V6Match.class);
39 private static final long serialVersionUID = 1L;
40 protected Inet6Address nwSrc;
41 protected Inet6Address nwDst;
42 protected short inputPortMask;
43 protected byte[] dataLayerSourceMask;
44 protected byte[] dataLayerDestinationMask;
45 protected int dataLayerVirtualLanTCIMask;
46 protected short dataLayerTypeMask;
47 protected byte networkTypeOfServiceMask;
48 protected byte networkProtocolMask;
49 protected short transportSourceMask;
50 protected short transportDestinationMask;
51 protected short srcIPv6SubnetMaskbits;
52 protected short dstIPv6SubnetMaskbits;
54 protected MatchFieldState inputPortState;
55 protected MatchFieldState dlSourceState;
56 protected MatchFieldState dlDestState;
57 protected MatchFieldState dlVlanIDState;
58 protected MatchFieldState dlVlanPCPState;
59 protected MatchFieldState dlVlanTCIState;
60 protected MatchFieldState ethTypeState;
61 protected MatchFieldState nwTosState;
62 protected MatchFieldState nwProtoState;
63 protected MatchFieldState nwSrcState;
64 protected MatchFieldState nwDstState;
65 protected MatchFieldState tpSrcState;
66 protected MatchFieldState tpDstState;
67 protected short match_len = 0;
68 protected short pad_size = 0;
70 private static int IPV6_EXT_MIN_HDR_LEN = 36;
72 private enum MatchFieldState {
73 MATCH_ABSENT, MATCH_FIELD_ONLY, MATCH_FIELD_WITH_MASK
76 private enum OF_Match_Types {
77 MATCH_OF_IN_PORT(0), MATCH_OF_ETH_DST(1), MATCH_OF_ETH_SRC(2), MATCH_OF_ETH_TYPE(
78 3), MATCH_OF_VLAN_TCI(4), MATCH_OF_IP_TOS(5), MATCH_OF_IP_PROTO(
79 6), MATCH_OF_IP_SRC(7), MATCH_OF_IP_DST(8), MATCH_OF_TCP_SRC(9), MATCH_OF_TCP_DST(
80 10), MATCH_OF_UDP_SRC(11), MATCH_OF_UDP_DST(12), MATCH_OF_ICMTP_TYPE(
81 13), MATCH_OF_ICMP_CODE(14), MATCH_OF_ARP_OP(15);
85 private OF_Match_Types(int value) {
89 public int getValue() {
94 private enum IPv6Extension_Match_Types {
95 MATCH_IPV6EXT_TUN_ID(16), MATCH_IPV6EXT_ARP_SHA(17), MATCH_IPV6EXT_ARP_THA(
96 18), MATCH_IPV6EXT_IPV6_SRC(19), MATCH_IPV6EXT_IPV6_DST(20);
100 private IPv6Extension_Match_Types(int value) {
104 public int getValue() {
109 public enum Extension_Types {
110 OF_10(0), IPV6EXT(1);
114 private Extension_Types(int value) {
118 public int getValue() {
129 this.inputPortMask = 0;
130 this.dataLayerSourceMask = null;
131 this.dataLayerDestinationMask = null;
132 this.dataLayerTypeMask = 0;
133 this.dataLayerVirtualLanTCIMask = 0;
134 this.networkTypeOfServiceMask = 0;
135 this.networkProtocolMask = 0;
136 this.transportSourceMask = 0;
137 this.transportDestinationMask = 0;
139 this.inputPortState = MatchFieldState.MATCH_ABSENT;
140 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
141 this.dlDestState = MatchFieldState.MATCH_ABSENT;
142 this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
143 this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
144 this.dlVlanTCIState = 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.setNetworkSource(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
188 && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
189 this.setDataLayerSource(match.getDataLayerSource(), null);
191 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
193 this.dataLayerDestinationMask = null;
194 if (match.getDataLayerDestination() != null
195 && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
196 this.setDataLayerDestination(match.getDataLayerDestination(), null);
198 this.dlDestState = MatchFieldState.MATCH_ABSENT;
201 this.dataLayerTypeMask = 0;
202 if (match.getDataLayerType() != 0) {
203 this.setDataLayerType(match.getDataLayerType(), (short) 0);
205 this.dataLayerType = 0;
206 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
209 this.dataLayerVirtualLanTCIMask = 0;
210 this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
211 if (match.getDataLayerVirtualLan() != 0) {
212 this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
215 this.dataLayerVirtualLan = 0;
216 this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
219 if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
220 this.setDataLayerVirtualLanPriorityCodePoint(
221 match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
223 this.dataLayerVirtualLanPriorityCodePoint = 0;
224 this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
227 this.networkProtocolMask = 0;
228 if (match.getNetworkProtocol() != 0) {
229 this.setNetworkProtocol(
230 this.networkProtocol = match.getNetworkProtocol(), (byte) 0);
232 this.networkProtocol = 0;
233 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
236 this.networkTypeOfServiceMask = 0;
237 if (match.getNetworkTypeOfService() != 0) {
238 this.setNetworkTypeOfService(
239 this.networkTypeOfService = match.getNetworkTypeOfService(),
242 this.networkTypeOfService = match.getNetworkTypeOfService();
243 this.nwTosState = MatchFieldState.MATCH_ABSENT;
246 this.transportSourceMask = 0;
247 if (match.getTransportSource() != 0) {
248 this.setTransportSource(match.getTransportSource(), (short) 0);
250 this.transportSource = 0;
251 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
254 this.transportDestinationMask = 0;
255 if (match.getTransportDestination() != 0) {
256 this.setTransportDestination(match.getTransportDestination(),
259 this.transportDestination = 0;
260 this.tpDstState = MatchFieldState.MATCH_ABSENT;
263 this.setWildcards(match.getWildcards());
266 private enum IPProtocols {
267 ICMP(1), TCP(6), UDP(17), ICMPV6(58);
269 private int protocol;
271 private IPProtocols(int value) {
272 this.protocol = value;
275 private byte getValue() {
276 return (byte) this.protocol;
280 public short getIPv6MatchLen() {
284 public int getIPv6ExtMinHdrLen() {
285 return IPV6_EXT_MIN_HDR_LEN;
288 public short getPadSize() {
289 return (short) (((match_len + 7) / 8) * 8 - match_len);
292 private int getIPv6ExtensionMatchHeader(Extension_Types extType, int field,
293 int has_mask, int length) {
294 return (((extType.getValue() & 0x0000ffff) << 16)
295 | ((field & 0x0000007f) << 9) | ((has_mask & 0x00000001) << 8) | (length & 0x000000ff));
298 private byte[] getIPv6ExtensionPortMatchMsg(short port) {
299 ByteBuffer ipv6ext_port_msg = ByteBuffer.allocate(6);
300 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
301 OF_Match_Types.MATCH_OF_IN_PORT.getValue(), 0, 2);
302 ipv6ext_port_msg.putInt(nxm_header);
303 ipv6ext_port_msg.putShort(port);
304 return (ipv6ext_port_msg.array());
307 private byte[] getIPv6ExtensionDestMacMatchMsg(byte[] destMac) {
308 ByteBuffer ipv6ext_destmac_msg = ByteBuffer.allocate(10);
309 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
310 OF_Match_Types.MATCH_OF_ETH_DST.getValue(), 0, 6);
311 ipv6ext_destmac_msg.putInt(nxm_header);
312 ipv6ext_destmac_msg.put(destMac);
313 return (ipv6ext_destmac_msg.array());
316 private byte[] getIPv6ExtensionSrcMacMatchMsg(byte[] srcMac) {
317 ByteBuffer ipv6ext_srcmac_msg = ByteBuffer.allocate(10);
318 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
319 OF_Match_Types.MATCH_OF_ETH_SRC.getValue(), 0, 6);
320 ipv6ext_srcmac_msg.putInt(nxm_header);
321 ipv6ext_srcmac_msg.put(srcMac);
322 return (ipv6ext_srcmac_msg.array());
325 private byte[] getIPv6ExtensionEtherTypeMatchMsg(short EtherType) {
326 ByteBuffer ipv6ext_etype_msg = ByteBuffer.allocate(6);
327 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
328 OF_Match_Types.MATCH_OF_ETH_TYPE.getValue(), 0, 2);
329 ipv6ext_etype_msg.putInt(nxm_header);
330 ipv6ext_etype_msg.putShort(EtherType);
331 return (ipv6ext_etype_msg.array());
334 private byte[] getVlanTCI(short dataLayerVirtualLanID,
335 byte dataLayerVirtualLanPriorityCodePoint) {
336 ByteBuffer vlan_tci = ByteBuffer.allocate(2);
337 int cfi = 1 << 12; // the cfi bit is in position 12
338 int pcp = dataLayerVirtualLanPriorityCodePoint << 13; // the pcp fields
341 int vlan_tci_int = pcp + cfi + dataLayerVirtualLanID;
342 vlan_tci.put((byte) (vlan_tci_int >> 8)); // bits 8 to 15
343 vlan_tci.put((byte) vlan_tci_int); // bits 0 to 7
344 return vlan_tci.array();
347 private byte[] getIPv6ExtensionVlanTCIMatchMsg(short dataLayerVirtualLanID,
348 byte dataLayerVirtualLanPriorityCodePoint) {
349 ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(6);
350 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
351 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
352 ipv6ext_vlan_tci_msg.putInt(nxm_header);
353 ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLanID,
354 dataLayerVirtualLanPriorityCodePoint));
355 return (ipv6ext_vlan_tci_msg.array());
358 private byte[] getIPv6ExtensionVlanTCIMatchWithMaskMsg(
359 short dataLayerVirtualLan,
360 byte dataLayerVirtualLanPriorityCodePoint,
361 int dataLayerVirtualLanTCIMask) {
362 ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(8);
363 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
364 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 1, 4);
365 ipv6ext_vlan_tci_msg.putInt(nxm_header);
366 ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLan,
367 dataLayerVirtualLanPriorityCodePoint));
368 ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask >> 8)); // bits
372 ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask)); // bits 0
374 return (ipv6ext_vlan_tci_msg.array());
377 private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
378 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
379 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
380 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 0,
382 ipv6ext_ipv6_msg.putInt(nxm_header);
383 ipv6ext_ipv6_msg.put(srcIpv6);
384 return (ipv6ext_ipv6_msg.array());
387 private byte[] getIPv6ExtensionSrcIPv6MatchwithMaskMsg(byte[] srcIpv6,
389 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
390 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
391 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 1,
393 ipv6ext_ipv6_msg.putInt(nxm_header);
394 ipv6ext_ipv6_msg.put(srcIpv6);
395 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
396 ipv6ext_ipv6_msg.put(ipv6_mask);
397 return (ipv6ext_ipv6_msg.array());
400 private byte[] getIPv6ExtensionDstIPv6MatchMsg(byte[] dstIpv6) {
401 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
402 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
403 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 0,
405 ipv6ext_ipv6_msg.putInt(nxm_header);
406 ipv6ext_ipv6_msg.put(dstIpv6);
407 return (ipv6ext_ipv6_msg.array());
410 private byte[] getIPv6ExtensionDstIPv6MatchwithMaskMsg(byte[] dstIpv6,
412 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
413 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
414 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 1,
416 ipv6ext_ipv6_msg.putInt(nxm_header);
417 ipv6ext_ipv6_msg.put(dstIpv6);
418 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
419 ipv6ext_ipv6_msg.put(ipv6_mask);
420 return (ipv6ext_ipv6_msg.array());
423 private byte[] getIPv6ExtensionProtocolMatchMsg(byte protocol) {
424 ByteBuffer ipv6ext_proto_msg = ByteBuffer.allocate(5);
425 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
426 OF_Match_Types.MATCH_OF_IP_PROTO.getValue(), 0, 1);
430 ipv6ext_proto_msg.putInt(nxm_header);
431 if (protocol == IPProtocols.ICMP.getValue()) {
433 * The front end passes the same protocol type values for IPv4 and
434 * IPv6 flows. For the Protocol types we allow in our GUI (ICMP,
435 * TCP, UDP), ICMP is the only one which is different for IPv6. It
436 * is 1 for v4 and 58 for v6 Therefore, we overwrite it here.
438 protocol = IPProtocols.ICMPV6.getValue();
440 ipv6ext_proto_msg.put(protocol);
441 return (ipv6ext_proto_msg.array());
444 private byte[] getIPv6ExtensionTOSMatchMsg(byte tos) {
445 ByteBuffer ipv6ext_tos_msg = ByteBuffer.allocate(5);
446 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
447 OF_Match_Types.MATCH_OF_IP_TOS.getValue(), 0, 1);
448 ipv6ext_tos_msg.putInt(nxm_header);
449 ipv6ext_tos_msg.put(tos);
450 return (ipv6ext_tos_msg.array());
453 private byte[] getIPv6ExtensionTCPSrcPortMatchMsg(short src_port) {
454 ByteBuffer ipv6ext_tcp_srcport_msg = ByteBuffer.allocate(6);
455 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
456 OF_Match_Types.MATCH_OF_TCP_SRC.getValue(), 0, 2);
457 ipv6ext_tcp_srcport_msg.putInt(nxm_header);
458 ipv6ext_tcp_srcport_msg.putShort(src_port);
459 return (ipv6ext_tcp_srcport_msg.array());
462 private byte[] getIPv6ExtensionTCPDstPortMatchMsg(short dst_port) {
463 ByteBuffer ipv6ext_tcp_dstport_msg = ByteBuffer.allocate(6);
464 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
465 OF_Match_Types.MATCH_OF_TCP_DST.getValue(), 0, 2);
466 ipv6ext_tcp_dstport_msg.putInt(nxm_header);
467 ipv6ext_tcp_dstport_msg.putShort(dst_port);
468 return (ipv6ext_tcp_dstport_msg.array());
471 private byte[] getIPv6ExtensionUDPSrcPortMatchMsg(short src_port) {
472 ByteBuffer ipv6ext_udp_srcport_msg = ByteBuffer.allocate(6);
473 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
474 OF_Match_Types.MATCH_OF_UDP_SRC.getValue(), 0, 2);
475 ipv6ext_udp_srcport_msg.putInt(nxm_header);
476 ipv6ext_udp_srcport_msg.putShort(src_port);
477 return (ipv6ext_udp_srcport_msg.array());
480 private byte[] getIPv6ExtensionUDPDstPortMatchMsg(short dst_port) {
481 ByteBuffer ipv6ext_udp_dstport_msg = ByteBuffer.allocate(6);
482 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
483 OF_Match_Types.MATCH_OF_UDP_DST.getValue(), 0, 2);
484 ipv6ext_udp_dstport_msg.putInt(nxm_header);
485 ipv6ext_udp_dstport_msg.putShort(dst_port);
486 return (ipv6ext_udp_dstport_msg.array());
490 * Sets this (V6Match) object's member variables based on a comma-separated
491 * key=value pair similar to OFMatch's fromString.
494 * a key=value comma separated string.
497 public void fromString(String match) throws IllegalArgumentException {
498 if (match.equals("") || match.equalsIgnoreCase("any")
499 || match.equalsIgnoreCase("all") || match.equals("[]")) {
502 String[] tokens = match.split("[\\[,\\]]");
505 if (tokens[0].equals("OFMatch")) {
508 this.wildcards = OFPFW_ALL;
510 for (i = initArg; i < tokens.length; i++) {
511 values = tokens[i].split("=");
512 if (values.length != 2) {
513 throw new IllegalArgumentException("Token " + tokens[i]
514 + " does not have form 'key=value' parsing " + match);
516 values[0] = values[0].toLowerCase(); // try to make this case insens
517 if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
518 this.inputPort = U16.t(Integer.valueOf(values[1]));
519 inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
521 } else if (values[0].equals(STR_DL_DST)
522 || values[0].equals("eth_dst")) {
523 this.dataLayerDestination = HexEncode
524 .bytesFromHexString(values[1]);
525 dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
527 } else if (values[0].equals(STR_DL_SRC)
528 || values[0].equals("eth_src")) {
529 this.dataLayerSource = HexEncode.bytesFromHexString(values[1]);
530 dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
532 this.wildcards &= ~OFPFW_DL_SRC;
533 } else if (values[0].equals(STR_DL_TYPE)
534 || values[0].equals("eth_type")) {
535 if (values[1].startsWith("0x")) {
536 this.dataLayerType = U16.t(Integer.valueOf(values[1]
537 .replaceFirst("0x", ""), 16));
540 this.dataLayerType = U16.t(Integer.valueOf(values[1]));
542 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
544 } else if (values[0].equals(STR_DL_VLAN)) {
545 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
546 this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
547 // the variable dlVlanIDState is not really used as a flag
548 // for serializing and deserializing. Rather it is used as a
550 // to check if the vlan id is being set so that we can set the
551 // dlVlanTCIState appropriately.
552 if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
553 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
556 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
557 this.dataLayerVirtualLanTCIMask = 0x1fff;
560 this.wildcards &= ~OFPFW_DL_VLAN;
561 } else if (values[0].equals(STR_DL_VLAN_PCP)) {
562 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
563 .valueOf(values[1]));
564 this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
565 // the variable dlVlanPCPState is not really used as a flag
566 // for serializing and deserializing. Rather it is used as a
568 // to check if the vlan pcp is being set so that we can set the
569 // dlVlanTCIState appropriately.
570 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
571 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
574 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
575 this.dataLayerVirtualLanTCIMask = 0xf000;
578 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
579 } else if (values[0].equals(STR_NW_DST)
580 || values[0].equals("ip_dst")) {
582 InetAddress address = null;
583 InetAddress mask = null;
584 if (values[1].contains("/")) {
585 String addressString[] = values[1].split("/");
586 address = InetAddress.getByName(addressString[0]);
587 int masklen = Integer.valueOf(addressString[1]);
588 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
590 address = InetAddress.getByName(values[1]);
592 this.setNetworkDestination(address, mask);
593 } catch (UnknownHostException e) {
596 } else if (values[0].equals(STR_NW_SRC)
597 || values[0].equals("ip_src")) {
599 InetAddress address = null;
600 InetAddress mask = null;
601 if (values[1].contains("/")) {
602 String addressString[] = values[1].split("/");
603 address = InetAddress.getByName(addressString[0]);
604 int masklen = Integer.valueOf(addressString[1]);
605 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
607 address = InetAddress.getByName(values[1]);
609 this.setNetworkSource(address, mask);
610 } catch (UnknownHostException e) {
613 } else if (values[0].equals(STR_NW_PROTO)) {
614 this.networkProtocol = U8.t(Short.valueOf(values[1]));
615 if (!(this.networkProtocol == 0)) {
617 * if user selects proto 0, don't use it
619 nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
622 } else if (values[0].equals(STR_NW_TOS)) {
623 this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
624 nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
626 } else if (values[0].equals(STR_TP_DST)) {
627 this.transportDestination = U16.t(Integer.valueOf(values[1]));
628 tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
630 } else if (values[0].equals(STR_TP_SRC)) {
631 this.transportSource = U16.t(Integer.valueOf(values[1]));
632 tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
635 throw new IllegalArgumentException("unknown token " + tokens[i]
636 + " parsing " + match);
641 * In a V6 extension message action list should be preceded by a padding
642 * of 0 to 7 bytes based upon following formula.
645 pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
650 * Write this message's binary format to the specified ByteBuffer
655 public void writeTo(ByteBuffer data) {
656 if (inputPortState == MatchFieldState.MATCH_FIELD_ONLY) {
657 byte[] ipv6ext_ingress_port_msg = getIPv6ExtensionPortMatchMsg(this.inputPort);
658 data.put(ipv6ext_ingress_port_msg);
660 if (ethTypeState == MatchFieldState.MATCH_FIELD_ONLY) {
661 byte[] ipv6ext_ether_type_msg = getIPv6ExtensionEtherTypeMatchMsg(this.dataLayerType);
662 data.put(ipv6ext_ether_type_msg);
664 if (dlDestState == MatchFieldState.MATCH_FIELD_ONLY) {
665 byte[] ipv6ext_destmac_msg = getIPv6ExtensionDestMacMatchMsg(this.dataLayerDestination);
666 data.put(ipv6ext_destmac_msg);
668 if (dlSourceState == MatchFieldState.MATCH_FIELD_ONLY) {
669 byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
670 data.put(ipv6ext_srcmac_msg);
672 if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_ONLY) {
673 byte[] ipv6ext_vlan_tci_msg = getIPv6ExtensionVlanTCIMatchMsg(
674 this.dataLayerVirtualLan,
675 this.dataLayerVirtualLanPriorityCodePoint);
676 data.put(ipv6ext_vlan_tci_msg);
677 } else if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
678 byte[] ipv6ext_vlan_tci_msg_with_mask = getIPv6ExtensionVlanTCIMatchWithMaskMsg(
679 this.dataLayerVirtualLan,
680 this.dataLayerVirtualLanPriorityCodePoint,
681 this.dataLayerVirtualLanTCIMask);
682 data.put(ipv6ext_vlan_tci_msg_with_mask);
684 if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
685 byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
687 data.put(ipv6ext_src_ipv6_msg);
688 } else if (nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
689 byte[] ipv6ext_src_ipv6_with_mask_msg = getIPv6ExtensionSrcIPv6MatchwithMaskMsg(
690 this.nwSrc.getAddress(), this.srcIPv6SubnetMaskbits);
691 data.put(ipv6ext_src_ipv6_with_mask_msg);
693 if (nwDstState == MatchFieldState.MATCH_FIELD_ONLY) {
694 byte[] ipv6ext_dst_ipv6_msg = getIPv6ExtensionDstIPv6MatchMsg(this.nwDst
696 data.put(ipv6ext_dst_ipv6_msg);
697 } else if (nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
698 byte[] ipv6ext_dst_ipv6_with_mask_msg = getIPv6ExtensionDstIPv6MatchwithMaskMsg(
699 this.nwDst.getAddress(), this.dstIPv6SubnetMaskbits);
700 data.put(ipv6ext_dst_ipv6_with_mask_msg);
702 if (nwProtoState == MatchFieldState.MATCH_FIELD_ONLY) {
703 byte[] ipv6ext_protocol_msg = getIPv6ExtensionProtocolMatchMsg(this.networkProtocol);
704 if (ipv6ext_protocol_msg != null) {
705 data.put(ipv6ext_protocol_msg);
708 if (nwTosState == MatchFieldState.MATCH_FIELD_ONLY) {
709 byte[] ipv6ext_tos_msg = getIPv6ExtensionTOSMatchMsg(this.networkTypeOfService);
710 data.put(ipv6ext_tos_msg);
712 if (tpSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
713 byte[] ipv6ext_srcport_msg = null;
714 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
715 ipv6ext_srcport_msg = getIPv6ExtensionTCPSrcPortMatchMsg(this.transportSource);
716 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
717 ipv6ext_srcport_msg = getIPv6ExtensionUDPSrcPortMatchMsg(this.transportSource);
719 if (ipv6ext_srcport_msg != null) {
720 data.put(ipv6ext_srcport_msg);
723 if (tpDstState == MatchFieldState.MATCH_FIELD_ONLY) {
724 byte[] ipv6ext_dstport_msg = null;
725 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
726 ipv6ext_dstport_msg = getIPv6ExtensionTCPDstPortMatchMsg(this.transportDestination);
727 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
728 ipv6ext_dstport_msg = getIPv6ExtensionUDPDstPortMatchMsg(this.transportDestination);
730 if (ipv6ext_dstport_msg != null) {
731 data.put(ipv6ext_dstport_msg);
734 logger.trace("{}", this);
737 private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
738 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
740 * mask is not allowed for inport port
744 super.setInputPort(data.getShort());
745 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
746 this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
750 private void readDataLinkDestination(ByteBuffer data, int nxmLen,
753 if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
756 byte[] bytes = new byte[6];
758 super.setDataLayerDestination(bytes);
759 this.dataLayerDestinationMask = new byte[6];
760 data.get(this.dataLayerDestinationMask);
761 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
762 this.match_len += 16;
765 if ((nxmLen != 6) || (data.remaining() < 6)) {
768 byte[] bytes = new byte[6];
770 super.setDataLayerDestination(bytes);
771 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
772 this.match_len += 10;
775 this.wildcards ^= (1 << 3); // Sync with 0F 1.0 Match
778 private void readDataLinkSource(ByteBuffer data, int nxmLen, boolean hasMask) {
780 * mask is not allowed in data link source
782 if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
785 byte[] bytes = new byte[6];
787 super.setDataLayerSource(bytes);
788 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
789 this.match_len += 10;
790 this.wildcards ^= (1 << 2); // Sync with 0F 1.0 Match
793 private void readEtherType(ByteBuffer data, int nxmLen, boolean hasMask) {
795 * mask is not allowed in ethertype
797 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
800 super.setDataLayerType(data.getShort());
801 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
802 this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
806 private short getVlanID(byte firstByte, byte secondByte) {
807 short vlan_id_mask_firstByte = 0x0f;// this is the mask for the first
809 short vlan_id_mask_secondByte = 0xff;// this is the mask for the second
811 int vlanPart1 = (firstByte & vlan_id_mask_firstByte) << 8;
812 int vlanPart2 = secondByte & vlan_id_mask_secondByte;
813 return (short) (vlanPart1 + vlanPart2);
816 private byte getVlanPCP(byte pcpByte) {
817 short vlan_pcp_mask = 0xe0;// this is the vlan pcp mask
818 int pcp_int = pcpByte & vlan_pcp_mask;
819 return (byte) (pcp_int >> 5);
822 private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
824 if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
828 byte firstByte = data.get();
829 byte secondByte = data.get();
830 this.dataLayerVirtualLanTCIMask = data.getShort() & 0xffff; // we
836 // check the mask now
837 if ((this.dataLayerVirtualLanTCIMask & 0x0fff) != 0) {
838 // if its a vlan id mask
839 // extract the vlan id
840 super.setDataLayerVirtualLan(getVlanID(firstByte,
843 this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
845 if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
846 // else if its a vlan pcp mask
847 // extract the vlan pcp
848 super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
850 this.wildcards ^= (1 << 20);
852 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
856 if ((nxmLen != 2) || (data.remaining() < 2)) {
861 byte firstByte = data.get();
862 byte secondByte = data.get();
863 super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
864 super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
865 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
871 private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
873 * mask is not allowed in IP TOS
875 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
878 super.setNetworkTypeOfService(data.get());
879 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
881 this.wildcards ^= (1 << 21); // Sync with 0F 1.0 Match
884 private void readIpProto(ByteBuffer data, int nxmLen, boolean hasMask) {
886 * mask is not allowed in IP protocol
888 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
891 super.setNetworkProtocol(data.get());
892 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
894 this.wildcards ^= (1 << 5); // Sync with 0F 1.0 Match
897 private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
899 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
902 byte[] sbytes = new byte[4];
904 // For compatibility, let's set the IPv4 in the parent OFMatch
905 int address = NetUtils.byteArray4ToInt(sbytes);
906 super.setNetworkSource(address);
907 byte[] mbytes = new byte[4];
909 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
910 this.match_len += 12;
911 int prefixlen = getNetworkMaskPrefixLength(mbytes);
912 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
913 this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
916 if ((nxmLen != 4) || (data.remaining() < 4)) {
919 byte[] sbytes = new byte[4];
921 // For compatibility, let's also set the IPv4 in the parent OFMatch
922 int address = NetUtils.byteArray4ToInt(sbytes);
923 super.setNetworkSource(address);
924 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
926 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0
932 private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
934 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
937 byte[] dbytes = new byte[4];
939 // For compatibility, let's also set the IPv4 in the parent OFMatch
940 int address = NetUtils.byteArray4ToInt(dbytes);
941 super.setNetworkDestination(address);
942 byte[] mbytes = new byte[4];
944 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
945 this.match_len += 12;
946 int prefixlen = getNetworkMaskPrefixLength(mbytes);
947 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
949 this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0
953 if ((nxmLen != 4) || (data.remaining() < 4)) {
956 byte[] dbytes = new byte[4];
958 int address = NetUtils.byteArray4ToInt(dbytes);
959 super.setNetworkDestination(address);
960 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
961 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
968 private void readTcpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
970 * mask is not allowed in TCP SRC
972 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
975 super.setTransportSource(data.getShort());
976 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
978 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
981 private void readTcpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
983 * mask is not allowed in TCP DST
985 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
988 super.setTransportDestination(data.getShort());
989 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
991 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
994 private void readUdpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
996 * mask is not allowed in UDP SRC
998 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1001 super.setTransportSource(data.getShort());
1002 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1003 this.match_len += 6;
1004 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
1007 private void readUdpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
1009 * mask is not allowed in UDP DST
1011 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1014 super.setTransportDestination(data.getShort());
1015 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1016 this.match_len += 6;
1017 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
1020 private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
1022 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
1025 byte[] sbytes = new byte[16];
1028 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
1029 } catch (UnknownHostException e) {
1032 byte[] mbytes = new byte[16];
1034 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
1035 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1036 this.match_len += 36;
1039 if ((nxmLen != 16) || (data.remaining() < 16)) {
1042 byte[] sbytes = new byte[16];
1045 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
1046 } catch (UnknownHostException e) {
1049 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1050 this.match_len += 20;
1055 private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
1057 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
1060 byte[] dbytes = new byte[16];
1063 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
1064 } catch (UnknownHostException e) {
1067 byte[] mbytes = new byte[16];
1069 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
1070 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1071 this.match_len += 36;
1074 if ((nxmLen != 16) || (data.remaining() < 16)) {
1077 byte[] dbytes = new byte[16];
1080 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
1081 } catch (UnknownHostException e) {
1084 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1085 this.match_len += 20;
1091 public String toString() {
1092 return "V6Match [nwSrc=" + nwSrc + ", nwDst=" + nwDst
1093 + ", inputPortMask=" + inputPortMask + ", dataLayerSourceMask="
1094 + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
1095 + ", dataLayerDestinationMask="
1096 + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
1097 + ", dataLayerVirtualLanTCIMask=" + dataLayerVirtualLanTCIMask
1098 + ", dataLayerTypeMask=" + dataLayerTypeMask
1099 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
1100 + ", networkProtocolMask=" + networkProtocolMask
1101 + ", transportSourceMask=" + transportSourceMask
1102 + ", transportDestinationMask=" + transportDestinationMask
1103 + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
1104 + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
1105 + ", inputPortState=" + inputPortState + ", dlSourceState="
1106 + dlSourceState + ", dlDestState=" + dlDestState
1107 + ", dlVlanTCIState=" + dlVlanTCIState + ", ethTypeState="
1108 + ethTypeState + ", nwTosState=" + nwTosState
1109 + ", nwProtoState=" + nwProtoState + ", nwSrcState="
1110 + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
1111 + tpSrcState + ", tpDstState=" + tpDstState + ", match_len="
1112 + match_len + ", pad_size=" + pad_size + "]";
1116 * Read the data corresponding to the match field (received from the wire)
1117 * Input: data: match field(s). Since match field is of variable length, the
1118 * whole data that are passed in are assumed to fem0tbd.be the match fields.
1123 public void readFrom(ByteBuffer data) {
1124 readFromInternal(data);
1125 postprocessWildCardInfo();
1128 private void readFromInternal(ByteBuffer data) {
1130 while (data.remaining() > 0) {
1131 if (data.remaining() < 4) {
1133 * at least 4 bytes for each match header
1135 logger.error("Invalid Vendor Extension Header. Size {}",
1140 * read the 4 byte match header
1142 int nxmVendor = data.getShort();
1144 int nxmField = b >> 1;
1145 boolean hasMask = ((b & 0x01) == 1) ? true : false;
1146 int nxmLen = data.get();
1147 if (nxmVendor == Extension_Types.OF_10.getValue()) {
1148 if (nxmField == OF_Match_Types.MATCH_OF_IN_PORT.getValue()) {
1149 readInPort(data, nxmLen, hasMask);
1150 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_DST
1152 readDataLinkDestination(data, nxmLen, hasMask);
1153 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_SRC
1155 readDataLinkSource(data, nxmLen, hasMask);
1156 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_TYPE
1158 readEtherType(data, nxmLen, hasMask);
1159 } else if (nxmField == OF_Match_Types.MATCH_OF_VLAN_TCI
1161 readVlanTci(data, nxmLen, hasMask);
1162 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_TOS
1164 readIpTos(data, nxmLen, hasMask);
1165 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_PROTO
1167 readIpProto(data, nxmLen, hasMask);
1168 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_SRC
1170 readIpv4Src(data, nxmLen, hasMask);
1171 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_DST
1173 readIpv4Dst(data, nxmLen, hasMask);
1174 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_SRC
1176 readTcpSrc(data, nxmLen, hasMask);
1177 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_DST
1179 readTcpDst(data, nxmLen, hasMask);
1180 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_SRC
1182 readUdpSrc(data, nxmLen, hasMask);
1183 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_DST
1185 readUdpDst(data, nxmLen, hasMask);
1187 // unexpected nxmField
1190 } else if (nxmVendor == Extension_Types.IPV6EXT.getValue()) {
1191 if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC
1193 readIpv6Src(data, nxmLen, hasMask);
1194 } else if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST
1196 readIpv6Dst(data, nxmLen, hasMask);
1198 // unexpected nxmField
1202 // invalid nxmVendor
1208 private void postprocessWildCardInfo() {
1209 // Sync with 0F 1.0 Match
1210 if (super.getDataLayerType() == 0x800) {
1211 if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
1212 // ipv4 src processing
1213 this.wildcards ^= (((1 << 5) - 1) << 8);
1215 if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
1216 // ipv4 dest processing
1217 this.wildcards ^= (((1 << 5) - 1) << 14);
1225 public V6Match clone() {
1227 V6Match ret = (V6Match) super.clone();
1229 if (this.nwSrc != null) {
1230 ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
1232 if (this.nwDst != null) {
1233 ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
1236 } catch (UnknownHostException e) {
1237 throw new RuntimeException(e);
1247 public Inet6Address getNetworkDest() {
1257 public Inet6Address getNetworkSrc() {
1261 private int getNetworkMaskPrefixLength(byte[] netMask) {
1262 ByteBuffer nm = ByteBuffer.wrap(netMask);
1263 int trailingZeros = Integer.numberOfTrailingZeros(nm.getInt());
1264 return 32 - trailingZeros;
1267 public short getInputPortMask() {
1268 return inputPortMask;
1271 public void setInputPort(short port, short mask) {
1272 super.inputPort = port;
1273 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
1275 // Looks like mask is not allowed for input port. Will discard it
1278 public byte[] getDataLayerSourceMask() {
1279 return dataLayerSourceMask;
1282 public void setDataLayerSource(byte[] mac, byte[] mask) {
1284 System.arraycopy(mac, 0, super.dataLayerSource, 0, mac.length);
1287 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
1288 this.match_len += 10;
1290 if (this.dataLayerSourceMask == null) {
1291 this.dataLayerSourceMask = new byte[mask.length];
1293 System.arraycopy(mask, 0, this.dataLayerSourceMask, 0, mask.length);
1294 this.dlSourceState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1295 this.match_len += 16;
1299 public byte[] getDataLayerDestinationMask() {
1300 return dataLayerDestinationMask;
1303 public void setDataLayerDestination(byte[] mac, byte[] mask) {
1305 System.arraycopy(mac, 0, super.dataLayerDestination, 0, mac.length);
1308 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
1309 this.match_len += 10;
1311 if (this.dataLayerDestinationMask == null) {
1312 this.dataLayerDestinationMask = new byte[mask.length];
1314 System.arraycopy(mask, 0, this.dataLayerDestinationMask, 0,
1316 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1317 this.match_len += 16;
1321 public void setDataLayerVirtualLan(short vlan, short mask) {
1322 // mask is ignored as the code sets the appropriate mask
1323 super.dataLayerVirtualLan = vlan;
1324 this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
1325 // the variable dlVlanIDState is not really used as a flag
1326 // for serializing and deserializing. Rather it is used as a flag
1327 // to check if the vlan id is being set so that we can set the
1328 // dlVlanTCIState appropriately.
1329 if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
1330 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
1333 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1334 this.dataLayerVirtualLanTCIMask = 0x1fff;
1339 public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
1340 // mask is ignored as the code sets the appropriate mask
1341 super.dataLayerVirtualLanPriorityCodePoint = pcp;
1342 this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
1343 // the variable dlVlanPCPState is not really used as a flag
1344 // for serializing and deserializing. Rather it is used as a flag
1345 // to check if the vlan pcp is being set so that we can set the
1346 // dlVlanTCIState appropriately.
1347 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
1348 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
1351 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1352 this.dataLayerVirtualLanTCIMask = 0xf000;
1357 public void setDataLayerType(short ethType, short mask) {
1359 super.dataLayerType = ethType;
1360 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
1361 this.match_len += 6;
1364 public void setNetworkTypeOfService(byte tos, byte mask) {
1366 super.networkTypeOfService = tos;
1367 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
1371 public void setNetworkProtocol(byte ipProto, byte mask) {
1373 super.networkProtocol = ipProto;
1374 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
1375 this.match_len += 5;
1378 public Inet6Address getNetworkSourceMask() {
1379 return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1380 this.srcIPv6SubnetMaskbits, true) : null;
1383 public void setNetworkSource(InetAddress address, InetAddress mask) {
1384 if (address instanceof Inet6Address) {
1385 this.nwSrc = (Inet6Address) address;
1387 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1388 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1390 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1391 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1392 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1395 super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
1396 this.wildcards ^= (((1 << 6) - 1) << 8);
1398 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1399 this.match_len += 8;
1401 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1402 this.match_len += 12;
1403 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
1408 public Inet6Address getNetworkDestinationMask() {
1409 return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1410 this.dstIPv6SubnetMaskbits, true) : null;
1413 public void setNetworkDestination(InetAddress address, InetAddress mask) {
1414 if (address instanceof Inet6Address) {
1415 this.nwDst = (Inet6Address) address;
1417 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1418 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1420 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1421 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1422 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1425 this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
1426 this.wildcards ^= (((1 << 6) - 1) << 14);
1428 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1429 this.match_len += 8;
1431 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1432 this.match_len += 12;
1433 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
1438 public void setTransportSource(short tpSrc, short mask) {
1440 super.transportSource = tpSrc;
1441 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1442 this.match_len += 6;
1445 public short getTransportDestinationMask() {
1446 return transportDestinationMask;
1449 public void setTransportDestination(short tpDst, short mask) {
1451 super.transportDestination = tpDst;
1452 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1453 this.match_len += 6;
1456 private byte[] getIPv6NetworkMaskinBytes(short num) {
1457 byte[] nbytes = new byte[16];
1462 for (i = 0; i < quot; i++) {
1463 nbytes[i] = (byte) 0xff;
1467 nbytes[i] = (byte) 0xff;
1468 nbytes[i] <<= 8 - bits;
1474 public int hashCode() {
1475 final int prime = 31;
1476 int result = super.hashCode();
1477 result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
1478 result = prime * result + Arrays.hashCode(dataLayerSourceMask);
1479 result = prime * result + dataLayerTypeMask;
1480 result = prime * result + dataLayerVirtualLanTCIMask;
1481 result = prime * result
1482 + ((dlDestState == null) ? 0 : dlDestState.hashCode());
1483 result = prime * result
1484 + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
1485 result = prime * result
1486 + ((dlVlanTCIState == null) ? 0 : dlVlanTCIState.hashCode());
1487 result = prime * result + dstIPv6SubnetMaskbits;
1488 result = prime * result
1489 + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
1490 result = prime * result + inputPortMask;
1491 result = prime * result
1492 + ((inputPortState == null) ? 0 : inputPortState.hashCode());
1493 result = prime * result + match_len;
1494 result = prime * result + networkProtocolMask;
1495 result = prime * result + networkTypeOfServiceMask;
1496 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
1497 result = prime * result
1498 + ((nwDstState == null) ? 0 : nwDstState.hashCode());
1499 result = prime * result
1500 + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
1501 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
1502 result = prime * result
1503 + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
1504 result = prime * result
1505 + ((nwTosState == null) ? 0 : nwTosState.hashCode());
1506 result = prime * result + pad_size;
1507 result = prime * result + srcIPv6SubnetMaskbits;
1508 result = prime * result
1509 + ((tpDstState == null) ? 0 : tpDstState.hashCode());
1510 result = prime * result
1511 + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
1512 result = prime * result + transportDestinationMask;
1513 result = prime * result + transportSourceMask;
1518 public boolean equals(Object obj) {
1522 if (!super.equals(obj)) {
1525 if (getClass() != obj.getClass()) {
1528 V6Match other = (V6Match) obj;
1529 if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
1532 if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
1535 if (dataLayerTypeMask != other.dataLayerTypeMask) {
1538 if (dataLayerVirtualLanTCIMask != other.dataLayerVirtualLanTCIMask) {
1541 if (dlVlanTCIState != other.dlVlanTCIState) {
1544 if (dlSourceState != other.dlSourceState) {
1547 if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
1550 if (ethTypeState != other.ethTypeState) {
1553 if (inputPortMask != other.inputPortMask) {
1556 if (inputPortState != other.inputPortState) {
1559 if (match_len != other.match_len) {
1562 if (networkProtocolMask != other.networkProtocolMask) {
1565 if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
1568 if (nwDst == null) {
1569 if (other.nwDst != null) {
1572 } else if (!nwDst.equals(other.nwDst)) {
1575 if (nwDstState != other.nwDstState) {
1578 if (nwProtoState != other.nwProtoState) {
1581 if (nwSrc == null) {
1582 if (other.nwSrc != null) {
1585 } else if (!nwSrc.equals(other.nwSrc)) {
1588 if (nwSrcState != other.nwSrcState) {
1591 if (nwTosState != other.nwTosState) {
1594 if (pad_size != other.pad_size) {
1597 if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
1600 if (tpDstState != other.tpDstState) {
1603 if (tpSrcState != other.tpSrcState) {
1606 if (transportDestinationMask != other.transportDestinationMask) {
1609 if (transportSourceMask != other.transportSourceMask) {