blob: d4f7cdf598d0f2c98b2bba7cdf7989743f8db3c0 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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"
Paul Jakma6d582722007-08-06 15:21:45 +000029#include "memory.h"
paul718e3742002-12-13 20:15:29 +000030
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"
hasso538621f2004-05-21 09:31:30 +000037#include "bgpd/bgp_vty.h"
38
paul718e3742002-12-13 20:15:29 +000039/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
40 negotiate remote peer supports extentions or not. But if
41 remote-peer doesn't supports negotiation process itself. We would
42 like to do manual configuration.
43
44 So there is many configurable point. First of all we want set each
45 peer whether we send capability negotiation to the peer or not.
46 Next, if we send capability to the peer we want to set my capabilty
47 inforation at each peer. */
48
49void
50bgp_capability_vty_out (struct vty *vty, struct peer *peer)
51{
paul5228ad22004-06-04 17:58:18 +000052 char *pnt;
53 char *end;
Paul Jakma6d582722007-08-06 15:21:45 +000054 struct capability_mp_data mpc;
55 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +000056
57 pnt = peer->notify.data;
58 end = pnt + peer->notify.length;
Paul Jakma6d582722007-08-06 15:21:45 +000059
paul718e3742002-12-13 20:15:29 +000060 while (pnt < end)
61 {
Paul Jakma6d582722007-08-06 15:21:45 +000062 if (pnt + sizeof (struct capability_mp_data) + 2 > end)
paul718e3742002-12-13 20:15:29 +000063 return;
Paul Jakma6d582722007-08-06 15:21:45 +000064
65 hdr = (struct capability_header *)pnt;
66 if (pnt + hdr->length + 2 > end)
paul718e3742002-12-13 20:15:29 +000067 return;
68
Paul Jakma6d582722007-08-06 15:21:45 +000069 memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
70
71 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +000072 {
73 vty_out (vty, " Capability error for: Multi protocol ");
74
Paul Jakma6d582722007-08-06 15:21:45 +000075 switch (ntohs (mpc.afi))
paul718e3742002-12-13 20:15:29 +000076 {
77 case AFI_IP:
78 vty_out (vty, "AFI IPv4, ");
79 break;
80 case AFI_IP6:
81 vty_out (vty, "AFI IPv6, ");
82 break;
83 default:
Paul Jakma6d582722007-08-06 15:21:45 +000084 vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
paul718e3742002-12-13 20:15:29 +000085 break;
86 }
Paul Jakma6d582722007-08-06 15:21:45 +000087 switch (mpc.safi)
paul718e3742002-12-13 20:15:29 +000088 {
89 case SAFI_UNICAST:
90 vty_out (vty, "SAFI Unicast");
91 break;
92 case SAFI_MULTICAST:
93 vty_out (vty, "SAFI Multicast");
94 break;
95 case SAFI_UNICAST_MULTICAST:
96 vty_out (vty, "SAFI Unicast Multicast");
97 break;
98 case BGP_SAFI_VPNV4:
99 vty_out (vty, "SAFI MPLS-VPN");
100 break;
101 default:
Paul Jakma6d582722007-08-06 15:21:45 +0000102 vty_out (vty, "SAFI Unknown %d ", mpc.safi);
paul718e3742002-12-13 20:15:29 +0000103 break;
104 }
105 vty_out (vty, "%s", VTY_NEWLINE);
106 }
Paul Jakma6d582722007-08-06 15:21:45 +0000107 else if (hdr->code >= 128)
paul718e3742002-12-13 20:15:29 +0000108 vty_out (vty, " Capability error: vendor specific capability code %d",
Paul Jakma6d582722007-08-06 15:21:45 +0000109 hdr->code);
paul718e3742002-12-13 20:15:29 +0000110 else
111 vty_out (vty, " Capability error: unknown capability code %d",
Paul Jakma6d582722007-08-06 15:21:45 +0000112 hdr->code);
paul718e3742002-12-13 20:15:29 +0000113
Paul Jakma6d582722007-08-06 15:21:45 +0000114 pnt += hdr->length + 2;
paul718e3742002-12-13 20:15:29 +0000115 }
116}
117
Paul Jakma6d582722007-08-06 15:21:45 +0000118static void
119bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
120{
121 mpc->afi = stream_getw (s);
122 mpc->reserved = stream_getc (s);
123 mpc->safi = stream_getc (s);
124}
125
126int
127bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
128{
129 /* VPNvX are AFI specific */
130 if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4)
131 || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6))
132 {
133 zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi);
134 return 0;
135 }
136
137 switch (afi)
138 {
139 case AFI_IP:
140#ifdef HAVE_IPV6
141 case AFI_IP6:
142#endif
143 switch (*safi)
144 {
145 /* BGP VPNvX SAFI isn't contigious with others, remap */
146 case BGP_SAFI_VPNV4:
147 case BGP_SAFI_VPNV6:
148 *safi = SAFI_MPLS_VPN;
149 case SAFI_UNICAST:
150 case SAFI_MULTICAST:
151 case SAFI_MPLS_VPN:
152 return 1;
153 }
154 }
155 zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
156
157 return 0;
158}
159
paul718e3742002-12-13 20:15:29 +0000160/* Set negotiated capability value. */
paul94f2b392005-06-28 12:44:16 +0000161static int
Paul Jakma6d582722007-08-06 15:21:45 +0000162bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
paul718e3742002-12-13 20:15:29 +0000163{
Paul Jakma6d582722007-08-06 15:21:45 +0000164 struct capability_mp_data mpc;
165 struct stream *s = BGP_INPUT (peer);
166
167 bgp_capability_mp_data (s, &mpc);
168
169 if (BGP_DEBUG (normal, NORMAL))
170 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
171 peer->host, mpc.afi, mpc.safi);
172
173 if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
174 return -1;
175
176 /* Now safi remapped, and afi/safi are valid array indices */
177 peer->afc_recv[mpc.afi][mpc.safi] = 1;
178
179 if (peer->afc[mpc.afi][mpc.safi])
180 peer->afc_nego[mpc.safi][mpc.safi] = 1;
181 else
182 return -1;
paul718e3742002-12-13 20:15:29 +0000183
184 return 0;
185}
186
paul94f2b392005-06-28 12:44:16 +0000187static void
paul718e3742002-12-13 20:15:29 +0000188bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
189 u_char type, u_char mode)
190{
191 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000192 zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
paul718e3742002-12-13 20:15:29 +0000193 peer->host, afi, safi, type, mode);
194}
195
Paul Jakma6d582722007-08-06 15:21:45 +0000196static struct message orf_type_str[] =
paul718e3742002-12-13 20:15:29 +0000197{
Paul Jakma6d582722007-08-06 15:21:45 +0000198 { ORF_TYPE_PREFIX, "Prefixlist" },
199 { ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
200};
201static int orf_type_str_max = sizeof(orf_type_str)/sizeof(orf_type_str[0]);
202
203static struct message orf_mode_str[] =
204{
205 { ORF_MODE_RECEIVE, "Receive" },
206 { ORF_MODE_SEND, "Send" },
207 { ORF_MODE_BOTH, "Both" },
208};
209static int orf_mode_str_max = sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
210
211static int
212bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
213{
214 struct stream *s = BGP_INPUT (peer);
215 struct capability_orf_entry entry;
216 afi_t afi;
217 safi_t safi;
paul718e3742002-12-13 20:15:29 +0000218 u_char type;
219 u_char mode;
220 u_int16_t sm_cap = 0; /* capability send-mode receive */
221 u_int16_t rm_cap = 0; /* capability receive-mode receive */
222 int i;
223
Paul Jakma6d582722007-08-06 15:21:45 +0000224 /* ORF Entry header */
225 bgp_capability_mp_data (s, &entry.mpc);
226 entry.num = stream_getc (s);
227 afi = entry.mpc.afi;
228 safi = entry.mpc.safi;
229
paul718e3742002-12-13 20:15:29 +0000230 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma6d582722007-08-06 15:21:45 +0000231 zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
232 peer->host, entry.mpc.afi, entry.mpc.safi);
paul718e3742002-12-13 20:15:29 +0000233
234 /* Check AFI and SAFI. */
Paul Jakma6d582722007-08-06 15:21:45 +0000235 if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
paul718e3742002-12-13 20:15:29 +0000236 {
Paul Jakma6d582722007-08-06 15:21:45 +0000237 zlog_info ("%s Addr-family %d/%d not supported."
238 " Ignoring the ORF capability",
239 peer->host, entry.mpc.afi, entry.mpc.safi);
240 return 0;
241 }
242
243 /* validate number field */
244 if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
245 {
246 zlog_info ("%s ORF Capability entry length error,"
247 " Cap length %u, num %u",
248 peer->host, hdr->length, entry.num);
249 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
paul718e3742002-12-13 20:15:29 +0000250 return -1;
251 }
252
Paul Jakma6d582722007-08-06 15:21:45 +0000253 for (i = 0 ; i < entry.num ; i++)
paul718e3742002-12-13 20:15:29 +0000254 {
Paul Jakma6d582722007-08-06 15:21:45 +0000255 type = stream_getc(s);
256 mode = stream_getc(s);
257
paul718e3742002-12-13 20:15:29 +0000258 /* ORF Mode error check */
Paul Jakma6d582722007-08-06 15:21:45 +0000259 switch (mode)
260 {
261 case ORF_MODE_BOTH:
262 case ORF_MODE_SEND:
263 case ORF_MODE_RECEIVE:
264 break;
265 default:
266 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
267 continue;
paul718e3742002-12-13 20:15:29 +0000268 }
Paul Jakma6d582722007-08-06 15:21:45 +0000269 /* ORF Type and afi/safi error checks */
270 /* capcode versus type */
271 switch (hdr->code)
272 {
273 case CAPABILITY_CODE_ORF:
274 switch (type)
275 {
276 case ORF_TYPE_PREFIX:
277 break;
278 default:
279 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
280 continue;
281 }
282 break;
283 case CAPABILITY_CODE_ORF_OLD:
284 switch (type)
285 {
286 case ORF_TYPE_PREFIX_OLD:
287 break;
288 default:
289 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
290 continue;
291 }
292 break;
293 default:
294 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
295 continue;
296 }
297
298 /* AFI vs SAFI */
299 if (!((afi == AFI_IP && safi == SAFI_UNICAST)
300 || (afi == AFI_IP && safi == SAFI_MULTICAST)
301 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
302 {
303 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
304 continue;
305 }
306
307 if (BGP_DEBUG (normal, NORMAL))
308 zlog_debug ("%s OPEN has %s ORF capability"
309 " as %s for afi/safi: %d/%d",
310 peer->host, LOOKUP (orf_type_str, type),
311 LOOKUP (orf_mode_str, mode),
312 entry.mpc.afi, safi);
paul718e3742002-12-13 20:15:29 +0000313
Paul Jakma6d582722007-08-06 15:21:45 +0000314 if (hdr->code == CAPABILITY_CODE_ORF)
paul718e3742002-12-13 20:15:29 +0000315 {
Paul Jakma6d582722007-08-06 15:21:45 +0000316 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
317 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
paul718e3742002-12-13 20:15:29 +0000318 }
Paul Jakma6d582722007-08-06 15:21:45 +0000319 else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
paul718e3742002-12-13 20:15:29 +0000320 {
Paul Jakma6d582722007-08-06 15:21:45 +0000321 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
322 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
paul718e3742002-12-13 20:15:29 +0000323 }
324 else
325 {
326 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
327 continue;
328 }
329
330 switch (mode)
331 {
332 case ORF_MODE_BOTH:
333 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
334 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
335 break;
336 case ORF_MODE_SEND:
337 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
338 break;
339 case ORF_MODE_RECEIVE:
340 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
341 break;
342 }
343 }
344 return 0;
345}
346
paul94f2b392005-06-28 12:44:16 +0000347static int
Paul Jakma6d582722007-08-06 15:21:45 +0000348bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
349{
350 struct stream *s = BGP_INPUT (peer);
351 size_t end = stream_get_getp (s) + hdr->length;
352
353 assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
354
355 /* We must have at least one ORF entry, as the caller has already done
356 * minimum length validation for the capability code - for ORF there must
357 * at least one ORF entry (header and unknown number of pairs of bytes).
358 */
359 do
360 {
361 if (bgp_capability_orf_entry (peer, hdr) == -1)
362 return -1;
363 }
364 while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
365
366 return 0;
367}
368
369static int
370bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
371{
372 struct stream *s = BGP_INPUT (peer);
373 u_int16_t restart_flag_time;
374 int restart_bit = 0;
375 size_t end = stream_get_getp (s) + caphdr->length;
376
377 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
378 restart_flag_time = stream_getw(s);
379 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
380 restart_bit = 1;
381 UNSET_FLAG (restart_flag_time, 0xF000);
382 peer->v_gr_restart = restart_flag_time;
383
384 if (BGP_DEBUG (normal, NORMAL))
385 {
386 zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
387 zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
388 peer->host, restart_bit ? " " : " not ",
389 peer->v_gr_restart);
390 }
391
392 while (stream_get_getp (s) + 4 < end)
393 {
394 afi_t afi = stream_getw (s);
395 safi_t safi = stream_getc (s);
396 u_char flag = stream_getc (s);
397
398 if (!bgp_afi_safi_valid_indices (afi, &safi))
399 {
400 if (BGP_DEBUG (normal, NORMAL))
401 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
402 " Ignore the Graceful Restart capability",
403 peer->host, afi, safi);
404 }
405 else if (!peer->afc[afi][safi])
406 {
407 if (BGP_DEBUG (normal, NORMAL))
408 zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
409 " Ignore the Graceful Restart capability",
410 peer->host, afi, safi);
411 }
412 else
413 {
414 if (BGP_DEBUG (normal, NORMAL))
415 zlog_debug ("%s Address family %s is%spreserved", peer->host,
416 afi_safi_print (afi, safi),
417 CHECK_FLAG (peer->af_cap[afi][safi],
418 PEER_CAP_RESTART_AF_PRESERVE_RCV)
419 ? " " : " not ");
420
421 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
422 if (CHECK_FLAG (flag, RESTART_F_BIT))
423 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
424
425 }
426 }
427 return 0;
428}
429
430static struct message capcode_str[] =
431{
432 { 0, ""},
433 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
434 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
435 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
436 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
437 { CAPABILITY_CODE_AS4, "4-octet AS number" },
438 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
439 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
440 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
441};
442int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
443
444/* Minimum sizes for length field of each cap (so not inc. the header) */
445static size_t cap_minsizes[] =
446{
447 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
448 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
449 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
450 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr) - 2,
451 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
452 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
453 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
454 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
455};
456
457/* Parse given capability.
458 * XXX: This is reading into a stream, but not using stream API
459 */
460static int
461bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
paul718e3742002-12-13 20:15:29 +0000462{
463 int ret;
Paul Jakma6d582722007-08-06 15:21:45 +0000464 struct stream *s = BGP_INPUT (peer);
465 size_t end = stream_get_getp (s) + length;
466
467 assert (STREAM_READABLE (s) >= length);
468
469 while (stream_get_getp (s) < end)
paul718e3742002-12-13 20:15:29 +0000470 {
Paul Jakma6d582722007-08-06 15:21:45 +0000471 size_t start;
472 u_char *sp = stream_pnt (s);
473 struct capability_header caphdr;
474
paul718e3742002-12-13 20:15:29 +0000475 /* We need at least capability code and capability length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000476 if (stream_get_getp(s) + 2 > end)
paul718e3742002-12-13 20:15:29 +0000477 {
Paul Jakma6d582722007-08-06 15:21:45 +0000478 zlog_info ("%s Capability length error (< header)", peer->host);
paul718e3742002-12-13 20:15:29 +0000479 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
480 return -1;
481 }
Paul Jakma6d582722007-08-06 15:21:45 +0000482
483 caphdr.code = stream_getc (s);
484 caphdr.length = stream_getc (s);
485 start = stream_get_getp (s);
486
487 /* Capability length check sanity check. */
488 if (start + caphdr.length > end)
paul718e3742002-12-13 20:15:29 +0000489 {
Paul Jakma6d582722007-08-06 15:21:45 +0000490 zlog_info ("%s Capability length error (< length)", peer->host);
paul718e3742002-12-13 20:15:29 +0000491 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
492 return -1;
493 }
Paul Jakma6d582722007-08-06 15:21:45 +0000494
495 if (BGP_DEBUG (normal, NORMAL))
496 zlog_debug ("%s OPEN has %s capability (%u), length %u",
497 peer->host,
498 LOOKUP (capcode_str, caphdr.code),
499 caphdr.code, caphdr.length);
500
501 /* Length sanity check, type-specific, for known capabilities */
502 switch (caphdr.code)
503 {
504 case CAPABILITY_CODE_MP:
505 case CAPABILITY_CODE_REFRESH:
506 case CAPABILITY_CODE_REFRESH_OLD:
507 case CAPABILITY_CODE_ORF:
508 case CAPABILITY_CODE_ORF_OLD:
509 case CAPABILITY_CODE_RESTART:
510 case CAPABILITY_CODE_DYNAMIC:
511 /* Check length. */
512 if (caphdr.length < cap_minsizes[caphdr.code])
513 {
514 zlog_info ("%s %s Capability length error: got %u,"
515 " expected at least %u",
516 peer->host,
517 LOOKUP (capcode_str, caphdr.code),
518 caphdr.length, cap_minsizes[caphdr.code]);
519 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
520 return -1;
521 }
522 /* we deliberately ignore unknown codes, see below */
523 default:
524 break;
525 }
526
527 switch (caphdr.code)
528 {
529 case CAPABILITY_CODE_MP:
530 {
531 /* Ignore capability when override-capability is set. */
532 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
533 {
534 /* Set negotiated value. */
535 ret = bgp_capability_mp (peer, &caphdr);
paul718e3742002-12-13 20:15:29 +0000536
Paul Jakma6d582722007-08-06 15:21:45 +0000537 /* Unsupported Capability. */
538 if (ret < 0)
539 {
540 /* Store return data. */
541 memcpy (*error, sp, caphdr.length + 2);
542 *error += caphdr.length + 2;
543 }
544 }
545 }
546 break;
547 case CAPABILITY_CODE_REFRESH:
548 case CAPABILITY_CODE_REFRESH_OLD:
549 {
550 /* BGP refresh capability */
551 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
552 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
553 else
554 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
555 }
556 break;
557 case CAPABILITY_CODE_ORF:
558 case CAPABILITY_CODE_ORF_OLD:
559 if (bgp_capability_orf (peer, &caphdr))
560 return -1;
561 break;
562 case CAPABILITY_CODE_RESTART:
563 if (bgp_capability_restart (peer, &caphdr))
564 return -1;
565 break;
566 case CAPABILITY_CODE_DYNAMIC:
567 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
568 break;
569 default:
570 if (caphdr.code > 128)
571 {
572 /* We don't send Notification for unknown vendor specific
573 capabilities. It seems reasonable for now... */
574 zlog_warn ("%s Vendor specific capability %d",
575 peer->host, caphdr.code);
576 }
577 else
578 {
579 zlog_warn ("%s unrecognized capability code: %d - ignored",
580 peer->host, caphdr.code);
581 memcpy (*error, sp, caphdr.length + 2);
582 *error += caphdr.length + 2;
583 }
584 }
585 if (stream_get_getp(s) != (start + caphdr.length))
586 {
587 if (stream_get_getp(s) > (start + caphdr.length))
588 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
589 peer->host, LOOKUP (capcode_str, caphdr.code),
590 caphdr.length);
591 stream_set_getp (s, start + caphdr.length);
592 }
paul718e3742002-12-13 20:15:29 +0000593 }
594 return 0;
595}
596
paul94f2b392005-06-28 12:44:16 +0000597static int
Paul Jakma6d582722007-08-06 15:21:45 +0000598bgp_auth_parse (struct peer *peer, size_t length)
paul718e3742002-12-13 20:15:29 +0000599{
600 bgp_notify_send (peer,
601 BGP_NOTIFY_OPEN_ERR,
602 BGP_NOTIFY_OPEN_AUTH_FAILURE);
603 return -1;
604}
605
paul94f2b392005-06-28 12:44:16 +0000606static int
paul718e3742002-12-13 20:15:29 +0000607strict_capability_same (struct peer *peer)
608{
609 int i, j;
610
611 for (i = AFI_IP; i < AFI_MAX; i++)
612 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
613 if (peer->afc[i][j] != peer->afc_nego[i][j])
614 return 0;
615 return 1;
616}
617
618/* Parse open option */
619int
620bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
621{
622 int ret;
paul718e3742002-12-13 20:15:29 +0000623 u_char *error;
624 u_char error_data[BGP_MAX_PACKET_SIZE];
Paul Jakma6d582722007-08-06 15:21:45 +0000625 struct stream *s = BGP_INPUT(peer);
626 size_t end = stream_get_getp (s) + length;
paul718e3742002-12-13 20:15:29 +0000627
628 ret = 0;
paul718e3742002-12-13 20:15:29 +0000629 error = error_data;
630
631 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000632 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
paul718e3742002-12-13 20:15:29 +0000633 peer->host, length);
634
Paul Jakma6d582722007-08-06 15:21:45 +0000635 while (stream_get_getp(s) < end)
paul718e3742002-12-13 20:15:29 +0000636 {
Paul Jakma6d582722007-08-06 15:21:45 +0000637 u_char opt_type;
638 u_char opt_length;
639
640 /* Must have at least an OPEN option header */
641 if (STREAM_READABLE(s) < 2)
paul718e3742002-12-13 20:15:29 +0000642 {
643 zlog_info ("%s Option length error", peer->host);
644 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
645 return -1;
646 }
647
648 /* Fetch option type and length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000649 opt_type = stream_getc (s);
650 opt_length = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000651
652 /* Option length check. */
Paul Jakma6d582722007-08-06 15:21:45 +0000653 if (STREAM_READABLE (s) < opt_length)
paul718e3742002-12-13 20:15:29 +0000654 {
655 zlog_info ("%s Option length error", peer->host);
656 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
657 return -1;
658 }
659
660 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000661 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
paul718e3742002-12-13 20:15:29 +0000662 peer->host, opt_type,
663 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
664 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
665 opt_length);
666
667 switch (opt_type)
668 {
669 case BGP_OPEN_OPT_AUTH:
Paul Jakma6d582722007-08-06 15:21:45 +0000670 ret = bgp_auth_parse (peer, opt_length);
paul718e3742002-12-13 20:15:29 +0000671 break;
672 case BGP_OPEN_OPT_CAP:
Paul Jakma6d582722007-08-06 15:21:45 +0000673 ret = bgp_capability_parse (peer, opt_length, &error);
paul718e3742002-12-13 20:15:29 +0000674 *capability = 1;
675 break;
676 default:
677 bgp_notify_send (peer,
678 BGP_NOTIFY_OPEN_ERR,
679 BGP_NOTIFY_OPEN_UNSUP_PARAM);
680 ret = -1;
681 break;
682 }
683
684 /* Parse error. To accumulate all unsupported capability codes,
685 bgp_capability_parse does not return -1 when encounter
686 unsupported capability code. To detect that, please check
687 error and erro_data pointer, like below. */
688 if (ret < 0)
689 return -1;
paul718e3742002-12-13 20:15:29 +0000690 }
691
692 /* All OPEN option is parsed. Check capability when strict compare
693 flag is enabled.*/
694 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
695 {
696 /* If Unsupported Capability exists. */
697 if (error != error_data)
698 {
699 bgp_notify_send_with_data (peer,
700 BGP_NOTIFY_OPEN_ERR,
701 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
702 error_data, error - error_data);
703 return -1;
704 }
705
706 /* Check local capability does not negotiated with remote
707 peer. */
708 if (! strict_capability_same (peer))
709 {
710 bgp_notify_send (peer,
711 BGP_NOTIFY_OPEN_ERR,
712 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
713 return -1;
714 }
715 }
716
717 /* Check there is no common capability send Unsupported Capability
718 error. */
719 if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
720 {
721 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
722 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
723 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
724 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
725 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
726 {
727 plog_err (peer->log, "%s [Error] No common capability", peer->host);
728
729 if (error != error_data)
730
731 bgp_notify_send_with_data (peer,
732 BGP_NOTIFY_OPEN_ERR,
733 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
734 error_data, error - error_data);
735 else
736 bgp_notify_send (peer,
737 BGP_NOTIFY_OPEN_ERR,
738 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
739 return -1;
740 }
741 }
742 return 0;
743}
744
paul94f2b392005-06-28 12:44:16 +0000745static void
paul718e3742002-12-13 20:15:29 +0000746bgp_open_capability_orf (struct stream *s, struct peer *peer,
747 afi_t afi, safi_t safi, u_char code)
748{
749 u_char cap_len;
750 u_char orf_len;
751 unsigned long capp;
752 unsigned long orfp;
753 unsigned long numberp;
754 int number_of_orfs = 0;
755
756 if (safi == SAFI_MPLS_VPN)
757 safi = BGP_SAFI_VPNV4;
758
759 stream_putc (s, BGP_OPEN_OPT_CAP);
paul9985f832005-02-09 15:51:56 +0000760 capp = stream_get_endp (s); /* Set Capability Len Pointer */
paul718e3742002-12-13 20:15:29 +0000761 stream_putc (s, 0); /* Capability Length */
762 stream_putc (s, code); /* Capability Code */
paul9985f832005-02-09 15:51:56 +0000763 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
paul718e3742002-12-13 20:15:29 +0000764 stream_putc (s, 0); /* ORF Length */
765 stream_putw (s, afi);
766 stream_putc (s, 0);
767 stream_putc (s, safi);
paul9985f832005-02-09 15:51:56 +0000768 numberp = stream_get_endp (s); /* Set Number Pointer */
paul718e3742002-12-13 20:15:29 +0000769 stream_putc (s, 0); /* Number of ORFs */
770
771 /* Address Prefix ORF */
772 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
773 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
774 {
775 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
776 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
777
778 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
779 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
780 {
781 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
782 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
783 stream_putc (s, ORF_MODE_BOTH);
784 }
785 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
786 {
787 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
788 stream_putc (s, ORF_MODE_SEND);
789 }
790 else
791 {
792 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
793 stream_putc (s, ORF_MODE_RECEIVE);
794 }
795 number_of_orfs++;
796 }
797
798 /* Total Number of ORFs. */
799 stream_putc_at (s, numberp, number_of_orfs);
800
801 /* Total ORF Len. */
paul9985f832005-02-09 15:51:56 +0000802 orf_len = stream_get_endp (s) - orfp - 1;
paul718e3742002-12-13 20:15:29 +0000803 stream_putc_at (s, orfp, orf_len);
804
805 /* Total Capability Len. */
paul9985f832005-02-09 15:51:56 +0000806 cap_len = stream_get_endp (s) - capp - 1;
paul718e3742002-12-13 20:15:29 +0000807 stream_putc_at (s, capp, cap_len);
808}
809
810/* Fill in capability open option to the packet. */
811void
812bgp_open_capability (struct stream *s, struct peer *peer)
813{
814 u_char len;
815 unsigned long cp;
816 afi_t afi;
817 safi_t safi;
818
819 /* Remember current pointer for Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000820 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000821
822 /* Opt Parm Len. */
823 stream_putc (s, 0);
824
825 /* Do not send capability. */
826 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
827 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
828 return;
829
paul718e3742002-12-13 20:15:29 +0000830 /* IPv4 unicast. */
831 if (peer->afc[AFI_IP][SAFI_UNICAST])
832 {
833 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
834 stream_putc (s, BGP_OPEN_OPT_CAP);
835 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
836 stream_putc (s, CAPABILITY_CODE_MP);
837 stream_putc (s, CAPABILITY_CODE_MP_LEN);
838 stream_putw (s, AFI_IP);
839 stream_putc (s, 0);
840 stream_putc (s, SAFI_UNICAST);
841 }
842 /* IPv4 multicast. */
843 if (peer->afc[AFI_IP][SAFI_MULTICAST])
844 {
845 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
846 stream_putc (s, BGP_OPEN_OPT_CAP);
847 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
848 stream_putc (s, CAPABILITY_CODE_MP);
849 stream_putc (s, CAPABILITY_CODE_MP_LEN);
850 stream_putw (s, AFI_IP);
851 stream_putc (s, 0);
852 stream_putc (s, SAFI_MULTICAST);
853 }
854 /* IPv4 VPN */
855 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
856 {
857 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
858 stream_putc (s, BGP_OPEN_OPT_CAP);
859 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
860 stream_putc (s, CAPABILITY_CODE_MP);
861 stream_putc (s, CAPABILITY_CODE_MP_LEN);
862 stream_putw (s, AFI_IP);
863 stream_putc (s, 0);
864 stream_putc (s, BGP_SAFI_VPNV4);
865 }
866#ifdef HAVE_IPV6
867 /* IPv6 unicast. */
868 if (peer->afc[AFI_IP6][SAFI_UNICAST])
869 {
870 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
871 stream_putc (s, BGP_OPEN_OPT_CAP);
872 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
873 stream_putc (s, CAPABILITY_CODE_MP);
874 stream_putc (s, CAPABILITY_CODE_MP_LEN);
875 stream_putw (s, AFI_IP6);
876 stream_putc (s, 0);
877 stream_putc (s, SAFI_UNICAST);
878 }
879 /* IPv6 multicast. */
880 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
881 {
882 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
883 stream_putc (s, BGP_OPEN_OPT_CAP);
884 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
885 stream_putc (s, CAPABILITY_CODE_MP);
886 stream_putc (s, CAPABILITY_CODE_MP_LEN);
887 stream_putw (s, AFI_IP6);
888 stream_putc (s, 0);
889 stream_putc (s, SAFI_MULTICAST);
890 }
891#endif /* HAVE_IPV6 */
892
893 /* Route refresh. */
hassoc9502432005-02-01 22:01:48 +0000894 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
895 stream_putc (s, BGP_OPEN_OPT_CAP);
896 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
897 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
898 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
899 stream_putc (s, BGP_OPEN_OPT_CAP);
900 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
901 stream_putc (s, CAPABILITY_CODE_REFRESH);
902 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
paul718e3742002-12-13 20:15:29 +0000903
904 /* ORF capability. */
905 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
906 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
907 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
908 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
909 {
910 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
911 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
912 }
913
914 /* Dynamic capability. */
915 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
916 {
917 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
918 stream_putc (s, BGP_OPEN_OPT_CAP);
919 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
920 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
921 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
922 }
923
hasso538621f2004-05-21 09:31:30 +0000924 /* Graceful restart capability */
925 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
926 {
927 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
928 stream_putc (s, BGP_OPEN_OPT_CAP);
929 stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
930 stream_putc (s, CAPABILITY_CODE_RESTART);
931 stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
932 stream_putw (s, peer->bgp->restart_time);
933 }
934
paul718e3742002-12-13 20:15:29 +0000935 /* Total Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000936 len = stream_get_endp (s) - cp - 1;
paul718e3742002-12-13 20:15:29 +0000937 stream_putc_at (s, cp, len);
938}