Refactor ForwardingRulesmanager
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / action / PushVlan.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.sal.action;
10
11 import javax.xml.bind.annotation.XmlAccessType;
12 import javax.xml.bind.annotation.XmlAccessorType;
13 import javax.xml.bind.annotation.XmlElement;
14 import javax.xml.bind.annotation.XmlRootElement;
15
16 import org.opendaylight.controller.sal.utils.EtherTypes;
17
18 /**
19  * Insert a 802.1q (outermost) header action Execute it multiple times to
20  * achieve QinQ
21  *
22  * 802.1q = [TPID(16) + TCI(16)] TCI = [PCP(3) + CFI(1) + VID(12)]
23  */
24 @XmlRootElement
25 @XmlAccessorType(XmlAccessType.NONE)
26 public class PushVlan extends Action {
27     private static final long serialVersionUID = 1L;
28     private int tag; // TPID - 16 bits
29     private int pcp; // PCP - 3 bits
30     private int cfi; // CFI - 1 bit (drop eligible)
31     private int vlanId; // VID - 12 bits
32     private transient int tci; // TCI = [PCP + CFI + VID] - 16 bits
33     private transient int header; // full 802.1q header [TPID + TCI] - 32 bits
34
35     /* Dummy constructor for JAXB */
36     @SuppressWarnings("unused")
37     private PushVlan() {
38     }
39
40     public PushVlan(int tag, int pcp, int cfi, int vlanId) {
41         type = ActionType.PUSH_VLAN;
42         this.tag = tag;
43         this.cfi = cfi;
44         this.pcp = pcp;
45         this.vlanId = vlanId;
46         this.tci = createTci();
47         this.header = createHeader();
48         runChecks();
49     }
50
51     public PushVlan(EtherTypes tag, int pcp, int cfi, int vlanId) {
52         type = ActionType.PUSH_VLAN;
53         this.tag = tag.intValue();
54         this.cfi = cfi;
55         this.pcp = pcp;
56         this.vlanId = vlanId;
57         this.tci = createTci();
58         this.header = createHeader();
59         runChecks();
60     }
61
62     private int createTci() {
63         return (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
64     }
65
66     private int createHeader() {
67         return (tag & 0xffff) << 16 | (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
68     }
69
70     private void runChecks() {
71         checkValue(ActionType.SET_DL_TYPE, tag);
72         checkValue(ActionType.SET_VLAN_PCP, pcp);
73         checkValue(ActionType.SET_VLAN_CFI, cfi);
74         checkValue(ActionType.SET_VLAN_ID, vlanId);
75         checkValue(tci);
76
77         // Run action specific check which cannot be run by parent
78         if (tag != EtherTypes.VLANTAGGED.intValue() && tag != EtherTypes.QINQ.intValue()
79                 && tag != EtherTypes.OLDQINQ.intValue() && tag != EtherTypes.CISCOQINQ.intValue()) {
80             // pass a value which will tell fail and tell something about the
81             // original wrong value
82             checkValue(ActionType.SET_DL_TYPE, 0xBAD << 16 | tag);
83         }
84     }
85
86     /**
87      * Returns the VID portion of the 802.1q header this action will insert VID
88      * - (12 bits)
89      *
90      * @return byte[]
91      */
92     public int getVlanId() {
93         return vlanId;
94     }
95
96     /**
97      * Returns the CFI portion of the 802.1q header this action will insert CFI
98      * - (1 bit)
99      *
100      * @return
101      */
102     public int getCfi() {
103         return cfi;
104     }
105
106     /**
107      * Returns the vlan PCP portion of the 802.1q header this action will insert
108      * PCP - (3 bits)
109      *
110      * @return byte[]
111      */
112     public int getPcp() {
113         return pcp;
114     }
115
116     /**
117      * Returns the TPID portion of the 802.1q header this action will insert
118      * TPID - (16 bits)
119      */
120     public int getTag() {
121         return tag;
122     }
123
124     /**
125      * Returns the TCI portion of the 802.1q header this action will insert TCI
126      * = [PCP + CFI + VID] - (16 bits)
127      *
128      * @return
129      */
130     public int getTci() {
131         return tci;
132     }
133
134     /**
135      * Returns the full 802.1q header this action will insert header = [TPID +
136      * TIC] (32 bits)
137      *
138      * @return int
139      */
140     @XmlElement(name = "VlanHeader")
141     public int getHeader() {
142         return header;
143     }
144
145     @Override
146     public boolean equals(Object obj) {
147         if (this == obj) {
148             return true;
149         }
150         if (!super.equals(obj)) {
151             return false;
152         }
153         if (getClass() != obj.getClass()) {
154             return false;
155         }
156         PushVlan other = (PushVlan) obj;
157         if (cfi != other.cfi) {
158             return false;
159         }
160         if (pcp != other.pcp) {
161             return false;
162         }
163         if (tag != other.tag) {
164             return false;
165         }
166         if (vlanId != other.vlanId) {
167             return false;
168         }
169         return true;
170     }
171
172     @Override
173     public int hashCode() {
174         final int prime = 31;
175         int result = super.hashCode();
176         result = prime * result + cfi;
177         result = prime * result + pcp;
178         result = prime * result + tag;
179         result = prime * result + vlanId;
180         return result;
181     }
182
183     @Override
184     public String toString() {
185         return type + "[tag = " + tag + ", pcp = " + pcp + ", cfi = " + cfi + ", vlanId = " + vlanId + "]";
186     }
187
188 }