blob: 38431d4c63d91875c69663c7a466006a3160de8b [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"
Paul Jakma0b2aa3a2007-10-14 22:32:21 +000037#include "bgpd/bgp_aspath.h"
hasso538621f2004-05-21 09:31:30 +000038#include "bgpd/bgp_vty.h"
39
paul718e3742002-12-13 20:15:29 +000040/* 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{
paul5228ad22004-06-04 17:58:18 +000053 char *pnt;
54 char *end;
Paul Jakma6d582722007-08-06 15:21:45 +000055 struct capability_mp_data mpc;
56 struct capability_header *hdr;
paul718e3742002-12-13 20:15:29 +000057
58 pnt = peer->notify.data;
59 end = pnt + peer->notify.length;
Paul Jakma6d582722007-08-06 15:21:45 +000060
paul718e3742002-12-13 20:15:29 +000061 while (pnt < end)
62 {
Paul Jakma6d582722007-08-06 15:21:45 +000063 if (pnt + sizeof (struct capability_mp_data) + 2 > end)
paul718e3742002-12-13 20:15:29 +000064 return;
Paul Jakma6d582722007-08-06 15:21:45 +000065
66 hdr = (struct capability_header *)pnt;
67 if (pnt + hdr->length + 2 > end)
paul718e3742002-12-13 20:15:29 +000068 return;
69
Paul Jakma6d582722007-08-06 15:21:45 +000070 memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
71
72 if (hdr->code == CAPABILITY_CODE_MP)
paul718e3742002-12-13 20:15:29 +000073 {
74 vty_out (vty, " Capability error for: Multi protocol ");
75
Paul Jakma6d582722007-08-06 15:21:45 +000076 switch (ntohs (mpc.afi))
paul718e3742002-12-13 20:15:29 +000077 {
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:
Paul Jakma6d582722007-08-06 15:21:45 +000085 vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
paul718e3742002-12-13 20:15:29 +000086 break;
87 }
Paul Jakma6d582722007-08-06 15:21:45 +000088 switch (mpc.safi)
paul718e3742002-12-13 20:15:29 +000089 {
90 case SAFI_UNICAST:
91 vty_out (vty, "SAFI Unicast");
92 break;
93 case SAFI_MULTICAST:
94 vty_out (vty, "SAFI Multicast");
95 break;
96 case SAFI_UNICAST_MULTICAST:
97 vty_out (vty, "SAFI Unicast Multicast");
98 break;
99 case BGP_SAFI_VPNV4:
100 vty_out (vty, "SAFI MPLS-VPN");
101 break;
102 default:
Paul Jakma6d582722007-08-06 15:21:45 +0000103 vty_out (vty, "SAFI Unknown %d ", mpc.safi);
paul718e3742002-12-13 20:15:29 +0000104 break;
105 }
106 vty_out (vty, "%s", VTY_NEWLINE);
107 }
Paul Jakma6d582722007-08-06 15:21:45 +0000108 else if (hdr->code >= 128)
paul718e3742002-12-13 20:15:29 +0000109 vty_out (vty, " Capability error: vendor specific capability code %d",
Paul Jakma6d582722007-08-06 15:21:45 +0000110 hdr->code);
paul718e3742002-12-13 20:15:29 +0000111 else
112 vty_out (vty, " Capability error: unknown capability code %d",
Paul Jakma6d582722007-08-06 15:21:45 +0000113 hdr->code);
paul718e3742002-12-13 20:15:29 +0000114
Paul Jakma6d582722007-08-06 15:21:45 +0000115 pnt += hdr->length + 2;
paul718e3742002-12-13 20:15:29 +0000116 }
117}
118
Paul Jakma6d582722007-08-06 15:21:45 +0000119static void
120bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
121{
122 mpc->afi = stream_getw (s);
123 mpc->reserved = stream_getc (s);
124 mpc->safi = stream_getc (s);
125}
126
127int
128bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
129{
130 /* VPNvX are AFI specific */
131 if ((afi == AFI_IP6 && *safi == BGP_SAFI_VPNV4)
132 || (afi == AFI_IP && *safi == BGP_SAFI_VPNV6))
133 {
134 zlog_warn ("Invalid afi/safi combination (%u/%u)", afi, *safi);
135 return 0;
136 }
137
138 switch (afi)
139 {
140 case AFI_IP:
141#ifdef HAVE_IPV6
142 case AFI_IP6:
143#endif
144 switch (*safi)
145 {
146 /* BGP VPNvX SAFI isn't contigious with others, remap */
147 case BGP_SAFI_VPNV4:
148 case BGP_SAFI_VPNV6:
149 *safi = SAFI_MPLS_VPN;
150 case SAFI_UNICAST:
151 case SAFI_MULTICAST:
152 case SAFI_MPLS_VPN:
153 return 1;
154 }
155 }
156 zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
157
158 return 0;
159}
160
paul718e3742002-12-13 20:15:29 +0000161/* Set negotiated capability value. */
paul94f2b392005-06-28 12:44:16 +0000162static int
Paul Jakma6d582722007-08-06 15:21:45 +0000163bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
paul718e3742002-12-13 20:15:29 +0000164{
Paul Jakma6d582722007-08-06 15:21:45 +0000165 struct capability_mp_data mpc;
166 struct stream *s = BGP_INPUT (peer);
167
168 bgp_capability_mp_data (s, &mpc);
169
170 if (BGP_DEBUG (normal, NORMAL))
171 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
172 peer->host, mpc.afi, mpc.safi);
173
174 if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
175 return -1;
176
177 /* Now safi remapped, and afi/safi are valid array indices */
178 peer->afc_recv[mpc.afi][mpc.safi] = 1;
179
180 if (peer->afc[mpc.afi][mpc.safi])
Paul Jakmae08286b2007-09-18 12:11:26 +0000181 peer->afc_nego[mpc.afi][mpc.safi] = 1;
Paul Jakma6d582722007-08-06 15:21:45 +0000182 else
183 return -1;
paul718e3742002-12-13 20:15:29 +0000184
185 return 0;
186}
187
paul94f2b392005-06-28 12:44:16 +0000188static void
paul718e3742002-12-13 20:15:29 +0000189bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
190 u_char type, u_char mode)
191{
192 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000193 zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
paul718e3742002-12-13 20:15:29 +0000194 peer->host, afi, safi, type, mode);
195}
196
Paul Jakma6d582722007-08-06 15:21:45 +0000197static struct message orf_type_str[] =
paul718e3742002-12-13 20:15:29 +0000198{
Paul Jakma6d582722007-08-06 15:21:45 +0000199 { ORF_TYPE_PREFIX, "Prefixlist" },
200 { ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
201};
202static int orf_type_str_max = sizeof(orf_type_str)/sizeof(orf_type_str[0]);
203
204static struct message orf_mode_str[] =
205{
206 { ORF_MODE_RECEIVE, "Receive" },
207 { ORF_MODE_SEND, "Send" },
208 { ORF_MODE_BOTH, "Both" },
209};
210static int orf_mode_str_max = sizeof(orf_mode_str)/sizeof(orf_mode_str[0]);
211
212static int
213bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
214{
215 struct stream *s = BGP_INPUT (peer);
216 struct capability_orf_entry entry;
217 afi_t afi;
218 safi_t safi;
paul718e3742002-12-13 20:15:29 +0000219 u_char type;
220 u_char mode;
221 u_int16_t sm_cap = 0; /* capability send-mode receive */
222 u_int16_t rm_cap = 0; /* capability receive-mode receive */
223 int i;
224
Paul Jakma6d582722007-08-06 15:21:45 +0000225 /* ORF Entry header */
226 bgp_capability_mp_data (s, &entry.mpc);
227 entry.num = stream_getc (s);
228 afi = entry.mpc.afi;
229 safi = entry.mpc.safi;
230
paul718e3742002-12-13 20:15:29 +0000231 if (BGP_DEBUG (normal, NORMAL))
Paul Jakma6d582722007-08-06 15:21:45 +0000232 zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
233 peer->host, entry.mpc.afi, entry.mpc.safi);
paul718e3742002-12-13 20:15:29 +0000234
235 /* Check AFI and SAFI. */
Paul Jakma6d582722007-08-06 15:21:45 +0000236 if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
paul718e3742002-12-13 20:15:29 +0000237 {
Paul Jakma6d582722007-08-06 15:21:45 +0000238 zlog_info ("%s Addr-family %d/%d not supported."
239 " Ignoring the ORF capability",
240 peer->host, entry.mpc.afi, entry.mpc.safi);
241 return 0;
242 }
243
244 /* validate number field */
245 if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
246 {
247 zlog_info ("%s ORF Capability entry length error,"
248 " Cap length %u, num %u",
249 peer->host, hdr->length, entry.num);
250 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
paul718e3742002-12-13 20:15:29 +0000251 return -1;
252 }
253
Paul Jakma6d582722007-08-06 15:21:45 +0000254 for (i = 0 ; i < entry.num ; i++)
paul718e3742002-12-13 20:15:29 +0000255 {
Paul Jakma6d582722007-08-06 15:21:45 +0000256 type = stream_getc(s);
257 mode = stream_getc(s);
258
paul718e3742002-12-13 20:15:29 +0000259 /* ORF Mode error check */
Paul Jakma6d582722007-08-06 15:21:45 +0000260 switch (mode)
261 {
262 case ORF_MODE_BOTH:
263 case ORF_MODE_SEND:
264 case ORF_MODE_RECEIVE:
265 break;
266 default:
267 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
268 continue;
paul718e3742002-12-13 20:15:29 +0000269 }
Paul Jakma6d582722007-08-06 15:21:45 +0000270 /* ORF Type and afi/safi error checks */
271 /* capcode versus type */
272 switch (hdr->code)
273 {
274 case CAPABILITY_CODE_ORF:
275 switch (type)
276 {
277 case ORF_TYPE_PREFIX:
278 break;
279 default:
280 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
281 continue;
282 }
283 break;
284 case CAPABILITY_CODE_ORF_OLD:
285 switch (type)
286 {
287 case ORF_TYPE_PREFIX_OLD:
288 break;
289 default:
290 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
291 continue;
292 }
293 break;
294 default:
295 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
296 continue;
297 }
298
299 /* AFI vs SAFI */
300 if (!((afi == AFI_IP && safi == SAFI_UNICAST)
301 || (afi == AFI_IP && safi == SAFI_MULTICAST)
302 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
303 {
304 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
305 continue;
306 }
307
308 if (BGP_DEBUG (normal, NORMAL))
309 zlog_debug ("%s OPEN has %s ORF capability"
310 " as %s for afi/safi: %d/%d",
311 peer->host, LOOKUP (orf_type_str, type),
312 LOOKUP (orf_mode_str, mode),
313 entry.mpc.afi, safi);
paul718e3742002-12-13 20:15:29 +0000314
Paul Jakma6d582722007-08-06 15:21:45 +0000315 if (hdr->code == CAPABILITY_CODE_ORF)
paul718e3742002-12-13 20:15:29 +0000316 {
Paul Jakma6d582722007-08-06 15:21:45 +0000317 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
318 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
paul718e3742002-12-13 20:15:29 +0000319 }
Paul Jakma6d582722007-08-06 15:21:45 +0000320 else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
paul718e3742002-12-13 20:15:29 +0000321 {
Paul Jakma6d582722007-08-06 15:21:45 +0000322 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
323 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
paul718e3742002-12-13 20:15:29 +0000324 }
325 else
326 {
327 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
328 continue;
329 }
330
331 switch (mode)
332 {
333 case ORF_MODE_BOTH:
334 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
335 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
336 break;
337 case ORF_MODE_SEND:
338 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
339 break;
340 case ORF_MODE_RECEIVE:
341 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
342 break;
343 }
344 }
345 return 0;
346}
347
paul94f2b392005-06-28 12:44:16 +0000348static int
Paul Jakma6d582722007-08-06 15:21:45 +0000349bgp_capability_orf (struct peer *peer, struct capability_header *hdr)
350{
351 struct stream *s = BGP_INPUT (peer);
352 size_t end = stream_get_getp (s) + hdr->length;
353
354 assert (stream_get_getp(s) + sizeof(struct capability_orf_entry) <= end);
355
356 /* We must have at least one ORF entry, as the caller has already done
357 * minimum length validation for the capability code - for ORF there must
358 * at least one ORF entry (header and unknown number of pairs of bytes).
359 */
360 do
361 {
362 if (bgp_capability_orf_entry (peer, hdr) == -1)
363 return -1;
364 }
365 while (stream_get_getp(s) + sizeof(struct capability_orf_entry) < end);
366
367 return 0;
368}
369
370static int
371bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
372{
373 struct stream *s = BGP_INPUT (peer);
374 u_int16_t restart_flag_time;
375 int restart_bit = 0;
376 size_t end = stream_get_getp (s) + caphdr->length;
377
378 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
379 restart_flag_time = stream_getw(s);
380 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
381 restart_bit = 1;
382 UNSET_FLAG (restart_flag_time, 0xF000);
383 peer->v_gr_restart = restart_flag_time;
384
385 if (BGP_DEBUG (normal, NORMAL))
386 {
387 zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
388 zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
389 peer->host, restart_bit ? " " : " not ",
390 peer->v_gr_restart);
391 }
392
393 while (stream_get_getp (s) + 4 < end)
394 {
395 afi_t afi = stream_getw (s);
396 safi_t safi = stream_getc (s);
397 u_char flag = stream_getc (s);
398
399 if (!bgp_afi_safi_valid_indices (afi, &safi))
400 {
401 if (BGP_DEBUG (normal, NORMAL))
402 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
403 " Ignore the Graceful Restart capability",
404 peer->host, afi, safi);
405 }
406 else if (!peer->afc[afi][safi])
407 {
408 if (BGP_DEBUG (normal, NORMAL))
409 zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
410 " Ignore the Graceful Restart capability",
411 peer->host, afi, safi);
412 }
413 else
414 {
415 if (BGP_DEBUG (normal, NORMAL))
416 zlog_debug ("%s Address family %s is%spreserved", peer->host,
417 afi_safi_print (afi, safi),
418 CHECK_FLAG (peer->af_cap[afi][safi],
419 PEER_CAP_RESTART_AF_PRESERVE_RCV)
420 ? " " : " not ");
421
422 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
423 if (CHECK_FLAG (flag, RESTART_F_BIT))
424 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
425
426 }
427 }
428 return 0;
429}
430
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000431static as_t
432bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
433{
434 as_t as4 = stream_getl (BGP_INPUT(peer));
435
436 if (BGP_DEBUG (as4, AS4))
437 zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
438 peer->host, as4);
439 SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
440
441 return as4;
442}
443
Paul Jakma6d582722007-08-06 15:21:45 +0000444static struct message capcode_str[] =
445{
446 { 0, ""},
447 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
448 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
449 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
450 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
451 { CAPABILITY_CODE_AS4, "4-octet AS number" },
452 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
453 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
454 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
455};
456int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
457
458/* Minimum sizes for length field of each cap (so not inc. the header) */
459static size_t cap_minsizes[] =
460{
461 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
462 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
463 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
464 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr) - 2,
465 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
466 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
467 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
468 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
469};
470
471/* Parse given capability.
472 * XXX: This is reading into a stream, but not using stream API
473 */
474static int
475bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
paul718e3742002-12-13 20:15:29 +0000476{
477 int ret;
Paul Jakma6d582722007-08-06 15:21:45 +0000478 struct stream *s = BGP_INPUT (peer);
479 size_t end = stream_get_getp (s) + length;
480
481 assert (STREAM_READABLE (s) >= length);
482
483 while (stream_get_getp (s) < end)
paul718e3742002-12-13 20:15:29 +0000484 {
Paul Jakma6d582722007-08-06 15:21:45 +0000485 size_t start;
486 u_char *sp = stream_pnt (s);
487 struct capability_header caphdr;
488
paul718e3742002-12-13 20:15:29 +0000489 /* We need at least capability code and capability length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000490 if (stream_get_getp(s) + 2 > end)
paul718e3742002-12-13 20:15:29 +0000491 {
Paul Jakma6d582722007-08-06 15:21:45 +0000492 zlog_info ("%s Capability length error (< header)", peer->host);
paul718e3742002-12-13 20:15:29 +0000493 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
494 return -1;
495 }
Paul Jakma6d582722007-08-06 15:21:45 +0000496
497 caphdr.code = stream_getc (s);
498 caphdr.length = stream_getc (s);
499 start = stream_get_getp (s);
500
501 /* Capability length check sanity check. */
502 if (start + caphdr.length > end)
paul718e3742002-12-13 20:15:29 +0000503 {
Paul Jakma6d582722007-08-06 15:21:45 +0000504 zlog_info ("%s Capability length error (< length)", peer->host);
paul718e3742002-12-13 20:15:29 +0000505 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
506 return -1;
507 }
Paul Jakma6d582722007-08-06 15:21:45 +0000508
509 if (BGP_DEBUG (normal, NORMAL))
510 zlog_debug ("%s OPEN has %s capability (%u), length %u",
511 peer->host,
512 LOOKUP (capcode_str, caphdr.code),
513 caphdr.code, caphdr.length);
514
515 /* Length sanity check, type-specific, for known capabilities */
516 switch (caphdr.code)
517 {
518 case CAPABILITY_CODE_MP:
519 case CAPABILITY_CODE_REFRESH:
520 case CAPABILITY_CODE_REFRESH_OLD:
521 case CAPABILITY_CODE_ORF:
522 case CAPABILITY_CODE_ORF_OLD:
523 case CAPABILITY_CODE_RESTART:
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000524 case CAPABILITY_CODE_AS4:
Paul Jakma6d582722007-08-06 15:21:45 +0000525 case CAPABILITY_CODE_DYNAMIC:
526 /* Check length. */
527 if (caphdr.length < cap_minsizes[caphdr.code])
528 {
529 zlog_info ("%s %s Capability length error: got %u,"
530 " expected at least %u",
531 peer->host,
532 LOOKUP (capcode_str, caphdr.code),
533 caphdr.length, cap_minsizes[caphdr.code]);
534 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
535 return -1;
536 }
537 /* we deliberately ignore unknown codes, see below */
538 default:
539 break;
540 }
541
542 switch (caphdr.code)
543 {
544 case CAPABILITY_CODE_MP:
545 {
546 /* Ignore capability when override-capability is set. */
547 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
548 {
549 /* Set negotiated value. */
550 ret = bgp_capability_mp (peer, &caphdr);
paul718e3742002-12-13 20:15:29 +0000551
Paul Jakma6d582722007-08-06 15:21:45 +0000552 /* Unsupported Capability. */
553 if (ret < 0)
554 {
555 /* Store return data. */
556 memcpy (*error, sp, caphdr.length + 2);
557 *error += caphdr.length + 2;
558 }
559 }
560 }
561 break;
562 case CAPABILITY_CODE_REFRESH:
563 case CAPABILITY_CODE_REFRESH_OLD:
564 {
565 /* BGP refresh capability */
566 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
567 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
568 else
569 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
570 }
571 break;
572 case CAPABILITY_CODE_ORF:
573 case CAPABILITY_CODE_ORF_OLD:
574 if (bgp_capability_orf (peer, &caphdr))
575 return -1;
576 break;
577 case CAPABILITY_CODE_RESTART:
578 if (bgp_capability_restart (peer, &caphdr))
579 return -1;
580 break;
581 case CAPABILITY_CODE_DYNAMIC:
582 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
583 break;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000584 case CAPABILITY_CODE_AS4:
585 /* Already handled as a special-case parsing of the capabilities
586 * at the beginning of OPEN processing. So we care not a jot
587 * for the value really, only error case.
588 */
589 if (!bgp_capability_as4 (peer, &caphdr))
590 return -1;
591 break;
Paul Jakma6d582722007-08-06 15:21:45 +0000592 default:
593 if (caphdr.code > 128)
594 {
595 /* We don't send Notification for unknown vendor specific
596 capabilities. It seems reasonable for now... */
597 zlog_warn ("%s Vendor specific capability %d",
598 peer->host, caphdr.code);
599 }
600 else
601 {
602 zlog_warn ("%s unrecognized capability code: %d - ignored",
603 peer->host, caphdr.code);
604 memcpy (*error, sp, caphdr.length + 2);
605 *error += caphdr.length + 2;
606 }
607 }
608 if (stream_get_getp(s) != (start + caphdr.length))
609 {
610 if (stream_get_getp(s) > (start + caphdr.length))
611 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
612 peer->host, LOOKUP (capcode_str, caphdr.code),
613 caphdr.length);
614 stream_set_getp (s, start + caphdr.length);
615 }
paul718e3742002-12-13 20:15:29 +0000616 }
617 return 0;
618}
619
paul94f2b392005-06-28 12:44:16 +0000620static int
Paul Jakma6d582722007-08-06 15:21:45 +0000621bgp_auth_parse (struct peer *peer, size_t length)
paul718e3742002-12-13 20:15:29 +0000622{
623 bgp_notify_send (peer,
624 BGP_NOTIFY_OPEN_ERR,
625 BGP_NOTIFY_OPEN_AUTH_FAILURE);
626 return -1;
627}
628
paul94f2b392005-06-28 12:44:16 +0000629static int
paul718e3742002-12-13 20:15:29 +0000630strict_capability_same (struct peer *peer)
631{
632 int i, j;
633
634 for (i = AFI_IP; i < AFI_MAX; i++)
635 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
636 if (peer->afc[i][j] != peer->afc_nego[i][j])
637 return 0;
638 return 1;
639}
640
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000641/* peek into option, stores ASN to *as4 if the AS4 capability was found.
642 * Returns 0 if no as4 found, as4cap value otherwise.
643 */
644as_t
645peek_for_as4_capability (struct peer *peer, u_char length)
646{
647 struct stream *s = BGP_INPUT (peer);
648 size_t orig_getp = stream_get_getp (s);
649 size_t end = orig_getp + length;
650 as_t as4 = 0;
651
652 /* The full capability parser will better flag the error.. */
653 if (STREAM_READABLE(s) < length)
654 return 0;
655
656 if (BGP_DEBUG (as4, AS4))
657 zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
658 " peeking for as4",
659 peer->host, length);
660 /* the error cases we DONT handle, we ONLY try to read as4 out of
661 * correctly formatted options.
662 */
663 while (stream_get_getp(s) < end)
664 {
665 u_char opt_type;
666 u_char opt_length;
667
668 /* Check the length. */
669 if (stream_get_getp (s) + 2 > end)
670 goto end;
671
672 /* Fetch option type and length. */
673 opt_type = stream_getc (s);
674 opt_length = stream_getc (s);
675
676 /* Option length check. */
677 if (stream_get_getp (s) + opt_length > end)
678 goto end;
679
680 if (opt_type == BGP_OPEN_OPT_CAP)
681 {
682 unsigned long capd_start = stream_get_getp (s);
683 unsigned long capd_end = capd_start + opt_length;
684
685 assert (capd_end <= end);
686
687 while (stream_get_getp (s) < capd_end)
688 {
689 struct capability_header hdr;
690
691 if (stream_get_getp (s) + 2 > capd_end)
692 goto end;
693
694 hdr.code = stream_getc (s);
695 hdr.length = stream_getc (s);
696
697 if ((stream_get_getp(s) + hdr.length) > capd_end)
698 goto end;
699
700 if (hdr.code == CAPABILITY_CODE_AS4)
701 {
702 if (hdr.length != CAPABILITY_CODE_AS4_LEN)
703 goto end;
704
705 if (BGP_DEBUG (as4, AS4))
706 zlog_info ("[AS4] found AS4 capability, about to parse");
707 as4 = bgp_capability_as4 (peer, &hdr);
708
709 goto end;
710 }
711 stream_forward_getp (s, hdr.length);
712 }
713 }
714 }
715
716end:
717 stream_set_getp (s, orig_getp);
718 return as4;
719}
720
paul718e3742002-12-13 20:15:29 +0000721/* Parse open option */
722int
723bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
724{
725 int ret;
paul718e3742002-12-13 20:15:29 +0000726 u_char *error;
727 u_char error_data[BGP_MAX_PACKET_SIZE];
Paul Jakma6d582722007-08-06 15:21:45 +0000728 struct stream *s = BGP_INPUT(peer);
729 size_t end = stream_get_getp (s) + length;
paul718e3742002-12-13 20:15:29 +0000730
731 ret = 0;
paul718e3742002-12-13 20:15:29 +0000732 error = error_data;
733
734 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000735 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
paul718e3742002-12-13 20:15:29 +0000736 peer->host, length);
737
Paul Jakma6d582722007-08-06 15:21:45 +0000738 while (stream_get_getp(s) < end)
paul718e3742002-12-13 20:15:29 +0000739 {
Paul Jakma6d582722007-08-06 15:21:45 +0000740 u_char opt_type;
741 u_char opt_length;
742
743 /* Must have at least an OPEN option header */
744 if (STREAM_READABLE(s) < 2)
paul718e3742002-12-13 20:15:29 +0000745 {
746 zlog_info ("%s Option length error", peer->host);
747 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
748 return -1;
749 }
750
751 /* Fetch option type and length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000752 opt_type = stream_getc (s);
753 opt_length = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000754
755 /* Option length check. */
Paul Jakma6d582722007-08-06 15:21:45 +0000756 if (STREAM_READABLE (s) < opt_length)
paul718e3742002-12-13 20:15:29 +0000757 {
758 zlog_info ("%s Option length error", peer->host);
759 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
760 return -1;
761 }
762
763 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000764 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
paul718e3742002-12-13 20:15:29 +0000765 peer->host, opt_type,
766 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
767 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
768 opt_length);
769
770 switch (opt_type)
771 {
772 case BGP_OPEN_OPT_AUTH:
Paul Jakma6d582722007-08-06 15:21:45 +0000773 ret = bgp_auth_parse (peer, opt_length);
paul718e3742002-12-13 20:15:29 +0000774 break;
775 case BGP_OPEN_OPT_CAP:
Paul Jakma6d582722007-08-06 15:21:45 +0000776 ret = bgp_capability_parse (peer, opt_length, &error);
paul718e3742002-12-13 20:15:29 +0000777 *capability = 1;
778 break;
779 default:
780 bgp_notify_send (peer,
781 BGP_NOTIFY_OPEN_ERR,
782 BGP_NOTIFY_OPEN_UNSUP_PARAM);
783 ret = -1;
784 break;
785 }
786
787 /* Parse error. To accumulate all unsupported capability codes,
788 bgp_capability_parse does not return -1 when encounter
789 unsupported capability code. To detect that, please check
790 error and erro_data pointer, like below. */
791 if (ret < 0)
792 return -1;
paul718e3742002-12-13 20:15:29 +0000793 }
794
795 /* All OPEN option is parsed. Check capability when strict compare
796 flag is enabled.*/
797 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
798 {
799 /* If Unsupported Capability exists. */
800 if (error != error_data)
801 {
802 bgp_notify_send_with_data (peer,
803 BGP_NOTIFY_OPEN_ERR,
804 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
805 error_data, error - error_data);
806 return -1;
807 }
808
809 /* Check local capability does not negotiated with remote
810 peer. */
811 if (! strict_capability_same (peer))
812 {
813 bgp_notify_send (peer,
814 BGP_NOTIFY_OPEN_ERR,
815 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
816 return -1;
817 }
818 }
819
820 /* Check there is no common capability send Unsupported Capability
821 error. */
822 if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
823 {
824 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
825 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
826 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
827 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
828 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
829 {
830 plog_err (peer->log, "%s [Error] No common capability", peer->host);
831
832 if (error != error_data)
833
834 bgp_notify_send_with_data (peer,
835 BGP_NOTIFY_OPEN_ERR,
836 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
837 error_data, error - error_data);
838 else
839 bgp_notify_send (peer,
840 BGP_NOTIFY_OPEN_ERR,
841 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
842 return -1;
843 }
844 }
845 return 0;
846}
847
paul94f2b392005-06-28 12:44:16 +0000848static void
paul718e3742002-12-13 20:15:29 +0000849bgp_open_capability_orf (struct stream *s, struct peer *peer,
850 afi_t afi, safi_t safi, u_char code)
851{
852 u_char cap_len;
853 u_char orf_len;
854 unsigned long capp;
855 unsigned long orfp;
856 unsigned long numberp;
857 int number_of_orfs = 0;
858
859 if (safi == SAFI_MPLS_VPN)
860 safi = BGP_SAFI_VPNV4;
861
862 stream_putc (s, BGP_OPEN_OPT_CAP);
paul9985f832005-02-09 15:51:56 +0000863 capp = stream_get_endp (s); /* Set Capability Len Pointer */
paul718e3742002-12-13 20:15:29 +0000864 stream_putc (s, 0); /* Capability Length */
865 stream_putc (s, code); /* Capability Code */
paul9985f832005-02-09 15:51:56 +0000866 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
paul718e3742002-12-13 20:15:29 +0000867 stream_putc (s, 0); /* ORF Length */
868 stream_putw (s, afi);
869 stream_putc (s, 0);
870 stream_putc (s, safi);
paul9985f832005-02-09 15:51:56 +0000871 numberp = stream_get_endp (s); /* Set Number Pointer */
paul718e3742002-12-13 20:15:29 +0000872 stream_putc (s, 0); /* Number of ORFs */
873
874 /* Address Prefix ORF */
875 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
876 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
877 {
878 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
879 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
880
881 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
882 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
883 {
884 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
885 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
886 stream_putc (s, ORF_MODE_BOTH);
887 }
888 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
889 {
890 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
891 stream_putc (s, ORF_MODE_SEND);
892 }
893 else
894 {
895 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
896 stream_putc (s, ORF_MODE_RECEIVE);
897 }
898 number_of_orfs++;
899 }
900
901 /* Total Number of ORFs. */
902 stream_putc_at (s, numberp, number_of_orfs);
903
904 /* Total ORF Len. */
paul9985f832005-02-09 15:51:56 +0000905 orf_len = stream_get_endp (s) - orfp - 1;
paul718e3742002-12-13 20:15:29 +0000906 stream_putc_at (s, orfp, orf_len);
907
908 /* Total Capability Len. */
paul9985f832005-02-09 15:51:56 +0000909 cap_len = stream_get_endp (s) - capp - 1;
paul718e3742002-12-13 20:15:29 +0000910 stream_putc_at (s, capp, cap_len);
911}
912
913/* Fill in capability open option to the packet. */
914void
915bgp_open_capability (struct stream *s, struct peer *peer)
916{
917 u_char len;
918 unsigned long cp;
919 afi_t afi;
920 safi_t safi;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000921 as_t local_as;
paul718e3742002-12-13 20:15:29 +0000922
923 /* Remember current pointer for Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000924 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000925
926 /* Opt Parm Len. */
927 stream_putc (s, 0);
928
929 /* Do not send capability. */
930 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
931 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
932 return;
933
paul718e3742002-12-13 20:15:29 +0000934 /* IPv4 unicast. */
935 if (peer->afc[AFI_IP][SAFI_UNICAST])
936 {
937 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
938 stream_putc (s, BGP_OPEN_OPT_CAP);
939 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
940 stream_putc (s, CAPABILITY_CODE_MP);
941 stream_putc (s, CAPABILITY_CODE_MP_LEN);
942 stream_putw (s, AFI_IP);
943 stream_putc (s, 0);
944 stream_putc (s, SAFI_UNICAST);
945 }
946 /* IPv4 multicast. */
947 if (peer->afc[AFI_IP][SAFI_MULTICAST])
948 {
949 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
950 stream_putc (s, BGP_OPEN_OPT_CAP);
951 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
952 stream_putc (s, CAPABILITY_CODE_MP);
953 stream_putc (s, CAPABILITY_CODE_MP_LEN);
954 stream_putw (s, AFI_IP);
955 stream_putc (s, 0);
956 stream_putc (s, SAFI_MULTICAST);
957 }
958 /* IPv4 VPN */
959 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
960 {
961 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
962 stream_putc (s, BGP_OPEN_OPT_CAP);
963 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
964 stream_putc (s, CAPABILITY_CODE_MP);
965 stream_putc (s, CAPABILITY_CODE_MP_LEN);
966 stream_putw (s, AFI_IP);
967 stream_putc (s, 0);
968 stream_putc (s, BGP_SAFI_VPNV4);
969 }
970#ifdef HAVE_IPV6
971 /* IPv6 unicast. */
972 if (peer->afc[AFI_IP6][SAFI_UNICAST])
973 {
974 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
975 stream_putc (s, BGP_OPEN_OPT_CAP);
976 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
977 stream_putc (s, CAPABILITY_CODE_MP);
978 stream_putc (s, CAPABILITY_CODE_MP_LEN);
979 stream_putw (s, AFI_IP6);
980 stream_putc (s, 0);
981 stream_putc (s, SAFI_UNICAST);
982 }
983 /* IPv6 multicast. */
984 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
985 {
986 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
987 stream_putc (s, BGP_OPEN_OPT_CAP);
988 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
989 stream_putc (s, CAPABILITY_CODE_MP);
990 stream_putc (s, CAPABILITY_CODE_MP_LEN);
991 stream_putw (s, AFI_IP6);
992 stream_putc (s, 0);
993 stream_putc (s, SAFI_MULTICAST);
994 }
995#endif /* HAVE_IPV6 */
996
997 /* Route refresh. */
hassoc9502432005-02-01 22:01:48 +0000998 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
999 stream_putc (s, BGP_OPEN_OPT_CAP);
1000 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1001 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1002 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1003 stream_putc (s, BGP_OPEN_OPT_CAP);
1004 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1005 stream_putc (s, CAPABILITY_CODE_REFRESH);
1006 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
paul718e3742002-12-13 20:15:29 +00001007
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001008 /* AS4 */
1009 SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1010 stream_putc (s, BGP_OPEN_OPT_CAP);
1011 stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1012 stream_putc (s, CAPABILITY_CODE_AS4);
1013 stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1014 if ( peer->change_local_as )
1015 local_as = peer->change_local_as;
1016 else
1017 local_as = peer->local_as;
1018 stream_putl (s, local_as );
1019
paul718e3742002-12-13 20:15:29 +00001020 /* ORF capability. */
1021 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1022 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1023 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1024 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1025 {
1026 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1027 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1028 }
1029
1030 /* Dynamic capability. */
1031 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1032 {
1033 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1034 stream_putc (s, BGP_OPEN_OPT_CAP);
1035 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1036 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1037 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1038 }
1039
hasso538621f2004-05-21 09:31:30 +00001040 /* Graceful restart capability */
1041 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1042 {
1043 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1044 stream_putc (s, BGP_OPEN_OPT_CAP);
1045 stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
1046 stream_putc (s, CAPABILITY_CODE_RESTART);
1047 stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
1048 stream_putw (s, peer->bgp->restart_time);
1049 }
1050
paul718e3742002-12-13 20:15:29 +00001051 /* Total Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +00001052 len = stream_get_endp (s) - cp - 1;
paul718e3742002-12-13 20:15:29 +00001053 stream_putc_at (s, cp, len);
1054}