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