]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
Merge pull request #9244 from LabNConsulting/chopps/fix-bgp-list-test
[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 =
1219 CHECK_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_RCV)
556beacf
QY
1220 ? BGP_EXTENDED_MESSAGE_MAX_PACKET_SIZE
1221 : BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
ef56aee4 1222
d62a17ae 1223 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1224 error. */
1225 if (*mp_capability
1226 && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1227 if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1228 && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1229 && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1230 && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1231 && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
7c40bf39 1232 && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
d62a17ae 1233 && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1234 && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1235 && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1236 && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1237 && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
7c40bf39 1238 && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
d62a17ae 1239 && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
e50f7cfd 1240 flog_err(EC_BGP_PKT_OPEN,
3efd0893 1241 "%s [Error] Configured AFI/SAFIs do not overlap with received MP capabilities",
1c50c1c0 1242 peer->host);
d62a17ae 1243
1244 if (error != error_data)
1245 bgp_notify_send_with_data(
1246 peer, BGP_NOTIFY_OPEN_ERR,
1247 BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1248 error - error_data);
1249 else
1250 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1251 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1252 return -1;
1253 }
718e3744 1254 }
d62a17ae 1255 return 0;
718e3744 1256}
1257
d62a17ae 1258static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
d7c0a89a 1259 afi_t afi, safi_t safi, uint8_t code)
718e3744 1260{
d7c0a89a
QY
1261 uint8_t cap_len;
1262 uint8_t orf_len;
d62a17ae 1263 unsigned long capp;
1264 unsigned long orfp;
1265 unsigned long numberp;
1266 int number_of_orfs = 0;
1267 iana_afi_t pkt_afi;
5c525538 1268 iana_safi_t pkt_safi;
d62a17ae 1269
1270 /* Convert AFI, SAFI to values for packet. */
1271 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1272
1273 stream_putc(s, BGP_OPEN_OPT_CAP);
1274 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1275 stream_putc(s, 0); /* Capability Length */
1276 stream_putc(s, code); /* Capability Code */
1277 orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1278 stream_putc(s, 0); /* ORF Length */
1279 stream_putw(s, pkt_afi);
1280 stream_putc(s, 0);
1281 stream_putc(s, pkt_safi);
1282 numberp = stream_get_endp(s); /* Set Number Pointer */
1283 stream_putc(s, 0); /* Number of ORFs */
1284
1285 /* Address Prefix ORF */
1286 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1287 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1288 stream_putc(s, (code == CAPABILITY_CODE_ORF
1289 ? ORF_TYPE_PREFIX
1290 : ORF_TYPE_PREFIX_OLD));
1291
1292 if (CHECK_FLAG(peer->af_flags[afi][safi],
1293 PEER_FLAG_ORF_PREFIX_SM)
1294 && CHECK_FLAG(peer->af_flags[afi][safi],
1295 PEER_FLAG_ORF_PREFIX_RM)) {
1296 SET_FLAG(peer->af_cap[afi][safi],
1297 PEER_CAP_ORF_PREFIX_SM_ADV);
1298 SET_FLAG(peer->af_cap[afi][safi],
1299 PEER_CAP_ORF_PREFIX_RM_ADV);
1300 stream_putc(s, ORF_MODE_BOTH);
1301 } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1302 PEER_FLAG_ORF_PREFIX_SM)) {
1303 SET_FLAG(peer->af_cap[afi][safi],
1304 PEER_CAP_ORF_PREFIX_SM_ADV);
1305 stream_putc(s, ORF_MODE_SEND);
1306 } else {
1307 SET_FLAG(peer->af_cap[afi][safi],
1308 PEER_CAP_ORF_PREFIX_RM_ADV);
1309 stream_putc(s, ORF_MODE_RECEIVE);
1310 }
1311 number_of_orfs++;
718e3744 1312 }
718e3744 1313
d62a17ae 1314 /* Total Number of ORFs. */
1315 stream_putc_at(s, numberp, number_of_orfs);
718e3744 1316
d62a17ae 1317 /* Total ORF Len. */
1318 orf_len = stream_get_endp(s) - orfp - 1;
1319 stream_putc_at(s, orfp, orf_len);
718e3744 1320
d62a17ae 1321 /* Total Capability Len. */
1322 cap_len = stream_get_endp(s) - capp - 1;
1323 stream_putc_at(s, capp, cap_len);
718e3744 1324}
1325
034e185d 1326static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
36235319 1327 unsigned long cp)
034e185d 1328{
1329 int len;
1330 iana_afi_t pkt_afi;
1331 afi_t afi;
1332 safi_t safi;
1333 iana_safi_t pkt_safi;
1334 uint32_t restart_time;
1335 unsigned long capp = 0;
1336 unsigned long rcapp = 0;
1337
13909c4f
DS
1338 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
1339 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
1340 return;
1341
1342 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1343 zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
1344 peer->host);
1345
1346 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1347 stream_putc(s, BGP_OPEN_OPT_CAP);
1348 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1349 stream_putc(s, 0); /* Capability Length */
1350 stream_putc(s, CAPABILITY_CODE_RESTART);
1351 /* Set Restart Capability Len Pointer */
1352 rcapp = stream_get_endp(s);
1353 stream_putc(s, 0);
1354 restart_time = peer->bgp->restart_time;
1355 if (peer->bgp->t_startup) {
1356 SET_FLAG(restart_time, RESTART_R_BIT);
1357 SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
034e185d 1358
1359 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
13909c4f
DS
1360 zlog_debug("[BGP_GR] Sending R-Bit for Peer :%s :",
1361 peer->host);
1362 }
1363
1364 stream_putw(s, restart_time);
1365
1366 /* Send address-family specific graceful-restart capability
1367 * only when GR config is present
1368 */
1369 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
892fedb6 1370 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
13909c4f
DS
1371 && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1372 zlog_debug("[BGP_GR] F bit Set");
1373
1374 FOREACH_AFI_SAFI (afi, safi) {
1375 if (!peer->afc[afi][safi])
1376 continue;
0f0444fb 1377
1378 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1379 zlog_debug(
13909c4f
DS
1380 "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
1381 afi, safi);
034e185d 1382
13909c4f
DS
1383 /* Convert AFI, SAFI to values for
1384 * packet.
1385 */
1386 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1387 &pkt_safi);
1388 stream_putw(s, pkt_afi);
1389 stream_putc(s, pkt_safi);
892fedb6
DA
1390 if (CHECK_FLAG(peer->bgp->flags,
1391 BGP_FLAG_GR_PRESERVE_FWD))
13909c4f
DS
1392 stream_putc(s, RESTART_F_BIT);
1393 else
1394 stream_putc(s, 0);
034e185d 1395 }
034e185d 1396 }
13909c4f
DS
1397
1398 /* Total Graceful restart capability Len. */
1399 len = stream_get_endp(s) - rcapp - 1;
1400 stream_putc_at(s, rcapp, len);
1401
1402 /* Total Capability Len. */
1403 len = stream_get_endp(s) - capp - 1;
1404 stream_putc_at(s, capp, len);
034e185d 1405}
1406
718e3744 1407/* Fill in capability open option to the packet. */
d62a17ae 1408void bgp_open_capability(struct stream *s, struct peer *peer)
718e3744 1409{
d7c0a89a 1410 uint8_t len;
d62a17ae 1411 unsigned long cp, capp, rcapp;
1412 iana_afi_t pkt_afi;
1413 afi_t afi;
5c525538
RW
1414 safi_t safi;
1415 iana_safi_t pkt_safi;
d62a17ae 1416 as_t local_as;
d7c0a89a 1417 uint8_t afi_safi_count = 0;
d62a17ae 1418 int adv_addpath_tx = 0;
1419
1420 /* Remember current pointer for Opt Parm Len. */
1421 cp = stream_get_endp(s);
1422
1423 /* Opt Parm Len. */
1424 stream_putc(s, 0);
1425
1426 /* Do not send capability. */
1427 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1428 || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
1429 return;
1430
1431 /* MP capability for configured AFI, SAFI */
05c7a1cc
QY
1432 FOREACH_AFI_SAFI (afi, safi) {
1433 if (peer->afc[afi][safi]) {
1434 /* Convert AFI, SAFI to values for packet. */
1435 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1436 &pkt_safi);
1437
1438 peer->afc_adv[afi][safi] = 1;
1439 stream_putc(s, BGP_OPEN_OPT_CAP);
1440 stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
1441 stream_putc(s, CAPABILITY_CODE_MP);
1442 stream_putc(s, CAPABILITY_CODE_MP_LEN);
1443 stream_putw(s, pkt_afi);
1444 stream_putc(s, 0);
1445 stream_putc(s, pkt_safi);
1446
1447 /* Extended nexthop capability - currently
1448 * supporting RFC-5549 for
1449 * Link-Local peering only
1450 */
1451 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1452 && peer->su.sa.sa_family == AF_INET6
05c7a1cc 1453 && afi == AFI_IP
770df5fd 1454 && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
05c7a1cc
QY
1455 || safi == SAFI_LABELED_UNICAST)) {
1456 /* RFC 5549 Extended Next Hop Encoding
1457 */
1458 SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
d62a17ae 1459 stream_putc(s, BGP_OPEN_OPT_CAP);
05c7a1cc
QY
1460 stream_putc(s, CAPABILITY_CODE_ENHE_LEN + 2);
1461 stream_putc(s, CAPABILITY_CODE_ENHE);
1462 stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1463
1464 SET_FLAG(peer->af_cap[AFI_IP][safi],
1465 PEER_CAP_ENHE_AF_ADV);
d62a17ae 1466 stream_putw(s, pkt_afi);
05c7a1cc
QY
1467 stream_putw(s, pkt_safi);
1468 stream_putw(s, afi_int2iana(AFI_IP6));
d62a17ae 1469
05c7a1cc
QY
1470 if (CHECK_FLAG(peer->af_cap[afi][safi],
1471 PEER_CAP_ENHE_AF_RCV))
1472 SET_FLAG(peer->af_cap[afi][safi],
1473 PEER_CAP_ENHE_AF_NEGO);
d62a17ae 1474 }
1475 }
05c7a1cc 1476 }
d62a17ae 1477
1478 /* Route refresh. */
1479 SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1480 stream_putc(s, BGP_OPEN_OPT_CAP);
1481 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1482 stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1483 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1484 stream_putc(s, BGP_OPEN_OPT_CAP);
1485 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1486 stream_putc(s, CAPABILITY_CODE_REFRESH);
1487 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1488
9af52ccf
DA
1489 /* Enhanced Route Refresh. */
1490 SET_FLAG(peer->cap, PEER_CAP_ENHANCED_RR_ADV);
1491 stream_putc(s, BGP_OPEN_OPT_CAP);
1492 stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN + 2);
1493 stream_putc(s, CAPABILITY_CODE_ENHANCED_RR);
1494 stream_putc(s, CAPABILITY_CODE_ENHANCED_LEN);
1495
d62a17ae 1496 /* AS4 */
1497 SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1498 stream_putc(s, BGP_OPEN_OPT_CAP);
1499 stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
1500 stream_putc(s, CAPABILITY_CODE_AS4);
1501 stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1502 if (peer->change_local_as)
1503 local_as = peer->change_local_as;
1504 else
1505 local_as = peer->local_as;
1506 stream_putl(s, local_as);
1507
ef56aee4
DA
1508 /* Extended Message Support */
1509 SET_FLAG(peer->cap, PEER_CAP_EXTENDED_MESSAGE_ADV);
1510 stream_putc(s, BGP_OPEN_OPT_CAP);
1511 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN + 2);
1512 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE);
1513 stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN);
1514
d62a17ae 1515 /* AddPath */
05c7a1cc
QY
1516 FOREACH_AFI_SAFI (afi, safi) {
1517 if (peer->afc[afi][safi]) {
1518 afi_safi_count++;
1519
1520 /* Only advertise addpath TX if a feature that
1521 * will use it is
1522 * configured */
dcc68b5e 1523 if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
05c7a1cc
QY
1524 adv_addpath_tx = 1;
1525 }
1526 }
d62a17ae 1527
1528 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1529 stream_putc(s, BGP_OPEN_OPT_CAP);
1530 stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1531 stream_putc(s, CAPABILITY_CODE_ADDPATH);
1532 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1533
05c7a1cc
QY
1534 FOREACH_AFI_SAFI (afi, safi) {
1535 if (peer->afc[afi][safi]) {
1536 /* Convert AFI, SAFI to values for packet. */
1537 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1538 &pkt_safi);
d62a17ae 1539
05c7a1cc
QY
1540 stream_putw(s, pkt_afi);
1541 stream_putc(s, pkt_safi);
d62a17ae 1542
05c7a1cc
QY
1543 if (adv_addpath_tx) {
1544 stream_putc(s, BGP_ADDPATH_RX | BGP_ADDPATH_TX);
1545 SET_FLAG(peer->af_cap[afi][safi],
1546 PEER_CAP_ADDPATH_AF_RX_ADV);
1547 SET_FLAG(peer->af_cap[afi][safi],
1548 PEER_CAP_ADDPATH_AF_TX_ADV);
1549 } else {
1550 stream_putc(s, BGP_ADDPATH_RX);
1551 SET_FLAG(peer->af_cap[afi][safi],
1552 PEER_CAP_ADDPATH_AF_RX_ADV);
1553 UNSET_FLAG(peer->af_cap[afi][safi],
1554 PEER_CAP_ADDPATH_AF_TX_ADV);
d62a17ae 1555 }
05c7a1cc
QY
1556 }
1557 }
d62a17ae 1558
1559 /* ORF capability. */
05c7a1cc
QY
1560 FOREACH_AFI_SAFI (afi, safi) {
1561 if (CHECK_FLAG(peer->af_flags[afi][safi],
1562 PEER_FLAG_ORF_PREFIX_SM)
1563 || CHECK_FLAG(peer->af_flags[afi][safi],
1564 PEER_FLAG_ORF_PREFIX_RM)) {
1565 bgp_open_capability_orf(s, peer, afi, safi,
1566 CAPABILITY_CODE_ORF_OLD);
1567 bgp_open_capability_orf(s, peer, afi, safi,
1568 CAPABILITY_CODE_ORF);
1569 }
1570 }
d62a17ae 1571
1572 /* Dynamic capability. */
1573 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1574 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1575 stream_putc(s, BGP_OPEN_OPT_CAP);
1576 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1577 stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1578 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1579 stream_putc(s, BGP_OPEN_OPT_CAP);
1580 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1581 stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1582 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
718e3744 1583 }
1584
d62a17ae 1585 /* Hostname capability */
6b3ee3a0 1586 if (cmd_hostname_get()) {
d62a17ae 1587 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1588 stream_putc(s, BGP_OPEN_OPT_CAP);
1589 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1590 stream_putc(s, 0); /* dummy len for now */
1591 stream_putc(s, CAPABILITY_CODE_FQDN);
1592 capp = stream_get_endp(s);
1593 stream_putc(s, 0); /* dummy len for now */
6b3ee3a0 1594 len = strlen(cmd_hostname_get());
d62a17ae 1595 if (len > BGP_MAX_HOSTNAME)
1596 len = BGP_MAX_HOSTNAME;
1597
1598 stream_putc(s, len);
6b3ee3a0
MK
1599 stream_put(s, cmd_hostname_get(), len);
1600 if (cmd_domainname_get()) {
1601 len = strlen(cmd_domainname_get());
d62a17ae 1602 if (len > BGP_MAX_HOSTNAME)
1603 len = BGP_MAX_HOSTNAME;
1604
1605 stream_putc(s, len);
6b3ee3a0 1606 stream_put(s, cmd_domainname_get(), len);
d62a17ae 1607 } else
d62a17ae 1608 stream_putc(s, 0); /* 0 length */
04b6bdc0 1609
d62a17ae 1610 /* Set the lengths straight */
1611 len = stream_get_endp(s) - rcapp - 1;
1612 stream_putc_at(s, rcapp, len);
1613 len = stream_get_endp(s) - capp - 1;
1614 stream_putc_at(s, capp, len);
04b6bdc0 1615
d62a17ae 1616 if (bgp_debug_neighbor_events(peer))
d62a17ae 1617 zlog_debug(
1618 "%s Sending hostname cap with hn = %s, dn = %s",
6b3ee3a0
MK
1619 peer->host, cmd_hostname_get(),
1620 cmd_domainname_get());
d62a17ae 1621 }
1622
034e185d 1623 bgp_peer_send_gr_capability(s, peer, cp);
d62a17ae 1624
1625 /* Total Opt Parm Len. */
1626 len = stream_get_endp(s) - cp - 1;
1627 stream_putc_at(s, cp, len);
718e3744 1628}