blob: ee605de8df031fccee0caeb17d03fde25a94ef2d [file] [log] [blame]
Yotam Harcholf3f11152013-09-05 16:47:16 -07001package org.projectfloodlight.openflow.types;
2
Andreas Wundsam5f71b412014-02-18 12:56:35 -08003import java.util.Arrays;
4
Yotam Harcholf3f11152013-09-05 16:47:16 -07005import org.jboss.netty.buffer.ChannelBuffer;
6import org.projectfloodlight.openflow.exceptions.OFParseError;
7
Andreas Wundsam22ba3af2013-10-04 16:00:30 -07008import com.google.common.hash.PrimitiveSink;
Andreas Wundsam85c961f2013-09-29 21:22:12 -07009import com.google.common.primitives.Shorts;
10
Andreas Wundsam98a18632013-11-05 11:34:24 -080011/** Represents an 802.1Q Vlan VID (12 bits).
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070012 *
13 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
14 *
15 */
Yotam Harcholf3f11152013-09-05 16:47:16 -070016public class VlanVid implements OFValueType<VlanVid> {
17
Andreas Wundsam98a18632013-11-05 11:34:24 -080018 private static final short VALIDATION_MASK = 0x0FFF;
19 private static final short ZERO_VAL = 0x0000;
Yotam Harcholf3f11152013-09-05 16:47:16 -070020 final static int LENGTH = 2;
21
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070022 /** this value means 'not set' in OF1.0 (e.g., in a match). not used elsewhere */
Andreas Wundsam98a18632013-11-05 11:34:24 -080023 public static final VlanVid ZERO = new VlanVid(ZERO_VAL);
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070024
25 /** for use with masking operations */
Yotam Harchol329f2b02013-09-11 15:05:26 -070026 public static final VlanVid NO_MASK = new VlanVid((short)0xFFFF);
Andreas Wundsam98a18632013-11-05 11:34:24 -080027 public static final VlanVid FULL_MASK = ZERO;
Yotam Harcholf3f11152013-09-05 16:47:16 -070028
29 private final short vid;
30
31 private VlanVid(short vid) {
32 this.vid = vid;
33 }
34
Andreas Wundsam503ceac2013-11-07 17:16:49 -080035 public static VlanVid ofVlan(int vid) {
KC Wangdd535162014-04-14 22:37:22 -070036 if (vid == NO_MASK.vid)
37 return NO_MASK;
38 if ((vid & VALIDATION_MASK) != vid)
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070039 throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
Andreas Wundsam503ceac2013-11-07 17:16:49 -080040 return new VlanVid((short) vid);
Yotam Harcholf3f11152013-09-05 16:47:16 -070041 }
42
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070043 /** @return the actual VLAN tag this vid identifies */
44 public short getVlan() {
Andreas Wundsam98a18632013-11-05 11:34:24 -080045 return vid;
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070046 }
47
Yotam Harcholf3f11152013-09-05 16:47:16 -070048 @Override
49 public boolean equals(Object obj) {
50 if (!(obj instanceof VlanVid))
51 return false;
52 VlanVid other = (VlanVid)obj;
53 if (other.vid != this.vid)
54 return false;
55 return true;
56 }
57
58 @Override
59 public int hashCode() {
60 int prime = 13873;
61 return this.vid * prime;
62 }
63
64 @Override
65 public String toString() {
66 return "0x" + Integer.toHexString(vid);
67 }
68
Yotam Harcholf3f11152013-09-05 16:47:16 -070069 @Override
70 public int getLength() {
71 return LENGTH;
72 }
73
Andreas Wundsam4e2469e2014-02-17 15:32:43 -080074 private volatile byte[] bytesCache = null;
Yotam Harcholf3f11152013-09-05 16:47:16 -070075
76 public byte[] getBytes() {
77 if (bytesCache == null) {
78 synchronized (this) {
79 if (bytesCache == null) {
80 bytesCache =
81 new byte[] { (byte) ((vid >>> 8) & 0xFF),
82 (byte) ((vid >>> 0) & 0xFF) };
83 }
84 }
85 }
Andreas Wundsam5f71b412014-02-18 12:56:35 -080086 return Arrays.copyOf(bytesCache, bytesCache.length);
Yotam Harcholf3f11152013-09-05 16:47:16 -070087 }
88
89 public void write2Bytes(ChannelBuffer c) {
90 c.writeShort(this.vid);
91 }
92
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070093 public void write2BytesOF10(ChannelBuffer c) {
94 c.writeShort(this.getVlan());
95 }
96
Yotam Harcholf3f11152013-09-05 16:47:16 -070097 public static VlanVid read2Bytes(ChannelBuffer c) throws OFParseError {
Andreas Wundsam98a18632013-11-05 11:34:24 -080098 return VlanVid.ofVlan(c.readShort());
Yotam Harcholf3f11152013-09-05 16:47:16 -070099 }
100
101 @Override
102 public VlanVid applyMask(VlanVid mask) {
Andreas Wundsam98a18632013-11-05 11:34:24 -0800103 return VlanVid.ofVlan((short)(this.vid & mask.vid));
Yotam Harcholf3f11152013-09-05 16:47:16 -0700104 }
105
Andreas Wundsam85c961f2013-09-29 21:22:12 -0700106 @Override
107 public int compareTo(VlanVid o) {
108 return Shorts.compare(vid, o.vid);
109 }
Andreas Wundsam98a18632013-11-05 11:34:24 -0800110
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700111 @Override
112 public void putTo(PrimitiveSink sink) {
113 sink.putShort(vid);
114 }
Yotam Harcholf3f11152013-09-05 16:47:16 -0700115}