3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.sal.action;
12 import javax.xml.bind.annotation.XmlAccessType;
13 import javax.xml.bind.annotation.XmlAccessorType;
14 import javax.xml.bind.annotation.XmlElement;
15 import javax.xml.bind.annotation.XmlRootElement;
17 import org.opendaylight.controller.sal.utils.EtherTypes;
20 * Insert a 802.1q (outermost) header action
21 * Execute it multiple times to achieve QinQ
23 * 802.1q = [TPID(16) + TCI(16)]
24 * TCI = [PCP(3) + CFI(1) + VID(12)]
30 @XmlAccessorType(XmlAccessType.NONE)
32 public class PushVlan extends Action {
33 private int tag; // TPID - 16 bits
34 private int pcp; // PCP - 3 bits
35 private int cfi; // CFI - 1 bit (drop eligible)
36 private int vlanId; // VID - 12 bits
37 private transient int tci; // TCI = [PCP + CFI + VID] - 16 bits
38 private transient int header; // full 802.1q header [TPID + TCI] - 32 bits
40 /* Dummy constructor for JAXB */
44 public PushVlan(int tag, int pcp, int cfi, int vlanId) {
45 type = ActionType.PUSH_VLAN;
50 this.tci = createTci();
51 this.header = createHeader();
55 public PushVlan(EtherTypes tag, int pcp, int cfi, int vlanId) {
56 type = ActionType.PUSH_VLAN;
57 this.tag = tag.intValue();
61 this.tci = createTci();
62 this.header = createHeader();
66 private int createTci() {
67 return (pcp & 0x7) << 13 | (cfi & 0x1) << 12 | (vlanId & 0xfff);
70 private int createHeader() {
71 return (tag & 0xffff) << 16 | (pcp & 0x7) << 13 | (cfi & 0x1) << 12
75 private void runChecks() {
76 checkValue(ActionType.SET_DL_TYPE, tag);
77 checkValue(ActionType.SET_VLAN_PCP, pcp);
78 checkValue(ActionType.SET_VLAN_CFI, cfi);
79 checkValue(ActionType.SET_VLAN_ID, vlanId);
82 // Run action specific check which cannot be run by parent
83 if (tag != EtherTypes.VLANTAGGED.intValue()
84 && tag != EtherTypes.QINQ.intValue()
85 && tag != EtherTypes.OLDQINQ.intValue()
86 && tag != EtherTypes.CISCOQINQ.intValue()) {
87 // pass a value which will tell fail and tell something about the original wrong value
88 checkValue(ActionType.SET_DL_TYPE, 0xBAD << 16 | tag);
93 * Returns the VID portion of the 802.1q header this action will insert
97 public int getVlanId() {
102 * Returns the CFI portion of the 802.1q header this action will insert
106 public int getCfi() {
111 * Returns the vlan PCP portion of the 802.1q header this action will insert
115 public int getPcp() {
120 * Returns the TPID portion of the 802.1q header this action will insert
123 public int getTag() {
128 * Returns the TCI portion of the 802.1q header this action will insert
129 * TCI = [PCP + CFI + VID] - (16 bits)
132 public int getTci() {
137 * Returns the full 802.1q header this action will insert
138 * header = [TPID + TIC] (32 bits)
142 @XmlElement(name="VlanHeader")
143 public int getHeader() {
148 public boolean equals(Object obj) {
151 if (!super.equals(obj))
153 if (getClass() != obj.getClass())
155 PushVlan other = (PushVlan) obj;
156 if (cfi != other.cfi)
158 if (pcp != other.pcp)
160 if (tag != other.tag)
162 if (vlanId != other.vlanId)
168 public int hashCode() {
169 final int prime = 31;
170 int result = super.hashCode();
171 result = prime * result + cfi;
172 result = prime * result + pcp;
173 result = prime * result + tag;
174 result = prime * result + vlanId;
179 public String toString() {
180 return type + "[tag = " + tag + ", pcp = " + pcp + ", cfi = " + cfi
181 + ", vlanId = " + vlanId + "]";