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