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