7c7c585bf4834db91724136dc214927ae5f0c63f
[controller.git] / opendaylight / adsal / sal / api / src / main / java / org / opendaylight / controller / sal / action / PushVlan.java
1 /*
2  * Copyright (c) 2013-2014 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 @Deprecated
27 public class PushVlan extends Action {
28     private static final long serialVersionUID = 1L;
29     private int tag; // TPID - 16 bits
30     private int pcp; // PCP - 3 bits
31     private int cfi; // CFI - 1 bit (drop eligible)
32     private int vlanId; // VID - 12 bits
33     private transient int tci; // TCI = [PCP + CFI + VID] - 16 bits
34     private transient int header; // full 802.1q header [TPID + TCI] - 32 bits
35
36     /* Dummy constructor for JAXB */
37     @SuppressWarnings("unused")
38     private PushVlan() {
39     }
40
41     public PushVlan(int tag, int pcp, int cfi, int vlanId) {
42         type = ActionType.PUSH_VLAN;
43         this.tag = tag;
44         this.cfi = cfi;
45         this.pcp = pcp;
46         this.vlanId = vlanId;
47         this.tci = createTci();
48         this.header = createHeader();
49         runChecks();
50     }
51
52     public PushVlan(EtherTypes tag, int pcp, int cfi, int vlanId) {
53         type = ActionType.PUSH_VLAN;
54         this.tag = tag.intValue();
55         this.cfi = cfi;
56         this.pcp = pcp;
57         this.vlanId = vlanId;
58         this.tci = createTci();
59         this.header = createHeader();
60         runChecks();
61     }
62
63     /**
64      * Construct a new action instance which represents OF 1.3 PUSH_VLAN.
65      *
66      * @param tag  An {@link EtherTypes} instance.
67      */
68     public PushVlan(EtherTypes tag) {
69         this(tag.intValue());
70     }
71
72     /**
73      * Construct a new action instance which represents OF 1.3 PUSH_VLAN.
74      *
75      * @param tag  An ethernet type of a new VLAN tag.
76      */
77     public PushVlan(int tag) {
78         type = ActionType.PUSH_VLAN;
79         this.tag = tag;
80
81         if (tag != EtherTypes.VLANTAGGED.intValue() &&
82             tag != EtherTypes.QINQ.intValue()) {
83             // pass a value which will tell fail and tell something about the
84             // original wrong value
85             checkValue(ActionType.SET_DL_TYPE, 0xBAD << 16 | tag);
86         }
87     }
88
89     private int createTci() {
90         return (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
91     }
92
93     private int createHeader() {
94         return (tag & 0xffff) << 16 | (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
95     }
96
97     private void runChecks() {
98         checkValue(ActionType.SET_DL_TYPE, tag);
99         checkValue(ActionType.SET_VLAN_PCP, pcp);
100         checkValue(ActionType.SET_VLAN_CFI, cfi);
101         checkValue(ActionType.SET_VLAN_ID, vlanId);
102         checkValue(tci);
103
104         // Run action specific check which cannot be run by parent
105         if (tag != EtherTypes.VLANTAGGED.intValue() && tag != EtherTypes.QINQ.intValue()
106                 && tag != EtherTypes.OLDQINQ.intValue() && tag != EtherTypes.CISCOQINQ.intValue()) {
107             // pass a value which will tell fail and tell something about the
108             // original wrong value
109             checkValue(ActionType.SET_DL_TYPE, 0xBAD << 16 | tag);
110         }
111     }
112
113     /**
114      * Returns the VID portion of the 802.1q header this action will insert VID
115      * - (12 bits)
116      *
117      * @return byte[]
118      */
119     public int getVlanId() {
120         return vlanId;
121     }
122
123     /**
124      * Returns the CFI portion of the 802.1q header this action will insert CFI
125      * - (1 bit)
126      *
127      * @return
128      */
129     public int getCfi() {
130         return cfi;
131     }
132
133     /**
134      * Returns the vlan PCP portion of the 802.1q header this action will insert
135      * PCP - (3 bits)
136      *
137      * @return byte[]
138      */
139     public int getPcp() {
140         return pcp;
141     }
142
143     /**
144      * Returns the TPID portion of the 802.1q header this action will insert
145      * TPID - (16 bits)
146      */
147     public int getTag() {
148         return tag;
149     }
150
151     /**
152      * Returns the TCI portion of the 802.1q header this action will insert TCI
153      * = [PCP + CFI + VID] - (16 bits)
154      *
155      * @return
156      */
157     public int getTci() {
158         return tci;
159     }
160
161     /**
162      * Returns the full 802.1q header this action will insert header = [TPID +
163      * TIC] (32 bits)
164      *
165      * @return int
166      */
167     @XmlElement(name = "VlanHeader")
168     public int getHeader() {
169         return header;
170     }
171
172     @Override
173     public boolean equals(Object obj) {
174         if (this == obj) {
175             return true;
176         }
177         if (!super.equals(obj)) {
178             return false;
179         }
180         if (getClass() != obj.getClass()) {
181             return false;
182         }
183         PushVlan other = (PushVlan) obj;
184         if (cfi != other.cfi) {
185             return false;
186         }
187         if (pcp != other.pcp) {
188             return false;
189         }
190         if (tag != other.tag) {
191             return false;
192         }
193         if (vlanId != other.vlanId) {
194             return false;
195         }
196         return true;
197     }
198
199     @Override
200     public int hashCode() {
201         final int prime = 31;
202         int result = super.hashCode();
203         result = prime * result + cfi;
204         result = prime * result + pcp;
205         result = prime * result + tag;
206         result = prime * result + vlanId;
207         return result;
208     }
209
210     @Override
211     public String toString() {
212         return type + "[tag = " + tag + ", pcp = " + pcp + ", cfi = " + cfi + ", vlanId = " + vlanId + "]";
213     }
214
215 }