Line data Source code
1 : /* BGP open message handling
2 : * Copyright (C) 1998, 1999 Kunihiro Ishiguro
3 : *
4 : * This file is part of GNU Zebra.
5 : *
6 : * GNU Zebra is free software; you can redistribute it and/or modify it
7 : * under the terms of the GNU General Public License as published by the
8 : * Free Software Foundation; either version 2, or (at your option) any
9 : * later version.
10 : *
11 : * GNU Zebra is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License along
17 : * with this program; see the file COPYING; if not, write to the Free Software
18 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 : */
20 :
21 : #include <zebra.h>
22 :
23 : #include "linklist.h"
24 : #include "prefix.h"
25 : #include "stream.h"
26 : #include "thread.h"
27 : #include "log.h"
28 : #include "command.h"
29 : #include "memory.h"
30 : #include "queue.h"
31 : #include "filter.h"
32 :
33 : #include "lib/json.h"
34 : #include "bgpd/bgpd.h"
35 : #include "bgpd/bgp_attr.h"
36 : #include "bgpd/bgp_debug.h"
37 : #include "bgpd/bgp_errors.h"
38 : #include "bgpd/bgp_fsm.h"
39 : #include "bgpd/bgp_packet.h"
40 : #include "bgpd/bgp_open.h"
41 : #include "bgpd/bgp_aspath.h"
42 : #include "bgpd/bgp_vty.h"
43 : #include "bgpd/bgp_memory.h"
44 :
45 : static const struct message capcode_str[] = {
46 : {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
47 : {CAPABILITY_CODE_REFRESH, "Route Refresh"},
48 : {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
49 : {CAPABILITY_CODE_RESTART, "Graceful Restart"},
50 : {CAPABILITY_CODE_AS4, "4-octet AS number"},
51 : {CAPABILITY_CODE_ADDPATH, "AddPath"},
52 : {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
53 : {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
54 : {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
55 : {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
56 : {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
57 : {CAPABILITY_CODE_FQDN, "FQDN"},
58 : {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
59 : {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
60 : {CAPABILITY_CODE_LLGR, "Long-lived BGP Graceful Restart"},
61 : {CAPABILITY_CODE_ROLE, "Role"},
62 : {0}};
63 :
64 : /* Minimum sizes for length field of each cap (so not inc. the header) */
65 : static const size_t cap_minsizes[] = {
66 : [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
67 : [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
68 : [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
69 : [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
70 : [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
71 : [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
72 : [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
73 : [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
74 : [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
75 : [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
76 : [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
77 : [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
78 : [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
79 : [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
80 : [CAPABILITY_CODE_LLGR] = CAPABILITY_CODE_LLGR_LEN,
81 : [CAPABILITY_CODE_ROLE] = CAPABILITY_CODE_ROLE_LEN,
82 : };
83 :
84 : /* value the capability must be a multiple of.
85 : * 0-data capabilities won't be checked against this.
86 : * Other capabilities whose data doesn't fall on convenient boundaries for this
87 : * table should be set to 1.
88 : */
89 : static const size_t cap_modsizes[] = {
90 : [CAPABILITY_CODE_MP] = 4,
91 : [CAPABILITY_CODE_REFRESH] = 1,
92 : [CAPABILITY_CODE_ORF] = 1,
93 : [CAPABILITY_CODE_RESTART] = 1,
94 : [CAPABILITY_CODE_AS4] = 4,
95 : [CAPABILITY_CODE_ADDPATH] = 4,
96 : [CAPABILITY_CODE_DYNAMIC] = 1,
97 : [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
98 : [CAPABILITY_CODE_ENHE] = 6,
99 : [CAPABILITY_CODE_REFRESH_OLD] = 1,
100 : [CAPABILITY_CODE_ORF_OLD] = 1,
101 : [CAPABILITY_CODE_FQDN] = 1,
102 : [CAPABILITY_CODE_ENHANCED_RR] = 1,
103 : [CAPABILITY_CODE_EXT_MESSAGE] = 1,
104 : [CAPABILITY_CODE_LLGR] = 1,
105 : [CAPABILITY_CODE_ROLE] = 1,
106 : };
107 :
108 : /* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
109 : negotiate remote peer supports extentions or not. But if
110 : remote-peer doesn't supports negotiation process itself. We would
111 : like to do manual configuration.
112 :
113 : So there is many configurable point. First of all we want set each
114 : peer whether we send capability negotiation to the peer or not.
115 : Next, if we send capability to the peer we want to set my capability
116 : inforation at each peer. */
117 :
118 0 : void bgp_capability_vty_out(struct vty *vty, struct peer *peer, bool use_json,
119 : json_object *json_neigh)
120 : {
121 0 : char *pnt;
122 0 : char *end;
123 0 : struct capability_mp_data mpc;
124 0 : struct capability_header *hdr;
125 0 : json_object *json_cap = NULL;
126 :
127 0 : if (use_json)
128 0 : json_cap = json_object_new_object();
129 :
130 0 : pnt = peer->notify.data;
131 0 : end = pnt + peer->notify.length;
132 :
133 0 : while (pnt < end) {
134 0 : if (pnt + sizeof(struct capability_mp_data) + 2 > end)
135 : return;
136 :
137 0 : hdr = (struct capability_header *)pnt;
138 0 : if (pnt + hdr->length + 2 > end)
139 : return;
140 :
141 0 : memcpy(&mpc, pnt + 2, sizeof(struct capability_mp_data));
142 :
143 0 : if (hdr->code == CAPABILITY_CODE_MP) {
144 0 : afi_t afi;
145 0 : safi_t safi;
146 :
147 0 : (void)bgp_map_afi_safi_iana2int(ntohs(mpc.afi),
148 : mpc.safi, &afi, &safi);
149 :
150 0 : if (use_json) {
151 0 : switch (afi) {
152 0 : case AFI_IP:
153 0 : json_object_string_add(
154 : json_cap,
155 : "capabilityErrorMultiProtocolAfi",
156 : "IPv4");
157 0 : break;
158 0 : case AFI_IP6:
159 0 : json_object_string_add(
160 : json_cap,
161 : "capabilityErrorMultiProtocolAfi",
162 : "IPv6");
163 0 : break;
164 0 : case AFI_L2VPN:
165 0 : json_object_string_add(
166 : json_cap,
167 : "capabilityErrorMultiProtocolAfi",
168 : "L2VPN");
169 0 : break;
170 0 : case AFI_UNSPEC:
171 : case AFI_MAX:
172 0 : json_object_int_add(
173 : json_cap,
174 : "capabilityErrorMultiProtocolAfiUnknown",
175 0 : ntohs(mpc.afi));
176 0 : break;
177 : }
178 0 : switch (safi) {
179 0 : case SAFI_UNICAST:
180 0 : json_object_string_add(
181 : json_cap,
182 : "capabilityErrorMultiProtocolSafi",
183 : "unicast");
184 0 : break;
185 0 : case SAFI_MULTICAST:
186 0 : json_object_string_add(
187 : json_cap,
188 : "capabilityErrorMultiProtocolSafi",
189 : "multicast");
190 0 : break;
191 0 : case SAFI_LABELED_UNICAST:
192 0 : json_object_string_add(
193 : json_cap,
194 : "capabilityErrorMultiProtocolSafi",
195 : "labeled-unicast");
196 0 : break;
197 0 : case SAFI_MPLS_VPN:
198 0 : json_object_string_add(
199 : json_cap,
200 : "capabilityErrorMultiProtocolSafi",
201 : "MPLS-labeled VPN");
202 0 : break;
203 0 : case SAFI_ENCAP:
204 0 : json_object_string_add(
205 : json_cap,
206 : "capabilityErrorMultiProtocolSafi",
207 : "encap");
208 0 : break;
209 0 : case SAFI_EVPN:
210 0 : json_object_string_add(
211 : json_cap,
212 : "capabilityErrorMultiProtocolSafi",
213 : "EVPN");
214 0 : break;
215 0 : case SAFI_FLOWSPEC:
216 0 : json_object_string_add(
217 : json_cap,
218 : "capabilityErrorMultiProtocolSafi",
219 : "flowspec");
220 0 : break;
221 0 : case SAFI_UNSPEC:
222 : case SAFI_MAX:
223 0 : json_object_int_add(
224 : json_cap,
225 : "capabilityErrorMultiProtocolSafiUnknown",
226 : mpc.safi);
227 0 : break;
228 : }
229 : } else {
230 0 : vty_out(vty,
231 : " Capability error for: Multi protocol ");
232 0 : switch (afi) {
233 0 : case AFI_IP:
234 0 : vty_out(vty, "AFI IPv4, ");
235 0 : break;
236 0 : case AFI_IP6:
237 0 : vty_out(vty, "AFI IPv6, ");
238 0 : break;
239 0 : case AFI_L2VPN:
240 0 : vty_out(vty, "AFI L2VPN, ");
241 0 : break;
242 0 : case AFI_UNSPEC:
243 : case AFI_MAX:
244 0 : vty_out(vty, "AFI Unknown %d, ",
245 0 : ntohs(mpc.afi));
246 0 : break;
247 : }
248 0 : switch (safi) {
249 0 : case SAFI_UNICAST:
250 0 : vty_out(vty, "SAFI Unicast");
251 0 : break;
252 0 : case SAFI_MULTICAST:
253 0 : vty_out(vty, "SAFI Multicast");
254 0 : break;
255 0 : case SAFI_LABELED_UNICAST:
256 0 : vty_out(vty, "SAFI Labeled-unicast");
257 0 : break;
258 0 : case SAFI_MPLS_VPN:
259 0 : vty_out(vty, "SAFI MPLS-labeled VPN");
260 0 : break;
261 0 : case SAFI_ENCAP:
262 0 : vty_out(vty, "SAFI ENCAP");
263 0 : break;
264 0 : case SAFI_FLOWSPEC:
265 0 : vty_out(vty, "SAFI FLOWSPEC");
266 0 : break;
267 0 : case SAFI_EVPN:
268 0 : vty_out(vty, "SAFI EVPN");
269 0 : break;
270 0 : case SAFI_UNSPEC:
271 : case SAFI_MAX:
272 0 : vty_out(vty, "SAFI Unknown %d ",
273 : mpc.safi);
274 0 : break;
275 : }
276 0 : vty_out(vty, "\n");
277 : }
278 0 : } else if (hdr->code >= 128) {
279 0 : if (use_json)
280 0 : json_object_int_add(
281 : json_cap,
282 : "capabilityErrorVendorSpecificCapabilityCode",
283 : hdr->code);
284 : else
285 0 : vty_out(vty,
286 : " Capability error: vendor specific capability code %d",
287 : hdr->code);
288 : } else {
289 0 : if (use_json)
290 0 : json_object_int_add(
291 : json_cap,
292 : "capabilityErrorUnknownCapabilityCode",
293 : hdr->code);
294 : else
295 0 : vty_out(vty,
296 : " Capability error: unknown capability code %d",
297 : hdr->code);
298 : }
299 0 : pnt += hdr->length + 2;
300 : }
301 0 : if (use_json)
302 0 : json_object_object_add(json_neigh, "capabilityErrors",
303 : json_cap);
304 : }
305 :
306 2 : static void bgp_capability_mp_data(struct stream *s,
307 : struct capability_mp_data *mpc)
308 : {
309 2 : mpc->afi = stream_getw(s);
310 2 : mpc->reserved = stream_getc(s);
311 2 : mpc->safi = stream_getc(s);
312 2 : }
313 :
314 : /* Set negotiated capability value. */
315 2 : static int bgp_capability_mp(struct peer *peer, struct capability_header *hdr)
316 : {
317 2 : struct capability_mp_data mpc;
318 2 : struct stream *s = BGP_INPUT(peer);
319 2 : afi_t afi;
320 2 : safi_t safi;
321 :
322 : /* Verify length is 4 */
323 2 : if (hdr->length != 4) {
324 0 : flog_warn(
325 : EC_BGP_CAPABILITY_INVALID_LENGTH,
326 : "MP Cap: Received invalid length %d, non-multiple of 4",
327 : hdr->length);
328 0 : return -1;
329 : }
330 :
331 2 : bgp_capability_mp_data(s, &mpc);
332 :
333 2 : if (bgp_debug_neighbor_events(peer))
334 0 : zlog_debug("%s OPEN has %s capability for afi/safi: %s/%s",
335 : peer->host, lookup_msg(capcode_str, hdr->code, NULL),
336 : iana_afi2str(mpc.afi), iana_safi2str(mpc.safi));
337 :
338 : /* Convert AFI, SAFI to internal values, check. */
339 2 : if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi))
340 : return -1;
341 :
342 : /* Now safi remapped, and afi/safi are valid array indices */
343 2 : peer->afc_recv[afi][safi] = 1;
344 :
345 2 : if (peer->afc[afi][safi])
346 2 : peer->afc_nego[afi][safi] = 1;
347 : else
348 : return -1;
349 :
350 2 : return 0;
351 : }
352 :
353 0 : static void bgp_capability_orf_not_support(struct peer *peer, iana_afi_t afi,
354 : iana_safi_t safi, uint8_t type,
355 : uint8_t mode)
356 : {
357 0 : if (bgp_debug_neighbor_events(peer))
358 0 : zlog_debug(
359 : "%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
360 : peer->host, afi, safi, type, mode);
361 0 : }
362 :
363 : static const struct message orf_type_str[] = {
364 : {ORF_TYPE_RESERVED, "Reserved"},
365 : {ORF_TYPE_PREFIX, "Prefixlist"},
366 : {ORF_TYPE_PREFIX_OLD, "Prefixlist (old)"},
367 : {0}};
368 :
369 : static const struct message orf_mode_str[] = {{ORF_MODE_RECEIVE, "Receive"},
370 : {ORF_MODE_SEND, "Send"},
371 : {ORF_MODE_BOTH, "Both"},
372 : {0}};
373 :
374 0 : static int bgp_capability_orf_entry(struct peer *peer,
375 : struct capability_header *hdr)
376 : {
377 0 : struct stream *s = BGP_INPUT(peer);
378 0 : struct capability_mp_data mpc;
379 0 : uint8_t num;
380 0 : iana_afi_t pkt_afi;
381 0 : afi_t afi;
382 0 : iana_safi_t pkt_safi;
383 0 : safi_t safi;
384 0 : uint8_t type;
385 0 : uint8_t mode;
386 0 : uint16_t sm_cap = 0; /* capability send-mode receive */
387 0 : uint16_t rm_cap = 0; /* capability receive-mode receive */
388 0 : int i;
389 :
390 : /* ORF Entry header */
391 0 : bgp_capability_mp_data(s, &mpc);
392 0 : num = stream_getc(s);
393 0 : pkt_afi = mpc.afi;
394 0 : pkt_safi = mpc.safi;
395 :
396 0 : if (bgp_debug_neighbor_events(peer))
397 0 : zlog_debug("%s ORF Cap entry for afi/safi: %s/%s", peer->host,
398 : iana_afi2str(mpc.afi), iana_safi2str(mpc.safi));
399 :
400 : /* Convert AFI, SAFI to internal values, check. */
401 0 : if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
402 0 : zlog_info(
403 : "%s Addr-family %d/%d not supported. Ignoring the ORF capability",
404 : peer->host, pkt_afi, pkt_safi);
405 0 : return 0;
406 : }
407 :
408 0 : mpc.afi = pkt_afi;
409 0 : mpc.safi = safi;
410 :
411 : /* validate number field */
412 0 : if (CAPABILITY_CODE_ORF_LEN + (num * 2) > hdr->length) {
413 0 : zlog_info(
414 : "%s ORF Capability entry length error, Cap length %u, num %u",
415 : peer->host, hdr->length, num);
416 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
417 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
418 0 : return -1;
419 : }
420 :
421 0 : for (i = 0; i < num; i++) {
422 0 : type = stream_getc(s);
423 0 : mode = stream_getc(s);
424 :
425 : /* ORF Mode error check */
426 0 : switch (mode) {
427 : case ORF_MODE_BOTH:
428 : case ORF_MODE_SEND:
429 : case ORF_MODE_RECEIVE:
430 0 : break;
431 0 : default:
432 0 : bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
433 : type, mode);
434 0 : continue;
435 : }
436 : /* ORF Type and afi/safi error checks */
437 : /* capcode versus type */
438 0 : switch (hdr->code) {
439 0 : case CAPABILITY_CODE_ORF:
440 0 : switch (type) {
441 0 : case ORF_TYPE_RESERVED:
442 0 : if (bgp_debug_neighbor_events(peer))
443 0 : zlog_debug(
444 : "%s Addr-family %d/%d has reserved ORF type, ignoring",
445 : peer->host, afi, safi);
446 : break;
447 : case ORF_TYPE_PREFIX:
448 : break;
449 0 : default:
450 0 : bgp_capability_orf_not_support(
451 : peer, pkt_afi, pkt_safi, type, mode);
452 0 : continue;
453 : }
454 : break;
455 0 : case CAPABILITY_CODE_ORF_OLD:
456 0 : switch (type) {
457 0 : case ORF_TYPE_RESERVED:
458 0 : if (bgp_debug_neighbor_events(peer))
459 0 : zlog_debug(
460 : "%s Addr-family %d/%d has reserved ORF type, ignoring",
461 : peer->host, afi, safi);
462 : break;
463 : case ORF_TYPE_PREFIX_OLD:
464 : break;
465 0 : default:
466 0 : bgp_capability_orf_not_support(
467 : peer, pkt_afi, pkt_safi, type, mode);
468 0 : continue;
469 : }
470 : break;
471 0 : default:
472 0 : bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
473 : type, mode);
474 0 : continue;
475 : }
476 :
477 : /* AFI vs SAFI */
478 0 : if (!((afi == AFI_IP && safi == SAFI_UNICAST)
479 0 : || (afi == AFI_IP && safi == SAFI_MULTICAST)
480 0 : || (afi == AFI_IP6 && safi == SAFI_UNICAST))) {
481 0 : bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
482 : type, mode);
483 0 : continue;
484 : }
485 :
486 0 : if (bgp_debug_neighbor_events(peer))
487 0 : zlog_debug(
488 : "%s OPEN has %s ORF capability as %s for afi/safi: %s/%s",
489 : peer->host,
490 : lookup_msg(orf_type_str, type, NULL),
491 : lookup_msg(orf_mode_str, mode, NULL),
492 : iana_afi2str(pkt_afi), iana_safi2str(pkt_safi));
493 :
494 0 : if (hdr->code == CAPABILITY_CODE_ORF) {
495 : sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
496 : rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
497 0 : } else if (hdr->code == CAPABILITY_CODE_ORF_OLD) {
498 : sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
499 : rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
500 : } else {
501 0 : bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
502 : type, mode);
503 0 : continue;
504 : }
505 :
506 0 : switch (mode) {
507 0 : case ORF_MODE_BOTH:
508 0 : SET_FLAG(peer->af_cap[afi][safi], sm_cap);
509 0 : SET_FLAG(peer->af_cap[afi][safi], rm_cap);
510 0 : break;
511 0 : case ORF_MODE_SEND:
512 0 : SET_FLAG(peer->af_cap[afi][safi], sm_cap);
513 0 : break;
514 0 : case ORF_MODE_RECEIVE:
515 0 : SET_FLAG(peer->af_cap[afi][safi], rm_cap);
516 0 : break;
517 : }
518 : }
519 : return 0;
520 : }
521 :
522 2 : static int bgp_capability_restart(struct peer *peer,
523 : struct capability_header *caphdr)
524 : {
525 2 : struct stream *s = BGP_INPUT(peer);
526 2 : uint16_t restart_flag_time;
527 2 : size_t end = stream_get_getp(s) + caphdr->length;
528 :
529 : /* Verify length is a multiple of 4 */
530 2 : if ((caphdr->length - 2) % 4) {
531 0 : flog_warn(
532 : EC_BGP_CAPABILITY_INVALID_LENGTH,
533 : "Restart Cap: Received invalid length %d, non-multiple of 4",
534 : caphdr->length);
535 0 : return -1;
536 : }
537 :
538 2 : SET_FLAG(peer->cap, PEER_CAP_RESTART_RCV);
539 2 : restart_flag_time = stream_getw(s);
540 :
541 : /* The most significant bit is defined in [RFC4724] as
542 : * the Restart State ("R") bit.
543 : */
544 2 : if (CHECK_FLAG(restart_flag_time, GRACEFUL_RESTART_R_BIT))
545 2 : SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV);
546 : else
547 0 : UNSET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV);
548 :
549 : /* The second most significant bit is defined in this
550 : * document as the Graceful Notification ("N") bit.
551 : */
552 2 : if (CHECK_FLAG(restart_flag_time, GRACEFUL_RESTART_N_BIT))
553 2 : SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV);
554 : else
555 0 : UNSET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV);
556 :
557 2 : UNSET_FLAG(restart_flag_time, 0xF000);
558 2 : peer->v_gr_restart = restart_flag_time;
559 :
560 2 : if (bgp_debug_neighbor_events(peer)) {
561 0 : zlog_debug(
562 : "%s Peer has%srestarted. Restart Time: %d, N-bit set: %s",
563 : peer->host,
564 : CHECK_FLAG(peer->cap,
565 : PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV)
566 : ? " "
567 : : " not ",
568 : peer->v_gr_restart,
569 : CHECK_FLAG(peer->cap,
570 : PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV)
571 : ? "yes"
572 : : "no");
573 : }
574 :
575 2 : while (stream_get_getp(s) + 4 <= end) {
576 0 : afi_t afi;
577 0 : safi_t safi;
578 0 : iana_afi_t pkt_afi = stream_getw(s);
579 0 : iana_safi_t pkt_safi = stream_getc(s);
580 0 : uint8_t flag = stream_getc(s);
581 :
582 : /* Convert AFI, SAFI to internal values, check. */
583 0 : if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
584 0 : if (bgp_debug_neighbor_events(peer))
585 0 : zlog_debug(
586 : "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI",
587 : peer->host, iana_afi2str(pkt_afi),
588 : iana_safi2str(pkt_safi));
589 0 : } else if (!peer->afc[afi][safi]) {
590 0 : if (bgp_debug_neighbor_events(peer))
591 0 : zlog_debug(
592 : "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability",
593 : peer->host, iana_afi2str(pkt_afi),
594 : iana_safi2str(pkt_safi));
595 : } else {
596 0 : if (bgp_debug_neighbor_events(peer))
597 0 : zlog_debug(
598 : "%s Address family %s is%spreserved",
599 : peer->host, get_afi_safi_str(afi, safi, false),
600 : CHECK_FLAG(
601 : peer->af_cap[afi][safi],
602 : PEER_CAP_RESTART_AF_PRESERVE_RCV)
603 : ? " "
604 : : " not ");
605 :
606 0 : SET_FLAG(peer->af_cap[afi][safi],
607 : PEER_CAP_RESTART_AF_RCV);
608 0 : if (CHECK_FLAG(flag, GRACEFUL_RESTART_F_BIT))
609 0 : SET_FLAG(peer->af_cap[afi][safi],
610 : PEER_CAP_RESTART_AF_PRESERVE_RCV);
611 : }
612 : }
613 : return 0;
614 : }
615 :
616 2 : static int bgp_capability_llgr(struct peer *peer,
617 : struct capability_header *caphdr)
618 : {
619 2 : struct stream *s = BGP_INPUT(peer);
620 2 : size_t end = stream_get_getp(s) + caphdr->length;
621 :
622 2 : SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV);
623 :
624 4 : while (stream_get_getp(s) + 4 <= end) {
625 2 : afi_t afi;
626 2 : safi_t safi;
627 2 : iana_afi_t pkt_afi = stream_getw(s);
628 2 : iana_safi_t pkt_safi = stream_getc(s);
629 2 : uint8_t flags = stream_getc(s);
630 2 : uint32_t stale_time = stream_get3(s);
631 :
632 2 : if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
633 0 : if (bgp_debug_neighbor_events(peer))
634 0 : zlog_debug(
635 : "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI",
636 : peer->host, iana_afi2str(pkt_afi),
637 : iana_safi2str(pkt_safi));
638 2 : } else if (!peer->afc[afi][safi]
639 2 : || !CHECK_FLAG(peer->af_cap[afi][safi],
640 : PEER_CAP_RESTART_AF_RCV)) {
641 2 : if (bgp_debug_neighbor_events(peer))
642 0 : zlog_debug(
643 : "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability",
644 : peer->host, iana_afi2str(pkt_afi),
645 : iana_safi2str(pkt_safi));
646 : } else {
647 0 : if (bgp_debug_neighbor_events(peer))
648 0 : zlog_debug(
649 : "%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec",
650 : peer->host, iana_afi2str(pkt_afi),
651 : iana_safi2str(pkt_safi), stale_time);
652 :
653 0 : peer->llgr[afi][safi].flags = flags;
654 0 : peer->llgr[afi][safi].stale_time =
655 0 : MIN(stale_time, peer->bgp->llgr_stale_time);
656 0 : SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_LLGR_AF_RCV);
657 : }
658 : }
659 :
660 2 : return 0;
661 : }
662 :
663 : /* Unlike other capability parsing routines, this one returns 0 on error */
664 6 : static as_t bgp_capability_as4(struct peer *peer, struct capability_header *hdr)
665 : {
666 6 : SET_FLAG(peer->cap, PEER_CAP_AS4_RCV);
667 :
668 6 : if (hdr->length != CAPABILITY_CODE_AS4_LEN) {
669 0 : flog_err(EC_BGP_PKT_OPEN,
670 : "%s AS4 capability has incorrect data length %d",
671 : peer->host, hdr->length);
672 0 : return 0;
673 : }
674 :
675 6 : as_t as4 = stream_getl(BGP_INPUT(peer));
676 :
677 6 : if (BGP_DEBUG(as4, AS4))
678 0 : zlog_debug(
679 : "%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
680 : peer->host, as4);
681 : return as4;
682 : }
683 :
684 2 : static int bgp_capability_ext_message(struct peer *peer,
685 : struct capability_header *hdr)
686 : {
687 2 : if (hdr->length != CAPABILITY_CODE_EXT_MESSAGE_LEN) {
688 0 : flog_err(
689 : EC_BGP_PKT_OPEN,
690 : "%s: BGP Extended Message capability has incorrect data length %d",
691 : peer->host, hdr->length);
692 0 : return -1;
693 : }
694 :
695 2 : SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV);
696 :
697 2 : return 0;
698 : }
699 :
700 2 : static int bgp_capability_addpath(struct peer *peer,
701 : struct capability_header *hdr)
702 : {
703 2 : struct stream *s = BGP_INPUT(peer);
704 2 : size_t end = stream_get_getp(s) + hdr->length;
705 :
706 2 : SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV);
707 :
708 : /* Verify length is a multiple of 4 */
709 2 : if (hdr->length % 4) {
710 0 : flog_warn(
711 : EC_BGP_CAPABILITY_INVALID_LENGTH,
712 : "Add Path: Received invalid length %d, non-multiple of 4",
713 : hdr->length);
714 0 : return -1;
715 : }
716 :
717 4 : while (stream_get_getp(s) + 4 <= end) {
718 2 : afi_t afi;
719 2 : safi_t safi;
720 2 : iana_afi_t pkt_afi = stream_getw(s);
721 2 : iana_safi_t pkt_safi = stream_getc(s);
722 2 : uint8_t send_receive = stream_getc(s);
723 :
724 2 : if (bgp_debug_neighbor_events(peer))
725 0 : zlog_debug(
726 : "%s OPEN has %s capability for afi/safi: %s/%s%s%s",
727 : peer->host,
728 : lookup_msg(capcode_str, hdr->code, NULL),
729 : iana_afi2str(pkt_afi), iana_safi2str(pkt_safi),
730 : (send_receive & BGP_ADDPATH_RX) ? ", receive"
731 : : "",
732 : (send_receive & BGP_ADDPATH_TX) ? ", transmit"
733 : : "");
734 :
735 : /* Convert AFI, SAFI to internal values, check. */
736 2 : if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
737 0 : if (bgp_debug_neighbor_events(peer))
738 0 : zlog_debug(
739 : "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI",
740 : peer->host, iana_afi2str(pkt_afi),
741 : iana_safi2str(pkt_safi));
742 0 : continue;
743 2 : } else if (!peer->afc[afi][safi]) {
744 0 : if (bgp_debug_neighbor_events(peer))
745 0 : zlog_debug(
746 : "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI",
747 : peer->host, iana_afi2str(pkt_afi),
748 : iana_safi2str(pkt_safi));
749 0 : continue;
750 : }
751 :
752 2 : if (send_receive & BGP_ADDPATH_RX)
753 2 : SET_FLAG(peer->af_cap[afi][safi],
754 : PEER_CAP_ADDPATH_AF_RX_RCV);
755 :
756 2 : if (send_receive & BGP_ADDPATH_TX)
757 0 : SET_FLAG(peer->af_cap[afi][safi],
758 : PEER_CAP_ADDPATH_AF_TX_RCV);
759 : }
760 :
761 : return 0;
762 : }
763 :
764 0 : static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
765 : {
766 0 : struct stream *s = BGP_INPUT(peer);
767 0 : size_t end = stream_get_getp(s) + hdr->length;
768 :
769 : /* Verify length is a multiple of 4 */
770 0 : if (hdr->length % 6) {
771 0 : flog_warn(
772 : EC_BGP_CAPABILITY_INVALID_LENGTH,
773 : "Extended NH: Received invalid length %d, non-multiple of 6",
774 : hdr->length);
775 0 : return -1;
776 : }
777 :
778 0 : while (stream_get_getp(s) + 6 <= end) {
779 0 : iana_afi_t pkt_afi = stream_getw(s);
780 0 : afi_t afi;
781 0 : iana_safi_t pkt_safi = stream_getw(s);
782 0 : safi_t safi;
783 0 : iana_afi_t pkt_nh_afi = stream_getw(s);
784 0 : afi_t nh_afi;
785 :
786 0 : if (bgp_debug_neighbor_events(peer))
787 0 : zlog_debug(
788 : "%s Received with afi/safi/next-hop afi: %s/%s/%u",
789 : peer->host, iana_afi2str(pkt_afi),
790 : iana_safi2str(pkt_safi), pkt_nh_afi);
791 :
792 : /* Convert AFI, SAFI to internal values, check. */
793 0 : if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
794 0 : if (bgp_debug_neighbor_events(peer))
795 0 : zlog_debug(
796 : "%s Addr-family %s/%s(afi/safi) not supported. Ignore the ENHE Attribute for this AFI/SAFI",
797 : peer->host, iana_afi2str(pkt_afi),
798 : iana_safi2str(pkt_safi));
799 0 : continue;
800 : }
801 :
802 : /* RFC 5549 specifies use of this capability only for IPv4 AFI,
803 : * with
804 : * the Nexthop AFI being IPv6. A future spec may introduce other
805 : * possibilities, so we ignore other values with a log. Also,
806 : * only
807 : * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported
808 : * (and expected).
809 : */
810 0 : nh_afi = afi_iana2int(pkt_nh_afi);
811 :
812 0 : if (afi != AFI_IP || nh_afi != AFI_IP6
813 0 : || !(safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
814 : || safi == SAFI_LABELED_UNICAST)) {
815 0 : flog_warn(
816 : EC_BGP_CAPABILITY_INVALID_DATA,
817 : "%s Unexpected afi/safi/next-hop afi: %s/%s/%u in Extended Next-hop capability, ignoring",
818 : peer->host, iana_afi2str(pkt_afi),
819 : iana_safi2str(pkt_safi), pkt_nh_afi);
820 0 : continue;
821 : }
822 :
823 0 : SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV);
824 :
825 0 : if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_ADV))
826 0 : SET_FLAG(peer->af_cap[afi][safi],
827 : PEER_CAP_ENHE_AF_NEGO);
828 : }
829 :
830 0 : SET_FLAG(peer->cap, PEER_CAP_ENHE_RCV);
831 :
832 0 : return 0;
833 : }
834 :
835 2 : static int bgp_capability_hostname(struct peer *peer,
836 : struct capability_header *hdr)
837 : {
838 2 : struct stream *s = BGP_INPUT(peer);
839 2 : char str[BGP_MAX_HOSTNAME + 1];
840 2 : size_t end = stream_get_getp(s) + hdr->length;
841 2 : uint8_t len;
842 :
843 2 : SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
844 :
845 2 : len = stream_getc(s);
846 2 : if (stream_get_getp(s) + len > end) {
847 0 : flog_warn(
848 : EC_BGP_CAPABILITY_INVALID_DATA,
849 : "%s: Received malformed hostname capability from peer %s",
850 : __func__, peer->host);
851 0 : return -1;
852 : }
853 :
854 2 : if (len > BGP_MAX_HOSTNAME) {
855 0 : stream_get(str, s, BGP_MAX_HOSTNAME);
856 0 : stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
857 0 : len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
858 2 : } else if (len)
859 2 : stream_get(str, s, len);
860 :
861 2 : if (len) {
862 2 : str[len] = '\0';
863 :
864 2 : XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
865 2 : XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
866 :
867 2 : peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
868 : }
869 :
870 2 : if (stream_get_getp(s) + 1 > end) {
871 0 : flog_warn(
872 : EC_BGP_CAPABILITY_INVALID_DATA,
873 : "%s: Received invalid domain name len (hostname capability) from peer %s",
874 : __func__, peer->host);
875 0 : return -1;
876 : }
877 :
878 2 : len = stream_getc(s);
879 2 : if (stream_get_getp(s) + len > end) {
880 0 : flog_warn(
881 : EC_BGP_CAPABILITY_INVALID_DATA,
882 : "%s: Received runt domain name (hostname capability) from peer %s",
883 : __func__, peer->host);
884 0 : return -1;
885 : }
886 :
887 2 : if (len > BGP_MAX_HOSTNAME) {
888 0 : stream_get(str, s, BGP_MAX_HOSTNAME);
889 0 : stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
890 0 : len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
891 2 : } else if (len)
892 0 : stream_get(str, s, len);
893 :
894 0 : if (len) {
895 0 : str[len] = '\0';
896 :
897 0 : XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
898 :
899 0 : peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
900 : }
901 :
902 2 : if (bgp_debug_neighbor_events(peer)) {
903 0 : zlog_debug("%s received hostname %s, domainname %s", peer->host,
904 : peer->hostname, peer->domainname);
905 : }
906 :
907 : return 0;
908 : }
909 :
910 0 : static int bgp_capability_role(struct peer *peer, struct capability_header *hdr)
911 : {
912 0 : SET_FLAG(peer->cap, PEER_CAP_ROLE_RCV);
913 0 : if (hdr->length != CAPABILITY_CODE_ROLE_LEN) {
914 0 : flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH,
915 : "Role: Received invalid length %d", hdr->length);
916 0 : return -1;
917 : }
918 0 : uint8_t role = stream_getc(BGP_INPUT(peer));
919 :
920 0 : peer->remote_role = role;
921 0 : return 0;
922 : }
923 :
924 : /**
925 : * Parse given capability.
926 : * XXX: This is reading into a stream, but not using stream API
927 : *
928 : * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
929 : * capabilities were encountered.
930 : */
931 20 : static int bgp_capability_parse(struct peer *peer, size_t length,
932 : int *mp_capability, uint8_t **error)
933 : {
934 20 : int ret;
935 20 : struct stream *s = BGP_INPUT(peer);
936 20 : size_t end = stream_get_getp(s) + length;
937 20 : uint16_t restart_flag_time = 0;
938 :
939 20 : assert(STREAM_READABLE(s) >= length);
940 :
941 40 : while (stream_get_getp(s) < end) {
942 20 : size_t start;
943 20 : uint8_t *sp = stream_pnt(s);
944 20 : struct capability_header caphdr;
945 :
946 20 : ret = 0;
947 : /* We need at least capability code and capability length. */
948 20 : if (stream_get_getp(s) + 2 > end) {
949 0 : zlog_info("%s Capability length error (< header)",
950 : peer->host);
951 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
952 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
953 0 : return -1;
954 : }
955 :
956 20 : caphdr.code = stream_getc(s);
957 20 : caphdr.length = stream_getc(s);
958 20 : start = stream_get_getp(s);
959 :
960 : /* Capability length check sanity check. */
961 20 : if (start + caphdr.length > end) {
962 0 : zlog_info("%s Capability length error (< length)",
963 : peer->host);
964 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
965 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
966 0 : return -1;
967 : }
968 :
969 20 : if (bgp_debug_neighbor_events(peer))
970 0 : zlog_debug("%s OPEN has %s capability (%u), length %u",
971 : peer->host,
972 : lookup_msg(capcode_str, caphdr.code, NULL),
973 : caphdr.code, caphdr.length);
974 :
975 : /* Length sanity check, type-specific, for known capabilities */
976 20 : switch (caphdr.code) {
977 18 : case CAPABILITY_CODE_MP:
978 : case CAPABILITY_CODE_REFRESH:
979 : case CAPABILITY_CODE_REFRESH_OLD:
980 : case CAPABILITY_CODE_ORF:
981 : case CAPABILITY_CODE_ORF_OLD:
982 : case CAPABILITY_CODE_RESTART:
983 : case CAPABILITY_CODE_AS4:
984 : case CAPABILITY_CODE_ADDPATH:
985 : case CAPABILITY_CODE_DYNAMIC:
986 : case CAPABILITY_CODE_DYNAMIC_OLD:
987 : case CAPABILITY_CODE_ENHE:
988 : case CAPABILITY_CODE_FQDN:
989 : case CAPABILITY_CODE_ENHANCED_RR:
990 : case CAPABILITY_CODE_EXT_MESSAGE:
991 : case CAPABILITY_CODE_ROLE:
992 : /* Check length. */
993 18 : if (caphdr.length < cap_minsizes[caphdr.code]) {
994 0 : zlog_info(
995 : "%s %s Capability length error: got %u, expected at least %u",
996 : peer->host,
997 : lookup_msg(capcode_str, caphdr.code,
998 : NULL),
999 : caphdr.length,
1000 : (unsigned)cap_minsizes[caphdr.code]);
1001 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1002 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1003 0 : return -1;
1004 : }
1005 18 : if (caphdr.length
1006 10 : && caphdr.length % cap_modsizes[caphdr.code] != 0) {
1007 0 : zlog_info(
1008 : "%s %s Capability length error: got %u, expected a multiple of %u",
1009 : peer->host,
1010 : lookup_msg(capcode_str, caphdr.code,
1011 : NULL),
1012 : caphdr.length,
1013 : (unsigned)cap_modsizes[caphdr.code]);
1014 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1015 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1016 0 : return -1;
1017 : }
1018 : /* we deliberately ignore unknown codes, see below */
1019 : default:
1020 20 : break;
1021 : }
1022 :
1023 20 : switch (caphdr.code) {
1024 2 : case CAPABILITY_CODE_MP: {
1025 2 : *mp_capability = 1;
1026 :
1027 : /* Ignore capability when override-capability is set. */
1028 2 : if (!CHECK_FLAG(peer->flags,
1029 : PEER_FLAG_OVERRIDE_CAPABILITY)) {
1030 : /* Set negotiated value. */
1031 2 : ret = bgp_capability_mp(peer, &caphdr);
1032 :
1033 : /* Unsupported Capability. */
1034 2 : if (ret < 0) {
1035 : /* Store return data. */
1036 0 : memcpy(*error, sp, caphdr.length + 2);
1037 0 : *error += caphdr.length + 2;
1038 : }
1039 : ret = 0; /* Don't return error for this */
1040 : }
1041 : } break;
1042 6 : case CAPABILITY_CODE_ENHANCED_RR:
1043 : case CAPABILITY_CODE_REFRESH:
1044 : case CAPABILITY_CODE_REFRESH_OLD: {
1045 : /* BGP refresh capability */
1046 6 : if (caphdr.code == CAPABILITY_CODE_ENHANCED_RR)
1047 2 : SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV);
1048 4 : else if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
1049 2 : SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV);
1050 : else
1051 2 : SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV);
1052 : } break;
1053 0 : case CAPABILITY_CODE_ORF:
1054 : case CAPABILITY_CODE_ORF_OLD:
1055 0 : ret = bgp_capability_orf_entry(peer, &caphdr);
1056 0 : break;
1057 2 : case CAPABILITY_CODE_RESTART:
1058 2 : ret = bgp_capability_restart(peer, &caphdr);
1059 2 : break;
1060 2 : case CAPABILITY_CODE_LLGR:
1061 2 : ret = bgp_capability_llgr(peer, &caphdr);
1062 2 : break;
1063 0 : case CAPABILITY_CODE_DYNAMIC:
1064 : case CAPABILITY_CODE_DYNAMIC_OLD:
1065 0 : SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV);
1066 0 : break;
1067 2 : case CAPABILITY_CODE_AS4:
1068 : /* Already handled as a special-case parsing of the
1069 : * capabilities
1070 : * at the beginning of OPEN processing. So we care not a
1071 : * jot
1072 : * for the value really, only error case.
1073 : */
1074 2 : if (!bgp_capability_as4(peer, &caphdr))
1075 : ret = -1;
1076 : break;
1077 2 : case CAPABILITY_CODE_ADDPATH:
1078 2 : ret = bgp_capability_addpath(peer, &caphdr);
1079 2 : break;
1080 0 : case CAPABILITY_CODE_ENHE:
1081 0 : ret = bgp_capability_enhe(peer, &caphdr);
1082 0 : break;
1083 2 : case CAPABILITY_CODE_EXT_MESSAGE:
1084 2 : ret = bgp_capability_ext_message(peer, &caphdr);
1085 2 : break;
1086 2 : case CAPABILITY_CODE_FQDN:
1087 2 : ret = bgp_capability_hostname(peer, &caphdr);
1088 2 : break;
1089 0 : case CAPABILITY_CODE_ROLE:
1090 0 : ret = bgp_capability_role(peer, &caphdr);
1091 0 : break;
1092 0 : default:
1093 0 : if (caphdr.code > 128) {
1094 : /* We don't send Notification for unknown vendor
1095 : specific
1096 : capabilities. It seems reasonable for now...
1097 : */
1098 0 : flog_warn(EC_BGP_CAPABILITY_VENDOR,
1099 : "%s Vendor specific capability %d",
1100 : peer->host, caphdr.code);
1101 : } else {
1102 0 : flog_warn(
1103 : EC_BGP_CAPABILITY_UNKNOWN,
1104 : "%s unrecognized capability code: %d - ignored",
1105 : peer->host, caphdr.code);
1106 0 : memcpy(*error, sp, caphdr.length + 2);
1107 0 : *error += caphdr.length + 2;
1108 : }
1109 : }
1110 :
1111 16 : if (ret < 0) {
1112 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1113 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1114 0 : return -1;
1115 : }
1116 20 : if (stream_get_getp(s) != (start + caphdr.length)) {
1117 0 : if (stream_get_getp(s) > (start + caphdr.length))
1118 0 : flog_warn(
1119 : EC_BGP_CAPABILITY_INVALID_LENGTH,
1120 : "%s Cap-parser for %s read past cap-length, %u!",
1121 : peer->host,
1122 : lookup_msg(capcode_str, caphdr.code,
1123 : NULL),
1124 : caphdr.length);
1125 0 : stream_set_getp(s, start + caphdr.length);
1126 : }
1127 :
1128 20 : if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
1129 16 : UNSET_FLAG(restart_flag_time, 0xF000);
1130 16 : peer->v_gr_restart = restart_flag_time;
1131 : }
1132 : }
1133 : return 0;
1134 : }
1135 :
1136 0 : static bool strict_capability_same(struct peer *peer)
1137 : {
1138 0 : int i, j;
1139 :
1140 0 : for (i = AFI_IP; i < AFI_MAX; i++)
1141 0 : for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
1142 0 : if (peer->afc[i][j] != peer->afc_nego[i][j])
1143 : return false;
1144 : return true;
1145 : }
1146 :
1147 :
1148 2 : static bool bgp_role_violation(struct peer *peer)
1149 : {
1150 2 : uint8_t local_role = peer->local_role;
1151 2 : uint8_t remote_role = peer->remote_role;
1152 :
1153 2 : if (local_role != ROLE_UNDEFINED && remote_role != ROLE_UNDEFINED &&
1154 0 : !((local_role == ROLE_PEER && remote_role == ROLE_PEER) ||
1155 0 : (local_role == ROLE_PROVIDER && remote_role == ROLE_CUSTOMER) ||
1156 0 : (local_role == ROLE_CUSTOMER && remote_role == ROLE_PROVIDER) ||
1157 0 : (local_role == ROLE_RS_SERVER && remote_role == ROLE_RS_CLIENT) ||
1158 0 : (local_role == ROLE_RS_CLIENT &&
1159 0 : remote_role == ROLE_RS_SERVER))) {
1160 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1161 : BGP_NOTIFY_OPEN_ROLE_MISMATCH);
1162 0 : return true;
1163 : }
1164 2 : if (remote_role == ROLE_UNDEFINED &&
1165 2 : CHECK_FLAG(peer->flags, PEER_FLAG_ROLE_STRICT_MODE)) {
1166 0 : const char *err_msg =
1167 : "Strict mode. Please set the role on your side.";
1168 0 : bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1169 : BGP_NOTIFY_OPEN_ROLE_MISMATCH,
1170 : (uint8_t *)err_msg, strlen(err_msg));
1171 0 : return true;
1172 : }
1173 : return false;
1174 : }
1175 :
1176 :
1177 : /* peek into option, stores ASN to *as4 if the AS4 capability was found.
1178 : * Returns 0 if no as4 found, as4cap value otherwise.
1179 : */
1180 4 : as_t peek_for_as4_capability(struct peer *peer, uint16_t length)
1181 : {
1182 4 : struct stream *s = BGP_INPUT(peer);
1183 4 : size_t orig_getp = stream_get_getp(s);
1184 4 : size_t end = orig_getp + length;
1185 4 : as_t as4 = 0;
1186 :
1187 4 : if (BGP_DEBUG(as4, AS4))
1188 0 : zlog_debug(
1189 : "%s [AS4] rcv OPEN w/ OPTION parameter len: %u, peeking for as4",
1190 : peer->host, length);
1191 : /* the error cases we DONT handle, we ONLY try to read as4 out of
1192 : * correctly formatted options.
1193 : */
1194 20 : while (stream_get_getp(s) < end) {
1195 20 : uint8_t opt_type;
1196 20 : uint16_t opt_length;
1197 :
1198 : /* Ensure we can read the option type */
1199 20 : if (stream_get_getp(s) + 1 > end)
1200 0 : goto end;
1201 :
1202 : /* Fetch the option type */
1203 20 : opt_type = stream_getc(s);
1204 :
1205 : /*
1206 : * Check the length and fetch the opt_length
1207 : * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
1208 : * then we do a getw which is 2 bytes. So we need to
1209 : * ensure that we can read that as well
1210 : */
1211 20 : if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
1212 0 : if (stream_get_getp(s) + 2 > end)
1213 0 : goto end;
1214 :
1215 0 : opt_length = stream_getw(s);
1216 : } else {
1217 20 : if (stream_get_getp(s) + 1 > end)
1218 0 : goto end;
1219 :
1220 20 : opt_length = stream_getc(s);
1221 : }
1222 :
1223 : /* Option length check. */
1224 20 : if (stream_get_getp(s) + opt_length > end)
1225 0 : goto end;
1226 :
1227 20 : if (opt_type == BGP_OPEN_OPT_CAP) {
1228 20 : unsigned long capd_start = stream_get_getp(s);
1229 20 : unsigned long capd_end = capd_start + opt_length;
1230 :
1231 20 : assert(capd_end <= end);
1232 :
1233 36 : while (stream_get_getp(s) < capd_end) {
1234 20 : struct capability_header hdr;
1235 :
1236 20 : if (stream_get_getp(s) + 2 > capd_end)
1237 4 : goto end;
1238 :
1239 20 : hdr.code = stream_getc(s);
1240 20 : hdr.length = stream_getc(s);
1241 :
1242 20 : if ((stream_get_getp(s) + hdr.length)
1243 : > capd_end)
1244 0 : goto end;
1245 :
1246 20 : if (hdr.code == CAPABILITY_CODE_AS4) {
1247 4 : if (BGP_DEBUG(as4, AS4))
1248 0 : zlog_debug(
1249 : "[AS4] found AS4 capability, about to parse");
1250 4 : as4 = bgp_capability_as4(peer, &hdr);
1251 :
1252 4 : goto end;
1253 : }
1254 16 : stream_forward_getp(s, hdr.length);
1255 : }
1256 : }
1257 : }
1258 :
1259 0 : end:
1260 4 : stream_set_getp(s, orig_getp);
1261 4 : return as4;
1262 : }
1263 :
1264 : /**
1265 : * Parse open option.
1266 : *
1267 : * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1268 : */
1269 2 : int bgp_open_option_parse(struct peer *peer, uint16_t length,
1270 : int *mp_capability)
1271 : {
1272 2 : int ret = 0;
1273 2 : uint8_t *error;
1274 2 : uint8_t error_data[BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE];
1275 2 : struct stream *s = BGP_INPUT(peer);
1276 2 : size_t end = stream_get_getp(s) + length;
1277 :
1278 2 : error = error_data;
1279 :
1280 2 : if (bgp_debug_neighbor_events(peer))
1281 0 : zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1282 : peer->host, length);
1283 :
1284 : /* Unset any previously received GR capability. */
1285 2 : UNSET_FLAG(peer->cap, PEER_CAP_RESTART_RCV);
1286 :
1287 22 : while (stream_get_getp(s) < end) {
1288 20 : uint8_t opt_type;
1289 20 : uint16_t opt_length;
1290 :
1291 : /*
1292 : * Check that we can read the opt_type and fetch it
1293 : */
1294 20 : if (STREAM_READABLE(s) < 1) {
1295 0 : zlog_info("%s Option length error", peer->host);
1296 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1297 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1298 0 : return -1;
1299 : }
1300 20 : opt_type = stream_getc(s);
1301 :
1302 : /*
1303 : * Check the length of the stream to ensure that
1304 : * FRR can properly read the opt_length. Then read it
1305 : */
1306 20 : if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
1307 0 : if (STREAM_READABLE(s) < 2) {
1308 0 : zlog_info("%s Option length error", peer->host);
1309 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1310 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1311 0 : return -1;
1312 : }
1313 :
1314 0 : opt_length = stream_getw(s);
1315 : } else {
1316 20 : if (STREAM_READABLE(s) < 1) {
1317 0 : zlog_info("%s Option length error", peer->host);
1318 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1319 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1320 0 : return -1;
1321 : }
1322 :
1323 20 : opt_length = stream_getc(s);
1324 : }
1325 :
1326 : /* Option length check. */
1327 20 : if (STREAM_READABLE(s) < opt_length) {
1328 0 : zlog_info("%s Option length error (%d)", peer->host,
1329 : opt_length);
1330 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1331 : BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1332 0 : return -1;
1333 : }
1334 :
1335 20 : if (bgp_debug_neighbor_events(peer))
1336 0 : zlog_debug(
1337 : "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1338 : peer->host, opt_type,
1339 : opt_type == BGP_OPEN_OPT_CAP ? "Capability"
1340 : : "Unknown",
1341 : opt_length);
1342 :
1343 20 : switch (opt_type) {
1344 20 : case BGP_OPEN_OPT_CAP:
1345 20 : ret = bgp_capability_parse(peer, opt_length,
1346 : mp_capability, &error);
1347 20 : break;
1348 0 : default:
1349 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1350 : BGP_NOTIFY_OPEN_UNSUP_PARAM);
1351 0 : ret = -1;
1352 0 : break;
1353 : }
1354 :
1355 : /* Parse error. To accumulate all unsupported capability codes,
1356 : bgp_capability_parse does not return -1 when encounter
1357 : unsupported capability code. To detect that, please check
1358 : error and erro_data pointer, like below. */
1359 20 : if (ret < 0)
1360 : return -1;
1361 : }
1362 :
1363 : /* All OPEN option is parsed. Check capability when strict compare
1364 : flag is enabled.*/
1365 2 : if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
1366 : /* If Unsupported Capability exists. */
1367 0 : if (error != error_data) {
1368 0 : bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1369 : BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1370 : error_data,
1371 0 : error - error_data);
1372 0 : return -1;
1373 : }
1374 :
1375 : /* Check local capability does not negotiated with remote
1376 : peer. */
1377 0 : if (!strict_capability_same(peer)) {
1378 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1379 : BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1380 0 : return -1;
1381 : }
1382 : }
1383 :
1384 : /* Extended Message Support */
1385 4 : peer->max_packet_size =
1386 : (CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
1387 2 : && CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV))
1388 : ? BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE
1389 : : BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
1390 :
1391 : /* Check that roles are corresponding to each other */
1392 2 : if (bgp_role_violation(peer))
1393 : return -1;
1394 :
1395 : /* Check there are no common AFI/SAFIs and send Unsupported Capability
1396 : error. */
1397 2 : if (*mp_capability
1398 2 : && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1399 2 : if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1400 2 : && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1401 0 : && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1402 : && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1403 0 : && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
1404 : && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
1405 0 : && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1406 0 : && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1407 0 : && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1408 : && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1409 0 : && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
1410 : && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
1411 0 : && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
1412 0 : flog_err(EC_BGP_PKT_OPEN,
1413 : "%s [Error] Configured AFI/SAFIs do not overlap with received MP capabilities",
1414 : peer->host);
1415 :
1416 0 : if (error != error_data)
1417 0 : bgp_notify_send_with_data(
1418 : peer, BGP_NOTIFY_OPEN_ERR,
1419 : BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1420 0 : error - error_data);
1421 : else
1422 0 : bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1423 : BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1424 0 : return -1;
1425 : }
1426 : }
1427 : return 0;
1428 : }
1429 :
1430 0 : static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
1431 : afi_t afi, safi_t safi, uint8_t code,
1432 : bool ext_opt_params)
1433 : {
1434 0 : uint16_t cap_len;
1435 0 : uint8_t orf_len;
1436 0 : unsigned long capp;
1437 0 : unsigned long orfp;
1438 0 : unsigned long numberp;
1439 0 : int number_of_orfs = 0;
1440 0 : iana_afi_t pkt_afi = IANA_AFI_IPV4;
1441 0 : iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1442 :
1443 : /* Convert AFI, SAFI to values for packet. */
1444 0 : bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1445 :
1446 0 : stream_putc(s, BGP_OPEN_OPT_CAP);
1447 0 : capp = stream_get_endp(s); /* Set Capability Len Pointer */
1448 0 : ext_opt_params ? stream_putw(s, 0)
1449 0 : : stream_putc(s, 0); /* Capability Length */
1450 0 : stream_putc(s, code); /* Capability Code */
1451 0 : orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1452 0 : stream_putc(s, 0); /* ORF Length */
1453 0 : stream_putw(s, pkt_afi);
1454 0 : stream_putc(s, 0);
1455 0 : stream_putc(s, pkt_safi);
1456 0 : numberp = stream_get_endp(s); /* Set Number Pointer */
1457 0 : stream_putc(s, 0); /* Number of ORFs */
1458 :
1459 : /* Address Prefix ORF */
1460 0 : if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1461 0 : || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1462 0 : stream_putc(s, (code == CAPABILITY_CODE_ORF
1463 : ? ORF_TYPE_PREFIX
1464 : : ORF_TYPE_PREFIX_OLD));
1465 :
1466 0 : if (CHECK_FLAG(peer->af_flags[afi][safi],
1467 : PEER_FLAG_ORF_PREFIX_SM)
1468 0 : && CHECK_FLAG(peer->af_flags[afi][safi],
1469 : PEER_FLAG_ORF_PREFIX_RM)) {
1470 0 : SET_FLAG(peer->af_cap[afi][safi],
1471 : PEER_CAP_ORF_PREFIX_SM_ADV);
1472 0 : SET_FLAG(peer->af_cap[afi][safi],
1473 : PEER_CAP_ORF_PREFIX_RM_ADV);
1474 0 : stream_putc(s, ORF_MODE_BOTH);
1475 0 : } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1476 : PEER_FLAG_ORF_PREFIX_SM)) {
1477 0 : SET_FLAG(peer->af_cap[afi][safi],
1478 : PEER_CAP_ORF_PREFIX_SM_ADV);
1479 0 : stream_putc(s, ORF_MODE_SEND);
1480 : } else {
1481 0 : SET_FLAG(peer->af_cap[afi][safi],
1482 : PEER_CAP_ORF_PREFIX_RM_ADV);
1483 0 : stream_putc(s, ORF_MODE_RECEIVE);
1484 : }
1485 : number_of_orfs++;
1486 : }
1487 :
1488 : /* Total Number of ORFs. */
1489 0 : stream_putc_at(s, numberp, number_of_orfs);
1490 :
1491 : /* Total ORF Len. */
1492 0 : orf_len = stream_get_endp(s) - orfp - 1;
1493 0 : stream_putc_at(s, orfp, orf_len);
1494 :
1495 : /* Total Capability Len. */
1496 0 : cap_len = stream_get_endp(s) - capp - 1;
1497 0 : ext_opt_params ? stream_putw_at(s, capp, cap_len)
1498 0 : : stream_putc_at(s, capp, cap_len);
1499 0 : }
1500 :
1501 4 : static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
1502 : bool ext_opt_params)
1503 : {
1504 4 : int len;
1505 4 : iana_afi_t pkt_afi = IANA_AFI_IPV4;
1506 4 : afi_t afi;
1507 4 : safi_t safi;
1508 4 : iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1509 4 : uint32_t restart_time;
1510 4 : unsigned long capp = 0;
1511 4 : unsigned long rcapp = 0;
1512 :
1513 4 : if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
1514 4 : && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
1515 0 : return;
1516 :
1517 4 : if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1518 0 : zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
1519 : peer->host);
1520 :
1521 4 : SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1522 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1523 4 : capp = stream_get_endp(s); /* Set Capability Len Pointer */
1524 0 : ext_opt_params ? stream_putw(s, 0)
1525 4 : : stream_putc(s, 0); /* Capability Length */
1526 4 : stream_putc(s, CAPABILITY_CODE_RESTART);
1527 : /* Set Restart Capability Len Pointer */
1528 4 : rcapp = stream_get_endp(s);
1529 4 : stream_putc(s, 0);
1530 4 : restart_time = peer->bgp->restart_time;
1531 4 : if (peer->bgp->t_startup) {
1532 4 : SET_FLAG(restart_time, GRACEFUL_RESTART_R_BIT);
1533 4 : SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV);
1534 4 : if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1535 0 : zlog_debug("[BGP_GR] Sending R-Bit for peer: %s",
1536 : peer->host);
1537 : }
1538 :
1539 4 : if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) {
1540 4 : SET_FLAG(restart_time, GRACEFUL_RESTART_N_BIT);
1541 4 : SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV);
1542 4 : if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1543 0 : zlog_debug("[BGP_GR] Sending N-Bit for peer: %s",
1544 : peer->host);
1545 : }
1546 :
1547 4 : stream_putw(s, restart_time);
1548 :
1549 : /* Send address-family specific graceful-restart capability
1550 : * only when GR config is present
1551 : */
1552 4 : if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
1553 0 : if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
1554 0 : && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1555 0 : zlog_debug("[BGP_GR] F bit Set");
1556 :
1557 0 : FOREACH_AFI_SAFI (afi, safi) {
1558 0 : if (!peer->afc[afi][safi])
1559 0 : continue;
1560 :
1561 0 : if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1562 0 : zlog_debug(
1563 : "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
1564 : afi, safi);
1565 :
1566 : /* Convert AFI, SAFI to values for
1567 : * packet.
1568 : */
1569 0 : bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1570 : &pkt_safi);
1571 0 : stream_putw(s, pkt_afi);
1572 0 : stream_putc(s, pkt_safi);
1573 0 : if (CHECK_FLAG(peer->bgp->flags,
1574 : BGP_FLAG_GR_PRESERVE_FWD))
1575 0 : stream_putc(s, GRACEFUL_RESTART_F_BIT);
1576 : else
1577 0 : stream_putc(s, 0);
1578 : }
1579 : }
1580 :
1581 : /* Total Graceful restart capability Len. */
1582 4 : len = stream_get_endp(s) - rcapp - 1;
1583 4 : stream_putc_at(s, rcapp, len);
1584 :
1585 : /* Total Capability Len. */
1586 4 : len = stream_get_endp(s) - capp - 1;
1587 0 : ext_opt_params ? stream_putw_at(s, capp, len - 1)
1588 4 : : stream_putc_at(s, capp, len);
1589 : }
1590 :
1591 4 : static void bgp_peer_send_llgr_capability(struct stream *s, struct peer *peer,
1592 : bool ext_opt_params)
1593 : {
1594 4 : int len;
1595 4 : iana_afi_t pkt_afi = IANA_AFI_IPV4;
1596 4 : afi_t afi;
1597 4 : safi_t safi;
1598 4 : iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1599 4 : unsigned long capp = 0;
1600 4 : unsigned long rcapp = 0;
1601 :
1602 4 : if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV))
1603 0 : return;
1604 :
1605 4 : SET_FLAG(peer->cap, PEER_CAP_LLGR_ADV);
1606 :
1607 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1608 4 : capp = stream_get_endp(s); /* Set Capability Len Pointer */
1609 0 : ext_opt_params ? stream_putw(s, 0)
1610 4 : : stream_putc(s, 0); /* Capability Length */
1611 4 : stream_putc(s, CAPABILITY_CODE_LLGR);
1612 :
1613 4 : rcapp = stream_get_endp(s);
1614 4 : stream_putc(s, 0);
1615 :
1616 104 : FOREACH_AFI_SAFI (afi, safi) {
1617 84 : if (!peer->afc[afi][safi])
1618 80 : continue;
1619 :
1620 4 : bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1621 :
1622 4 : stream_putw(s, pkt_afi);
1623 4 : stream_putc(s, pkt_safi);
1624 4 : stream_putc(s, LLGR_F_BIT);
1625 4 : stream_put3(s, peer->bgp->llgr_stale_time);
1626 :
1627 4 : SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_LLGR_AF_ADV);
1628 : }
1629 :
1630 : /* Total Long-lived Graceful Restart capability Len. */
1631 4 : len = stream_get_endp(s) - rcapp - 1;
1632 4 : stream_putc_at(s, rcapp, len);
1633 :
1634 : /* Total Capability Len. */
1635 4 : len = stream_get_endp(s) - capp - 1;
1636 0 : ext_opt_params ? stream_putw_at(s, capp, len - 1)
1637 4 : : stream_putc_at(s, capp, len);
1638 : }
1639 :
1640 : /* Fill in capability open option to the packet. */
1641 4 : uint16_t bgp_open_capability(struct stream *s, struct peer *peer,
1642 : bool ext_opt_params)
1643 : {
1644 4 : uint16_t len;
1645 4 : unsigned long cp, capp, rcapp, eopl = 0;
1646 4 : iana_afi_t pkt_afi = IANA_AFI_IPV4;
1647 4 : afi_t afi;
1648 4 : safi_t safi;
1649 4 : iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
1650 4 : as_t local_as;
1651 4 : uint8_t afi_safi_count = 0;
1652 4 : bool adv_addpath_tx = false;
1653 :
1654 : /* Non-Ext OP Len. */
1655 4 : cp = stream_get_endp(s);
1656 4 : stream_putc(s, 0);
1657 :
1658 4 : if (ext_opt_params) {
1659 : /* Non-Ext OP Len. */
1660 0 : stream_putc_at(s, cp, BGP_OPEN_NON_EXT_OPT_LEN);
1661 :
1662 : /* Non-Ext OP Type */
1663 0 : stream_putc(s, BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH);
1664 :
1665 : /* Extended Opt. Parm. Length */
1666 0 : eopl = stream_get_endp(s);
1667 0 : stream_putw(s, 0);
1668 : }
1669 :
1670 : /* Do not send capability. */
1671 4 : if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1672 4 : || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
1673 : return 0;
1674 :
1675 : /* MP capability for configured AFI, SAFI */
1676 100 : FOREACH_AFI_SAFI (afi, safi) {
1677 84 : if (peer->afc[afi][safi]) {
1678 : /* Convert AFI, SAFI to values for packet. */
1679 4 : bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1680 : &pkt_safi);
1681 :
1682 4 : peer->afc_adv[afi][safi] = 1;
1683 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1684 4 : ext_opt_params
1685 0 : ? stream_putw(s, CAPABILITY_CODE_MP_LEN + 2)
1686 4 : : stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
1687 4 : stream_putc(s, CAPABILITY_CODE_MP);
1688 4 : stream_putc(s, CAPABILITY_CODE_MP_LEN);
1689 4 : stream_putw(s, pkt_afi);
1690 4 : stream_putc(s, 0);
1691 4 : stream_putc(s, pkt_safi);
1692 :
1693 : /* Extended nexthop capability - currently
1694 : * supporting RFC-5549 for
1695 : * Link-Local peering only
1696 : */
1697 4 : if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1698 0 : && peer->su.sa.sa_family == AF_INET6
1699 0 : && afi == AFI_IP
1700 0 : && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
1701 : || safi == SAFI_LABELED_UNICAST)) {
1702 : /* RFC 5549 Extended Next Hop Encoding
1703 : */
1704 0 : SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
1705 0 : stream_putc(s, BGP_OPEN_OPT_CAP);
1706 0 : ext_opt_params
1707 0 : ? stream_putw(s,
1708 : CAPABILITY_CODE_ENHE_LEN
1709 : + 2)
1710 0 : : stream_putc(s,
1711 : CAPABILITY_CODE_ENHE_LEN
1712 : + 2);
1713 0 : stream_putc(s, CAPABILITY_CODE_ENHE);
1714 0 : stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1715 :
1716 0 : SET_FLAG(peer->af_cap[AFI_IP][safi],
1717 : PEER_CAP_ENHE_AF_ADV);
1718 0 : stream_putw(s, pkt_afi);
1719 0 : stream_putw(s, pkt_safi);
1720 0 : stream_putw(s, afi_int2iana(AFI_IP6));
1721 :
1722 0 : if (CHECK_FLAG(peer->af_cap[afi][safi],
1723 : PEER_CAP_ENHE_AF_RCV))
1724 0 : SET_FLAG(peer->af_cap[afi][safi],
1725 : PEER_CAP_ENHE_AF_NEGO);
1726 : }
1727 : }
1728 : }
1729 :
1730 : /* Route refresh. */
1731 4 : SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1732 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1733 0 : ext_opt_params ? stream_putw(s, CAPABILITY_CODE_REFRESH_LEN + 2)
1734 4 : : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1735 4 : stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1736 4 : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1737 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1738 0 : ext_opt_params ? stream_putw(s, CAPABILITY_CODE_REFRESH_LEN + 2)
1739 4 : : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1740 4 : stream_putc(s, CAPABILITY_CODE_REFRESH);
1741 4 : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1742 :
1743 : /* Enhanced Route Refresh. */
1744 4 : SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_ADV);
1745 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1746 0 : ext_opt_params ? stream_putw(s, CAPABILITY_CODE_ENHANCED_LEN + 2)
1747 4 : : stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN + 2);
1748 4 : stream_putc(s, CAPABILITY_CODE_ENHANCED_RR);
1749 4 : stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN);
1750 :
1751 : /* AS4 */
1752 4 : SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1753 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1754 0 : ext_opt_params ? stream_putw(s, CAPABILITY_CODE_AS4_LEN + 2)
1755 4 : : stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
1756 4 : stream_putc(s, CAPABILITY_CODE_AS4);
1757 4 : stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1758 4 : if (peer->change_local_as)
1759 : local_as = peer->change_local_as;
1760 : else
1761 4 : local_as = peer->local_as;
1762 4 : stream_putl(s, local_as);
1763 :
1764 : /* Extended Message Support */
1765 4 : SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV);
1766 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1767 0 : ext_opt_params ? stream_putw(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2)
1768 4 : : stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2);
1769 4 : stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE);
1770 4 : stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN);
1771 :
1772 : /* Role*/
1773 4 : if (peer->local_role != ROLE_UNDEFINED) {
1774 0 : SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV);
1775 0 : stream_putc(s, BGP_OPEN_OPT_CAP);
1776 0 : stream_putc(s, CAPABILITY_CODE_ROLE_LEN + 2);
1777 0 : stream_putc(s, CAPABILITY_CODE_ROLE);
1778 0 : stream_putc(s, CAPABILITY_CODE_ROLE_LEN);
1779 0 : stream_putc(s, peer->local_role);
1780 : }
1781 :
1782 : /* AddPath */
1783 100 : FOREACH_AFI_SAFI (afi, safi) {
1784 84 : if (peer->afc[afi][safi]) {
1785 4 : afi_safi_count++;
1786 :
1787 : /* Only advertise addpath TX if a feature that
1788 : * will use it is
1789 : * configured */
1790 4 : if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
1791 0 : adv_addpath_tx = true;
1792 :
1793 : /* If we have enabled labeled unicast, we MUST check
1794 : * against unicast SAFI because addpath IDs are
1795 : * allocated under unicast SAFI, the same as the RIB
1796 : * is managed in unicast SAFI.
1797 : */
1798 4 : if (safi == SAFI_LABELED_UNICAST)
1799 0 : if (peer->addpath_type[afi][SAFI_UNICAST] !=
1800 : BGP_ADDPATH_NONE)
1801 84 : adv_addpath_tx = true;
1802 : }
1803 : }
1804 :
1805 4 : SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1806 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1807 4 : ext_opt_params
1808 0 : ? stream_putw(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count)
1809 0 : + 2)
1810 4 : : stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count)
1811 4 : + 2);
1812 4 : stream_putc(s, CAPABILITY_CODE_ADDPATH);
1813 4 : stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1814 :
1815 104 : FOREACH_AFI_SAFI (afi, safi) {
1816 84 : if (peer->afc[afi][safi]) {
1817 4 : bool adv_addpath_rx =
1818 4 : !CHECK_FLAG(peer->af_flags[afi][safi],
1819 : PEER_FLAG_DISABLE_ADDPATH_RX);
1820 4 : uint8_t flags = 0;
1821 :
1822 : /* Convert AFI, SAFI to values for packet. */
1823 4 : bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1824 : &pkt_safi);
1825 :
1826 4 : stream_putw(s, pkt_afi);
1827 4 : stream_putc(s, pkt_safi);
1828 :
1829 4 : if (adv_addpath_rx) {
1830 4 : SET_FLAG(flags, BGP_ADDPATH_RX);
1831 4 : SET_FLAG(peer->af_cap[afi][safi],
1832 : PEER_CAP_ADDPATH_AF_RX_ADV);
1833 : } else {
1834 0 : UNSET_FLAG(peer->af_cap[afi][safi],
1835 : PEER_CAP_ADDPATH_AF_RX_ADV);
1836 : }
1837 :
1838 4 : if (adv_addpath_tx) {
1839 0 : SET_FLAG(flags, BGP_ADDPATH_TX);
1840 0 : SET_FLAG(peer->af_cap[afi][safi],
1841 : PEER_CAP_ADDPATH_AF_TX_ADV);
1842 0 : if (safi == SAFI_LABELED_UNICAST)
1843 0 : SET_FLAG(
1844 : peer->af_cap[afi][SAFI_UNICAST],
1845 : PEER_CAP_ADDPATH_AF_TX_ADV);
1846 : } else {
1847 4 : UNSET_FLAG(peer->af_cap[afi][safi],
1848 : PEER_CAP_ADDPATH_AF_TX_ADV);
1849 : }
1850 :
1851 4 : stream_putc(s, flags);
1852 : }
1853 : }
1854 :
1855 : /* ORF capability. */
1856 100 : FOREACH_AFI_SAFI (afi, safi) {
1857 84 : if (CHECK_FLAG(peer->af_flags[afi][safi],
1858 : PEER_FLAG_ORF_PREFIX_SM)
1859 84 : || CHECK_FLAG(peer->af_flags[afi][safi],
1860 : PEER_FLAG_ORF_PREFIX_RM)) {
1861 0 : bgp_open_capability_orf(s, peer, afi, safi,
1862 : CAPABILITY_CODE_ORF_OLD,
1863 : ext_opt_params);
1864 0 : bgp_open_capability_orf(s, peer, afi, safi,
1865 : CAPABILITY_CODE_ORF,
1866 : ext_opt_params);
1867 : }
1868 : }
1869 :
1870 : /* Dynamic capability. */
1871 4 : if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1872 0 : SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1873 0 : stream_putc(s, BGP_OPEN_OPT_CAP);
1874 0 : ext_opt_params
1875 0 : ? stream_putw(s, CAPABILITY_CODE_DYNAMIC_LEN + 2)
1876 0 : : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1877 0 : stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1878 0 : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1879 0 : stream_putc(s, BGP_OPEN_OPT_CAP);
1880 0 : ext_opt_params
1881 0 : ? stream_putw(s, CAPABILITY_CODE_DYNAMIC_LEN + 2)
1882 0 : : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1883 0 : stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1884 0 : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1885 : }
1886 :
1887 : /* Hostname capability */
1888 4 : if (cmd_hostname_get()) {
1889 4 : SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1890 4 : stream_putc(s, BGP_OPEN_OPT_CAP);
1891 4 : rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1892 0 : ext_opt_params ? stream_putw(s, 0)
1893 4 : : stream_putc(s, 0); /* Capability Length */
1894 4 : stream_putc(s, CAPABILITY_CODE_FQDN);
1895 4 : capp = stream_get_endp(s);
1896 4 : stream_putc(s, 0); /* dummy len for now */
1897 4 : len = strlen(cmd_hostname_get());
1898 4 : if (len > BGP_MAX_HOSTNAME)
1899 : len = BGP_MAX_HOSTNAME;
1900 :
1901 4 : stream_putc(s, len);
1902 4 : stream_put(s, cmd_hostname_get(), len);
1903 4 : if (cmd_domainname_get()) {
1904 0 : len = strlen(cmd_domainname_get());
1905 0 : if (len > BGP_MAX_HOSTNAME)
1906 : len = BGP_MAX_HOSTNAME;
1907 :
1908 0 : stream_putc(s, len);
1909 0 : stream_put(s, cmd_domainname_get(), len);
1910 : } else
1911 4 : stream_putc(s, 0); /* 0 length */
1912 :
1913 : /* Set the lengths straight */
1914 4 : len = stream_get_endp(s) - rcapp - 1;
1915 0 : ext_opt_params ? stream_putw_at(s, rcapp, len - 1)
1916 4 : : stream_putc_at(s, rcapp, len);
1917 :
1918 4 : len = stream_get_endp(s) - capp - 1;
1919 4 : stream_putc_at(s, capp, len);
1920 :
1921 4 : if (bgp_debug_neighbor_events(peer))
1922 0 : zlog_debug(
1923 : "%s Sending hostname cap with hn = %s, dn = %s",
1924 : peer->host, cmd_hostname_get(),
1925 : cmd_domainname_get());
1926 : }
1927 :
1928 4 : bgp_peer_send_gr_capability(s, peer, ext_opt_params);
1929 4 : bgp_peer_send_llgr_capability(s, peer, ext_opt_params);
1930 :
1931 : /* Total Opt Parm Len. */
1932 4 : len = stream_get_endp(s) - cp - 1;
1933 :
1934 4 : if (ext_opt_params) {
1935 0 : len = stream_get_endp(s) - eopl - 2;
1936 0 : stream_putw_at(s, eopl, len);
1937 : } else {
1938 4 : stream_putc_at(s, cp, len);
1939 : }
1940 :
1941 : return len;
1942 : }
|