Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef SRC_BGP_BGP_PROTO_H_
6 : #define SRC_BGP_BGP_PROTO_H_
7 :
8 : #include <sstream>
9 : #include <string>
10 : #include <vector>
11 :
12 : #include "base/parse_object.h"
13 : #include "bgp/bgp_attr.h"
14 : #include "bgp/community.h"
15 :
16 : struct BgpMpNlri;
17 : class BgpPeer;
18 :
19 : class BgpProto {
20 : public:
21 : enum MessageType {
22 : OPEN = 1,
23 : UPDATE = 2,
24 : NOTIFICATION = 3,
25 : KEEPALIVE = 4
26 : };
27 :
28 : enum BgpPeerType {
29 : IBGP,
30 : EBGP,
31 : XMPP,
32 : };
33 :
34 4 : static std::string BgpPeerTypeString(BgpPeerType peer_type) {
35 4 : switch (peer_type) {
36 4 : case IBGP:
37 4 : return "IBGP";
38 : break;
39 0 : case EBGP:
40 0 : return "EBGP";
41 : break;
42 0 : case XMPP:
43 0 : return "XMPP";
44 : break;
45 : }
46 0 : assert(false);
47 : return "OTHER";
48 : }
49 :
50 : struct BgpMessage : public ParseObject {
51 407973 : explicit BgpMessage(MessageType type) : type(type) {
52 407968 : }
53 : MessageType type;
54 0 : virtual const std::string ToString() const { return ""; }
55 : };
56 :
57 : struct OpenMessage : public BgpMessage {
58 : enum OpenOptParamTypes {
59 : OPEN_OPT_CAPABILITIES = 2,
60 : };
61 :
62 : OpenMessage();
63 : ~OpenMessage();
64 : int Validate(BgpPeer *peer) const;
65 : uint32_t as_num;
66 : int32_t holdtime;
67 : uint32_t identifier;
68 :
69 : struct Capability : public ParseObject {
70 : enum CapabilityCode {
71 : Reserved = 0,
72 : MpExtension = 1,
73 : RouteRefresh = 2,
74 : OutboundRouteFiltering = 3,
75 : MultipleRoutesToADestination = 4,
76 : ExtendedNextHop = 5,
77 : GracefulRestart = 64,
78 : AS4Support = 65,
79 : Dynamic = 67,
80 : MultisessionBgp = 68,
81 : AddPath = 69,
82 : EnhancedRouteRefresh = 70,
83 : LongLivedGracefulRestart = 71,
84 : RouteRefreshCisco = 128
85 : };
86 34824 : static std::string CapabilityToString(int capability) {
87 34824 : switch (capability) {
88 0 : case Reserved:
89 0 : return "Reserved";
90 22585 : case MpExtension:
91 22585 : return "MpExtension";
92 122 : case RouteRefresh:
93 122 : return "RouteRefresh";
94 0 : case OutboundRouteFiltering:
95 0 : return "OutboundRouteFiltering";
96 0 : case MultipleRoutesToADestination:
97 0 : return "MultipleRoutesToADestination";
98 0 : case ExtendedNextHop:
99 0 : return "ExtendedNextHop";
100 6719 : case GracefulRestart:
101 6719 : return "GracefulRestart";
102 122 : case AS4Support:
103 122 : return "AS4Support";
104 0 : case Dynamic:
105 0 : return "Dynamic";
106 0 : case MultisessionBgp:
107 0 : return "MultisessionBgp";
108 0 : case AddPath:
109 0 : return "AddPath";
110 0 : case EnhancedRouteRefresh:
111 0 : return "EnhancedRouteRefresh";
112 5154 : case LongLivedGracefulRestart:
113 5154 : return "LongLivedGracefulRestart";
114 122 : case RouteRefreshCisco:
115 122 : return "RouteRefreshCisco";
116 : }
117 :
118 0 : std::ostringstream oss;
119 0 : oss << "Unknown(" << capability << ")";
120 0 : return oss.str();
121 : }
122 23213 : Capability() : code(Reserved) { }
123 436095 : explicit Capability(int code, const uint8_t *src, int size) :
124 436095 : code(code), capability(src, src + size) {}
125 :
126 : struct GR {
127 : enum Flags {
128 : ForwardingStatePreservedFlag = 0x80,
129 : RestartedFlag = 0x8000,
130 : NotificationFlag = 0x4000,
131 : RestartTimeMask = 0x0FFF,
132 : };
133 213827 : explicit GR() { Initialize(); }
134 1430119 : void Initialize() {
135 1430119 : flags = 0;
136 1430119 : time = 0;
137 1430119 : families.clear();
138 1430119 : }
139 : struct Family {
140 612107 : Family(uint16_t afi, uint8_t safi, uint8_t flags) :
141 612107 : afi(afi), safi(safi), flags(flags) { }
142 : uint16_t afi;
143 : uint8_t safi;
144 : uint8_t flags;
145 :
146 19304 : bool forwarding_state_preserved() const {
147 19304 : return (flags & ForwardingStatePreservedFlag) != 0;
148 : }
149 : };
150 : static Capability *Encode(uint16_t gr_time, bool restarted,
151 : bool notification,
152 : const std::vector<uint8_t> &gr_afi_flags,
153 : const std::vector<Address::Family> &gr_families);
154 : static bool Decode(GR *gr_params,
155 : const std::vector<Capability *> &capabilities);
156 : static void GetFamilies(const GR &gr_params,
157 : std::vector<std::string> *families);
158 8 : bool restarted() const { return (flags & RestartedFlag) != 0; }
159 2453 : bool notification() const {
160 2453 : return (flags & NotificationFlag) != 0;
161 : }
162 405231 : void set_flags(uint16_t gr_cap_bytes) {
163 405231 : flags = gr_cap_bytes & ~RestartTimeMask;
164 405231 : }
165 405232 : void set_time(uint16_t gr_cap_bytes) {
166 405232 : time = gr_cap_bytes & RestartTimeMask;
167 405232 : }
168 : uint16_t flags;
169 : uint16_t time;
170 : std::vector<Family> families;
171 : };
172 :
173 : struct LLGR {
174 : enum {
175 : ForwardingStatePreservedFlag = 0x80,
176 : RestartTimeMask = 0x00FFFFFF,
177 : };
178 213826 : explicit LLGR() { Initialize(); }
179 1424574 : void Initialize() {
180 1424574 : time = 0;
181 1424574 : families.clear();
182 1424574 : }
183 : struct Family {
184 612086 : Family(uint16_t afi, uint8_t safi, uint8_t flags,
185 612086 : uint32_t time) :
186 612086 : afi(afi), safi(safi), flags(flags), time(time) {
187 612086 : }
188 : uint16_t afi;
189 : uint8_t safi;
190 : uint8_t flags;
191 : uint32_t time; // 24 bits only
192 :
193 19224 : bool forwarding_state_preserved() const {
194 19224 : return (flags & ForwardingStatePreservedFlag) != 0;
195 : }
196 : };
197 :
198 : static Capability *Encode(uint32_t llgr_time,
199 : uint8_t llgr_afi_flags,
200 : const std::vector<Address::Family> &llgr_families);
201 : static bool Decode(LLGR *llgr_params,
202 : const std::vector<Capability *> &capabilities);
203 : static void GetFamilies(const LLGR &llgr_params,
204 : std::vector<std::string> *families);
205 : uint32_t time;
206 : std::vector<Family> families;
207 : };
208 :
209 : int code;
210 : std::vector<uint8_t> capability;
211 : };
212 :
213 : struct OptParam : public ParseObject {
214 31962 : ~OptParam() {
215 15981 : STLDeleteValues(&capabilities);
216 31961 : }
217 : std::vector<Capability *> capabilities;
218 : };
219 : std::vector<OptParam *> opt_params;
220 : static BgpProto::OpenMessage *Decode(const uint8_t *data, size_t size);
221 : static int EncodeData(OpenMessage *msg, uint8_t *data, size_t size);
222 : virtual const std::string ToString() const;
223 :
224 : private:
225 : int ValidateCapabilities(BgpPeer *peer) const;
226 : int EncodeCapabilities(OpenMessage *msg, uint8_t *data, size_t size);
227 : };
228 :
229 : struct Notification : public BgpMessage {
230 : enum Code {
231 : MsgHdrErr = 1,
232 : OpenMsgErr = 2,
233 : UpdateMsgErr = 3,
234 : HoldTimerExp = 4,
235 : FSMErr = 5,
236 : Cease = 6
237 : };
238 : static std::string CodeToString(Code code) {
239 : switch (code) {
240 : case MsgHdrErr:
241 : return "Message Header Error";
242 : case OpenMsgErr:
243 : return "OPEN Message Error";
244 : case UpdateMsgErr:
245 : return "UPDATE Message Error";
246 : case HoldTimerExp:
247 : return "Hold Timer Expired";
248 : case FSMErr:
249 : return "Finite State Machine Error";
250 : case Cease:
251 : return "Cease";
252 : }
253 :
254 : std::ostringstream oss;
255 : oss << "Unknown(" << code << ")";
256 : return oss.str();
257 : }
258 : enum MsgHdrSubCode {
259 : ConnNotSync = 1,
260 : BadMsgLength = 2,
261 : BadMsgType = 3,
262 : };
263 10 : static std::string MsgHdrSubcodeToString(MsgHdrSubCode sub_code) {
264 10 : switch (sub_code) {
265 0 : case ConnNotSync:
266 0 : return "Connection Not Synchronized";
267 0 : case BadMsgLength:
268 0 : return "Bad Message Length";
269 0 : case BadMsgType:
270 0 : return "Bad Message Type";
271 : }
272 :
273 20 : std::ostringstream oss;
274 10 : oss << "Unknown(" << sub_code << ")";
275 10 : return oss.str();
276 : }
277 : enum OpenMsgSubCode {
278 : UnsupportedVersion = 1,
279 : BadPeerAS = 2,
280 : BadBgpId = 3,
281 : UnsupportedOptionalParam = 4,
282 : AuthenticationFailure = 5,
283 : UnacceptableHoldTime = 6,
284 : UnsupportedCapability = 7
285 : };
286 230 : static std::string OpenMsgSubcodeToString(OpenMsgSubCode sub_code) {
287 230 : switch (sub_code) {
288 0 : case UnsupportedVersion:
289 0 : return "Unsupported Version Number";
290 174 : case BadPeerAS:
291 174 : return "Bad Peer AS";
292 8 : case BadBgpId:
293 8 : return "Bad BGP Identifier";
294 0 : case UnsupportedOptionalParam:
295 0 : return "Unsupported Optional Parameter";
296 0 : case AuthenticationFailure:
297 0 : return "Authentication Failure";
298 0 : case UnacceptableHoldTime:
299 0 : return "Unacceptable Hold Time";
300 38 : case UnsupportedCapability:
301 38 : return "Unsupported Capability";
302 : }
303 :
304 20 : std::ostringstream oss;
305 10 : oss << "Unknown(" << sub_code << ")";
306 10 : return oss.str();
307 : }
308 : enum UpdateMsgSubCode {
309 : MalformedAttributeList = 1,
310 : UnrecognizedWellKnownAttrib = 2,
311 : MissingWellKnownAttrib = 3,
312 : AttribFlagsError = 4,
313 : AttribLengthError = 5,
314 : InvalidOrigin = 6,
315 : InvalidNH = 8,
316 : OptionalAttribError = 9,
317 : InvalidNetworkField = 10,
318 : MalformedASPath = 11
319 : };
320 10 : static std::string UpdateMsgSubCodeToString(UpdateMsgSubCode sub_code) {
321 10 : switch (sub_code) {
322 0 : case MalformedAttributeList:
323 0 : return "Malformed Attribute List";
324 0 : case UnrecognizedWellKnownAttrib:
325 0 : return "Unrecognized Well-known Attribute";
326 0 : case MissingWellKnownAttrib:
327 0 : return "Missing Well-known Attribute";
328 0 : case AttribFlagsError:
329 0 : return "Attribute Flags Error";
330 0 : case AttribLengthError:
331 0 : return "Attribute Length Error";
332 0 : case InvalidOrigin:
333 0 : return "Invalid ORIGIN Attribute";
334 0 : case InvalidNH:
335 0 : return "Invalid NEXT_HOP Attribute";
336 0 : case OptionalAttribError:
337 0 : return "Optional Attribute Error";
338 0 : case InvalidNetworkField:
339 0 : return "Invalid Network Field";
340 0 : case MalformedASPath:
341 0 : return "Malformed AS_PATH";
342 : }
343 :
344 20 : std::ostringstream oss;
345 10 : oss << "Unknown(" << sub_code << ")";
346 10 : return oss.str();
347 : }
348 : enum FsmSubcode {
349 : UnspecifiedError = 0,
350 : OpenSentError = 1,
351 : OpenConfirmError = 2,
352 : EstablishedError = 3
353 : };
354 28 : static std::string FsmSubcodeToString(FsmSubcode sub_code) {
355 28 : switch (sub_code) {
356 28 : case UnspecifiedError:
357 28 : return "Unspecified Error";
358 0 : case OpenSentError:
359 0 : return "Receive Unexpected Message in OpenSent State";
360 0 : case OpenConfirmError:
361 0 : return "Receive Unexpected Message in OpenConfirm State";
362 0 : case EstablishedError:
363 0 : return "Receive Unexpected Message in Established State";
364 : }
365 :
366 0 : std::ostringstream oss;
367 0 : oss << "Unknown(" << sub_code << ")";
368 0 : return oss.str();
369 : }
370 : enum CeaseSubCode {
371 : Unknown = 0,
372 : MaxPrefixes = 1,
373 : AdminShutdown = 2,
374 : PeerDeconfigured = 3,
375 : AdminReset = 4,
376 : ConnectionRejected = 5,
377 : OtherConfigChange = 6,
378 : ConnectionCollision = 7,
379 : OutOfResources = 8,
380 : HardReset = 9,
381 : };
382 :
383 14448 : static std::string CeaseSubcodeToString(CeaseSubCode sub_code) {
384 14448 : switch (sub_code) {
385 468 : case Unknown:
386 468 : return "Unspecified Error";
387 584 : case MaxPrefixes:
388 584 : return "Received Maximum prefixes from peer";
389 5208 : case AdminShutdown:
390 5208 : return "Administrator has disabled the peer";
391 4668 : case PeerDeconfigured:
392 4668 : return "Administrator has unconfigured the peer";
393 24 : case AdminReset:
394 24 : return "Administrator reset the peer";
395 243 : case ConnectionRejected:
396 243 : return "Connection is rejected by the peer";
397 1096 : case OtherConfigChange:
398 1096 : return "Peer configuration has changed";
399 2142 : case ConnectionCollision:
400 2142 : return "Connection collision";
401 0 : case OutOfResources:
402 0 : return "Unable handle peer due to resource limit";
403 16 : case HardReset:
404 16 : return "Received HardReset to skip GR Helper mode";
405 : }
406 :
407 0 : std::ostringstream oss;
408 0 : oss << "Unknown(" << sub_code << ")";
409 0 : return oss.str();
410 : }
411 :
412 : Notification();
413 : int error;
414 : int subcode;
415 : std::string data;
416 : static BgpProto::Notification *Decode(const uint8_t *data, size_t size);
417 : static int EncodeData(Notification *msg, uint8_t *data, size_t size);
418 : virtual const std::string ToString() const;
419 : static const std::string toString(Code code, int subcode);
420 : };
421 :
422 : struct Keepalive : public BgpMessage {
423 : Keepalive();
424 : static BgpProto::Keepalive *Decode(const uint8_t *data, size_t size);
425 : };
426 :
427 : struct Update : public BgpMessage {
428 : Update();
429 : ~Update();
430 : int Validate(const BgpPeer *, std::string *data);
431 : int CompareTo(const Update &rhs) const;
432 : static BgpProto::Update *Decode(const uint8_t *data, size_t size);
433 :
434 : std::vector <BgpProtoPrefix *> withdrawn_routes;
435 : std::vector <BgpAttribute *> path_attributes;
436 : std::vector <BgpProtoPrefix *> nlri;
437 : static int EncodeData(Update *msg, uint8_t *data, size_t size);
438 : };
439 :
440 : static const int kMinMessageSize = 19;
441 : static const int kMaxMessageSize = 4096;
442 :
443 : static BgpMessage *Decode(const uint8_t *data, size_t size,
444 : ParseErrorContext *ec = NULL, bool as4 = false);
445 :
446 : static int Encode(const BgpMessage *msg, uint8_t *data, size_t size,
447 : EncodeOffsets *offsets = NULL, bool as4 = false);
448 : static int Encode(const BgpMpNlri *msg, uint8_t *data, size_t size,
449 : EncodeOffsets *offsets = NULL);
450 : };
451 :
452 : #endif // SRC_BGP_BGP_PROTO_H_
|