2 * Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations
18 package org.openflow.protocol;
20 import java.io.Serializable;
21 import java.nio.ByteBuffer;
22 import java.util.Arrays;
25 import org.jboss.netty.buffer.ChannelBuffer;
26 import org.openflow.util.HexString;
27 import org.openflow.util.U16;
28 import org.openflow.util.U8;
31 * Represents an ofp_match structure
33 * @author David Erickson (daviderickson@cs.stanford.edu)
34 * @author Rob Sherwood (rob.sherwood@stanford.edu)
36 public class OFMatch implements Cloneable, Serializable {
42 public static final short VLAN_UNTAGGED = (short)0xffff;
44 private static final long serialVersionUID = 1L;
45 public static int MINIMUM_LENGTH = 40;
46 final public static int OFPFW_ALL = ((1 << 22) - 1);
48 final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
49 final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
50 final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
51 final public static int OFPFW_DL_DST = 1 << 3; /*
52 * Ethernet destination
55 final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
56 final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
57 final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
58 final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */
61 * IP source address wildcard bit count. 0 is exact match, 1 ignores the
62 * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
63 * the entire field. This is the *opposite* of the usual convention where
64 * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
66 final public static int OFPFW_NW_SRC_SHIFT = 8;
67 final public static int OFPFW_NW_SRC_BITS = 6;
68 final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
69 final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;
71 /* IP destination address wildcard bit count. Same format as source. */
72 final public static int OFPFW_NW_DST_SHIFT = 14;
73 final public static int OFPFW_NW_DST_BITS = 6;
74 final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
75 final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;
77 final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
78 final public static int OFPFW_NW_TOS = 1 << 21; /*
79 * IP ToS (DSCP field, 6
83 final public static int OFPFW_ALL_SANITIZED = (((1 << 22) - 1)
84 & ~OFPFW_NW_SRC_MASK & ~OFPFW_NW_DST_MASK)
88 /* List of Strings for marshalling and unmarshalling to human readable forms */
89 final public static String STR_IN_PORT = "in_port";
90 final public static String STR_DL_DST = "dl_dst";
91 final public static String STR_DL_SRC = "dl_src";
92 final public static String STR_DL_TYPE = "dl_type";
93 final public static String STR_DL_VLAN = "dl_vlan";
94 final public static String STR_DL_VLAN_PCP = "dl_vlan_pcp";
95 final public static String STR_NW_DST = "nw_dst";
96 final public static String STR_NW_SRC = "nw_src";
97 final public static String STR_NW_PROTO = "nw_proto";
98 final public static String STR_NW_TOS = "nw_tos";
99 final public static String STR_TP_DST = "tp_dst";
100 final public static String STR_TP_SRC = "tp_src";
102 protected int wildcards;
103 protected short inputPort;
104 protected byte[] dataLayerSource;
105 protected byte[] dataLayerDestination;
106 protected short dataLayerVirtualLan;
107 protected byte dataLayerVirtualLanPriorityCodePoint;
108 protected short dataLayerType;
109 protected byte networkTypeOfService;
110 protected byte networkProtocol;
111 protected int networkSource;
112 protected int networkDestination;
113 protected short transportSource;
114 protected short transportDestination;
117 * By default, create a OFMatch that matches everything (mostly because it's
118 * the least amount of work to make a valid OFMatch)
121 this.wildcards = OFPFW_ALL;
122 this.dataLayerDestination = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0,
124 this.dataLayerSource = new byte[] { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
125 this.dataLayerVirtualLan = VLAN_UNTAGGED;
126 this.dataLayerVirtualLanPriorityCodePoint = 0;
127 this.dataLayerType = 0;
129 this.networkProtocol = 0;
130 this.networkTypeOfService = 0;
131 this.networkSource = 0;
132 this.networkDestination = 0;
133 this.transportDestination = 0;
134 this.transportSource = 0;
140 * @return an arrays of bytes
142 public byte[] getDataLayerDestination() {
143 return this.dataLayerDestination;
149 * @param dataLayerDestination
151 public OFMatch setDataLayerDestination(byte[] dataLayerDestination) {
152 this.dataLayerDestination = dataLayerDestination;
157 * Set dl_dst, but first translate to byte[] using HexString
160 * A colon separated string of 6 pairs of octets, e..g.,
161 * "00:17:42:EF:CD:8D"
163 public OFMatch setDataLayerDestination(String mac) {
164 byte bytes[] = HexString.fromHexString(mac);
165 if (bytes.length != 6)
166 throw new IllegalArgumentException(
167 "expected string with 6 octets, got '"
170 this.dataLayerDestination = bytes;
177 * @return an array of bytes
179 public byte[] getDataLayerSource() {
180 return this.dataLayerSource;
186 * @param dataLayerSource
188 public OFMatch setDataLayerSource(byte[] dataLayerSource) {
189 this.dataLayerSource = dataLayerSource;
194 * Set dl_src, but first translate to byte[] using HexString
197 * A colon separated string of 6 pairs of octets, e..g.,
198 * "00:17:42:EF:CD:8D"
200 public OFMatch setDataLayerSource(String mac) {
201 byte bytes[] = HexString.fromHexString(mac);
202 if (bytes.length != 6)
203 throw new IllegalArgumentException(
204 "expected string with 6 octets, got '"
207 this.dataLayerSource = bytes;
216 public short getDataLayerType() {
217 return this.dataLayerType;
223 * @param dataLayerType
225 public OFMatch setDataLayerType(short dataLayerType) {
226 this.dataLayerType = dataLayerType;
233 * @return vlan tag; VLAN_NONE == no tag
235 public short getDataLayerVirtualLan() {
236 return this.dataLayerVirtualLan;
242 * @param dataLayerVirtualLan
244 public OFMatch setDataLayerVirtualLan(short dataLayerVirtualLan) {
245 this.dataLayerVirtualLan = dataLayerVirtualLan;
254 public byte getDataLayerVirtualLanPriorityCodePoint() {
255 return this.dataLayerVirtualLanPriorityCodePoint;
263 public OFMatch setDataLayerVirtualLanPriorityCodePoint(byte pcp) {
264 this.dataLayerVirtualLanPriorityCodePoint = pcp;
273 public short getInputPort() {
274 return this.inputPort;
282 public OFMatch setInputPort(short inputPort) {
283 this.inputPort = inputPort;
292 public int getNetworkDestination() {
293 return this.networkDestination;
299 * @param networkDestination
301 public OFMatch setNetworkDestination(int networkDestination) {
302 this.networkDestination = networkDestination;
307 * Parse this match's wildcard fields and return the number of significant
308 * bits in the IP destination field. NOTE: this returns the number of bits
309 * that are fixed, i.e., like CIDR, not the number of bits that are free
310 * like OpenFlow encodes.
312 * @return a number between 0 (matches all IPs) and 63 ( 32>= implies exact
315 public int getNetworkDestinationMaskLen() {
316 return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
321 * Parse this match's wildcard fields and return the number of significant
322 * bits in the IP destination field. NOTE: this returns the number of bits
323 * that are fixed, i.e., like CIDR, not the number of bits that are free
324 * like OpenFlow encodes.
326 * @return a number between 0 (matches all IPs) and 32 (exact match)
328 public int getNetworkSourceMaskLen() {
329 return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
338 public byte getNetworkProtocol() {
339 return this.networkProtocol;
345 * @param networkProtocol
347 public OFMatch setNetworkProtocol(byte networkProtocol) {
348 this.networkProtocol = networkProtocol;
357 public int getNetworkSource() {
358 return this.networkSource;
364 * @param networkSource
366 public OFMatch setNetworkSource(int networkSource) {
367 this.networkSource = networkSource;
372 * Get nw_tos OFMatch stores the ToS bits as top 6-bits, so right shift by 2
373 * bits before returning the value
375 * @return : 6-bit DSCP value (0-63)
377 public byte getNetworkTypeOfService() {
378 return (byte) ((this.networkTypeOfService >> 2) & 0x3f);
382 * Set nw_tos OFMatch stores the ToS bits as top 6-bits, so left shift by 2
383 * bits before storing the value
385 * @param networkTypeOfService
386 * : 6-bit DSCP value (0-63)
388 public OFMatch setNetworkTypeOfService(byte networkTypeOfService) {
389 this.networkTypeOfService = (byte) (networkTypeOfService << 2);
398 public short getTransportDestination() {
399 return this.transportDestination;
405 * @param transportDestination
407 public OFMatch setTransportDestination(short transportDestination) {
408 this.transportDestination = transportDestination;
417 public short getTransportSource() {
418 return this.transportSource;
424 * @param transportSource
426 public OFMatch setTransportSource(short transportSource) {
427 this.transportSource = transportSource;
436 public int getWildcards() {
437 return this.wildcards;
445 public Wildcards getWildcardObj() {
446 return Wildcards.of(wildcards);
454 public OFMatch setWildcards(int wildcards) {
455 this.wildcards = wildcards;
459 /** set the wildcard using the Wildcards convenience object */
460 public OFMatch setWildcards(Wildcards wildcards) {
461 this.wildcards = wildcards.getInt();
466 * Initializes this OFMatch structure with the corresponding data from the
467 * specified packet. Must specify the input port, to ensure that
468 * this.in_port is set correctly. Specify OFPort.NONE or OFPort.ANY if input
469 * port not applicable or available
474 * the port the packet arrived on
476 public OFMatch loadFromPacket(byte[] packetData, short inputPort) {
478 int transportOffset = 34;
479 ByteBuffer packetDataBB = ByteBuffer.wrap(packetData);
480 int limit = packetDataBB.limit();
482 this.wildcards = 0; // all fields have explicit entries
484 this.inputPort = inputPort;
486 if (inputPort == OFPort.OFPP_ALL.getValue())
487 this.wildcards |= OFPFW_IN_PORT;
489 assert (limit >= 14);
491 this.dataLayerDestination = new byte[6];
492 packetDataBB.get(this.dataLayerDestination);
494 this.dataLayerSource = new byte[6];
495 packetDataBB.get(this.dataLayerSource);
497 this.dataLayerType = packetDataBB.getShort();
499 if (getDataLayerType() != (short) 0x8100) { // need cast to avoid signed
501 setDataLayerVirtualLan((short) 0xffff);
502 setDataLayerVirtualLanPriorityCodePoint((byte) 0);
505 scratch = packetDataBB.getShort();
506 setDataLayerVirtualLan((short) (0xfff & scratch));
507 setDataLayerVirtualLanPriorityCodePoint((byte) ((0xe000 & scratch) >> 13));
508 this.dataLayerType = packetDataBB.getShort();
511 switch (getDataLayerType()) {
514 // check packet length
515 scratch = packetDataBB.get();
516 scratch = (short) (0xf & scratch);
517 transportOffset = (packetDataBB.position() - 1)
520 scratch = packetDataBB.get();
521 setNetworkTypeOfService((byte) ((0xfc & scratch) >> 2));
523 packetDataBB.position(packetDataBB.position() + 7);
524 this.networkProtocol = packetDataBB.get();
526 packetDataBB.position(packetDataBB.position() + 2);
527 this.networkSource = packetDataBB.getInt();
529 this.networkDestination = packetDataBB.getInt();
530 packetDataBB.position(transportOffset);
534 int arpPos = packetDataBB.position();
536 scratch = packetDataBB.getShort(arpPos + 6);
537 setNetworkProtocol((byte) (0xff & scratch));
539 scratch = packetDataBB.getShort(arpPos + 2);
540 // if ipv4 and addr len is 4
541 if (scratch == 0x800 && packetDataBB.get(arpPos + 5) == 4) {
543 this.networkSource = packetDataBB.getInt(arpPos + 14);
545 this.networkDestination = packetDataBB.getInt(arpPos + 24);
548 setNetworkDestination(0);
552 setNetworkTypeOfService((byte) 0);
553 setNetworkProtocol((byte) 0);
555 setNetworkDestination(0);
559 switch (getNetworkProtocol()) {
563 this.transportSource = U8.f(packetDataBB.get());
565 this.transportDestination = U8.f(packetDataBB.get());
570 this.transportSource = packetDataBB.getShort();
572 this.transportDestination = packetDataBB.getShort();
577 this.transportSource = packetDataBB.getShort();
579 this.transportDestination = packetDataBB.getShort();
582 setTransportDestination((short) 0);
583 setTransportSource((short) 0);
590 * Read this message off the wire from the specified ByteBuffer
594 public void readFrom(ChannelBuffer data) {
595 this.wildcards = data.readInt();
596 this.inputPort = data.readShort();
597 this.dataLayerSource = new byte[6];
598 data.readBytes(this.dataLayerSource);
599 this.dataLayerDestination = new byte[6];
600 data.readBytes(this.dataLayerDestination);
601 this.dataLayerVirtualLan = data.readShort();
602 this.dataLayerVirtualLanPriorityCodePoint = data.readByte();
603 data.readByte(); // pad
604 this.dataLayerType = data.readShort();
605 this.networkTypeOfService = data.readByte();
606 this.networkProtocol = data.readByte();
607 data.readByte(); // pad
608 data.readByte(); // pad
609 this.networkSource = data.readInt();
610 this.networkDestination = data.readInt();
611 this.transportSource = data.readShort();
612 this.transportDestination = data.readShort();
616 * Write this message's binary format to the specified ByteBuffer
620 public void writeTo(ChannelBuffer data) {
621 data.writeInt(wildcards);
622 data.writeShort(inputPort);
623 data.writeBytes(this.dataLayerSource);
624 data.writeBytes(this.dataLayerDestination);
625 data.writeShort(dataLayerVirtualLan);
626 data.writeByte(dataLayerVirtualLanPriorityCodePoint);
627 data.writeByte((byte) 0x0); // pad
628 data.writeShort(dataLayerType);
629 data.writeByte(networkTypeOfService);
630 data.writeByte(networkProtocol);
631 data.writeByte((byte) 0x0); // pad
632 data.writeByte((byte) 0x0); // pad
633 data.writeInt(networkSource);
634 data.writeInt(networkDestination);
635 data.writeShort(transportSource);
636 data.writeShort(transportDestination);
640 public int hashCode() {
641 final int prime = 131;
643 result = prime * result + Arrays.hashCode(dataLayerDestination);
644 result = prime * result + Arrays.hashCode(dataLayerSource);
645 result = prime * result + dataLayerType;
646 result = prime * result + dataLayerVirtualLan;
647 result = prime * result + dataLayerVirtualLanPriorityCodePoint;
648 result = prime * result + inputPort;
649 result = prime * result + networkDestination;
650 result = prime * result + networkProtocol;
651 result = prime * result + networkSource;
652 result = prime * result + networkTypeOfService;
653 result = prime * result + transportDestination;
654 result = prime * result + transportSource;
655 result = prime * result + wildcards;
660 public boolean equals(Object obj) {
667 if (!(obj instanceof OFMatch)) {
670 OFMatch other = (OFMatch) obj;
671 if (!Arrays.equals(dataLayerDestination, other.dataLayerDestination)) {
674 if (!Arrays.equals(dataLayerSource, other.dataLayerSource)) {
677 if (dataLayerType != other.dataLayerType) {
680 if (dataLayerVirtualLan != other.dataLayerVirtualLan) {
683 if (dataLayerVirtualLanPriorityCodePoint != other.dataLayerVirtualLanPriorityCodePoint) {
686 if (inputPort != other.inputPort) {
689 if (networkDestination != other.networkDestination) {
692 if (networkProtocol != other.networkProtocol) {
695 if (networkSource != other.networkSource) {
698 if (networkTypeOfService != other.networkTypeOfService) {
701 if (transportDestination != other.transportDestination) {
704 if (transportSource != other.transportSource) {
707 if ((wildcards & OFMatch.OFPFW_ALL) != (other.wildcards & OFPFW_ALL)) { // only
719 * Implement clonable interface
722 public OFMatch clone() {
724 OFMatch ret = (OFMatch) super.clone();
725 ret.dataLayerDestination = this.dataLayerDestination.clone();
726 ret.dataLayerSource = this.dataLayerSource.clone();
728 } catch (CloneNotSupportedException e) {
729 throw new RuntimeException(e);
734 * Output a dpctl-styled string, i.e., only list the elements that are not
735 * wildcarded A match-everything OFMatch outputs "OFMatch[]"
738 * "OFMatch[dl_src:00:20:01:11:22:33,nw_src:192.168.0.0/24,tp_dst:80]"
741 public String toString() {
745 if ((wildcards & OFPFW_IN_PORT) == 0)
746 str += "," + STR_IN_PORT + "="
747 + U16.f(this.inputPort);
750 if ((wildcards & OFPFW_DL_DST) == 0)
754 + HexString.toHexString(this.dataLayerDestination);
755 if ((wildcards & OFPFW_DL_SRC) == 0)
759 + HexString.toHexString(this.dataLayerSource);
760 if ((wildcards & OFPFW_DL_TYPE) == 0)
764 + Integer.toHexString(U16.f(this.dataLayerType));
765 if ((wildcards & OFPFW_DL_VLAN) == 0)
769 + Integer.toHexString(U16.f(this.dataLayerVirtualLan));
770 if ((wildcards & OFPFW_DL_VLAN_PCP) == 0)
774 + Integer.toHexString(U8.f(this.dataLayerVirtualLanPriorityCodePoint));
777 if (getNetworkDestinationMaskLen() > 0)
781 + cidrToString(networkDestination,
782 getNetworkDestinationMaskLen());
783 if (getNetworkSourceMaskLen() > 0)
787 + cidrToString(networkSource,
788 getNetworkSourceMaskLen());
789 if ((wildcards & OFPFW_NW_PROTO) == 0)
790 str += "," + STR_NW_PROTO
792 + this.networkProtocol;
793 if ((wildcards & OFPFW_NW_TOS) == 0)
797 + this.getNetworkTypeOfService();
800 if ((wildcards & OFPFW_TP_DST) == 0)
804 + this.transportDestination;
805 if ((wildcards & OFPFW_TP_SRC) == 0)
806 str += "," + STR_TP_SRC + "="
807 + this.transportSource;
808 if ((str.length() > 0) && (str.charAt(0) == ','))
809 str = str.substring(1); // trim
814 return "OFMatch[" + str + "]";
818 * debug a set of wildcards
820 public static String debugWildCards(int wildcards) {
824 if ((wildcards & OFPFW_IN_PORT) != 0) str += "|" + STR_IN_PORT;
827 if ((wildcards & OFPFW_DL_DST) != 0) str += "|" + STR_DL_DST;
828 if ((wildcards & OFPFW_DL_SRC) != 0) str += "|" + STR_DL_SRC;
829 if ((wildcards & OFPFW_DL_TYPE) != 0) str += "|" + STR_DL_TYPE;
830 if ((wildcards & OFPFW_DL_VLAN) != 0) str += "|" + STR_DL_VLAN;
831 if ((wildcards & OFPFW_DL_VLAN_PCP) != 0)
835 int nwDstMask = Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
837 int nwSrcMask = Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
842 str += "|" + STR_NW_DST + "(/" + nwDstMask + ")";
845 str += "|" + STR_NW_SRC + "(/" + nwSrcMask + ")";
847 if ((wildcards & OFPFW_NW_PROTO) != 0) str += "|" + STR_NW_PROTO;
848 if ((wildcards & OFPFW_NW_TOS) != 0) str += "|" + STR_NW_TOS;
851 if ((wildcards & OFPFW_TP_DST) != 0) str += "|" + STR_TP_DST;
852 if ((wildcards & OFPFW_TP_SRC) != 0) str += "|" + STR_TP_SRC;
853 if ((str.length() > 0) && (str.charAt(0) == '|'))
854 str = str.substring(1); // trim
862 private String cidrToString(int ip, int prefix) {
865 str = ipToString(ip);
867 // use the negation of mask to fake endian magic
868 int mask = ~((1 << (32 - prefix)) - 1);
869 str = ipToString(ip & mask) + "/" + prefix;
876 * Set this OFMatch's parameters based on a comma-separated key=value pair
877 * dpctl-style string, e.g., from the output of OFMatch.toString() <br>
879 * Supported keys/values include <br>
887 * <TD>"in_port","input_port"
891 * <TD>"dl_src","eth_src", "dl_dst","eth_dst"
895 * <TD>"dl_type", "dl_vlan", "dl_vlan_pcp"
899 * <TD>"nw_src", "nw_dst", "ip_src", "ip_dst"
900 * <TD>CIDR-style netmask
903 * <TD>"tp_src","tp_dst"
904 * <TD>integer (max 64k)
908 * The CIDR-style netmasks assume 32 netmask if none given, so:
909 * "128.8.128.118/32" is the same as "128.8.128.118"
912 * a key=value comma separated string, e.g.
913 * "in_port=5,ip_dst=192.168.0.0/16,tp_src=80"
914 * @throws IllegalArgumentException
915 * on unexpected key or value
918 public void fromString(String match) throws IllegalArgumentException {
919 if (match.equals("") || match.equalsIgnoreCase("any")
920 || match.equalsIgnoreCase("all") || match.equals("[]"))
922 String[] tokens = match.split("[\\[,\\]]");
925 if (tokens[0].equals("OFMatch")) initArg = 1;
926 this.wildcards = OFPFW_ALL;
928 for (i = initArg; i < tokens.length; i++) {
929 values = tokens[i].split("=");
930 if (values.length != 2)
931 throw new IllegalArgumentException(
934 + " does not have form 'key=value' parsing "
936 values[0] = values[0].toLowerCase(); // try to make this case insens
937 if (values[0].equals(STR_IN_PORT)
938 || values[0].equals("input_port")) {
939 this.inputPort = U16.t(Integer.valueOf(values[1]));
940 this.wildcards &= ~OFPFW_IN_PORT;
941 } else if (values[0].equals(STR_DL_DST)
942 || values[0].equals("eth_dst")) {
943 this.dataLayerDestination = HexString.fromHexString(values[1]);
944 this.wildcards &= ~OFPFW_DL_DST;
945 } else if (values[0].equals(STR_DL_SRC)
946 || values[0].equals("eth_src")) {
947 this.dataLayerSource = HexString.fromHexString(values[1]);
948 this.wildcards &= ~OFPFW_DL_SRC;
949 } else if (values[0].equals(STR_DL_TYPE)
950 || values[0].equals("eth_type")) {
951 if (values[1].startsWith("0x"))
952 this.dataLayerType = U16.t(Integer.valueOf(values[1].replaceFirst("0x",
956 this.dataLayerType = U16.t(Integer.valueOf(values[1]));
957 this.wildcards &= ~OFPFW_DL_TYPE;
958 } else if (values[0].equals(STR_DL_VLAN)) {
959 if (values[1].startsWith("0x"))
960 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1].replaceFirst("0x",
964 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
965 this.wildcards &= ~OFPFW_DL_VLAN;
966 } else if (values[0].equals(STR_DL_VLAN_PCP)) {
967 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short.valueOf(values[1]));
968 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
969 } else if (values[0].equals(STR_NW_DST)
970 || values[0].equals("ip_dst")) {
971 setFromCIDR(values[1], STR_NW_DST);
972 } else if (values[0].equals(STR_NW_SRC)
973 || values[0].equals("ip_src")) {
974 setFromCIDR(values[1], STR_NW_SRC);
975 } else if (values[0].equals(STR_NW_PROTO)) {
976 if (values[1].startsWith("0x"))
977 this.networkProtocol = U8.t(Short.valueOf(values[1].replaceFirst("0x",""),16));
979 this.networkProtocol = U8.t(Short.valueOf(values[1]));
980 this.wildcards &= ~OFPFW_NW_PROTO;
981 } else if (values[0].equals(STR_NW_TOS)) {
982 this.setNetworkTypeOfService(U8.t(Short.valueOf(values[1])));
983 this.wildcards &= ~OFPFW_NW_TOS;
984 } else if (values[0].equals(STR_TP_DST)) {
985 this.transportDestination = U16.t(Integer.valueOf(values[1]));
986 this.wildcards &= ~OFPFW_TP_DST;
987 } else if (values[0].equals(STR_TP_SRC)) {
988 this.transportSource = U16.t(Integer.valueOf(values[1]));
989 this.wildcards &= ~OFPFW_TP_SRC;
991 throw new IllegalArgumentException("unknown token "
992 + tokens[i] + " parsing "
999 * Set the networkSource or networkDestionation address and their wildcards
1000 * from the CIDR string
1003 * "192.168.0.0/16" or "172.16.1.5"
1005 * one of STR_NW_DST or STR_NW_SRC
1006 * @throws IllegalArgumentException
1010 setFromCIDR(String cidr, String which)
1011 throws IllegalArgumentException {
1012 String values[] = cidr.split("/");
1013 String[] ip_str = values[0].split("\\.");
1015 ip += Integer.valueOf(ip_str[0]) << 24;
1016 ip += Integer.valueOf(ip_str[1]) << 16;
1017 ip += Integer.valueOf(ip_str[2]) << 8;
1018 ip += Integer.valueOf(ip_str[3]);
1019 int prefix = 32; // all bits are fixed, by default
1021 if (values.length >= 2) prefix = Integer.valueOf(values[1]);
1022 int mask = 32 - prefix;
1023 if (which.equals(STR_NW_DST)) {
1024 this.networkDestination = ip;
1025 this.wildcards = (wildcards & ~OFPFW_NW_DST_MASK)
1026 | (mask << OFPFW_NW_DST_SHIFT);
1027 } else if (which.equals(STR_NW_SRC)) {
1028 this.networkSource = ip;
1029 this.wildcards = (wildcards & ~OFPFW_NW_SRC_MASK)
1030 | (mask << OFPFW_NW_SRC_SHIFT);
1034 protected static String ipToString(int ip) {
1035 return Integer.toString(U8.f((byte) ((ip & 0xff000000) >> 24)))
1036 + "." + Integer.toString((ip & 0x00ff0000) >> 16) + "."
1037 + Integer.toString((ip & 0x0000ff00) >> 8) + "."
1038 + Integer.toString(ip & 0x000000ff);