1 /* BGP open message handling
2 * Copyright (C) 1998, 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
34 #include "bgpd/bgpd.h"
35 #include "bgpd/bgp_attr.h"
36 #include "bgpd/bgp_debug.h"
37 #include "bgpd/bgp_errors.h"
38 #include "bgpd/bgp_fsm.h"
39 #include "bgpd/bgp_packet.h"
40 #include "bgpd/bgp_open.h"
41 #include "bgpd/bgp_aspath.h"
42 #include "bgpd/bgp_vty.h"
43 #include "bgpd/bgp_memory.h"
45 /* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
46 negotiate remote peer supports extentions or not. But if
47 remote-peer doesn't supports negotiation process itself. We would
48 like to do manual configuration.
50 So there is many configurable point. First of all we want set each
51 peer whether we send capability negotiation to the peer or not.
52 Next, if we send capability to the peer we want to set my capabilty
53 inforation at each peer. */
55 void bgp_capability_vty_out(struct vty
*vty
, struct peer
*peer
, bool use_json
,
56 json_object
*json_neigh
)
60 struct capability_mp_data mpc
;
61 struct capability_header
*hdr
;
62 json_object
*json_cap
= NULL
;
65 json_cap
= json_object_new_object();
67 pnt
= peer
->notify
.data
;
68 end
= pnt
+ peer
->notify
.length
;
71 if (pnt
+ sizeof(struct capability_mp_data
) + 2 > end
)
74 hdr
= (struct capability_header
*)pnt
;
75 if (pnt
+ hdr
->length
+ 2 > end
)
78 memcpy(&mpc
, pnt
+ 2, sizeof(struct capability_mp_data
));
80 if (hdr
->code
== CAPABILITY_CODE_MP
) {
84 (void)bgp_map_afi_safi_iana2int(ntohs(mpc
.afi
),
85 mpc
.safi
, &afi
, &safi
);
90 json_object_string_add(
92 "capabilityErrorMultiProtocolAfi",
96 json_object_string_add(
98 "capabilityErrorMultiProtocolAfi",
102 json_object_string_add(
104 "capabilityErrorMultiProtocolAfi",
110 "capabilityErrorMultiProtocolAfiUnknown",
116 json_object_string_add(
118 "capabilityErrorMultiProtocolSafi",
122 json_object_string_add(
124 "capabilityErrorMultiProtocolSafi",
127 case SAFI_LABELED_UNICAST
:
128 json_object_string_add(
130 "capabilityErrorMultiProtocolSafi",
134 json_object_string_add(
136 "capabilityErrorMultiProtocolSafi",
140 json_object_string_add(
142 "capabilityErrorMultiProtocolSafi",
146 json_object_string_add(
148 "capabilityErrorMultiProtocolSafi",
152 json_object_string_add(
154 "capabilityErrorMultiProtocolSafi",
160 "capabilityErrorMultiProtocolSafiUnknown",
166 " Capability error for: Multi protocol ");
169 vty_out(vty
, "AFI IPv4, ");
172 vty_out(vty
, "AFI IPv6, ");
175 vty_out(vty
, "AFI L2VPN, ");
178 vty_out(vty
, "AFI Unknown %d, ",
184 vty_out(vty
, "SAFI Unicast");
187 vty_out(vty
, "SAFI Multicast");
189 case SAFI_LABELED_UNICAST
:
190 vty_out(vty
, "SAFI Labeled-unicast");
193 vty_out(vty
, "SAFI MPLS-labeled VPN");
196 vty_out(vty
, "SAFI ENCAP");
199 vty_out(vty
, "SAFI FLOWSPEC");
202 vty_out(vty
, "SAFI EVPN");
205 vty_out(vty
, "SAFI Unknown %d ",
211 } else if (hdr
->code
>= 128) {
215 "capabilityErrorVendorSpecificCapabilityCode",
219 " Capability error: vendor specific capability code %d",
225 "capabilityErrorUnknownCapabilityCode",
229 " Capability error: unknown capability code %d",
232 pnt
+= hdr
->length
+ 2;
235 json_object_object_add(json_neigh
, "capabilityErrors",
239 static void bgp_capability_mp_data(struct stream
*s
,
240 struct capability_mp_data
*mpc
)
242 mpc
->afi
= stream_getw(s
);
243 mpc
->reserved
= stream_getc(s
);
244 mpc
->safi
= stream_getc(s
);
247 /* Set negotiated capability value. */
248 static int bgp_capability_mp(struct peer
*peer
, struct capability_header
*hdr
)
250 struct capability_mp_data mpc
;
251 struct stream
*s
= BGP_INPUT(peer
);
255 /* Verify length is 4 */
256 if (hdr
->length
!= 4) {
258 EC_BGP_CAPABILITY_INVALID_LENGTH
,
259 "MP Cap: Received invalid length %d, non-multiple of 4",
264 bgp_capability_mp_data(s
, &mpc
);
266 if (bgp_debug_neighbor_events(peer
))
267 zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
268 peer
->host
, mpc
.afi
, mpc
.safi
);
270 /* Convert AFI, SAFI to internal values, check. */
271 if (bgp_map_afi_safi_iana2int(mpc
.afi
, mpc
.safi
, &afi
, &safi
))
274 /* Now safi remapped, and afi/safi are valid array indices */
275 peer
->afc_recv
[afi
][safi
] = 1;
277 if (peer
->afc
[afi
][safi
])
278 peer
->afc_nego
[afi
][safi
] = 1;
285 static void bgp_capability_orf_not_support(struct peer
*peer
, iana_afi_t afi
,
286 iana_safi_t safi
, uint8_t type
,
289 if (bgp_debug_neighbor_events(peer
))
291 "%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
292 peer
->host
, afi
, safi
, type
, mode
);
295 static const struct message orf_type_str
[] = {
296 {ORF_TYPE_PREFIX
, "Prefixlist"},
297 {ORF_TYPE_PREFIX_OLD
, "Prefixlist (old)"},
300 static const struct message orf_mode_str
[] = {{ORF_MODE_RECEIVE
, "Receive"},
301 {ORF_MODE_SEND
, "Send"},
302 {ORF_MODE_BOTH
, "Both"},
305 static int bgp_capability_orf_entry(struct peer
*peer
,
306 struct capability_header
*hdr
)
308 struct stream
*s
= BGP_INPUT(peer
);
309 struct capability_mp_data mpc
;
313 iana_safi_t pkt_safi
;
317 uint16_t sm_cap
= 0; /* capability send-mode receive */
318 uint16_t rm_cap
= 0; /* capability receive-mode receive */
321 /* ORF Entry header */
322 bgp_capability_mp_data(s
, &mpc
);
323 num
= stream_getc(s
);
327 if (bgp_debug_neighbor_events(peer
))
328 zlog_debug("%s ORF Cap entry for afi/safi: %u/%u", peer
->host
,
331 /* Convert AFI, SAFI to internal values, check. */
332 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
, &safi
)) {
334 "%s Addr-family %d/%d not supported."
335 " Ignoring the ORF capability",
336 peer
->host
, pkt_afi
, pkt_safi
);
343 /* validate number field */
344 if (CAPABILITY_CODE_ORF_LEN
+ (num
* 2) > hdr
->length
) {
346 "%s ORF Capability entry length error,"
347 " Cap length %u, num %u",
348 peer
->host
, hdr
->length
, num
);
349 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
350 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
354 for (i
= 0; i
< num
; i
++) {
355 type
= stream_getc(s
);
356 mode
= stream_getc(s
);
358 /* ORF Mode error check */
362 case ORF_MODE_RECEIVE
:
365 bgp_capability_orf_not_support(peer
, pkt_afi
, pkt_safi
,
369 /* ORF Type and afi/safi error checks */
370 /* capcode versus type */
372 case CAPABILITY_CODE_ORF
:
374 case ORF_TYPE_PREFIX
:
377 bgp_capability_orf_not_support(
378 peer
, pkt_afi
, pkt_safi
, type
, mode
);
382 case CAPABILITY_CODE_ORF_OLD
:
384 case ORF_TYPE_PREFIX_OLD
:
387 bgp_capability_orf_not_support(
388 peer
, pkt_afi
, pkt_safi
, type
, mode
);
393 bgp_capability_orf_not_support(peer
, pkt_afi
, pkt_safi
,
399 if (!((afi
== AFI_IP
&& safi
== SAFI_UNICAST
)
400 || (afi
== AFI_IP
&& safi
== SAFI_MULTICAST
)
401 || (afi
== AFI_IP6
&& safi
== SAFI_UNICAST
))) {
402 bgp_capability_orf_not_support(peer
, pkt_afi
, pkt_safi
,
407 if (bgp_debug_neighbor_events(peer
))
409 "%s OPEN has %s ORF capability"
410 " as %s for afi/safi: %d/%d",
412 lookup_msg(orf_type_str
, type
, NULL
),
413 lookup_msg(orf_mode_str
, mode
, NULL
), pkt_afi
,
416 if (hdr
->code
== CAPABILITY_CODE_ORF
) {
417 sm_cap
= PEER_CAP_ORF_PREFIX_SM_RCV
;
418 rm_cap
= PEER_CAP_ORF_PREFIX_RM_RCV
;
419 } else if (hdr
->code
== CAPABILITY_CODE_ORF_OLD
) {
420 sm_cap
= PEER_CAP_ORF_PREFIX_SM_OLD_RCV
;
421 rm_cap
= PEER_CAP_ORF_PREFIX_RM_OLD_RCV
;
423 bgp_capability_orf_not_support(peer
, pkt_afi
, pkt_safi
,
430 SET_FLAG(peer
->af_cap
[afi
][safi
], sm_cap
);
431 SET_FLAG(peer
->af_cap
[afi
][safi
], rm_cap
);
434 SET_FLAG(peer
->af_cap
[afi
][safi
], sm_cap
);
436 case ORF_MODE_RECEIVE
:
437 SET_FLAG(peer
->af_cap
[afi
][safi
], rm_cap
);
444 static int bgp_capability_restart(struct peer
*peer
,
445 struct capability_header
*caphdr
)
447 struct stream
*s
= BGP_INPUT(peer
);
448 uint16_t restart_flag_time
;
449 size_t end
= stream_get_getp(s
) + caphdr
->length
;
451 /* Verify length is a multiple of 4 */
452 if ((caphdr
->length
- 2) % 4) {
454 EC_BGP_CAPABILITY_INVALID_LENGTH
,
455 "Restart Cap: Received invalid length %d, non-multiple of 4",
460 SET_FLAG(peer
->cap
, PEER_CAP_RESTART_RCV
);
461 restart_flag_time
= stream_getw(s
);
462 if (CHECK_FLAG(restart_flag_time
, RESTART_R_BIT
))
463 SET_FLAG(peer
->cap
, PEER_CAP_RESTART_BIT_RCV
);
465 UNSET_FLAG(restart_flag_time
, 0xF000);
466 peer
->v_gr_restart
= restart_flag_time
;
468 if (bgp_debug_neighbor_events(peer
)) {
469 zlog_debug("%s OPEN has Graceful Restart capability",
471 zlog_debug("%s Peer has%srestarted. Restart Time : %d",
473 CHECK_FLAG(peer
->cap
, PEER_CAP_RESTART_BIT_RCV
)
479 while (stream_get_getp(s
) + 4 <= end
) {
482 iana_afi_t pkt_afi
= stream_getw(s
);
483 iana_safi_t pkt_safi
= stream_getc(s
);
484 uint8_t flag
= stream_getc(s
);
486 /* Convert AFI, SAFI to internal values, check. */
487 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
, &safi
)) {
488 if (bgp_debug_neighbor_events(peer
))
490 "%s Addr-family %d/%d(afi/safi) not supported."
491 " Ignore the Graceful Restart capability for this AFI/SAFI",
492 peer
->host
, pkt_afi
, pkt_safi
);
493 } else if (!peer
->afc
[afi
][safi
]) {
494 if (bgp_debug_neighbor_events(peer
))
496 "%s Addr-family %d/%d(afi/safi) not enabled."
497 " Ignore the Graceful Restart capability",
498 peer
->host
, pkt_afi
, pkt_safi
);
500 if (bgp_debug_neighbor_events(peer
))
502 "%s Address family %s is%spreserved",
503 peer
->host
, afi_safi_print(afi
, safi
),
505 peer
->af_cap
[afi
][safi
],
506 PEER_CAP_RESTART_AF_PRESERVE_RCV
)
510 SET_FLAG(peer
->af_cap
[afi
][safi
],
511 PEER_CAP_RESTART_AF_RCV
);
512 if (CHECK_FLAG(flag
, RESTART_F_BIT
))
513 SET_FLAG(peer
->af_cap
[afi
][safi
],
514 PEER_CAP_RESTART_AF_PRESERVE_RCV
);
520 /* Unlike other capability parsing routines, this one returns 0 on error */
521 static as_t
bgp_capability_as4(struct peer
*peer
, struct capability_header
*hdr
)
523 SET_FLAG(peer
->cap
, PEER_CAP_AS4_RCV
);
525 if (hdr
->length
!= CAPABILITY_CODE_AS4_LEN
) {
526 flog_err(EC_BGP_PKT_OPEN
,
527 "%s AS4 capability has incorrect data length %d",
528 peer
->host
, hdr
->length
);
532 as_t as4
= stream_getl(BGP_INPUT(peer
));
534 if (BGP_DEBUG(as4
, AS4
))
536 "%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
541 static int bgp_capability_addpath(struct peer
*peer
,
542 struct capability_header
*hdr
)
544 struct stream
*s
= BGP_INPUT(peer
);
545 size_t end
= stream_get_getp(s
) + hdr
->length
;
547 SET_FLAG(peer
->cap
, PEER_CAP_ADDPATH_RCV
);
549 /* Verify length is a multiple of 4 */
550 if (hdr
->length
% 4) {
552 EC_BGP_CAPABILITY_INVALID_LENGTH
,
553 "Add Path: Received invalid length %d, non-multiple of 4",
558 while (stream_get_getp(s
) + 4 <= end
) {
561 iana_afi_t pkt_afi
= stream_getw(s
);
562 iana_safi_t pkt_safi
= stream_getc(s
);
563 uint8_t send_receive
= stream_getc(s
);
565 if (bgp_debug_neighbor_events(peer
))
567 "%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
568 peer
->host
, pkt_afi
, pkt_safi
,
569 (send_receive
& BGP_ADDPATH_RX
) ? ", receive"
571 (send_receive
& BGP_ADDPATH_TX
) ? ", transmit"
574 /* Convert AFI, SAFI to internal values, check. */
575 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
, &safi
)) {
576 if (bgp_debug_neighbor_events(peer
))
578 "%s Addr-family %d/%d(afi/safi) not supported."
579 " Ignore the Addpath Attribute for this AFI/SAFI",
580 peer
->host
, pkt_afi
, pkt_safi
);
582 } else if (!peer
->afc
[afi
][safi
]) {
583 if (bgp_debug_neighbor_events(peer
))
585 "%s Addr-family %d/%d(afi/safi) not enabled."
586 " Ignore the AddPath capability for this AFI/SAFI",
587 peer
->host
, pkt_afi
, pkt_safi
);
591 if (send_receive
& BGP_ADDPATH_RX
)
592 SET_FLAG(peer
->af_cap
[afi
][safi
],
593 PEER_CAP_ADDPATH_AF_RX_RCV
);
595 if (send_receive
& BGP_ADDPATH_TX
)
596 SET_FLAG(peer
->af_cap
[afi
][safi
],
597 PEER_CAP_ADDPATH_AF_TX_RCV
);
603 static int bgp_capability_enhe(struct peer
*peer
, struct capability_header
*hdr
)
605 struct stream
*s
= BGP_INPUT(peer
);
606 size_t end
= stream_get_getp(s
) + hdr
->length
;
608 /* Verify length is a multiple of 4 */
609 if (hdr
->length
% 6) {
611 EC_BGP_CAPABILITY_INVALID_LENGTH
,
612 "Extended NH: Received invalid length %d, non-multiple of 6",
617 while (stream_get_getp(s
) + 6 <= end
) {
618 iana_afi_t pkt_afi
= stream_getw(s
);
620 iana_safi_t pkt_safi
= stream_getw(s
);
622 iana_afi_t pkt_nh_afi
= stream_getw(s
);
625 if (bgp_debug_neighbor_events(peer
))
627 "%s Received with afi/safi/next-hop afi: %u/%u/%u",
628 peer
->host
, pkt_afi
, pkt_safi
, pkt_nh_afi
);
630 /* Convert AFI, SAFI to internal values, check. */
631 if (bgp_map_afi_safi_iana2int(pkt_afi
, pkt_safi
, &afi
, &safi
)) {
632 if (bgp_debug_neighbor_events(peer
))
634 "%s Addr-family %d/%d(afi/safi) not supported."
635 " Ignore the ENHE Attribute for this AFI/SAFI",
636 peer
->host
, pkt_afi
, pkt_safi
);
640 /* RFC 5549 specifies use of this capability only for IPv4 AFI,
642 * the Nexthop AFI being IPv6. A future spec may introduce other
643 * possibilities, so we ignore other values with a log. Also,
645 * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported
648 nh_afi
= afi_iana2int(pkt_nh_afi
);
650 if (afi
!= AFI_IP
|| nh_afi
!= AFI_IP6
651 || !(safi
== SAFI_UNICAST
652 || safi
== SAFI_LABELED_UNICAST
)) {
654 EC_BGP_CAPABILITY_INVALID_DATA
,
655 "%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
656 "in Extended Next-hop capability, ignoring",
657 peer
->host
, pkt_afi
, pkt_safi
, pkt_nh_afi
);
661 SET_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ENHE_AF_RCV
);
663 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
], PEER_CAP_ENHE_AF_ADV
))
664 SET_FLAG(peer
->af_cap
[afi
][safi
],
665 PEER_CAP_ENHE_AF_NEGO
);
668 SET_FLAG(peer
->cap
, PEER_CAP_ENHE_RCV
);
673 static int bgp_capability_hostname(struct peer
*peer
,
674 struct capability_header
*hdr
)
676 struct stream
*s
= BGP_INPUT(peer
);
677 char str
[BGP_MAX_HOSTNAME
+ 1];
678 size_t end
= stream_get_getp(s
) + hdr
->length
;
681 SET_FLAG(peer
->cap
, PEER_CAP_HOSTNAME_RCV
);
683 len
= stream_getc(s
);
684 if (stream_get_getp(s
) + len
> end
) {
686 EC_BGP_CAPABILITY_INVALID_DATA
,
687 "%s: Received malformed hostname capability from peer %s",
688 __FUNCTION__
, peer
->host
);
692 if (len
> BGP_MAX_HOSTNAME
) {
693 stream_get(str
, s
, BGP_MAX_HOSTNAME
);
694 stream_forward_getp(s
, len
- BGP_MAX_HOSTNAME
);
695 len
= BGP_MAX_HOSTNAME
; /* to set the '\0' below */
697 stream_get(str
, s
, len
);
702 if (peer
->hostname
!= NULL
) {
703 XFREE(MTYPE_BGP_PEER_HOST
, peer
->hostname
);
704 peer
->hostname
= NULL
;
707 if (peer
->domainname
!= NULL
) {
708 XFREE(MTYPE_BGP_PEER_HOST
, peer
->domainname
);
709 peer
->domainname
= NULL
;
712 peer
->hostname
= XSTRDUP(MTYPE_BGP_PEER_HOST
, str
);
715 if (stream_get_getp(s
) + 1 > end
) {
717 EC_BGP_CAPABILITY_INVALID_DATA
,
718 "%s: Received invalid domain name len (hostname capability) from peer %s",
719 __FUNCTION__
, peer
->host
);
723 len
= stream_getc(s
);
724 if (stream_get_getp(s
) + len
> end
) {
726 EC_BGP_CAPABILITY_INVALID_DATA
,
727 "%s: Received runt domain name (hostname capability) from peer %s",
728 __FUNCTION__
, peer
->host
);
732 if (len
> BGP_MAX_HOSTNAME
) {
733 stream_get(str
, s
, BGP_MAX_HOSTNAME
);
734 stream_forward_getp(s
, len
- BGP_MAX_HOSTNAME
);
735 len
= BGP_MAX_HOSTNAME
; /* to set the '\0' below */
737 stream_get(str
, s
, len
);
741 peer
->domainname
= XSTRDUP(MTYPE_BGP_PEER_HOST
, str
);
744 if (bgp_debug_neighbor_events(peer
)) {
745 zlog_debug("%s received hostname %s, domainname %s", peer
->host
,
746 peer
->hostname
, peer
->domainname
);
752 static const struct message capcode_str
[] = {
753 {CAPABILITY_CODE_MP
, "MultiProtocol Extensions"},
754 {CAPABILITY_CODE_REFRESH
, "Route Refresh"},
755 {CAPABILITY_CODE_ORF
, "Cooperative Route Filtering"},
756 {CAPABILITY_CODE_RESTART
, "Graceful Restart"},
757 {CAPABILITY_CODE_AS4
, "4-octet AS number"},
758 {CAPABILITY_CODE_ADDPATH
, "AddPath"},
759 {CAPABILITY_CODE_DYNAMIC
, "Dynamic"},
760 {CAPABILITY_CODE_ENHE
, "Extended Next Hop Encoding"},
761 {CAPABILITY_CODE_DYNAMIC_OLD
, "Dynamic (Old)"},
762 {CAPABILITY_CODE_REFRESH_OLD
, "Route Refresh (Old)"},
763 {CAPABILITY_CODE_ORF_OLD
, "ORF (Old)"},
764 {CAPABILITY_CODE_FQDN
, "FQDN"},
767 /* Minimum sizes for length field of each cap (so not inc. the header) */
768 static const size_t cap_minsizes
[] = {
769 [CAPABILITY_CODE_MP
] = CAPABILITY_CODE_MP_LEN
,
770 [CAPABILITY_CODE_REFRESH
] = CAPABILITY_CODE_REFRESH_LEN
,
771 [CAPABILITY_CODE_ORF
] = CAPABILITY_CODE_ORF_LEN
,
772 [CAPABILITY_CODE_RESTART
] = CAPABILITY_CODE_RESTART_LEN
,
773 [CAPABILITY_CODE_AS4
] = CAPABILITY_CODE_AS4_LEN
,
774 [CAPABILITY_CODE_ADDPATH
] = CAPABILITY_CODE_ADDPATH_LEN
,
775 [CAPABILITY_CODE_DYNAMIC
] = CAPABILITY_CODE_DYNAMIC_LEN
,
776 [CAPABILITY_CODE_DYNAMIC_OLD
] = CAPABILITY_CODE_DYNAMIC_LEN
,
777 [CAPABILITY_CODE_ENHE
] = CAPABILITY_CODE_ENHE_LEN
,
778 [CAPABILITY_CODE_REFRESH_OLD
] = CAPABILITY_CODE_REFRESH_LEN
,
779 [CAPABILITY_CODE_ORF_OLD
] = CAPABILITY_CODE_ORF_LEN
,
780 [CAPABILITY_CODE_FQDN
] = CAPABILITY_CODE_MIN_FQDN_LEN
,
783 /* value the capability must be a multiple of.
784 * 0-data capabilities won't be checked against this.
785 * Other capabilities whose data doesn't fall on convenient boundaries for this
786 * table should be set to 1.
788 static const size_t cap_modsizes
[] = {
789 [CAPABILITY_CODE_MP
] = 4,
790 [CAPABILITY_CODE_REFRESH
] = 1,
791 [CAPABILITY_CODE_ORF
] = 1,
792 [CAPABILITY_CODE_RESTART
] = 1,
793 [CAPABILITY_CODE_AS4
] = 4,
794 [CAPABILITY_CODE_ADDPATH
] = 4,
795 [CAPABILITY_CODE_DYNAMIC
] = 1,
796 [CAPABILITY_CODE_DYNAMIC_OLD
] = 1,
797 [CAPABILITY_CODE_ENHE
] = 6,
798 [CAPABILITY_CODE_REFRESH_OLD
] = 1,
799 [CAPABILITY_CODE_ORF_OLD
] = 1,
800 [CAPABILITY_CODE_FQDN
] = 1,
804 * Parse given capability.
805 * XXX: This is reading into a stream, but not using stream API
807 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
808 * capabilities were encountered.
810 static int bgp_capability_parse(struct peer
*peer
, size_t length
,
811 int *mp_capability
, uint8_t **error
)
814 struct stream
*s
= BGP_INPUT(peer
);
815 size_t end
= stream_get_getp(s
) + length
;
817 assert(STREAM_READABLE(s
) >= length
);
819 while (stream_get_getp(s
) < end
) {
821 uint8_t *sp
= stream_pnt(s
);
822 struct capability_header caphdr
;
825 /* We need at least capability code and capability length. */
826 if (stream_get_getp(s
) + 2 > end
) {
827 zlog_info("%s Capability length error (< header)",
829 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
830 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
834 caphdr
.code
= stream_getc(s
);
835 caphdr
.length
= stream_getc(s
);
836 start
= stream_get_getp(s
);
838 /* Capability length check sanity check. */
839 if (start
+ caphdr
.length
> end
) {
840 zlog_info("%s Capability length error (< length)",
842 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
843 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
847 if (bgp_debug_neighbor_events(peer
))
848 zlog_debug("%s OPEN has %s capability (%u), length %u",
850 lookup_msg(capcode_str
, caphdr
.code
, NULL
),
851 caphdr
.code
, caphdr
.length
);
853 /* Length sanity check, type-specific, for known capabilities */
854 switch (caphdr
.code
) {
855 case CAPABILITY_CODE_MP
:
856 case CAPABILITY_CODE_REFRESH
:
857 case CAPABILITY_CODE_REFRESH_OLD
:
858 case CAPABILITY_CODE_ORF
:
859 case CAPABILITY_CODE_ORF_OLD
:
860 case CAPABILITY_CODE_RESTART
:
861 case CAPABILITY_CODE_AS4
:
862 case CAPABILITY_CODE_ADDPATH
:
863 case CAPABILITY_CODE_DYNAMIC
:
864 case CAPABILITY_CODE_DYNAMIC_OLD
:
865 case CAPABILITY_CODE_ENHE
:
866 case CAPABILITY_CODE_FQDN
:
868 if (caphdr
.length
< cap_minsizes
[caphdr
.code
]) {
870 "%s %s Capability length error: got %u,"
871 " expected at least %u",
873 lookup_msg(capcode_str
, caphdr
.code
,
876 (unsigned)cap_minsizes
[caphdr
.code
]);
877 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
878 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
882 && caphdr
.length
% cap_modsizes
[caphdr
.code
] != 0) {
884 "%s %s Capability length error: got %u,"
885 " expected a multiple of %u",
887 lookup_msg(capcode_str
, caphdr
.code
,
890 (unsigned)cap_modsizes
[caphdr
.code
]);
891 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
892 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
895 /* we deliberately ignore unknown codes, see below */
900 switch (caphdr
.code
) {
901 case CAPABILITY_CODE_MP
: {
904 /* Ignore capability when override-capability is set. */
905 if (!CHECK_FLAG(peer
->flags
,
906 PEER_FLAG_OVERRIDE_CAPABILITY
)) {
907 /* Set negotiated value. */
908 ret
= bgp_capability_mp(peer
, &caphdr
);
910 /* Unsupported Capability. */
912 /* Store return data. */
913 memcpy(*error
, sp
, caphdr
.length
+ 2);
914 *error
+= caphdr
.length
+ 2;
916 ret
= 0; /* Don't return error for this */
919 case CAPABILITY_CODE_REFRESH
:
920 case CAPABILITY_CODE_REFRESH_OLD
: {
921 /* BGP refresh capability */
922 if (caphdr
.code
== CAPABILITY_CODE_REFRESH_OLD
)
923 SET_FLAG(peer
->cap
, PEER_CAP_REFRESH_OLD_RCV
);
925 SET_FLAG(peer
->cap
, PEER_CAP_REFRESH_NEW_RCV
);
927 case CAPABILITY_CODE_ORF
:
928 case CAPABILITY_CODE_ORF_OLD
:
929 ret
= bgp_capability_orf_entry(peer
, &caphdr
);
931 case CAPABILITY_CODE_RESTART
:
932 ret
= bgp_capability_restart(peer
, &caphdr
);
934 case CAPABILITY_CODE_DYNAMIC
:
935 case CAPABILITY_CODE_DYNAMIC_OLD
:
936 SET_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_RCV
);
938 case CAPABILITY_CODE_AS4
:
939 /* Already handled as a special-case parsing of the
941 * at the beginning of OPEN processing. So we care not a
943 * for the value really, only error case.
945 if (!bgp_capability_as4(peer
, &caphdr
))
948 case CAPABILITY_CODE_ADDPATH
:
949 ret
= bgp_capability_addpath(peer
, &caphdr
);
951 case CAPABILITY_CODE_ENHE
:
952 ret
= bgp_capability_enhe(peer
, &caphdr
);
954 case CAPABILITY_CODE_FQDN
:
955 ret
= bgp_capability_hostname(peer
, &caphdr
);
958 if (caphdr
.code
> 128) {
959 /* We don't send Notification for unknown vendor
961 capabilities. It seems reasonable for now...
963 flog_warn(EC_BGP_CAPABILITY_VENDOR
,
964 "%s Vendor specific capability %d",
965 peer
->host
, caphdr
.code
);
968 EC_BGP_CAPABILITY_UNKNOWN
,
969 "%s unrecognized capability code: %d - ignored",
970 peer
->host
, caphdr
.code
);
971 memcpy(*error
, sp
, caphdr
.length
+ 2);
972 *error
+= caphdr
.length
+ 2;
977 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
978 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
981 if (stream_get_getp(s
) != (start
+ caphdr
.length
)) {
982 if (stream_get_getp(s
) > (start
+ caphdr
.length
))
984 EC_BGP_CAPABILITY_INVALID_LENGTH
,
985 "%s Cap-parser for %s read past cap-length, %u!",
987 lookup_msg(capcode_str
, caphdr
.code
,
990 stream_set_getp(s
, start
+ caphdr
.length
);
996 static int bgp_auth_parse(struct peer
*peer
, size_t length
)
998 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
999 BGP_NOTIFY_OPEN_AUTH_FAILURE
);
1003 static int strict_capability_same(struct peer
*peer
)
1007 for (i
= AFI_IP
; i
< AFI_MAX
; i
++)
1008 for (j
= SAFI_UNICAST
; j
< SAFI_MAX
; j
++)
1009 if (peer
->afc
[i
][j
] != peer
->afc_nego
[i
][j
])
1014 /* peek into option, stores ASN to *as4 if the AS4 capability was found.
1015 * Returns 0 if no as4 found, as4cap value otherwise.
1017 as_t
peek_for_as4_capability(struct peer
*peer
, uint8_t length
)
1019 struct stream
*s
= BGP_INPUT(peer
);
1020 size_t orig_getp
= stream_get_getp(s
);
1021 size_t end
= orig_getp
+ length
;
1024 if (BGP_DEBUG(as4
, AS4
))
1026 "%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
1028 peer
->host
, length
);
1029 /* the error cases we DONT handle, we ONLY try to read as4 out of
1030 * correctly formatted options.
1032 while (stream_get_getp(s
) < end
) {
1036 /* Check the length. */
1037 if (stream_get_getp(s
) + 2 > end
)
1040 /* Fetch option type and length. */
1041 opt_type
= stream_getc(s
);
1042 opt_length
= stream_getc(s
);
1044 /* Option length check. */
1045 if (stream_get_getp(s
) + opt_length
> end
)
1048 if (opt_type
== BGP_OPEN_OPT_CAP
) {
1049 unsigned long capd_start
= stream_get_getp(s
);
1050 unsigned long capd_end
= capd_start
+ opt_length
;
1052 assert(capd_end
<= end
);
1054 while (stream_get_getp(s
) < capd_end
) {
1055 struct capability_header hdr
;
1057 if (stream_get_getp(s
) + 2 > capd_end
)
1060 hdr
.code
= stream_getc(s
);
1061 hdr
.length
= stream_getc(s
);
1063 if ((stream_get_getp(s
) + hdr
.length
)
1067 if (hdr
.code
== CAPABILITY_CODE_AS4
) {
1068 if (BGP_DEBUG(as4
, AS4
))
1070 "[AS4] found AS4 capability, about to parse");
1071 as4
= bgp_capability_as4(peer
, &hdr
);
1075 stream_forward_getp(s
, hdr
.length
);
1081 stream_set_getp(s
, orig_getp
);
1086 * Parse open option.
1088 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1090 int bgp_open_option_parse(struct peer
*peer
, uint8_t length
, int *mp_capability
)
1094 uint8_t error_data
[BGP_MAX_PACKET_SIZE
];
1095 struct stream
*s
= BGP_INPUT(peer
);
1096 size_t end
= stream_get_getp(s
) + length
;
1100 if (bgp_debug_neighbor_events(peer
))
1101 zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1102 peer
->host
, length
);
1104 while (stream_get_getp(s
) < end
) {
1108 /* Must have at least an OPEN option header */
1109 if (STREAM_READABLE(s
) < 2) {
1110 zlog_info("%s Option length error", peer
->host
);
1111 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1112 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
1116 /* Fetch option type and length. */
1117 opt_type
= stream_getc(s
);
1118 opt_length
= stream_getc(s
);
1120 /* Option length check. */
1121 if (STREAM_READABLE(s
) < opt_length
) {
1122 zlog_info("%s Option length error", peer
->host
);
1123 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1124 BGP_NOTIFY_OPEN_MALFORMED_ATTR
);
1128 if (bgp_debug_neighbor_events(peer
))
1130 "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1131 peer
->host
, opt_type
,
1132 opt_type
== BGP_OPEN_OPT_AUTH
1134 : opt_type
== BGP_OPEN_OPT_CAP
1140 case BGP_OPEN_OPT_AUTH
:
1141 ret
= bgp_auth_parse(peer
, opt_length
);
1143 case BGP_OPEN_OPT_CAP
:
1144 ret
= bgp_capability_parse(peer
, opt_length
,
1145 mp_capability
, &error
);
1148 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1149 BGP_NOTIFY_OPEN_UNSUP_PARAM
);
1154 /* Parse error. To accumulate all unsupported capability codes,
1155 bgp_capability_parse does not return -1 when encounter
1156 unsupported capability code. To detect that, please check
1157 error and erro_data pointer, like below. */
1162 /* All OPEN option is parsed. Check capability when strict compare
1164 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_STRICT_CAP_MATCH
)) {
1165 /* If Unsupported Capability exists. */
1166 if (error
!= error_data
) {
1167 bgp_notify_send_with_data(peer
, BGP_NOTIFY_OPEN_ERR
,
1168 BGP_NOTIFY_OPEN_UNSUP_CAPBL
,
1170 error
- error_data
);
1174 /* Check local capability does not negotiated with remote
1176 if (!strict_capability_same(peer
)) {
1177 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1178 BGP_NOTIFY_OPEN_UNSUP_CAPBL
);
1183 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1186 && !CHECK_FLAG(peer
->flags
, PEER_FLAG_OVERRIDE_CAPABILITY
)) {
1187 if (!peer
->afc_nego
[AFI_IP
][SAFI_UNICAST
]
1188 && !peer
->afc_nego
[AFI_IP
][SAFI_MULTICAST
]
1189 && !peer
->afc_nego
[AFI_IP
][SAFI_LABELED_UNICAST
]
1190 && !peer
->afc_nego
[AFI_IP
][SAFI_MPLS_VPN
]
1191 && !peer
->afc_nego
[AFI_IP
][SAFI_ENCAP
]
1192 && !peer
->afc_nego
[AFI_IP
][SAFI_FLOWSPEC
]
1193 && !peer
->afc_nego
[AFI_IP6
][SAFI_UNICAST
]
1194 && !peer
->afc_nego
[AFI_IP6
][SAFI_MULTICAST
]
1195 && !peer
->afc_nego
[AFI_IP6
][SAFI_LABELED_UNICAST
]
1196 && !peer
->afc_nego
[AFI_IP6
][SAFI_MPLS_VPN
]
1197 && !peer
->afc_nego
[AFI_IP6
][SAFI_ENCAP
]
1198 && !peer
->afc_nego
[AFI_IP6
][SAFI_FLOWSPEC
]
1199 && !peer
->afc_nego
[AFI_L2VPN
][SAFI_EVPN
]) {
1200 flog_err(EC_BGP_PKT_OPEN
,
1201 "%s [Error] Configured AFI/SAFIs do not "
1202 "overlap with received MP capabilities",
1205 if (error
!= error_data
)
1206 bgp_notify_send_with_data(
1207 peer
, BGP_NOTIFY_OPEN_ERR
,
1208 BGP_NOTIFY_OPEN_UNSUP_CAPBL
, error_data
,
1209 error
- error_data
);
1211 bgp_notify_send(peer
, BGP_NOTIFY_OPEN_ERR
,
1212 BGP_NOTIFY_OPEN_UNSUP_CAPBL
);
1219 static void bgp_open_capability_orf(struct stream
*s
, struct peer
*peer
,
1220 afi_t afi
, safi_t safi
, uint8_t code
)
1226 unsigned long numberp
;
1227 int number_of_orfs
= 0;
1229 iana_safi_t pkt_safi
;
1231 /* Convert AFI, SAFI to values for packet. */
1232 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
, &pkt_safi
);
1234 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1235 capp
= stream_get_endp(s
); /* Set Capability Len Pointer */
1236 stream_putc(s
, 0); /* Capability Length */
1237 stream_putc(s
, code
); /* Capability Code */
1238 orfp
= stream_get_endp(s
); /* Set ORF Len Pointer */
1239 stream_putc(s
, 0); /* ORF Length */
1240 stream_putw(s
, pkt_afi
);
1242 stream_putc(s
, pkt_safi
);
1243 numberp
= stream_get_endp(s
); /* Set Number Pointer */
1244 stream_putc(s
, 0); /* Number of ORFs */
1246 /* Address Prefix ORF */
1247 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ORF_PREFIX_SM
)
1248 || CHECK_FLAG(peer
->af_flags
[afi
][safi
], PEER_FLAG_ORF_PREFIX_RM
)) {
1249 stream_putc(s
, (code
== CAPABILITY_CODE_ORF
1251 : ORF_TYPE_PREFIX_OLD
));
1253 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1254 PEER_FLAG_ORF_PREFIX_SM
)
1255 && CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1256 PEER_FLAG_ORF_PREFIX_RM
)) {
1257 SET_FLAG(peer
->af_cap
[afi
][safi
],
1258 PEER_CAP_ORF_PREFIX_SM_ADV
);
1259 SET_FLAG(peer
->af_cap
[afi
][safi
],
1260 PEER_CAP_ORF_PREFIX_RM_ADV
);
1261 stream_putc(s
, ORF_MODE_BOTH
);
1262 } else if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1263 PEER_FLAG_ORF_PREFIX_SM
)) {
1264 SET_FLAG(peer
->af_cap
[afi
][safi
],
1265 PEER_CAP_ORF_PREFIX_SM_ADV
);
1266 stream_putc(s
, ORF_MODE_SEND
);
1268 SET_FLAG(peer
->af_cap
[afi
][safi
],
1269 PEER_CAP_ORF_PREFIX_RM_ADV
);
1270 stream_putc(s
, ORF_MODE_RECEIVE
);
1275 /* Total Number of ORFs. */
1276 stream_putc_at(s
, numberp
, number_of_orfs
);
1278 /* Total ORF Len. */
1279 orf_len
= stream_get_endp(s
) - orfp
- 1;
1280 stream_putc_at(s
, orfp
, orf_len
);
1282 /* Total Capability Len. */
1283 cap_len
= stream_get_endp(s
) - capp
- 1;
1284 stream_putc_at(s
, capp
, cap_len
);
1287 /* Fill in capability open option to the packet. */
1288 void bgp_open_capability(struct stream
*s
, struct peer
*peer
)
1291 unsigned long cp
, capp
, rcapp
;
1295 iana_safi_t pkt_safi
;
1297 uint32_t restart_time
;
1298 uint8_t afi_safi_count
= 0;
1299 int adv_addpath_tx
= 0;
1301 /* Remember current pointer for Opt Parm Len. */
1302 cp
= stream_get_endp(s
);
1307 /* Do not send capability. */
1308 if (!CHECK_FLAG(peer
->sflags
, PEER_STATUS_CAPABILITY_OPEN
)
1309 || CHECK_FLAG(peer
->flags
, PEER_FLAG_DONT_CAPABILITY
))
1312 /* MP capability for configured AFI, SAFI */
1313 FOREACH_AFI_SAFI (afi
, safi
) {
1314 if (peer
->afc
[afi
][safi
]) {
1315 /* Convert AFI, SAFI to values for packet. */
1316 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
,
1319 peer
->afc_adv
[afi
][safi
] = 1;
1320 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1321 stream_putc(s
, CAPABILITY_CODE_MP_LEN
+ 2);
1322 stream_putc(s
, CAPABILITY_CODE_MP
);
1323 stream_putc(s
, CAPABILITY_CODE_MP_LEN
);
1324 stream_putw(s
, pkt_afi
);
1326 stream_putc(s
, pkt_safi
);
1328 /* Extended nexthop capability - currently
1329 * supporting RFC-5549 for
1330 * Link-Local peering only
1332 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_CAPABILITY_ENHE
)
1333 && peer
->su
.sa
.sa_family
== AF_INET6
1335 && (safi
== SAFI_UNICAST
1336 || safi
== SAFI_LABELED_UNICAST
)) {
1337 /* RFC 5549 Extended Next Hop Encoding
1339 SET_FLAG(peer
->cap
, PEER_CAP_ENHE_ADV
);
1340 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1341 stream_putc(s
, CAPABILITY_CODE_ENHE_LEN
+ 2);
1342 stream_putc(s
, CAPABILITY_CODE_ENHE
);
1343 stream_putc(s
, CAPABILITY_CODE_ENHE_LEN
);
1345 SET_FLAG(peer
->af_cap
[AFI_IP
][safi
],
1346 PEER_CAP_ENHE_AF_ADV
);
1347 stream_putw(s
, pkt_afi
);
1348 stream_putw(s
, pkt_safi
);
1349 stream_putw(s
, afi_int2iana(AFI_IP6
));
1351 if (CHECK_FLAG(peer
->af_cap
[afi
][safi
],
1352 PEER_CAP_ENHE_AF_RCV
))
1353 SET_FLAG(peer
->af_cap
[afi
][safi
],
1354 PEER_CAP_ENHE_AF_NEGO
);
1359 /* Route refresh. */
1360 SET_FLAG(peer
->cap
, PEER_CAP_REFRESH_ADV
);
1361 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1362 stream_putc(s
, CAPABILITY_CODE_REFRESH_LEN
+ 2);
1363 stream_putc(s
, CAPABILITY_CODE_REFRESH_OLD
);
1364 stream_putc(s
, CAPABILITY_CODE_REFRESH_LEN
);
1365 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1366 stream_putc(s
, CAPABILITY_CODE_REFRESH_LEN
+ 2);
1367 stream_putc(s
, CAPABILITY_CODE_REFRESH
);
1368 stream_putc(s
, CAPABILITY_CODE_REFRESH_LEN
);
1371 SET_FLAG(peer
->cap
, PEER_CAP_AS4_ADV
);
1372 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1373 stream_putc(s
, CAPABILITY_CODE_AS4_LEN
+ 2);
1374 stream_putc(s
, CAPABILITY_CODE_AS4
);
1375 stream_putc(s
, CAPABILITY_CODE_AS4_LEN
);
1376 if (peer
->change_local_as
)
1377 local_as
= peer
->change_local_as
;
1379 local_as
= peer
->local_as
;
1380 stream_putl(s
, local_as
);
1383 FOREACH_AFI_SAFI (afi
, safi
) {
1384 if (peer
->afc
[afi
][safi
]) {
1387 /* Only advertise addpath TX if a feature that
1390 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1391 PEER_FLAG_ADDPATH_TX_ALL_PATHS
)
1392 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1393 PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
))
1398 SET_FLAG(peer
->cap
, PEER_CAP_ADDPATH_ADV
);
1399 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1400 stream_putc(s
, (CAPABILITY_CODE_ADDPATH_LEN
* afi_safi_count
) + 2);
1401 stream_putc(s
, CAPABILITY_CODE_ADDPATH
);
1402 stream_putc(s
, CAPABILITY_CODE_ADDPATH_LEN
* afi_safi_count
);
1404 FOREACH_AFI_SAFI (afi
, safi
) {
1405 if (peer
->afc
[afi
][safi
]) {
1406 /* Convert AFI, SAFI to values for packet. */
1407 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
,
1410 stream_putw(s
, pkt_afi
);
1411 stream_putc(s
, pkt_safi
);
1413 if (adv_addpath_tx
) {
1414 stream_putc(s
, BGP_ADDPATH_RX
| BGP_ADDPATH_TX
);
1415 SET_FLAG(peer
->af_cap
[afi
][safi
],
1416 PEER_CAP_ADDPATH_AF_RX_ADV
);
1417 SET_FLAG(peer
->af_cap
[afi
][safi
],
1418 PEER_CAP_ADDPATH_AF_TX_ADV
);
1420 stream_putc(s
, BGP_ADDPATH_RX
);
1421 SET_FLAG(peer
->af_cap
[afi
][safi
],
1422 PEER_CAP_ADDPATH_AF_RX_ADV
);
1423 UNSET_FLAG(peer
->af_cap
[afi
][safi
],
1424 PEER_CAP_ADDPATH_AF_TX_ADV
);
1429 /* ORF capability. */
1430 FOREACH_AFI_SAFI (afi
, safi
) {
1431 if (CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1432 PEER_FLAG_ORF_PREFIX_SM
)
1433 || CHECK_FLAG(peer
->af_flags
[afi
][safi
],
1434 PEER_FLAG_ORF_PREFIX_RM
)) {
1435 bgp_open_capability_orf(s
, peer
, afi
, safi
,
1436 CAPABILITY_CODE_ORF_OLD
);
1437 bgp_open_capability_orf(s
, peer
, afi
, safi
,
1438 CAPABILITY_CODE_ORF
);
1442 /* Dynamic capability. */
1443 if (CHECK_FLAG(peer
->flags
, PEER_FLAG_DYNAMIC_CAPABILITY
)) {
1444 SET_FLAG(peer
->cap
, PEER_CAP_DYNAMIC_ADV
);
1445 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1446 stream_putc(s
, CAPABILITY_CODE_DYNAMIC_LEN
+ 2);
1447 stream_putc(s
, CAPABILITY_CODE_DYNAMIC_OLD
);
1448 stream_putc(s
, CAPABILITY_CODE_DYNAMIC_LEN
);
1449 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1450 stream_putc(s
, CAPABILITY_CODE_DYNAMIC_LEN
+ 2);
1451 stream_putc(s
, CAPABILITY_CODE_DYNAMIC
);
1452 stream_putc(s
, CAPABILITY_CODE_DYNAMIC_LEN
);
1455 /* Hostname capability */
1456 if (cmd_hostname_get()) {
1457 SET_FLAG(peer
->cap
, PEER_CAP_HOSTNAME_ADV
);
1458 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1459 rcapp
= stream_get_endp(s
); /* Ptr to length placeholder */
1460 stream_putc(s
, 0); /* dummy len for now */
1461 stream_putc(s
, CAPABILITY_CODE_FQDN
);
1462 capp
= stream_get_endp(s
);
1463 stream_putc(s
, 0); /* dummy len for now */
1464 len
= strlen(cmd_hostname_get());
1465 if (len
> BGP_MAX_HOSTNAME
)
1466 len
= BGP_MAX_HOSTNAME
;
1468 stream_putc(s
, len
);
1469 stream_put(s
, cmd_hostname_get(), len
);
1470 if (cmd_domainname_get()) {
1471 len
= strlen(cmd_domainname_get());
1472 if (len
> BGP_MAX_HOSTNAME
)
1473 len
= BGP_MAX_HOSTNAME
;
1475 stream_putc(s
, len
);
1476 stream_put(s
, cmd_domainname_get(), len
);
1478 stream_putc(s
, 0); /* 0 length */
1480 /* Set the lengths straight */
1481 len
= stream_get_endp(s
) - rcapp
- 1;
1482 stream_putc_at(s
, rcapp
, len
);
1483 len
= stream_get_endp(s
) - capp
- 1;
1484 stream_putc_at(s
, capp
, len
);
1486 if (bgp_debug_neighbor_events(peer
))
1488 "%s Sending hostname cap with hn = %s, dn = %s",
1489 peer
->host
, cmd_hostname_get(),
1490 cmd_domainname_get());
1493 /* Sending base graceful-restart capability irrespective of the config
1495 SET_FLAG(peer
->cap
, PEER_CAP_RESTART_ADV
);
1496 stream_putc(s
, BGP_OPEN_OPT_CAP
);
1497 capp
= stream_get_endp(s
); /* Set Capability Len Pointer */
1498 stream_putc(s
, 0); /* Capability Length */
1499 stream_putc(s
, CAPABILITY_CODE_RESTART
);
1500 rcapp
= stream_get_endp(s
); /* Set Restart Capability Len Pointer */
1502 restart_time
= peer
->bgp
->restart_time
;
1503 if (peer
->bgp
->t_startup
) {
1504 SET_FLAG(restart_time
, RESTART_R_BIT
);
1505 SET_FLAG(peer
->cap
, PEER_CAP_RESTART_BIT_ADV
);
1507 stream_putw(s
, restart_time
);
1509 /* Send address-family specific graceful-restart capability only when GR
1512 if (bgp_flag_check(peer
->bgp
, BGP_FLAG_GRACEFUL_RESTART
)) {
1513 FOREACH_AFI_SAFI (afi
, safi
) {
1514 if (peer
->afc
[afi
][safi
]) {
1515 /* Convert AFI, SAFI to values for
1517 bgp_map_afi_safi_int2iana(afi
, safi
, &pkt_afi
,
1519 stream_putw(s
, pkt_afi
);
1520 stream_putc(s
, pkt_safi
);
1521 if (bgp_flag_check(peer
->bgp
,
1522 BGP_FLAG_GR_PRESERVE_FWD
))
1523 stream_putc(s
, RESTART_F_BIT
);
1530 /* Total Graceful restart capability Len. */
1531 len
= stream_get_endp(s
) - rcapp
- 1;
1532 stream_putc_at(s
, rcapp
, len
);
1534 /* Total Capability Len. */
1535 len
= stream_get_endp(s
) - capp
- 1;
1536 stream_putc_at(s
, capp
, len
);
1538 /* Total Opt Parm Len. */
1539 len
= stream_get_endp(s
) - cp
- 1;
1540 stream_putc_at(s
, cp
, len
);