]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[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"
11#include "thread.h"
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{
607 struct stream *s = BGP_INPUT(peer);
608 size_t end = stream_get_getp(s) + caphdr->length;
609
610 SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV);
611
612 while (stream_get_getp(s) + 4 <= end) {
613 afi_t afi;
614 safi_t safi;
615 iana_afi_t pkt_afi = stream_getw(s);
616 iana_safi_t pkt_safi = stream_getc(s);
617 uint8_t flags = stream_getc(s);
618 uint32_t stale_time = stream_get3(s);
619
620 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
621 if (bgp_debug_neighbor_events(peer))
622 zlog_debug(
623 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Long-lived Graceful Restart capability for this AFI/SAFI",
624 peer->host, iana_afi2str(pkt_afi),
625 iana_safi2str(pkt_safi));
626 } else if (!peer->afc[afi][safi]
627 || !CHECK_FLAG(peer->af_cap[afi][safi],
628 PEER_CAP_RESTART_AF_RCV)) {
629 if (bgp_debug_neighbor_events(peer))
630 zlog_debug(
631 "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Long-lived Graceful Restart capability",
632 peer->host, iana_afi2str(pkt_afi),
633 iana_safi2str(pkt_safi));
634 } else {
1479ed2f
DA
635 if (bgp_debug_neighbor_events(peer))
636 zlog_debug(
637 "%s Addr-family %s/%s(afi/safi) Long-lived Graceful Restart capability stale time %u sec",
638 peer->host, iana_afi2str(pkt_afi),
639 iana_safi2str(pkt_safi), stale_time);
640
8606be87 641 peer->llgr[afi][safi].flags = flags;
1479ed2f
DA
642 peer->llgr[afi][safi].stale_time =
643 MIN(stale_time, peer->bgp->llgr_stale_time);
8606be87
DA
644 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_LLGR_AF_RCV);
645 }
646 }
647
648 return 0;
649}
650
14051b36 651/* Unlike other capability parsing routines, this one returns 0 on error */
d62a17ae 652static as_t bgp_capability_as4(struct peer *peer, struct capability_header *hdr)
0b2aa3a0 653{
d62a17ae 654 SET_FLAG(peer->cap, PEER_CAP_AS4_RCV);
655
656 if (hdr->length != CAPABILITY_CODE_AS4_LEN) {
e50f7cfd 657 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
658 "%s AS4 capability has incorrect data length %d",
659 peer->host, hdr->length);
d62a17ae 660 return 0;
661 }
662
663 as_t as4 = stream_getl(BGP_INPUT(peer));
664
665 if (BGP_DEBUG(as4, AS4))
666 zlog_debug(
667 "%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
668 peer->host, as4);
669 return as4;
0b2aa3a0
PJ
670}
671
ef56aee4
DA
672static int bgp_capability_ext_message(struct peer *peer,
673 struct capability_header *hdr)
674{
675 if (hdr->length != CAPABILITY_CODE_EXT_MESSAGE_LEN) {
676 flog_err(
677 EC_BGP_PKT_OPEN,
678 "%s: BGP Extended Message capability has incorrect data length %d",
679 peer->host, hdr->length);
680 return -1;
681 }
682
683 SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV);
684
685 return 0;
686}
687
d62a17ae 688static int bgp_capability_addpath(struct peer *peer,
689 struct capability_header *hdr)
a82478b9 690{
d62a17ae 691 struct stream *s = BGP_INPUT(peer);
692 size_t end = stream_get_getp(s) + hdr->length;
693
694 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV);
695
696 /* Verify length is a multiple of 4 */
697 if (hdr->length % 4) {
065eaa36 698 flog_warn(
e50f7cfd 699 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 700 "Add Path: Received invalid length %d, non-multiple of 4",
701 hdr->length);
702 return -1;
703 }
704
705 while (stream_get_getp(s) + 4 <= end) {
706 afi_t afi;
707 safi_t safi;
708 iana_afi_t pkt_afi = stream_getw(s);
5c525538 709 iana_safi_t pkt_safi = stream_getc(s);
d7c0a89a 710 uint8_t send_receive = stream_getc(s);
d62a17ae 711
712 if (bgp_debug_neighbor_events(peer))
713 zlog_debug(
70aa70f9
DA
714 "%s OPEN has %s capability for afi/safi: %s/%s%s%s",
715 peer->host,
716 lookup_msg(capcode_str, hdr->code, NULL),
717 iana_afi2str(pkt_afi), iana_safi2str(pkt_safi),
d62a17ae 718 (send_receive & BGP_ADDPATH_RX) ? ", receive"
719 : "",
720 (send_receive & BGP_ADDPATH_TX) ? ", transmit"
721 : "");
722
723 /* Convert AFI, SAFI to internal values, check. */
724 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
725 if (bgp_debug_neighbor_events(peer))
726 zlog_debug(
3efd0893 727 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI",
748a041f
DS
728 peer->host, iana_afi2str(pkt_afi),
729 iana_safi2str(pkt_safi));
d62a17ae 730 continue;
731 } else if (!peer->afc[afi][safi]) {
732 if (bgp_debug_neighbor_events(peer))
733 zlog_debug(
3efd0893 734 "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI",
748a041f
DS
735 peer->host, iana_afi2str(pkt_afi),
736 iana_safi2str(pkt_safi));
d62a17ae 737 continue;
738 }
739
740 if (send_receive & BGP_ADDPATH_RX)
741 SET_FLAG(peer->af_cap[afi][safi],
742 PEER_CAP_ADDPATH_AF_RX_RCV);
743
744 if (send_receive & BGP_ADDPATH_TX)
745 SET_FLAG(peer->af_cap[afi][safi],
746 PEER_CAP_ADDPATH_AF_TX_RCV);
747 }
748
749 return 0;
a82478b9
DS
750}
751
d62a17ae 752static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
8a92a8a0 753{
d62a17ae 754 struct stream *s = BGP_INPUT(peer);
755 size_t end = stream_get_getp(s) + hdr->length;
756
757 /* Verify length is a multiple of 4 */
758 if (hdr->length % 6) {
065eaa36 759 flog_warn(
e50f7cfd 760 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 761 "Extended NH: Received invalid length %d, non-multiple of 6",
762 hdr->length);
763 return -1;
764 }
765
766 while (stream_get_getp(s) + 6 <= end) {
767 iana_afi_t pkt_afi = stream_getw(s);
768 afi_t afi;
5c525538
RW
769 iana_safi_t pkt_safi = stream_getw(s);
770 safi_t safi;
d62a17ae 771 iana_afi_t pkt_nh_afi = stream_getw(s);
772 afi_t nh_afi;
773
774 if (bgp_debug_neighbor_events(peer))
775 zlog_debug(
748a041f
DS
776 "%s Received with afi/safi/next-hop afi: %s/%s/%u",
777 peer->host, iana_afi2str(pkt_afi),
778 iana_safi2str(pkt_safi), pkt_nh_afi);
d62a17ae 779
780 /* Convert AFI, SAFI to internal values, check. */
781 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
782 if (bgp_debug_neighbor_events(peer))
783 zlog_debug(
3efd0893 784 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the ENHE Attribute for this AFI/SAFI",
748a041f
DS
785 peer->host, iana_afi2str(pkt_afi),
786 iana_safi2str(pkt_safi));
d62a17ae 787 continue;
788 }
789
790 /* RFC 5549 specifies use of this capability only for IPv4 AFI,
791 * with
792 * the Nexthop AFI being IPv6. A future spec may introduce other
793 * possibilities, so we ignore other values with a log. Also,
794 * only
795 * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported
796 * (and expected).
797 */
798 nh_afi = afi_iana2int(pkt_nh_afi);
799
800 if (afi != AFI_IP || nh_afi != AFI_IP6
770df5fd 801 || !(safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
d62a17ae 802 || safi == SAFI_LABELED_UNICAST)) {
065eaa36 803 flog_warn(
e50f7cfd 804 EC_BGP_CAPABILITY_INVALID_DATA,
3efd0893 805 "%s Unexpected afi/safi/next-hop afi: %s/%s/%u in Extended Next-hop capability, ignoring",
748a041f
DS
806 peer->host, iana_afi2str(pkt_afi),
807 iana_safi2str(pkt_safi), pkt_nh_afi);
d62a17ae 808 continue;
809 }
810
811 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV);
812
813 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_ADV))
814 SET_FLAG(peer->af_cap[afi][safi],
815 PEER_CAP_ENHE_AF_NEGO);
816 }
817
818 SET_FLAG(peer->cap, PEER_CAP_ENHE_RCV);
819
820 return 0;
8a92a8a0
DS
821}
822
d62a17ae 823static int bgp_capability_hostname(struct peer *peer,
824 struct capability_header *hdr)
04b6bdc0 825{
d62a17ae 826 struct stream *s = BGP_INPUT(peer);
827 char str[BGP_MAX_HOSTNAME + 1];
828 size_t end = stream_get_getp(s) + hdr->length;
d7c0a89a 829 uint8_t len;
d62a17ae 830
831 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
832
833 len = stream_getc(s);
834 if (stream_get_getp(s) + len > end) {
065eaa36 835 flog_warn(
e50f7cfd 836 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 837 "%s: Received malformed hostname capability from peer %s",
15569c58 838 __func__, peer->host);
d62a17ae 839 return -1;
840 }
841
842 if (len > BGP_MAX_HOSTNAME) {
843 stream_get(str, s, BGP_MAX_HOSTNAME);
844 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
845 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
846 } else if (len)
847 stream_get(str, s, len);
848
849 if (len) {
850 str[len] = '\0';
851
e1b36e13
QY
852 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
853 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
d62a17ae 854
855 peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
856 }
857
858 if (stream_get_getp(s) + 1 > end) {
065eaa36 859 flog_warn(
e50f7cfd 860 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 861 "%s: Received invalid domain name len (hostname capability) from peer %s",
15569c58 862 __func__, peer->host);
d62a17ae 863 return -1;
864 }
865
866 len = stream_getc(s);
867 if (stream_get_getp(s) + len > end) {
065eaa36 868 flog_warn(
e50f7cfd 869 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 870 "%s: Received runt domain name (hostname capability) from peer %s",
15569c58 871 __func__, peer->host);
d62a17ae 872 return -1;
873 }
874
875 if (len > BGP_MAX_HOSTNAME) {
876 stream_get(str, s, BGP_MAX_HOSTNAME);
877 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
878 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
879 } else if (len)
880 stream_get(str, s, len);
881
882 if (len) {
883 str[len] = '\0';
aba5353c 884
e1b36e13 885 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
aba5353c 886
d62a17ae 887 peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
888 }
889
890 if (bgp_debug_neighbor_events(peer)) {
891 zlog_debug("%s received hostname %s, domainname %s", peer->host,
892 peer->hostname, peer->domainname);
893 }
894
895 return 0;
04b6bdc0
DW
896}
897
d864dd9e
EB
898static int bgp_capability_role(struct peer *peer, struct capability_header *hdr)
899{
900 SET_FLAG(peer->cap, PEER_CAP_ROLE_RCV);
901 if (hdr->length != CAPABILITY_CODE_ROLE_LEN) {
902 flog_warn(EC_BGP_CAPABILITY_INVALID_LENGTH,
903 "Role: Received invalid length %d", hdr->length);
904 return -1;
905 }
906 uint8_t role = stream_getc(BGP_INPUT(peer));
907
8f2d6021 908 peer->remote_role = role;
d864dd9e
EB
909 return 0;
910}
911
234f6fd4
DA
912static int bgp_capability_software_version(struct peer *peer,
913 struct capability_header *hdr)
914{
915 struct stream *s = BGP_INPUT(peer);
916 char str[BGP_MAX_SOFT_VERSION + 1];
917 size_t end = stream_get_getp(s) + hdr->length;
918 uint8_t len;
919
920 SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_RCV);
921
922 len = stream_getc(s);
923 if (stream_get_getp(s) + len > end) {
924 flog_warn(
925 EC_BGP_CAPABILITY_INVALID_DATA,
926 "%s: Received malformed Software Version capability from peer %s",
927 __func__, peer->host);
928 return -1;
929 }
930
931 if (len) {
932 stream_get(str, s, len);
933 str[len] = '\0';
934
935 XFREE(MTYPE_BGP_SOFT_VERSION, peer->soft_version);
936
937 peer->soft_version = XSTRDUP(MTYPE_BGP_SOFT_VERSION, str);
938
939 if (bgp_debug_neighbor_events(peer))
940 zlog_debug("%s sent Software Version: %s", peer->host,
941 peer->soft_version);
942 }
943
944 return 0;
945}
946
3b381c32
AS
947/**
948 * Parse given capability.
6d58272b 949 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
950 *
951 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
952 * capabilities were encountered.
6d58272b 953 */
d62a17ae 954static int bgp_capability_parse(struct peer *peer, size_t length,
d7c0a89a 955 int *mp_capability, uint8_t **error)
6d58272b 956{
d62a17ae 957 int ret;
958 struct stream *s = BGP_INPUT(peer);
959 size_t end = stream_get_getp(s) + length;
34aa7448 960 uint16_t restart_flag_time = 0;
d62a17ae 961
962 assert(STREAM_READABLE(s) >= length);
963
964 while (stream_get_getp(s) < end) {
965 size_t start;
d7c0a89a 966 uint8_t *sp = stream_pnt(s);
d62a17ae 967 struct capability_header caphdr;
968
969 ret = 0;
970 /* We need at least capability code and capability length. */
971 if (stream_get_getp(s) + 2 > end) {
972 zlog_info("%s Capability length error (< header)",
973 peer->host);
974 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
975 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
976 return -1;
977 }
978
979 caphdr.code = stream_getc(s);
980 caphdr.length = stream_getc(s);
981 start = stream_get_getp(s);
982
983 /* Capability length check sanity check. */
984 if (start + caphdr.length > end) {
985 zlog_info("%s Capability length error (< length)",
986 peer->host);
987 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
988 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
989 return -1;
990 }
991
992 if (bgp_debug_neighbor_events(peer))
993 zlog_debug("%s OPEN has %s capability (%u), length %u",
994 peer->host,
995 lookup_msg(capcode_str, caphdr.code, NULL),
996 caphdr.code, caphdr.length);
997
998 /* Length sanity check, type-specific, for known capabilities */
999 switch (caphdr.code) {
1000 case CAPABILITY_CODE_MP:
1001 case CAPABILITY_CODE_REFRESH:
1002 case CAPABILITY_CODE_REFRESH_OLD:
1003 case CAPABILITY_CODE_ORF:
1004 case CAPABILITY_CODE_ORF_OLD:
1005 case CAPABILITY_CODE_RESTART:
1006 case CAPABILITY_CODE_AS4:
1007 case CAPABILITY_CODE_ADDPATH:
1008 case CAPABILITY_CODE_DYNAMIC:
1009 case CAPABILITY_CODE_DYNAMIC_OLD:
1010 case CAPABILITY_CODE_ENHE:
1011 case CAPABILITY_CODE_FQDN:
9af52ccf 1012 case CAPABILITY_CODE_ENHANCED_RR:
ef56aee4 1013 case CAPABILITY_CODE_EXT_MESSAGE:
d864dd9e 1014 case CAPABILITY_CODE_ROLE:
234f6fd4 1015 case CAPABILITY_CODE_SOFT_VERSION:
d62a17ae 1016 /* Check length. */
1017 if (caphdr.length < cap_minsizes[caphdr.code]) {
1018 zlog_info(
3efd0893 1019 "%s %s Capability length error: got %u, expected at least %u",
d62a17ae 1020 peer->host,
1021 lookup_msg(capcode_str, caphdr.code,
1022 NULL),
1023 caphdr.length,
1024 (unsigned)cap_minsizes[caphdr.code]);
1025 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1026 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1027 return -1;
1028 }
1029 if (caphdr.length
1030 && caphdr.length % cap_modsizes[caphdr.code] != 0) {
1031 zlog_info(
3efd0893 1032 "%s %s Capability length error: got %u, expected a multiple of %u",
d62a17ae 1033 peer->host,
1034 lookup_msg(capcode_str, caphdr.code,
1035 NULL),
1036 caphdr.length,
1037 (unsigned)cap_modsizes[caphdr.code]);
1038 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1039 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1040 return -1;
1041 }
1042 /* we deliberately ignore unknown codes, see below */
1043 default:
1044 break;
1045 }
1046
1047 switch (caphdr.code) {
1048 case CAPABILITY_CODE_MP: {
1049 *mp_capability = 1;
1050
1051 /* Ignore capability when override-capability is set. */
1052 if (!CHECK_FLAG(peer->flags,
1053 PEER_FLAG_OVERRIDE_CAPABILITY)) {
1054 /* Set negotiated value. */
1055 ret = bgp_capability_mp(peer, &caphdr);
1056
1057 /* Unsupported Capability. */
1058 if (ret < 0) {
1059 /* Store return data. */
1060 memcpy(*error, sp, caphdr.length + 2);
1061 *error += caphdr.length + 2;
1062 }
1063 ret = 0; /* Don't return error for this */
1064 }
1065 } break;
9af52ccf 1066 case CAPABILITY_CODE_ENHANCED_RR:
d62a17ae 1067 case CAPABILITY_CODE_REFRESH:
1068 case CAPABILITY_CODE_REFRESH_OLD: {
1069 /* BGP refresh capability */
9af52ccf
DA
1070 if (caphdr.code == CAPABILITY_CODE_ENHANCED_RR)
1071 SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV);
1072 else if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
d62a17ae 1073 SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV);
1074 else
1075 SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV);
1076 } break;
1077 case CAPABILITY_CODE_ORF:
1078 case CAPABILITY_CODE_ORF_OLD:
1079 ret = bgp_capability_orf_entry(peer, &caphdr);
1080 break;
1081 case CAPABILITY_CODE_RESTART:
1082 ret = bgp_capability_restart(peer, &caphdr);
1083 break;
8606be87
DA
1084 case CAPABILITY_CODE_LLGR:
1085 ret = bgp_capability_llgr(peer, &caphdr);
1086 break;
d62a17ae 1087 case CAPABILITY_CODE_DYNAMIC:
1088 case CAPABILITY_CODE_DYNAMIC_OLD:
1089 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV);
1090 break;
1091 case CAPABILITY_CODE_AS4:
1092 /* Already handled as a special-case parsing of the
1093 * capabilities
1094 * at the beginning of OPEN processing. So we care not a
1095 * jot
1096 * for the value really, only error case.
1097 */
1098 if (!bgp_capability_as4(peer, &caphdr))
1099 ret = -1;
1100 break;
1101 case CAPABILITY_CODE_ADDPATH:
1102 ret = bgp_capability_addpath(peer, &caphdr);
1103 break;
1104 case CAPABILITY_CODE_ENHE:
1105 ret = bgp_capability_enhe(peer, &caphdr);
1106 break;
ef56aee4
DA
1107 case CAPABILITY_CODE_EXT_MESSAGE:
1108 ret = bgp_capability_ext_message(peer, &caphdr);
1109 break;
d62a17ae 1110 case CAPABILITY_CODE_FQDN:
1111 ret = bgp_capability_hostname(peer, &caphdr);
1112 break;
d864dd9e
EB
1113 case CAPABILITY_CODE_ROLE:
1114 ret = bgp_capability_role(peer, &caphdr);
1115 break;
234f6fd4
DA
1116 case CAPABILITY_CODE_SOFT_VERSION:
1117 ret = bgp_capability_software_version(peer, &caphdr);
1118 break;
d62a17ae 1119 default:
1120 if (caphdr.code > 128) {
1121 /* We don't send Notification for unknown vendor
1122 specific
1123 capabilities. It seems reasonable for now...
1124 */
e50f7cfd 1125 flog_warn(EC_BGP_CAPABILITY_VENDOR,
065eaa36 1126 "%s Vendor specific capability %d",
d62a17ae 1127 peer->host, caphdr.code);
1128 } else {
065eaa36 1129 flog_warn(
e50f7cfd 1130 EC_BGP_CAPABILITY_UNKNOWN,
d62a17ae 1131 "%s unrecognized capability code: %d - ignored",
1132 peer->host, caphdr.code);
1133 memcpy(*error, sp, caphdr.length + 2);
1134 *error += caphdr.length + 2;
1135 }
1136 }
1137
1138 if (ret < 0) {
1139 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1140 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1141 return -1;
1142 }
1143 if (stream_get_getp(s) != (start + caphdr.length)) {
1144 if (stream_get_getp(s) > (start + caphdr.length))
065eaa36 1145 flog_warn(
e50f7cfd 1146 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 1147 "%s Cap-parser for %s read past cap-length, %u!",
1148 peer->host,
1149 lookup_msg(capcode_str, caphdr.code,
1150 NULL),
1151 caphdr.length);
1152 stream_set_getp(s, start + caphdr.length);
1153 }
34aa7448 1154
1155 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
1156 UNSET_FLAG(restart_flag_time, 0xF000);
1157 peer->v_gr_restart = restart_flag_time;
1158 }
718e3744 1159 }
d62a17ae 1160 return 0;
718e3744 1161}
1162
3dc339cd 1163static bool strict_capability_same(struct peer *peer)
718e3744 1164{
d62a17ae 1165 int i, j;
718e3744 1166
d62a17ae 1167 for (i = AFI_IP; i < AFI_MAX; i++)
1168 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
1169 if (peer->afc[i][j] != peer->afc_nego[i][j])
3dc339cd
DA
1170 return false;
1171 return true;
718e3744 1172}
1173
d864dd9e
EB
1174
1175static bool bgp_role_violation(struct peer *peer)
1176{
1177 uint8_t local_role = peer->local_role;
8f2d6021
EB
1178 uint8_t remote_role = peer->remote_role;
1179
1180 if (local_role != ROLE_UNDEFINED && remote_role != ROLE_UNDEFINED &&
1181 !((local_role == ROLE_PEER && remote_role == ROLE_PEER) ||
1182 (local_role == ROLE_PROVIDER && remote_role == ROLE_CUSTOMER) ||
1183 (local_role == ROLE_CUSTOMER && remote_role == ROLE_PROVIDER) ||
1184 (local_role == ROLE_RS_SERVER && remote_role == ROLE_RS_CLIENT) ||
1185 (local_role == ROLE_RS_CLIENT &&
1186 remote_role == ROLE_RS_SERVER))) {
d864dd9e
EB
1187 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1188 BGP_NOTIFY_OPEN_ROLE_MISMATCH);
1189 return true;
1190 }
8f2d6021 1191 if (remote_role == ROLE_UNDEFINED &&
7dddd1f7 1192 CHECK_FLAG(peer->flags, PEER_FLAG_ROLE_STRICT_MODE)) {
d864dd9e
EB
1193 const char *err_msg =
1194 "Strict mode. Please set the role on your side.";
1195 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1196 BGP_NOTIFY_OPEN_ROLE_MISMATCH,
1197 (uint8_t *)err_msg, strlen(err_msg));
1198 return true;
1199 }
1200 return false;
1201}
1202
1203
0b2aa3a0
PJ
1204/* peek into option, stores ASN to *as4 if the AS4 capability was found.
1205 * Returns 0 if no as4 found, as4cap value otherwise.
1206 */
d08c0c80 1207as_t peek_for_as4_capability(struct peer *peer, uint16_t length)
0b2aa3a0 1208{
d62a17ae 1209 struct stream *s = BGP_INPUT(peer);
1210 size_t orig_getp = stream_get_getp(s);
1211 size_t end = orig_getp + length;
1212 as_t as4 = 0;
1213
1214 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1215 zlog_debug(
3efd0893 1216 "%s [AS4] rcv OPEN w/ OPTION parameter len: %u, peeking for as4",
d62a17ae 1217 peer->host, length);
1218 /* the error cases we DONT handle, we ONLY try to read as4 out of
1219 * correctly formatted options.
1220 */
1221 while (stream_get_getp(s) < end) {
d7c0a89a 1222 uint8_t opt_type;
d08c0c80 1223 uint16_t opt_length;
d62a17ae 1224
3e46b43e
DS
1225 /* Ensure we can read the option type */
1226 if (stream_get_getp(s) + 1 > end)
d62a17ae 1227 goto end;
1228
3e46b43e 1229 /* Fetch the option type */
d62a17ae 1230 opt_type = stream_getc(s);
3e46b43e
DS
1231
1232 /*
1233 * Check the length and fetch the opt_length
1234 * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
1235 * then we do a getw which is 2 bytes. So we need to
1236 * ensure that we can read that as well
1237 */
1238 if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
1239 if (stream_get_getp(s) + 2 > end)
1240 goto end;
1241
1242 opt_length = stream_getw(s);
1243 } else {
1244 if (stream_get_getp(s) + 1 > end)
1245 goto end;
1246
1247 opt_length = stream_getc(s);
1248 }
d62a17ae 1249
1250 /* Option length check. */
1251 if (stream_get_getp(s) + opt_length > end)
1252 goto end;
1253
1254 if (opt_type == BGP_OPEN_OPT_CAP) {
1255 unsigned long capd_start = stream_get_getp(s);
1256 unsigned long capd_end = capd_start + opt_length;
1257
1258 assert(capd_end <= end);
1259
1260 while (stream_get_getp(s) < capd_end) {
1261 struct capability_header hdr;
1262
1263 if (stream_get_getp(s) + 2 > capd_end)
1264 goto end;
1265
1266 hdr.code = stream_getc(s);
1267 hdr.length = stream_getc(s);
1268
1269 if ((stream_get_getp(s) + hdr.length)
1270 > capd_end)
1271 goto end;
1272
1273 if (hdr.code == CAPABILITY_CODE_AS4) {
1274 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1275 zlog_debug(
d62a17ae 1276 "[AS4] found AS4 capability, about to parse");
1277 as4 = bgp_capability_as4(peer, &hdr);
1278
1279 goto end;
1280 }
1281 stream_forward_getp(s, hdr.length);
1282 }
1283 }
0b2aa3a0 1284 }
0b2aa3a0
PJ
1285
1286end:
d62a17ae 1287 stream_set_getp(s, orig_getp);
1288 return as4;
0b2aa3a0
PJ
1289}
1290
3b381c32
AS
1291/**
1292 * Parse open option.
1293 *
1294 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1295 */
d08c0c80
DA
1296int bgp_open_option_parse(struct peer *peer, uint16_t length,
1297 int *mp_capability)
718e3744 1298{
d62a17ae 1299 int ret = 0;
d7c0a89a 1300 uint8_t *error;
556beacf 1301 uint8_t error_data[BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE];
d62a17ae 1302 struct stream *s = BGP_INPUT(peer);
1303 size_t end = stream_get_getp(s) + length;
1304
1305 error = error_data;
1306
1307 if (bgp_debug_neighbor_events(peer))
1308 zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1309 peer->host, length);
1310
77b34214
NT
1311 /* Unset any previously received GR capability. */
1312 UNSET_FLAG(peer->cap, PEER_CAP_RESTART_RCV);
1313
d62a17ae 1314 while (stream_get_getp(s) < end) {
d7c0a89a 1315 uint8_t opt_type;
d08c0c80 1316 uint16_t opt_length;
d62a17ae 1317
1117baca
DS
1318 /*
1319 * Check that we can read the opt_type and fetch it
1320 */
1321 if (STREAM_READABLE(s) < 1) {
d62a17ae 1322 zlog_info("%s Option length error", peer->host);
1323 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1324 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1325 return -1;
1326 }
d62a17ae 1327 opt_type = stream_getc(s);
1117baca
DS
1328
1329 /*
1330 * Check the length of the stream to ensure that
1331 * FRR can properly read the opt_length. Then read it
1332 */
1333 if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
1334 if (STREAM_READABLE(s) < 2) {
1335 zlog_info("%s Option length error", peer->host);
1336 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1337 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1338 return -1;
1339 }
1340
1341 opt_length = stream_getw(s);
1342 } else {
1343 if (STREAM_READABLE(s) < 1) {
1344 zlog_info("%s Option length error", peer->host);
1345 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1346 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1347 return -1;
1348 }
1349
1350 opt_length = stream_getc(s);
1351 }
d62a17ae 1352
1353 /* Option length check. */
1354 if (STREAM_READABLE(s) < opt_length) {
d08c0c80
DA
1355 zlog_info("%s Option length error (%d)", peer->host,
1356 opt_length);
d62a17ae 1357 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1358 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1359 return -1;
1360 }
1361
1362 if (bgp_debug_neighbor_events(peer))
1363 zlog_debug(
1364 "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1365 peer->host, opt_type,
db3f8f31
DA
1366 opt_type == BGP_OPEN_OPT_CAP ? "Capability"
1367 : "Unknown",
d62a17ae 1368 opt_length);
1369
1370 switch (opt_type) {
d62a17ae 1371 case BGP_OPEN_OPT_CAP:
1372 ret = bgp_capability_parse(peer, opt_length,
1373 mp_capability, &error);
1374 break;
1375 default:
1376 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1377 BGP_NOTIFY_OPEN_UNSUP_PARAM);
1378 ret = -1;
1379 break;
1380 }
1381
1382 /* Parse error. To accumulate all unsupported capability codes,
1383 bgp_capability_parse does not return -1 when encounter
1384 unsupported capability code. To detect that, please check
1385 error and erro_data pointer, like below. */
1386 if (ret < 0)
1387 return -1;
718e3744 1388 }
1389
d62a17ae 1390 /* All OPEN option is parsed. Check capability when strict compare
1391 flag is enabled.*/
1392 if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
1393 /* If Unsupported Capability exists. */
1394 if (error != error_data) {
1395 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1396 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1397 error_data,
1398 error - error_data);
1399 return -1;
1400 }
1401
1402 /* Check local capability does not negotiated with remote
1403 peer. */
1404 if (!strict_capability_same(peer)) {
1405 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1406 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1407 return -1;
1408 }
718e3744 1409 }
1410
ef56aee4
DA
1411 /* Extended Message Support */
1412 peer->max_packet_size =
8d976b0e
DA
1413 (CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
1414 && CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV))
556beacf
QY
1415 ? BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE
1416 : BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
ef56aee4 1417
d864dd9e
EB
1418 /* Check that roles are corresponding to each other */
1419 if (bgp_role_violation(peer))
1420 return -1;
1421
d62a17ae 1422 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1423 error. */
1424 if (*mp_capability
1425 && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1426 if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1427 && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1428 && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1429 && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1430 && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
7c40bf39 1431 && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
d62a17ae 1432 && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1433 && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1434 && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1435 && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1436 && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
7c40bf39 1437 && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
d62a17ae 1438 && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
e50f7cfd 1439 flog_err(EC_BGP_PKT_OPEN,
3efd0893 1440 "%s [Error] Configured AFI/SAFIs do not overlap with received MP capabilities",
1c50c1c0 1441 peer->host);
d62a17ae 1442
1443 if (error != error_data)
1444 bgp_notify_send_with_data(
1445 peer, BGP_NOTIFY_OPEN_ERR,
1446 BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1447 error - error_data);
1448 else
1449 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1450 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1451 return -1;
1452 }
718e3744 1453 }
d62a17ae 1454 return 0;
718e3744 1455}
1456
d62a17ae 1457static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
d08c0c80
DA
1458 afi_t afi, safi_t safi, uint8_t code,
1459 bool ext_opt_params)
718e3744 1460{
d08c0c80 1461 uint16_t cap_len;
d7c0a89a 1462 uint8_t orf_len;
d62a17ae 1463 unsigned long capp;
1464 unsigned long orfp;
1465 unsigned long numberp;
1466 int number_of_orfs = 0;
617975d1
DS
1467 iana_afi_t pkt_afi = IANA_AFI_IPV4;
1468 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
d62a17ae 1469
1470 /* Convert AFI, SAFI to values for packet. */
1471 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1472
1473 stream_putc(s, BGP_OPEN_OPT_CAP);
1474 capp = stream_get_endp(s); /* Set Capability Len Pointer */
d08c0c80
DA
1475 ext_opt_params ? stream_putw(s, 0)
1476 : stream_putc(s, 0); /* Capability Length */
d62a17ae 1477 stream_putc(s, code); /* Capability Code */
1478 orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1479 stream_putc(s, 0); /* ORF Length */
1480 stream_putw(s, pkt_afi);
1481 stream_putc(s, 0);
1482 stream_putc(s, pkt_safi);
1483 numberp = stream_get_endp(s); /* Set Number Pointer */
1484 stream_putc(s, 0); /* Number of ORFs */
1485
1486 /* Address Prefix ORF */
1487 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1488 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1489 stream_putc(s, (code == CAPABILITY_CODE_ORF
1490 ? ORF_TYPE_PREFIX
1491 : ORF_TYPE_PREFIX_OLD));
1492
1493 if (CHECK_FLAG(peer->af_flags[afi][safi],
1494 PEER_FLAG_ORF_PREFIX_SM)
1495 && CHECK_FLAG(peer->af_flags[afi][safi],
1496 PEER_FLAG_ORF_PREFIX_RM)) {
1497 SET_FLAG(peer->af_cap[afi][safi],
1498 PEER_CAP_ORF_PREFIX_SM_ADV);
1499 SET_FLAG(peer->af_cap[afi][safi],
1500 PEER_CAP_ORF_PREFIX_RM_ADV);
1501 stream_putc(s, ORF_MODE_BOTH);
1502 } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1503 PEER_FLAG_ORF_PREFIX_SM)) {
1504 SET_FLAG(peer->af_cap[afi][safi],
1505 PEER_CAP_ORF_PREFIX_SM_ADV);
1506 stream_putc(s, ORF_MODE_SEND);
1507 } else {
1508 SET_FLAG(peer->af_cap[afi][safi],
1509 PEER_CAP_ORF_PREFIX_RM_ADV);
1510 stream_putc(s, ORF_MODE_RECEIVE);
1511 }
1512 number_of_orfs++;
718e3744 1513 }
718e3744 1514
d62a17ae 1515 /* Total Number of ORFs. */
1516 stream_putc_at(s, numberp, number_of_orfs);
718e3744 1517
d62a17ae 1518 /* Total ORF Len. */
1519 orf_len = stream_get_endp(s) - orfp - 1;
1520 stream_putc_at(s, orfp, orf_len);
718e3744 1521
d62a17ae 1522 /* Total Capability Len. */
1523 cap_len = stream_get_endp(s) - capp - 1;
d08c0c80
DA
1524 ext_opt_params ? stream_putw_at(s, capp, cap_len)
1525 : stream_putc_at(s, capp, cap_len);
718e3744 1526}
1527
034e185d 1528static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
d08c0c80 1529 bool ext_opt_params)
034e185d 1530{
1531 int len;
617975d1 1532 iana_afi_t pkt_afi = IANA_AFI_IPV4;
034e185d 1533 afi_t afi;
1534 safi_t safi;
617975d1 1535 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
034e185d 1536 uint32_t restart_time;
1537 unsigned long capp = 0;
1538 unsigned long rcapp = 0;
1539
13909c4f
DS
1540 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
1541 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
1542 return;
1543
1544 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1545 zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
1546 peer->host);
1547
1548 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1549 stream_putc(s, BGP_OPEN_OPT_CAP);
1550 capp = stream_get_endp(s); /* Set Capability Len Pointer */
d08c0c80
DA
1551 ext_opt_params ? stream_putw(s, 0)
1552 : stream_putc(s, 0); /* Capability Length */
13909c4f
DS
1553 stream_putc(s, CAPABILITY_CODE_RESTART);
1554 /* Set Restart Capability Len Pointer */
1555 rcapp = stream_get_endp(s);
1556 stream_putc(s, 0);
1557 restart_time = peer->bgp->restart_time;
1558 if (peer->bgp->t_startup) {
d83facbb 1559 SET_FLAG(restart_time, GRACEFUL_RESTART_R_BIT);
54394daa 1560 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV);
f2ca5c5b
DA
1561 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1562 zlog_debug("[BGP_GR] Sending R-Bit for peer: %s",
1563 peer->host);
1564 }
034e185d 1565
f2ca5c5b
DA
1566 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) {
1567 SET_FLAG(restart_time, GRACEFUL_RESTART_N_BIT);
1568 SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV);
034e185d 1569 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
f2ca5c5b 1570 zlog_debug("[BGP_GR] Sending N-Bit for peer: %s",
13909c4f
DS
1571 peer->host);
1572 }
1573
1574 stream_putw(s, restart_time);
1575
1576 /* Send address-family specific graceful-restart capability
1577 * only when GR config is present
1578 */
1579 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
892fedb6 1580 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
13909c4f
DS
1581 && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1582 zlog_debug("[BGP_GR] F bit Set");
1583
1584 FOREACH_AFI_SAFI (afi, safi) {
1585 if (!peer->afc[afi][safi])
1586 continue;
0f0444fb 1587
1588 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1589 zlog_debug(
13909c4f
DS
1590 "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
1591 afi, safi);
034e185d 1592
13909c4f
DS
1593 /* Convert AFI, SAFI to values for
1594 * packet.
1595 */
1596 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1597 &pkt_safi);
1598 stream_putw(s, pkt_afi);
1599 stream_putc(s, pkt_safi);
892fedb6
DA
1600 if (CHECK_FLAG(peer->bgp->flags,
1601 BGP_FLAG_GR_PRESERVE_FWD))
d83facbb 1602 stream_putc(s, GRACEFUL_RESTART_F_BIT);
13909c4f
DS
1603 else
1604 stream_putc(s, 0);
034e185d 1605 }
034e185d 1606 }
13909c4f
DS
1607
1608 /* Total Graceful restart capability Len. */
1609 len = stream_get_endp(s) - rcapp - 1;
1610 stream_putc_at(s, rcapp, len);
1611
1612 /* Total Capability Len. */
1613 len = stream_get_endp(s) - capp - 1;
d08c0c80
DA
1614 ext_opt_params ? stream_putw_at(s, capp, len - 1)
1615 : stream_putc_at(s, capp, len);
034e185d 1616}
1617
8606be87 1618static void bgp_peer_send_llgr_capability(struct stream *s, struct peer *peer,
d08c0c80 1619 bool ext_opt_params)
8606be87
DA
1620{
1621 int len;
617975d1 1622 iana_afi_t pkt_afi = IANA_AFI_IPV4;
8606be87
DA
1623 afi_t afi;
1624 safi_t safi;
617975d1 1625 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
8606be87
DA
1626 unsigned long capp = 0;
1627 unsigned long rcapp = 0;
1628
1629 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV))
1630 return;
1631
1632 SET_FLAG(peer->cap, PEER_CAP_LLGR_ADV);
1633
1634 stream_putc(s, BGP_OPEN_OPT_CAP);
1635 capp = stream_get_endp(s); /* Set Capability Len Pointer */
d08c0c80
DA
1636 ext_opt_params ? stream_putw(s, 0)
1637 : stream_putc(s, 0); /* Capability Length */
8606be87
DA
1638 stream_putc(s, CAPABILITY_CODE_LLGR);
1639
1640 rcapp = stream_get_endp(s);
1641 stream_putc(s, 0);
1642
1643 FOREACH_AFI_SAFI (afi, safi) {
1644 if (!peer->afc[afi][safi])
1645 continue;
1646
1647 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1648
1649 stream_putw(s, pkt_afi);
1650 stream_putc(s, pkt_safi);
1651 stream_putc(s, LLGR_F_BIT);
1652 stream_put3(s, peer->bgp->llgr_stale_time);
1653
1654 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_LLGR_AF_ADV);
1655 }
1656
1657 /* Total Long-lived Graceful Restart capability Len. */
1658 len = stream_get_endp(s) - rcapp - 1;
1659 stream_putc_at(s, rcapp, len);
1660
1661 /* Total Capability Len. */
1662 len = stream_get_endp(s) - capp - 1;
d08c0c80
DA
1663 ext_opt_params ? stream_putw_at(s, capp, len - 1)
1664 : stream_putc_at(s, capp, len);
8606be87
DA
1665}
1666
718e3744 1667/* Fill in capability open option to the packet. */
d08c0c80
DA
1668uint16_t bgp_open_capability(struct stream *s, struct peer *peer,
1669 bool ext_opt_params)
718e3744 1670{
d08c0c80
DA
1671 uint16_t len;
1672 unsigned long cp, capp, rcapp, eopl = 0;
617975d1 1673 iana_afi_t pkt_afi = IANA_AFI_IPV4;
d62a17ae 1674 afi_t afi;
5c525538 1675 safi_t safi;
617975d1 1676 iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
d62a17ae 1677 as_t local_as;
d7c0a89a 1678 uint8_t afi_safi_count = 0;
8ccee4b8 1679 bool adv_addpath_tx = false;
d62a17ae 1680
d08c0c80 1681 /* Non-Ext OP Len. */
d62a17ae 1682 cp = stream_get_endp(s);
d62a17ae 1683 stream_putc(s, 0);
1684
d08c0c80
DA
1685 if (ext_opt_params) {
1686 /* Non-Ext OP Len. */
1687 stream_putc_at(s, cp, BGP_OPEN_NON_EXT_OPT_LEN);
1688
1689 /* Non-Ext OP Type */
1690 stream_putc(s, BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH);
1691
1692 /* Extended Opt. Parm. Length */
1693 eopl = stream_get_endp(s);
1694 stream_putw(s, 0);
1695 }
1696
d62a17ae 1697 /* Do not send capability. */
1698 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1699 || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
d08c0c80 1700 return 0;
d62a17ae 1701
1702 /* MP capability for configured AFI, SAFI */
05c7a1cc
QY
1703 FOREACH_AFI_SAFI (afi, safi) {
1704 if (peer->afc[afi][safi]) {
1705 /* Convert AFI, SAFI to values for packet. */
1706 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1707 &pkt_safi);
1708
1709 peer->afc_adv[afi][safi] = 1;
1710 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1711 ext_opt_params
1712 ? stream_putw(s, CAPABILITY_CODE_MP_LEN + 2)
1713 : stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
05c7a1cc
QY
1714 stream_putc(s, CAPABILITY_CODE_MP);
1715 stream_putc(s, CAPABILITY_CODE_MP_LEN);
1716 stream_putw(s, pkt_afi);
1717 stream_putc(s, 0);
1718 stream_putc(s, pkt_safi);
1719
1720 /* Extended nexthop capability - currently
1721 * supporting RFC-5549 for
1722 * Link-Local peering only
1723 */
1724 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1725 && peer->su.sa.sa_family == AF_INET6
05c7a1cc 1726 && afi == AFI_IP
770df5fd 1727 && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
05c7a1cc
QY
1728 || safi == SAFI_LABELED_UNICAST)) {
1729 /* RFC 5549 Extended Next Hop Encoding
1730 */
1731 SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
d62a17ae 1732 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1733 ext_opt_params
1734 ? stream_putw(s,
1735 CAPABILITY_CODE_ENHE_LEN
1736 + 2)
1737 : stream_putc(s,
1738 CAPABILITY_CODE_ENHE_LEN
1739 + 2);
05c7a1cc
QY
1740 stream_putc(s, CAPABILITY_CODE_ENHE);
1741 stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1742
1743 SET_FLAG(peer->af_cap[AFI_IP][safi],
1744 PEER_CAP_ENHE_AF_ADV);
d62a17ae 1745 stream_putw(s, pkt_afi);
05c7a1cc
QY
1746 stream_putw(s, pkt_safi);
1747 stream_putw(s, afi_int2iana(AFI_IP6));
d62a17ae 1748
05c7a1cc
QY
1749 if (CHECK_FLAG(peer->af_cap[afi][safi],
1750 PEER_CAP_ENHE_AF_RCV))
1751 SET_FLAG(peer->af_cap[afi][safi],
1752 PEER_CAP_ENHE_AF_NEGO);
d62a17ae 1753 }
1754 }
05c7a1cc 1755 }
d62a17ae 1756
1757 /* Route refresh. */
1758 SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1759 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1760 ext_opt_params ? stream_putw(s, CAPABILITY_CODE_REFRESH_LEN + 2)
1761 : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
d62a17ae 1762 stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1763 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1764 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1765 ext_opt_params ? stream_putw(s, CAPABILITY_CODE_REFRESH_LEN + 2)
1766 : stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
d62a17ae 1767 stream_putc(s, CAPABILITY_CODE_REFRESH);
1768 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1769
9af52ccf
DA
1770 /* Enhanced Route Refresh. */
1771 SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_ADV);
1772 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1773 ext_opt_params ? stream_putw(s, CAPABILITY_CODE_ENHANCED_LEN + 2)
1774 : stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN + 2);
9af52ccf
DA
1775 stream_putc(s, CAPABILITY_CODE_ENHANCED_RR);
1776 stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN);
1777
d62a17ae 1778 /* AS4 */
1779 SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1780 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1781 ext_opt_params ? stream_putw(s, CAPABILITY_CODE_AS4_LEN + 2)
1782 : stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
d62a17ae 1783 stream_putc(s, CAPABILITY_CODE_AS4);
1784 stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1785 if (peer->change_local_as)
1786 local_as = peer->change_local_as;
1787 else
1788 local_as = peer->local_as;
1789 stream_putl(s, local_as);
1790
ef56aee4
DA
1791 /* Extended Message Support */
1792 SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV);
1793 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1794 ext_opt_params ? stream_putw(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2)
1795 : stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2);
ef56aee4
DA
1796 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE);
1797 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN);
1798
d864dd9e 1799 /* Role*/
8f2d6021 1800 if (peer->local_role != ROLE_UNDEFINED) {
d864dd9e
EB
1801 SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV);
1802 stream_putc(s, BGP_OPEN_OPT_CAP);
1803 stream_putc(s, CAPABILITY_CODE_ROLE_LEN + 2);
1804 stream_putc(s, CAPABILITY_CODE_ROLE);
1805 stream_putc(s, CAPABILITY_CODE_ROLE_LEN);
1806 stream_putc(s, peer->local_role);
1807 }
1808
d62a17ae 1809 /* AddPath */
05c7a1cc
QY
1810 FOREACH_AFI_SAFI (afi, safi) {
1811 if (peer->afc[afi][safi]) {
1812 afi_safi_count++;
1813
1814 /* Only advertise addpath TX if a feature that
1815 * will use it is
1816 * configured */
dcc68b5e 1817 if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
8ccee4b8
DA
1818 adv_addpath_tx = true;
1819
1820 /* If we have enabled labeled unicast, we MUST check
1821 * against unicast SAFI because addpath IDs are
1822 * allocated under unicast SAFI, the same as the RIB
1823 * is managed in unicast SAFI.
1824 */
1825 if (safi == SAFI_LABELED_UNICAST)
1826 if (peer->addpath_type[afi][SAFI_UNICAST] !=
1827 BGP_ADDPATH_NONE)
1828 adv_addpath_tx = true;
05c7a1cc
QY
1829 }
1830 }
d62a17ae 1831
1832 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1833 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1834 ext_opt_params
1835 ? stream_putw(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count)
1836 + 2)
1837 : stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count)
1838 + 2);
d62a17ae 1839 stream_putc(s, CAPABILITY_CODE_ADDPATH);
1840 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1841
05c7a1cc
QY
1842 FOREACH_AFI_SAFI (afi, safi) {
1843 if (peer->afc[afi][safi]) {
7c0e4312
DA
1844 bool adv_addpath_rx =
1845 !CHECK_FLAG(peer->af_flags[afi][safi],
1846 PEER_FLAG_DISABLE_ADDPATH_RX);
1847 uint8_t flags = 0;
1848
05c7a1cc
QY
1849 /* Convert AFI, SAFI to values for packet. */
1850 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1851 &pkt_safi);
d62a17ae 1852
05c7a1cc
QY
1853 stream_putw(s, pkt_afi);
1854 stream_putc(s, pkt_safi);
d62a17ae 1855
7c0e4312
DA
1856 if (adv_addpath_rx) {
1857 SET_FLAG(flags, BGP_ADDPATH_RX);
05c7a1cc
QY
1858 SET_FLAG(peer->af_cap[afi][safi],
1859 PEER_CAP_ADDPATH_AF_RX_ADV);
7c0e4312
DA
1860 } else {
1861 UNSET_FLAG(peer->af_cap[afi][safi],
1862 PEER_CAP_ADDPATH_AF_RX_ADV);
1863 }
1864
1865 if (adv_addpath_tx) {
1866 SET_FLAG(flags, BGP_ADDPATH_TX);
05c7a1cc
QY
1867 SET_FLAG(peer->af_cap[afi][safi],
1868 PEER_CAP_ADDPATH_AF_TX_ADV);
8ccee4b8
DA
1869 if (safi == SAFI_LABELED_UNICAST)
1870 SET_FLAG(
1871 peer->af_cap[afi][SAFI_UNICAST],
1872 PEER_CAP_ADDPATH_AF_TX_ADV);
05c7a1cc 1873 } else {
05c7a1cc
QY
1874 UNSET_FLAG(peer->af_cap[afi][safi],
1875 PEER_CAP_ADDPATH_AF_TX_ADV);
d62a17ae 1876 }
7c0e4312
DA
1877
1878 stream_putc(s, flags);
05c7a1cc
QY
1879 }
1880 }
d62a17ae 1881
1882 /* ORF capability. */
05c7a1cc
QY
1883 FOREACH_AFI_SAFI (afi, safi) {
1884 if (CHECK_FLAG(peer->af_flags[afi][safi],
1885 PEER_FLAG_ORF_PREFIX_SM)
1886 || CHECK_FLAG(peer->af_flags[afi][safi],
1887 PEER_FLAG_ORF_PREFIX_RM)) {
1888 bgp_open_capability_orf(s, peer, afi, safi,
d08c0c80
DA
1889 CAPABILITY_CODE_ORF_OLD,
1890 ext_opt_params);
05c7a1cc 1891 bgp_open_capability_orf(s, peer, afi, safi,
d08c0c80
DA
1892 CAPABILITY_CODE_ORF,
1893 ext_opt_params);
05c7a1cc
QY
1894 }
1895 }
d62a17ae 1896
1897 /* Dynamic capability. */
1898 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1899 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1900 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1901 ext_opt_params
1902 ? stream_putw(s, CAPABILITY_CODE_DYNAMIC_LEN + 2)
1903 : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
d62a17ae 1904 stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1905 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1906 stream_putc(s, BGP_OPEN_OPT_CAP);
d08c0c80
DA
1907 ext_opt_params
1908 ? stream_putw(s, CAPABILITY_CODE_DYNAMIC_LEN + 2)
1909 : stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
d62a17ae 1910 stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1911 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
718e3744 1912 }
1913
d62a17ae 1914 /* Hostname capability */
6b3ee3a0 1915 if (cmd_hostname_get()) {
d62a17ae 1916 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1917 stream_putc(s, BGP_OPEN_OPT_CAP);
1918 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
d08c0c80
DA
1919 ext_opt_params ? stream_putw(s, 0)
1920 : stream_putc(s, 0); /* Capability Length */
d62a17ae 1921 stream_putc(s, CAPABILITY_CODE_FQDN);
1922 capp = stream_get_endp(s);
1923 stream_putc(s, 0); /* dummy len for now */
6b3ee3a0 1924 len = strlen(cmd_hostname_get());
d62a17ae 1925 if (len > BGP_MAX_HOSTNAME)
1926 len = BGP_MAX_HOSTNAME;
1927
1928 stream_putc(s, len);
6b3ee3a0
MK
1929 stream_put(s, cmd_hostname_get(), len);
1930 if (cmd_domainname_get()) {
1931 len = strlen(cmd_domainname_get());
d62a17ae 1932 if (len > BGP_MAX_HOSTNAME)
1933 len = BGP_MAX_HOSTNAME;
1934
1935 stream_putc(s, len);
6b3ee3a0 1936 stream_put(s, cmd_domainname_get(), len);
d62a17ae 1937 } else
d62a17ae 1938 stream_putc(s, 0); /* 0 length */
04b6bdc0 1939
d62a17ae 1940 /* Set the lengths straight */
1941 len = stream_get_endp(s) - rcapp - 1;
d08c0c80
DA
1942 ext_opt_params ? stream_putw_at(s, rcapp, len - 1)
1943 : stream_putc_at(s, rcapp, len);
1944
d62a17ae 1945 len = stream_get_endp(s) - capp - 1;
1946 stream_putc_at(s, capp, len);
04b6bdc0 1947
d62a17ae 1948 if (bgp_debug_neighbor_events(peer))
d62a17ae 1949 zlog_debug(
1950 "%s Sending hostname cap with hn = %s, dn = %s",
6b3ee3a0
MK
1951 peer->host, cmd_hostname_get(),
1952 cmd_domainname_get());
d62a17ae 1953 }
1954
d08c0c80
DA
1955 bgp_peer_send_gr_capability(s, peer, ext_opt_params);
1956 bgp_peer_send_llgr_capability(s, peer, ext_opt_params);
d62a17ae 1957
234f6fd4
DA
1958 /* Software Version capability
1959 * An implementation is REQUIRED Extended Optional Parameters
1960 * Length for BGP OPEN Message support as defined in [RFC9072].
1961 * The inclusion of the Software Version Capability is OPTIONAL.
1962 * If an implementation supports the inclusion of the capability,
1963 * the implementation MUST include a configuration switch to enable
1964 * or disable its use, and that switch MUST be off by default.
1965 */
1966 if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_SOFT_VERSION) ||
1967 peer->sort == BGP_PEER_IBGP) {
1968 SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV);
1969 stream_putc(s, BGP_OPEN_OPT_CAP);
1970 rcapp = stream_get_endp(s);
1971 ext_opt_params ? stream_putw(s, 0)
1972 : stream_putc(s, 0); /* Capability Length */
1973 stream_putc(s, CAPABILITY_CODE_SOFT_VERSION);
1974 capp = stream_get_endp(s);
1975 stream_putc(s, 0); /* dummy placeholder len */
1976
1977 /* The Capability Length SHOULD be no greater than 64.
1978 * This is the limit to allow other capabilities as much
1979 * space as they require.
1980 */
1981 len = strlen(cmd_software_version_get());
1982 if (len > BGP_MAX_SOFT_VERSION)
1983 len = BGP_MAX_SOFT_VERSION;
1984
1985 stream_putc(s, len);
1986 stream_put(s, cmd_software_version_get(), len);
1987
1988 /* Software Version capability Len. */
1989 len = stream_get_endp(s) - rcapp - 1;
1990 ext_opt_params ? stream_putw_at(s, rcapp, len - 1)
1991 : stream_putc_at(s, rcapp, len);
1992
1993 /* Total Capability Len. */
1994 len = stream_get_endp(s) - capp - 1;
1995 stream_putc_at(s, capp, len);
1996
1997 if (bgp_debug_neighbor_events(peer))
1998 zlog_debug("%s Sending Software Version cap, value: %s",
1999 peer->host, cmd_software_version_get());
2000 }
2001
d62a17ae 2002 /* Total Opt Parm Len. */
2003 len = stream_get_endp(s) - cp - 1;
d08c0c80
DA
2004
2005 if (ext_opt_params) {
2006 len = stream_get_endp(s) - eopl - 2;
2007 stream_putw_at(s, eopl, len);
2008 } else {
2009 stream_putc_at(s, cp, len);
2010 }
2011
2012 return len;
718e3744 2013}