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