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