blob: eecea608b3ace966388b1ce5c84998aef41ae861 [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. */
115int
116bgp_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
184void
185bgp_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))
189 zlog_info ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
190 peer->host, afi, safi, type, mode);
191}
192
193int
194bgp_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))
216 zlog_info ("%s OPEN has ORF CAP(%s) for afi/safi: %u/%u",
217 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))
256 zlog_info ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
257 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))
276 zlog_info ("%s OPEN has Prefixlist ORF(%d) capability as %s for afi/safi: %d/%d",
277 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. */
310int
311bgp_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))
332 zlog_info ("%s OPEN has CAPABILITY code: %d, length %d",
333 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))
355 zlog_info ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
356 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))
386 zlog_info ("%s OPEN has ROUTE-REFRESH capability(%s) for all address-families",
387 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;
404 int forwarding_bit = 0;
405 u_char *restart_pnt;
406 u_char *restart_end;
407
408 /* Check length. */
409 if (cap.length < CAPABILITY_CODE_RESTART_LEN)
410 {
411 zlog_info ("%s Graceful Restart Capability length error %d",
412 peer->host, cap.length);
413 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
414 return -1;
415 }
416
417 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
418 restart_flag_time = ntohs(cap.mpc.afi);
419 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
420 restart_bit = 1;
421 UNSET_FLAG (restart_flag_time, 0xF000);
422 peer->restart_time_rcv = restart_flag_time;
423
424 if (BGP_DEBUG (normal, NORMAL))
425 {
426 zlog_info ("%s OPEN has Graceful Restart capability", peer->host);
427 zlog_info ("%s Peer has%srestarted. Restart Time : %d",
428 peer->host, restart_bit ? " " : " not ",
429 peer->restart_time_rcv);
430 }
431
432 restart_pnt = pnt + 4;
433 restart_end = pnt + cap.length + 2;
434
435 while (restart_pnt < restart_end)
436 {
437 memcpy (&graf, restart_pnt, sizeof (struct graceful_restart_af));
438
439 afi = ntohs(graf.afi);
440 safi = graf.safi;
441
442 if (CHECK_FLAG (graf.flag, RESTART_F_BIT))
443 forwarding_bit = 1;
444
445 if (strcmp (afi_safi_print (afi, safi), "Unknown") == 0)
446 {
447 if (BGP_DEBUG (normal, NORMAL))
448 zlog_info ("%s Addr-family %d/%d(afi/safi) not supported. I gnore the Graceful Restart capability",
449 peer->host, afi, safi);
450 }
451 else if (! peer->afc[afi][safi])
452 {
453 if (BGP_DEBUG (normal, NORMAL))
454 zlog_info ("%s Addr-family %d/%d(afi/safi) not enabled. Ignore the Graceful Restart capability",
455 peer->host, afi, safi);
456 }
457 else
458 {
459 if (BGP_DEBUG (normal, NORMAL))
460 zlog_info ("%s Address family %s is%spreserved", peer->host,
461 afi_safi_print (afi, safi), forwarding_bit ? " " : " not ");
462
463 if (forwarding_bit)
464 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
465 }
466 forwarding_bit = 0;
467 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))
482 zlog_info ("%s OPEN has DYNAMIC capability", peer->host);
483
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
507int
508bgp_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
516int
517strict_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))
550 zlog_info ("%s rcv OPEN w/ OPTION parameter len: %u",
551 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))
576 zlog_info ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
577 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
663void
664bgp_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);
678 capp = stream_get_putp (s); /* Set Capability Len Pointer */
679 stream_putc (s, 0); /* Capability Length */
680 stream_putc (s, code); /* Capability Code */
681 orfp = stream_get_putp (s); /* Set ORF Len Pointer */
682 stream_putc (s, 0); /* ORF Length */
683 stream_putw (s, afi);
684 stream_putc (s, 0);
685 stream_putc (s, safi);
686 numberp = stream_get_putp (s); /* Set Number Pointer */
687 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. */
720 orf_len = stream_get_putp (s) - orfp - 1;
721 stream_putc_at (s, orfp, orf_len);
722
723 /* Total Capability Len. */
724 cap_len = stream_get_putp (s) - capp - 1;
725 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. */
738 cp = stream_get_putp (s);
739
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
748 /* When the peer is IPv4 unicast only, do not send capability. */
749 if (! peer->afc[AFI_IP][SAFI_MULTICAST]
750 && ! peer->afc[AFI_IP][SAFI_MPLS_VPN]
751 && ! peer->afc[AFI_IP6][SAFI_UNICAST]
752 && ! peer->afc[AFI_IP6][SAFI_MULTICAST]
753 && CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)
754 && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
755 PEER_FLAG_ORF_PREFIX_SM)
756 && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST],
757 PEER_FLAG_ORF_PREFIX_RM)
758 && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
759 PEER_FLAG_ORF_PREFIX_SM)
760 && ! CHECK_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST],
761 PEER_FLAG_ORF_PREFIX_RM)
762 && ! CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
763 return;
764
765 /* IPv4 unicast. */
766 if (peer->afc[AFI_IP][SAFI_UNICAST])
767 {
768 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
769 stream_putc (s, BGP_OPEN_OPT_CAP);
770 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
771 stream_putc (s, CAPABILITY_CODE_MP);
772 stream_putc (s, CAPABILITY_CODE_MP_LEN);
773 stream_putw (s, AFI_IP);
774 stream_putc (s, 0);
775 stream_putc (s, SAFI_UNICAST);
776 }
777 /* IPv4 multicast. */
778 if (peer->afc[AFI_IP][SAFI_MULTICAST])
779 {
780 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
781 stream_putc (s, BGP_OPEN_OPT_CAP);
782 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
783 stream_putc (s, CAPABILITY_CODE_MP);
784 stream_putc (s, CAPABILITY_CODE_MP_LEN);
785 stream_putw (s, AFI_IP);
786 stream_putc (s, 0);
787 stream_putc (s, SAFI_MULTICAST);
788 }
789 /* IPv4 VPN */
790 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
791 {
792 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
793 stream_putc (s, BGP_OPEN_OPT_CAP);
794 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
795 stream_putc (s, CAPABILITY_CODE_MP);
796 stream_putc (s, CAPABILITY_CODE_MP_LEN);
797 stream_putw (s, AFI_IP);
798 stream_putc (s, 0);
799 stream_putc (s, BGP_SAFI_VPNV4);
800 }
801#ifdef HAVE_IPV6
802 /* IPv6 unicast. */
803 if (peer->afc[AFI_IP6][SAFI_UNICAST])
804 {
805 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
806 stream_putc (s, BGP_OPEN_OPT_CAP);
807 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
808 stream_putc (s, CAPABILITY_CODE_MP);
809 stream_putc (s, CAPABILITY_CODE_MP_LEN);
810 stream_putw (s, AFI_IP6);
811 stream_putc (s, 0);
812 stream_putc (s, SAFI_UNICAST);
813 }
814 /* IPv6 multicast. */
815 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
816 {
817 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
818 stream_putc (s, BGP_OPEN_OPT_CAP);
819 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
820 stream_putc (s, CAPABILITY_CODE_MP);
821 stream_putc (s, CAPABILITY_CODE_MP_LEN);
822 stream_putw (s, AFI_IP6);
823 stream_putc (s, 0);
824 stream_putc (s, SAFI_MULTICAST);
825 }
826#endif /* HAVE_IPV6 */
827
828 /* Route refresh. */
829 if (! CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP))
830 {
831 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
832 stream_putc (s, BGP_OPEN_OPT_CAP);
833 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
834 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
835 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
836 stream_putc (s, BGP_OPEN_OPT_CAP);
837 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
838 stream_putc (s, CAPABILITY_CODE_REFRESH);
839 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
840 }
841
842 /* ORF capability. */
843 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
844 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
845 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
846 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
847 {
848 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
849 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
850 }
851
852 /* Dynamic capability. */
853 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
854 {
855 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
856 stream_putc (s, BGP_OPEN_OPT_CAP);
857 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
858 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
859 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
860 }
861
hasso538621f2004-05-21 09:31:30 +0000862 /* Graceful restart capability */
863 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
864 {
865 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
866 stream_putc (s, BGP_OPEN_OPT_CAP);
867 stream_putc (s, CAPABILITY_CODE_RESTART_LEN + 2);
868 stream_putc (s, CAPABILITY_CODE_RESTART);
869 stream_putc (s, CAPABILITY_CODE_RESTART_LEN);
870 stream_putw (s, peer->bgp->restart_time);
871 }
872
paul718e3742002-12-13 20:15:29 +0000873 /* Total Opt Parm Len. */
874 len = stream_get_putp (s) - cp - 1;
875 stream_putc_at (s, cp, len);
876}