blob: 84d8191eab76f9642c25cc4350481c960ae7f645 [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{
Paul Jakma6d582722007-08-06 15:21:45 +0000446 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
447 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
448 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
449 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
450 { CAPABILITY_CODE_AS4, "4-octet AS number" },
451 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
452 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
453 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
454};
455int capcode_str_max = sizeof(capcode_str)/sizeof(capcode_str[0]);
456
457/* Minimum sizes for length field of each cap (so not inc. the header) */
458static size_t cap_minsizes[] =
459{
460 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
461 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
462 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
Paul Jakma370b64a2007-12-22 16:49:52 +0000463 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
Paul Jakma6d582722007-08-06 15:21:45 +0000464 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
465 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
466 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
467 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
468};
469
470/* Parse given capability.
471 * XXX: This is reading into a stream, but not using stream API
472 */
473static int
474bgp_capability_parse (struct peer *peer, size_t length, u_char **error)
paul718e3742002-12-13 20:15:29 +0000475{
476 int ret;
Paul Jakma6d582722007-08-06 15:21:45 +0000477 struct stream *s = BGP_INPUT (peer);
478 size_t end = stream_get_getp (s) + length;
479
480 assert (STREAM_READABLE (s) >= length);
481
482 while (stream_get_getp (s) < end)
paul718e3742002-12-13 20:15:29 +0000483 {
Paul Jakma6d582722007-08-06 15:21:45 +0000484 size_t start;
485 u_char *sp = stream_pnt (s);
486 struct capability_header caphdr;
487
paul718e3742002-12-13 20:15:29 +0000488 /* We need at least capability code and capability length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000489 if (stream_get_getp(s) + 2 > end)
paul718e3742002-12-13 20:15:29 +0000490 {
Paul Jakma6d582722007-08-06 15:21:45 +0000491 zlog_info ("%s Capability length error (< header)", peer->host);
paul718e3742002-12-13 20:15:29 +0000492 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
493 return -1;
494 }
Paul Jakma6d582722007-08-06 15:21:45 +0000495
496 caphdr.code = stream_getc (s);
497 caphdr.length = stream_getc (s);
498 start = stream_get_getp (s);
499
500 /* Capability length check sanity check. */
501 if (start + caphdr.length > end)
paul718e3742002-12-13 20:15:29 +0000502 {
Paul Jakma6d582722007-08-06 15:21:45 +0000503 zlog_info ("%s Capability length error (< length)", peer->host);
paul718e3742002-12-13 20:15:29 +0000504 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
505 return -1;
506 }
Paul Jakma6d582722007-08-06 15:21:45 +0000507
508 if (BGP_DEBUG (normal, NORMAL))
509 zlog_debug ("%s OPEN has %s capability (%u), length %u",
510 peer->host,
511 LOOKUP (capcode_str, caphdr.code),
512 caphdr.code, caphdr.length);
513
514 /* Length sanity check, type-specific, for known capabilities */
515 switch (caphdr.code)
516 {
517 case CAPABILITY_CODE_MP:
518 case CAPABILITY_CODE_REFRESH:
519 case CAPABILITY_CODE_REFRESH_OLD:
520 case CAPABILITY_CODE_ORF:
521 case CAPABILITY_CODE_ORF_OLD:
522 case CAPABILITY_CODE_RESTART:
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000523 case CAPABILITY_CODE_AS4:
Paul Jakma6d582722007-08-06 15:21:45 +0000524 case CAPABILITY_CODE_DYNAMIC:
525 /* Check length. */
526 if (caphdr.length < cap_minsizes[caphdr.code])
527 {
528 zlog_info ("%s %s Capability length error: got %u,"
529 " expected at least %u",
530 peer->host,
531 LOOKUP (capcode_str, caphdr.code),
532 caphdr.length, cap_minsizes[caphdr.code]);
533 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
534 return -1;
535 }
536 /* we deliberately ignore unknown codes, see below */
537 default:
538 break;
539 }
540
541 switch (caphdr.code)
542 {
543 case CAPABILITY_CODE_MP:
544 {
545 /* Ignore capability when override-capability is set. */
546 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
547 {
548 /* Set negotiated value. */
549 ret = bgp_capability_mp (peer, &caphdr);
paul718e3742002-12-13 20:15:29 +0000550
Paul Jakma6d582722007-08-06 15:21:45 +0000551 /* Unsupported Capability. */
552 if (ret < 0)
553 {
554 /* Store return data. */
555 memcpy (*error, sp, caphdr.length + 2);
556 *error += caphdr.length + 2;
557 }
558 }
559 }
560 break;
561 case CAPABILITY_CODE_REFRESH:
562 case CAPABILITY_CODE_REFRESH_OLD:
563 {
564 /* BGP refresh capability */
565 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
566 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
567 else
568 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
569 }
570 break;
571 case CAPABILITY_CODE_ORF:
572 case CAPABILITY_CODE_ORF_OLD:
573 if (bgp_capability_orf (peer, &caphdr))
574 return -1;
575 break;
576 case CAPABILITY_CODE_RESTART:
577 if (bgp_capability_restart (peer, &caphdr))
578 return -1;
579 break;
580 case CAPABILITY_CODE_DYNAMIC:
581 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
582 break;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000583 case CAPABILITY_CODE_AS4:
584 /* Already handled as a special-case parsing of the capabilities
585 * at the beginning of OPEN processing. So we care not a jot
586 * for the value really, only error case.
587 */
588 if (!bgp_capability_as4 (peer, &caphdr))
589 return -1;
590 break;
Paul Jakma6d582722007-08-06 15:21:45 +0000591 default:
592 if (caphdr.code > 128)
593 {
594 /* We don't send Notification for unknown vendor specific
595 capabilities. It seems reasonable for now... */
596 zlog_warn ("%s Vendor specific capability %d",
597 peer->host, caphdr.code);
598 }
599 else
600 {
601 zlog_warn ("%s unrecognized capability code: %d - ignored",
602 peer->host, caphdr.code);
603 memcpy (*error, sp, caphdr.length + 2);
604 *error += caphdr.length + 2;
605 }
606 }
607 if (stream_get_getp(s) != (start + caphdr.length))
608 {
609 if (stream_get_getp(s) > (start + caphdr.length))
610 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
611 peer->host, LOOKUP (capcode_str, caphdr.code),
612 caphdr.length);
613 stream_set_getp (s, start + caphdr.length);
614 }
paul718e3742002-12-13 20:15:29 +0000615 }
616 return 0;
617}
618
paul94f2b392005-06-28 12:44:16 +0000619static int
Paul Jakma6d582722007-08-06 15:21:45 +0000620bgp_auth_parse (struct peer *peer, size_t length)
paul718e3742002-12-13 20:15:29 +0000621{
622 bgp_notify_send (peer,
623 BGP_NOTIFY_OPEN_ERR,
624 BGP_NOTIFY_OPEN_AUTH_FAILURE);
625 return -1;
626}
627
paul94f2b392005-06-28 12:44:16 +0000628static int
paul718e3742002-12-13 20:15:29 +0000629strict_capability_same (struct peer *peer)
630{
631 int i, j;
632
633 for (i = AFI_IP; i < AFI_MAX; i++)
634 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
635 if (peer->afc[i][j] != peer->afc_nego[i][j])
636 return 0;
637 return 1;
638}
639
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000640/* peek into option, stores ASN to *as4 if the AS4 capability was found.
641 * Returns 0 if no as4 found, as4cap value otherwise.
642 */
643as_t
644peek_for_as4_capability (struct peer *peer, u_char length)
645{
646 struct stream *s = BGP_INPUT (peer);
647 size_t orig_getp = stream_get_getp (s);
648 size_t end = orig_getp + length;
649 as_t as4 = 0;
650
651 /* The full capability parser will better flag the error.. */
652 if (STREAM_READABLE(s) < length)
653 return 0;
654
655 if (BGP_DEBUG (as4, AS4))
656 zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
657 " peeking for as4",
658 peer->host, length);
659 /* the error cases we DONT handle, we ONLY try to read as4 out of
660 * correctly formatted options.
661 */
662 while (stream_get_getp(s) < end)
663 {
664 u_char opt_type;
665 u_char opt_length;
666
667 /* Check the length. */
668 if (stream_get_getp (s) + 2 > end)
669 goto end;
670
671 /* Fetch option type and length. */
672 opt_type = stream_getc (s);
673 opt_length = stream_getc (s);
674
675 /* Option length check. */
676 if (stream_get_getp (s) + opt_length > end)
677 goto end;
678
679 if (opt_type == BGP_OPEN_OPT_CAP)
680 {
681 unsigned long capd_start = stream_get_getp (s);
682 unsigned long capd_end = capd_start + opt_length;
683
684 assert (capd_end <= end);
685
686 while (stream_get_getp (s) < capd_end)
687 {
688 struct capability_header hdr;
689
690 if (stream_get_getp (s) + 2 > capd_end)
691 goto end;
692
693 hdr.code = stream_getc (s);
694 hdr.length = stream_getc (s);
695
696 if ((stream_get_getp(s) + hdr.length) > capd_end)
697 goto end;
698
699 if (hdr.code == CAPABILITY_CODE_AS4)
700 {
701 if (hdr.length != CAPABILITY_CODE_AS4_LEN)
702 goto end;
703
704 if (BGP_DEBUG (as4, AS4))
705 zlog_info ("[AS4] found AS4 capability, about to parse");
706 as4 = bgp_capability_as4 (peer, &hdr);
707
708 goto end;
709 }
710 stream_forward_getp (s, hdr.length);
711 }
712 }
713 }
714
715end:
716 stream_set_getp (s, orig_getp);
717 return as4;
718}
719
paul718e3742002-12-13 20:15:29 +0000720/* Parse open option */
721int
722bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
723{
724 int ret;
paul718e3742002-12-13 20:15:29 +0000725 u_char *error;
726 u_char error_data[BGP_MAX_PACKET_SIZE];
Paul Jakma6d582722007-08-06 15:21:45 +0000727 struct stream *s = BGP_INPUT(peer);
728 size_t end = stream_get_getp (s) + length;
paul718e3742002-12-13 20:15:29 +0000729
730 ret = 0;
paul718e3742002-12-13 20:15:29 +0000731 error = error_data;
732
733 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000734 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
paul718e3742002-12-13 20:15:29 +0000735 peer->host, length);
736
Paul Jakma6d582722007-08-06 15:21:45 +0000737 while (stream_get_getp(s) < end)
paul718e3742002-12-13 20:15:29 +0000738 {
Paul Jakma6d582722007-08-06 15:21:45 +0000739 u_char opt_type;
740 u_char opt_length;
741
742 /* Must have at least an OPEN option header */
743 if (STREAM_READABLE(s) < 2)
paul718e3742002-12-13 20:15:29 +0000744 {
745 zlog_info ("%s Option length error", peer->host);
746 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
747 return -1;
748 }
749
750 /* Fetch option type and length. */
Paul Jakma6d582722007-08-06 15:21:45 +0000751 opt_type = stream_getc (s);
752 opt_length = stream_getc (s);
paul718e3742002-12-13 20:15:29 +0000753
754 /* Option length check. */
Paul Jakma6d582722007-08-06 15:21:45 +0000755 if (STREAM_READABLE (s) < opt_length)
paul718e3742002-12-13 20:15:29 +0000756 {
757 zlog_info ("%s Option length error", peer->host);
758 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
759 return -1;
760 }
761
762 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000763 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
paul718e3742002-12-13 20:15:29 +0000764 peer->host, opt_type,
765 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
766 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
767 opt_length);
768
769 switch (opt_type)
770 {
771 case BGP_OPEN_OPT_AUTH:
Paul Jakma6d582722007-08-06 15:21:45 +0000772 ret = bgp_auth_parse (peer, opt_length);
paul718e3742002-12-13 20:15:29 +0000773 break;
774 case BGP_OPEN_OPT_CAP:
Paul Jakma6d582722007-08-06 15:21:45 +0000775 ret = bgp_capability_parse (peer, opt_length, &error);
paul718e3742002-12-13 20:15:29 +0000776 *capability = 1;
777 break;
778 default:
779 bgp_notify_send (peer,
780 BGP_NOTIFY_OPEN_ERR,
781 BGP_NOTIFY_OPEN_UNSUP_PARAM);
782 ret = -1;
783 break;
784 }
785
786 /* Parse error. To accumulate all unsupported capability codes,
787 bgp_capability_parse does not return -1 when encounter
788 unsupported capability code. To detect that, please check
789 error and erro_data pointer, like below. */
790 if (ret < 0)
791 return -1;
paul718e3742002-12-13 20:15:29 +0000792 }
793
794 /* All OPEN option is parsed. Check capability when strict compare
795 flag is enabled.*/
796 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
797 {
798 /* If Unsupported Capability exists. */
799 if (error != error_data)
800 {
801 bgp_notify_send_with_data (peer,
802 BGP_NOTIFY_OPEN_ERR,
803 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
804 error_data, error - error_data);
805 return -1;
806 }
807
808 /* Check local capability does not negotiated with remote
809 peer. */
810 if (! strict_capability_same (peer))
811 {
812 bgp_notify_send (peer,
813 BGP_NOTIFY_OPEN_ERR,
814 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
815 return -1;
816 }
817 }
818
819 /* Check there is no common capability send Unsupported Capability
820 error. */
821 if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
822 {
823 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
824 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
825 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
826 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
827 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
828 {
829 plog_err (peer->log, "%s [Error] No common capability", peer->host);
830
831 if (error != error_data)
832
833 bgp_notify_send_with_data (peer,
834 BGP_NOTIFY_OPEN_ERR,
835 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
836 error_data, error - error_data);
837 else
838 bgp_notify_send (peer,
839 BGP_NOTIFY_OPEN_ERR,
840 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
841 return -1;
842 }
843 }
844 return 0;
845}
846
paul94f2b392005-06-28 12:44:16 +0000847static void
paul718e3742002-12-13 20:15:29 +0000848bgp_open_capability_orf (struct stream *s, struct peer *peer,
849 afi_t afi, safi_t safi, u_char code)
850{
851 u_char cap_len;
852 u_char orf_len;
853 unsigned long capp;
854 unsigned long orfp;
855 unsigned long numberp;
856 int number_of_orfs = 0;
857
858 if (safi == SAFI_MPLS_VPN)
859 safi = BGP_SAFI_VPNV4;
860
861 stream_putc (s, BGP_OPEN_OPT_CAP);
paul9985f832005-02-09 15:51:56 +0000862 capp = stream_get_endp (s); /* Set Capability Len Pointer */
paul718e3742002-12-13 20:15:29 +0000863 stream_putc (s, 0); /* Capability Length */
864 stream_putc (s, code); /* Capability Code */
paul9985f832005-02-09 15:51:56 +0000865 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
paul718e3742002-12-13 20:15:29 +0000866 stream_putc (s, 0); /* ORF Length */
867 stream_putw (s, afi);
868 stream_putc (s, 0);
869 stream_putc (s, safi);
paul9985f832005-02-09 15:51:56 +0000870 numberp = stream_get_endp (s); /* Set Number Pointer */
paul718e3742002-12-13 20:15:29 +0000871 stream_putc (s, 0); /* Number of ORFs */
872
873 /* Address Prefix ORF */
874 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
875 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
876 {
877 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
878 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
879
880 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
881 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
882 {
883 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
884 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
885 stream_putc (s, ORF_MODE_BOTH);
886 }
887 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
888 {
889 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
890 stream_putc (s, ORF_MODE_SEND);
891 }
892 else
893 {
894 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
895 stream_putc (s, ORF_MODE_RECEIVE);
896 }
897 number_of_orfs++;
898 }
899
900 /* Total Number of ORFs. */
901 stream_putc_at (s, numberp, number_of_orfs);
902
903 /* Total ORF Len. */
paul9985f832005-02-09 15:51:56 +0000904 orf_len = stream_get_endp (s) - orfp - 1;
paul718e3742002-12-13 20:15:29 +0000905 stream_putc_at (s, orfp, orf_len);
906
907 /* Total Capability Len. */
paul9985f832005-02-09 15:51:56 +0000908 cap_len = stream_get_endp (s) - capp - 1;
paul718e3742002-12-13 20:15:29 +0000909 stream_putc_at (s, capp, cap_len);
910}
911
912/* Fill in capability open option to the packet. */
913void
914bgp_open_capability (struct stream *s, struct peer *peer)
915{
916 u_char len;
917 unsigned long cp;
918 afi_t afi;
919 safi_t safi;
Paul Jakma0b2aa3a2007-10-14 22:32:21 +0000920 as_t local_as;
paul718e3742002-12-13 20:15:29 +0000921
922 /* Remember current pointer for Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000923 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000924
925 /* Opt Parm Len. */
926 stream_putc (s, 0);
927
928 /* Do not send capability. */
929 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
930 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
931 return;
932
paul718e3742002-12-13 20:15:29 +0000933 /* IPv4 unicast. */
934 if (peer->afc[AFI_IP][SAFI_UNICAST])
935 {
936 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
937 stream_putc (s, BGP_OPEN_OPT_CAP);
938 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
939 stream_putc (s, CAPABILITY_CODE_MP);
940 stream_putc (s, CAPABILITY_CODE_MP_LEN);
941 stream_putw (s, AFI_IP);
942 stream_putc (s, 0);
943 stream_putc (s, SAFI_UNICAST);
944 }
945 /* IPv4 multicast. */
946 if (peer->afc[AFI_IP][SAFI_MULTICAST])
947 {
948 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
949 stream_putc (s, BGP_OPEN_OPT_CAP);
950 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
951 stream_putc (s, CAPABILITY_CODE_MP);
952 stream_putc (s, CAPABILITY_CODE_MP_LEN);
953 stream_putw (s, AFI_IP);
954 stream_putc (s, 0);
955 stream_putc (s, SAFI_MULTICAST);
956 }
957 /* IPv4 VPN */
958 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
959 {
960 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 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_IP);
966 stream_putc (s, 0);
967 stream_putc (s, BGP_SAFI_VPNV4);
968 }
969#ifdef HAVE_IPV6
970 /* IPv6 unicast. */
971 if (peer->afc[AFI_IP6][SAFI_UNICAST])
972 {
973 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
974 stream_putc (s, BGP_OPEN_OPT_CAP);
975 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
976 stream_putc (s, CAPABILITY_CODE_MP);
977 stream_putc (s, CAPABILITY_CODE_MP_LEN);
978 stream_putw (s, AFI_IP6);
979 stream_putc (s, 0);
980 stream_putc (s, SAFI_UNICAST);
981 }
982 /* IPv6 multicast. */
983 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
984 {
985 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
986 stream_putc (s, BGP_OPEN_OPT_CAP);
987 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
988 stream_putc (s, CAPABILITY_CODE_MP);
989 stream_putc (s, CAPABILITY_CODE_MP_LEN);
990 stream_putw (s, AFI_IP6);
991 stream_putc (s, 0);
992 stream_putc (s, SAFI_MULTICAST);
993 }
994#endif /* HAVE_IPV6 */
995
996 /* Route refresh. */
hassoc9502432005-02-01 22:01:48 +0000997 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
998 stream_putc (s, BGP_OPEN_OPT_CAP);
999 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1000 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1001 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1002 stream_putc (s, BGP_OPEN_OPT_CAP);
1003 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1004 stream_putc (s, CAPABILITY_CODE_REFRESH);
1005 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
paul718e3742002-12-13 20:15:29 +00001006
Paul Jakma0b2aa3a2007-10-14 22:32:21 +00001007 /* AS4 */
1008 SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1009 stream_putc (s, BGP_OPEN_OPT_CAP);
1010 stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1011 stream_putc (s, CAPABILITY_CODE_AS4);
1012 stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1013 if ( peer->change_local_as )
1014 local_as = peer->change_local_as;
1015 else
1016 local_as = peer->local_as;
1017 stream_putl (s, local_as );
1018
paul718e3742002-12-13 20:15:29 +00001019 /* ORF capability. */
1020 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1021 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1022 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1023 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1024 {
1025 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1026 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1027 }
1028
1029 /* Dynamic capability. */
1030 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1031 {
1032 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1033 stream_putc (s, BGP_OPEN_OPT_CAP);
1034 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
1035 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1036 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1037 }
1038
hasso538621f2004-05-21 09:31:30 +00001039 /* Graceful restart capability */
1040 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1041 {
1042 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1043 stream_putc (s, BGP_OPEN_OPT_CAP);
1044 stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
1045 stream_putc (s, CAPABILITY_CODE_RESTART);
1046 stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
1047 stream_putw (s, peer->bgp->restart_time);
1048 }
1049
paul718e3742002-12-13 20:15:29 +00001050 /* Total Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +00001051 len = stream_get_endp (s) - cp - 1;
paul718e3742002-12-13 20:15:29 +00001052 stream_putc_at (s, cp, len);
1053}