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