]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
A valid BGP nexthop is flagged as invalid
[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
fc52f953 420static const struct message capcode_str[] =
6d58272b 421{
6d58272b
PJ
422 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
423 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
424 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
425 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
426 { CAPABILITY_CODE_AS4, "4-octet AS number" },
427 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
428 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
429 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
430};
837d16cc 431static const int capcode_str_max = array_size(capcode_str);
6d58272b
PJ
432
433/* Minimum sizes for length field of each cap (so not inc. the header) */
fc52f953 434static const size_t cap_minsizes[] =
6d58272b
PJ
435{
436 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
437 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
438 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
370b64a2 439 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
6d58272b
PJ
440 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
441 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
442 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
443 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
444};
445
3b381c32
AS
446/**
447 * Parse given capability.
6d58272b 448 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
449 *
450 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
451 * capabilities were encountered.
6d58272b
PJ
452 */
453static int
3b381c32
AS
454bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
455 u_char **error)
6d58272b
PJ
456{
457 int ret;
458 struct stream *s = BGP_INPUT (peer);
459 size_t end = stream_get_getp (s) + length;
460
461 assert (STREAM_READABLE (s) >= length);
462
463 while (stream_get_getp (s) < end)
464 {
465 size_t start;
466 u_char *sp = stream_pnt (s);
467 struct capability_header caphdr;
468
718e3744 469 /* We need at least capability code and capability length. */
6d58272b 470 if (stream_get_getp(s) + 2 > end)
718e3744 471 {
6d58272b 472 zlog_info ("%s Capability length error (< header)", peer->host);
718e3744 473 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
474 return -1;
475 }
6d58272b
PJ
476
477 caphdr.code = stream_getc (s);
478 caphdr.length = stream_getc (s);
479 start = stream_get_getp (s);
480
481 /* Capability length check sanity check. */
482 if (start + caphdr.length > end)
718e3744 483 {
6d58272b 484 zlog_info ("%s Capability length error (< length)", peer->host);
718e3744 485 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
486 return -1;
487 }
6d58272b 488
16286195 489 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
490 zlog_debug ("%s OPEN has %s capability (%u), length %u",
491 peer->host,
492 LOOKUP (capcode_str, caphdr.code),
493 caphdr.code, caphdr.length);
494
495 /* Length sanity check, type-specific, for known capabilities */
496 switch (caphdr.code)
497 {
498 case CAPABILITY_CODE_MP:
499 case CAPABILITY_CODE_REFRESH:
500 case CAPABILITY_CODE_REFRESH_OLD:
501 case CAPABILITY_CODE_ORF:
502 case CAPABILITY_CODE_ORF_OLD:
503 case CAPABILITY_CODE_RESTART:
0b2aa3a0 504 case CAPABILITY_CODE_AS4:
6d58272b
PJ
505 case CAPABILITY_CODE_DYNAMIC:
506 /* Check length. */
507 if (caphdr.length < cap_minsizes[caphdr.code])
508 {
509 zlog_info ("%s %s Capability length error: got %u,"
510 " expected at least %u",
511 peer->host,
512 LOOKUP (capcode_str, caphdr.code),
fc52f953
SH
513 caphdr.length,
514 (unsigned) cap_minsizes[caphdr.code]);
6d58272b
PJ
515 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
516 return -1;
517 }
518 /* we deliberately ignore unknown codes, see below */
519 default:
520 break;
521 }
522
523 switch (caphdr.code)
524 {
525 case CAPABILITY_CODE_MP:
526 {
3b381c32
AS
527 *mp_capability = 1;
528
6d58272b
PJ
529 /* Ignore capability when override-capability is set. */
530 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
531 {
532 /* Set negotiated value. */
533 ret = bgp_capability_mp (peer, &caphdr);
534
535 /* Unsupported Capability. */
536 if (ret < 0)
537 {
538 /* Store return data. */
539 memcpy (*error, sp, caphdr.length + 2);
540 *error += caphdr.length + 2;
541 }
542 }
543 }
544 break;
545 case CAPABILITY_CODE_REFRESH:
546 case CAPABILITY_CODE_REFRESH_OLD:
547 {
548 /* BGP refresh capability */
549 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
550 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
551 else
552 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
553 }
554 break;
555 case CAPABILITY_CODE_ORF:
556 case CAPABILITY_CODE_ORF_OLD:
fe9bb645 557 if (bgp_capability_orf_entry (peer, &caphdr))
6d58272b
PJ
558 return -1;
559 break;
560 case CAPABILITY_CODE_RESTART:
561 if (bgp_capability_restart (peer, &caphdr))
562 return -1;
563 break;
564 case CAPABILITY_CODE_DYNAMIC:
565 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
566 break;
0b2aa3a0
PJ
567 case CAPABILITY_CODE_AS4:
568 /* Already handled as a special-case parsing of the capabilities
569 * at the beginning of OPEN processing. So we care not a jot
570 * for the value really, only error case.
571 */
572 if (!bgp_capability_as4 (peer, &caphdr))
573 return -1;
574 break;
6d58272b
PJ
575 default:
576 if (caphdr.code > 128)
577 {
578 /* We don't send Notification for unknown vendor specific
579 capabilities. It seems reasonable for now... */
580 zlog_warn ("%s Vendor specific capability %d",
581 peer->host, caphdr.code);
582 }
583 else
584 {
585 zlog_warn ("%s unrecognized capability code: %d - ignored",
586 peer->host, caphdr.code);
587 memcpy (*error, sp, caphdr.length + 2);
588 *error += caphdr.length + 2;
589 }
590 }
591 if (stream_get_getp(s) != (start + caphdr.length))
592 {
593 if (stream_get_getp(s) > (start + caphdr.length))
594 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
595 peer->host, LOOKUP (capcode_str, caphdr.code),
596 caphdr.length);
597 stream_set_getp (s, start + caphdr.length);
598 }
718e3744 599 }
600 return 0;
601}
602
94f2b392 603static int
6d58272b 604bgp_auth_parse (struct peer *peer, size_t length)
718e3744 605{
606 bgp_notify_send (peer,
607 BGP_NOTIFY_OPEN_ERR,
608 BGP_NOTIFY_OPEN_AUTH_FAILURE);
609 return -1;
610}
611
94f2b392 612static int
718e3744 613strict_capability_same (struct peer *peer)
614{
615 int i, j;
616
617 for (i = AFI_IP; i < AFI_MAX; i++)
618 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
619 if (peer->afc[i][j] != peer->afc_nego[i][j])
620 return 0;
621 return 1;
622}
623
0b2aa3a0
PJ
624/* peek into option, stores ASN to *as4 if the AS4 capability was found.
625 * Returns 0 if no as4 found, as4cap value otherwise.
626 */
627as_t
628peek_for_as4_capability (struct peer *peer, u_char length)
629{
630 struct stream *s = BGP_INPUT (peer);
631 size_t orig_getp = stream_get_getp (s);
632 size_t end = orig_getp + length;
633 as_t as4 = 0;
634
635 /* The full capability parser will better flag the error.. */
636 if (STREAM_READABLE(s) < length)
637 return 0;
638
639 if (BGP_DEBUG (as4, AS4))
640 zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
641 " peeking for as4",
642 peer->host, length);
643 /* the error cases we DONT handle, we ONLY try to read as4 out of
644 * correctly formatted options.
645 */
646 while (stream_get_getp(s) < end)
647 {
648 u_char opt_type;
649 u_char opt_length;
650
651 /* Check the length. */
652 if (stream_get_getp (s) + 2 > end)
653 goto end;
654
655 /* Fetch option type and length. */
656 opt_type = stream_getc (s);
657 opt_length = stream_getc (s);
658
659 /* Option length check. */
660 if (stream_get_getp (s) + opt_length > end)
661 goto end;
662
663 if (opt_type == BGP_OPEN_OPT_CAP)
664 {
665 unsigned long capd_start = stream_get_getp (s);
666 unsigned long capd_end = capd_start + opt_length;
667
668 assert (capd_end <= end);
669
670 while (stream_get_getp (s) < capd_end)
671 {
672 struct capability_header hdr;
673
674 if (stream_get_getp (s) + 2 > capd_end)
675 goto end;
676
677 hdr.code = stream_getc (s);
678 hdr.length = stream_getc (s);
679
680 if ((stream_get_getp(s) + hdr.length) > capd_end)
681 goto end;
682
683 if (hdr.code == CAPABILITY_CODE_AS4)
684 {
0b2aa3a0
PJ
685 if (BGP_DEBUG (as4, AS4))
686 zlog_info ("[AS4] found AS4 capability, about to parse");
687 as4 = bgp_capability_as4 (peer, &hdr);
688
689 goto end;
690 }
691 stream_forward_getp (s, hdr.length);
692 }
693 }
694 }
695
696end:
697 stream_set_getp (s, orig_getp);
698 return as4;
699}
700
3b381c32
AS
701/**
702 * Parse open option.
703 *
704 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
705 */
718e3744 706int
3b381c32 707bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
718e3744 708{
709 int ret;
718e3744 710 u_char *error;
711 u_char error_data[BGP_MAX_PACKET_SIZE];
6d58272b
PJ
712 struct stream *s = BGP_INPUT(peer);
713 size_t end = stream_get_getp (s) + length;
718e3744 714
715 ret = 0;
718e3744 716 error = error_data;
717
16286195 718 if (bgp_debug_neighbor_events(peer))
8325cd7f 719 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
718e3744 720 peer->host, length);
721
6d58272b 722 while (stream_get_getp(s) < end)
718e3744 723 {
6d58272b
PJ
724 u_char opt_type;
725 u_char opt_length;
726
727 /* Must have at least an OPEN option header */
728 if (STREAM_READABLE(s) < 2)
718e3744 729 {
730 zlog_info ("%s Option length error", peer->host);
731 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
732 return -1;
733 }
734
735 /* Fetch option type and length. */
6d58272b
PJ
736 opt_type = stream_getc (s);
737 opt_length = stream_getc (s);
718e3744 738
739 /* Option length check. */
6d58272b 740 if (STREAM_READABLE (s) < opt_length)
718e3744 741 {
742 zlog_info ("%s Option length error", peer->host);
743 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
744 return -1;
745 }
746
16286195 747 if (bgp_debug_neighbor_events(peer))
8325cd7f 748 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
718e3744 749 peer->host, opt_type,
750 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
751 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
752 opt_length);
753
754 switch (opt_type)
755 {
756 case BGP_OPEN_OPT_AUTH:
6d58272b 757 ret = bgp_auth_parse (peer, opt_length);
718e3744 758 break;
759 case BGP_OPEN_OPT_CAP:
3b381c32 760 ret = bgp_capability_parse (peer, opt_length, mp_capability, &error);
718e3744 761 break;
762 default:
763 bgp_notify_send (peer,
764 BGP_NOTIFY_OPEN_ERR,
765 BGP_NOTIFY_OPEN_UNSUP_PARAM);
766 ret = -1;
767 break;
768 }
769
770 /* Parse error. To accumulate all unsupported capability codes,
771 bgp_capability_parse does not return -1 when encounter
772 unsupported capability code. To detect that, please check
773 error and erro_data pointer, like below. */
774 if (ret < 0)
775 return -1;
718e3744 776 }
777
778 /* All OPEN option is parsed. Check capability when strict compare
779 flag is enabled.*/
780 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
781 {
782 /* If Unsupported Capability exists. */
783 if (error != error_data)
784 {
785 bgp_notify_send_with_data (peer,
786 BGP_NOTIFY_OPEN_ERR,
787 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
788 error_data, error - error_data);
789 return -1;
790 }
791
792 /* Check local capability does not negotiated with remote
793 peer. */
794 if (! strict_capability_same (peer))
795 {
796 bgp_notify_send (peer,
797 BGP_NOTIFY_OPEN_ERR,
798 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
799 return -1;
800 }
801 }
802
3b381c32 803 /* Check there are no common AFI/SAFIs and send Unsupported Capability
718e3744 804 error. */
3b381c32
AS
805 if (*mp_capability &&
806 ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
718e3744 807 {
808 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
809 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
810 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
811 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
812 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
813 {
16286195 814 zlog_err ("%s [Error] Configured AFI/SAFIs do not "
3b381c32
AS
815 "overlap with received MP capabilities",
816 peer->host);
718e3744 817
818 if (error != error_data)
718e3744 819 bgp_notify_send_with_data (peer,
820 BGP_NOTIFY_OPEN_ERR,
821 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
822 error_data, error - error_data);
823 else
824 bgp_notify_send (peer,
825 BGP_NOTIFY_OPEN_ERR,
826 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
827 return -1;
828 }
829 }
830 return 0;
831}
832
94f2b392 833static void
718e3744 834bgp_open_capability_orf (struct stream *s, struct peer *peer,
835 afi_t afi, safi_t safi, u_char code)
836{
837 u_char cap_len;
838 u_char orf_len;
839 unsigned long capp;
840 unsigned long orfp;
841 unsigned long numberp;
842 int number_of_orfs = 0;
843
844 if (safi == SAFI_MPLS_VPN)
42e6d745 845 safi = SAFI_MPLS_LABELED_VPN;
718e3744 846
847 stream_putc (s, BGP_OPEN_OPT_CAP);
9985f83c 848 capp = stream_get_endp (s); /* Set Capability Len Pointer */
718e3744 849 stream_putc (s, 0); /* Capability Length */
850 stream_putc (s, code); /* Capability Code */
9985f83c 851 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
718e3744 852 stream_putc (s, 0); /* ORF Length */
853 stream_putw (s, afi);
854 stream_putc (s, 0);
855 stream_putc (s, safi);
9985f83c 856 numberp = stream_get_endp (s); /* Set Number Pointer */
718e3744 857 stream_putc (s, 0); /* Number of ORFs */
858
859 /* Address Prefix ORF */
860 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
861 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
862 {
863 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
864 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
865
866 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
867 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
868 {
869 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
870 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
871 stream_putc (s, ORF_MODE_BOTH);
872 }
873 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
874 {
875 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
876 stream_putc (s, ORF_MODE_SEND);
877 }
878 else
879 {
880 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
881 stream_putc (s, ORF_MODE_RECEIVE);
882 }
883 number_of_orfs++;
884 }
885
886 /* Total Number of ORFs. */
887 stream_putc_at (s, numberp, number_of_orfs);
888
889 /* Total ORF Len. */
9985f83c 890 orf_len = stream_get_endp (s) - orfp - 1;
718e3744 891 stream_putc_at (s, orfp, orf_len);
892
893 /* Total Capability Len. */
9985f83c 894 cap_len = stream_get_endp (s) - capp - 1;
718e3744 895 stream_putc_at (s, capp, cap_len);
896}
897
898/* Fill in capability open option to the packet. */
899void
900bgp_open_capability (struct stream *s, struct peer *peer)
901{
902 u_char len;
fe7d2a48 903 unsigned long cp, capp, rcapp;
718e3744 904 afi_t afi;
905 safi_t safi;
0b2aa3a0 906 as_t local_as;
fe7d2a48 907 u_int32_t restart_time;
718e3744 908
909 /* Remember current pointer for Opt Parm Len. */
9985f83c 910 cp = stream_get_endp (s);
718e3744 911
912 /* Opt Parm Len. */
913 stream_putc (s, 0);
914
915 /* Do not send capability. */
916 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
917 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
918 return;
919
718e3744 920 /* IPv4 unicast. */
921 if (peer->afc[AFI_IP][SAFI_UNICAST])
922 {
923 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
924 stream_putc (s, BGP_OPEN_OPT_CAP);
925 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
926 stream_putc (s, CAPABILITY_CODE_MP);
927 stream_putc (s, CAPABILITY_CODE_MP_LEN);
928 stream_putw (s, AFI_IP);
929 stream_putc (s, 0);
930 stream_putc (s, SAFI_UNICAST);
931 }
932 /* IPv4 multicast. */
933 if (peer->afc[AFI_IP][SAFI_MULTICAST])
934 {
935 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
936 stream_putc (s, BGP_OPEN_OPT_CAP);
937 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
938 stream_putc (s, CAPABILITY_CODE_MP);
939 stream_putc (s, CAPABILITY_CODE_MP_LEN);
940 stream_putw (s, AFI_IP);
941 stream_putc (s, 0);
942 stream_putc (s, SAFI_MULTICAST);
943 }
944 /* IPv4 VPN */
945 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
946 {
947 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
948 stream_putc (s, BGP_OPEN_OPT_CAP);
949 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
950 stream_putc (s, CAPABILITY_CODE_MP);
951 stream_putc (s, CAPABILITY_CODE_MP_LEN);
952 stream_putw (s, AFI_IP);
953 stream_putc (s, 0);
42e6d745 954 stream_putc (s, SAFI_MPLS_LABELED_VPN);
718e3744 955 }
956#ifdef HAVE_IPV6
957 /* IPv6 unicast. */
958 if (peer->afc[AFI_IP6][SAFI_UNICAST])
959 {
960 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
961 stream_putc (s, BGP_OPEN_OPT_CAP);
962 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
963 stream_putc (s, CAPABILITY_CODE_MP);
964 stream_putc (s, CAPABILITY_CODE_MP_LEN);
965 stream_putw (s, AFI_IP6);
966 stream_putc (s, 0);
967 stream_putc (s, SAFI_UNICAST);
968 }
969 /* IPv6 multicast. */
970 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
971 {
972 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
973 stream_putc (s, BGP_OPEN_OPT_CAP);
974 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
975 stream_putc (s, CAPABILITY_CODE_MP);
976 stream_putc (s, CAPABILITY_CODE_MP_LEN);
977 stream_putw (s, AFI_IP6);
978 stream_putc (s, 0);
979 stream_putc (s, SAFI_MULTICAST);
980 }
981#endif /* HAVE_IPV6 */
982
983 /* Route refresh. */
c9502438 984 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
985 stream_putc (s, BGP_OPEN_OPT_CAP);
986 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
987 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
988 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
989 stream_putc (s, BGP_OPEN_OPT_CAP);
990 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
991 stream_putc (s, CAPABILITY_CODE_REFRESH);
992 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
718e3744 993
0b2aa3a0
PJ
994 /* AS4 */
995 SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
996 stream_putc (s, BGP_OPEN_OPT_CAP);
997 stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
998 stream_putc (s, CAPABILITY_CODE_AS4);
999 stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1000 if ( peer->change_local_as )
1001 local_as = peer->change_local_as;
1002 else
1003 local_as = peer->local_as;
1004 stream_putl (s, local_as );
1005
718e3744 1006 /* ORF capability. */
1007 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1008 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1009 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1010 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1011 {
1012 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1013 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1014 }
1015
1016 /* Dynamic capability. */
1017 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1018 {
1019 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1020 stream_putc (s, BGP_OPEN_OPT_CAP);
1021 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1022 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1023 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1024 }
1025
fe7d2a48
DS
1026 /* Sending base graceful-restart capability irrespective of the config */
1027 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1028 stream_putc (s, BGP_OPEN_OPT_CAP);
1029 capp = stream_get_endp (s); /* Set Capability Len Pointer */
1030 stream_putc (s, 0); /* Capability Length */
1031 stream_putc (s, CAPABILITY_CODE_RESTART);
1032 rcapp = stream_get_endp (s); /* Set Restart Capability Len Pointer */
1033 stream_putc (s, 0);
1034 restart_time = peer->bgp->restart_time;
1035 if (peer->bgp->t_startup)
1036 {
1037 SET_FLAG (restart_time, RESTART_R_BIT);
1038 SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_ADV);
1039 }
1040 stream_putw (s, restart_time);
1041
1042 /* Send address-family specific graceful-restart capability only when GR config
1043 is present */
538621f2 1044 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1045 {
fe7d2a48
DS
1046 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1047 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1048 if (peer->afc[afi][safi])
1049 {
1050 stream_putw (s, afi);
1051 stream_putc (s, safi);
1052 stream_putc (s, 0); //Forwarding is not retained as of now.
1053 }
1054 }
1055
1056 /* Total Graceful restart capability Len. */
1057 len = stream_get_endp (s) - rcapp - 1;
1058 stream_putc_at (s, rcapp, len);
1059
1060 /* Total Capability Len. */
1061 len = stream_get_endp (s) - capp - 1;
1062 stream_putc_at (s, capp, len);
538621f2 1063
718e3744 1064 /* Total Opt Parm Len. */
9985f83c 1065 len = stream_get_endp (s) - cp - 1;
718e3744 1066 stream_putc_at (s, cp, len);
1067}