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