2 * Copyright (c) 2013-2014 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;
73 * CFI bit in VLAN TCI field.
75 private static final int VLAN_TCI_CFI = 1 << 12;
78 * Value of OFP_VLAN_NONE defined by OpenFlow 1.0.
80 private static final short OFP_VLAN_NONE = (short) 0xffff;
82 private enum MatchFieldState {
83 MATCH_ABSENT, MATCH_FIELD_ONLY, MATCH_FIELD_WITH_MASK
86 private enum OF_Match_Types {
87 MATCH_OF_IN_PORT(0), MATCH_OF_ETH_DST(1), MATCH_OF_ETH_SRC(2), MATCH_OF_ETH_TYPE(
88 3), MATCH_OF_VLAN_TCI(4), MATCH_OF_IP_TOS(5), MATCH_OF_IP_PROTO(
89 6), MATCH_OF_IP_SRC(7), MATCH_OF_IP_DST(8), MATCH_OF_TCP_SRC(9), MATCH_OF_TCP_DST(
90 10), MATCH_OF_UDP_SRC(11), MATCH_OF_UDP_DST(12), MATCH_OF_ICMTP_TYPE(
91 13), MATCH_OF_ICMP_CODE(14), MATCH_OF_ARP_OP(15);
95 private OF_Match_Types(int value) {
99 public int getValue() {
104 private enum IPv6Extension_Match_Types {
105 MATCH_IPV6EXT_TUN_ID(16), MATCH_IPV6EXT_ARP_SHA(17), MATCH_IPV6EXT_ARP_THA(
106 18), MATCH_IPV6EXT_IPV6_SRC(19), MATCH_IPV6EXT_IPV6_DST(20);
110 private IPv6Extension_Match_Types(int value) {
114 public int getValue() {
119 public enum Extension_Types {
120 OF_10(0), IPV6EXT(1);
124 private Extension_Types(int value) {
128 public int getValue() {
139 this.inputPortMask = 0;
140 this.dataLayerSourceMask = null;
141 this.dataLayerDestinationMask = null;
142 this.dataLayerTypeMask = 0;
143 this.dataLayerVirtualLanTCIMask = 0;
144 this.networkTypeOfServiceMask = 0;
145 this.networkProtocolMask = 0;
146 this.transportSourceMask = 0;
147 this.transportDestinationMask = 0;
149 this.inputPortState = MatchFieldState.MATCH_ABSENT;
150 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
151 this.dlDestState = MatchFieldState.MATCH_ABSENT;
152 this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
153 this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
154 this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
155 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
156 this.nwTosState = MatchFieldState.MATCH_ABSENT;
157 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
158 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
159 this.nwDstState = MatchFieldState.MATCH_ABSENT;
160 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
161 this.tpDstState = MatchFieldState.MATCH_ABSENT;
167 public V6Match(OFMatch match) {
172 if (match.getNetworkSource() != 0) {
173 InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
174 InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
175 this.setNetworkSource(address, mask);
177 this.nwSrcState = MatchFieldState.MATCH_ABSENT;
180 if (match.getNetworkDestination() != 0) {
181 InetAddress address = NetUtils.getInetAddress(match.getNetworkDestination());
182 InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkDestinationMaskLen(), false);
183 this.setNetworkDestination(address, mask);
185 this.nwDstState = MatchFieldState.MATCH_ABSENT;
188 this.inputPortMask = 0;
189 if (match.getInputPort() != 0) {
190 this.setInputPort(match.getInputPort(), (short) 0);
192 this.inputPortMask = 0;
193 this.inputPortState = MatchFieldState.MATCH_ABSENT;
196 this.dataLayerSourceMask = null;
197 if (match.getDataLayerSource() != null
198 && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
199 this.setDataLayerSource(match.getDataLayerSource(), null);
201 this.dlSourceState = MatchFieldState.MATCH_ABSENT;
203 this.dataLayerDestinationMask = null;
204 if (match.getDataLayerDestination() != null
205 && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
206 this.setDataLayerDestination(match.getDataLayerDestination(), null);
208 this.dlDestState = MatchFieldState.MATCH_ABSENT;
211 this.dataLayerTypeMask = 0;
212 if (match.getDataLayerType() != 0) {
213 this.setDataLayerType(match.getDataLayerType(), (short) 0);
215 this.dataLayerType = 0;
216 this.ethTypeState = MatchFieldState.MATCH_ABSENT;
219 this.dataLayerVirtualLanTCIMask = 0;
220 this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
221 if (match.getDataLayerVirtualLan() != 0) {
222 this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
225 this.dataLayerVirtualLan = 0;
226 this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
229 if ((match.getWildcards() & OFMatch.OFPFW_DL_VLAN_PCP) == 0) {
230 this.setDataLayerVirtualLanPriorityCodePoint(
231 match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
233 this.dataLayerVirtualLanPriorityCodePoint = 0;
234 this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
237 this.networkProtocolMask = 0;
238 if (match.getNetworkProtocol() != 0) {
239 this.setNetworkProtocol(
240 this.networkProtocol = match.getNetworkProtocol(), (byte) 0);
242 this.networkProtocol = 0;
243 this.nwProtoState = MatchFieldState.MATCH_ABSENT;
246 this.networkTypeOfServiceMask = 0;
247 if (match.getNetworkTypeOfService() != 0) {
248 this.setNetworkTypeOfService(
249 this.networkTypeOfService = match.getNetworkTypeOfService(),
252 this.networkTypeOfService = match.getNetworkTypeOfService();
253 this.nwTosState = MatchFieldState.MATCH_ABSENT;
256 this.transportSourceMask = 0;
257 if (match.getTransportSource() != 0) {
258 this.setTransportSource(match.getTransportSource(), (short) 0);
260 this.transportSource = 0;
261 this.tpSrcState = MatchFieldState.MATCH_ABSENT;
264 this.transportDestinationMask = 0;
265 if (match.getTransportDestination() != 0) {
266 this.setTransportDestination(match.getTransportDestination(),
269 this.transportDestination = 0;
270 this.tpDstState = MatchFieldState.MATCH_ABSENT;
273 this.setWildcards(match.getWildcards());
276 private enum IPProtocols {
277 ICMP(1), TCP(6), UDP(17), ICMPV6(58);
279 private int protocol;
281 private IPProtocols(int value) {
282 this.protocol = value;
285 private byte getValue() {
286 return (byte) this.protocol;
290 public short getIPv6MatchLen() {
294 public int getIPv6ExtMinHdrLen() {
295 return IPV6_EXT_MIN_HDR_LEN;
298 public short getPadSize() {
299 return (short) (((match_len + 7) / 8) * 8 - match_len);
302 private int getIPv6ExtensionMatchHeader(Extension_Types extType, int field,
303 int has_mask, int length) {
304 return (((extType.getValue() & 0x0000ffff) << 16)
305 | ((field & 0x0000007f) << 9) | ((has_mask & 0x00000001) << 8) | (length & 0x000000ff));
308 private byte[] getIPv6ExtensionPortMatchMsg(short port) {
309 ByteBuffer ipv6ext_port_msg = ByteBuffer.allocate(6);
310 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
311 OF_Match_Types.MATCH_OF_IN_PORT.getValue(), 0, 2);
312 ipv6ext_port_msg.putInt(nxm_header);
313 ipv6ext_port_msg.putShort(port);
314 return (ipv6ext_port_msg.array());
317 private byte[] getIPv6ExtensionDestMacMatchMsg(byte[] destMac) {
318 ByteBuffer ipv6ext_destmac_msg = ByteBuffer.allocate(10);
319 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
320 OF_Match_Types.MATCH_OF_ETH_DST.getValue(), 0, 6);
321 ipv6ext_destmac_msg.putInt(nxm_header);
322 ipv6ext_destmac_msg.put(destMac);
323 return (ipv6ext_destmac_msg.array());
326 private byte[] getIPv6ExtensionSrcMacMatchMsg(byte[] srcMac) {
327 ByteBuffer ipv6ext_srcmac_msg = ByteBuffer.allocate(10);
328 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
329 OF_Match_Types.MATCH_OF_ETH_SRC.getValue(), 0, 6);
330 ipv6ext_srcmac_msg.putInt(nxm_header);
331 ipv6ext_srcmac_msg.put(srcMac);
332 return (ipv6ext_srcmac_msg.array());
335 private byte[] getIPv6ExtensionEtherTypeMatchMsg(short EtherType) {
336 ByteBuffer ipv6ext_etype_msg = ByteBuffer.allocate(6);
337 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
338 OF_Match_Types.MATCH_OF_ETH_TYPE.getValue(), 0, 2);
339 ipv6ext_etype_msg.putInt(nxm_header);
340 ipv6ext_etype_msg.putShort(EtherType);
341 return (ipv6ext_etype_msg.array());
344 private byte[] getVlanTCI(short dataLayerVirtualLanID,
345 byte dataLayerVirtualLanPriorityCodePoint) {
346 ByteBuffer vlan_tci = ByteBuffer.allocate(2);
348 if (dataLayerVirtualLanID == OFP_VLAN_NONE) {
349 // Match only packets without VLAN tag.
352 // the pcp fields have to move by 13
353 int pcp = dataLayerVirtualLanPriorityCodePoint << 13;
354 vlan_tci_int = pcp + VLAN_TCI_CFI + dataLayerVirtualLanID;
356 vlan_tci.put((byte) (vlan_tci_int >> 8)); // bits 8 to 15
357 vlan_tci.put((byte) vlan_tci_int); // bits 0 to 7
358 return vlan_tci.array();
361 private byte[] getIPv6ExtensionVlanTCIMatchMsg(short dataLayerVirtualLanID,
362 byte dataLayerVirtualLanPriorityCodePoint) {
363 ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(6);
364 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
365 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
366 ipv6ext_vlan_tci_msg.putInt(nxm_header);
367 ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLanID,
368 dataLayerVirtualLanPriorityCodePoint));
369 return (ipv6ext_vlan_tci_msg.array());
372 private byte[] getIPv6ExtensionVlanTCIMatchWithMaskMsg(
373 short dataLayerVirtualLan,
374 byte dataLayerVirtualLanPriorityCodePoint,
375 int dataLayerVirtualLanTCIMask) {
376 ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(8);
377 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
378 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 1, 4);
379 ipv6ext_vlan_tci_msg.putInt(nxm_header);
380 ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLan,
381 dataLayerVirtualLanPriorityCodePoint));
382 ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask >> 8)); // bits
386 ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask)); // bits 0
388 return (ipv6ext_vlan_tci_msg.array());
391 private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
392 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
393 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
394 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 0,
396 ipv6ext_ipv6_msg.putInt(nxm_header);
397 ipv6ext_ipv6_msg.put(srcIpv6);
398 return (ipv6ext_ipv6_msg.array());
401 private byte[] getIPv6ExtensionSrcIPv6MatchwithMaskMsg(byte[] srcIpv6,
403 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
404 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
405 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC.getValue(), 1,
407 ipv6ext_ipv6_msg.putInt(nxm_header);
408 ipv6ext_ipv6_msg.put(srcIpv6);
409 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
410 ipv6ext_ipv6_msg.put(ipv6_mask);
411 return (ipv6ext_ipv6_msg.array());
414 private byte[] getIPv6ExtensionDstIPv6MatchMsg(byte[] dstIpv6) {
415 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(20);
416 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
417 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 0,
419 ipv6ext_ipv6_msg.putInt(nxm_header);
420 ipv6ext_ipv6_msg.put(dstIpv6);
421 return (ipv6ext_ipv6_msg.array());
424 private byte[] getIPv6ExtensionDstIPv6MatchwithMaskMsg(byte[] dstIpv6,
426 ByteBuffer ipv6ext_ipv6_msg = ByteBuffer.allocate(36);
427 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.IPV6EXT,
428 IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST.getValue(), 1,
430 ipv6ext_ipv6_msg.putInt(nxm_header);
431 ipv6ext_ipv6_msg.put(dstIpv6);
432 byte[] ipv6_mask = getIPv6NetworkMaskinBytes(masklen);
433 ipv6ext_ipv6_msg.put(ipv6_mask);
434 return (ipv6ext_ipv6_msg.array());
437 private byte[] getIPv6ExtensionProtocolMatchMsg(byte protocol) {
438 ByteBuffer ipv6ext_proto_msg = ByteBuffer.allocate(5);
439 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
440 OF_Match_Types.MATCH_OF_IP_PROTO.getValue(), 0, 1);
444 ipv6ext_proto_msg.putInt(nxm_header);
445 if (protocol == IPProtocols.ICMP.getValue()) {
447 * The front end passes the same protocol type values for IPv4 and
448 * IPv6 flows. For the Protocol types we allow in our GUI (ICMP,
449 * TCP, UDP), ICMP is the only one which is different for IPv6. It
450 * is 1 for v4 and 58 for v6 Therefore, we overwrite it here.
452 protocol = IPProtocols.ICMPV6.getValue();
454 ipv6ext_proto_msg.put(protocol);
455 return (ipv6ext_proto_msg.array());
458 private byte[] getIPv6ExtensionTOSMatchMsg(byte tos) {
459 ByteBuffer ipv6ext_tos_msg = ByteBuffer.allocate(5);
460 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
461 OF_Match_Types.MATCH_OF_IP_TOS.getValue(), 0, 1);
462 ipv6ext_tos_msg.putInt(nxm_header);
463 ipv6ext_tos_msg.put(tos);
464 return (ipv6ext_tos_msg.array());
467 private byte[] getIPv6ExtensionTCPSrcPortMatchMsg(short src_port) {
468 ByteBuffer ipv6ext_tcp_srcport_msg = ByteBuffer.allocate(6);
469 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
470 OF_Match_Types.MATCH_OF_TCP_SRC.getValue(), 0, 2);
471 ipv6ext_tcp_srcport_msg.putInt(nxm_header);
472 ipv6ext_tcp_srcport_msg.putShort(src_port);
473 return (ipv6ext_tcp_srcport_msg.array());
476 private byte[] getIPv6ExtensionTCPDstPortMatchMsg(short dst_port) {
477 ByteBuffer ipv6ext_tcp_dstport_msg = ByteBuffer.allocate(6);
478 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
479 OF_Match_Types.MATCH_OF_TCP_DST.getValue(), 0, 2);
480 ipv6ext_tcp_dstport_msg.putInt(nxm_header);
481 ipv6ext_tcp_dstport_msg.putShort(dst_port);
482 return (ipv6ext_tcp_dstport_msg.array());
485 private byte[] getIPv6ExtensionUDPSrcPortMatchMsg(short src_port) {
486 ByteBuffer ipv6ext_udp_srcport_msg = ByteBuffer.allocate(6);
487 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
488 OF_Match_Types.MATCH_OF_UDP_SRC.getValue(), 0, 2);
489 ipv6ext_udp_srcport_msg.putInt(nxm_header);
490 ipv6ext_udp_srcport_msg.putShort(src_port);
491 return (ipv6ext_udp_srcport_msg.array());
494 private byte[] getIPv6ExtensionUDPDstPortMatchMsg(short dst_port) {
495 ByteBuffer ipv6ext_udp_dstport_msg = ByteBuffer.allocate(6);
496 int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
497 OF_Match_Types.MATCH_OF_UDP_DST.getValue(), 0, 2);
498 ipv6ext_udp_dstport_msg.putInt(nxm_header);
499 ipv6ext_udp_dstport_msg.putShort(dst_port);
500 return (ipv6ext_udp_dstport_msg.array());
504 * Sets this (V6Match) object's member variables based on a comma-separated
505 * key=value pair similar to OFMatch's fromString.
508 * a key=value comma separated string.
511 public void fromString(String match) throws IllegalArgumentException {
512 if (match.equals("") || match.equalsIgnoreCase("any")
513 || match.equalsIgnoreCase("all") || match.equals("[]")) {
516 String[] tokens = match.split("[\\[,\\]]");
519 if (tokens[0].equals("OFMatch")) {
522 this.wildcards = OFPFW_ALL;
524 for (i = initArg; i < tokens.length; i++) {
525 values = tokens[i].split("=");
526 if (values.length != 2) {
527 throw new IllegalArgumentException("Token " + tokens[i]
528 + " does not have form 'key=value' parsing " + match);
530 values[0] = values[0].toLowerCase(); // try to make this case insens
531 if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) {
532 this.inputPort = U16.t(Integer.valueOf(values[1]));
533 inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
535 } else if (values[0].equals(STR_DL_DST)
536 || values[0].equals("eth_dst")) {
537 this.dataLayerDestination = HexEncode
538 .bytesFromHexString(values[1]);
539 dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
541 } else if (values[0].equals(STR_DL_SRC)
542 || values[0].equals("eth_src")) {
543 this.dataLayerSource = HexEncode.bytesFromHexString(values[1]);
544 dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
546 this.wildcards &= ~OFPFW_DL_SRC;
547 } else if (values[0].equals(STR_DL_TYPE)
548 || values[0].equals("eth_type")) {
549 if (values[1].startsWith("0x")) {
550 this.dataLayerType = U16.t(Integer.valueOf(values[1]
551 .replaceFirst("0x", ""), 16));
554 this.dataLayerType = U16.t(Integer.valueOf(values[1]));
556 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
558 } else if (values[0].equals(STR_DL_VLAN)) {
559 short vlan = U16.t(Integer.valueOf(values[1]));
560 if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT &&
561 vlan == OFP_VLAN_NONE) {
562 throw new IllegalArgumentException("DL_VLAN_PCP is set.");
564 this.dataLayerVirtualLan = vlan;
565 this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
566 // the variable dlVlanIDState is not really used as a flag
567 // for serializing and deserializing. Rather it is used as a
569 // to check if the vlan id is being set so that we can set the
570 // dlVlanTCIState appropriately.
571 if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
572 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
574 } else if (this.dataLayerVirtualLan == OFP_VLAN_NONE) {
575 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
578 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
579 this.dataLayerVirtualLanTCIMask = 0x1fff;
582 this.wildcards &= ~OFPFW_DL_VLAN;
583 } else if (values[0].equals(STR_DL_VLAN_PCP)) {
584 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT &&
585 this.dataLayerVirtualLan == OFP_VLAN_NONE) {
586 throw new IllegalArgumentException
587 ("OFP_VLAN_NONE is specified to DL_VLAN.");
589 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
590 .valueOf(values[1]));
591 this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
592 // the variable dlVlanPCPState is not really used as a flag
593 // for serializing and deserializing. Rather it is used as a
595 // to check if the vlan pcp is being set so that we can set the
596 // dlVlanTCIState appropriately.
597 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
598 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
601 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
602 this.dataLayerVirtualLanTCIMask = 0xf000;
605 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
606 } else if (values[0].equals(STR_NW_DST)
607 || values[0].equals("ip_dst")) {
609 InetAddress address = null;
610 InetAddress mask = null;
611 if (values[1].contains("/")) {
612 String addressString[] = values[1].split("/");
613 address = InetAddress.getByName(addressString[0]);
614 int masklen = Integer.valueOf(addressString[1]);
615 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
617 address = InetAddress.getByName(values[1]);
619 this.setNetworkDestination(address, mask);
620 } catch (UnknownHostException e) {
623 } else if (values[0].equals(STR_NW_SRC)
624 || values[0].equals("ip_src")) {
626 InetAddress address = null;
627 InetAddress mask = null;
628 if (values[1].contains("/")) {
629 String addressString[] = values[1].split("/");
630 address = InetAddress.getByName(addressString[0]);
631 int masklen = Integer.valueOf(addressString[1]);
632 mask = NetUtils.getInetNetworkMask(masklen, address instanceof Inet6Address);
634 address = InetAddress.getByName(values[1]);
636 this.setNetworkSource(address, mask);
637 } catch (UnknownHostException e) {
640 } else if (values[0].equals(STR_NW_PROTO)) {
641 this.networkProtocol = U8.t(Short.valueOf(values[1]));
642 if (!(this.networkProtocol == 0)) {
644 * if user selects proto 0, don't use it
646 nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
649 } else if (values[0].equals(STR_NW_TOS)) {
650 this.networkTypeOfService = U8.t(Short.valueOf(values[1]));
651 nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
653 } else if (values[0].equals(STR_TP_DST)) {
654 this.transportDestination = U16.t(Integer.valueOf(values[1]));
655 tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
657 } else if (values[0].equals(STR_TP_SRC)) {
658 this.transportSource = U16.t(Integer.valueOf(values[1]));
659 tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
662 throw new IllegalArgumentException("unknown token " + tokens[i]
663 + " parsing " + match);
668 * In a V6 extension message action list should be preceded by a padding
669 * of 0 to 7 bytes based upon following formula.
672 pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
677 * Write this message's binary format to the specified ByteBuffer
682 public void writeTo(ByteBuffer data) {
683 if (inputPortState == MatchFieldState.MATCH_FIELD_ONLY) {
684 byte[] ipv6ext_ingress_port_msg = getIPv6ExtensionPortMatchMsg(this.inputPort);
685 data.put(ipv6ext_ingress_port_msg);
687 if (ethTypeState == MatchFieldState.MATCH_FIELD_ONLY) {
688 byte[] ipv6ext_ether_type_msg = getIPv6ExtensionEtherTypeMatchMsg(this.dataLayerType);
689 data.put(ipv6ext_ether_type_msg);
691 if (dlDestState == MatchFieldState.MATCH_FIELD_ONLY) {
692 byte[] ipv6ext_destmac_msg = getIPv6ExtensionDestMacMatchMsg(this.dataLayerDestination);
693 data.put(ipv6ext_destmac_msg);
695 if (dlSourceState == MatchFieldState.MATCH_FIELD_ONLY) {
696 byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
697 data.put(ipv6ext_srcmac_msg);
699 if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_ONLY) {
700 byte[] ipv6ext_vlan_tci_msg = getIPv6ExtensionVlanTCIMatchMsg(
701 this.dataLayerVirtualLan,
702 this.dataLayerVirtualLanPriorityCodePoint);
703 data.put(ipv6ext_vlan_tci_msg);
704 } else if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
705 byte[] ipv6ext_vlan_tci_msg_with_mask = getIPv6ExtensionVlanTCIMatchWithMaskMsg(
706 this.dataLayerVirtualLan,
707 this.dataLayerVirtualLanPriorityCodePoint,
708 this.dataLayerVirtualLanTCIMask);
709 data.put(ipv6ext_vlan_tci_msg_with_mask);
711 if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
712 byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
714 data.put(ipv6ext_src_ipv6_msg);
715 } else if (nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
716 byte[] ipv6ext_src_ipv6_with_mask_msg = getIPv6ExtensionSrcIPv6MatchwithMaskMsg(
717 this.nwSrc.getAddress(), this.srcIPv6SubnetMaskbits);
718 data.put(ipv6ext_src_ipv6_with_mask_msg);
720 if (nwDstState == MatchFieldState.MATCH_FIELD_ONLY) {
721 byte[] ipv6ext_dst_ipv6_msg = getIPv6ExtensionDstIPv6MatchMsg(this.nwDst
723 data.put(ipv6ext_dst_ipv6_msg);
724 } else if (nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
725 byte[] ipv6ext_dst_ipv6_with_mask_msg = getIPv6ExtensionDstIPv6MatchwithMaskMsg(
726 this.nwDst.getAddress(), this.dstIPv6SubnetMaskbits);
727 data.put(ipv6ext_dst_ipv6_with_mask_msg);
729 if (nwProtoState == MatchFieldState.MATCH_FIELD_ONLY) {
730 byte[] ipv6ext_protocol_msg = getIPv6ExtensionProtocolMatchMsg(this.networkProtocol);
731 if (ipv6ext_protocol_msg != null) {
732 data.put(ipv6ext_protocol_msg);
735 if (nwTosState == MatchFieldState.MATCH_FIELD_ONLY) {
736 byte[] ipv6ext_tos_msg = getIPv6ExtensionTOSMatchMsg(this.networkTypeOfService);
737 data.put(ipv6ext_tos_msg);
739 if (tpSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
740 byte[] ipv6ext_srcport_msg = null;
741 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
742 ipv6ext_srcport_msg = getIPv6ExtensionTCPSrcPortMatchMsg(this.transportSource);
743 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
744 ipv6ext_srcport_msg = getIPv6ExtensionUDPSrcPortMatchMsg(this.transportSource);
746 if (ipv6ext_srcport_msg != null) {
747 data.put(ipv6ext_srcport_msg);
750 if (tpDstState == MatchFieldState.MATCH_FIELD_ONLY) {
751 byte[] ipv6ext_dstport_msg = null;
752 if (this.networkProtocol == IPProtocols.TCP.getValue()) {
753 ipv6ext_dstport_msg = getIPv6ExtensionTCPDstPortMatchMsg(this.transportDestination);
754 } else if (this.networkProtocol == IPProtocols.UDP.getValue()) {
755 ipv6ext_dstport_msg = getIPv6ExtensionUDPDstPortMatchMsg(this.transportDestination);
757 if (ipv6ext_dstport_msg != null) {
758 data.put(ipv6ext_dstport_msg);
761 logger.trace("{}", this);
764 private void readInPort(ByteBuffer data, int nxmLen, boolean hasMask) {
765 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
767 * mask is not allowed for inport port
771 super.setInputPort(data.getShort());
772 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
773 this.wildcards ^= (1 << 0); // Sync with 0F 1.0 Match
777 private void readDataLinkDestination(ByteBuffer data, int nxmLen,
780 if ((nxmLen != 2 * 6) || (data.remaining() < 2 * 6)) {
783 byte[] bytes = new byte[6];
785 super.setDataLayerDestination(bytes);
786 this.dataLayerDestinationMask = new byte[6];
787 data.get(this.dataLayerDestinationMask);
788 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
789 this.match_len += 16;
792 if ((nxmLen != 6) || (data.remaining() < 6)) {
795 byte[] bytes = new byte[6];
797 super.setDataLayerDestination(bytes);
798 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
799 this.match_len += 10;
802 this.wildcards ^= (1 << 3); // Sync with 0F 1.0 Match
805 private void readDataLinkSource(ByteBuffer data, int nxmLen, boolean hasMask) {
807 * mask is not allowed in data link source
809 if ((nxmLen != 6) || (data.remaining() < 6) || (hasMask)) {
812 byte[] bytes = new byte[6];
814 super.setDataLayerSource(bytes);
815 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
816 this.match_len += 10;
817 this.wildcards ^= (1 << 2); // Sync with 0F 1.0 Match
820 private void readEtherType(ByteBuffer data, int nxmLen, boolean hasMask) {
822 * mask is not allowed in ethertype
824 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
827 super.setDataLayerType(data.getShort());
828 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
829 this.wildcards ^= (1 << 4); // Sync with 0F 1.0 Match
833 private short getVlanID(byte firstByte, byte secondByte) {
834 short vlan_id_mask_firstByte = 0x0f;// this is the mask for the first
836 short vlan_id_mask_secondByte = 0xff;// this is the mask for the second
838 int vlanPart1 = (firstByte & vlan_id_mask_firstByte) << 8;
839 int vlanPart2 = secondByte & vlan_id_mask_secondByte;
840 return (short) (vlanPart1 + vlanPart2);
843 private byte getVlanPCP(byte pcpByte) {
844 short vlan_pcp_mask = 0xe0;// this is the vlan pcp mask
845 int pcp_int = pcpByte & vlan_pcp_mask;
846 return (byte) (pcp_int >> 5);
849 private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
851 if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
855 byte firstByte = data.get();
856 byte secondByte = data.get();
857 this.dataLayerVirtualLanTCIMask = data.getShort() & 0xffff; // we
863 // check the mask now
864 if ((this.dataLayerVirtualLanTCIMask & 0x0fff) != 0) {
865 // if its a vlan id mask
866 // extract the vlan id
867 super.setDataLayerVirtualLan(getVlanID(firstByte,
869 this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
871 if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
872 // else if its a vlan pcp mask
873 // extract the vlan pcp
874 super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
875 this.wildcards ^= (1 << 20);
877 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
881 if ((nxmLen != 2) || (data.remaining() < 2)) {
886 byte firstByte = data.get();
887 byte secondByte = data.get();
888 if (firstByte == 0 && secondByte == 0) {
889 // Match only packets without VLAN tag.
890 setDataLayerVirtualLan(OFP_VLAN_NONE);
891 } else if (((firstByte << 8) & VLAN_TCI_CFI) == 0) {
892 // Ignore invalid TCI field.
895 super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
896 super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
897 this.wildcards ^= (1 << 20);
899 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
901 this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
906 private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
908 * mask is not allowed in IP TOS
910 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
913 super.setNetworkTypeOfService(data.get());
914 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
916 this.wildcards ^= (1 << 21); // Sync with 0F 1.0 Match
919 private void readIpProto(ByteBuffer data, int nxmLen, boolean hasMask) {
921 * mask is not allowed in IP protocol
923 if ((nxmLen != 1) || (data.remaining() < 1) || (hasMask)) {
926 super.setNetworkProtocol(data.get());
927 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
929 this.wildcards ^= (1 << 5); // Sync with 0F 1.0 Match
932 private void readIpv4Src(ByteBuffer data, int nxmLen, boolean hasMask) {
934 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
937 byte[] sbytes = new byte[4];
939 // For compatibility, let's set the IPv4 in the parent OFMatch
940 int address = NetUtils.byteArray4ToInt(sbytes);
941 super.setNetworkSource(address);
942 byte[] mbytes = new byte[4];
944 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
945 this.match_len += 12;
946 int prefixlen = getNetworkMaskPrefixLength(mbytes);
947 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
948 this.wildcards |= ((32 - prefixlen) << 8); // Sync with 0F 1.0 Match
951 if ((nxmLen != 4) || (data.remaining() < 4)) {
954 byte[] sbytes = new byte[4];
956 // For compatibility, let's also set the IPv4 in the parent OFMatch
957 int address = NetUtils.byteArray4ToInt(sbytes);
958 super.setNetworkSource(address);
959 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
961 this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0
967 private void readIpv4Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
969 if ((nxmLen != 2 * 4) || (data.remaining() < 2 * 4)) {
972 byte[] dbytes = new byte[4];
974 // For compatibility, let's also set the IPv4 in the parent OFMatch
975 int address = NetUtils.byteArray4ToInt(dbytes);
976 super.setNetworkDestination(address);
977 byte[] mbytes = new byte[4];
979 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
980 this.match_len += 12;
981 int prefixlen = getNetworkMaskPrefixLength(mbytes);
982 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
984 this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0
988 if ((nxmLen != 4) || (data.remaining() < 4)) {
991 byte[] dbytes = new byte[4];
993 int address = NetUtils.byteArray4ToInt(dbytes);
994 super.setNetworkDestination(address);
995 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
996 this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
1003 private void readTcpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
1005 * mask is not allowed in TCP SRC
1007 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1010 super.setTransportSource(data.getShort());
1011 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1012 this.match_len += 6;
1013 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
1016 private void readTcpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
1018 * mask is not allowed in TCP DST
1020 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1023 super.setTransportDestination(data.getShort());
1024 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1025 this.match_len += 6;
1026 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
1029 private void readUdpSrc(ByteBuffer data, int nxmLen, boolean hasMask) {
1031 * mask is not allowed in UDP SRC
1033 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1036 super.setTransportSource(data.getShort());
1037 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1038 this.match_len += 6;
1039 this.wildcards ^= (1 << 6); // Sync with 0F 1.0 Match
1042 private void readUdpDst(ByteBuffer data, int nxmLen, boolean hasMask) {
1044 * mask is not allowed in UDP DST
1046 if ((nxmLen != 2) || (data.remaining() < 2) || (hasMask)) {
1049 super.setTransportDestination(data.getShort());
1050 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1051 this.match_len += 6;
1052 this.wildcards ^= (1 << 7); // Sync with 0F 1.0 Match
1055 private void readIpv6Src(ByteBuffer data, int nxmLen, boolean hasMask) {
1057 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
1060 byte[] sbytes = new byte[16];
1063 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
1064 } catch (UnknownHostException e) {
1067 byte[] mbytes = new byte[16];
1069 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
1070 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1071 this.match_len += 36;
1074 if ((nxmLen != 16) || (data.remaining() < 16)) {
1077 byte[] sbytes = new byte[16];
1080 this.nwSrc = (Inet6Address) InetAddress.getByAddress(sbytes);
1081 } catch (UnknownHostException e) {
1084 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1085 this.match_len += 20;
1090 private void readIpv6Dst(ByteBuffer data, int nxmLen, boolean hasMask) {
1092 if ((nxmLen != 2 * 16) || (data.remaining() < 2 * 16)) {
1095 byte[] dbytes = new byte[16];
1098 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
1099 } catch (UnknownHostException e) {
1102 byte[] mbytes = new byte[16];
1104 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mbytes);
1105 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1106 this.match_len += 36;
1109 if ((nxmLen != 16) || (data.remaining() < 16)) {
1112 byte[] dbytes = new byte[16];
1115 this.nwDst = (Inet6Address) InetAddress.getByAddress(dbytes);
1116 } catch (UnknownHostException e) {
1119 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1120 this.match_len += 20;
1126 public String toString() {
1127 return "V6Match [nwSrc=" + nwSrc + ", nwDst=" + nwDst
1128 + ", inputPortMask=" + inputPortMask + ", dataLayerSourceMask="
1129 + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
1130 + ", dataLayerDestinationMask="
1131 + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
1132 + ", dataLayerVirtualLanTCIMask=" + dataLayerVirtualLanTCIMask
1133 + ", dataLayerTypeMask=" + dataLayerTypeMask
1134 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
1135 + ", networkProtocolMask=" + networkProtocolMask
1136 + ", transportSourceMask=" + transportSourceMask
1137 + ", transportDestinationMask=" + transportDestinationMask
1138 + ", srcIPv6SubnetMaskbits=" + srcIPv6SubnetMaskbits
1139 + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
1140 + ", inputPortState=" + inputPortState + ", dlSourceState="
1141 + dlSourceState + ", dlDestState=" + dlDestState
1142 + ", dlVlanTCIState=" + dlVlanTCIState + ", ethTypeState="
1143 + ethTypeState + ", nwTosState=" + nwTosState
1144 + ", nwProtoState=" + nwProtoState + ", nwSrcState="
1145 + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
1146 + tpSrcState + ", tpDstState=" + tpDstState + ", match_len="
1147 + match_len + ", pad_size=" + pad_size + "]";
1151 * Read the data corresponding to the match field (received from the wire)
1152 * Input: data: match field(s). Since match field is of variable length, the
1153 * whole data that are passed in are assumed to fem0tbd.be the match fields.
1158 public void readFrom(ByteBuffer data) {
1159 readFromInternal(data);
1160 postprocessWildCardInfo();
1163 private void readFromInternal(ByteBuffer data) {
1165 while (data.remaining() > 0) {
1166 if (data.remaining() < 4) {
1168 * at least 4 bytes for each match header
1170 logger.error("Invalid Vendor Extension Header. Size {}",
1175 * read the 4 byte match header
1177 int nxmVendor = data.getShort();
1179 int nxmField = b >> 1;
1180 boolean hasMask = ((b & 0x01) == 1) ? true : false;
1181 int nxmLen = data.get();
1182 if (nxmVendor == Extension_Types.OF_10.getValue()) {
1183 if (nxmField == OF_Match_Types.MATCH_OF_IN_PORT.getValue()) {
1184 readInPort(data, nxmLen, hasMask);
1185 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_DST
1187 readDataLinkDestination(data, nxmLen, hasMask);
1188 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_SRC
1190 readDataLinkSource(data, nxmLen, hasMask);
1191 } else if (nxmField == OF_Match_Types.MATCH_OF_ETH_TYPE
1193 readEtherType(data, nxmLen, hasMask);
1194 } else if (nxmField == OF_Match_Types.MATCH_OF_VLAN_TCI
1196 readVlanTci(data, nxmLen, hasMask);
1197 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_TOS
1199 readIpTos(data, nxmLen, hasMask);
1200 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_PROTO
1202 readIpProto(data, nxmLen, hasMask);
1203 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_SRC
1205 readIpv4Src(data, nxmLen, hasMask);
1206 } else if (nxmField == OF_Match_Types.MATCH_OF_IP_DST
1208 readIpv4Dst(data, nxmLen, hasMask);
1209 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_SRC
1211 readTcpSrc(data, nxmLen, hasMask);
1212 } else if (nxmField == OF_Match_Types.MATCH_OF_TCP_DST
1214 readTcpDst(data, nxmLen, hasMask);
1215 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_SRC
1217 readUdpSrc(data, nxmLen, hasMask);
1218 } else if (nxmField == OF_Match_Types.MATCH_OF_UDP_DST
1220 readUdpDst(data, nxmLen, hasMask);
1222 // unexpected nxmField
1225 } else if (nxmVendor == Extension_Types.IPV6EXT.getValue()) {
1226 if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_SRC
1228 readIpv6Src(data, nxmLen, hasMask);
1229 } else if (nxmField == IPv6Extension_Match_Types.MATCH_IPV6EXT_IPV6_DST
1231 readIpv6Dst(data, nxmLen, hasMask);
1233 // unexpected nxmField
1237 // invalid nxmVendor
1243 private void postprocessWildCardInfo() {
1244 // Sync with 0F 1.0 Match
1245 if (super.getDataLayerType() == 0x800) {
1246 if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
1247 // ipv4 src processing
1248 this.wildcards ^= (((1 << 5) - 1) << 8);
1250 if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
1251 // ipv4 dest processing
1252 this.wildcards ^= (((1 << 5) - 1) << 14);
1258 public V6Match clone() {
1260 V6Match ret = (V6Match) super.clone();
1262 if (this.nwSrc != null) {
1263 ret.nwSrc = (Inet6Address) InetAddress.getByAddress(this.nwSrc.getAddress());
1265 if (this.nwDst != null) {
1266 ret.nwDst = (Inet6Address) InetAddress.getByAddress(this.nwDst.getAddress());
1269 } catch (UnknownHostException e) {
1270 throw new RuntimeException(e);
1279 public Inet6Address getNetworkDest() {
1288 public Inet6Address getNetworkSrc() {
1292 private int getNetworkMaskPrefixLength(byte[] netMask) {
1293 ByteBuffer nm = ByteBuffer.wrap(netMask);
1294 int trailingZeros = Integer.numberOfTrailingZeros(nm.getInt());
1295 return 32 - trailingZeros;
1298 public short getInputPortMask() {
1299 return inputPortMask;
1302 public void setInputPort(short port, short mask) {
1303 super.inputPort = port;
1304 this.inputPortState = MatchFieldState.MATCH_FIELD_ONLY;
1306 // Looks like mask is not allowed for input port. Will discard it
1309 public byte[] getDataLayerSourceMask() {
1310 return dataLayerSourceMask;
1313 public void setDataLayerSource(byte[] mac, byte[] mask) {
1315 System.arraycopy(mac, 0, super.dataLayerSource, 0, mac.length);
1318 this.dlSourceState = MatchFieldState.MATCH_FIELD_ONLY;
1319 this.match_len += 10;
1321 if (this.dataLayerSourceMask == null) {
1322 this.dataLayerSourceMask = new byte[mask.length];
1324 System.arraycopy(mask, 0, this.dataLayerSourceMask, 0, mask.length);
1325 this.dlSourceState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1326 this.match_len += 16;
1330 public byte[] getDataLayerDestinationMask() {
1331 return dataLayerDestinationMask;
1334 public void setDataLayerDestination(byte[] mac, byte[] mask) {
1336 System.arraycopy(mac, 0, super.dataLayerDestination, 0, mac.length);
1339 this.dlDestState = MatchFieldState.MATCH_FIELD_ONLY;
1340 this.match_len += 10;
1342 if (this.dataLayerDestinationMask == null) {
1343 this.dataLayerDestinationMask = new byte[mask.length];
1345 System.arraycopy(mask, 0, this.dataLayerDestinationMask, 0,
1347 this.dlDestState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1348 this.match_len += 16;
1353 * Set a value to VLAN ID match field.
1355 * @param vlan A value to match for VLAN ID.
1356 * @param mask A bitmask for VLAN ID.
1358 public void setDataLayerVirtualLan(short vlan, short mask) {
1359 if (vlan == OFP_VLAN_NONE
1360 && this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
1361 throw new IllegalStateException
1362 ("DL_VLAN_PCP is set.");
1365 // mask is ignored as the code sets the appropriate mask
1366 super.dataLayerVirtualLan = vlan;
1367 this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
1368 // the variable dlVlanIDState is not really used as a flag
1369 // for serializing and deserializing. Rather it is used as a flag
1370 // to check if the vlan id is being set so that we can set the
1371 // dlVlanTCIState appropriately.
1372 if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
1373 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
1375 } else if (this.dataLayerVirtualLan == OFP_VLAN_NONE) {
1376 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
1379 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1380 this.dataLayerVirtualLanTCIMask = 0x1fff;
1386 * Set a value to VLAN PCP match field.
1388 * @param pcp A value to match for VLAN PCP.
1389 * @param mask A bitmask for VLAN PCP.
1391 public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
1392 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT
1393 && this.dataLayerVirtualLan == OFP_VLAN_NONE) {
1394 throw new IllegalStateException
1395 ("OFP_VLAN_NONE is specified to DL_VLAN.");
1398 // mask is ignored as the code sets the appropriate mask
1399 super.dataLayerVirtualLanPriorityCodePoint = pcp;
1400 this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
1401 // the variable dlVlanPCPState is not really used as a flag
1402 // for serializing and deserializing. Rather it is used as a flag
1403 // to check if the vlan pcp is being set so that we can set the
1404 // dlVlanTCIState appropriately.
1405 if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
1406 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
1409 this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1410 this.dataLayerVirtualLanTCIMask = 0xf000;
1415 public void setDataLayerType(short ethType, short mask) {
1417 super.dataLayerType = ethType;
1418 this.ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
1419 this.match_len += 6;
1422 public void setNetworkTypeOfService(byte tos, byte mask) {
1424 super.networkTypeOfService = tos;
1425 this.nwTosState = MatchFieldState.MATCH_FIELD_ONLY;
1429 public void setNetworkProtocol(byte ipProto, byte mask) {
1431 super.networkProtocol = ipProto;
1432 this.nwProtoState = MatchFieldState.MATCH_FIELD_ONLY;
1433 this.match_len += 5;
1436 public Inet6Address getNetworkSourceMask() {
1437 return (this.nwSrcState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1438 this.srcIPv6SubnetMaskbits, true) : null;
1441 public void setNetworkSource(InetAddress address, InetAddress mask) {
1442 if (address instanceof Inet6Address) {
1443 this.nwSrc = (Inet6Address) address;
1445 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1446 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1448 this.srcIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1449 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1450 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1453 super.setNetworkSource(NetUtils.byteArray4ToInt(address.getAddress()));
1454 this.wildcards ^= (((1 << 6) - 1) << 8);
1456 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1457 this.match_len += 8;
1459 this.nwSrcState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1460 this.match_len += 12;
1461 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 8);
1466 public Inet6Address getNetworkDestinationMask() {
1467 return (this.nwDstState == MatchFieldState.MATCH_FIELD_WITH_MASK) ? (Inet6Address) NetUtils.getInetNetworkMask(
1468 this.dstIPv6SubnetMaskbits, true) : null;
1471 public void setNetworkDestination(InetAddress address, InetAddress mask) {
1472 if (address instanceof Inet6Address) {
1473 this.nwDst = (Inet6Address) address;
1475 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1476 this.match_len += (address instanceof Inet6Address) ? 20 : 8;
1478 this.dstIPv6SubnetMaskbits = (short)NetUtils.getSubnetMaskLength(mask);
1479 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1480 this.match_len += (address instanceof Inet6Address) ? 36 : 12;
1483 this.setNetworkDestination(NetUtils.byteArray4ToInt(address.getAddress()));
1484 this.wildcards ^= (((1 << 6) - 1) << 14);
1486 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
1487 this.match_len += 8;
1489 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
1490 this.match_len += 12;
1491 this.wildcards |= ((32 - NetUtils.getSubnetMaskLength(mask)) << 14);
1496 public void setTransportSource(short tpSrc, short mask) {
1498 super.transportSource = tpSrc;
1499 this.tpSrcState = MatchFieldState.MATCH_FIELD_ONLY;
1500 this.match_len += 6;
1503 public short getTransportDestinationMask() {
1504 return transportDestinationMask;
1507 public void setTransportDestination(short tpDst, short mask) {
1509 super.transportDestination = tpDst;
1510 this.tpDstState = MatchFieldState.MATCH_FIELD_ONLY;
1511 this.match_len += 6;
1514 private byte[] getIPv6NetworkMaskinBytes(short num) {
1515 byte[] nbytes = new byte[16];
1520 for (i = 0; i < quot; i++) {
1521 nbytes[i] = (byte) 0xff;
1525 nbytes[i] = (byte) 0xff;
1526 nbytes[i] <<= 8 - bits;
1532 public int hashCode() {
1533 final int prime = 31;
1534 int result = super.hashCode();
1535 result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
1536 result = prime * result + Arrays.hashCode(dataLayerSourceMask);
1537 result = prime * result + dataLayerTypeMask;
1538 result = prime * result + dataLayerVirtualLanTCIMask;
1539 result = prime * result
1540 + ((dlDestState == null) ? 0 : dlDestState.hashCode());
1541 result = prime * result
1542 + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
1543 result = prime * result
1544 + ((dlVlanTCIState == null) ? 0 : dlVlanTCIState.hashCode());
1545 result = prime * result + dstIPv6SubnetMaskbits;
1546 result = prime * result
1547 + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
1548 result = prime * result + inputPortMask;
1549 result = prime * result
1550 + ((inputPortState == null) ? 0 : inputPortState.hashCode());
1551 result = prime * result + match_len;
1552 result = prime * result + networkProtocolMask;
1553 result = prime * result + networkTypeOfServiceMask;
1554 result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
1555 result = prime * result
1556 + ((nwDstState == null) ? 0 : nwDstState.hashCode());
1557 result = prime * result
1558 + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
1559 result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
1560 result = prime * result
1561 + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
1562 result = prime * result
1563 + ((nwTosState == null) ? 0 : nwTosState.hashCode());
1564 result = prime * result + pad_size;
1565 result = prime * result + srcIPv6SubnetMaskbits;
1566 result = prime * result
1567 + ((tpDstState == null) ? 0 : tpDstState.hashCode());
1568 result = prime * result
1569 + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
1570 result = prime * result + transportDestinationMask;
1571 result = prime * result + transportSourceMask;
1576 public boolean equals(Object obj) {
1580 if (!super.equals(obj)) {
1583 if (getClass() != obj.getClass()) {
1586 V6Match other = (V6Match) obj;
1587 if (!Arrays.equals(dataLayerDestinationMask, other.dataLayerDestinationMask)) {
1590 if (!Arrays.equals(dataLayerSourceMask, other.dataLayerSourceMask)) {
1593 if (dataLayerTypeMask != other.dataLayerTypeMask) {
1596 if (dataLayerVirtualLanTCIMask != other.dataLayerVirtualLanTCIMask) {
1599 if (dlVlanTCIState != other.dlVlanTCIState) {
1602 if (dlSourceState != other.dlSourceState) {
1605 if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
1608 if (ethTypeState != other.ethTypeState) {
1611 if (inputPortMask != other.inputPortMask) {
1614 if (inputPortState != other.inputPortState) {
1617 if (match_len != other.match_len) {
1620 if (networkProtocolMask != other.networkProtocolMask) {
1623 if (networkTypeOfServiceMask != other.networkTypeOfServiceMask) {
1626 if (nwDst == null) {
1627 if (other.nwDst != null) {
1630 } else if (!nwDst.equals(other.nwDst)) {
1633 if (nwDstState != other.nwDstState) {
1636 if (nwProtoState != other.nwProtoState) {
1639 if (nwSrc == null) {
1640 if (other.nwSrc != null) {
1643 } else if (!nwSrc.equals(other.nwSrc)) {
1646 if (nwSrcState != other.nwSrcState) {
1649 if (nwTosState != other.nwTosState) {
1652 if (pad_size != other.pad_size) {
1655 if (srcIPv6SubnetMaskbits != other.srcIPv6SubnetMaskbits) {
1658 if (tpDstState != other.tpDstState) {
1661 if (tpSrcState != other.tpSrcState) {
1664 if (transportDestinationMask != other.transportDestinationMask) {
1667 if (transportSourceMask != other.transportSourceMask) {