blob: e44bd2a07d08b083cb288f8e5617dc9187829525 [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"
29
30#include "bgpd/bgpd.h"
31#include "bgpd/bgp_attr.h"
32#include "bgpd/bgp_debug.h"
33#include "bgpd/bgp_fsm.h"
34#include "bgpd/bgp_packet.h"
35#include "bgpd/bgp_open.h"
hasso538621f2004-05-21 09:31:30 +000036#include "bgpd/bgp_vty.h"
37
paul718e3742002-12-13 20:15:29 +000038/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
39 negotiate remote peer supports extentions or not. But if
40 remote-peer doesn't supports negotiation process itself. We would
41 like to do manual configuration.
42
43 So there is many configurable point. First of all we want set each
44 peer whether we send capability negotiation to the peer or not.
45 Next, if we send capability to the peer we want to set my capabilty
46 inforation at each peer. */
47
48void
49bgp_capability_vty_out (struct vty *vty, struct peer *peer)
50{
paul5228ad22004-06-04 17:58:18 +000051 char *pnt;
52 char *end;
paul718e3742002-12-13 20:15:29 +000053 struct capability cap;
54
55 pnt = peer->notify.data;
56 end = pnt + peer->notify.length;
57
58 while (pnt < end)
59 {
60 memcpy(&cap, pnt, sizeof(struct capability));
61
62 if (pnt + 2 > end)
63 return;
64 if (pnt + (cap.length + 2) > end)
65 return;
66
67 if (cap.code == CAPABILITY_CODE_MP)
68 {
69 vty_out (vty, " Capability error for: Multi protocol ");
70
71 switch (ntohs (cap.mpc.afi))
72 {
73 case AFI_IP:
74 vty_out (vty, "AFI IPv4, ");
75 break;
76 case AFI_IP6:
77 vty_out (vty, "AFI IPv6, ");
78 break;
79 default:
80 vty_out (vty, "AFI Unknown %d, ", ntohs (cap.mpc.afi));
81 break;
82 }
83 switch (cap.mpc.safi)
84 {
85 case SAFI_UNICAST:
86 vty_out (vty, "SAFI Unicast");
87 break;
88 case SAFI_MULTICAST:
89 vty_out (vty, "SAFI Multicast");
90 break;
91 case SAFI_UNICAST_MULTICAST:
92 vty_out (vty, "SAFI Unicast Multicast");
93 break;
94 case BGP_SAFI_VPNV4:
95 vty_out (vty, "SAFI MPLS-VPN");
96 break;
97 default:
98 vty_out (vty, "SAFI Unknown %d ", cap.mpc.safi);
99 break;
100 }
101 vty_out (vty, "%s", VTY_NEWLINE);
102 }
103 else if (cap.code >= 128)
104 vty_out (vty, " Capability error: vendor specific capability code %d",
105 cap.code);
106 else
107 vty_out (vty, " Capability error: unknown capability code %d",
108 cap.code);
109
110 pnt += cap.length + 2;
111 }
112}
113
114/* Set negotiated capability value. */
paul94f2b392005-06-28 12:44:16 +0000115static int
paul718e3742002-12-13 20:15:29 +0000116bgp_capability_mp (struct peer *peer, struct capability *cap)
117{
118 if (ntohs (cap->mpc.afi) == AFI_IP)
119 {
120 if (cap->mpc.safi == SAFI_UNICAST)
121 {
122 peer->afc_recv[AFI_IP][SAFI_UNICAST] = 1;
123
124 if (peer->afc[AFI_IP][SAFI_UNICAST])
125 peer->afc_nego[AFI_IP][SAFI_UNICAST] = 1;
126 else
127 return -1;
128 }
129 else if (cap->mpc.safi == SAFI_MULTICAST)
130 {
131 peer->afc_recv[AFI_IP][SAFI_MULTICAST] = 1;
132
133 if (peer->afc[AFI_IP][SAFI_MULTICAST])
134 peer->afc_nego[AFI_IP][SAFI_MULTICAST] = 1;
135 else
136 return -1;
137 }
138 else if (cap->mpc.safi == BGP_SAFI_VPNV4)
139 {
140 peer->afc_recv[AFI_IP][SAFI_MPLS_VPN] = 1;
141
142 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
143 peer->afc_nego[AFI_IP][SAFI_MPLS_VPN] = 1;
144 else
145 return -1;
146 }
147 else
148 return -1;
149 }
150#ifdef HAVE_IPV6
151 else if (ntohs (cap->mpc.afi) == AFI_IP6)
152 {
153 if (cap->mpc.safi == SAFI_UNICAST)
154 {
155 peer->afc_recv[AFI_IP6][SAFI_UNICAST] = 1;
156
157 if (peer->afc[AFI_IP6][SAFI_UNICAST])
158 peer->afc_nego[AFI_IP6][SAFI_UNICAST] = 1;
159 else
160 return -1;
161 }
162 else if (cap->mpc.safi == SAFI_MULTICAST)
163 {
164 peer->afc_recv[AFI_IP6][SAFI_MULTICAST] = 1;
165
166 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
167 peer->afc_nego[AFI_IP6][SAFI_MULTICAST] = 1;
168 else
169 return -1;
170 }
171 else
172 return -1;
173 }
174#endif /* HAVE_IPV6 */
175 else
176 {
177 /* Unknown Address Family. */
178 return -1;
179 }
180
181 return 0;
182}
183
paul94f2b392005-06-28 12:44:16 +0000184static void
paul718e3742002-12-13 20:15:29 +0000185bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
186 u_char type, u_char mode)
187{
188 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000189 zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
paul718e3742002-12-13 20:15:29 +0000190 peer->host, afi, safi, type, mode);
191}
192
paul94f2b392005-06-28 12:44:16 +0000193static int
paul718e3742002-12-13 20:15:29 +0000194bgp_capability_orf (struct peer *peer, struct capability *cap,
195 u_char *pnt)
196{
197 afi_t afi = ntohs(cap->mpc.afi);
198 safi_t safi = cap->mpc.safi;
199 u_char number_of_orfs;
200 u_char type;
201 u_char mode;
202 u_int16_t sm_cap = 0; /* capability send-mode receive */
203 u_int16_t rm_cap = 0; /* capability receive-mode receive */
204 int i;
205
206 /* Check length. */
207 if (cap->length < 7)
208 {
209 zlog_info ("%s ORF Capability length error %d",
210 peer->host, cap->length);
211 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
212 return -1;
213 }
214
215 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000216 zlog_debug ("%s OPEN has ORF CAP(%s) for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +0000217 peer->host, (cap->code == CAPABILITY_CODE_ORF ?
218 "new" : "old"), afi, safi);
219
220 /* Check AFI and SAFI. */
221 if ((afi != AFI_IP && afi != AFI_IP6)
222 || (safi != SAFI_UNICAST && safi != SAFI_MULTICAST
223 && safi != BGP_SAFI_VPNV4))
224 {
225 zlog_info ("%s Addr-family %d/%d not supported. Ignoring the ORF capability",
226 peer->host, afi, safi);
227 return -1;
228 }
229
230 number_of_orfs = *pnt++;
231
232 for (i = 0 ; i < number_of_orfs ; i++)
233 {
234 type = *pnt++;
235 mode = *pnt++;
236
237 /* ORF Mode error check */
238 if (mode != ORF_MODE_BOTH && mode != ORF_MODE_SEND
239 && mode != ORF_MODE_RECEIVE)
240 {
241 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
242 continue;
243 }
244
245 /* ORF Type and afi/safi error check */
246 if (cap->code == CAPABILITY_CODE_ORF)
247 {
248 if (type == ORF_TYPE_PREFIX &&
249 ((afi == AFI_IP && safi == SAFI_UNICAST)
250 || (afi == AFI_IP && safi == SAFI_MULTICAST)
251 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
252 {
253 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
254 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
255 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000256 zlog_debug ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000257 peer->host, ORF_TYPE_PREFIX, (mode == ORF_MODE_SEND ? "SEND" :
258 mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
259 }
260 else
261 {
262 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
263 continue;
264 }
265 }
266 else if (cap->code == CAPABILITY_CODE_ORF_OLD)
267 {
268 if (type == ORF_TYPE_PREFIX_OLD &&
269 ((afi == AFI_IP && safi == SAFI_UNICAST)
270 || (afi == AFI_IP && safi == SAFI_MULTICAST)
271 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
272 {
273 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
274 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
275 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000276 zlog_debug ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
paul718e3742002-12-13 20:15:29 +0000277 peer->host, ORF_TYPE_PREFIX_OLD, (mode == ORF_MODE_SEND ? "SEND" :
278 mode == ORF_MODE_RECEIVE ? "RECEIVE" : "BOTH") , afi, safi);
279 }
280 else
281 {
282 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
283 continue;
284 }
285 }
286 else
287 {
288 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
289 continue;
290 }
291
292 switch (mode)
293 {
294 case ORF_MODE_BOTH:
295 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
296 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
297 break;
298 case ORF_MODE_SEND:
299 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
300 break;
301 case ORF_MODE_RECEIVE:
302 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
303 break;
304 }
305 }
306 return 0;
307}
308
309/* Parse given capability. */
paul94f2b392005-06-28 12:44:16 +0000310static int
paul718e3742002-12-13 20:15:29 +0000311bgp_capability_parse (struct peer *peer, u_char *pnt, u_char length,
312 u_char **error)
313{
314 int ret;
315 u_char *end;
316 struct capability cap;
317
318 end = pnt + length;
319
320 while (pnt < end)
321 {
322 afi_t afi;
323 safi_t safi;
324
325 /* Fetch structure to the byte stream. */
326 memcpy (&cap, pnt, sizeof (struct capability));
327
328 afi = ntohs(cap.mpc.afi);
329 safi = cap.mpc.safi;
330
331 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000332 zlog_debug ("%s OPEN has CAPABILITY code: %d, length %d",
paul718e3742002-12-13 20:15:29 +0000333 peer->host, cap.code, cap.length);
334
335 /* We need at least capability code and capability length. */
336 if (pnt + 2 > end)
337 {
338 zlog_info ("%s Capability length error", peer->host);
339 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
340 return -1;
341 }
342
343 /* Capability length check. */
344 if (pnt + (cap.length + 2) > end)
345 {
346 zlog_info ("%s Capability length error", peer->host);
347 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
348 return -1;
349 }
350
351 /* We know MP Capability Code. */
352 if (cap.code == CAPABILITY_CODE_MP)
353 {
354 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000355 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
paul718e3742002-12-13 20:15:29 +0000356 peer->host, afi, safi);
357
358 /* Ignore capability when override-capability is set. */
359 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
360 {
361 /* Set negotiated value. */
362 ret = bgp_capability_mp (peer, &cap);
363
364 /* Unsupported Capability. */
365 if (ret < 0)
366 {
367 /* Store return data. */
368 memcpy (*error, &cap, cap.length + 2);
369 *error += cap.length + 2;
370 }
371 }
372 }
373 else if (cap.code == CAPABILITY_CODE_REFRESH
374 || cap.code == CAPABILITY_CODE_REFRESH_OLD)
375 {
376 /* Check length. */
hasso538621f2004-05-21 09:31:30 +0000377 if (cap.length != CAPABILITY_CODE_REFRESH_LEN)
paul718e3742002-12-13 20:15:29 +0000378 {
379 zlog_info ("%s Route Refresh Capability length error %d",
380 peer->host, cap.length);
381 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
382 return -1;
383 }
384
385 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000386 zlog_debug ("%s OPEN has ROUTE-REFRESH capability(%s) for all address-families",
paul718e3742002-12-13 20:15:29 +0000387 peer->host,
388 cap.code == CAPABILITY_CODE_REFRESH_OLD ? "old" : "new");
389
390 /* BGP refresh capability */
391 if (cap.code == CAPABILITY_CODE_REFRESH_OLD)
392 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
393 else
394 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
395 }
396 else if (cap.code == CAPABILITY_CODE_ORF
397 || cap.code == CAPABILITY_CODE_ORF_OLD)
398 bgp_capability_orf (peer, &cap, pnt + sizeof (struct capability));
hasso538621f2004-05-21 09:31:30 +0000399 else if (cap.code == CAPABILITY_CODE_RESTART)
400 {
401 struct graceful_restart_af graf;
402 u_int16_t restart_flag_time;
403 int restart_bit = 0;
hasso538621f2004-05-21 09:31:30 +0000404 u_char *restart_pnt;
405 u_char *restart_end;
406
407 /* Check length. */
408 if (cap.length < CAPABILITY_CODE_RESTART_LEN)
409 {
410 zlog_info ("%s Graceful Restart Capability length error %d",
411 peer->host, cap.length);
412 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
413 return -1;
414 }
415
416 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
417 restart_flag_time = ntohs(cap.mpc.afi);
418 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
419 restart_bit = 1;
hasso93406d82005-02-02 14:40:33 +0000420 UNSET_FLAG (restart_flag_time, 0xF000);
421 peer->v_gr_restart = restart_flag_time;
hasso538621f2004-05-21 09:31:30 +0000422
423 if (BGP_DEBUG (normal, NORMAL))
424 {
ajs8325cd72004-12-08 20:47:40 +0000425 zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
426 zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
hasso538621f2004-05-21 09:31:30 +0000427 peer->host, restart_bit ? " " : " not ",
hasso93406d82005-02-02 14:40:33 +0000428 peer->v_gr_restart);
hasso538621f2004-05-21 09:31:30 +0000429 }
430
431 restart_pnt = pnt + 4;
432 restart_end = pnt + cap.length + 2;
433
434 while (restart_pnt < restart_end)
435 {
436 memcpy (&graf, restart_pnt, sizeof (struct graceful_restart_af));
437
438 afi = ntohs(graf.afi);
439 safi = graf.safi;
440
441 if (CHECK_FLAG (graf.flag, RESTART_F_BIT))
hasso93406d82005-02-02 14:40:33 +0000442 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
hasso538621f2004-05-21 09:31:30 +0000443
444 if (strcmp (afi_safi_print (afi, safi), "Unknown") == 0)
445 {
446 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000447 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported. I gnore the Graceful Restart capability",
hasso538621f2004-05-21 09:31:30 +0000448 peer->host, afi, safi);
449 }
450 else if (! peer->afc[afi][safi])
451 {
452 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000453 zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled. Ignore the Graceful Restart capability",
hasso538621f2004-05-21 09:31:30 +0000454 peer->host, afi, safi);
455 }
456 else
457 {
458 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000459 zlog_debug ("%s Address family %s is%spreserved", peer->host,
hasso93406d82005-02-02 14:40:33 +0000460 afi_safi_print (afi, safi),
461 CHECK_FLAG (peer->af_cap[afi][safi],
462 PEER_CAP_RESTART_AF_PRESERVE_RCV)
463 ? " " : " not ");
hasso538621f2004-05-21 09:31:30 +0000464
hasso538621f2004-05-21 09:31:30 +0000465 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
466 }
hasso538621f2004-05-21 09:31:30 +0000467 restart_pnt += 4;
468 }
469 }
paul718e3742002-12-13 20:15:29 +0000470 else if (cap.code == CAPABILITY_CODE_DYNAMIC)
471 {
472 /* Check length. */
hasso538621f2004-05-21 09:31:30 +0000473 if (cap.length != CAPABILITY_CODE_DYNAMIC_LEN)
paul718e3742002-12-13 20:15:29 +0000474 {
475 zlog_info ("%s Dynamic Capability length error %d",
476 peer->host, cap.length);
477 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
478 return -1;
479 }
480
481 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000482 zlog_debug ("%s OPEN has DYNAMIC capability", peer->host);
paul718e3742002-12-13 20:15:29 +0000483
484 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
485 }
486
487 else if (cap.code > 128)
488 {
489 /* We don't send Notification for unknown vendor specific
490 capabilities. It seems reasonable for now... */
491 zlog_warn ("%s Vendor specific capability %d",
492 peer->host, cap.code);
493 }
494 else
495 {
496 zlog_warn ("%s unrecognized capability code: %d - ignored",
497 peer->host, cap.code);
498 memcpy (*error, &cap, cap.length + 2);
499 *error += cap.length + 2;
500 }
501
502 pnt += cap.length + 2;
503 }
504 return 0;
505}
506
paul94f2b392005-06-28 12:44:16 +0000507static int
paul718e3742002-12-13 20:15:29 +0000508bgp_auth_parse (struct peer *peer, u_char *pnt, size_t length)
509{
510 bgp_notify_send (peer,
511 BGP_NOTIFY_OPEN_ERR,
512 BGP_NOTIFY_OPEN_AUTH_FAILURE);
513 return -1;
514}
515
paul94f2b392005-06-28 12:44:16 +0000516static int
paul718e3742002-12-13 20:15:29 +0000517strict_capability_same (struct peer *peer)
518{
519 int i, j;
520
521 for (i = AFI_IP; i < AFI_MAX; i++)
522 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
523 if (peer->afc[i][j] != peer->afc_nego[i][j])
524 return 0;
525 return 1;
526}
527
528/* Parse open option */
529int
530bgp_open_option_parse (struct peer *peer, u_char length, int *capability)
531{
532 int ret;
533 u_char *end;
534 u_char opt_type;
535 u_char opt_length;
536 u_char *pnt;
537 u_char *error;
538 u_char error_data[BGP_MAX_PACKET_SIZE];
539
540 /* Fetch pointer. */
541 pnt = stream_pnt (peer->ibuf);
542
543 ret = 0;
544 opt_type = 0;
545 opt_length = 0;
546 end = pnt + length;
547 error = error_data;
548
549 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000550 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
paul718e3742002-12-13 20:15:29 +0000551 peer->host, length);
552
553 while (pnt < end)
554 {
555 /* Check the length. */
556 if (pnt + 2 > end)
557 {
558 zlog_info ("%s Option length error", peer->host);
559 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
560 return -1;
561 }
562
563 /* Fetch option type and length. */
564 opt_type = *pnt++;
565 opt_length = *pnt++;
566
567 /* Option length check. */
568 if (pnt + opt_length > end)
569 {
570 zlog_info ("%s Option length error", peer->host);
571 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
572 return -1;
573 }
574
575 if (BGP_DEBUG (normal, NORMAL))
ajs8325cd72004-12-08 20:47:40 +0000576 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
paul718e3742002-12-13 20:15:29 +0000577 peer->host, opt_type,
578 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
579 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
580 opt_length);
581
582 switch (opt_type)
583 {
584 case BGP_OPEN_OPT_AUTH:
585 ret = bgp_auth_parse (peer, pnt, opt_length);
586 break;
587 case BGP_OPEN_OPT_CAP:
588 ret = bgp_capability_parse (peer, pnt, opt_length, &error);
589 *capability = 1;
590 break;
591 default:
592 bgp_notify_send (peer,
593 BGP_NOTIFY_OPEN_ERR,
594 BGP_NOTIFY_OPEN_UNSUP_PARAM);
595 ret = -1;
596 break;
597 }
598
599 /* Parse error. To accumulate all unsupported capability codes,
600 bgp_capability_parse does not return -1 when encounter
601 unsupported capability code. To detect that, please check
602 error and erro_data pointer, like below. */
603 if (ret < 0)
604 return -1;
605
606 /* Forward pointer. */
607 pnt += opt_length;
608 }
609
610 /* All OPEN option is parsed. Check capability when strict compare
611 flag is enabled.*/
612 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
613 {
614 /* If Unsupported Capability exists. */
615 if (error != error_data)
616 {
617 bgp_notify_send_with_data (peer,
618 BGP_NOTIFY_OPEN_ERR,
619 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
620 error_data, error - error_data);
621 return -1;
622 }
623
624 /* Check local capability does not negotiated with remote
625 peer. */
626 if (! strict_capability_same (peer))
627 {
628 bgp_notify_send (peer,
629 BGP_NOTIFY_OPEN_ERR,
630 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
631 return -1;
632 }
633 }
634
635 /* Check there is no common capability send Unsupported Capability
636 error. */
637 if (*capability && ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
638 {
639 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
640 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
641 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
642 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
643 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
644 {
645 plog_err (peer->log, "%s [Error] No common capability", peer->host);
646
647 if (error != error_data)
648
649 bgp_notify_send_with_data (peer,
650 BGP_NOTIFY_OPEN_ERR,
651 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
652 error_data, error - error_data);
653 else
654 bgp_notify_send (peer,
655 BGP_NOTIFY_OPEN_ERR,
656 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
657 return -1;
658 }
659 }
660 return 0;
661}
662
paul94f2b392005-06-28 12:44:16 +0000663static void
paul718e3742002-12-13 20:15:29 +0000664bgp_open_capability_orf (struct stream *s, struct peer *peer,
665 afi_t afi, safi_t safi, u_char code)
666{
667 u_char cap_len;
668 u_char orf_len;
669 unsigned long capp;
670 unsigned long orfp;
671 unsigned long numberp;
672 int number_of_orfs = 0;
673
674 if (safi == SAFI_MPLS_VPN)
675 safi = BGP_SAFI_VPNV4;
676
677 stream_putc (s, BGP_OPEN_OPT_CAP);
paul9985f832005-02-09 15:51:56 +0000678 capp = stream_get_endp (s); /* Set Capability Len Pointer */
paul718e3742002-12-13 20:15:29 +0000679 stream_putc (s, 0); /* Capability Length */
680 stream_putc (s, code); /* Capability Code */
paul9985f832005-02-09 15:51:56 +0000681 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
paul718e3742002-12-13 20:15:29 +0000682 stream_putc (s, 0); /* ORF Length */
683 stream_putw (s, afi);
684 stream_putc (s, 0);
685 stream_putc (s, safi);
paul9985f832005-02-09 15:51:56 +0000686 numberp = stream_get_endp (s); /* Set Number Pointer */
paul718e3742002-12-13 20:15:29 +0000687 stream_putc (s, 0); /* Number of ORFs */
688
689 /* Address Prefix ORF */
690 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
691 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
692 {
693 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
694 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
695
696 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
697 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
698 {
699 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
700 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
701 stream_putc (s, ORF_MODE_BOTH);
702 }
703 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
704 {
705 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
706 stream_putc (s, ORF_MODE_SEND);
707 }
708 else
709 {
710 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
711 stream_putc (s, ORF_MODE_RECEIVE);
712 }
713 number_of_orfs++;
714 }
715
716 /* Total Number of ORFs. */
717 stream_putc_at (s, numberp, number_of_orfs);
718
719 /* Total ORF Len. */
paul9985f832005-02-09 15:51:56 +0000720 orf_len = stream_get_endp (s) - orfp - 1;
paul718e3742002-12-13 20:15:29 +0000721 stream_putc_at (s, orfp, orf_len);
722
723 /* Total Capability Len. */
paul9985f832005-02-09 15:51:56 +0000724 cap_len = stream_get_endp (s) - capp - 1;
paul718e3742002-12-13 20:15:29 +0000725 stream_putc_at (s, capp, cap_len);
726}
727
728/* Fill in capability open option to the packet. */
729void
730bgp_open_capability (struct stream *s, struct peer *peer)
731{
732 u_char len;
733 unsigned long cp;
734 afi_t afi;
735 safi_t safi;
736
737 /* Remember current pointer for Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000738 cp = stream_get_endp (s);
paul718e3742002-12-13 20:15:29 +0000739
740 /* Opt Parm Len. */
741 stream_putc (s, 0);
742
743 /* Do not send capability. */
744 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
745 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
746 return;
747
paul718e3742002-12-13 20:15:29 +0000748 /* IPv4 unicast. */
749 if (peer->afc[AFI_IP][SAFI_UNICAST])
750 {
751 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
752 stream_putc (s, BGP_OPEN_OPT_CAP);
753 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
754 stream_putc (s, CAPABILITY_CODE_MP);
755 stream_putc (s, CAPABILITY_CODE_MP_LEN);
756 stream_putw (s, AFI_IP);
757 stream_putc (s, 0);
758 stream_putc (s, SAFI_UNICAST);
759 }
760 /* IPv4 multicast. */
761 if (peer->afc[AFI_IP][SAFI_MULTICAST])
762 {
763 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
764 stream_putc (s, BGP_OPEN_OPT_CAP);
765 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
766 stream_putc (s, CAPABILITY_CODE_MP);
767 stream_putc (s, CAPABILITY_CODE_MP_LEN);
768 stream_putw (s, AFI_IP);
769 stream_putc (s, 0);
770 stream_putc (s, SAFI_MULTICAST);
771 }
772 /* IPv4 VPN */
773 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
774 {
775 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
776 stream_putc (s, BGP_OPEN_OPT_CAP);
777 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
778 stream_putc (s, CAPABILITY_CODE_MP);
779 stream_putc (s, CAPABILITY_CODE_MP_LEN);
780 stream_putw (s, AFI_IP);
781 stream_putc (s, 0);
782 stream_putc (s, BGP_SAFI_VPNV4);
783 }
784#ifdef HAVE_IPV6
785 /* IPv6 unicast. */
786 if (peer->afc[AFI_IP6][SAFI_UNICAST])
787 {
788 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
789 stream_putc (s, BGP_OPEN_OPT_CAP);
790 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
791 stream_putc (s, CAPABILITY_CODE_MP);
792 stream_putc (s, CAPABILITY_CODE_MP_LEN);
793 stream_putw (s, AFI_IP6);
794 stream_putc (s, 0);
795 stream_putc (s, SAFI_UNICAST);
796 }
797 /* IPv6 multicast. */
798 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
799 {
800 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
801 stream_putc (s, BGP_OPEN_OPT_CAP);
802 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
803 stream_putc (s, CAPABILITY_CODE_MP);
804 stream_putc (s, CAPABILITY_CODE_MP_LEN);
805 stream_putw (s, AFI_IP6);
806 stream_putc (s, 0);
807 stream_putc (s, SAFI_MULTICAST);
808 }
809#endif /* HAVE_IPV6 */
810
811 /* Route refresh. */
hassoc9502432005-02-01 22:01:48 +0000812 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
813 stream_putc (s, BGP_OPEN_OPT_CAP);
814 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
815 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
816 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
817 stream_putc (s, BGP_OPEN_OPT_CAP);
818 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
819 stream_putc (s, CAPABILITY_CODE_REFRESH);
820 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
paul718e3742002-12-13 20:15:29 +0000821
822 /* ORF capability. */
823 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
824 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
825 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
826 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
827 {
828 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
829 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
830 }
831
832 /* Dynamic capability. */
833 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
834 {
835 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
836 stream_putc (s, BGP_OPEN_OPT_CAP);
837 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
838 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
839 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
840 }
841
hasso538621f2004-05-21 09:31:30 +0000842 /* Graceful restart capability */
843 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
844 {
845 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
846 stream_putc (s, BGP_OPEN_OPT_CAP);
847 stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
848 stream_putc (s, CAPABILITY_CODE_RESTART);
849 stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
850 stream_putw (s, peer->bgp->restart_time);
851 }
852
paul718e3742002-12-13 20:15:29 +0000853 /* Total Opt Parm Len. */
paul9985f832005-02-09 15:51:56 +0000854 len = stream_get_endp (s) - cp - 1;
paul718e3742002-12-13 20:15:29 +0000855 stream_putc_at (s, cp, len);
856}