blob: 6a16d29c5adfca282f7fa7375582d19e2d4c933f [file] [log] [blame]
Shashikanth VH826990b2016-02-11 16:52:46 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Shashikanth VH826990b2016-02-11 16:52:46 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.bgpio.types;
18
19import com.google.common.base.MoreObjects;
20import org.jboss.netty.buffer.ChannelBuffer;
21import org.onosproject.bgpio.exceptions.BgpParseException;
22import org.onosproject.bgpio.util.Constants;
23import org.onosproject.bgpio.util.Validation;
24import org.slf4j.Logger;
25import org.slf4j.LoggerFactory;
Shashikanth VHe30cfc42016-02-18 23:31:02 +053026
27import java.util.LinkedList;
28import java.util.List;
29import java.util.ListIterator;
Shashikanth VH826990b2016-02-11 16:52:46 +053030import java.util.Objects;
31
32/**
33 * Provides implementation of extended community BGP Path Attribute.
34 */
35public class BgpExtendedCommunity implements BgpValueType {
36
37 private static final Logger log = LoggerFactory.getLogger(BgpExtendedCommunity.class);
38 public static final short TYPE = Constants.BGP_EXTENDED_COMMUNITY;
39 public static final byte FLAGS = (byte) 0xC0;
Shashikanth VHe30cfc42016-02-18 23:31:02 +053040 private List<BgpValueType> fsActionTlv;
Shashikanth VH826990b2016-02-11 16:52:46 +053041
42 /**
43 * Constructor to initialize the value.
44 *
45 * @param fsActionTlv flow specification action type
46 */
Shashikanth VHe30cfc42016-02-18 23:31:02 +053047 public BgpExtendedCommunity(List<BgpValueType> fsActionTlv) {
Shashikanth VH826990b2016-02-11 16:52:46 +053048 this.fsActionTlv = fsActionTlv;
49 }
50
51 /**
52 * Returns extended community type.
53 *
54 * @return extended community
55 */
Shashikanth VHe30cfc42016-02-18 23:31:02 +053056 public List<BgpValueType> fsActionTlv() {
Shashikanth VH826990b2016-02-11 16:52:46 +053057 return this.fsActionTlv;
58 }
59
60 /**
61 * Reads from the channel buffer and parses extended community.
62 *
63 * @param cb ChannelBuffer
64 * @return object of BgpExtendedCommunity
65 * @throws BgpParseException while parsing extended community
66 */
67 public static BgpExtendedCommunity read(ChannelBuffer cb) throws BgpParseException {
68
69 ChannelBuffer tempCb = cb.copy();
70 Validation validation = Validation.parseAttributeHeader(cb);
Shashikanth VHe30cfc42016-02-18 23:31:02 +053071 List<BgpValueType> fsActionTlvs = new LinkedList<>();
Shashikanth VH826990b2016-02-11 16:52:46 +053072
73 if (cb.readableBytes() < validation.getLength()) {
74 Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
75 validation.getLength());
76 }
77 //if fourth bit is set, length is read as short otherwise as byte , len includes type, length and value
78 int len = validation.isShort() ? validation.getLength() + Constants.TYPE_AND_LEN_AS_SHORT : validation
79 .getLength() + Constants.TYPE_AND_LEN_AS_BYTE;
80 ChannelBuffer data = tempCb.readBytes(len);
81 if (validation.getFirstBit() && !validation.getSecondBit() && validation.getThirdBit()) {
82 throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data);
83 }
84
85 ChannelBuffer tempBuf = cb.readBytes(validation.getLength());
86 if (tempBuf.readableBytes() > 0) {
Shashikanth VHe30cfc42016-02-18 23:31:02 +053087 BgpValueType fsActionTlv = null;
Shashikanth VH826990b2016-02-11 16:52:46 +053088 ChannelBuffer actionBuf = tempBuf.readBytes(validation.getLength());
Shashikanth VHe30cfc42016-02-18 23:31:02 +053089
90 while (actionBuf.readableBytes() > 0) {
91 short actionType = actionBuf.readShort();
92 switch (actionType) {
93 case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION:
94 fsActionTlv = BgpFsActionTrafficAction.read(actionBuf);
95 break;
96 case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING:
97 fsActionTlv = BgpFsActionTrafficMarking.read(actionBuf);
98 break;
99 case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE:
100 fsActionTlv = BgpFsActionTrafficRate.read(actionBuf);
101 break;
102 case Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT:
103 fsActionTlv = BgpFsActionReDirect.read(actionBuf);
104 break;
105 default: log.debug("Other type Not Supported:" + actionType);
106 break;
107 }
Shashikanth VH03205d22016-02-19 22:48:08 +0530108 if (fsActionTlv != null) {
109 fsActionTlvs.add(fsActionTlv);
110 }
Shashikanth VH826990b2016-02-11 16:52:46 +0530111 }
112 }
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530113 return new BgpExtendedCommunity(fsActionTlvs);
Shashikanth VH826990b2016-02-11 16:52:46 +0530114 }
115
116 @Override
117 public short getType() {
118 return TYPE;
119 }
120
121 @Override
122 public int hashCode() {
123 return Objects.hash(fsActionTlv);
124 }
125
126 @Override
127 public boolean equals(Object obj) {
128 if (this == obj) {
129 return true;
130 }
131 if (obj instanceof BgpExtendedCommunity) {
132 BgpExtendedCommunity other = (BgpExtendedCommunity) obj;
133 return Objects.equals(fsActionTlv, other.fsActionTlv);
134 }
135 return false;
136 }
137
138 @Override
139 public String toString() {
140 return MoreObjects.toStringHelper(getClass())
141 .omitNullValues()
142 .add("fsActionTlv", fsActionTlv)
143 .toString();
144 }
145
146 @Override
147 public int write(ChannelBuffer cb) {
148 int iLenStartIndex = cb.writerIndex();
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530149 ListIterator<BgpValueType> listIterator = fsActionTlv().listIterator();
150
Shashikanth VH826990b2016-02-11 16:52:46 +0530151 cb.writeByte(FLAGS);
152 cb.writeByte(getType());
153
154 int iActionLenIndex = cb.writerIndex();
155 cb.writeByte(0);
156
Shashikanth VHe30cfc42016-02-18 23:31:02 +0530157 while (listIterator.hasNext()) {
158 BgpValueType fsTlv = listIterator.next();
159 if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_ACTION) {
160 BgpFsActionTrafficAction trafficAction = (BgpFsActionTrafficAction) fsTlv;
161 trafficAction.write(cb);
162 } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_MARKING) {
163 BgpFsActionTrafficMarking trafficMarking = (BgpFsActionTrafficMarking) fsTlv;
164 trafficMarking.write(cb);
165 } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_RATE) {
166 BgpFsActionTrafficRate trafficRate = (BgpFsActionTrafficRate) fsTlv;
167 trafficRate.write(cb);
168 } else if (fsTlv.getType() == Constants.BGP_FLOWSPEC_ACTION_TRAFFIC_REDIRECT) {
169 BgpFsActionReDirect trafficRedirect = (BgpFsActionReDirect) fsTlv;
170 trafficRedirect.write(cb);
171 }
Shashikanth VH826990b2016-02-11 16:52:46 +0530172 }
173
174 int fsActionLen = cb.writerIndex() - iActionLenIndex;
175 cb.setByte(iActionLenIndex, (byte) (fsActionLen - 1));
176
177 return cb.writerIndex() - iLenStartIndex;
178 }
179
180 @Override
181 public int compareTo(Object o) {
182 // TODO Auto-generated method stub
183 return 0;
184 }
185}