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