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