]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
tools: add source code string mangler
[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
770df5fd 661 || !(safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
d62a17ae 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",
15569c58 699 __func__, peer->host);
d62a17ae 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
e1b36e13
QY
713 XFREE(MTYPE_BGP_PEER_HOST, peer->hostname);
714 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
d62a17ae 715
716 peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
717 }
718
719 if (stream_get_getp(s) + 1 > end) {
065eaa36 720 flog_warn(
e50f7cfd 721 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 722 "%s: Received invalid domain name len (hostname capability) from peer %s",
15569c58 723 __func__, peer->host);
d62a17ae 724 return -1;
725 }
726
727 len = stream_getc(s);
728 if (stream_get_getp(s) + len > end) {
065eaa36 729 flog_warn(
e50f7cfd 730 EC_BGP_CAPABILITY_INVALID_DATA,
d62a17ae 731 "%s: Received runt domain name (hostname capability) from peer %s",
15569c58 732 __func__, peer->host);
d62a17ae 733 return -1;
734 }
735
736 if (len > BGP_MAX_HOSTNAME) {
737 stream_get(str, s, BGP_MAX_HOSTNAME);
738 stream_forward_getp(s, len - BGP_MAX_HOSTNAME);
739 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
740 } else if (len)
741 stream_get(str, s, len);
742
743 if (len) {
744 str[len] = '\0';
aba5353c 745
e1b36e13 746 XFREE(MTYPE_BGP_PEER_HOST, peer->domainname);
aba5353c 747
d62a17ae 748 peer->domainname = XSTRDUP(MTYPE_BGP_PEER_HOST, str);
749 }
750
751 if (bgp_debug_neighbor_events(peer)) {
752 zlog_debug("%s received hostname %s, domainname %s", peer->host,
753 peer->hostname, peer->domainname);
754 }
755
756 return 0;
04b6bdc0
DW
757}
758
d62a17ae 759static const struct message capcode_str[] = {
760 {CAPABILITY_CODE_MP, "MultiProtocol Extensions"},
761 {CAPABILITY_CODE_REFRESH, "Route Refresh"},
762 {CAPABILITY_CODE_ORF, "Cooperative Route Filtering"},
763 {CAPABILITY_CODE_RESTART, "Graceful Restart"},
764 {CAPABILITY_CODE_AS4, "4-octet AS number"},
765 {CAPABILITY_CODE_ADDPATH, "AddPath"},
766 {CAPABILITY_CODE_DYNAMIC, "Dynamic"},
767 {CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding"},
768 {CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)"},
769 {CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)"},
770 {CAPABILITY_CODE_ORF_OLD, "ORF (Old)"},
771 {CAPABILITY_CODE_FQDN, "FQDN"},
772 {0}};
6d58272b
PJ
773
774/* Minimum sizes for length field of each cap (so not inc. the header) */
d62a17ae 775static const size_t cap_minsizes[] = {
9d303b37
DL
776 [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN,
777 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
778 [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN,
779 [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN,
780 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
781 [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
782 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
783 [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
784 [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
785 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
786 [CAPABILITY_CODE_ORF_OLD] = CAPABILITY_CODE_ORF_LEN,
787 [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN,
6d58272b
PJ
788};
789
695ef95f
PJ
790/* value the capability must be a multiple of.
791 * 0-data capabilities won't be checked against this.
792 * Other capabilities whose data doesn't fall on convenient boundaries for this
793 * table should be set to 1.
794 */
d62a17ae 795static const size_t cap_modsizes[] = {
9d303b37
DL
796 [CAPABILITY_CODE_MP] = 4,
797 [CAPABILITY_CODE_REFRESH] = 1,
798 [CAPABILITY_CODE_ORF] = 1,
799 [CAPABILITY_CODE_RESTART] = 1,
800 [CAPABILITY_CODE_AS4] = 4,
801 [CAPABILITY_CODE_ADDPATH] = 4,
802 [CAPABILITY_CODE_DYNAMIC] = 1,
803 [CAPABILITY_CODE_DYNAMIC_OLD] = 1,
804 [CAPABILITY_CODE_ENHE] = 6,
805 [CAPABILITY_CODE_REFRESH_OLD] = 1,
806 [CAPABILITY_CODE_ORF_OLD] = 1,
807 [CAPABILITY_CODE_FQDN] = 1,
695ef95f
PJ
808};
809
3b381c32
AS
810/**
811 * Parse given capability.
6d58272b 812 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
813 *
814 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
815 * capabilities were encountered.
6d58272b 816 */
d62a17ae 817static int bgp_capability_parse(struct peer *peer, size_t length,
d7c0a89a 818 int *mp_capability, uint8_t **error)
6d58272b 819{
d62a17ae 820 int ret;
821 struct stream *s = BGP_INPUT(peer);
822 size_t end = stream_get_getp(s) + length;
34aa7448 823 uint16_t restart_flag_time = 0;
d62a17ae 824
825 assert(STREAM_READABLE(s) >= length);
826
827 while (stream_get_getp(s) < end) {
828 size_t start;
d7c0a89a 829 uint8_t *sp = stream_pnt(s);
d62a17ae 830 struct capability_header caphdr;
831
832 ret = 0;
833 /* We need at least capability code and capability length. */
834 if (stream_get_getp(s) + 2 > end) {
835 zlog_info("%s Capability length error (< header)",
836 peer->host);
837 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
838 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
839 return -1;
840 }
841
842 caphdr.code = stream_getc(s);
843 caphdr.length = stream_getc(s);
844 start = stream_get_getp(s);
845
846 /* Capability length check sanity check. */
847 if (start + caphdr.length > end) {
848 zlog_info("%s Capability length error (< length)",
849 peer->host);
850 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
851 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
852 return -1;
853 }
854
855 if (bgp_debug_neighbor_events(peer))
856 zlog_debug("%s OPEN has %s capability (%u), length %u",
857 peer->host,
858 lookup_msg(capcode_str, caphdr.code, NULL),
859 caphdr.code, caphdr.length);
860
861 /* Length sanity check, type-specific, for known capabilities */
862 switch (caphdr.code) {
863 case CAPABILITY_CODE_MP:
864 case CAPABILITY_CODE_REFRESH:
865 case CAPABILITY_CODE_REFRESH_OLD:
866 case CAPABILITY_CODE_ORF:
867 case CAPABILITY_CODE_ORF_OLD:
868 case CAPABILITY_CODE_RESTART:
869 case CAPABILITY_CODE_AS4:
870 case CAPABILITY_CODE_ADDPATH:
871 case CAPABILITY_CODE_DYNAMIC:
872 case CAPABILITY_CODE_DYNAMIC_OLD:
873 case CAPABILITY_CODE_ENHE:
874 case CAPABILITY_CODE_FQDN:
875 /* Check length. */
876 if (caphdr.length < cap_minsizes[caphdr.code]) {
877 zlog_info(
878 "%s %s Capability length error: got %u,"
879 " expected at least %u",
880 peer->host,
881 lookup_msg(capcode_str, caphdr.code,
882 NULL),
883 caphdr.length,
884 (unsigned)cap_minsizes[caphdr.code]);
885 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
886 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
887 return -1;
888 }
889 if (caphdr.length
890 && caphdr.length % cap_modsizes[caphdr.code] != 0) {
891 zlog_info(
892 "%s %s Capability length error: got %u,"
893 " expected a multiple of %u",
894 peer->host,
895 lookup_msg(capcode_str, caphdr.code,
896 NULL),
897 caphdr.length,
898 (unsigned)cap_modsizes[caphdr.code]);
899 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
900 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
901 return -1;
902 }
903 /* we deliberately ignore unknown codes, see below */
904 default:
905 break;
906 }
907
908 switch (caphdr.code) {
909 case CAPABILITY_CODE_MP: {
910 *mp_capability = 1;
911
912 /* Ignore capability when override-capability is set. */
913 if (!CHECK_FLAG(peer->flags,
914 PEER_FLAG_OVERRIDE_CAPABILITY)) {
915 /* Set negotiated value. */
916 ret = bgp_capability_mp(peer, &caphdr);
917
918 /* Unsupported Capability. */
919 if (ret < 0) {
920 /* Store return data. */
921 memcpy(*error, sp, caphdr.length + 2);
922 *error += caphdr.length + 2;
923 }
924 ret = 0; /* Don't return error for this */
925 }
926 } break;
927 case CAPABILITY_CODE_REFRESH:
928 case CAPABILITY_CODE_REFRESH_OLD: {
929 /* BGP refresh capability */
930 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
931 SET_FLAG(peer->cap, PEER_CAP_REFRESH_OLD_RCV);
932 else
933 SET_FLAG(peer->cap, PEER_CAP_REFRESH_NEW_RCV);
934 } break;
935 case CAPABILITY_CODE_ORF:
936 case CAPABILITY_CODE_ORF_OLD:
937 ret = bgp_capability_orf_entry(peer, &caphdr);
938 break;
939 case CAPABILITY_CODE_RESTART:
940 ret = bgp_capability_restart(peer, &caphdr);
941 break;
942 case CAPABILITY_CODE_DYNAMIC:
943 case CAPABILITY_CODE_DYNAMIC_OLD:
944 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV);
945 break;
946 case CAPABILITY_CODE_AS4:
947 /* Already handled as a special-case parsing of the
948 * capabilities
949 * at the beginning of OPEN processing. So we care not a
950 * jot
951 * for the value really, only error case.
952 */
953 if (!bgp_capability_as4(peer, &caphdr))
954 ret = -1;
955 break;
956 case CAPABILITY_CODE_ADDPATH:
957 ret = bgp_capability_addpath(peer, &caphdr);
958 break;
959 case CAPABILITY_CODE_ENHE:
960 ret = bgp_capability_enhe(peer, &caphdr);
961 break;
962 case CAPABILITY_CODE_FQDN:
963 ret = bgp_capability_hostname(peer, &caphdr);
964 break;
965 default:
966 if (caphdr.code > 128) {
967 /* We don't send Notification for unknown vendor
968 specific
969 capabilities. It seems reasonable for now...
970 */
e50f7cfd 971 flog_warn(EC_BGP_CAPABILITY_VENDOR,
065eaa36 972 "%s Vendor specific capability %d",
d62a17ae 973 peer->host, caphdr.code);
974 } else {
065eaa36 975 flog_warn(
e50f7cfd 976 EC_BGP_CAPABILITY_UNKNOWN,
d62a17ae 977 "%s unrecognized capability code: %d - ignored",
978 peer->host, caphdr.code);
979 memcpy(*error, sp, caphdr.length + 2);
980 *error += caphdr.length + 2;
981 }
982 }
983
984 if (ret < 0) {
985 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
986 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
987 return -1;
988 }
989 if (stream_get_getp(s) != (start + caphdr.length)) {
990 if (stream_get_getp(s) > (start + caphdr.length))
065eaa36 991 flog_warn(
e50f7cfd 992 EC_BGP_CAPABILITY_INVALID_LENGTH,
d62a17ae 993 "%s Cap-parser for %s read past cap-length, %u!",
994 peer->host,
995 lookup_msg(capcode_str, caphdr.code,
996 NULL),
997 caphdr.length);
998 stream_set_getp(s, start + caphdr.length);
999 }
34aa7448 1000
1001 if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
1002 UNSET_FLAG(restart_flag_time, 0xF000);
1003 peer->v_gr_restart = restart_flag_time;
1004 }
718e3744 1005 }
d62a17ae 1006 return 0;
718e3744 1007}
1008
d62a17ae 1009static int bgp_auth_parse(struct peer *peer, size_t length)
718e3744 1010{
d62a17ae 1011 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1012 BGP_NOTIFY_OPEN_AUTH_FAILURE);
1013 return -1;
718e3744 1014}
1015
3dc339cd 1016static bool strict_capability_same(struct peer *peer)
718e3744 1017{
d62a17ae 1018 int i, j;
718e3744 1019
d62a17ae 1020 for (i = AFI_IP; i < AFI_MAX; i++)
1021 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
1022 if (peer->afc[i][j] != peer->afc_nego[i][j])
3dc339cd
DA
1023 return false;
1024 return true;
718e3744 1025}
1026
0b2aa3a0
PJ
1027/* peek into option, stores ASN to *as4 if the AS4 capability was found.
1028 * Returns 0 if no as4 found, as4cap value otherwise.
1029 */
d7c0a89a 1030as_t peek_for_as4_capability(struct peer *peer, uint8_t length)
0b2aa3a0 1031{
d62a17ae 1032 struct stream *s = BGP_INPUT(peer);
1033 size_t orig_getp = stream_get_getp(s);
1034 size_t end = orig_getp + length;
1035 as_t as4 = 0;
1036
1037 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1038 zlog_debug(
d62a17ae 1039 "%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
1040 " peeking for as4",
1041 peer->host, length);
1042 /* the error cases we DONT handle, we ONLY try to read as4 out of
1043 * correctly formatted options.
1044 */
1045 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1046 uint8_t opt_type;
1047 uint8_t opt_length;
d62a17ae 1048
1049 /* Check the length. */
1050 if (stream_get_getp(s) + 2 > end)
1051 goto end;
1052
1053 /* Fetch option type and length. */
1054 opt_type = stream_getc(s);
1055 opt_length = stream_getc(s);
1056
1057 /* Option length check. */
1058 if (stream_get_getp(s) + opt_length > end)
1059 goto end;
1060
1061 if (opt_type == BGP_OPEN_OPT_CAP) {
1062 unsigned long capd_start = stream_get_getp(s);
1063 unsigned long capd_end = capd_start + opt_length;
1064
1065 assert(capd_end <= end);
1066
1067 while (stream_get_getp(s) < capd_end) {
1068 struct capability_header hdr;
1069
1070 if (stream_get_getp(s) + 2 > capd_end)
1071 goto end;
1072
1073 hdr.code = stream_getc(s);
1074 hdr.length = stream_getc(s);
1075
1076 if ((stream_get_getp(s) + hdr.length)
1077 > capd_end)
1078 goto end;
1079
1080 if (hdr.code == CAPABILITY_CODE_AS4) {
1081 if (BGP_DEBUG(as4, AS4))
4cb5e18b 1082 zlog_debug(
d62a17ae 1083 "[AS4] found AS4 capability, about to parse");
1084 as4 = bgp_capability_as4(peer, &hdr);
1085
1086 goto end;
1087 }
1088 stream_forward_getp(s, hdr.length);
1089 }
1090 }
0b2aa3a0 1091 }
0b2aa3a0
PJ
1092
1093end:
d62a17ae 1094 stream_set_getp(s, orig_getp);
1095 return as4;
0b2aa3a0
PJ
1096}
1097
3b381c32
AS
1098/**
1099 * Parse open option.
1100 *
1101 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
1102 */
d7c0a89a 1103int bgp_open_option_parse(struct peer *peer, uint8_t length, int *mp_capability)
718e3744 1104{
d62a17ae 1105 int ret = 0;
d7c0a89a
QY
1106 uint8_t *error;
1107 uint8_t error_data[BGP_MAX_PACKET_SIZE];
d62a17ae 1108 struct stream *s = BGP_INPUT(peer);
1109 size_t end = stream_get_getp(s) + length;
1110
1111 error = error_data;
1112
1113 if (bgp_debug_neighbor_events(peer))
1114 zlog_debug("%s rcv OPEN w/ OPTION parameter len: %u",
1115 peer->host, length);
1116
1117 while (stream_get_getp(s) < end) {
d7c0a89a
QY
1118 uint8_t opt_type;
1119 uint8_t opt_length;
d62a17ae 1120
1121 /* Must have at least an OPEN option header */
1122 if (STREAM_READABLE(s) < 2) {
1123 zlog_info("%s Option length error", peer->host);
1124 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1125 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1126 return -1;
1127 }
1128
1129 /* Fetch option type and length. */
1130 opt_type = stream_getc(s);
1131 opt_length = stream_getc(s);
1132
1133 /* Option length check. */
1134 if (STREAM_READABLE(s) < opt_length) {
1135 zlog_info("%s Option length error", peer->host);
1136 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1137 BGP_NOTIFY_OPEN_MALFORMED_ATTR);
1138 return -1;
1139 }
1140
1141 if (bgp_debug_neighbor_events(peer))
1142 zlog_debug(
1143 "%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
1144 peer->host, opt_type,
1145 opt_type == BGP_OPEN_OPT_AUTH
1146 ? "Authentication"
1147 : opt_type == BGP_OPEN_OPT_CAP
1148 ? "Capability"
1149 : "Unknown",
1150 opt_length);
1151
1152 switch (opt_type) {
1153 case BGP_OPEN_OPT_AUTH:
1154 ret = bgp_auth_parse(peer, opt_length);
1155 break;
1156 case BGP_OPEN_OPT_CAP:
1157 ret = bgp_capability_parse(peer, opt_length,
1158 mp_capability, &error);
1159 break;
1160 default:
1161 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1162 BGP_NOTIFY_OPEN_UNSUP_PARAM);
1163 ret = -1;
1164 break;
1165 }
1166
1167 /* Parse error. To accumulate all unsupported capability codes,
1168 bgp_capability_parse does not return -1 when encounter
1169 unsupported capability code. To detect that, please check
1170 error and erro_data pointer, like below. */
1171 if (ret < 0)
1172 return -1;
718e3744 1173 }
1174
d62a17ae 1175 /* All OPEN option is parsed. Check capability when strict compare
1176 flag is enabled.*/
1177 if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_CAP_MATCH)) {
1178 /* If Unsupported Capability exists. */
1179 if (error != error_data) {
1180 bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
1181 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1182 error_data,
1183 error - error_data);
1184 return -1;
1185 }
1186
1187 /* Check local capability does not negotiated with remote
1188 peer. */
1189 if (!strict_capability_same(peer)) {
1190 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1191 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1192 return -1;
1193 }
718e3744 1194 }
1195
d62a17ae 1196 /* Check there are no common AFI/SAFIs and send Unsupported Capability
1197 error. */
1198 if (*mp_capability
1199 && !CHECK_FLAG(peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY)) {
1200 if (!peer->afc_nego[AFI_IP][SAFI_UNICAST]
1201 && !peer->afc_nego[AFI_IP][SAFI_MULTICAST]
1202 && !peer->afc_nego[AFI_IP][SAFI_LABELED_UNICAST]
1203 && !peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
1204 && !peer->afc_nego[AFI_IP][SAFI_ENCAP]
7c40bf39 1205 && !peer->afc_nego[AFI_IP][SAFI_FLOWSPEC]
d62a17ae 1206 && !peer->afc_nego[AFI_IP6][SAFI_UNICAST]
1207 && !peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
1208 && !peer->afc_nego[AFI_IP6][SAFI_LABELED_UNICAST]
1209 && !peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN]
1210 && !peer->afc_nego[AFI_IP6][SAFI_ENCAP]
7c40bf39 1211 && !peer->afc_nego[AFI_IP6][SAFI_FLOWSPEC]
d62a17ae 1212 && !peer->afc_nego[AFI_L2VPN][SAFI_EVPN]) {
e50f7cfd 1213 flog_err(EC_BGP_PKT_OPEN,
1c50c1c0
QY
1214 "%s [Error] Configured AFI/SAFIs do not "
1215 "overlap with received MP capabilities",
1216 peer->host);
d62a17ae 1217
1218 if (error != error_data)
1219 bgp_notify_send_with_data(
1220 peer, BGP_NOTIFY_OPEN_ERR,
1221 BGP_NOTIFY_OPEN_UNSUP_CAPBL, error_data,
1222 error - error_data);
1223 else
1224 bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
1225 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1226 return -1;
1227 }
718e3744 1228 }
d62a17ae 1229 return 0;
718e3744 1230}
1231
d62a17ae 1232static void bgp_open_capability_orf(struct stream *s, struct peer *peer,
d7c0a89a 1233 afi_t afi, safi_t safi, uint8_t code)
718e3744 1234{
d7c0a89a
QY
1235 uint8_t cap_len;
1236 uint8_t orf_len;
d62a17ae 1237 unsigned long capp;
1238 unsigned long orfp;
1239 unsigned long numberp;
1240 int number_of_orfs = 0;
1241 iana_afi_t pkt_afi;
5c525538 1242 iana_safi_t pkt_safi;
d62a17ae 1243
1244 /* Convert AFI, SAFI to values for packet. */
1245 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi, &pkt_safi);
1246
1247 stream_putc(s, BGP_OPEN_OPT_CAP);
1248 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1249 stream_putc(s, 0); /* Capability Length */
1250 stream_putc(s, code); /* Capability Code */
1251 orfp = stream_get_endp(s); /* Set ORF Len Pointer */
1252 stream_putc(s, 0); /* ORF Length */
1253 stream_putw(s, pkt_afi);
1254 stream_putc(s, 0);
1255 stream_putc(s, pkt_safi);
1256 numberp = stream_get_endp(s); /* Set Number Pointer */
1257 stream_putc(s, 0); /* Number of ORFs */
1258
1259 /* Address Prefix ORF */
1260 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1261 || CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM)) {
1262 stream_putc(s, (code == CAPABILITY_CODE_ORF
1263 ? ORF_TYPE_PREFIX
1264 : ORF_TYPE_PREFIX_OLD));
1265
1266 if (CHECK_FLAG(peer->af_flags[afi][safi],
1267 PEER_FLAG_ORF_PREFIX_SM)
1268 && CHECK_FLAG(peer->af_flags[afi][safi],
1269 PEER_FLAG_ORF_PREFIX_RM)) {
1270 SET_FLAG(peer->af_cap[afi][safi],
1271 PEER_CAP_ORF_PREFIX_SM_ADV);
1272 SET_FLAG(peer->af_cap[afi][safi],
1273 PEER_CAP_ORF_PREFIX_RM_ADV);
1274 stream_putc(s, ORF_MODE_BOTH);
1275 } else if (CHECK_FLAG(peer->af_flags[afi][safi],
1276 PEER_FLAG_ORF_PREFIX_SM)) {
1277 SET_FLAG(peer->af_cap[afi][safi],
1278 PEER_CAP_ORF_PREFIX_SM_ADV);
1279 stream_putc(s, ORF_MODE_SEND);
1280 } else {
1281 SET_FLAG(peer->af_cap[afi][safi],
1282 PEER_CAP_ORF_PREFIX_RM_ADV);
1283 stream_putc(s, ORF_MODE_RECEIVE);
1284 }
1285 number_of_orfs++;
718e3744 1286 }
718e3744 1287
d62a17ae 1288 /* Total Number of ORFs. */
1289 stream_putc_at(s, numberp, number_of_orfs);
718e3744 1290
d62a17ae 1291 /* Total ORF Len. */
1292 orf_len = stream_get_endp(s) - orfp - 1;
1293 stream_putc_at(s, orfp, orf_len);
718e3744 1294
d62a17ae 1295 /* Total Capability Len. */
1296 cap_len = stream_get_endp(s) - capp - 1;
1297 stream_putc_at(s, capp, cap_len);
718e3744 1298}
1299
034e185d 1300static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer,
36235319 1301 unsigned long cp)
034e185d 1302{
1303 int len;
1304 iana_afi_t pkt_afi;
1305 afi_t afi;
1306 safi_t safi;
1307 iana_safi_t pkt_safi;
1308 uint32_t restart_time;
1309 unsigned long capp = 0;
1310 unsigned long rcapp = 0;
1311
13909c4f
DS
1312 if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)
1313 && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER))
1314 return;
1315
1316 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1317 zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :",
1318 peer->host);
1319
1320 SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV);
1321 stream_putc(s, BGP_OPEN_OPT_CAP);
1322 capp = stream_get_endp(s); /* Set Capability Len Pointer */
1323 stream_putc(s, 0); /* Capability Length */
1324 stream_putc(s, CAPABILITY_CODE_RESTART);
1325 /* Set Restart Capability Len Pointer */
1326 rcapp = stream_get_endp(s);
1327 stream_putc(s, 0);
1328 restart_time = peer->bgp->restart_time;
1329 if (peer->bgp->t_startup) {
1330 SET_FLAG(restart_time, RESTART_R_BIT);
1331 SET_FLAG(peer->cap, PEER_CAP_RESTART_BIT_ADV);
034e185d 1332
1333 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
13909c4f
DS
1334 zlog_debug("[BGP_GR] Sending R-Bit for Peer :%s :",
1335 peer->host);
1336 }
1337
1338 stream_putw(s, restart_time);
1339
1340 /* Send address-family specific graceful-restart capability
1341 * only when GR config is present
1342 */
1343 if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) {
892fedb6 1344 if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)
13909c4f
DS
1345 && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1346 zlog_debug("[BGP_GR] F bit Set");
1347
1348 FOREACH_AFI_SAFI (afi, safi) {
1349 if (!peer->afc[afi][safi])
1350 continue;
0f0444fb 1351
1352 if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
1353 zlog_debug(
13909c4f
DS
1354 "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:",
1355 afi, safi);
034e185d 1356
13909c4f
DS
1357 /* Convert AFI, SAFI to values for
1358 * packet.
1359 */
1360 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1361 &pkt_safi);
1362 stream_putw(s, pkt_afi);
1363 stream_putc(s, pkt_safi);
892fedb6
DA
1364 if (CHECK_FLAG(peer->bgp->flags,
1365 BGP_FLAG_GR_PRESERVE_FWD))
13909c4f
DS
1366 stream_putc(s, RESTART_F_BIT);
1367 else
1368 stream_putc(s, 0);
034e185d 1369 }
034e185d 1370 }
13909c4f
DS
1371
1372 /* Total Graceful restart capability Len. */
1373 len = stream_get_endp(s) - rcapp - 1;
1374 stream_putc_at(s, rcapp, len);
1375
1376 /* Total Capability Len. */
1377 len = stream_get_endp(s) - capp - 1;
1378 stream_putc_at(s, capp, len);
034e185d 1379}
1380
718e3744 1381/* Fill in capability open option to the packet. */
d62a17ae 1382void bgp_open_capability(struct stream *s, struct peer *peer)
718e3744 1383{
d7c0a89a 1384 uint8_t len;
d62a17ae 1385 unsigned long cp, capp, rcapp;
1386 iana_afi_t pkt_afi;
1387 afi_t afi;
5c525538
RW
1388 safi_t safi;
1389 iana_safi_t pkt_safi;
d62a17ae 1390 as_t local_as;
d7c0a89a 1391 uint8_t afi_safi_count = 0;
d62a17ae 1392 int adv_addpath_tx = 0;
1393
1394 /* Remember current pointer for Opt Parm Len. */
1395 cp = stream_get_endp(s);
1396
1397 /* Opt Parm Len. */
1398 stream_putc(s, 0);
1399
1400 /* Do not send capability. */
1401 if (!CHECK_FLAG(peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1402 || CHECK_FLAG(peer->flags, PEER_FLAG_DONT_CAPABILITY))
1403 return;
1404
1405 /* MP capability for configured AFI, SAFI */
05c7a1cc
QY
1406 FOREACH_AFI_SAFI (afi, safi) {
1407 if (peer->afc[afi][safi]) {
1408 /* Convert AFI, SAFI to values for packet. */
1409 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1410 &pkt_safi);
1411
1412 peer->afc_adv[afi][safi] = 1;
1413 stream_putc(s, BGP_OPEN_OPT_CAP);
1414 stream_putc(s, CAPABILITY_CODE_MP_LEN + 2);
1415 stream_putc(s, CAPABILITY_CODE_MP);
1416 stream_putc(s, CAPABILITY_CODE_MP_LEN);
1417 stream_putw(s, pkt_afi);
1418 stream_putc(s, 0);
1419 stream_putc(s, pkt_safi);
1420
1421 /* Extended nexthop capability - currently
1422 * supporting RFC-5549 for
1423 * Link-Local peering only
1424 */
1425 if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE)
1426 && peer->su.sa.sa_family == AF_INET6
05c7a1cc 1427 && afi == AFI_IP
770df5fd 1428 && (safi == SAFI_UNICAST || safi == SAFI_MPLS_VPN
05c7a1cc
QY
1429 || safi == SAFI_LABELED_UNICAST)) {
1430 /* RFC 5549 Extended Next Hop Encoding
1431 */
1432 SET_FLAG(peer->cap, PEER_CAP_ENHE_ADV);
d62a17ae 1433 stream_putc(s, BGP_OPEN_OPT_CAP);
05c7a1cc
QY
1434 stream_putc(s, CAPABILITY_CODE_ENHE_LEN + 2);
1435 stream_putc(s, CAPABILITY_CODE_ENHE);
1436 stream_putc(s, CAPABILITY_CODE_ENHE_LEN);
1437
1438 SET_FLAG(peer->af_cap[AFI_IP][safi],
1439 PEER_CAP_ENHE_AF_ADV);
d62a17ae 1440 stream_putw(s, pkt_afi);
05c7a1cc
QY
1441 stream_putw(s, pkt_safi);
1442 stream_putw(s, afi_int2iana(AFI_IP6));
d62a17ae 1443
05c7a1cc
QY
1444 if (CHECK_FLAG(peer->af_cap[afi][safi],
1445 PEER_CAP_ENHE_AF_RCV))
1446 SET_FLAG(peer->af_cap[afi][safi],
1447 PEER_CAP_ENHE_AF_NEGO);
d62a17ae 1448 }
1449 }
05c7a1cc 1450 }
d62a17ae 1451
1452 /* Route refresh. */
1453 SET_FLAG(peer->cap, PEER_CAP_REFRESH_ADV);
1454 stream_putc(s, BGP_OPEN_OPT_CAP);
1455 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1456 stream_putc(s, CAPABILITY_CODE_REFRESH_OLD);
1457 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1458 stream_putc(s, BGP_OPEN_OPT_CAP);
1459 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN + 2);
1460 stream_putc(s, CAPABILITY_CODE_REFRESH);
1461 stream_putc(s, CAPABILITY_CODE_REFRESH_LEN);
1462
1463 /* AS4 */
1464 SET_FLAG(peer->cap, PEER_CAP_AS4_ADV);
1465 stream_putc(s, BGP_OPEN_OPT_CAP);
1466 stream_putc(s, CAPABILITY_CODE_AS4_LEN + 2);
1467 stream_putc(s, CAPABILITY_CODE_AS4);
1468 stream_putc(s, CAPABILITY_CODE_AS4_LEN);
1469 if (peer->change_local_as)
1470 local_as = peer->change_local_as;
1471 else
1472 local_as = peer->local_as;
1473 stream_putl(s, local_as);
1474
1475 /* AddPath */
05c7a1cc
QY
1476 FOREACH_AFI_SAFI (afi, safi) {
1477 if (peer->afc[afi][safi]) {
1478 afi_safi_count++;
1479
1480 /* Only advertise addpath TX if a feature that
1481 * will use it is
1482 * configured */
dcc68b5e 1483 if (peer->addpath_type[afi][safi] != BGP_ADDPATH_NONE)
05c7a1cc
QY
1484 adv_addpath_tx = 1;
1485 }
1486 }
d62a17ae 1487
1488 SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV);
1489 stream_putc(s, BGP_OPEN_OPT_CAP);
1490 stream_putc(s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1491 stream_putc(s, CAPABILITY_CODE_ADDPATH);
1492 stream_putc(s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1493
05c7a1cc
QY
1494 FOREACH_AFI_SAFI (afi, safi) {
1495 if (peer->afc[afi][safi]) {
1496 /* Convert AFI, SAFI to values for packet. */
1497 bgp_map_afi_safi_int2iana(afi, safi, &pkt_afi,
1498 &pkt_safi);
d62a17ae 1499
05c7a1cc
QY
1500 stream_putw(s, pkt_afi);
1501 stream_putc(s, pkt_safi);
d62a17ae 1502
05c7a1cc
QY
1503 if (adv_addpath_tx) {
1504 stream_putc(s, BGP_ADDPATH_RX | BGP_ADDPATH_TX);
1505 SET_FLAG(peer->af_cap[afi][safi],
1506 PEER_CAP_ADDPATH_AF_RX_ADV);
1507 SET_FLAG(peer->af_cap[afi][safi],
1508 PEER_CAP_ADDPATH_AF_TX_ADV);
1509 } else {
1510 stream_putc(s, BGP_ADDPATH_RX);
1511 SET_FLAG(peer->af_cap[afi][safi],
1512 PEER_CAP_ADDPATH_AF_RX_ADV);
1513 UNSET_FLAG(peer->af_cap[afi][safi],
1514 PEER_CAP_ADDPATH_AF_TX_ADV);
d62a17ae 1515 }
05c7a1cc
QY
1516 }
1517 }
d62a17ae 1518
1519 /* ORF capability. */
05c7a1cc
QY
1520 FOREACH_AFI_SAFI (afi, safi) {
1521 if (CHECK_FLAG(peer->af_flags[afi][safi],
1522 PEER_FLAG_ORF_PREFIX_SM)
1523 || CHECK_FLAG(peer->af_flags[afi][safi],
1524 PEER_FLAG_ORF_PREFIX_RM)) {
1525 bgp_open_capability_orf(s, peer, afi, safi,
1526 CAPABILITY_CODE_ORF_OLD);
1527 bgp_open_capability_orf(s, peer, afi, safi,
1528 CAPABILITY_CODE_ORF);
1529 }
1530 }
d62a17ae 1531
1532 /* Dynamic capability. */
1533 if (CHECK_FLAG(peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) {
1534 SET_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV);
1535 stream_putc(s, BGP_OPEN_OPT_CAP);
1536 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1537 stream_putc(s, CAPABILITY_CODE_DYNAMIC_OLD);
1538 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
1539 stream_putc(s, BGP_OPEN_OPT_CAP);
1540 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1541 stream_putc(s, CAPABILITY_CODE_DYNAMIC);
1542 stream_putc(s, CAPABILITY_CODE_DYNAMIC_LEN);
718e3744 1543 }
1544
d62a17ae 1545 /* Hostname capability */
6b3ee3a0 1546 if (cmd_hostname_get()) {
d62a17ae 1547 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1548 stream_putc(s, BGP_OPEN_OPT_CAP);
1549 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1550 stream_putc(s, 0); /* dummy len for now */
1551 stream_putc(s, CAPABILITY_CODE_FQDN);
1552 capp = stream_get_endp(s);
1553 stream_putc(s, 0); /* dummy len for now */
6b3ee3a0 1554 len = strlen(cmd_hostname_get());
d62a17ae 1555 if (len > BGP_MAX_HOSTNAME)
1556 len = BGP_MAX_HOSTNAME;
1557
1558 stream_putc(s, len);
6b3ee3a0
MK
1559 stream_put(s, cmd_hostname_get(), len);
1560 if (cmd_domainname_get()) {
1561 len = strlen(cmd_domainname_get());
d62a17ae 1562 if (len > BGP_MAX_HOSTNAME)
1563 len = BGP_MAX_HOSTNAME;
1564
1565 stream_putc(s, len);
6b3ee3a0 1566 stream_put(s, cmd_domainname_get(), len);
d62a17ae 1567 } else
d62a17ae 1568 stream_putc(s, 0); /* 0 length */
04b6bdc0 1569
d62a17ae 1570 /* Set the lengths straight */
1571 len = stream_get_endp(s) - rcapp - 1;
1572 stream_putc_at(s, rcapp, len);
1573 len = stream_get_endp(s) - capp - 1;
1574 stream_putc_at(s, capp, len);
04b6bdc0 1575
d62a17ae 1576 if (bgp_debug_neighbor_events(peer))
d62a17ae 1577 zlog_debug(
1578 "%s Sending hostname cap with hn = %s, dn = %s",
6b3ee3a0
MK
1579 peer->host, cmd_hostname_get(),
1580 cmd_domainname_get());
d62a17ae 1581 }
1582
034e185d 1583 bgp_peer_send_gr_capability(s, peer, cp);
d62a17ae 1584
1585 /* Total Opt Parm Len. */
1586 len = stream_get_endp(s) - cp - 1;
1587 stream_putc_at(s, cp, len);
718e3744 1588}