]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
Merge pull request #9497 from opensourcerouting/cli-better-no
[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)) {
469 zlog_debug("%s OPEN has Graceful Restart capability",
470 peer->host);
471 zlog_debug("%s Peer has%srestarted. Restart Time : %d",
472 peer->host,
473 CHECK_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV)
474 ? " "
475 : " not ",
476 peer->v_gr_restart);
477 }
478
479 while (stream_get_getp(s) + 4 <= end) {
480 afi_t afi;
481 safi_t safi;
482 iana_afi_t pkt_afi = stream_getw(s);
5c525538 483 iana_safi_t pkt_safi = stream_getc(s);
d7c0a89a 484 uint8_t flag = stream_getc(s);
d62a17ae 485
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))
489 zlog_debug(
3efd0893 490 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Graceful Restart capability for this AFI/SAFI",
748a041f
DS
491 peer->host, iana_afi2str(pkt_afi),
492 iana_safi2str(pkt_safi));
d62a17ae 493 } else if (!peer->afc[afi][safi]) {
494 if (bgp_debug_neighbor_events(peer))
495 zlog_debug(
3efd0893 496 "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the Graceful Restart capability",
748a041f
DS
497 peer->host, iana_afi2str(pkt_afi),
498 iana_safi2str(pkt_safi));
d62a17ae 499 } else {
500 if (bgp_debug_neighbor_events(peer))
501 zlog_debug(
502 "%s Address family %s is%spreserved",
5cb5f4d0 503 peer->host, get_afi_safi_str(afi, safi, false),
d62a17ae 504 CHECK_FLAG(
505 peer->af_cap[afi][safi],
506 PEER_CAP_RESTART_AF_PRESERVE_RCV)
507 ? " "
508 : " not ");
509
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);
515 }
516 }
517 return 0;
6d58272b 518}
718e3744 519
14051b36 520/* Unlike other capability parsing routines, this one returns 0 on error */
d62a17ae 521static as_t bgp_capability_as4(struct peer *peer, struct capability_header *hdr)
0b2aa3a0 522{
d62a17ae 523 SET_FLAG(peer->cap, PEER_CAP_AS4_RCV);
524
525 if (hdr->length != CAPABILITY_CODE_AS4_LEN) {
e50f7cfd 526 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
527 "%s AS4 capability has incorrect data length %d",
528 peer->host, hdr->length);
d62a17ae 529 return 0;
530 }
531
532 as_t as4 = stream_getl(BGP_INPUT(peer));
533
534 if (BGP_DEBUG(as4, AS4))
535 zlog_debug(
536 "%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
537 peer->host, as4);
538 return as4;
0b2aa3a0
PJ
539}
540
ef56aee4
DA
541static int bgp_capability_ext_message(struct peer *peer,
542 struct capability_header *hdr)
543{
544 if (hdr->length != CAPABILITY_CODE_EXT_MESSAGE_LEN) {
545 flog_err(
546 EC_BGP_PKT_OPEN,
547 "%s: BGP Extended Message capability has incorrect data length %d",
548 peer->host, hdr->length);
549 return -1;
550 }
551
552 SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV);
553
554 return 0;
555}
556
d62a17ae 557static int bgp_capability_addpath(struct peer *peer,
558 struct capability_header *hdr)
a82478b9 559{
d62a17ae 560 struct stream *s = BGP_INPUT(peer);
561 size_t end = stream_get_getp(s) + hdr->length;
562
563 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV);
564
565 /* Verify length is a multiple of 4 */
566 if (hdr->length % 4) {
065eaa36 567 flog_warn(
e50f7cfd 568 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 569 "Add Path: Received invalid length %d, non-multiple of 4",
570 hdr->length);
571 return -1;
572 }
573
574 while (stream_get_getp(s) + 4 <= end) {
575 afi_t afi;
576 safi_t safi;
577 iana_afi_t pkt_afi = stream_getw(s);
5c525538 578 iana_safi_t pkt_safi = stream_getc(s);
d7c0a89a 579 uint8_t send_receive = stream_getc(s);
d62a17ae 580
581 if (bgp_debug_neighbor_events(peer))
582 zlog_debug(
748a041f
DS
583 "%s OPEN has AddPath CAP for afi/safi: %s/%s%s%s",
584 peer->host, iana_afi2str(pkt_afi),
585 iana_safi2str(pkt_safi),
d62a17ae 586 (send_receive & BGP_ADDPATH_RX) ? ", receive"
587 : "",
588 (send_receive & BGP_ADDPATH_TX) ? ", transmit"
589 : "");
590
591 /* Convert AFI, SAFI to internal values, check. */
592 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
593 if (bgp_debug_neighbor_events(peer))
594 zlog_debug(
3efd0893 595 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the Addpath Attribute for this AFI/SAFI",
748a041f
DS
596 peer->host, iana_afi2str(pkt_afi),
597 iana_safi2str(pkt_safi));
d62a17ae 598 continue;
599 } else if (!peer->afc[afi][safi]) {
600 if (bgp_debug_neighbor_events(peer))
601 zlog_debug(
3efd0893 602 "%s Addr-family %s/%s(afi/safi) not enabled. Ignore the AddPath capability for this AFI/SAFI",
748a041f
DS
603 peer->host, iana_afi2str(pkt_afi),
604 iana_safi2str(pkt_safi));
d62a17ae 605 continue;
606 }
607
608 if (send_receive & BGP_ADDPATH_RX)
609 SET_FLAG(peer->af_cap[afi][safi],
610 PEER_CAP_ADDPATH_AF_RX_RCV);
611
612 if (send_receive & BGP_ADDPATH_TX)
613 SET_FLAG(peer->af_cap[afi][safi],
614 PEER_CAP_ADDPATH_AF_TX_RCV);
615 }
616
617 return 0;
a82478b9
DS
618}
619
d62a17ae 620static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
8a92a8a0 621{
d62a17ae 622 struct stream *s = BGP_INPUT(peer);
623 size_t end = stream_get_getp(s) + hdr->length;
624
625 /* Verify length is a multiple of 4 */
626 if (hdr->length % 6) {
065eaa36 627 flog_warn(
e50f7cfd 628 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 629 "Extended NH: Received invalid length %d, non-multiple of 6",
630 hdr->length);
631 return -1;
632 }
633
634 while (stream_get_getp(s) + 6 <= end) {
635 iana_afi_t pkt_afi = stream_getw(s);
636 afi_t afi;
5c525538
RW
637 iana_safi_t pkt_safi = stream_getw(s);
638 safi_t safi;
d62a17ae 639 iana_afi_t pkt_nh_afi = stream_getw(s);
640 afi_t nh_afi;
641
642 if (bgp_debug_neighbor_events(peer))
643 zlog_debug(
748a041f
DS
644 "%s Received with afi/safi/next-hop afi: %s/%s/%u",
645 peer->host, iana_afi2str(pkt_afi),
646 iana_safi2str(pkt_safi), pkt_nh_afi);
d62a17ae 647
648 /* Convert AFI, SAFI to internal values, check. */
649 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
650 if (bgp_debug_neighbor_events(peer))
651 zlog_debug(
3efd0893 652 "%s Addr-family %s/%s(afi/safi) not supported. Ignore the ENHE Attribute for this AFI/SAFI",
748a041f
DS
653 peer->host, iana_afi2str(pkt_afi),
654 iana_safi2str(pkt_safi));
d62a17ae 655 continue;
656 }
657
658 /* RFC 5549 specifies use of this capability only for IPv4 AFI,
659 * with
660 * the Nexthop AFI being IPv6. A future spec may introduce other
661 * possibilities, so we ignore other values with a log. Also,
662 * only
663 * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported
664 * (and expected).
665 */
666 nh_afi = afi_iana2int(pkt_nh_afi);
667
668 if (afi != AFI_IP || nh_afi != AFI_IP6
770df5fd 669 || !(safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
d62a17ae 670 || safi == SAFI_LABELED_UNICAST)) {
065eaa36 671 flog_warn(
e50f7cfd 672 EC_BGP_CAPABILITY_INVALID_DATA,
3efd0893 673 "%s Unexpected afi/safi/next-hop afi: %s/%s/%u in Extended Next-hop capability, ignoring",
748a041f
DS
674 peer->host, iana_afi2str(pkt_afi),
675 iana_safi2str(pkt_safi), pkt_nh_afi);
d62a17ae 676 continue;
677 }
678
679 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV);
680
681 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_ADV))
682 SET_FLAG(peer->af_cap[afi][safi],
683 PEER_CAP_ENHE_AF_NEGO);
684 }
685
686 SET_FLAG(peer->cap, PEER_CAP_ENHE_RCV);
687
688 return 0;
8a92a8a0
DS
689}
690
d62a17ae 691static int bgp_capability_hostname(struct peer *peer,
692 struct capability_header *hdr)
04b6bdc0 693{
d62a17ae 694 struct stream *s = BGP_INPUT(peer);
695 char str[BGP_MAX_HOSTNAME + 1];
696 size_t end = stream_get_getp(s) + hdr->length;
d7c0a89a 697 uint8_t len;
d62a17ae 698
699 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
700
701 len = stream_getc(s);
702 if (stream_get_getp(s) + len > end) {
065eaa36 703 flog_warn(
e50f7cfd 704 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 705 "%s: Received malformed hostname capability from peer %s",
15569c58 706 __func__, peer->host);
d62a17ae 707 return -1;
708 }
709
710 if (len > BGP_MAX_HOSTNAME) {
711 stream_get(str, s, BGP_MAX_HOSTNAME);
712 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
713 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
714 } else if (len)
715 stream_get(str, s, len);
716
717 if (len) {
718 str[len] = '\0';
719
e1b36e13
QY
720 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
721 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
d62a17ae 722
723 peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
724 }
725
726 if (stream_get_getp(s) + 1 > end) {
065eaa36 727 flog_warn(
e50f7cfd 728 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 729 "%s: Received invalid domain name len (hostname capability) from peer %s",
15569c58 730 __func__, peer->host);
d62a17ae 731 return -1;
732 }
733
734 len = stream_getc(s);
735 if (stream_get_getp(s) + len > end) {
065eaa36 736 flog_warn(
e50f7cfd 737 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 738 "%s: Received runt domain name (hostname capability) from peer %s",
15569c58 739 __func__, peer->host);
d62a17ae 740 return -1;
741 }
742
743 if (len > BGP_MAX_HOSTNAME) {
744 stream_get(str, s, BGP_MAX_HOSTNAME);
745 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
746 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
747 } else if (len)
748 stream_get(str, s, len);
749
750 if (len) {
751 str[len] = '\0';
aba5353c 752
e1b36e13 753 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
aba5353c 754
d62a17ae 755 peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
756 }
757
758 if (bgp_debug_neighbor_events(peer)) {
759 zlog_debug("%s received hostname %s, domainname %s", peer->host,
760 peer->hostname, peer->domainname);
761 }
762
763 return 0;
04b6bdc0
DW
764}
765
d62a17ae 766static const struct message capcode_str[] = {
767 {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
768 {CAPABILITY_CODE_REFRESH, "Route Refresh"},
769 {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
770 {CAPABILITY_CODE_RESTART, "Graceful Restart"},
771 {CAPABILITY_CODE_AS4, "4-octet AS number"},
772 {CAPABILITY_CODE_ADDPATH, "AddPath"},
773 {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
774 {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
775 {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
776 {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
777 {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
778 {CAPABILITY_CODE_FQDN, "FQDN"},
9af52ccf 779 {CAPABILITY_CODE_ENHANCED_RR, "Enhanced Route Refresh"},
ef56aee4 780 {CAPABILITY_CODE_EXT_MESSAGE, "BGP Extended Message"},
d62a17ae 781 {0}};
6d58272b
PJ
782
783/* Minimum sizes for length field of each cap (so not inc. the header) */
d62a17ae 784static const size_t cap_minsizes[] = {
9d303b37
DL
785 [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
786 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
787 [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
788 [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
789 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
790 [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
791 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
792 [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
793 [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
794 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
795 [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
796 [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
9af52ccf 797 [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN,
ef56aee4 798 [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN,
6d58272b
PJ
799};
800
695ef95f
PJ
801/* value the capability must be a multiple of.
802 * 0-data capabilities won't be checked against this.
803 * Other capabilities whose data doesn't fall on convenient boundaries for this
804 * table should be set to 1.
805 */
d62a17ae 806static const size_t cap_modsizes[] = {
9d303b37
DL
807 [CAPABILITY_CODE_MP] = 4,
808 [CAPABILITY_CODE_REFRESH] = 1,
809 [CAPABILITY_CODE_ORF] = 1,
810 [CAPABILITY_CODE_RESTART] = 1,
811 [CAPABILITY_CODE_AS4] = 4,
812 [CAPABILITY_CODE_ADDPATH] = 4,
813 [CAPABILITY_CODE_DYNAMIC] = 1,
814 [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
815 [CAPABILITY_CODE_ENHE] = 6,
816 [CAPABILITY_CODE_REFRESH_OLD] = 1,
817 [CAPABILITY_CODE_ORF_OLD] = 1,
818 [CAPABILITY_CODE_FQDN] = 1,
9af52ccf 819 [CAPABILITY_CODE_ENHANCED_RR] = 1,
ef56aee4 820 [CAPABILITY_CODE_EXT_MESSAGE] = 1,
695ef95f
PJ
821};
822
3b381c32
AS
823/**
824 * Parse given capability.
6d58272b 825 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
826 *
827 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
828 * capabilities were encountered.
6d58272b 829 */
d62a17ae 830static int bgp_capability_parse(struct peer *peer, size_t length,
d7c0a89a 831 int *mp_capability, uint8_t **error)
6d58272b 832{
d62a17ae 833 int ret;
834 struct stream *s = BGP_INPUT(peer);
835 size_t end = stream_get_getp(s) + length;
34aa7448 836 uint16_t restart_flag_time = 0;
d62a17ae 837
838 assert(STREAM_READABLE(s) >= length);
839
840 while (stream_get_getp(s) < end) {
841 size_t start;
d7c0a89a 842 uint8_t *sp = stream_pnt(s);
d62a17ae 843 struct capability_header caphdr;
844
845 ret = 0;
846 /* We need at least capability code and capability length. */
847 if (stream_get_getp(s) + 2 > end) {
848 zlog_info("%s Capability length error (< header)",
849 peer->host);
850 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
851 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
852 return -1;
853 }
854
855 caphdr.code = stream_getc(s);
856 caphdr.length = stream_getc(s);
857 start = stream_get_getp(s);
858
859 /* Capability length check sanity check. */
860 if (start + caphdr.length > end) {
861 zlog_info("%s Capability length error (< length)",
862 peer->host);
863 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
864 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
865 return -1;
866 }
867
868 if (bgp_debug_neighbor_events(peer))
869 zlog_debug("%s OPEN has %s capability (%u), length %u",
870 peer->host,
871 lookup_msg(capcode_str, caphdr.code, NULL),
872 caphdr.code, caphdr.length);
873
874 /* Length sanity check, type-specific, for known capabilities */
875 switch (caphdr.code) {
876 case CAPABILITY_CODE_MP:
877 case CAPABILITY_CODE_REFRESH:
878 case CAPABILITY_CODE_REFRESH_OLD:
879 case CAPABILITY_CODE_ORF:
880 case CAPABILITY_CODE_ORF_OLD:
881 case CAPABILITY_CODE_RESTART:
882 case CAPABILITY_CODE_AS4:
883 case CAPABILITY_CODE_ADDPATH:
884 case CAPABILITY_CODE_DYNAMIC:
885 case CAPABILITY_CODE_DYNAMIC_OLD:
886 case CAPABILITY_CODE_ENHE:
887 case CAPABILITY_CODE_FQDN:
9af52ccf 888 case CAPABILITY_CODE_ENHANCED_RR:
ef56aee4 889 case CAPABILITY_CODE_EXT_MESSAGE:
d62a17ae 890 /* Check length. */
891 if (caphdr.length < cap_minsizes[caphdr.code]) {
892 zlog_info(
3efd0893 893 "%s %s Capability length error: got %u, expected at least %u",
d62a17ae 894 peer->host,
895 lookup_msg(capcode_str, caphdr.code,
896 NULL),
897 caphdr.length,
898 (unsigned)cap_minsizes[caphdr.code]);
899 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
900 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
901 return -1;
902 }
903 if (caphdr.length
904 && caphdr.length % cap_modsizes[caphdr.code] != 0) {
905 zlog_info(
3efd0893 906 "%s %s Capability length error: got %u, expected a multiple of %u",
d62a17ae 907 peer->host,
908 lookup_msg(capcode_str, caphdr.code,
909 NULL),
910 caphdr.length,
911 (unsigned)cap_modsizes[caphdr.code]);
912 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
913 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
914 return -1;
915 }
916 /* we deliberately ignore unknown codes, see below */
917 default:
918 break;
919 }
920
921 switch (caphdr.code) {
922 case CAPABILITY_CODE_MP: {
923 *mp_capability = 1;
924
925 /* Ignore capability when override-capability is set. */
926 if (!CHECK_FLAG(peer->flags,
927 PEER_FLAG_OVERRIDE_CAPABILITY)) {
928 /* Set negotiated value. */
929 ret = bgp_capability_mp(peer, &caphdr);
930
931 /* Unsupported Capability. */
932 if (ret < 0) {
933 /* Store return data. */
934 memcpy(*error, sp, caphdr.length + 2);
935 *error += caphdr.length + 2;
936 }
937 ret = 0; /* Don't return error for this */
938 }
939 } break;
9af52ccf 940 case CAPABILITY_CODE_ENHANCED_RR:
d62a17ae 941 case CAPABILITY_CODE_REFRESH:
942 case CAPABILITY_CODE_REFRESH_OLD: {
943 /* BGP refresh capability */
9af52ccf
DA
944 if (caphdr.code == CAPABILITY_CODE_ENHANCED_RR)
945 SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_RCV);
946 else if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
d62a17ae 947 SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV);
948 else
949 SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV);
950 } break;
951 case CAPABILITY_CODE_ORF:
952 case CAPABILITY_CODE_ORF_OLD:
953 ret = bgp_capability_orf_entry(peer, &caphdr);
954 break;
955 case CAPABILITY_CODE_RESTART:
956 ret = bgp_capability_restart(peer, &caphdr);
957 break;
958 case CAPABILITY_CODE_DYNAMIC:
959 case CAPABILITY_CODE_DYNAMIC_OLD:
960 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV);
961 break;
962 case CAPABILITY_CODE_AS4:
963 /* Already handled as a special-case parsing of the
964 * capabilities
965 * at the beginning of OPEN processing. So we care not a
966 * jot
967 * for the value really, only error case.
968 */
969 if (!bgp_capability_as4(peer, &caphdr))
970 ret = -1;
971 break;
972 case CAPABILITY_CODE_ADDPATH:
973 ret = bgp_capability_addpath(peer, &caphdr);
974 break;
975 case CAPABILITY_CODE_ENHE:
976 ret = bgp_capability_enhe(peer, &caphdr);
977 break;
ef56aee4
DA
978 case CAPABILITY_CODE_EXT_MESSAGE:
979 ret = bgp_capability_ext_message(peer, &caphdr);
980 break;
d62a17ae 981 case CAPABILITY_CODE_FQDN:
982 ret = bgp_capability_hostname(peer, &caphdr);
983 break;
984 default:
985 if (caphdr.code > 128) {
986 /* We don't send Notification for unknown vendor
987 specific
988 capabilities. It seems reasonable for now...
989 */
e50f7cfd 990 flog_warn(EC_BGP_CAPABILITY_VENDOR,
065eaa36 991 "%s Vendor specific capability %d",
d62a17ae 992 peer->host, caphdr.code);
993 } else {
065eaa36 994 flog_warn(
e50f7cfd 995 EC_BGP_CAPABILITY_UNKNOWN,
d62a17ae 996 "%s unrecognized capability code: %d - ignored",
997 peer->host, caphdr.code);
998 memcpy(*error, sp, caphdr.length + 2);
999 *error += caphdr.length + 2;
1000 }
1001 }
1002
1003 if (ret < 0) {
1004 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1005 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1006 return -1;
1007 }
1008 if (stream_get_getp(s) != (start + caphdr.length)) {
1009 if (stream_get_getp(s) > (start + caphdr.length))
065eaa36 1010 flog_warn(
e50f7cfd 1011 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 1012 "%s Cap-parser for %s read past cap-length, %u!",
1013 peer->host,
1014 lookup_msg(capcode_str, caphdr.code,
1015 NULL),
1016 caphdr.length);
1017 stream_set_getp(s, start + caphdr.length);
1018 }
34aa7448 1019
1020 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
1021 UNSET_FLAG(restart_flag_time, 0xF000);
1022 peer->v_gr_restart = restart_flag_time;
1023 }
718e3744 1024 }
d62a17ae 1025 return 0;
718e3744 1026}
1027
d62a17ae 1028static int bgp_auth_parse(struct peer *peer, size_t length)
718e3744 1029{
d62a17ae 1030 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1031 BGP_NOTIFY_OPEN_AUTH_FAILURE);
1032 return -1;
718e3744 1033}
1034
3dc339cd 1035static bool strict_capability_same(struct peer *peer)
718e3744 1036{
d62a17ae 1037 int i, j;
718e3744 1038
d62a17ae 1039 for (i = AFI_IP; i < AFI_MAX; i++)
1040 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
1041 if (peer->afc[i][j] != peer->afc_nego[i][j])
3dc339cd
DA
1042 return false;
1043 return true;
718e3744 1044}
1045
0b2aa3a0
PJ
1046/* peek into option, stores ASN to *as4 if the AS4 capability was found.
1047 * Returns 0 if no as4 found, as4cap value otherwise.
1048 */
d7c0a89a 1049as_t peek_for_as4_capability(struct peer *peer, uint8_t length)
0b2aa3a0 1050{
d62a17ae 1051 struct stream *s = BGP_INPUT(peer);
1052 size_t orig_getp = stream_get_getp(s);
1053 size_t end = orig_getp + length;
1054 as_t as4 = 0;
1055
1056 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1057 zlog_debug(
3efd0893 1058 "%s [AS4] rcv OPEN w/ OPTION parameter len: %u, peeking for as4",
d62a17ae 1059 peer->host, length);
1060 /* the error cases we DONT handle, we ONLY try to read as4 out of
1061 * correctly formatted options.
1062 */
1063 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1064 uint8_t opt_type;
1065 uint8_t opt_length;
d62a17ae 1066
1067 /* Check the length. */
1068 if (stream_get_getp(s) + 2 > end)
1069 goto end;
1070
1071 /* Fetch option type and length. */
1072 opt_type = stream_getc(s);
1073 opt_length = stream_getc(s);
1074
1075 /* Option length check. */
1076 if (stream_get_getp(s) + opt_length > end)
1077 goto end;
1078
1079 if (opt_type == BGP_OPEN_OPT_CAP) {
1080 unsigned long capd_start = stream_get_getp(s);
1081 unsigned long capd_end = capd_start + opt_length;
1082
1083 assert(capd_end <= end);
1084
1085 while (stream_get_getp(s) < capd_end) {
1086 struct capability_header hdr;
1087
1088 if (stream_get_getp(s) + 2 > capd_end)
1089 goto end;
1090
1091 hdr.code = stream_getc(s);
1092 hdr.length = stream_getc(s);
1093
1094 if ((stream_get_getp(s) + hdr.length)
1095 > capd_end)
1096 goto end;
1097
1098 if (hdr.code == CAPABILITY_CODE_AS4) {
1099 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1100 zlog_debug(
d62a17ae 1101 "[AS4] found AS4 capability, about to parse");
1102 as4 = bgp_capability_as4(peer, &hdr);
1103
1104 goto end;
1105 }
1106 stream_forward_getp(s, hdr.length);
1107 }
1108 }
0b2aa3a0 1109 }
0b2aa3a0
PJ
1110
1111end:
d62a17ae 1112 stream_set_getp(s, orig_getp);
1113 return as4;
0b2aa3a0
PJ
1114}
1115
3b381c32
AS
1116/**
1117 * Parse open option.
1118 *
1119 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1120 */
d7c0a89a 1121int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability)
718e3744 1122{
d62a17ae 1123 int ret = 0;
d7c0a89a 1124 uint8_t *error;
556beacf 1125 uint8_t error_data[BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE];
d62a17ae 1126 struct stream *s = BGP_INPUT(peer);
1127 size_t end = stream_get_getp(s) + length;
1128
1129 error = error_data;
1130
1131 if (bgp_debug_neighbor_events(peer))
1132 zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1133 peer->host, length);
1134
77b34214
NT
1135 /* Unset any previously received GR capability. */
1136 UNSET_FLAG(peer->cap, PEER_CAP_RESTART_RCV);
1137
d62a17ae 1138 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1139 uint8_t opt_type;
1140 uint8_t opt_length;
d62a17ae 1141
1142 /* Must have at least an OPEN option header */
1143 if (STREAM_READABLE(s) < 2) {
1144 zlog_info("%s Option length error", peer->host);
1145 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1146 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1147 return -1;
1148 }
1149
1150 /* Fetch option type and length. */
1151 opt_type = stream_getc(s);
1152 opt_length = stream_getc(s);
1153
1154 /* Option length check. */
1155 if (STREAM_READABLE(s) < opt_length) {
1156 zlog_info("%s Option length error", peer->host);
1157 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1158 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1159 return -1;
1160 }
1161
1162 if (bgp_debug_neighbor_events(peer))
1163 zlog_debug(
1164 "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1165 peer->host, opt_type,
1166 opt_type == BGP_OPEN_OPT_AUTH
1167 ? "Authentication"
1168 : opt_type == BGP_OPEN_OPT_CAP
1169 ? "Capability"
1170 : "Unknown",
1171 opt_length);
1172
1173 switch (opt_type) {
1174 case BGP_OPEN_OPT_AUTH:
1175 ret = bgp_auth_parse(peer, opt_length);
1176 break;
1177 case BGP_OPEN_OPT_CAP:
1178 ret = bgp_capability_parse(peer, opt_length,
1179 mp_capability, &error);
1180 break;
1181 default:
1182 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1183 BGP_NOTIFY_OPEN_UNSUP_PARAM);
1184 ret = -1;
1185 break;
1186 }
1187
1188 /* Parse error. To accumulate all unsupported capability codes,
1189 bgp_capability_parse does not return -1 when encounter
1190 unsupported capability code. To detect that, please check
1191 error and erro_data pointer, like below. */
1192 if (ret < 0)
1193 return -1;
718e3744 1194 }
1195
d62a17ae 1196 /* All OPEN option is parsed. Check capability when strict compare
1197 flag is enabled.*/
1198 if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
1199 /* If Unsupported Capability exists. */
1200 if (error != error_data) {
1201 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1202 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1203 error_data,
1204 error - error_data);
1205 return -1;
1206 }
1207
1208 /* Check local capability does not negotiated with remote
1209 peer. */
1210 if (!strict_capability_same(peer)) {
1211 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1212 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1213 return -1;
1214 }
718e3744 1215 }
1216
ef56aee4
DA
1217 /* Extended Message Support */
1218 peer->max_packet_size =
8d976b0e
DA
1219 (CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
1220 && CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV))
556beacf
QY
1221 ? BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE
1222 : BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
ef56aee4 1223
d62a17ae 1224 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1225 error. */
1226 if (*mp_capability
1227 && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1228 if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1229 && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1230 && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1231 && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1232 && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
7c40bf39 1233 && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
d62a17ae 1234 && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1235 && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1236 && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1237 && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1238 && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
7c40bf39 1239 && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
d62a17ae 1240 && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
e50f7cfd 1241 flog_err(EC_BGP_PKT_OPEN,
3efd0893 1242 "%s [Error] Configured AFI/SAFIs do not overlap with received MP capabilities",
1c50c1c0 1243 peer->host);
d62a17ae 1244
1245 if (error != error_data)
1246 bgp_notify_send_with_data(
1247 peer, BGP_NOTIFY_OPEN_ERR,
1248 BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1249 error - error_data);
1250 else
1251 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1252 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1253 return -1;
1254 }
718e3744 1255 }
d62a17ae 1256 return 0;
718e3744 1257}
1258
d62a17ae 1259static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
d7c0a89a 1260 afi_t afi, safi_t safi, uint8_t code)
718e3744 1261{
d7c0a89a
QY
1262 uint8_t cap_len;
1263 uint8_t orf_len;
d62a17ae 1264 unsigned long capp;
1265 unsigned long orfp;
1266 unsigned long numberp;
1267 int number_of_orfs = 0;
1268 iana_afi_t pkt_afi;
5c525538 1269 iana_safi_t pkt_safi;
d62a17ae 1270
1271 /* Convert AFI, SAFI to values for packet. */
1272 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1273
1274 stream_putc(s, BGP_OPEN_OPT_CAP);
1275 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1276 stream_putc(s, 0); /* Capability Length */
1277 stream_putc(s, code); /* Capability Code */
1278 orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1279 stream_putc(s, 0); /* ORF Length */
1280 stream_putw(s, pkt_afi);
1281 stream_putc(s, 0);
1282 stream_putc(s, pkt_safi);
1283 numberp = stream_get_endp(s); /* Set Number Pointer */
1284 stream_putc(s, 0); /* Number of ORFs */
1285
1286 /* Address Prefix ORF */
1287 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1288 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1289 stream_putc(s, (code == CAPABILITY_CODE_ORF
1290 ? ORF_TYPE_PREFIX
1291 : ORF_TYPE_PREFIX_OLD));
1292
1293 if (CHECK_FLAG(peer->af_flags[afi][safi],
1294 PEER_FLAG_ORF_PREFIX_SM)
1295 && CHECK_FLAG(peer->af_flags[afi][safi],
1296 PEER_FLAG_ORF_PREFIX_RM)) {
1297 SET_FLAG(peer->af_cap[afi][safi],
1298 PEER_CAP_ORF_PREFIX_SM_ADV);
1299 SET_FLAG(peer->af_cap[afi][safi],
1300 PEER_CAP_ORF_PREFIX_RM_ADV);
1301 stream_putc(s, ORF_MODE_BOTH);
1302 } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1303 PEER_FLAG_ORF_PREFIX_SM)) {
1304 SET_FLAG(peer->af_cap[afi][safi],
1305 PEER_CAP_ORF_PREFIX_SM_ADV);
1306 stream_putc(s, ORF_MODE_SEND);
1307 } else {
1308 SET_FLAG(peer->af_cap[afi][safi],
1309 PEER_CAP_ORF_PREFIX_RM_ADV);
1310 stream_putc(s, ORF_MODE_RECEIVE);
1311 }
1312 number_of_orfs++;
718e3744 1313 }
718e3744 1314
d62a17ae 1315 /* Total Number of ORFs. */
1316 stream_putc_at(s, numberp, number_of_orfs);
718e3744 1317
d62a17ae 1318 /* Total ORF Len. */
1319 orf_len = stream_get_endp(s) - orfp - 1;
1320 stream_putc_at(s, orfp, orf_len);
718e3744 1321
d62a17ae 1322 /* Total Capability Len. */
1323 cap_len = stream_get_endp(s) - capp - 1;
1324 stream_putc_at(s, capp, cap_len);
718e3744 1325}
1326
034e185d 1327static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
36235319 1328 unsigned long cp)
034e185d 1329{
1330 int len;
1331 iana_afi_t pkt_afi;
1332 afi_t afi;
1333 safi_t safi;
1334 iana_safi_t pkt_safi;
1335 uint32_t restart_time;
1336 unsigned long capp = 0;
1337 unsigned long rcapp = 0;
1338
13909c4f
DS
1339 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
1340 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
1341 return;
1342
1343 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1344 zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
1345 peer->host);
1346
1347 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1348 stream_putc(s, BGP_OPEN_OPT_CAP);
1349 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1350 stream_putc(s, 0); /* Capability Length */
1351 stream_putc(s, CAPABILITY_CODE_RESTART);
1352 /* Set Restart Capability Len Pointer */
1353 rcapp = stream_get_endp(s);
1354 stream_putc(s, 0);
1355 restart_time = peer->bgp->restart_time;
1356 if (peer->bgp->t_startup) {
1357 SET_FLAG(restart_time, RESTART_R_BIT);
1358 SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
034e185d 1359
1360 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
13909c4f
DS
1361 zlog_debug("[BGP_GR] Sending R-Bit for Peer :%s :",
1362 peer->host);
1363 }
1364
1365 stream_putw(s, restart_time);
1366
1367 /* Send address-family specific graceful-restart capability
1368 * only when GR config is present
1369 */
1370 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
892fedb6 1371 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
13909c4f
DS
1372 && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1373 zlog_debug("[BGP_GR] F bit Set");
1374
1375 FOREACH_AFI_SAFI (afi, safi) {
1376 if (!peer->afc[afi][safi])
1377 continue;
0f0444fb 1378
1379 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1380 zlog_debug(
13909c4f
DS
1381 "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
1382 afi, safi);
034e185d 1383
13909c4f
DS
1384 /* Convert AFI, SAFI to values for
1385 * packet.
1386 */
1387 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1388 &pkt_safi);
1389 stream_putw(s, pkt_afi);
1390 stream_putc(s, pkt_safi);
892fedb6
DA
1391 if (CHECK_FLAG(peer->bgp->flags,
1392 BGP_FLAG_GR_PRESERVE_FWD))
13909c4f
DS
1393 stream_putc(s, RESTART_F_BIT);
1394 else
1395 stream_putc(s, 0);
034e185d 1396 }
034e185d 1397 }
13909c4f
DS
1398
1399 /* Total Graceful restart capability Len. */
1400 len = stream_get_endp(s) - rcapp - 1;
1401 stream_putc_at(s, rcapp, len);
1402
1403 /* Total Capability Len. */
1404 len = stream_get_endp(s) - capp - 1;
1405 stream_putc_at(s, capp, len);
034e185d 1406}
1407
718e3744 1408/* Fill in capability open option to the packet. */
d62a17ae 1409void bgp_open_capability(struct stream *s, struct peer *peer)
718e3744 1410{
d7c0a89a 1411 uint8_t len;
d62a17ae 1412 unsigned long cp, capp, rcapp;
1413 iana_afi_t pkt_afi;
1414 afi_t afi;
5c525538
RW
1415 safi_t safi;
1416 iana_safi_t pkt_safi;
d62a17ae 1417 as_t local_as;
d7c0a89a 1418 uint8_t afi_safi_count = 0;
d62a17ae 1419 int adv_addpath_tx = 0;
1420
1421 /* Remember current pointer for Opt Parm Len. */
1422 cp = stream_get_endp(s);
1423
1424 /* Opt Parm Len. */
1425 stream_putc(s, 0);
1426
1427 /* Do not send capability. */
1428 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1429 || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
1430 return;
1431
1432 /* MP capability for configured AFI, SAFI */
05c7a1cc
QY
1433 FOREACH_AFI_SAFI (afi, safi) {
1434 if (peer->afc[afi][safi]) {
1435 /* Convert AFI, SAFI to values for packet. */
1436 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1437 &pkt_safi);
1438
1439 peer->afc_adv[afi][safi] = 1;
1440 stream_putc(s, BGP_OPEN_OPT_CAP);
1441 stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
1442 stream_putc(s, CAPABILITY_CODE_MP);
1443 stream_putc(s, CAPABILITY_CODE_MP_LEN);
1444 stream_putw(s, pkt_afi);
1445 stream_putc(s, 0);
1446 stream_putc(s, pkt_safi);
1447
1448 /* Extended nexthop capability - currently
1449 * supporting RFC-5549 for
1450 * Link-Local peering only
1451 */
1452 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1453 && peer->su.sa.sa_family == AF_INET6
05c7a1cc 1454 && afi == AFI_IP
770df5fd 1455 && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
05c7a1cc
QY
1456 || safi == SAFI_LABELED_UNICAST)) {
1457 /* RFC 5549 Extended Next Hop Encoding
1458 */
1459 SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
d62a17ae 1460 stream_putc(s, BGP_OPEN_OPT_CAP);
05c7a1cc
QY
1461 stream_putc(s, CAPABILITY_CODE_ENHE_LEN + 2);
1462 stream_putc(s, CAPABILITY_CODE_ENHE);
1463 stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1464
1465 SET_FLAG(peer->af_cap[AFI_IP][safi],
1466 PEER_CAP_ENHE_AF_ADV);
d62a17ae 1467 stream_putw(s, pkt_afi);
05c7a1cc
QY
1468 stream_putw(s, pkt_safi);
1469 stream_putw(s, afi_int2iana(AFI_IP6));
d62a17ae 1470
05c7a1cc
QY
1471 if (CHECK_FLAG(peer->af_cap[afi][safi],
1472 PEER_CAP_ENHE_AF_RCV))
1473 SET_FLAG(peer->af_cap[afi][safi],
1474 PEER_CAP_ENHE_AF_NEGO);
d62a17ae 1475 }
1476 }
05c7a1cc 1477 }
d62a17ae 1478
1479 /* Route refresh. */
1480 SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1481 stream_putc(s, BGP_OPEN_OPT_CAP);
1482 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1483 stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1484 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1485 stream_putc(s, BGP_OPEN_OPT_CAP);
1486 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1487 stream_putc(s, CAPABILITY_CODE_REFRESH);
1488 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1489
9af52ccf
DA
1490 /* Enhanced Route Refresh. */
1491 SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_ADV);
1492 stream_putc(s, BGP_OPEN_OPT_CAP);
1493 stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN + 2);
1494 stream_putc(s, CAPABILITY_CODE_ENHANCED_RR);
1495 stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN);
1496
d62a17ae 1497 /* AS4 */
1498 SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1499 stream_putc(s, BGP_OPEN_OPT_CAP);
1500 stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
1501 stream_putc(s, CAPABILITY_CODE_AS4);
1502 stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1503 if (peer->change_local_as)
1504 local_as = peer->change_local_as;
1505 else
1506 local_as = peer->local_as;
1507 stream_putl(s, local_as);
1508
ef56aee4
DA
1509 /* Extended Message Support */
1510 SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV);
1511 stream_putc(s, BGP_OPEN_OPT_CAP);
1512 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2);
1513 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE);
1514 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN);
1515
d62a17ae 1516 /* AddPath */
05c7a1cc
QY
1517 FOREACH_AFI_SAFI (afi, safi) {
1518 if (peer->afc[afi][safi]) {
1519 afi_safi_count++;
1520
1521 /* Only advertise addpath TX if a feature that
1522 * will use it is
1523 * configured */
dcc68b5e 1524 if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
05c7a1cc
QY
1525 adv_addpath_tx = 1;
1526 }
1527 }
d62a17ae 1528
1529 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1530 stream_putc(s, BGP_OPEN_OPT_CAP);
1531 stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1532 stream_putc(s, CAPABILITY_CODE_ADDPATH);
1533 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1534
05c7a1cc
QY
1535 FOREACH_AFI_SAFI (afi, safi) {
1536 if (peer->afc[afi][safi]) {
7c0e4312
DA
1537 bool adv_addpath_rx =
1538 !CHECK_FLAG(peer->af_flags[afi][safi],
1539 PEER_FLAG_DISABLE_ADDPATH_RX);
1540 uint8_t flags = 0;
1541
05c7a1cc
QY
1542 /* Convert AFI, SAFI to values for packet. */
1543 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1544 &pkt_safi);
d62a17ae 1545
05c7a1cc
QY
1546 stream_putw(s, pkt_afi);
1547 stream_putc(s, pkt_safi);
d62a17ae 1548
7c0e4312
DA
1549 if (adv_addpath_rx) {
1550 SET_FLAG(flags, BGP_ADDPATH_RX);
05c7a1cc
QY
1551 SET_FLAG(peer->af_cap[afi][safi],
1552 PEER_CAP_ADDPATH_AF_RX_ADV);
7c0e4312
DA
1553 } else {
1554 UNSET_FLAG(peer->af_cap[afi][safi],
1555 PEER_CAP_ADDPATH_AF_RX_ADV);
1556 }
1557
1558 if (adv_addpath_tx) {
1559 SET_FLAG(flags, BGP_ADDPATH_TX);
05c7a1cc
QY
1560 SET_FLAG(peer->af_cap[afi][safi],
1561 PEER_CAP_ADDPATH_AF_TX_ADV);
1562 } else {
05c7a1cc
QY
1563 UNSET_FLAG(peer->af_cap[afi][safi],
1564 PEER_CAP_ADDPATH_AF_TX_ADV);
d62a17ae 1565 }
7c0e4312
DA
1566
1567 stream_putc(s, flags);
05c7a1cc
QY
1568 }
1569 }
d62a17ae 1570
1571 /* ORF capability. */
05c7a1cc
QY
1572 FOREACH_AFI_SAFI (afi, safi) {
1573 if (CHECK_FLAG(peer->af_flags[afi][safi],
1574 PEER_FLAG_ORF_PREFIX_SM)
1575 || CHECK_FLAG(peer->af_flags[afi][safi],
1576 PEER_FLAG_ORF_PREFIX_RM)) {
1577 bgp_open_capability_orf(s, peer, afi, safi,
1578 CAPABILITY_CODE_ORF_OLD);
1579 bgp_open_capability_orf(s, peer, afi, safi,
1580 CAPABILITY_CODE_ORF);
1581 }
1582 }
d62a17ae 1583
1584 /* Dynamic capability. */
1585 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1586 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1587 stream_putc(s, BGP_OPEN_OPT_CAP);
1588 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1589 stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1590 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1591 stream_putc(s, BGP_OPEN_OPT_CAP);
1592 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1593 stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1594 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
718e3744 1595 }
1596
d62a17ae 1597 /* Hostname capability */
6b3ee3a0 1598 if (cmd_hostname_get()) {
d62a17ae 1599 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1600 stream_putc(s, BGP_OPEN_OPT_CAP);
1601 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1602 stream_putc(s, 0); /* dummy len for now */
1603 stream_putc(s, CAPABILITY_CODE_FQDN);
1604 capp = stream_get_endp(s);
1605 stream_putc(s, 0); /* dummy len for now */
6b3ee3a0 1606 len = strlen(cmd_hostname_get());
d62a17ae 1607 if (len > BGP_MAX_HOSTNAME)
1608 len = BGP_MAX_HOSTNAME;
1609
1610 stream_putc(s, len);
6b3ee3a0
MK
1611 stream_put(s, cmd_hostname_get(), len);
1612 if (cmd_domainname_get()) {
1613 len = strlen(cmd_domainname_get());
d62a17ae 1614 if (len > BGP_MAX_HOSTNAME)
1615 len = BGP_MAX_HOSTNAME;
1616
1617 stream_putc(s, len);
6b3ee3a0 1618 stream_put(s, cmd_domainname_get(), len);
d62a17ae 1619 } else
d62a17ae 1620 stream_putc(s, 0); /* 0 length */
04b6bdc0 1621
d62a17ae 1622 /* Set the lengths straight */
1623 len = stream_get_endp(s) - rcapp - 1;
1624 stream_putc_at(s, rcapp, len);
1625 len = stream_get_endp(s) - capp - 1;
1626 stream_putc_at(s, capp, len);
04b6bdc0 1627
d62a17ae 1628 if (bgp_debug_neighbor_events(peer))
d62a17ae 1629 zlog_debug(
1630 "%s Sending hostname cap with hn = %s, dn = %s",
6b3ee3a0
MK
1631 peer->host, cmd_hostname_get(),
1632 cmd_domainname_get());
d62a17ae 1633 }
1634
034e185d 1635 bgp_peer_send_gr_capability(s, peer, cp);
d62a17ae 1636
1637 /* Total Opt Parm Len. */
1638 len = stream_get_endp(s) - cp - 1;
1639 stream_putc_at(s, cp, len);
718e3744 1640}