]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
*: remove the configuration lock from all daemons
[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.
52 Next, if we send capability to the peer we want to set my capabilty
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))
267 zlog_debug("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
268 peer->host, mpc.afi, mpc.safi);
269
270 /* Convert AFI, SAFI to internal values, check. */
271 if (bgp_map_afi_safi_iana2int(mpc.afi, mpc.safi, &afi, &safi))
272 return -1;
273
274 /* Now safi remapped, and afi/safi are valid array indices */
275 peer->afc_recv[afi][safi] = 1;
276
277 if (peer->afc[afi][safi])
278 peer->afc_nego[afi][safi] = 1;
279 else
280 return -1;
281
282 return 0;
718e3744 283}
284
d62a17ae 285static void bgp_capability_orf_not_support(struct peer *peer, iana_afi_t afi,
d7c0a89a
QY
286 iana_safi_t safi, uint8_t type,
287 uint8_t mode)
718e3744 288{
d62a17ae 289 if (bgp_debug_neighbor_events(peer))
290 zlog_debug(
291 "%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
292 peer->host, afi, safi, type, mode);
718e3744 293}
294
d62a17ae 295static const struct message orf_type_str[] = {
296 {ORF_TYPE_PREFIX, "Prefixlist"},
297 {ORF_TYPE_PREFIX_OLD, "Prefixlist (old)"},
298 {0}};
6d58272b 299
d62a17ae 300static const struct message orf_mode_str[] = {{ORF_MODE_RECEIVE, "Receive"},
301 {ORF_MODE_SEND, "Send"},
302 {ORF_MODE_BOTH, "Both"},
303 {0}};
6d58272b 304
d62a17ae 305static int bgp_capability_orf_entry(struct peer *peer,
306 struct capability_header *hdr)
718e3744 307{
d62a17ae 308 struct stream *s = BGP_INPUT(peer);
309 struct capability_mp_data mpc;
d7c0a89a 310 uint8_t num;
d62a17ae 311 iana_afi_t pkt_afi;
312 afi_t afi;
5c525538
RW
313 iana_safi_t pkt_safi;
314 safi_t safi;
d7c0a89a
QY
315 uint8_t type;
316 uint8_t mode;
317 uint16_t sm_cap = 0; /* capability send-mode receive */
318 uint16_t rm_cap = 0; /* capability receive-mode receive */
d62a17ae 319 int i;
320
321 /* ORF Entry header */
322 bgp_capability_mp_data(s, &mpc);
323 num = stream_getc(s);
324 pkt_afi = mpc.afi;
325 pkt_safi = mpc.safi;
326
327 if (bgp_debug_neighbor_events(peer))
328 zlog_debug("%s ORF Cap entry for afi/safi: %u/%u", peer->host,
329 mpc.afi, mpc.safi);
330
331 /* Convert AFI, SAFI to internal values, check. */
332 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
333 zlog_info(
334 "%s Addr-family %d/%d not supported."
335 " Ignoring the ORF capability",
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(
346 "%s ORF Capability entry length error,"
347 " Cap length %u, num %u",
348 peer->host, hdr->length, num);
349 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
350 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
351 return -1;
718e3744 352 }
353
d62a17ae 354 for (i = 0; i < num; i++) {
355 type = stream_getc(s);
356 mode = stream_getc(s);
357
358 /* ORF Mode error check */
359 switch (mode) {
360 case ORF_MODE_BOTH:
361 case ORF_MODE_SEND:
362 case ORF_MODE_RECEIVE:
363 break;
364 default:
365 bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
366 type, mode);
367 continue;
368 }
369 /* ORF Type and afi/safi error checks */
370 /* capcode versus type */
371 switch (hdr->code) {
372 case CAPABILITY_CODE_ORF:
373 switch (type) {
374 case ORF_TYPE_PREFIX:
375 break;
376 default:
377 bgp_capability_orf_not_support(
378 peer, pkt_afi, pkt_safi, type, mode);
379 continue;
380 }
381 break;
382 case CAPABILITY_CODE_ORF_OLD:
383 switch (type) {
384 case ORF_TYPE_PREFIX_OLD:
385 break;
386 default:
387 bgp_capability_orf_not_support(
388 peer, pkt_afi, pkt_safi, type, mode);
389 continue;
390 }
391 break;
392 default:
393 bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
394 type, mode);
395 continue;
396 }
397
398 /* AFI vs SAFI */
399 if (!((afi == AFI_IP && safi == SAFI_UNICAST)
400 || (afi == AFI_IP && safi == SAFI_MULTICAST)
401 || (afi == AFI_IP6 && safi == SAFI_UNICAST))) {
402 bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
403 type, mode);
404 continue;
405 }
406
407 if (bgp_debug_neighbor_events(peer))
408 zlog_debug(
409 "%s OPEN has %s ORF capability"
410 " as %s for afi/safi: %d/%d",
411 peer->host,
412 lookup_msg(orf_type_str, type, NULL),
413 lookup_msg(orf_mode_str, mode, NULL), pkt_afi,
414 pkt_safi);
415
416 if (hdr->code == CAPABILITY_CODE_ORF) {
417 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
418 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
419 } else if (hdr->code == CAPABILITY_CODE_ORF_OLD) {
420 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
421 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
422 } else {
423 bgp_capability_orf_not_support(peer, pkt_afi, pkt_safi,
424 type, mode);
425 continue;
426 }
427
428 switch (mode) {
429 case ORF_MODE_BOTH:
430 SET_FLAG(peer->af_cap[afi][safi], sm_cap);
431 SET_FLAG(peer->af_cap[afi][safi], rm_cap);
432 break;
433 case ORF_MODE_SEND:
434 SET_FLAG(peer->af_cap[afi][safi], sm_cap);
435 break;
436 case ORF_MODE_RECEIVE:
437 SET_FLAG(peer->af_cap[afi][safi], rm_cap);
438 break;
439 }
718e3744 440 }
d62a17ae 441 return 0;
718e3744 442}
443
d62a17ae 444static int bgp_capability_restart(struct peer *peer,
445 struct capability_header *caphdr)
6d58272b 446{
d62a17ae 447 struct stream *s = BGP_INPUT(peer);
d7c0a89a 448 uint16_t restart_flag_time;
d62a17ae 449 size_t end = stream_get_getp(s) + caphdr->length;
450
451 /* Verify length is a multiple of 4 */
452 if ((caphdr->length - 2) % 4) {
065eaa36 453 flog_warn(
e50f7cfd 454 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 455 "Restart Cap: Received invalid length %d, non-multiple of 4",
456 caphdr->length);
457 return -1;
458 }
459
460 SET_FLAG(peer->cap, PEER_CAP_RESTART_RCV);
461 restart_flag_time = stream_getw(s);
462 if (CHECK_FLAG(restart_flag_time, RESTART_R_BIT))
463 SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_RCV);
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(
490 "%s Addr-family %d/%d(afi/safi) not supported."
491 " Ignore the Graceful Restart capability for this AFI/SAFI",
492 peer->host, pkt_afi, pkt_safi);
493 } else if (!peer->afc[afi][safi]) {
494 if (bgp_debug_neighbor_events(peer))
495 zlog_debug(
496 "%s Addr-family %d/%d(afi/safi) not enabled."
497 " Ignore the Graceful Restart capability",
498 peer->host, pkt_afi, pkt_safi);
499 } else {
500 if (bgp_debug_neighbor_events(peer))
501 zlog_debug(
502 "%s Address family %s is%spreserved",
503 peer->host, afi_safi_print(afi, safi),
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
d62a17ae 541static int bgp_capability_addpath(struct peer *peer,
542 struct capability_header *hdr)
a82478b9 543{
d62a17ae 544 struct stream *s = BGP_INPUT(peer);
545 size_t end = stream_get_getp(s) + hdr->length;
546
547 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_RCV);
548
549 /* Verify length is a multiple of 4 */
550 if (hdr->length % 4) {
065eaa36 551 flog_warn(
e50f7cfd 552 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 553 "Add Path: Received invalid length %d, non-multiple of 4",
554 hdr->length);
555 return -1;
556 }
557
558 while (stream_get_getp(s) + 4 <= end) {
559 afi_t afi;
560 safi_t safi;
561 iana_afi_t pkt_afi = stream_getw(s);
5c525538 562 iana_safi_t pkt_safi = stream_getc(s);
d7c0a89a 563 uint8_t send_receive = stream_getc(s);
d62a17ae 564
565 if (bgp_debug_neighbor_events(peer))
566 zlog_debug(
567 "%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
568 peer->host, pkt_afi, pkt_safi,
569 (send_receive & BGP_ADDPATH_RX) ? ", receive"
570 : "",
571 (send_receive & BGP_ADDPATH_TX) ? ", transmit"
572 : "");
573
574 /* Convert AFI, SAFI to internal values, check. */
575 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
576 if (bgp_debug_neighbor_events(peer))
577 zlog_debug(
578 "%s Addr-family %d/%d(afi/safi) not supported."
579 " Ignore the Addpath Attribute for this AFI/SAFI",
580 peer->host, pkt_afi, pkt_safi);
581 continue;
582 } else if (!peer->afc[afi][safi]) {
583 if (bgp_debug_neighbor_events(peer))
584 zlog_debug(
585 "%s Addr-family %d/%d(afi/safi) not enabled."
586 " Ignore the AddPath capability for this AFI/SAFI",
587 peer->host, pkt_afi, pkt_safi);
588 continue;
589 }
590
591 if (send_receive & BGP_ADDPATH_RX)
592 SET_FLAG(peer->af_cap[afi][safi],
593 PEER_CAP_ADDPATH_AF_RX_RCV);
594
595 if (send_receive & BGP_ADDPATH_TX)
596 SET_FLAG(peer->af_cap[afi][safi],
597 PEER_CAP_ADDPATH_AF_TX_RCV);
598 }
599
600 return 0;
a82478b9
DS
601}
602
d62a17ae 603static int bgp_capability_enhe(struct peer *peer, struct capability_header *hdr)
8a92a8a0 604{
d62a17ae 605 struct stream *s = BGP_INPUT(peer);
606 size_t end = stream_get_getp(s) + hdr->length;
607
608 /* Verify length is a multiple of 4 */
609 if (hdr->length % 6) {
065eaa36 610 flog_warn(
e50f7cfd 611 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 612 "Extended NH: Received invalid length %d, non-multiple of 6",
613 hdr->length);
614 return -1;
615 }
616
617 while (stream_get_getp(s) + 6 <= end) {
618 iana_afi_t pkt_afi = stream_getw(s);
619 afi_t afi;
5c525538
RW
620 iana_safi_t pkt_safi = stream_getw(s);
621 safi_t safi;
d62a17ae 622 iana_afi_t pkt_nh_afi = stream_getw(s);
623 afi_t nh_afi;
624
625 if (bgp_debug_neighbor_events(peer))
626 zlog_debug(
627 "%s Received with afi/safi/next-hop afi: %u/%u/%u",
628 peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
629
630 /* Convert AFI, SAFI to internal values, check. */
631 if (bgp_map_afi_safi_iana2int(pkt_afi, pkt_safi, &afi, &safi)) {
632 if (bgp_debug_neighbor_events(peer))
633 zlog_debug(
634 "%s Addr-family %d/%d(afi/safi) not supported."
635 " Ignore the ENHE Attribute for this AFI/SAFI",
636 peer->host, pkt_afi, pkt_safi);
637 continue;
638 }
639
640 /* RFC 5549 specifies use of this capability only for IPv4 AFI,
641 * with
642 * the Nexthop AFI being IPv6. A future spec may introduce other
643 * possibilities, so we ignore other values with a log. Also,
644 * only
645 * SAFI_UNICAST and SAFI_LABELED_UNICAST are currently supported
646 * (and expected).
647 */
648 nh_afi = afi_iana2int(pkt_nh_afi);
649
650 if (afi != AFI_IP || nh_afi != AFI_IP6
651 || !(safi == SAFI_UNICAST
652 || safi == SAFI_LABELED_UNICAST)) {
065eaa36 653 flog_warn(
e50f7cfd 654 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 655 "%s Unexpected afi/safi/next-hop afi: %u/%u/%u "
656 "in Extended Next-hop capability, ignoring",
657 peer->host, pkt_afi, pkt_safi, pkt_nh_afi);
658 continue;
659 }
660
661 SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV);
662
663 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_ADV))
664 SET_FLAG(peer->af_cap[afi][safi],
665 PEER_CAP_ENHE_AF_NEGO);
666 }
667
668 SET_FLAG(peer->cap, PEER_CAP_ENHE_RCV);
669
670 return 0;
8a92a8a0
DS
671}
672
d62a17ae 673static int bgp_capability_hostname(struct peer *peer,
674 struct capability_header *hdr)
04b6bdc0 675{
d62a17ae 676 struct stream *s = BGP_INPUT(peer);
677 char str[BGP_MAX_HOSTNAME + 1];
678 size_t end = stream_get_getp(s) + hdr->length;
d7c0a89a 679 uint8_t len;
d62a17ae 680
681 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
682
683 len = stream_getc(s);
684 if (stream_get_getp(s) + len > end) {
065eaa36 685 flog_warn(
e50f7cfd 686 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 687 "%s: Received malformed hostname capability from peer %s",
688 __FUNCTION__, peer->host);
689 return -1;
690 }
691
692 if (len > BGP_MAX_HOSTNAME) {
693 stream_get(str, s, BGP_MAX_HOSTNAME);
694 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
695 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
696 } else if (len)
697 stream_get(str, s, len);
698
699 if (len) {
700 str[len] = '\0';
701
702 if (peer->hostname != NULL) {
703 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
704 peer->hostname = NULL;
705 }
706
707 if (peer->domainname != NULL) {
708 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
709 peer->domainname = NULL;
710 }
711
712 peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
713 }
714
715 if (stream_get_getp(s) + 1 > end) {
065eaa36 716 flog_warn(
e50f7cfd 717 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 718 "%s: Received invalid domain name len (hostname capability) from peer %s",
719 __FUNCTION__, peer->host);
720 return -1;
721 }
722
723 len = stream_getc(s);
724 if (stream_get_getp(s) + len > end) {
065eaa36 725 flog_warn(
e50f7cfd 726 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 727 "%s: Received runt domain name (hostname capability) from peer %s",
728 __FUNCTION__, peer->host);
729 return -1;
730 }
731
732 if (len > BGP_MAX_HOSTNAME) {
733 stream_get(str, s, BGP_MAX_HOSTNAME);
734 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
735 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
736 } else if (len)
737 stream_get(str, s, len);
738
739 if (len) {
740 str[len] = '\0';
741 peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
742 }
743
744 if (bgp_debug_neighbor_events(peer)) {
745 zlog_debug("%s received hostname %s, domainname %s", peer->host,
746 peer->hostname, peer->domainname);
747 }
748
749 return 0;
04b6bdc0
DW
750}
751
d62a17ae 752static const struct message capcode_str[] = {
753 {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
754 {CAPABILITY_CODE_REFRESH, "Route Refresh"},
755 {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
756 {CAPABILITY_CODE_RESTART, "Graceful Restart"},
757 {CAPABILITY_CODE_AS4, "4-octet AS number"},
758 {CAPABILITY_CODE_ADDPATH, "AddPath"},
759 {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
760 {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
761 {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
762 {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
763 {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
764 {CAPABILITY_CODE_FQDN, "FQDN"},
765 {0}};
6d58272b
PJ
766
767/* Minimum sizes for length field of each cap (so not inc. the header) */
d62a17ae 768static const size_t cap_minsizes[] = {
9d303b37
DL
769 [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
770 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
771 [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
772 [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
773 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
774 [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
775 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
776 [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
777 [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
778 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
779 [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
780 [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
6d58272b
PJ
781};
782
695ef95f
PJ
783/* value the capability must be a multiple of.
784 * 0-data capabilities won't be checked against this.
785 * Other capabilities whose data doesn't fall on convenient boundaries for this
786 * table should be set to 1.
787 */
d62a17ae 788static const size_t cap_modsizes[] = {
9d303b37
DL
789 [CAPABILITY_CODE_MP] = 4,
790 [CAPABILITY_CODE_REFRESH] = 1,
791 [CAPABILITY_CODE_ORF] = 1,
792 [CAPABILITY_CODE_RESTART] = 1,
793 [CAPABILITY_CODE_AS4] = 4,
794 [CAPABILITY_CODE_ADDPATH] = 4,
795 [CAPABILITY_CODE_DYNAMIC] = 1,
796 [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
797 [CAPABILITY_CODE_ENHE] = 6,
798 [CAPABILITY_CODE_REFRESH_OLD] = 1,
799 [CAPABILITY_CODE_ORF_OLD] = 1,
800 [CAPABILITY_CODE_FQDN] = 1,
695ef95f
PJ
801};
802
3b381c32
AS
803/**
804 * Parse given capability.
6d58272b 805 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
806 *
807 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
808 * capabilities were encountered.
6d58272b 809 */
d62a17ae 810static int bgp_capability_parse(struct peer *peer, size_t length,
d7c0a89a 811 int *mp_capability, uint8_t **error)
6d58272b 812{
d62a17ae 813 int ret;
814 struct stream *s = BGP_INPUT(peer);
815 size_t end = stream_get_getp(s) + length;
816
817 assert(STREAM_READABLE(s) >= length);
818
819 while (stream_get_getp(s) < end) {
820 size_t start;
d7c0a89a 821 uint8_t *sp = stream_pnt(s);
d62a17ae 822 struct capability_header caphdr;
823
824 ret = 0;
825 /* We need at least capability code and capability length. */
826 if (stream_get_getp(s) + 2 > end) {
827 zlog_info("%s Capability length error (< header)",
828 peer->host);
829 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
830 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
831 return -1;
832 }
833
834 caphdr.code = stream_getc(s);
835 caphdr.length = stream_getc(s);
836 start = stream_get_getp(s);
837
838 /* Capability length check sanity check. */
839 if (start + caphdr.length > end) {
840 zlog_info("%s Capability length error (< length)",
841 peer->host);
842 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
843 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
844 return -1;
845 }
846
847 if (bgp_debug_neighbor_events(peer))
848 zlog_debug("%s OPEN has %s capability (%u), length %u",
849 peer->host,
850 lookup_msg(capcode_str, caphdr.code, NULL),
851 caphdr.code, caphdr.length);
852
853 /* Length sanity check, type-specific, for known capabilities */
854 switch (caphdr.code) {
855 case CAPABILITY_CODE_MP:
856 case CAPABILITY_CODE_REFRESH:
857 case CAPABILITY_CODE_REFRESH_OLD:
858 case CAPABILITY_CODE_ORF:
859 case CAPABILITY_CODE_ORF_OLD:
860 case CAPABILITY_CODE_RESTART:
861 case CAPABILITY_CODE_AS4:
862 case CAPABILITY_CODE_ADDPATH:
863 case CAPABILITY_CODE_DYNAMIC:
864 case CAPABILITY_CODE_DYNAMIC_OLD:
865 case CAPABILITY_CODE_ENHE:
866 case CAPABILITY_CODE_FQDN:
867 /* Check length. */
868 if (caphdr.length < cap_minsizes[caphdr.code]) {
869 zlog_info(
870 "%s %s Capability length error: got %u,"
871 " expected at least %u",
872 peer->host,
873 lookup_msg(capcode_str, caphdr.code,
874 NULL),
875 caphdr.length,
876 (unsigned)cap_minsizes[caphdr.code]);
877 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
878 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
879 return -1;
880 }
881 if (caphdr.length
882 && caphdr.length % cap_modsizes[caphdr.code] != 0) {
883 zlog_info(
884 "%s %s Capability length error: got %u,"
885 " expected a multiple of %u",
886 peer->host,
887 lookup_msg(capcode_str, caphdr.code,
888 NULL),
889 caphdr.length,
890 (unsigned)cap_modsizes[caphdr.code]);
891 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
892 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
893 return -1;
894 }
895 /* we deliberately ignore unknown codes, see below */
896 default:
897 break;
898 }
899
900 switch (caphdr.code) {
901 case CAPABILITY_CODE_MP: {
902 *mp_capability = 1;
903
904 /* Ignore capability when override-capability is set. */
905 if (!CHECK_FLAG(peer->flags,
906 PEER_FLAG_OVERRIDE_CAPABILITY)) {
907 /* Set negotiated value. */
908 ret = bgp_capability_mp(peer, &caphdr);
909
910 /* Unsupported Capability. */
911 if (ret < 0) {
912 /* Store return data. */
913 memcpy(*error, sp, caphdr.length + 2);
914 *error += caphdr.length + 2;
915 }
916 ret = 0; /* Don't return error for this */
917 }
918 } break;
919 case CAPABILITY_CODE_REFRESH:
920 case CAPABILITY_CODE_REFRESH_OLD: {
921 /* BGP refresh capability */
922 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
923 SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV);
924 else
925 SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV);
926 } break;
927 case CAPABILITY_CODE_ORF:
928 case CAPABILITY_CODE_ORF_OLD:
929 ret = bgp_capability_orf_entry(peer, &caphdr);
930 break;
931 case CAPABILITY_CODE_RESTART:
932 ret = bgp_capability_restart(peer, &caphdr);
933 break;
934 case CAPABILITY_CODE_DYNAMIC:
935 case CAPABILITY_CODE_DYNAMIC_OLD:
936 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV);
937 break;
938 case CAPABILITY_CODE_AS4:
939 /* Already handled as a special-case parsing of the
940 * capabilities
941 * at the beginning of OPEN processing. So we care not a
942 * jot
943 * for the value really, only error case.
944 */
945 if (!bgp_capability_as4(peer, &caphdr))
946 ret = -1;
947 break;
948 case CAPABILITY_CODE_ADDPATH:
949 ret = bgp_capability_addpath(peer, &caphdr);
950 break;
951 case CAPABILITY_CODE_ENHE:
952 ret = bgp_capability_enhe(peer, &caphdr);
953 break;
954 case CAPABILITY_CODE_FQDN:
955 ret = bgp_capability_hostname(peer, &caphdr);
956 break;
957 default:
958 if (caphdr.code > 128) {
959 /* We don't send Notification for unknown vendor
960 specific
961 capabilities. It seems reasonable for now...
962 */
e50f7cfd 963 flog_warn(EC_BGP_CAPABILITY_VENDOR,
065eaa36 964 "%s Vendor specific capability %d",
d62a17ae 965 peer->host, caphdr.code);
966 } else {
065eaa36 967 flog_warn(
e50f7cfd 968 EC_BGP_CAPABILITY_UNKNOWN,
d62a17ae 969 "%s unrecognized capability code: %d - ignored",
970 peer->host, caphdr.code);
971 memcpy(*error, sp, caphdr.length + 2);
972 *error += caphdr.length + 2;
973 }
974 }
975
976 if (ret < 0) {
977 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
978 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
979 return -1;
980 }
981 if (stream_get_getp(s) != (start + caphdr.length)) {
982 if (stream_get_getp(s) > (start + caphdr.length))
065eaa36 983 flog_warn(
e50f7cfd 984 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 985 "%s Cap-parser for %s read past cap-length, %u!",
986 peer->host,
987 lookup_msg(capcode_str, caphdr.code,
988 NULL),
989 caphdr.length);
990 stream_set_getp(s, start + caphdr.length);
991 }
718e3744 992 }
d62a17ae 993 return 0;
718e3744 994}
995
d62a17ae 996static int bgp_auth_parse(struct peer *peer, size_t length)
718e3744 997{
d62a17ae 998 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
999 BGP_NOTIFY_OPEN_AUTH_FAILURE);
1000 return -1;
718e3744 1001}
1002
d62a17ae 1003static int strict_capability_same(struct peer *peer)
718e3744 1004{
d62a17ae 1005 int i, j;
718e3744 1006
d62a17ae 1007 for (i = AFI_IP; i < AFI_MAX; i++)
1008 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
1009 if (peer->afc[i][j] != peer->afc_nego[i][j])
1010 return 0;
1011 return 1;
718e3744 1012}
1013
0b2aa3a0
PJ
1014/* peek into option, stores ASN to *as4 if the AS4 capability was found.
1015 * Returns 0 if no as4 found, as4cap value otherwise.
1016 */
d7c0a89a 1017as_t peek_for_as4_capability(struct peer *peer, uint8_t length)
0b2aa3a0 1018{
d62a17ae 1019 struct stream *s = BGP_INPUT(peer);
1020 size_t orig_getp = stream_get_getp(s);
1021 size_t end = orig_getp + length;
1022 as_t as4 = 0;
1023
1024 if (BGP_DEBUG(as4, AS4))
1025 zlog_info(
1026 "%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
1027 " peeking for as4",
1028 peer->host, length);
1029 /* the error cases we DONT handle, we ONLY try to read as4 out of
1030 * correctly formatted options.
1031 */
1032 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1033 uint8_t opt_type;
1034 uint8_t opt_length;
d62a17ae 1035
1036 /* Check the length. */
1037 if (stream_get_getp(s) + 2 > end)
1038 goto end;
1039
1040 /* Fetch option type and length. */
1041 opt_type = stream_getc(s);
1042 opt_length = stream_getc(s);
1043
1044 /* Option length check. */
1045 if (stream_get_getp(s) + opt_length > end)
1046 goto end;
1047
1048 if (opt_type == BGP_OPEN_OPT_CAP) {
1049 unsigned long capd_start = stream_get_getp(s);
1050 unsigned long capd_end = capd_start + opt_length;
1051
1052 assert(capd_end <= end);
1053
1054 while (stream_get_getp(s) < capd_end) {
1055 struct capability_header hdr;
1056
1057 if (stream_get_getp(s) + 2 > capd_end)
1058 goto end;
1059
1060 hdr.code = stream_getc(s);
1061 hdr.length = stream_getc(s);
1062
1063 if ((stream_get_getp(s) + hdr.length)
1064 > capd_end)
1065 goto end;
1066
1067 if (hdr.code == CAPABILITY_CODE_AS4) {
1068 if (BGP_DEBUG(as4, AS4))
1069 zlog_info(
1070 "[AS4] found AS4 capability, about to parse");
1071 as4 = bgp_capability_as4(peer, &hdr);
1072
1073 goto end;
1074 }
1075 stream_forward_getp(s, hdr.length);
1076 }
1077 }
0b2aa3a0 1078 }
0b2aa3a0
PJ
1079
1080end:
d62a17ae 1081 stream_set_getp(s, orig_getp);
1082 return as4;
0b2aa3a0
PJ
1083}
1084
3b381c32
AS
1085/**
1086 * Parse open option.
1087 *
1088 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1089 */
d7c0a89a 1090int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability)
718e3744 1091{
d62a17ae 1092 int ret = 0;
d7c0a89a
QY
1093 uint8_t *error;
1094 uint8_t error_data[BGP_MAX_PACKET_SIZE];
d62a17ae 1095 struct stream *s = BGP_INPUT(peer);
1096 size_t end = stream_get_getp(s) + length;
1097
1098 error = error_data;
1099
1100 if (bgp_debug_neighbor_events(peer))
1101 zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1102 peer->host, length);
1103
1104 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1105 uint8_t opt_type;
1106 uint8_t opt_length;
d62a17ae 1107
1108 /* Must have at least an OPEN option header */
1109 if (STREAM_READABLE(s) < 2) {
1110 zlog_info("%s Option length error", peer->host);
1111 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1112 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1113 return -1;
1114 }
1115
1116 /* Fetch option type and length. */
1117 opt_type = stream_getc(s);
1118 opt_length = stream_getc(s);
1119
1120 /* Option length check. */
1121 if (STREAM_READABLE(s) < opt_length) {
1122 zlog_info("%s Option length error", peer->host);
1123 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1124 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1125 return -1;
1126 }
1127
1128 if (bgp_debug_neighbor_events(peer))
1129 zlog_debug(
1130 "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1131 peer->host, opt_type,
1132 opt_type == BGP_OPEN_OPT_AUTH
1133 ? "Authentication"
1134 : opt_type == BGP_OPEN_OPT_CAP
1135 ? "Capability"
1136 : "Unknown",
1137 opt_length);
1138
1139 switch (opt_type) {
1140 case BGP_OPEN_OPT_AUTH:
1141 ret = bgp_auth_parse(peer, opt_length);
1142 break;
1143 case BGP_OPEN_OPT_CAP:
1144 ret = bgp_capability_parse(peer, opt_length,
1145 mp_capability, &error);
1146 break;
1147 default:
1148 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1149 BGP_NOTIFY_OPEN_UNSUP_PARAM);
1150 ret = -1;
1151 break;
1152 }
1153
1154 /* Parse error. To accumulate all unsupported capability codes,
1155 bgp_capability_parse does not return -1 when encounter
1156 unsupported capability code. To detect that, please check
1157 error and erro_data pointer, like below. */
1158 if (ret < 0)
1159 return -1;
718e3744 1160 }
1161
d62a17ae 1162 /* All OPEN option is parsed. Check capability when strict compare
1163 flag is enabled.*/
1164 if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
1165 /* If Unsupported Capability exists. */
1166 if (error != error_data) {
1167 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1168 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1169 error_data,
1170 error - error_data);
1171 return -1;
1172 }
1173
1174 /* Check local capability does not negotiated with remote
1175 peer. */
1176 if (!strict_capability_same(peer)) {
1177 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1178 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1179 return -1;
1180 }
718e3744 1181 }
1182
d62a17ae 1183 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1184 error. */
1185 if (*mp_capability
1186 && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1187 if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1188 && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1189 && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1190 && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1191 && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
7c40bf39 1192 && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
d62a17ae 1193 && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1194 && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1195 && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1196 && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1197 && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
7c40bf39 1198 && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
d62a17ae 1199 && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
e50f7cfd 1200 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
1201 "%s [Error] Configured AFI/SAFIs do not "
1202 "overlap with received MP capabilities",
1203 peer->host);
d62a17ae 1204
1205 if (error != error_data)
1206 bgp_notify_send_with_data(
1207 peer, BGP_NOTIFY_OPEN_ERR,
1208 BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1209 error - error_data);
1210 else
1211 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1212 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1213 return -1;
1214 }
718e3744 1215 }
d62a17ae 1216 return 0;
718e3744 1217}
1218
d62a17ae 1219static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
d7c0a89a 1220 afi_t afi, safi_t safi, uint8_t code)
718e3744 1221{
d7c0a89a
QY
1222 uint8_t cap_len;
1223 uint8_t orf_len;
d62a17ae 1224 unsigned long capp;
1225 unsigned long orfp;
1226 unsigned long numberp;
1227 int number_of_orfs = 0;
1228 iana_afi_t pkt_afi;
5c525538 1229 iana_safi_t pkt_safi;
d62a17ae 1230
1231 /* Convert AFI, SAFI to values for packet. */
1232 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1233
1234 stream_putc(s, BGP_OPEN_OPT_CAP);
1235 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1236 stream_putc(s, 0); /* Capability Length */
1237 stream_putc(s, code); /* Capability Code */
1238 orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1239 stream_putc(s, 0); /* ORF Length */
1240 stream_putw(s, pkt_afi);
1241 stream_putc(s, 0);
1242 stream_putc(s, pkt_safi);
1243 numberp = stream_get_endp(s); /* Set Number Pointer */
1244 stream_putc(s, 0); /* Number of ORFs */
1245
1246 /* Address Prefix ORF */
1247 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1248 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1249 stream_putc(s, (code == CAPABILITY_CODE_ORF
1250 ? ORF_TYPE_PREFIX
1251 : ORF_TYPE_PREFIX_OLD));
1252
1253 if (CHECK_FLAG(peer->af_flags[afi][safi],
1254 PEER_FLAG_ORF_PREFIX_SM)
1255 && CHECK_FLAG(peer->af_flags[afi][safi],
1256 PEER_FLAG_ORF_PREFIX_RM)) {
1257 SET_FLAG(peer->af_cap[afi][safi],
1258 PEER_CAP_ORF_PREFIX_SM_ADV);
1259 SET_FLAG(peer->af_cap[afi][safi],
1260 PEER_CAP_ORF_PREFIX_RM_ADV);
1261 stream_putc(s, ORF_MODE_BOTH);
1262 } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1263 PEER_FLAG_ORF_PREFIX_SM)) {
1264 SET_FLAG(peer->af_cap[afi][safi],
1265 PEER_CAP_ORF_PREFIX_SM_ADV);
1266 stream_putc(s, ORF_MODE_SEND);
1267 } else {
1268 SET_FLAG(peer->af_cap[afi][safi],
1269 PEER_CAP_ORF_PREFIX_RM_ADV);
1270 stream_putc(s, ORF_MODE_RECEIVE);
1271 }
1272 number_of_orfs++;
718e3744 1273 }
718e3744 1274
d62a17ae 1275 /* Total Number of ORFs. */
1276 stream_putc_at(s, numberp, number_of_orfs);
718e3744 1277
d62a17ae 1278 /* Total ORF Len. */
1279 orf_len = stream_get_endp(s) - orfp - 1;
1280 stream_putc_at(s, orfp, orf_len);
718e3744 1281
d62a17ae 1282 /* Total Capability Len. */
1283 cap_len = stream_get_endp(s) - capp - 1;
1284 stream_putc_at(s, capp, cap_len);
718e3744 1285}
1286
1287/* Fill in capability open option to the packet. */
d62a17ae 1288void bgp_open_capability(struct stream *s, struct peer *peer)
718e3744 1289{
d7c0a89a 1290 uint8_t len;
d62a17ae 1291 unsigned long cp, capp, rcapp;
1292 iana_afi_t pkt_afi;
1293 afi_t afi;
5c525538
RW
1294 safi_t safi;
1295 iana_safi_t pkt_safi;
d62a17ae 1296 as_t local_as;
d7c0a89a
QY
1297 uint32_t restart_time;
1298 uint8_t afi_safi_count = 0;
d62a17ae 1299 int adv_addpath_tx = 0;
1300
1301 /* Remember current pointer for Opt Parm Len. */
1302 cp = stream_get_endp(s);
1303
1304 /* Opt Parm Len. */
1305 stream_putc(s, 0);
1306
1307 /* Do not send capability. */
1308 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1309 || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
1310 return;
1311
1312 /* MP capability for configured AFI, SAFI */
05c7a1cc
QY
1313 FOREACH_AFI_SAFI (afi, safi) {
1314 if (peer->afc[afi][safi]) {
1315 /* Convert AFI, SAFI to values for packet. */
1316 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1317 &pkt_safi);
1318
1319 peer->afc_adv[afi][safi] = 1;
1320 stream_putc(s, BGP_OPEN_OPT_CAP);
1321 stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
1322 stream_putc(s, CAPABILITY_CODE_MP);
1323 stream_putc(s, CAPABILITY_CODE_MP_LEN);
1324 stream_putw(s, pkt_afi);
1325 stream_putc(s, 0);
1326 stream_putc(s, pkt_safi);
1327
1328 /* Extended nexthop capability - currently
1329 * supporting RFC-5549 for
1330 * Link-Local peering only
1331 */
1332 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1333 && peer->su.sa.sa_family == AF_INET6
05c7a1cc
QY
1334 && afi == AFI_IP
1335 && (safi == SAFI_UNICAST
1336 || safi == SAFI_LABELED_UNICAST)) {
1337 /* RFC 5549 Extended Next Hop Encoding
1338 */
1339 SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
d62a17ae 1340 stream_putc(s, BGP_OPEN_OPT_CAP);
05c7a1cc
QY
1341 stream_putc(s, CAPABILITY_CODE_ENHE_LEN + 2);
1342 stream_putc(s, CAPABILITY_CODE_ENHE);
1343 stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1344
1345 SET_FLAG(peer->af_cap[AFI_IP][safi],
1346 PEER_CAP_ENHE_AF_ADV);
d62a17ae 1347 stream_putw(s, pkt_afi);
05c7a1cc
QY
1348 stream_putw(s, pkt_safi);
1349 stream_putw(s, afi_int2iana(AFI_IP6));
d62a17ae 1350
05c7a1cc
QY
1351 if (CHECK_FLAG(peer->af_cap[afi][safi],
1352 PEER_CAP_ENHE_AF_RCV))
1353 SET_FLAG(peer->af_cap[afi][safi],
1354 PEER_CAP_ENHE_AF_NEGO);
d62a17ae 1355 }
1356 }
05c7a1cc 1357 }
d62a17ae 1358
1359 /* Route refresh. */
1360 SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1361 stream_putc(s, BGP_OPEN_OPT_CAP);
1362 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1363 stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1364 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1365 stream_putc(s, BGP_OPEN_OPT_CAP);
1366 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1367 stream_putc(s, CAPABILITY_CODE_REFRESH);
1368 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1369
1370 /* AS4 */
1371 SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1372 stream_putc(s, BGP_OPEN_OPT_CAP);
1373 stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
1374 stream_putc(s, CAPABILITY_CODE_AS4);
1375 stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1376 if (peer->change_local_as)
1377 local_as = peer->change_local_as;
1378 else
1379 local_as = peer->local_as;
1380 stream_putl(s, local_as);
1381
1382 /* AddPath */
05c7a1cc
QY
1383 FOREACH_AFI_SAFI (afi, safi) {
1384 if (peer->afc[afi][safi]) {
1385 afi_safi_count++;
1386
1387 /* Only advertise addpath TX if a feature that
1388 * will use it is
1389 * configured */
dcc68b5e 1390 if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
05c7a1cc
QY
1391 adv_addpath_tx = 1;
1392 }
1393 }
d62a17ae 1394
1395 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1396 stream_putc(s, BGP_OPEN_OPT_CAP);
1397 stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1398 stream_putc(s, CAPABILITY_CODE_ADDPATH);
1399 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1400
05c7a1cc
QY
1401 FOREACH_AFI_SAFI (afi, safi) {
1402 if (peer->afc[afi][safi]) {
1403 /* Convert AFI, SAFI to values for packet. */
1404 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1405 &pkt_safi);
d62a17ae 1406
05c7a1cc
QY
1407 stream_putw(s, pkt_afi);
1408 stream_putc(s, pkt_safi);
d62a17ae 1409
05c7a1cc
QY
1410 if (adv_addpath_tx) {
1411 stream_putc(s, BGP_ADDPATH_RX | BGP_ADDPATH_TX);
1412 SET_FLAG(peer->af_cap[afi][safi],
1413 PEER_CAP_ADDPATH_AF_RX_ADV);
1414 SET_FLAG(peer->af_cap[afi][safi],
1415 PEER_CAP_ADDPATH_AF_TX_ADV);
1416 } else {
1417 stream_putc(s, BGP_ADDPATH_RX);
1418 SET_FLAG(peer->af_cap[afi][safi],
1419 PEER_CAP_ADDPATH_AF_RX_ADV);
1420 UNSET_FLAG(peer->af_cap[afi][safi],
1421 PEER_CAP_ADDPATH_AF_TX_ADV);
d62a17ae 1422 }
05c7a1cc
QY
1423 }
1424 }
d62a17ae 1425
1426 /* ORF capability. */
05c7a1cc
QY
1427 FOREACH_AFI_SAFI (afi, safi) {
1428 if (CHECK_FLAG(peer->af_flags[afi][safi],
1429 PEER_FLAG_ORF_PREFIX_SM)
1430 || CHECK_FLAG(peer->af_flags[afi][safi],
1431 PEER_FLAG_ORF_PREFIX_RM)) {
1432 bgp_open_capability_orf(s, peer, afi, safi,
1433 CAPABILITY_CODE_ORF_OLD);
1434 bgp_open_capability_orf(s, peer, afi, safi,
1435 CAPABILITY_CODE_ORF);
1436 }
1437 }
d62a17ae 1438
1439 /* Dynamic capability. */
1440 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1441 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1442 stream_putc(s, BGP_OPEN_OPT_CAP);
1443 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1444 stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1445 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1446 stream_putc(s, BGP_OPEN_OPT_CAP);
1447 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1448 stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1449 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
718e3744 1450 }
1451
d62a17ae 1452 /* Hostname capability */
6b3ee3a0 1453 if (cmd_hostname_get()) {
d62a17ae 1454 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1455 stream_putc(s, BGP_OPEN_OPT_CAP);
1456 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1457 stream_putc(s, 0); /* dummy len for now */
1458 stream_putc(s, CAPABILITY_CODE_FQDN);
1459 capp = stream_get_endp(s);
1460 stream_putc(s, 0); /* dummy len for now */
6b3ee3a0 1461 len = strlen(cmd_hostname_get());
d62a17ae 1462 if (len > BGP_MAX_HOSTNAME)
1463 len = BGP_MAX_HOSTNAME;
1464
1465 stream_putc(s, len);
6b3ee3a0
MK
1466 stream_put(s, cmd_hostname_get(), len);
1467 if (cmd_domainname_get()) {
1468 len = strlen(cmd_domainname_get());
d62a17ae 1469 if (len > BGP_MAX_HOSTNAME)
1470 len = BGP_MAX_HOSTNAME;
1471
1472 stream_putc(s, len);
6b3ee3a0 1473 stream_put(s, cmd_domainname_get(), len);
d62a17ae 1474 } else
d62a17ae 1475 stream_putc(s, 0); /* 0 length */
04b6bdc0 1476
d62a17ae 1477 /* Set the lengths straight */
1478 len = stream_get_endp(s) - rcapp - 1;
1479 stream_putc_at(s, rcapp, len);
1480 len = stream_get_endp(s) - capp - 1;
1481 stream_putc_at(s, capp, len);
04b6bdc0 1482
d62a17ae 1483 if (bgp_debug_neighbor_events(peer))
d62a17ae 1484 zlog_debug(
1485 "%s Sending hostname cap with hn = %s, dn = %s",
6b3ee3a0
MK
1486 peer->host, cmd_hostname_get(),
1487 cmd_domainname_get());
d62a17ae 1488 }
1489
1490 /* Sending base graceful-restart capability irrespective of the config
1491 */
1492 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1493 stream_putc(s, BGP_OPEN_OPT_CAP);
1494 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1495 stream_putc(s, 0); /* Capability Length */
1496 stream_putc(s, CAPABILITY_CODE_RESTART);
1497 rcapp = stream_get_endp(s); /* Set Restart Capability Len Pointer */
1498 stream_putc(s, 0);
1499 restart_time = peer->bgp->restart_time;
1500 if (peer->bgp->t_startup) {
1501 SET_FLAG(restart_time, RESTART_R_BIT);
1502 SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
1503 }
1504 stream_putw(s, restart_time);
1505
1506 /* Send address-family specific graceful-restart capability only when GR
1507 config
1508 is present */
1509 if (bgp_flag_check(peer->bgp, BGP_FLAG_GRACEFUL_RESTART)) {
05c7a1cc
QY
1510 FOREACH_AFI_SAFI (afi, safi) {
1511 if (peer->afc[afi][safi]) {
1512 /* Convert AFI, SAFI to values for
1513 * packet. */
1514 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1515 &pkt_safi);
1516 stream_putw(s, pkt_afi);
1517 stream_putc(s, pkt_safi);
1518 if (bgp_flag_check(peer->bgp,
1519 BGP_FLAG_GR_PRESERVE_FWD))
1520 stream_putc(s, RESTART_F_BIT);
1521 else
1522 stream_putc(s, 0);
1523 }
1524 }
d62a17ae 1525 }
1526
1527 /* Total Graceful restart capability Len. */
1528 len = stream_get_endp(s) - rcapp - 1;
1529 stream_putc_at(s, rcapp, len);
1530
1531 /* Total Capability Len. */
1532 len = stream_get_endp(s) - capp - 1;
1533 stream_putc_at(s, capp, len);
1534
1535 /* Total Opt Parm Len. */
1536 len = stream_get_endp(s) - cp - 1;
1537 stream_putc_at(s, cp, len);
718e3744 1538}