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