]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
BGP: add addpath RX support
[mirror_frr.git] / bgpd / bgp_open.c
CommitLineData
718e3744 1/* BGP open message handling
2 Copyright (C) 1998, 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
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"
718e3744 30
31#include "bgpd/bgpd.h"
32#include "bgpd/bgp_attr.h"
33#include "bgpd/bgp_debug.h"
34#include "bgpd/bgp_fsm.h"
35#include "bgpd/bgp_packet.h"
36#include "bgpd/bgp_open.h"
0b2aa3a0 37#include "bgpd/bgp_aspath.h"
538621f2 38#include "bgpd/bgp_vty.h"
39
718e3744 40/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
41 negotiate remote peer supports extentions or not. But if
42 remote-peer doesn't supports negotiation process itself. We would
43 like to do manual configuration.
44
45 So there is many configurable point. First of all we want set each
46 peer whether we send capability negotiation to the peer or not.
47 Next, if we send capability to the peer we want to set my capabilty
48 inforation at each peer. */
49
50void
51bgp_capability_vty_out (struct vty *vty, struct peer *peer)
52{
5228ad27 53 char *pnt;
54 char *end;
6d58272b
PJ
55 struct capability_mp_data mpc;
56 struct capability_header *hdr;
718e3744 57
58 pnt = peer->notify.data;
59 end = pnt + peer->notify.length;
6d58272b 60
718e3744 61 while (pnt < end)
62 {
6d58272b 63 if (pnt + sizeof (struct capability_mp_data) + 2 > end)
718e3744 64 return;
6d58272b
PJ
65
66 hdr = (struct capability_header *)pnt;
67 if (pnt + hdr->length + 2 > end)
718e3744 68 return;
69
6d58272b
PJ
70 memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
71
72 if (hdr->code == CAPABILITY_CODE_MP)
718e3744 73 {
74 vty_out (vty, " Capability error for: Multi protocol ");
75
6d58272b 76 switch (ntohs (mpc.afi))
718e3744 77 {
78 case AFI_IP:
79 vty_out (vty, "AFI IPv4, ");
80 break;
81 case AFI_IP6:
82 vty_out (vty, "AFI IPv6, ");
83 break;
84 default:
6d58272b 85 vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
718e3744 86 break;
87 }
6d58272b 88 switch (mpc.safi)
718e3744 89 {
90 case SAFI_UNICAST:
91 vty_out (vty, "SAFI Unicast");
92 break;
93 case SAFI_MULTICAST:
94 vty_out (vty, "SAFI Multicast");
95 break;
42e6d745
DO
96 case SAFI_MPLS_LABELED_VPN:
97 vty_out (vty, "SAFI MPLS-labeled VPN");
718e3744 98 break;
99 default:
6d58272b 100 vty_out (vty, "SAFI Unknown %d ", mpc.safi);
718e3744 101 break;
102 }
103 vty_out (vty, "%s", VTY_NEWLINE);
104 }
6d58272b 105 else if (hdr->code >= 128)
718e3744 106 vty_out (vty, " Capability error: vendor specific capability code %d",
6d58272b 107 hdr->code);
718e3744 108 else
109 vty_out (vty, " Capability error: unknown capability code %d",
6d58272b 110 hdr->code);
718e3744 111
6d58272b 112 pnt += hdr->length + 2;
718e3744 113 }
114}
115
6d58272b
PJ
116static void
117bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
718e3744 118{
6d58272b
PJ
119 mpc->afi = stream_getw (s);
120 mpc->reserved = stream_getc (s);
121 mpc->safi = stream_getc (s);
122}
718e3744 123
6d58272b
PJ
124int
125bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
126{
6d58272b 127 switch (afi)
718e3744 128 {
6d58272b
PJ
129 case AFI_IP:
130#ifdef HAVE_IPV6
131 case AFI_IP6:
132#endif
133 switch (*safi)
134 {
42e6d745
DO
135 /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */
136 case SAFI_MPLS_LABELED_VPN:
6d58272b
PJ
137 *safi = SAFI_MPLS_VPN;
138 case SAFI_UNICAST:
139 case SAFI_MULTICAST:
140 case SAFI_MPLS_VPN:
141 return 1;
142 }
718e3744 143 }
6d58272b
PJ
144 zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
145
146 return 0;
147}
148
149/* Set negotiated capability value. */
150static int
151bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
152{
153 struct capability_mp_data mpc;
154 struct stream *s = BGP_INPUT (peer);
155
156 bgp_capability_mp_data (s, &mpc);
157
16286195 158 if (bgp_debug_neighbor_events(peer->host))
6d58272b
PJ
159 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
160 peer->host, mpc.afi, mpc.safi);
161
162 if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
163 return -1;
164
165 /* Now safi remapped, and afi/safi are valid array indices */
166 peer->afc_recv[mpc.afi][mpc.safi] = 1;
167
168 if (peer->afc[mpc.afi][mpc.safi])
e08286bc 169 peer->afc_nego[mpc.afi][mpc.safi] = 1;
6d58272b
PJ
170 else
171 return -1;
718e3744 172
173 return 0;
174}
175
94f2b392 176static void
718e3744 177bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
178 u_char type, u_char mode)
179{
16286195 180 if (bgp_debug_neighbor_events(peer))
8325cd7f 181 zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
718e3744 182 peer->host, afi, safi, type, mode);
183}
184
8f5abac1 185static const struct message orf_type_str[] =
6d58272b
PJ
186{
187 { ORF_TYPE_PREFIX, "Prefixlist" },
188 { ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
189};
837d16cc 190static const int orf_type_str_max = array_size(orf_type_str);
6d58272b 191
8f5abac1 192static const struct message orf_mode_str[] =
6d58272b
PJ
193{
194 { ORF_MODE_RECEIVE, "Receive" },
195 { ORF_MODE_SEND, "Send" },
196 { ORF_MODE_BOTH, "Both" },
197};
837d16cc 198static const int orf_mode_str_max = array_size(orf_mode_str);
6d58272b 199
94f2b392 200static int
6d58272b 201bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
718e3744 202{
6d58272b
PJ
203 struct stream *s = BGP_INPUT (peer);
204 struct capability_orf_entry entry;
205 afi_t afi;
206 safi_t safi;
718e3744 207 u_char type;
208 u_char mode;
209 u_int16_t sm_cap = 0; /* capability send-mode receive */
210 u_int16_t rm_cap = 0; /* capability receive-mode receive */
211 int i;
212
6d58272b
PJ
213 /* ORF Entry header */
214 bgp_capability_mp_data (s, &entry.mpc);
215 entry.num = stream_getc (s);
216 afi = entry.mpc.afi;
217 safi = entry.mpc.safi;
218
16286195 219 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
220 zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
221 peer->host, entry.mpc.afi, entry.mpc.safi);
718e3744 222
223 /* Check AFI and SAFI. */
6d58272b
PJ
224 if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
225 {
226 zlog_info ("%s Addr-family %d/%d not supported."
227 " Ignoring the ORF capability",
228 peer->host, entry.mpc.afi, entry.mpc.safi);
229 return 0;
230 }
231
232 /* validate number field */
5e728e92 233 if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
718e3744 234 {
6d58272b
PJ
235 zlog_info ("%s ORF Capability entry length error,"
236 " Cap length %u, num %u",
237 peer->host, hdr->length, entry.num);
238 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
718e3744 239 return -1;
240 }
241
6d58272b 242 for (i = 0 ; i < entry.num ; i++)
718e3744 243 {
6d58272b
PJ
244 type = stream_getc(s);
245 mode = stream_getc(s);
246
718e3744 247 /* ORF Mode error check */
6d58272b
PJ
248 switch (mode)
249 {
250 case ORF_MODE_BOTH:
251 case ORF_MODE_SEND:
252 case ORF_MODE_RECEIVE:
253 break;
254 default:
255 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
256 continue;
718e3744 257 }
6d58272b
PJ
258 /* ORF Type and afi/safi error checks */
259 /* capcode versus type */
260 switch (hdr->code)
261 {
262 case CAPABILITY_CODE_ORF:
263 switch (type)
264 {
265 case ORF_TYPE_PREFIX:
266 break;
267 default:
268 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
269 continue;
270 }
271 break;
272 case CAPABILITY_CODE_ORF_OLD:
273 switch (type)
274 {
275 case ORF_TYPE_PREFIX_OLD:
276 break;
277 default:
278 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
279 continue;
280 }
281 break;
282 default:
283 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
284 continue;
285 }
286
287 /* AFI vs SAFI */
288 if (!((afi == AFI_IP && safi == SAFI_UNICAST)
289 || (afi == AFI_IP && safi == SAFI_MULTICAST)
290 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
291 {
292 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
293 continue;
294 }
295
16286195 296 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
297 zlog_debug ("%s OPEN has %s ORF capability"
298 " as %s for afi/safi: %d/%d",
299 peer->host, LOOKUP (orf_type_str, type),
300 LOOKUP (orf_mode_str, mode),
301 entry.mpc.afi, safi);
718e3744 302
6d58272b 303 if (hdr->code == CAPABILITY_CODE_ORF)
718e3744 304 {
6d58272b
PJ
305 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
306 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
718e3744 307 }
6d58272b 308 else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
718e3744 309 {
6d58272b
PJ
310 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
311 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
718e3744 312 }
313 else
314 {
315 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
316 continue;
317 }
318
319 switch (mode)
320 {
321 case ORF_MODE_BOTH:
322 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
323 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
324 break;
325 case ORF_MODE_SEND:
326 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
327 break;
328 case ORF_MODE_RECEIVE:
329 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
330 break;
331 }
332 }
333 return 0;
334}
335
6d58272b
PJ
336static int
337bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
338{
339 struct stream *s = BGP_INPUT (peer);
340 u_int16_t restart_flag_time;
341 int restart_bit = 0;
342 size_t end = stream_get_getp (s) + caphdr->length;
343
344 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
345 restart_flag_time = stream_getw(s);
346 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
fe7d2a48
DS
347 {
348 SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV);
349 restart_bit = 1;
350 }
6d58272b
PJ
351 UNSET_FLAG (restart_flag_time, 0xF000);
352 peer->v_gr_restart = restart_flag_time;
718e3744 353
16286195 354 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
355 {
356 zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
357 zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
358 peer->host, restart_bit ? " " : " not ",
359 peer->v_gr_restart);
360 }
718e3744 361
21cc7694 362 while (stream_get_getp (s) + 4 <= end)
6d58272b
PJ
363 {
364 afi_t afi = stream_getw (s);
365 safi_t safi = stream_getc (s);
366 u_char flag = stream_getc (s);
367
368 if (!bgp_afi_safi_valid_indices (afi, &safi))
369 {
16286195 370 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
371 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
372 " Ignore the Graceful Restart capability",
373 peer->host, afi, safi);
374 }
375 else if (!peer->afc[afi][safi])
376 {
16286195 377 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
378 zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
379 " Ignore the Graceful Restart capability",
380 peer->host, afi, safi);
381 }
382 else
383 {
16286195 384 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
385 zlog_debug ("%s Address family %s is%spreserved", peer->host,
386 afi_safi_print (afi, safi),
387 CHECK_FLAG (peer->af_cap[afi][safi],
388 PEER_CAP_RESTART_AF_PRESERVE_RCV)
389 ? " " : " not ");
390
391 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
392 if (CHECK_FLAG (flag, RESTART_F_BIT))
393 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
394
395 }
396 }
397 return 0;
398}
718e3744 399
0b2aa3a0
PJ
400static as_t
401bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
402{
5861739f
PJ
403 SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
404
405 if (hdr->length != CAPABILITY_CODE_AS4_LEN)
406 {
407 zlog_err ("%s AS4 capability has incorrect data length %d",
408 peer->host, hdr->length);
409 return 0;
410 }
411
0b2aa3a0
PJ
412 as_t as4 = stream_getl (BGP_INPUT(peer));
413
414 if (BGP_DEBUG (as4, AS4))
415 zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
416 peer->host, as4);
0b2aa3a0
PJ
417 return as4;
418}
419
a82478b9
DS
420static int
421bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
422{
423 struct stream *s = BGP_INPUT (peer);
424 size_t end = stream_get_getp (s) + hdr->length;
425
426 SET_FLAG (peer->cap, PEER_CAP_ADDPATH_RCV);
427
428 while (stream_get_getp (s) + 4 <= end)
429 {
430 afi_t afi = stream_getw (s);
431 safi_t safi = stream_getc (s);
432 u_char send_receive = stream_getc (s);
433
434 if (bgp_debug_neighbor_events(peer->host))
435 zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
436 peer->host, afi, safi,
437 (send_receive & BGP_ADDPATH_RX) ? ", receive" : "",
438 (send_receive & BGP_ADDPATH_TX) ? ", transmit" : "");
439
440 if (!bgp_afi_safi_valid_indices (afi, &safi))
441 return -1;
442
443 if (send_receive & BGP_ADDPATH_RX)
444 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV);
445
446 if (send_receive & BGP_ADDPATH_TX)
447 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV);
448 }
449
450 return 0;
451}
452
fc52f953 453static const struct message capcode_str[] =
6d58272b 454{
6d58272b
PJ
455 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
456 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
457 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
458 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
459 { CAPABILITY_CODE_AS4, "4-octet AS number" },
a82478b9 460 { CAPABILITY_CODE_ADDPATH, "AddPath" },
6d58272b
PJ
461 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
462 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
463 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
464};
837d16cc 465static const int capcode_str_max = array_size(capcode_str);
6d58272b
PJ
466
467/* Minimum sizes for length field of each cap (so not inc. the header) */
fc52f953 468static const size_t cap_minsizes[] =
6d58272b
PJ
469{
470 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
471 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
472 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
370b64a2 473 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
6d58272b 474 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
a82478b9 475 [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
6d58272b
PJ
476 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
477 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
478 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
479};
480
3b381c32
AS
481/**
482 * Parse given capability.
6d58272b 483 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
484 *
485 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
486 * capabilities were encountered.
6d58272b
PJ
487 */
488static int
3b381c32
AS
489bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
490 u_char **error)
6d58272b
PJ
491{
492 int ret;
493 struct stream *s = BGP_INPUT (peer);
494 size_t end = stream_get_getp (s) + length;
495
496 assert (STREAM_READABLE (s) >= length);
497
498 while (stream_get_getp (s) < end)
499 {
500 size_t start;
501 u_char *sp = stream_pnt (s);
502 struct capability_header caphdr;
503
718e3744 504 /* We need at least capability code and capability length. */
6d58272b 505 if (stream_get_getp(s) + 2 > end)
718e3744 506 {
6d58272b 507 zlog_info ("%s Capability length error (< header)", peer->host);
718e3744 508 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
509 return -1;
510 }
6d58272b
PJ
511
512 caphdr.code = stream_getc (s);
513 caphdr.length = stream_getc (s);
514 start = stream_get_getp (s);
515
516 /* Capability length check sanity check. */
517 if (start + caphdr.length > end)
718e3744 518 {
6d58272b 519 zlog_info ("%s Capability length error (< length)", peer->host);
718e3744 520 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
521 return -1;
522 }
6d58272b 523
16286195 524 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
525 zlog_debug ("%s OPEN has %s capability (%u), length %u",
526 peer->host,
527 LOOKUP (capcode_str, caphdr.code),
528 caphdr.code, caphdr.length);
529
530 /* Length sanity check, type-specific, for known capabilities */
531 switch (caphdr.code)
532 {
533 case CAPABILITY_CODE_MP:
534 case CAPABILITY_CODE_REFRESH:
535 case CAPABILITY_CODE_REFRESH_OLD:
536 case CAPABILITY_CODE_ORF:
537 case CAPABILITY_CODE_ORF_OLD:
538 case CAPABILITY_CODE_RESTART:
0b2aa3a0 539 case CAPABILITY_CODE_AS4:
a82478b9 540 case CAPABILITY_CODE_ADDPATH:
6d58272b
PJ
541 case CAPABILITY_CODE_DYNAMIC:
542 /* Check length. */
543 if (caphdr.length < cap_minsizes[caphdr.code])
544 {
545 zlog_info ("%s %s Capability length error: got %u,"
546 " expected at least %u",
547 peer->host,
548 LOOKUP (capcode_str, caphdr.code),
fc52f953
SH
549 caphdr.length,
550 (unsigned) cap_minsizes[caphdr.code]);
6d58272b
PJ
551 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
552 return -1;
553 }
554 /* we deliberately ignore unknown codes, see below */
555 default:
556 break;
557 }
558
559 switch (caphdr.code)
560 {
561 case CAPABILITY_CODE_MP:
562 {
3b381c32
AS
563 *mp_capability = 1;
564
6d58272b
PJ
565 /* Ignore capability when override-capability is set. */
566 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
567 {
568 /* Set negotiated value. */
569 ret = bgp_capability_mp (peer, &caphdr);
570
571 /* Unsupported Capability. */
572 if (ret < 0)
573 {
574 /* Store return data. */
575 memcpy (*error, sp, caphdr.length + 2);
576 *error += caphdr.length + 2;
577 }
578 }
579 }
580 break;
581 case CAPABILITY_CODE_REFRESH:
582 case CAPABILITY_CODE_REFRESH_OLD:
583 {
584 /* BGP refresh capability */
585 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
586 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
587 else
588 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
589 }
590 break;
591 case CAPABILITY_CODE_ORF:
592 case CAPABILITY_CODE_ORF_OLD:
fe9bb645 593 if (bgp_capability_orf_entry (peer, &caphdr))
6d58272b
PJ
594 return -1;
595 break;
596 case CAPABILITY_CODE_RESTART:
597 if (bgp_capability_restart (peer, &caphdr))
598 return -1;
599 break;
600 case CAPABILITY_CODE_DYNAMIC:
601 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
602 break;
0b2aa3a0
PJ
603 case CAPABILITY_CODE_AS4:
604 /* Already handled as a special-case parsing of the capabilities
605 * at the beginning of OPEN processing. So we care not a jot
606 * for the value really, only error case.
607 */
608 if (!bgp_capability_as4 (peer, &caphdr))
609 return -1;
610 break;
a82478b9
DS
611 case CAPABILITY_CODE_ADDPATH:
612 if (bgp_capability_addpath (peer, &caphdr))
613 return -1;
614 break;
6d58272b
PJ
615 default:
616 if (caphdr.code > 128)
617 {
618 /* We don't send Notification for unknown vendor specific
619 capabilities. It seems reasonable for now... */
620 zlog_warn ("%s Vendor specific capability %d",
621 peer->host, caphdr.code);
622 }
623 else
624 {
625 zlog_warn ("%s unrecognized capability code: %d - ignored",
626 peer->host, caphdr.code);
627 memcpy (*error, sp, caphdr.length + 2);
628 *error += caphdr.length + 2;
629 }
630 }
631 if (stream_get_getp(s) != (start + caphdr.length))
632 {
633 if (stream_get_getp(s) > (start + caphdr.length))
634 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
635 peer->host, LOOKUP (capcode_str, caphdr.code),
636 caphdr.length);
637 stream_set_getp (s, start + caphdr.length);
638 }
718e3744 639 }
640 return 0;
641}
642
94f2b392 643static int
6d58272b 644bgp_auth_parse (struct peer *peer, size_t length)
718e3744 645{
646 bgp_notify_send (peer,
647 BGP_NOTIFY_OPEN_ERR,
648 BGP_NOTIFY_OPEN_AUTH_FAILURE);
649 return -1;
650}
651
94f2b392 652static int
718e3744 653strict_capability_same (struct peer *peer)
654{
655 int i, j;
656
657 for (i = AFI_IP; i < AFI_MAX; i++)
658 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
659 if (peer->afc[i][j] != peer->afc_nego[i][j])
660 return 0;
661 return 1;
662}
663
0b2aa3a0
PJ
664/* peek into option, stores ASN to *as4 if the AS4 capability was found.
665 * Returns 0 if no as4 found, as4cap value otherwise.
666 */
667as_t
668peek_for_as4_capability (struct peer *peer, u_char length)
669{
670 struct stream *s = BGP_INPUT (peer);
671 size_t orig_getp = stream_get_getp (s);
672 size_t end = orig_getp + length;
673 as_t as4 = 0;
674
675 /* The full capability parser will better flag the error.. */
676 if (STREAM_READABLE(s) < length)
677 return 0;
678
679 if (BGP_DEBUG (as4, AS4))
680 zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
681 " peeking for as4",
682 peer->host, length);
683 /* the error cases we DONT handle, we ONLY try to read as4 out of
684 * correctly formatted options.
685 */
686 while (stream_get_getp(s) < end)
687 {
688 u_char opt_type;
689 u_char opt_length;
690
691 /* Check the length. */
692 if (stream_get_getp (s) + 2 > end)
693 goto end;
694
695 /* Fetch option type and length. */
696 opt_type = stream_getc (s);
697 opt_length = stream_getc (s);
698
699 /* Option length check. */
700 if (stream_get_getp (s) + opt_length > end)
701 goto end;
702
703 if (opt_type == BGP_OPEN_OPT_CAP)
704 {
705 unsigned long capd_start = stream_get_getp (s);
706 unsigned long capd_end = capd_start + opt_length;
707
708 assert (capd_end <= end);
709
710 while (stream_get_getp (s) < capd_end)
711 {
712 struct capability_header hdr;
713
714 if (stream_get_getp (s) + 2 > capd_end)
715 goto end;
716
717 hdr.code = stream_getc (s);
718 hdr.length = stream_getc (s);
719
720 if ((stream_get_getp(s) + hdr.length) > capd_end)
721 goto end;
722
723 if (hdr.code == CAPABILITY_CODE_AS4)
724 {
0b2aa3a0
PJ
725 if (BGP_DEBUG (as4, AS4))
726 zlog_info ("[AS4] found AS4 capability, about to parse");
727 as4 = bgp_capability_as4 (peer, &hdr);
728
729 goto end;
730 }
731 stream_forward_getp (s, hdr.length);
732 }
733 }
734 }
735
736end:
737 stream_set_getp (s, orig_getp);
738 return as4;
739}
740
3b381c32
AS
741/**
742 * Parse open option.
743 *
744 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
745 */
718e3744 746int
3b381c32 747bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
718e3744 748{
749 int ret;
718e3744 750 u_char *error;
751 u_char error_data[BGP_MAX_PACKET_SIZE];
6d58272b
PJ
752 struct stream *s = BGP_INPUT(peer);
753 size_t end = stream_get_getp (s) + length;
718e3744 754
755 ret = 0;
718e3744 756 error = error_data;
757
16286195 758 if (bgp_debug_neighbor_events(peer))
8325cd7f 759 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
718e3744 760 peer->host, length);
761
6d58272b 762 while (stream_get_getp(s) < end)
718e3744 763 {
6d58272b
PJ
764 u_char opt_type;
765 u_char opt_length;
766
767 /* Must have at least an OPEN option header */
768 if (STREAM_READABLE(s) < 2)
718e3744 769 {
770 zlog_info ("%s Option length error", peer->host);
771 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
772 return -1;
773 }
774
775 /* Fetch option type and length. */
6d58272b
PJ
776 opt_type = stream_getc (s);
777 opt_length = stream_getc (s);
718e3744 778
779 /* Option length check. */
6d58272b 780 if (STREAM_READABLE (s) < opt_length)
718e3744 781 {
782 zlog_info ("%s Option length error", peer->host);
783 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
784 return -1;
785 }
786
16286195 787 if (bgp_debug_neighbor_events(peer))
8325cd7f 788 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
718e3744 789 peer->host, opt_type,
790 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
791 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
792 opt_length);
793
794 switch (opt_type)
795 {
796 case BGP_OPEN_OPT_AUTH:
6d58272b 797 ret = bgp_auth_parse (peer, opt_length);
718e3744 798 break;
799 case BGP_OPEN_OPT_CAP:
3b381c32 800 ret = bgp_capability_parse (peer, opt_length, mp_capability, &error);
718e3744 801 break;
802 default:
803 bgp_notify_send (peer,
804 BGP_NOTIFY_OPEN_ERR,
805 BGP_NOTIFY_OPEN_UNSUP_PARAM);
806 ret = -1;
807 break;
808 }
809
810 /* Parse error. To accumulate all unsupported capability codes,
811 bgp_capability_parse does not return -1 when encounter
812 unsupported capability code. To detect that, please check
813 error and erro_data pointer, like below. */
814 if (ret < 0)
815 return -1;
718e3744 816 }
817
818 /* All OPEN option is parsed. Check capability when strict compare
819 flag is enabled.*/
820 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
821 {
822 /* If Unsupported Capability exists. */
823 if (error != error_data)
824 {
825 bgp_notify_send_with_data (peer,
826 BGP_NOTIFY_OPEN_ERR,
827 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
828 error_data, error - error_data);
829 return -1;
830 }
831
832 /* Check local capability does not negotiated with remote
833 peer. */
834 if (! strict_capability_same (peer))
835 {
836 bgp_notify_send (peer,
837 BGP_NOTIFY_OPEN_ERR,
838 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
839 return -1;
840 }
841 }
842
3b381c32 843 /* Check there are no common AFI/SAFIs and send Unsupported Capability
718e3744 844 error. */
3b381c32
AS
845 if (*mp_capability &&
846 ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
718e3744 847 {
848 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
849 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
850 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
851 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
852 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
853 {
16286195 854 zlog_err ("%s [Error] Configured AFI/SAFIs do not "
3b381c32
AS
855 "overlap with received MP capabilities",
856 peer->host);
718e3744 857
858 if (error != error_data)
718e3744 859 bgp_notify_send_with_data (peer,
860 BGP_NOTIFY_OPEN_ERR,
861 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
862 error_data, error - error_data);
863 else
864 bgp_notify_send (peer,
865 BGP_NOTIFY_OPEN_ERR,
866 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
867 return -1;
868 }
869 }
870 return 0;
871}
872
94f2b392 873static void
718e3744 874bgp_open_capability_orf (struct stream *s, struct peer *peer,
875 afi_t afi, safi_t safi, u_char code)
876{
877 u_char cap_len;
878 u_char orf_len;
879 unsigned long capp;
880 unsigned long orfp;
881 unsigned long numberp;
882 int number_of_orfs = 0;
883
884 if (safi == SAFI_MPLS_VPN)
42e6d745 885 safi = SAFI_MPLS_LABELED_VPN;
718e3744 886
887 stream_putc (s, BGP_OPEN_OPT_CAP);
9985f83c 888 capp = stream_get_endp (s); /* Set Capability Len Pointer */
718e3744 889 stream_putc (s, 0); /* Capability Length */
890 stream_putc (s, code); /* Capability Code */
9985f83c 891 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
718e3744 892 stream_putc (s, 0); /* ORF Length */
893 stream_putw (s, afi);
894 stream_putc (s, 0);
895 stream_putc (s, safi);
9985f83c 896 numberp = stream_get_endp (s); /* Set Number Pointer */
718e3744 897 stream_putc (s, 0); /* Number of ORFs */
898
899 /* Address Prefix ORF */
900 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
901 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
902 {
903 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
904 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
905
906 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
907 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
908 {
909 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
910 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
911 stream_putc (s, ORF_MODE_BOTH);
912 }
913 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
914 {
915 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
916 stream_putc (s, ORF_MODE_SEND);
917 }
918 else
919 {
920 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
921 stream_putc (s, ORF_MODE_RECEIVE);
922 }
923 number_of_orfs++;
924 }
925
926 /* Total Number of ORFs. */
927 stream_putc_at (s, numberp, number_of_orfs);
928
929 /* Total ORF Len. */
9985f83c 930 orf_len = stream_get_endp (s) - orfp - 1;
718e3744 931 stream_putc_at (s, orfp, orf_len);
932
933 /* Total Capability Len. */
9985f83c 934 cap_len = stream_get_endp (s) - capp - 1;
718e3744 935 stream_putc_at (s, capp, cap_len);
936}
937
938/* Fill in capability open option to the packet. */
939void
940bgp_open_capability (struct stream *s, struct peer *peer)
941{
942 u_char len;
fe7d2a48 943 unsigned long cp, capp, rcapp;
718e3744 944 afi_t afi;
945 safi_t safi;
0b2aa3a0 946 as_t local_as;
fe7d2a48 947 u_int32_t restart_time;
a82478b9 948 u_char afi_safi_count = 0;
718e3744 949
950 /* Remember current pointer for Opt Parm Len. */
9985f83c 951 cp = stream_get_endp (s);
718e3744 952
953 /* Opt Parm Len. */
954 stream_putc (s, 0);
955
956 /* Do not send capability. */
957 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
958 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
959 return;
960
718e3744 961 /* IPv4 unicast. */
962 if (peer->afc[AFI_IP][SAFI_UNICAST])
963 {
964 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
965 stream_putc (s, BGP_OPEN_OPT_CAP);
966 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
967 stream_putc (s, CAPABILITY_CODE_MP);
968 stream_putc (s, CAPABILITY_CODE_MP_LEN);
969 stream_putw (s, AFI_IP);
970 stream_putc (s, 0);
971 stream_putc (s, SAFI_UNICAST);
972 }
973 /* IPv4 multicast. */
974 if (peer->afc[AFI_IP][SAFI_MULTICAST])
975 {
976 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
977 stream_putc (s, BGP_OPEN_OPT_CAP);
978 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
979 stream_putc (s, CAPABILITY_CODE_MP);
980 stream_putc (s, CAPABILITY_CODE_MP_LEN);
981 stream_putw (s, AFI_IP);
982 stream_putc (s, 0);
983 stream_putc (s, SAFI_MULTICAST);
984 }
985 /* IPv4 VPN */
986 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
987 {
988 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
989 stream_putc (s, BGP_OPEN_OPT_CAP);
990 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
991 stream_putc (s, CAPABILITY_CODE_MP);
992 stream_putc (s, CAPABILITY_CODE_MP_LEN);
993 stream_putw (s, AFI_IP);
994 stream_putc (s, 0);
42e6d745 995 stream_putc (s, SAFI_MPLS_LABELED_VPN);
718e3744 996 }
997#ifdef HAVE_IPV6
998 /* IPv6 unicast. */
999 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1000 {
1001 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
1002 stream_putc (s, BGP_OPEN_OPT_CAP);
1003 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1004 stream_putc (s, CAPABILITY_CODE_MP);
1005 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1006 stream_putw (s, AFI_IP6);
1007 stream_putc (s, 0);
1008 stream_putc (s, SAFI_UNICAST);
1009 }
1010 /* IPv6 multicast. */
1011 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1012 {
1013 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
1014 stream_putc (s, BGP_OPEN_OPT_CAP);
1015 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1016 stream_putc (s, CAPABILITY_CODE_MP);
1017 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1018 stream_putw (s, AFI_IP6);
1019 stream_putc (s, 0);
1020 stream_putc (s, SAFI_MULTICAST);
1021 }
1022#endif /* HAVE_IPV6 */
1023
1024 /* Route refresh. */
c9502438 1025 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
1026 stream_putc (s, BGP_OPEN_OPT_CAP);
1027 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1028 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1029 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1030 stream_putc (s, BGP_OPEN_OPT_CAP);
1031 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1032 stream_putc (s, CAPABILITY_CODE_REFRESH);
1033 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
718e3744 1034
0b2aa3a0
PJ
1035 /* AS4 */
1036 SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1037 stream_putc (s, BGP_OPEN_OPT_CAP);
1038 stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1039 stream_putc (s, CAPABILITY_CODE_AS4);
1040 stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1041 if ( peer->change_local_as )
1042 local_as = peer->change_local_as;
1043 else
1044 local_as = peer->local_as;
1045 stream_putl (s, local_as );
1046
a82478b9
DS
1047 /* AddPath
1048 * For now we will only advertise RX support. TX support will be added later.
1049 */
1050 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1051 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1052 if (peer->afc[afi][safi])
1053 afi_safi_count++;
1054
1055 SET_FLAG (peer->cap, PEER_CAP_ADDPATH_ADV);
1056 stream_putc (s, BGP_OPEN_OPT_CAP);
1057 stream_putc (s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1058 stream_putc (s, CAPABILITY_CODE_ADDPATH);
1059 stream_putc (s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1060
1061 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1062 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1063 if (peer->afc[afi][safi])
1064 {
1065 stream_putw (s, afi);
1066 stream_putc (s, safi);
1067 stream_putc (s, BGP_ADDPATH_RX);
1068 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV);
1069 }
1070
718e3744 1071 /* ORF capability. */
1072 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1073 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1074 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1075 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1076 {
1077 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1078 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1079 }
1080
1081 /* Dynamic capability. */
1082 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1083 {
1084 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1085 stream_putc (s, BGP_OPEN_OPT_CAP);
1086 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1087 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1088 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1089 }
1090
fe7d2a48
DS
1091 /* Sending base graceful-restart capability irrespective of the config */
1092 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1093 stream_putc (s, BGP_OPEN_OPT_CAP);
1094 capp = stream_get_endp (s); /* Set Capability Len Pointer */
1095 stream_putc (s, 0); /* Capability Length */
1096 stream_putc (s, CAPABILITY_CODE_RESTART);
1097 rcapp = stream_get_endp (s); /* Set Restart Capability Len Pointer */
1098 stream_putc (s, 0);
1099 restart_time = peer->bgp->restart_time;
1100 if (peer->bgp->t_startup)
1101 {
1102 SET_FLAG (restart_time, RESTART_R_BIT);
1103 SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_ADV);
1104 }
1105 stream_putw (s, restart_time);
1106
1107 /* Send address-family specific graceful-restart capability only when GR config
1108 is present */
538621f2 1109 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1110 {
fe7d2a48
DS
1111 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1112 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1113 if (peer->afc[afi][safi])
1114 {
1115 stream_putw (s, afi);
1116 stream_putc (s, safi);
1117 stream_putc (s, 0); //Forwarding is not retained as of now.
1118 }
1119 }
1120
1121 /* Total Graceful restart capability Len. */
1122 len = stream_get_endp (s) - rcapp - 1;
1123 stream_putc_at (s, rcapp, len);
1124
1125 /* Total Capability Len. */
1126 len = stream_get_endp (s) - capp - 1;
1127 stream_putc_at (s, capp, len);
538621f2 1128
718e3744 1129 /* Total Opt Parm Len. */
9985f83c 1130 len = stream_get_endp (s) - cp - 1;
718e3744 1131 stream_putc_at (s, cp, len);
1132}