blob: 3c745814ac3a882702e76cd4426863a3d04c859d [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 Wang3d555b02014-04-14 21:53:30 -070036 if ((vid & VALIDATION_MASK) != vid && vid != NO_MASK.vid)
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070037 throw new IllegalArgumentException(String.format("Illegal VLAN value: %x", vid));
Andreas Wundsam503ceac2013-11-07 17:16:49 -080038 return new VlanVid((short) vid);
Yotam Harcholf3f11152013-09-05 16:47:16 -070039 }
40
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070041 /** @return the actual VLAN tag this vid identifies */
42 public short getVlan() {
Andreas Wundsam98a18632013-11-05 11:34:24 -080043 return vid;
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070044 }
45
Yotam Harcholf3f11152013-09-05 16:47:16 -070046 @Override
47 public boolean equals(Object obj) {
48 if (!(obj instanceof VlanVid))
49 return false;
50 VlanVid other = (VlanVid)obj;
51 if (other.vid != this.vid)
52 return false;
53 return true;
54 }
55
56 @Override
57 public int hashCode() {
58 int prime = 13873;
59 return this.vid * prime;
60 }
61
62 @Override
63 public String toString() {
64 return "0x" + Integer.toHexString(vid);
65 }
66
Yotam Harcholf3f11152013-09-05 16:47:16 -070067 @Override
68 public int getLength() {
69 return LENGTH;
70 }
71
Andreas Wundsam4e2469e2014-02-17 15:32:43 -080072 private volatile byte[] bytesCache = null;
Yotam Harcholf3f11152013-09-05 16:47:16 -070073
74 public byte[] getBytes() {
75 if (bytesCache == null) {
76 synchronized (this) {
77 if (bytesCache == null) {
78 bytesCache =
79 new byte[] { (byte) ((vid >>> 8) & 0xFF),
80 (byte) ((vid >>> 0) & 0xFF) };
81 }
82 }
83 }
Andreas Wundsam5f71b412014-02-18 12:56:35 -080084 return Arrays.copyOf(bytesCache, bytesCache.length);
Yotam Harcholf3f11152013-09-05 16:47:16 -070085 }
86
87 public void write2Bytes(ChannelBuffer c) {
88 c.writeShort(this.vid);
89 }
90
Andreas Wundsam55b71ce2013-10-01 19:26:46 -070091 public void write2BytesOF10(ChannelBuffer c) {
92 c.writeShort(this.getVlan());
93 }
94
Yotam Harcholf3f11152013-09-05 16:47:16 -070095 public static VlanVid read2Bytes(ChannelBuffer c) throws OFParseError {
Andreas Wundsam98a18632013-11-05 11:34:24 -080096 return VlanVid.ofVlan(c.readShort());
Yotam Harcholf3f11152013-09-05 16:47:16 -070097 }
98
99 @Override
100 public VlanVid applyMask(VlanVid mask) {
Andreas Wundsam98a18632013-11-05 11:34:24 -0800101 return VlanVid.ofVlan((short)(this.vid & mask.vid));
Yotam Harcholf3f11152013-09-05 16:47:16 -0700102 }
103
Andreas Wundsam85c961f2013-09-29 21:22:12 -0700104 @Override
105 public int compareTo(VlanVid o) {
106 return Shorts.compare(vid, o.vid);
107 }
Andreas Wundsam98a18632013-11-05 11:34:24 -0800108
Andreas Wundsam22ba3af2013-10-04 16:00:30 -0700109 @Override
110 public void putTo(PrimitiveSink sink) {
111 sink.putShort(vid);
112 }
Yotam Harcholf3f11152013-09-05 16:47:16 -0700113}