]> git.proxmox.com Git - mirror_frr.git/blame - bgpd/bgp_open.c
bgpd, zebra: rfc-5549-generic.patch
[mirror_frr.git] / bgpd / bgp_open.c
CommitLineData
718e3744 1/* 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"
6d58272b 29#include "memory.h"
3f9c7369 30#include "queue.h"
718e3744 31
32#include "bgpd/bgpd.h"
33#include "bgpd/bgp_attr.h"
34#include "bgpd/bgp_debug.h"
35#include "bgpd/bgp_fsm.h"
36#include "bgpd/bgp_packet.h"
37#include "bgpd/bgp_open.h"
0b2aa3a0 38#include "bgpd/bgp_aspath.h"
538621f2 39#include "bgpd/bgp_vty.h"
40
718e3744 41/* BGP-4 Multiprotocol Extentions lead us to the complex world. We can
42 negotiate remote peer supports extentions or not. But if
43 remote-peer doesn't supports negotiation process itself. We would
44 like to do manual configuration.
45
46 So there is many configurable point. First of all we want set each
47 peer whether we send capability negotiation to the peer or not.
48 Next, if we send capability to the peer we want to set my capabilty
49 inforation at each peer. */
50
51void
52bgp_capability_vty_out (struct vty *vty, struct peer *peer)
53{
5228ad27 54 char *pnt;
55 char *end;
6d58272b
PJ
56 struct capability_mp_data mpc;
57 struct capability_header *hdr;
718e3744 58
59 pnt = peer->notify.data;
60 end = pnt + peer->notify.length;
6d58272b 61
718e3744 62 while (pnt < end)
63 {
6d58272b 64 if (pnt + sizeof (struct capability_mp_data) + 2 > end)
718e3744 65 return;
6d58272b
PJ
66
67 hdr = (struct capability_header *)pnt;
68 if (pnt + hdr->length + 2 > end)
718e3744 69 return;
70
6d58272b
PJ
71 memcpy (&mpc, pnt + 2, sizeof(struct capability_mp_data));
72
73 if (hdr->code == CAPABILITY_CODE_MP)
718e3744 74 {
75 vty_out (vty, " Capability error for: Multi protocol ");
76
6d58272b 77 switch (ntohs (mpc.afi))
718e3744 78 {
79 case AFI_IP:
80 vty_out (vty, "AFI IPv4, ");
81 break;
82 case AFI_IP6:
83 vty_out (vty, "AFI IPv6, ");
84 break;
85 default:
6d58272b 86 vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi));
718e3744 87 break;
88 }
6d58272b 89 switch (mpc.safi)
718e3744 90 {
91 case SAFI_UNICAST:
92 vty_out (vty, "SAFI Unicast");
93 break;
94 case SAFI_MULTICAST:
95 vty_out (vty, "SAFI Multicast");
96 break;
42e6d745
DO
97 case SAFI_MPLS_LABELED_VPN:
98 vty_out (vty, "SAFI MPLS-labeled VPN");
718e3744 99 break;
100 default:
6d58272b 101 vty_out (vty, "SAFI Unknown %d ", mpc.safi);
718e3744 102 break;
103 }
104 vty_out (vty, "%s", VTY_NEWLINE);
105 }
6d58272b 106 else if (hdr->code >= 128)
718e3744 107 vty_out (vty, " Capability error: vendor specific capability code %d",
6d58272b 108 hdr->code);
718e3744 109 else
110 vty_out (vty, " Capability error: unknown capability code %d",
6d58272b 111 hdr->code);
718e3744 112
6d58272b 113 pnt += hdr->length + 2;
718e3744 114 }
115}
116
6d58272b
PJ
117static void
118bgp_capability_mp_data (struct stream *s, struct capability_mp_data *mpc)
718e3744 119{
6d58272b
PJ
120 mpc->afi = stream_getw (s);
121 mpc->reserved = stream_getc (s);
122 mpc->safi = stream_getc (s);
123}
718e3744 124
6d58272b
PJ
125int
126bgp_afi_safi_valid_indices (afi_t afi, safi_t *safi)
127{
6d58272b 128 switch (afi)
718e3744 129 {
6d58272b
PJ
130 case AFI_IP:
131#ifdef HAVE_IPV6
132 case AFI_IP6:
133#endif
134 switch (*safi)
135 {
42e6d745
DO
136 /* BGP MPLS-labeled VPN SAFI isn't contigious with others, remap */
137 case SAFI_MPLS_LABELED_VPN:
6d58272b
PJ
138 *safi = SAFI_MPLS_VPN;
139 case SAFI_UNICAST:
140 case SAFI_MULTICAST:
141 case SAFI_MPLS_VPN:
142 return 1;
143 }
718e3744 144 }
6d58272b
PJ
145 zlog_debug ("unknown afi/safi (%u/%u)", afi, *safi);
146
147 return 0;
148}
149
150/* Set negotiated capability value. */
151static int
152bgp_capability_mp (struct peer *peer, struct capability_header *hdr)
153{
154 struct capability_mp_data mpc;
155 struct stream *s = BGP_INPUT (peer);
156
157 bgp_capability_mp_data (s, &mpc);
158
167d390a 159 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
160 zlog_debug ("%s OPEN has MP_EXT CAP for afi/safi: %u/%u",
161 peer->host, mpc.afi, mpc.safi);
162
163 if (!bgp_afi_safi_valid_indices (mpc.afi, &mpc.safi))
164 return -1;
165
166 /* Now safi remapped, and afi/safi are valid array indices */
167 peer->afc_recv[mpc.afi][mpc.safi] = 1;
168
169 if (peer->afc[mpc.afi][mpc.safi])
e08286bc 170 peer->afc_nego[mpc.afi][mpc.safi] = 1;
6d58272b
PJ
171 else
172 return -1;
718e3744 173
174 return 0;
175}
176
94f2b392 177static void
718e3744 178bgp_capability_orf_not_support (struct peer *peer, afi_t afi, safi_t safi,
179 u_char type, u_char mode)
180{
16286195 181 if (bgp_debug_neighbor_events(peer))
8325cd7f 182 zlog_debug ("%s Addr-family %d/%d has ORF type/mode %d/%d not supported",
718e3744 183 peer->host, afi, safi, type, mode);
184}
185
8f5abac1 186static const struct message orf_type_str[] =
6d58272b
PJ
187{
188 { ORF_TYPE_PREFIX, "Prefixlist" },
189 { ORF_TYPE_PREFIX_OLD, "Prefixlist (old)" },
190};
837d16cc 191static const int orf_type_str_max = array_size(orf_type_str);
6d58272b 192
8f5abac1 193static const struct message orf_mode_str[] =
6d58272b
PJ
194{
195 { ORF_MODE_RECEIVE, "Receive" },
196 { ORF_MODE_SEND, "Send" },
197 { ORF_MODE_BOTH, "Both" },
198};
837d16cc 199static const int orf_mode_str_max = array_size(orf_mode_str);
6d58272b 200
94f2b392 201static int
6d58272b 202bgp_capability_orf_entry (struct peer *peer, struct capability_header *hdr)
718e3744 203{
6d58272b
PJ
204 struct stream *s = BGP_INPUT (peer);
205 struct capability_orf_entry entry;
206 afi_t afi;
207 safi_t safi;
718e3744 208 u_char type;
209 u_char mode;
210 u_int16_t sm_cap = 0; /* capability send-mode receive */
211 u_int16_t rm_cap = 0; /* capability receive-mode receive */
212 int i;
213
6d58272b
PJ
214 /* ORF Entry header */
215 bgp_capability_mp_data (s, &entry.mpc);
216 entry.num = stream_getc (s);
217 afi = entry.mpc.afi;
218 safi = entry.mpc.safi;
219
16286195 220 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
221 zlog_debug ("%s ORF Cap entry for afi/safi: %u/%u",
222 peer->host, entry.mpc.afi, entry.mpc.safi);
718e3744 223
224 /* Check AFI and SAFI. */
6d58272b
PJ
225 if (!bgp_afi_safi_valid_indices (entry.mpc.afi, &safi))
226 {
227 zlog_info ("%s Addr-family %d/%d not supported."
228 " Ignoring the ORF capability",
229 peer->host, entry.mpc.afi, entry.mpc.safi);
230 return 0;
231 }
232
233 /* validate number field */
5e728e92 234 if (sizeof (struct capability_orf_entry) + (entry.num * 2) > hdr->length)
718e3744 235 {
6d58272b
PJ
236 zlog_info ("%s ORF Capability entry length error,"
237 " Cap length %u, num %u",
238 peer->host, hdr->length, entry.num);
239 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
718e3744 240 return -1;
241 }
242
6d58272b 243 for (i = 0 ; i < entry.num ; i++)
718e3744 244 {
6d58272b
PJ
245 type = stream_getc(s);
246 mode = stream_getc(s);
247
718e3744 248 /* ORF Mode error check */
6d58272b
PJ
249 switch (mode)
250 {
251 case ORF_MODE_BOTH:
252 case ORF_MODE_SEND:
253 case ORF_MODE_RECEIVE:
254 break;
255 default:
256 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
257 continue;
718e3744 258 }
6d58272b
PJ
259 /* ORF Type and afi/safi error checks */
260 /* capcode versus type */
261 switch (hdr->code)
262 {
263 case CAPABILITY_CODE_ORF:
264 switch (type)
265 {
266 case ORF_TYPE_PREFIX:
267 break;
268 default:
269 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
270 continue;
271 }
272 break;
273 case CAPABILITY_CODE_ORF_OLD:
274 switch (type)
275 {
276 case ORF_TYPE_PREFIX_OLD:
277 break;
278 default:
279 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
280 continue;
281 }
282 break;
283 default:
284 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
285 continue;
286 }
287
288 /* AFI vs SAFI */
289 if (!((afi == AFI_IP && safi == SAFI_UNICAST)
290 || (afi == AFI_IP && safi == SAFI_MULTICAST)
291 || (afi == AFI_IP6 && safi == SAFI_UNICAST)))
292 {
293 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
294 continue;
295 }
296
16286195 297 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
298 zlog_debug ("%s OPEN has %s ORF capability"
299 " as %s for afi/safi: %d/%d",
300 peer->host, LOOKUP (orf_type_str, type),
301 LOOKUP (orf_mode_str, mode),
302 entry.mpc.afi, safi);
718e3744 303
6d58272b 304 if (hdr->code == CAPABILITY_CODE_ORF)
718e3744 305 {
6d58272b
PJ
306 sm_cap = PEER_CAP_ORF_PREFIX_SM_RCV;
307 rm_cap = PEER_CAP_ORF_PREFIX_RM_RCV;
718e3744 308 }
6d58272b 309 else if (hdr->code == CAPABILITY_CODE_ORF_OLD)
718e3744 310 {
6d58272b
PJ
311 sm_cap = PEER_CAP_ORF_PREFIX_SM_OLD_RCV;
312 rm_cap = PEER_CAP_ORF_PREFIX_RM_OLD_RCV;
718e3744 313 }
314 else
315 {
316 bgp_capability_orf_not_support (peer, afi, safi, type, mode);
317 continue;
318 }
319
320 switch (mode)
321 {
322 case ORF_MODE_BOTH:
323 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
324 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
325 break;
326 case ORF_MODE_SEND:
327 SET_FLAG (peer->af_cap[afi][safi], sm_cap);
328 break;
329 case ORF_MODE_RECEIVE:
330 SET_FLAG (peer->af_cap[afi][safi], rm_cap);
331 break;
332 }
333 }
334 return 0;
335}
336
6d58272b
PJ
337static int
338bgp_capability_restart (struct peer *peer, struct capability_header *caphdr)
339{
340 struct stream *s = BGP_INPUT (peer);
341 u_int16_t restart_flag_time;
342 int restart_bit = 0;
343 size_t end = stream_get_getp (s) + caphdr->length;
344
345 SET_FLAG (peer->cap, PEER_CAP_RESTART_RCV);
346 restart_flag_time = stream_getw(s);
347 if (CHECK_FLAG (restart_flag_time, RESTART_R_BIT))
fe7d2a48
DS
348 {
349 SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_RCV);
350 restart_bit = 1;
351 }
6d58272b
PJ
352 UNSET_FLAG (restart_flag_time, 0xF000);
353 peer->v_gr_restart = restart_flag_time;
718e3744 354
16286195 355 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
356 {
357 zlog_debug ("%s OPEN has Graceful Restart capability", peer->host);
358 zlog_debug ("%s Peer has%srestarted. Restart Time : %d",
359 peer->host, restart_bit ? " " : " not ",
360 peer->v_gr_restart);
361 }
718e3744 362
21cc7694 363 while (stream_get_getp (s) + 4 <= end)
6d58272b
PJ
364 {
365 afi_t afi = stream_getw (s);
366 safi_t safi = stream_getc (s);
367 u_char flag = stream_getc (s);
368
369 if (!bgp_afi_safi_valid_indices (afi, &safi))
370 {
16286195 371 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
372 zlog_debug ("%s Addr-family %d/%d(afi/safi) not supported."
373 " Ignore the Graceful Restart capability",
374 peer->host, afi, safi);
375 }
376 else if (!peer->afc[afi][safi])
377 {
16286195 378 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
379 zlog_debug ("%s Addr-family %d/%d(afi/safi) not enabled."
380 " Ignore the Graceful Restart capability",
381 peer->host, afi, safi);
382 }
383 else
384 {
16286195 385 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
386 zlog_debug ("%s Address family %s is%spreserved", peer->host,
387 afi_safi_print (afi, safi),
388 CHECK_FLAG (peer->af_cap[afi][safi],
389 PEER_CAP_RESTART_AF_PRESERVE_RCV)
390 ? " " : " not ");
391
392 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV);
393 if (CHECK_FLAG (flag, RESTART_F_BIT))
394 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV);
395
396 }
397 }
398 return 0;
399}
718e3744 400
0b2aa3a0
PJ
401static as_t
402bgp_capability_as4 (struct peer *peer, struct capability_header *hdr)
403{
5861739f
PJ
404 SET_FLAG (peer->cap, PEER_CAP_AS4_RCV);
405
406 if (hdr->length != CAPABILITY_CODE_AS4_LEN)
407 {
408 zlog_err ("%s AS4 capability has incorrect data length %d",
409 peer->host, hdr->length);
410 return 0;
411 }
412
0b2aa3a0
PJ
413 as_t as4 = stream_getl (BGP_INPUT(peer));
414
415 if (BGP_DEBUG (as4, AS4))
416 zlog_debug ("%s [AS4] about to set cap PEER_CAP_AS4_RCV, got as4 %u",
417 peer->host, as4);
0b2aa3a0
PJ
418 return as4;
419}
420
a82478b9
DS
421static int
422bgp_capability_addpath (struct peer *peer, struct capability_header *hdr)
423{
424 struct stream *s = BGP_INPUT (peer);
425 size_t end = stream_get_getp (s) + hdr->length;
426
427 SET_FLAG (peer->cap, PEER_CAP_ADDPATH_RCV);
428
429 while (stream_get_getp (s) + 4 <= end)
430 {
431 afi_t afi = stream_getw (s);
432 safi_t safi = stream_getc (s);
433 u_char send_receive = stream_getc (s);
434
167d390a 435 if (bgp_debug_neighbor_events(peer))
a82478b9
DS
436 zlog_debug ("%s OPEN has AddPath CAP for afi/safi: %u/%u%s%s",
437 peer->host, afi, safi,
438 (send_receive & BGP_ADDPATH_RX) ? ", receive" : "",
439 (send_receive & BGP_ADDPATH_TX) ? ", transmit" : "");
440
441 if (!bgp_afi_safi_valid_indices (afi, &safi))
442 return -1;
443
444 if (send_receive & BGP_ADDPATH_RX)
445 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV);
446
447 if (send_receive & BGP_ADDPATH_TX)
448 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV);
449 }
450
451 return 0;
452}
453
6410e93a
DS
454static int
455bgp_capability_hostname (struct peer *peer, struct capability_header *hdr)
456{
457 struct stream *s = BGP_INPUT (peer);
458 char str[BGP_MAX_HOSTNAME+1];
459 size_t end = stream_get_getp (s) + hdr->length;
460 u_char len;
461
462 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_RCV);
463
464 len = stream_getc(s);
465 if (stream_get_getp(s) + len > end)
466 {
467 zlog_warn("%s: Received malformed hostname capability from peer %s",
468 __FUNCTION__, peer->host);
469 return -1;
470 }
471
472 if (len > BGP_MAX_HOSTNAME)
473 {
474 stream_get(str, s, BGP_MAX_HOSTNAME);
475 stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
476 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
477 }
478 else if (len)
479 stream_get(str, s, len);
480
481 if (len)
482 {
483 str[len] = '\0';
484
485 if (peer->hostname != NULL)
486 XFREE(MTYPE_HOST, peer->hostname);
487
488 if (peer->domainname != NULL)
489 XFREE(MTYPE_HOST, peer->domainname);
490
491 peer->hostname = XSTRDUP(MTYPE_HOST, str);
492 }
493
494 if (stream_get_getp(s) +1 > end)
495 {
496 zlog_warn("%s: Received invalid domain name len (hostname capability) from peer %s",
497 __FUNCTION__, peer->host);
498 return -1;
499 }
500
501 len = stream_getc(s);
502 if (stream_get_getp(s) + len > end)
503 {
504 zlog_warn("%s: Received runt domain name (hostname capability) from peer %s",
505 __FUNCTION__, peer->host);
506 return -1;
507 }
508
509 if (len > BGP_MAX_HOSTNAME)
510 {
511 stream_get(str, s, BGP_MAX_HOSTNAME);
512 stream_forward_getp(s, len-BGP_MAX_HOSTNAME);
513 len = BGP_MAX_HOSTNAME; /* to set the '\0' below */
514 }
515 else if (len)
516 stream_get(str, s, len);
517
518 if (len)
519 {
520 str[len] = '\0';
521 peer->domainname = XSTRDUP(MTYPE_HOST, str);
522 }
523
524 if (bgp_debug_neighbor_events(peer))
525 {
526 zlog_debug("%s received hostname %s, domainname %s",
527 peer->host, peer->hostname, peer->domainname);
528 }
529
530 return 0;
531}
532
8a92a8a0
DS
533static int
534bgp_capability_enhe (struct peer *peer, struct capability_header *hdr)
535{
536 struct stream *s = BGP_INPUT (peer);
537 size_t end = stream_get_getp (s) + hdr->length;
538
539 while (stream_get_getp (s) + 6 <= end)
540 {
541 afi_t afi = stream_getw (s);
542 safi_t safi = stream_getw (s);
543 afi_t nh_afi = stream_getw (s);
544
545 if (bgp_debug_neighbor_events(peer))
546 zlog_debug ("%s Received with value triple (afi/safi/next-hop afi): %u/%u/%u",
547 peer->host, afi, safi, nh_afi);
548
549 if (!bgp_afi_safi_valid_indices (afi, &safi))
550 return -1;
551
552 if (afi != AFI_IP || nh_afi != AFI_IP6)
553 {
554 zlog_warn ("%s Extended Next-hop capability, wrong afi/next-hop afi: %u/%u",
555 peer->host, afi, nh_afi);
556 return -1;
557 }
558
559 /* Until SAFIs other than SAFI_UNICAST are supported */
560 if (safi != SAFI_UNICAST)
561 zlog_warn ("%s Extended Next-hop capability came with unsupported SAFI: %u",
562 peer->host, safi);
563
564 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_RCV);
565
566 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_ADV))
567 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ENHE_AF_NEGO);
568 }
569
570 SET_FLAG (peer->cap, PEER_CAP_ENHE_RCV);
571
572 return 0;
573}
574
6410e93a 575 static const struct message capcode_str[] =
6d58272b 576{
6d58272b
PJ
577 { CAPABILITY_CODE_MP, "MultiProtocol Extensions" },
578 { CAPABILITY_CODE_REFRESH, "Route Refresh" },
579 { CAPABILITY_CODE_ORF, "Cooperative Route Filtering" },
580 { CAPABILITY_CODE_RESTART, "Graceful Restart" },
581 { CAPABILITY_CODE_AS4, "4-octet AS number" },
89eeecb8 582 { CAPABILITY_CODE_ADDPATH, "AddPath" },
6d58272b 583 { CAPABILITY_CODE_DYNAMIC, "Dynamic" },
8a92a8a0 584 { CAPABILITY_CODE_ENHE, "Extended Next Hop Encoding" },
89eeecb8 585 { CAPABILITY_CODE_DYNAMIC_OLD, "Dynamic (Old)" },
6d58272b
PJ
586 { CAPABILITY_CODE_REFRESH_OLD, "Route Refresh (Old)" },
587 { CAPABILITY_CODE_ORF_OLD, "ORF (Old)" },
6410e93a 588 { CAPABILITY_CODE_HOSTNAME, "Hostname" },
6d58272b 589};
837d16cc 590static const int capcode_str_max = array_size(capcode_str);
6d58272b
PJ
591
592/* Minimum sizes for length field of each cap (so not inc. the header) */
fc52f953 593static const size_t cap_minsizes[] =
6d58272b
PJ
594{
595 [CAPABILITY_CODE_MP] = sizeof (struct capability_mp_data),
596 [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN,
597 [CAPABILITY_CODE_ORF] = sizeof (struct capability_orf_entry),
370b64a2 598 [CAPABILITY_CODE_RESTART] = sizeof (struct capability_gr),
6d58272b 599 [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN,
a82478b9 600 [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN,
6d58272b 601 [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN,
89eeecb8 602 [CAPABILITY_CODE_DYNAMIC_OLD] = CAPABILITY_CODE_DYNAMIC_LEN,
8a92a8a0 603 [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN,
6d58272b
PJ
604 [CAPABILITY_CODE_REFRESH_OLD] = CAPABILITY_CODE_REFRESH_LEN,
605 [CAPABILITY_CODE_ORF_OLD] = sizeof (struct capability_orf_entry),
6410e93a 606 [CAPABILITY_CODE_HOSTNAME] = CAPABILITY_CODE_MIN_HOSTNAME_LEN,
6d58272b
PJ
607};
608
3b381c32
AS
609/**
610 * Parse given capability.
6d58272b 611 * XXX: This is reading into a stream, but not using stream API
3b381c32
AS
612 *
613 * @param[out] mp_capability Set to 1 on return iff one or more Multiprotocol
614 * capabilities were encountered.
6d58272b
PJ
615 */
616static int
3b381c32
AS
617bgp_capability_parse (struct peer *peer, size_t length, int *mp_capability,
618 u_char **error)
6d58272b
PJ
619{
620 int ret;
621 struct stream *s = BGP_INPUT (peer);
622 size_t end = stream_get_getp (s) + length;
623
624 assert (STREAM_READABLE (s) >= length);
625
626 while (stream_get_getp (s) < end)
627 {
628 size_t start;
629 u_char *sp = stream_pnt (s);
630 struct capability_header caphdr;
631
718e3744 632 /* We need at least capability code and capability length. */
6d58272b 633 if (stream_get_getp(s) + 2 > end)
718e3744 634 {
6d58272b 635 zlog_info ("%s Capability length error (< header)", peer->host);
718e3744 636 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
637 return -1;
638 }
6d58272b
PJ
639
640 caphdr.code = stream_getc (s);
641 caphdr.length = stream_getc (s);
642 start = stream_get_getp (s);
643
644 /* Capability length check sanity check. */
645 if (start + caphdr.length > end)
718e3744 646 {
6d58272b 647 zlog_info ("%s Capability length error (< length)", peer->host);
718e3744 648 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
649 return -1;
650 }
6d58272b 651
16286195 652 if (bgp_debug_neighbor_events(peer))
6d58272b
PJ
653 zlog_debug ("%s OPEN has %s capability (%u), length %u",
654 peer->host,
655 LOOKUP (capcode_str, caphdr.code),
656 caphdr.code, caphdr.length);
657
658 /* Length sanity check, type-specific, for known capabilities */
659 switch (caphdr.code)
660 {
661 case CAPABILITY_CODE_MP:
662 case CAPABILITY_CODE_REFRESH:
663 case CAPABILITY_CODE_REFRESH_OLD:
664 case CAPABILITY_CODE_ORF:
665 case CAPABILITY_CODE_ORF_OLD:
666 case CAPABILITY_CODE_RESTART:
0b2aa3a0 667 case CAPABILITY_CODE_AS4:
a82478b9 668 case CAPABILITY_CODE_ADDPATH:
6d58272b 669 case CAPABILITY_CODE_DYNAMIC:
89eeecb8 670 case CAPABILITY_CODE_DYNAMIC_OLD:
8a92a8a0 671 case CAPABILITY_CODE_ENHE:
6410e93a 672 case CAPABILITY_CODE_HOSTNAME:
6d58272b
PJ
673 /* Check length. */
674 if (caphdr.length < cap_minsizes[caphdr.code])
675 {
676 zlog_info ("%s %s Capability length error: got %u,"
677 " expected at least %u",
678 peer->host,
679 LOOKUP (capcode_str, caphdr.code),
fc52f953
SH
680 caphdr.length,
681 (unsigned) cap_minsizes[caphdr.code]);
6d58272b
PJ
682 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
683 return -1;
684 }
685 /* we deliberately ignore unknown codes, see below */
686 default:
687 break;
688 }
689
690 switch (caphdr.code)
691 {
692 case CAPABILITY_CODE_MP:
693 {
3b381c32
AS
694 *mp_capability = 1;
695
6d58272b
PJ
696 /* Ignore capability when override-capability is set. */
697 if (! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
698 {
699 /* Set negotiated value. */
700 ret = bgp_capability_mp (peer, &caphdr);
701
702 /* Unsupported Capability. */
703 if (ret < 0)
704 {
705 /* Store return data. */
706 memcpy (*error, sp, caphdr.length + 2);
707 *error += caphdr.length + 2;
708 }
709 }
710 }
711 break;
712 case CAPABILITY_CODE_REFRESH:
713 case CAPABILITY_CODE_REFRESH_OLD:
714 {
715 /* BGP refresh capability */
716 if (caphdr.code == CAPABILITY_CODE_REFRESH_OLD)
717 SET_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV);
718 else
719 SET_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV);
720 }
721 break;
722 case CAPABILITY_CODE_ORF:
723 case CAPABILITY_CODE_ORF_OLD:
fe9bb645 724 if (bgp_capability_orf_entry (peer, &caphdr))
6d58272b
PJ
725 return -1;
726 break;
727 case CAPABILITY_CODE_RESTART:
728 if (bgp_capability_restart (peer, &caphdr))
729 return -1;
730 break;
731 case CAPABILITY_CODE_DYNAMIC:
89eeecb8 732 case CAPABILITY_CODE_DYNAMIC_OLD:
6d58272b
PJ
733 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV);
734 break;
0b2aa3a0
PJ
735 case CAPABILITY_CODE_AS4:
736 /* Already handled as a special-case parsing of the capabilities
737 * at the beginning of OPEN processing. So we care not a jot
738 * for the value really, only error case.
739 */
740 if (!bgp_capability_as4 (peer, &caphdr))
741 return -1;
742 break;
a82478b9
DS
743 case CAPABILITY_CODE_ADDPATH:
744 if (bgp_capability_addpath (peer, &caphdr))
745 return -1;
746 break;
6410e93a
DS
747 case CAPABILITY_CODE_HOSTNAME:
748 if (bgp_capability_hostname (peer, &caphdr))
749 return -1;
750 break;
8a92a8a0
DS
751 case CAPABILITY_CODE_ENHE:
752 if (bgp_capability_enhe (peer, &caphdr))
753 return -1;
754 break;
6d58272b
PJ
755 default:
756 if (caphdr.code > 128)
757 {
758 /* We don't send Notification for unknown vendor specific
759 capabilities. It seems reasonable for now... */
760 zlog_warn ("%s Vendor specific capability %d",
761 peer->host, caphdr.code);
762 }
763 else
764 {
765 zlog_warn ("%s unrecognized capability code: %d - ignored",
766 peer->host, caphdr.code);
767 memcpy (*error, sp, caphdr.length + 2);
768 *error += caphdr.length + 2;
769 }
770 }
771 if (stream_get_getp(s) != (start + caphdr.length))
772 {
773 if (stream_get_getp(s) > (start + caphdr.length))
774 zlog_warn ("%s Cap-parser for %s read past cap-length, %u!",
775 peer->host, LOOKUP (capcode_str, caphdr.code),
776 caphdr.length);
777 stream_set_getp (s, start + caphdr.length);
778 }
718e3744 779 }
780 return 0;
781}
782
94f2b392 783static int
6d58272b 784bgp_auth_parse (struct peer *peer, size_t length)
718e3744 785{
786 bgp_notify_send (peer,
787 BGP_NOTIFY_OPEN_ERR,
788 BGP_NOTIFY_OPEN_AUTH_FAILURE);
789 return -1;
790}
791
94f2b392 792static int
718e3744 793strict_capability_same (struct peer *peer)
794{
795 int i, j;
796
797 for (i = AFI_IP; i < AFI_MAX; i++)
798 for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
799 if (peer->afc[i][j] != peer->afc_nego[i][j])
800 return 0;
801 return 1;
802}
803
0b2aa3a0
PJ
804/* peek into option, stores ASN to *as4 if the AS4 capability was found.
805 * Returns 0 if no as4 found, as4cap value otherwise.
806 */
807as_t
808peek_for_as4_capability (struct peer *peer, u_char length)
809{
810 struct stream *s = BGP_INPUT (peer);
811 size_t orig_getp = stream_get_getp (s);
812 size_t end = orig_getp + length;
813 as_t as4 = 0;
814
815 /* The full capability parser will better flag the error.. */
816 if (STREAM_READABLE(s) < length)
817 return 0;
818
819 if (BGP_DEBUG (as4, AS4))
820 zlog_info ("%s [AS4] rcv OPEN w/ OPTION parameter len: %u,"
821 " peeking for as4",
822 peer->host, length);
823 /* the error cases we DONT handle, we ONLY try to read as4 out of
824 * correctly formatted options.
825 */
826 while (stream_get_getp(s) < end)
827 {
828 u_char opt_type;
829 u_char opt_length;
830
831 /* Check the length. */
832 if (stream_get_getp (s) + 2 > end)
833 goto end;
834
835 /* Fetch option type and length. */
836 opt_type = stream_getc (s);
837 opt_length = stream_getc (s);
838
839 /* Option length check. */
840 if (stream_get_getp (s) + opt_length > end)
841 goto end;
842
843 if (opt_type == BGP_OPEN_OPT_CAP)
844 {
845 unsigned long capd_start = stream_get_getp (s);
846 unsigned long capd_end = capd_start + opt_length;
847
848 assert (capd_end <= end);
849
850 while (stream_get_getp (s) < capd_end)
851 {
852 struct capability_header hdr;
853
854 if (stream_get_getp (s) + 2 > capd_end)
855 goto end;
856
857 hdr.code = stream_getc (s);
858 hdr.length = stream_getc (s);
859
860 if ((stream_get_getp(s) + hdr.length) > capd_end)
861 goto end;
862
863 if (hdr.code == CAPABILITY_CODE_AS4)
864 {
0b2aa3a0
PJ
865 if (BGP_DEBUG (as4, AS4))
866 zlog_info ("[AS4] found AS4 capability, about to parse");
867 as4 = bgp_capability_as4 (peer, &hdr);
868
869 goto end;
870 }
871 stream_forward_getp (s, hdr.length);
872 }
873 }
874 }
875
876end:
877 stream_set_getp (s, orig_getp);
878 return as4;
879}
880
3b381c32
AS
881/**
882 * Parse open option.
883 *
884 * @param[out] mp_capability @see bgp_capability_parse() for semantics.
885 */
718e3744 886int
3b381c32 887bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
718e3744 888{
889 int ret;
718e3744 890 u_char *error;
891 u_char error_data[BGP_MAX_PACKET_SIZE];
6d58272b
PJ
892 struct stream *s = BGP_INPUT(peer);
893 size_t end = stream_get_getp (s) + length;
718e3744 894
895 ret = 0;
718e3744 896 error = error_data;
897
16286195 898 if (bgp_debug_neighbor_events(peer))
8325cd7f 899 zlog_debug ("%s rcv OPEN w/ OPTION parameter len: %u",
718e3744 900 peer->host, length);
901
6d58272b 902 while (stream_get_getp(s) < end)
718e3744 903 {
6d58272b
PJ
904 u_char opt_type;
905 u_char opt_length;
906
907 /* Must have at least an OPEN option header */
908 if (STREAM_READABLE(s) < 2)
718e3744 909 {
910 zlog_info ("%s Option length error", peer->host);
911 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
912 return -1;
913 }
914
915 /* Fetch option type and length. */
6d58272b
PJ
916 opt_type = stream_getc (s);
917 opt_length = stream_getc (s);
718e3744 918
919 /* Option length check. */
6d58272b 920 if (STREAM_READABLE (s) < opt_length)
718e3744 921 {
922 zlog_info ("%s Option length error", peer->host);
923 bgp_notify_send (peer, BGP_NOTIFY_CEASE, 0);
924 return -1;
925 }
926
16286195 927 if (bgp_debug_neighbor_events(peer))
8325cd7f 928 zlog_debug ("%s rcvd OPEN w/ optional parameter type %u (%s) len %u",
718e3744 929 peer->host, opt_type,
930 opt_type == BGP_OPEN_OPT_AUTH ? "Authentication" :
931 opt_type == BGP_OPEN_OPT_CAP ? "Capability" : "Unknown",
932 opt_length);
933
934 switch (opt_type)
935 {
936 case BGP_OPEN_OPT_AUTH:
6d58272b 937 ret = bgp_auth_parse (peer, opt_length);
718e3744 938 break;
939 case BGP_OPEN_OPT_CAP:
3b381c32 940 ret = bgp_capability_parse (peer, opt_length, mp_capability, &error);
718e3744 941 break;
942 default:
943 bgp_notify_send (peer,
944 BGP_NOTIFY_OPEN_ERR,
945 BGP_NOTIFY_OPEN_UNSUP_PARAM);
946 ret = -1;
947 break;
948 }
949
950 /* Parse error. To accumulate all unsupported capability codes,
951 bgp_capability_parse does not return -1 when encounter
952 unsupported capability code. To detect that, please check
953 error and erro_data pointer, like below. */
954 if (ret < 0)
955 return -1;
718e3744 956 }
957
958 /* All OPEN option is parsed. Check capability when strict compare
959 flag is enabled.*/
960 if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
961 {
962 /* If Unsupported Capability exists. */
963 if (error != error_data)
964 {
965 bgp_notify_send_with_data (peer,
966 BGP_NOTIFY_OPEN_ERR,
967 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
968 error_data, error - error_data);
969 return -1;
970 }
971
972 /* Check local capability does not negotiated with remote
973 peer. */
974 if (! strict_capability_same (peer))
975 {
976 bgp_notify_send (peer,
977 BGP_NOTIFY_OPEN_ERR,
978 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
979 return -1;
980 }
981 }
982
3b381c32 983 /* Check there are no common AFI/SAFIs and send Unsupported Capability
718e3744 984 error. */
3b381c32
AS
985 if (*mp_capability &&
986 ! CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
718e3744 987 {
988 if (! peer->afc_nego[AFI_IP][SAFI_UNICAST]
989 && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
990 && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
991 && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
992 && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
993 {
16286195 994 zlog_err ("%s [Error] Configured AFI/SAFIs do not "
3b381c32
AS
995 "overlap with received MP capabilities",
996 peer->host);
718e3744 997
998 if (error != error_data)
718e3744 999 bgp_notify_send_with_data (peer,
1000 BGP_NOTIFY_OPEN_ERR,
1001 BGP_NOTIFY_OPEN_UNSUP_CAPBL,
1002 error_data, error - error_data);
1003 else
1004 bgp_notify_send (peer,
1005 BGP_NOTIFY_OPEN_ERR,
1006 BGP_NOTIFY_OPEN_UNSUP_CAPBL);
1007 return -1;
1008 }
1009 }
1010 return 0;
1011}
1012
94f2b392 1013static void
718e3744 1014bgp_open_capability_orf (struct stream *s, struct peer *peer,
1015 afi_t afi, safi_t safi, u_char code)
1016{
1017 u_char cap_len;
1018 u_char orf_len;
1019 unsigned long capp;
1020 unsigned long orfp;
1021 unsigned long numberp;
1022 int number_of_orfs = 0;
1023
1024 if (safi == SAFI_MPLS_VPN)
42e6d745 1025 safi = SAFI_MPLS_LABELED_VPN;
718e3744 1026
1027 stream_putc (s, BGP_OPEN_OPT_CAP);
9985f83c 1028 capp = stream_get_endp (s); /* Set Capability Len Pointer */
718e3744 1029 stream_putc (s, 0); /* Capability Length */
1030 stream_putc (s, code); /* Capability Code */
9985f83c 1031 orfp = stream_get_endp (s); /* Set ORF Len Pointer */
718e3744 1032 stream_putc (s, 0); /* ORF Length */
1033 stream_putw (s, afi);
1034 stream_putc (s, 0);
1035 stream_putc (s, safi);
9985f83c 1036 numberp = stream_get_endp (s); /* Set Number Pointer */
718e3744 1037 stream_putc (s, 0); /* Number of ORFs */
1038
1039 /* Address Prefix ORF */
1040 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1041 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1042 {
1043 stream_putc (s, (code == CAPABILITY_CODE_ORF ?
1044 ORF_TYPE_PREFIX : ORF_TYPE_PREFIX_OLD));
1045
1046 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1047 && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1048 {
1049 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
1050 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
1051 stream_putc (s, ORF_MODE_BOTH);
1052 }
1053 else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
1054 {
1055 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV);
1056 stream_putc (s, ORF_MODE_SEND);
1057 }
1058 else
1059 {
1060 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV);
1061 stream_putc (s, ORF_MODE_RECEIVE);
1062 }
1063 number_of_orfs++;
1064 }
1065
1066 /* Total Number of ORFs. */
1067 stream_putc_at (s, numberp, number_of_orfs);
1068
1069 /* Total ORF Len. */
9985f83c 1070 orf_len = stream_get_endp (s) - orfp - 1;
718e3744 1071 stream_putc_at (s, orfp, orf_len);
1072
1073 /* Total Capability Len. */
9985f83c 1074 cap_len = stream_get_endp (s) - capp - 1;
718e3744 1075 stream_putc_at (s, capp, cap_len);
1076}
1077
1078/* Fill in capability open option to the packet. */
1079void
1080bgp_open_capability (struct stream *s, struct peer *peer)
1081{
1082 u_char len;
fe7d2a48 1083 unsigned long cp, capp, rcapp;
718e3744 1084 afi_t afi;
1085 safi_t safi;
0b2aa3a0 1086 as_t local_as;
fe7d2a48 1087 u_int32_t restart_time;
a82478b9 1088 u_char afi_safi_count = 0;
6410e93a 1089 struct utsname names;
718e3744 1090
1091 /* Remember current pointer for Opt Parm Len. */
9985f83c 1092 cp = stream_get_endp (s);
718e3744 1093
1094 /* Opt Parm Len. */
1095 stream_putc (s, 0);
1096
1097 /* Do not send capability. */
1098 if (! CHECK_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN)
1099 || CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
1100 return;
1101
718e3744 1102 /* IPv4 unicast. */
1103 if (peer->afc[AFI_IP][SAFI_UNICAST])
1104 {
1105 peer->afc_adv[AFI_IP][SAFI_UNICAST] = 1;
1106 stream_putc (s, BGP_OPEN_OPT_CAP);
1107 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1108 stream_putc (s, CAPABILITY_CODE_MP);
1109 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1110 stream_putw (s, AFI_IP);
1111 stream_putc (s, 0);
1112 stream_putc (s, SAFI_UNICAST);
1113 }
1114 /* IPv4 multicast. */
1115 if (peer->afc[AFI_IP][SAFI_MULTICAST])
1116 {
1117 peer->afc_adv[AFI_IP][SAFI_MULTICAST] = 1;
1118 stream_putc (s, BGP_OPEN_OPT_CAP);
1119 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1120 stream_putc (s, CAPABILITY_CODE_MP);
1121 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1122 stream_putw (s, AFI_IP);
1123 stream_putc (s, 0);
1124 stream_putc (s, SAFI_MULTICAST);
1125 }
1126 /* IPv4 VPN */
1127 if (peer->afc[AFI_IP][SAFI_MPLS_VPN])
1128 {
1129 peer->afc_adv[AFI_IP][SAFI_MPLS_VPN] = 1;
1130 stream_putc (s, BGP_OPEN_OPT_CAP);
1131 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1132 stream_putc (s, CAPABILITY_CODE_MP);
1133 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1134 stream_putw (s, AFI_IP);
1135 stream_putc (s, 0);
42e6d745 1136 stream_putc (s, SAFI_MPLS_LABELED_VPN);
718e3744 1137 }
1138#ifdef HAVE_IPV6
8a92a8a0
DS
1139 /* Currently supporting RFC-5549 for Link-Local peering only */
1140 if (CHECK_FLAG (peer->flags, PEER_FLAG_CAPABILITY_ENHE) &&
1141 peer->su.sa.sa_family == AF_INET6 &&
1142 IN6_IS_ADDR_LINKLOCAL(&peer->su.sin6.sin6_addr))
1143 {
1144 /* RFC 5549 Extended Next Hop Encoding */
1145 SET_FLAG (peer->cap, PEER_CAP_ENHE_ADV);
1146 stream_putc (s, BGP_OPEN_OPT_CAP);
1147 stream_putc (s, CAPABILITY_CODE_ENHE_LEN + 2);
1148 stream_putc (s, CAPABILITY_CODE_ENHE);
1149 stream_putc (s, CAPABILITY_CODE_ENHE_LEN);
1150 /* Currently supporting for SAFI_UNICAST only */
1151 SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_ADV);
1152 stream_putw (s, AFI_IP);
1153 stream_putw (s, SAFI_UNICAST);
1154 stream_putw (s, AFI_IP6);
1155
1156 if (CHECK_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_RCV))
1157 SET_FLAG (peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO);
1158 }
718e3744 1159 /* IPv6 unicast. */
1160 if (peer->afc[AFI_IP6][SAFI_UNICAST])
1161 {
1162 peer->afc_adv[AFI_IP6][SAFI_UNICAST] = 1;
1163 stream_putc (s, BGP_OPEN_OPT_CAP);
1164 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1165 stream_putc (s, CAPABILITY_CODE_MP);
1166 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1167 stream_putw (s, AFI_IP6);
1168 stream_putc (s, 0);
1169 stream_putc (s, SAFI_UNICAST);
1170 }
1171 /* IPv6 multicast. */
1172 if (peer->afc[AFI_IP6][SAFI_MULTICAST])
1173 {
1174 peer->afc_adv[AFI_IP6][SAFI_MULTICAST] = 1;
1175 stream_putc (s, BGP_OPEN_OPT_CAP);
1176 stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
1177 stream_putc (s, CAPABILITY_CODE_MP);
1178 stream_putc (s, CAPABILITY_CODE_MP_LEN);
1179 stream_putw (s, AFI_IP6);
1180 stream_putc (s, 0);
1181 stream_putc (s, SAFI_MULTICAST);
1182 }
1183#endif /* HAVE_IPV6 */
1184
1185 /* Route refresh. */
c9502438 1186 SET_FLAG (peer->cap, PEER_CAP_REFRESH_ADV);
1187 stream_putc (s, BGP_OPEN_OPT_CAP);
1188 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1189 stream_putc (s, CAPABILITY_CODE_REFRESH_OLD);
1190 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
1191 stream_putc (s, BGP_OPEN_OPT_CAP);
1192 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN + 2);
1193 stream_putc (s, CAPABILITY_CODE_REFRESH);
1194 stream_putc (s, CAPABILITY_CODE_REFRESH_LEN);
718e3744 1195
0b2aa3a0
PJ
1196 /* AS4 */
1197 SET_FLAG (peer->cap, PEER_CAP_AS4_ADV);
1198 stream_putc (s, BGP_OPEN_OPT_CAP);
1199 stream_putc (s, CAPABILITY_CODE_AS4_LEN + 2);
1200 stream_putc (s, CAPABILITY_CODE_AS4);
1201 stream_putc (s, CAPABILITY_CODE_AS4_LEN);
1202 if ( peer->change_local_as )
1203 local_as = peer->change_local_as;
1204 else
1205 local_as = peer->local_as;
1206 stream_putl (s, local_as );
1207
a82478b9
DS
1208 /* AddPath
1209 * For now we will only advertise RX support. TX support will be added later.
1210 */
1211 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1212 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1213 if (peer->afc[afi][safi])
1214 afi_safi_count++;
1215
1216 SET_FLAG (peer->cap, PEER_CAP_ADDPATH_ADV);
1217 stream_putc (s, BGP_OPEN_OPT_CAP);
1218 stream_putc (s, (CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count) + 2);
1219 stream_putc (s, CAPABILITY_CODE_ADDPATH);
1220 stream_putc (s, CAPABILITY_CODE_ADDPATH_LEN * afi_safi_count);
1221
1222 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1223 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1224 if (peer->afc[afi][safi])
1225 {
1226 stream_putw (s, afi);
1227 stream_putc (s, safi);
1228 stream_putc (s, BGP_ADDPATH_RX);
1229 SET_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV);
1230 }
1231
718e3744 1232 /* ORF capability. */
1233 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1234 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1235 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
1236 || CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
1237 {
1238 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF_OLD);
1239 bgp_open_capability_orf (s, peer, afi, safi, CAPABILITY_CODE_ORF);
1240 }
1241
1242 /* Dynamic capability. */
1243 if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
1244 {
1245 SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
1246 stream_putc (s, BGP_OPEN_OPT_CAP);
1247 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
89eeecb8
DS
1248 stream_putc (s, CAPABILITY_CODE_DYNAMIC_OLD);
1249 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1250 stream_putc (s, BGP_OPEN_OPT_CAP);
1251 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN + 2);
718e3744 1252 stream_putc (s, CAPABILITY_CODE_DYNAMIC);
1253 stream_putc (s, CAPABILITY_CODE_DYNAMIC_LEN);
1254 }
1255
6410e93a
DS
1256 /* Hostname capability */
1257 uname(&names);
1258 if (names.nodename[0] != '\0')
1259 {
1260 SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV);
1261 stream_putc (s, BGP_OPEN_OPT_CAP);
1262 rcapp = stream_get_endp(s); /* Ptr to length placeholder */
1263 stream_putc(s, 0); /* dummy len for now */
1264 stream_putc (s, CAPABILITY_CODE_HOSTNAME);
1265 capp = stream_get_endp(s);
1266 stream_putc(s, 0); /* dummy len for now */
1267 len = strlen(names.nodename);
1268 if (len > BGP_MAX_HOSTNAME)
1269 len = BGP_MAX_HOSTNAME;
1270
1271 stream_putc(s, len);
1272 stream_put(s, names.nodename, len);
1273#ifdef _GNU_SOURCE
1274 if ((names.domainname[0] != '\0') &&
1275 (strcmp(names.domainname, "(none)") != 0))
1276 {
1277 len = strlen(names.domainname);
1278 if (len > BGP_MAX_HOSTNAME)
1279 len = BGP_MAX_HOSTNAME;
1280
1281 stream_putc(s, len);
1282 stream_put(s, names.domainname, len);
1283 }
1284 else
1285#endif
1286 {
1287 stream_putc(s, 0); /* 0 length */
1288 }
1289
1290 /* Set the lengths straight */
1291 len = stream_get_endp(s) - rcapp - 1;
1292 stream_putc_at(s, rcapp, len);
1293 len = stream_get_endp(s) - capp - 1;
1294 stream_putc_at(s, capp, len);
1295
1296 if (bgp_debug_neighbor_events(peer))
1297 zlog_debug("%s Sending hostname cap with hn = %s, dn = %s",
1298 peer->host, names.nodename, names.domainname);
1299 }
1300
fe7d2a48
DS
1301 /* Sending base graceful-restart capability irrespective of the config */
1302 SET_FLAG (peer->cap, PEER_CAP_RESTART_ADV);
1303 stream_putc (s, BGP_OPEN_OPT_CAP);
1304 capp = stream_get_endp (s); /* Set Capability Len Pointer */
1305 stream_putc (s, 0); /* Capability Length */
1306 stream_putc (s, CAPABILITY_CODE_RESTART);
1307 rcapp = stream_get_endp (s); /* Set Restart Capability Len Pointer */
1308 stream_putc (s, 0);
1309 restart_time = peer->bgp->restart_time;
1310 if (peer->bgp->t_startup)
1311 {
1312 SET_FLAG (restart_time, RESTART_R_BIT);
1313 SET_FLAG (peer->cap, PEER_CAP_RESTART_BIT_ADV);
1314 }
1315 stream_putw (s, restart_time);
1316
1317 /* Send address-family specific graceful-restart capability only when GR config
1318 is present */
538621f2 1319 if (bgp_flag_check (peer->bgp, BGP_FLAG_GRACEFUL_RESTART))
1320 {
fe7d2a48
DS
1321 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
1322 for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
1323 if (peer->afc[afi][safi])
1324 {
1325 stream_putw (s, afi);
1326 stream_putc (s, safi);
1327 stream_putc (s, 0); //Forwarding is not retained as of now.
1328 }
1329 }
1330
1331 /* Total Graceful restart capability Len. */
1332 len = stream_get_endp (s) - rcapp - 1;
1333 stream_putc_at (s, rcapp, len);
1334
1335 /* Total Capability Len. */
1336 len = stream_get_endp (s) - capp - 1;
1337 stream_putc_at (s, capp, len);
538621f2 1338
718e3744 1339 /* Total Opt Parm Len. */
9985f83c 1340 len = stream_get_endp (s) - cp - 1;
718e3744 1341 stream_putc_at (s, cp, len);
1342}