]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Update to draft-ietf-idr-bgp-prefix-sid-05
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 Copyright (C) 2016 Job Snijders <job@instituut.net>
4
5 This file is part of GNU Zebra.
6
7 GNU Zebra is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 GNU Zebra is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Zebra; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "linklist.h"
26 #include "memory.h"
27 #include "command.h"
28 #include "stream.h"
29 #include "filter.h"
30 #include "log.h"
31 #include "routemap.h"
32 #include "buffer.h"
33 #include "sockunion.h"
34 #include "plist.h"
35 #include "thread.h"
36 #include "workqueue.h"
37 #include "queue.h"
38 #include "mpls.h"
39 #include "memory.h"
40 #include "lib/json.h"
41
42 #include "bgpd/bgpd.h"
43 #include "bgpd/bgp_table.h"
44 #include "bgpd/bgp_route.h"
45 #include "bgpd/bgp_attr.h"
46 #include "bgpd/bgp_debug.h"
47 #include "bgpd/bgp_aspath.h"
48 #include "bgpd/bgp_regex.h"
49 #include "bgpd/bgp_community.h"
50 #include "bgpd/bgp_ecommunity.h"
51 #include "bgpd/bgp_lcommunity.h"
52 #include "bgpd/bgp_clist.h"
53 #include "bgpd/bgp_packet.h"
54 #include "bgpd/bgp_filter.h"
55 #include "bgpd/bgp_fsm.h"
56 #include "bgpd/bgp_mplsvpn.h"
57 #include "bgpd/bgp_encap.h"
58 #include "bgpd/bgp_nexthop.h"
59 #include "bgpd/bgp_damp.h"
60 #include "bgpd/bgp_advertise.h"
61 #include "bgpd/bgp_zebra.h"
62 #include "bgpd/bgp_vty.h"
63 #include "bgpd/bgp_mpath.h"
64 #include "bgpd/bgp_nht.h"
65 #include "bgpd/bgp_updgrp.h"
66 #include "bgpd/bgp_label.h"
67
68 #if ENABLE_BGP_VNC
69 #include "bgpd/rfapi/rfapi_backend.h"
70 #include "bgpd/rfapi/vnc_import_bgp.h"
71 #include "bgpd/rfapi/vnc_export_bgp.h"
72 #endif
73 #include "bgpd/bgp_encap_types.h"
74 #include "bgpd/bgp_encap_tlv.h"
75 #include "bgpd/bgp_evpn.h"
76 #include "bgpd/bgp_evpn_vty.h"
77
78
79 /* Extern from bgp_dump.c */
80 extern const char *bgp_origin_str[];
81 extern const char *bgp_origin_long_str[];
82
83 struct bgp_node *
84 bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
85 struct prefix_rd *prd)
86 {
87 struct bgp_node *rn;
88 struct bgp_node *prn = NULL;
89
90 assert (table);
91 if (!table)
92 return NULL;
93
94 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) ||
95 (safi == SAFI_EVPN))
96 {
97 prn = bgp_node_get (table, (struct prefix *) prd);
98
99 if (prn->info == NULL)
100 prn->info = bgp_table_init (afi, safi);
101 else
102 bgp_unlock_node (prn);
103 table = prn->info;
104 }
105
106 rn = bgp_node_get (table, p);
107
108 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) ||
109 (safi == SAFI_EVPN))
110 rn->prn = prn;
111
112 return rn;
113 }
114
115 /* Allocate bgp_info_extra */
116 static struct bgp_info_extra *
117 bgp_info_extra_new (void)
118 {
119 struct bgp_info_extra *new;
120 new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra));
121 return new;
122 }
123
124 static void
125 bgp_info_extra_free (struct bgp_info_extra **extra)
126 {
127 if (extra && *extra)
128 {
129 if ((*extra)->damp_info)
130 bgp_damp_info_free ((*extra)->damp_info, 0);
131
132 (*extra)->damp_info = NULL;
133
134 XFREE (MTYPE_BGP_ROUTE_EXTRA, *extra);
135
136 *extra = NULL;
137 }
138 }
139
140 /* Get bgp_info extra information for the given bgp_info, lazy allocated
141 * if required.
142 */
143 struct bgp_info_extra *
144 bgp_info_extra_get (struct bgp_info *ri)
145 {
146 if (!ri->extra)
147 ri->extra = bgp_info_extra_new();
148 return ri->extra;
149 }
150
151 /* Allocate new bgp info structure. */
152 struct bgp_info *
153 bgp_info_new (void)
154 {
155 return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
156 }
157
158 /* Free bgp route information. */
159 static void
160 bgp_info_free (struct bgp_info *binfo)
161 {
162 if (binfo->attr)
163 bgp_attr_unintern (&binfo->attr);
164
165 bgp_unlink_nexthop(binfo);
166 bgp_info_extra_free (&binfo->extra);
167 bgp_info_mpath_free (&binfo->mpath);
168
169 peer_unlock (binfo->peer); /* bgp_info peer reference */
170
171 XFREE (MTYPE_BGP_ROUTE, binfo);
172 }
173
174 struct bgp_info *
175 bgp_info_lock (struct bgp_info *binfo)
176 {
177 binfo->lock++;
178 return binfo;
179 }
180
181 struct bgp_info *
182 bgp_info_unlock (struct bgp_info *binfo)
183 {
184 assert (binfo && binfo->lock > 0);
185 binfo->lock--;
186
187 if (binfo->lock == 0)
188 {
189 #if 0
190 zlog_debug ("%s: unlocked and freeing", __func__);
191 zlog_backtrace (LOG_DEBUG);
192 #endif
193 bgp_info_free (binfo);
194 return NULL;
195 }
196
197 #if 0
198 if (binfo->lock == 1)
199 {
200 zlog_debug ("%s: unlocked to 1", __func__);
201 zlog_backtrace (LOG_DEBUG);
202 }
203 #endif
204
205 return binfo;
206 }
207
208 void
209 bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
210 {
211 struct bgp_info *top;
212
213 top = rn->info;
214
215 ri->next = rn->info;
216 ri->prev = NULL;
217 if (top)
218 top->prev = ri;
219 rn->info = ri;
220
221 bgp_info_lock (ri);
222 bgp_lock_node (rn);
223 peer_lock (ri->peer); /* bgp_info peer reference */
224 }
225
226 /* Do the actual removal of info from RIB, for use by bgp_process
227 completion callback *only* */
228 static void
229 bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri)
230 {
231 if (ri->next)
232 ri->next->prev = ri->prev;
233 if (ri->prev)
234 ri->prev->next = ri->next;
235 else
236 rn->info = ri->next;
237
238 bgp_info_mpath_dequeue (ri);
239 bgp_info_unlock (ri);
240 bgp_unlock_node (rn);
241 }
242
243 void
244 bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
245 {
246 bgp_info_set_flag (rn, ri, BGP_INFO_REMOVED);
247 /* set of previous already took care of pcount */
248 UNSET_FLAG (ri->flags, BGP_INFO_VALID);
249 }
250
251 /* undo the effects of a previous call to bgp_info_delete; typically
252 called when a route is deleted and then quickly re-added before the
253 deletion has been processed */
254 void
255 bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
256 {
257 bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
258 /* unset of previous already took care of pcount */
259 SET_FLAG (ri->flags, BGP_INFO_VALID);
260 }
261
262 /* Adjust pcount as required */
263 static void
264 bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
265 {
266 struct bgp_table *table;
267
268 assert (rn && bgp_node_table (rn));
269 assert (ri && ri->peer && ri->peer->bgp);
270
271 table = bgp_node_table (rn);
272
273 if (ri->peer == ri->peer->bgp->peer_self)
274 return;
275
276 if (!BGP_INFO_COUNTABLE (ri)
277 && CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
278 {
279
280 UNSET_FLAG (ri->flags, BGP_INFO_COUNTED);
281
282 /* slight hack, but more robust against errors. */
283 if (ri->peer->pcount[table->afi][table->safi])
284 ri->peer->pcount[table->afi][table->safi]--;
285 else
286 {
287 zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
288 __func__, ri->peer->host);
289 zlog_backtrace (LOG_WARNING);
290 zlog_warn ("%s: Please report to Quagga bugzilla", __func__);
291 }
292 }
293 else if (BGP_INFO_COUNTABLE (ri)
294 && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
295 {
296 SET_FLAG (ri->flags, BGP_INFO_COUNTED);
297 ri->peer->pcount[table->afi][table->safi]++;
298 }
299 }
300
301 static int
302 bgp_label_index_differs (struct bgp_info *ri1, struct bgp_info *ri2)
303 {
304 return (!(ri1->attr->extra->label_index == ri2->attr->extra->label_index));
305 }
306
307 /* Set/unset bgp_info flags, adjusting any other state as needed.
308 * This is here primarily to keep prefix-count in check.
309 */
310 void
311 bgp_info_set_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
312 {
313 SET_FLAG (ri->flags, flag);
314
315 /* early bath if we know it's not a flag that changes countability state */
316 if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_HISTORY|BGP_INFO_REMOVED))
317 return;
318
319 bgp_pcount_adjust (rn, ri);
320 }
321
322 void
323 bgp_info_unset_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
324 {
325 UNSET_FLAG (ri->flags, flag);
326
327 /* early bath if we know it's not a flag that changes countability state */
328 if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_HISTORY|BGP_INFO_REMOVED))
329 return;
330
331 bgp_pcount_adjust (rn, ri);
332 }
333
334 /* Get MED value. If MED value is missing and "bgp bestpath
335 missing-as-worst" is specified, treat it as the worst value. */
336 static u_int32_t
337 bgp_med_value (struct attr *attr, struct bgp *bgp)
338 {
339 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
340 return attr->med;
341 else
342 {
343 if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
344 return BGP_MED_MAX;
345 else
346 return 0;
347 }
348 }
349
350 void
351 bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf)
352 {
353 if (ri->addpath_rx_id)
354 sprintf(buf, "path %s (addpath rxid %d)", ri->peer->host, ri->addpath_rx_id);
355 else
356 sprintf(buf, "path %s", ri->peer->host);
357 }
358
359 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
360 static int
361 bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
362 int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg, int debug,
363 const char *pfx_buf)
364 {
365 struct attr *newattr, *existattr;
366 struct attr_extra *newattre, *existattre;
367 bgp_peer_sort_t new_sort;
368 bgp_peer_sort_t exist_sort;
369 u_int32_t new_pref;
370 u_int32_t exist_pref;
371 u_int32_t new_med;
372 u_int32_t exist_med;
373 u_int32_t new_weight;
374 u_int32_t exist_weight;
375 uint32_t newm, existm;
376 struct in_addr new_id;
377 struct in_addr exist_id;
378 int new_cluster;
379 int exist_cluster;
380 int internal_as_route;
381 int confed_as_route;
382 int ret;
383 char new_buf[PATH_ADDPATH_STR_BUFFER];
384 char exist_buf[PATH_ADDPATH_STR_BUFFER];
385
386 *paths_eq = 0;
387
388 /* 0. Null check. */
389 if (new == NULL)
390 {
391 if (debug)
392 zlog_debug("%s: new is NULL", pfx_buf);
393 return 0;
394 }
395
396 if (debug)
397 bgp_info_path_with_addpath_rx_str (new, new_buf);
398
399 if (exist == NULL)
400 {
401 if (debug)
402 zlog_debug("%s: %s is the initial bestpath", pfx_buf, new_buf);
403 return 1;
404 }
405
406 if (debug)
407 {
408 bgp_info_path_with_addpath_rx_str (exist, exist_buf);
409 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
410 pfx_buf, new_buf, new->flags, exist_buf, exist->flags);
411 }
412
413 newattr = new->attr;
414 existattr = exist->attr;
415 newattre = newattr->extra;
416 existattre = existattr->extra;
417
418 /* 1. Weight check. */
419 new_weight = exist_weight = 0;
420
421 if (newattre)
422 new_weight = newattre->weight;
423 if (existattre)
424 exist_weight = existattre->weight;
425
426 if (new_weight > exist_weight)
427 {
428 if (debug)
429 zlog_debug("%s: %s wins over %s due to weight %d > %d",
430 pfx_buf, new_buf, exist_buf, new_weight, exist_weight);
431 return 1;
432 }
433
434 if (new_weight < exist_weight)
435 {
436 if (debug)
437 zlog_debug("%s: %s loses to %s due to weight %d < %d",
438 pfx_buf, new_buf, exist_buf, new_weight, exist_weight);
439 return 0;
440 }
441
442 /* 2. Local preference check. */
443 new_pref = exist_pref = bgp->default_local_pref;
444
445 if (newattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
446 new_pref = newattr->local_pref;
447 if (existattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
448 exist_pref = existattr->local_pref;
449
450 if (new_pref > exist_pref)
451 {
452 if (debug)
453 zlog_debug("%s: %s wins over %s due to localpref %d > %d",
454 pfx_buf, new_buf, exist_buf, new_pref, exist_pref);
455 return 1;
456 }
457
458 if (new_pref < exist_pref)
459 {
460 if (debug)
461 zlog_debug("%s: %s loses to %s due to localpref %d < %d",
462 pfx_buf, new_buf, exist_buf, new_pref, exist_pref);
463 return 0;
464 }
465
466 /* 3. Local route check. We prefer:
467 * - BGP_ROUTE_STATIC
468 * - BGP_ROUTE_AGGREGATE
469 * - BGP_ROUTE_REDISTRIBUTE
470 */
471 if (! (new->sub_type == BGP_ROUTE_NORMAL))
472 {
473 if (debug)
474 zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
475 pfx_buf, new_buf, exist_buf);
476 return 1;
477 }
478
479 if (! (exist->sub_type == BGP_ROUTE_NORMAL))
480 {
481 if (debug)
482 zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
483 pfx_buf, new_buf, exist_buf);
484 return 0;
485 }
486
487 /* 4. AS path length check. */
488 if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
489 {
490 int exist_hops = aspath_count_hops (existattr->aspath);
491 int exist_confeds = aspath_count_confeds (existattr->aspath);
492
493 if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
494 {
495 int aspath_hops;
496
497 aspath_hops = aspath_count_hops (newattr->aspath);
498 aspath_hops += aspath_count_confeds (newattr->aspath);
499
500 if ( aspath_hops < (exist_hops + exist_confeds))
501 {
502 if (debug)
503 zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
504 pfx_buf, new_buf, exist_buf,
505 aspath_hops, (exist_hops + exist_confeds));
506 return 1;
507 }
508
509 if ( aspath_hops > (exist_hops + exist_confeds))
510 {
511 if (debug)
512 zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
513 pfx_buf, new_buf, exist_buf,
514 aspath_hops, (exist_hops + exist_confeds));
515 return 0;
516 }
517 }
518 else
519 {
520 int newhops = aspath_count_hops (newattr->aspath);
521
522 if (newhops < exist_hops)
523 {
524 if (debug)
525 zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
526 pfx_buf, new_buf, exist_buf, newhops, exist_hops);
527 return 1;
528 }
529
530 if (newhops > exist_hops)
531 {
532 if (debug)
533 zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
534 pfx_buf, new_buf, exist_buf, newhops, exist_hops);
535 return 0;
536 }
537 }
538 }
539
540 /* 5. Origin check. */
541 if (newattr->origin < existattr->origin)
542 {
543 if (debug)
544 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
545 pfx_buf, new_buf, exist_buf,
546 bgp_origin_long_str[newattr->origin],
547 bgp_origin_long_str[existattr->origin]);
548 return 1;
549 }
550
551 if (newattr->origin > existattr->origin)
552 {
553 if (debug)
554 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
555 pfx_buf, new_buf, exist_buf,
556 bgp_origin_long_str[newattr->origin],
557 bgp_origin_long_str[existattr->origin]);
558 return 0;
559 }
560
561 /* 6. MED check. */
562 internal_as_route = (aspath_count_hops (newattr->aspath) == 0
563 && aspath_count_hops (existattr->aspath) == 0);
564 confed_as_route = (aspath_count_confeds (newattr->aspath) > 0
565 && aspath_count_confeds (existattr->aspath) > 0
566 && aspath_count_hops (newattr->aspath) == 0
567 && aspath_count_hops (existattr->aspath) == 0);
568
569 if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
570 || (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
571 && confed_as_route)
572 || aspath_cmp_left (newattr->aspath, existattr->aspath)
573 || aspath_cmp_left_confed (newattr->aspath, existattr->aspath)
574 || internal_as_route)
575 {
576 new_med = bgp_med_value (new->attr, bgp);
577 exist_med = bgp_med_value (exist->attr, bgp);
578
579 if (new_med < exist_med)
580 {
581 if (debug)
582 zlog_debug("%s: %s wins over %s due to MED %d < %d",
583 pfx_buf, new_buf, exist_buf, new_med, exist_med);
584 return 1;
585 }
586
587 if (new_med > exist_med)
588 {
589 if (debug)
590 zlog_debug("%s: %s loses to %s due to MED %d > %d",
591 pfx_buf, new_buf, exist_buf, new_med, exist_med);
592 return 0;
593 }
594 }
595
596 /* 7. Peer type check. */
597 new_sort = new->peer->sort;
598 exist_sort = exist->peer->sort;
599
600 if (new_sort == BGP_PEER_EBGP
601 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED))
602 {
603 if (debug)
604 zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
605 pfx_buf, new_buf, exist_buf);
606 return 1;
607 }
608
609 if (exist_sort == BGP_PEER_EBGP
610 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED))
611 {
612 if (debug)
613 zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
614 pfx_buf, new_buf, exist_buf);
615 return 0;
616 }
617
618 /* 8. IGP metric check. */
619 newm = existm = 0;
620
621 if (new->extra)
622 newm = new->extra->igpmetric;
623 if (exist->extra)
624 existm = exist->extra->igpmetric;
625
626 if (newm < existm)
627 {
628 if (debug)
629 zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
630 pfx_buf, new_buf, exist_buf, newm, existm);
631 ret = 1;
632 }
633
634 if (newm > existm)
635 {
636 if (debug)
637 zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
638 pfx_buf, new_buf, exist_buf, newm, existm);
639 ret = 0;
640 }
641
642 /* 9. Same IGP metric. Compare the cluster list length as
643 representative of IGP hops metric. Rewrite the metric value
644 pair (newm, existm) with the cluster list length. Prefer the
645 path with smaller cluster list length. */
646 if (newm == existm)
647 {
648 if (peer_sort (new->peer) == BGP_PEER_IBGP
649 && peer_sort (exist->peer) == BGP_PEER_IBGP
650 && (mpath_cfg == NULL ||
651 CHECK_FLAG (mpath_cfg->ibgp_flags,
652 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN)))
653 {
654 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
655 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
656
657 if (newm < existm)
658 {
659 if (debug)
660 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
661 pfx_buf, new_buf, exist_buf, newm, existm);
662 ret = 1;
663 }
664
665 if (newm > existm)
666 {
667 if (debug)
668 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
669 pfx_buf, new_buf, exist_buf, newm, existm);
670 ret = 0;
671 }
672 }
673 }
674
675 /* 10. confed-external vs. confed-internal */
676 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
677 {
678 if (new_sort == BGP_PEER_CONFED && exist_sort == BGP_PEER_IBGP)
679 {
680 if (debug)
681 zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
682 pfx_buf, new_buf, exist_buf);
683 return 1;
684 }
685
686 if (exist_sort == BGP_PEER_CONFED && new_sort == BGP_PEER_IBGP)
687 {
688 if (debug)
689 zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
690 pfx_buf, new_buf, exist_buf);
691 return 0;
692 }
693 }
694
695 /* 11. Maximum path check. */
696 if (newm == existm)
697 {
698 if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX))
699 {
700
701 /*
702 * For the two paths, all comparison steps till IGP metric
703 * have succeeded - including AS_PATH hop count. Since 'bgp
704 * bestpath as-path multipath-relax' knob is on, we don't need
705 * an exact match of AS_PATH. Thus, mark the paths are equal.
706 * That will trigger both these paths to get into the multipath
707 * array.
708 */
709 *paths_eq = 1;
710
711 if (debug)
712 zlog_debug("%s: %s and %s are equal via multipath-relax",
713 pfx_buf, new_buf, exist_buf);
714 }
715 else if (new->peer->sort == BGP_PEER_IBGP)
716 {
717 if (aspath_cmp (new->attr->aspath, exist->attr->aspath))
718 {
719 *paths_eq = 1;
720
721 if (debug)
722 zlog_debug("%s: %s and %s are equal via matching aspaths",
723 pfx_buf, new_buf, exist_buf);
724 }
725 }
726 else if (new->peer->as == exist->peer->as)
727 {
728 *paths_eq = 1;
729
730 if (debug)
731 zlog_debug("%s: %s and %s are equal via same remote-as",
732 pfx_buf, new_buf, exist_buf);
733 }
734 }
735 else
736 {
737 /*
738 * TODO: If unequal cost ibgp multipath is enabled we can
739 * mark the paths as equal here instead of returning
740 */
741 if (debug)
742 {
743 if (ret == 1)
744 zlog_debug("%s: %s wins over %s after IGP metric comparison",
745 pfx_buf, new_buf, exist_buf);
746 else
747 zlog_debug("%s: %s loses to %s after IGP metric comparison",
748 pfx_buf, new_buf, exist_buf);
749 }
750 return ret;
751 }
752
753 /* 12. If both paths are external, prefer the path that was received
754 first (the oldest one). This step minimizes route-flap, since a
755 newer path won't displace an older one, even if it was the
756 preferred route based on the additional decision criteria below. */
757 if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
758 && new_sort == BGP_PEER_EBGP
759 && exist_sort == BGP_PEER_EBGP)
760 {
761 if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
762 {
763 if (debug)
764 zlog_debug("%s: %s wins over %s due to oldest external",
765 pfx_buf, new_buf, exist_buf);
766 return 1;
767 }
768
769 if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED))
770 {
771 if (debug)
772 zlog_debug("%s: %s loses to %s due to oldest external",
773 pfx_buf, new_buf, exist_buf);
774 return 0;
775 }
776 }
777
778 /* 13. Router-ID comparision. */
779 /* If one of the paths is "stale", the corresponding peer router-id will
780 * be 0 and would always win over the other path. If originator id is
781 * used for the comparision, it will decide which path is better.
782 */
783 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
784 new_id.s_addr = newattre->originator_id.s_addr;
785 else
786 new_id.s_addr = new->peer->remote_id.s_addr;
787 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
788 exist_id.s_addr = existattre->originator_id.s_addr;
789 else
790 exist_id.s_addr = exist->peer->remote_id.s_addr;
791
792 if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr))
793 {
794 if (debug)
795 zlog_debug("%s: %s wins over %s due to Router-ID comparison",
796 pfx_buf, new_buf, exist_buf);
797 return 1;
798 }
799
800 if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr))
801 {
802 if (debug)
803 zlog_debug("%s: %s loses to %s due to Router-ID comparison",
804 pfx_buf, new_buf, exist_buf);
805 return 0;
806 }
807
808 /* 14. Cluster length comparision. */
809 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
810 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
811
812 if (new_cluster < exist_cluster)
813 {
814 if (debug)
815 zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
816 pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster);
817 return 1;
818 }
819
820 if (new_cluster > exist_cluster)
821 {
822 if (debug)
823 zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
824 pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster);
825 return 0;
826 }
827
828 /* 15. Neighbor address comparision. */
829 /* Do this only if neither path is "stale" as stale paths do not have
830 * valid peer information (as the connection may or may not be up).
831 */
832 if (CHECK_FLAG (exist->flags, BGP_INFO_STALE))
833 {
834 if (debug)
835 zlog_debug("%s: %s wins over %s due to latter path being STALE",
836 pfx_buf, new_buf, exist_buf);
837 return 1;
838 }
839
840 if (CHECK_FLAG (new->flags, BGP_INFO_STALE))
841 {
842 if (debug)
843 zlog_debug("%s: %s loses to %s due to former path being STALE",
844 pfx_buf, new_buf, exist_buf);
845 return 0;
846 }
847
848 /* locally configured routes to advertise do not have su_remote */
849 if (new->peer->su_remote == NULL)
850 return 0;
851 if (exist->peer->su_remote == NULL)
852 return 1;
853
854 ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote);
855
856 if (ret == 1)
857 {
858 if (debug)
859 zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
860 pfx_buf, new_buf, exist_buf);
861 return 0;
862 }
863
864 if (ret == -1)
865 {
866 if (debug)
867 zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
868 pfx_buf, new_buf, exist_buf);
869 return 1;
870 }
871
872 if (debug)
873 zlog_debug("%s: %s wins over %s due to nothing left to compare",
874 pfx_buf, new_buf, exist_buf);
875
876 return 1;
877 }
878
879 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
880 * is preferred, or 0 if they are the same (usually will only occur if
881 * multipath is enabled
882 * This version is compatible with */
883 int
884 bgp_info_cmp_compatible (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
885 afi_t afi, safi_t safi)
886 {
887 int paths_eq;
888 int ret;
889 ret = bgp_info_cmp (bgp, new, exist, &paths_eq, NULL, 0, __func__);
890
891 if (paths_eq)
892 ret = 0;
893 else
894 {
895 if (ret == 1)
896 ret = -1;
897 else
898 ret = 1;
899 }
900 return ret;
901 }
902
903 static enum filter_type
904 bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
905 afi_t afi, safi_t safi)
906 {
907 struct bgp_filter *filter;
908
909 filter = &peer->filter[afi][safi];
910
911 #define FILTER_EXIST_WARN(F,f,filter) \
912 if (BGP_DEBUG (update, UPDATE_IN) \
913 && !(F ## _IN (filter))) \
914 zlog_warn ("%s: Could not find configured input %s-list %s!", \
915 peer->host, #f, F ## _IN_NAME(filter));
916
917 if (DISTRIBUTE_IN_NAME (filter)) {
918 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
919
920 if (access_list_apply (DISTRIBUTE_IN (filter), p) == FILTER_DENY)
921 return FILTER_DENY;
922 }
923
924 if (PREFIX_LIST_IN_NAME (filter)) {
925 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
926
927 if (prefix_list_apply (PREFIX_LIST_IN (filter), p) == PREFIX_DENY)
928 return FILTER_DENY;
929 }
930
931 if (FILTER_LIST_IN_NAME (filter)) {
932 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
933
934 if (as_list_apply (FILTER_LIST_IN (filter), attr->aspath)== AS_FILTER_DENY)
935 return FILTER_DENY;
936 }
937
938 return FILTER_PERMIT;
939 #undef FILTER_EXIST_WARN
940 }
941
942 static enum filter_type
943 bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
944 afi_t afi, safi_t safi)
945 {
946 struct bgp_filter *filter;
947
948 filter = &peer->filter[afi][safi];
949
950 #define FILTER_EXIST_WARN(F,f,filter) \
951 if (BGP_DEBUG (update, UPDATE_OUT) \
952 && !(F ## _OUT (filter))) \
953 zlog_warn ("%s: Could not find configured output %s-list %s!", \
954 peer->host, #f, F ## _OUT_NAME(filter));
955
956 if (DISTRIBUTE_OUT_NAME (filter)) {
957 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
958
959 if (access_list_apply (DISTRIBUTE_OUT (filter), p) == FILTER_DENY)
960 return FILTER_DENY;
961 }
962
963 if (PREFIX_LIST_OUT_NAME (filter)) {
964 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
965
966 if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
967 return FILTER_DENY;
968 }
969
970 if (FILTER_LIST_OUT_NAME (filter)) {
971 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
972
973 if (as_list_apply (FILTER_LIST_OUT (filter), attr->aspath) == AS_FILTER_DENY)
974 return FILTER_DENY;
975 }
976
977 return FILTER_PERMIT;
978 #undef FILTER_EXIST_WARN
979 }
980
981 /* If community attribute includes no_export then return 1. */
982 static int
983 bgp_community_filter (struct peer *peer, struct attr *attr)
984 {
985 if (attr->community)
986 {
987 /* NO_ADVERTISE check. */
988 if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
989 return 1;
990
991 /* NO_EXPORT check. */
992 if (peer->sort == BGP_PEER_EBGP &&
993 community_include (attr->community, COMMUNITY_NO_EXPORT))
994 return 1;
995
996 /* NO_EXPORT_SUBCONFED check. */
997 if (peer->sort == BGP_PEER_EBGP
998 || peer->sort == BGP_PEER_CONFED)
999 if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
1000 return 1;
1001 }
1002 return 0;
1003 }
1004
1005 /* Route reflection loop check. */
1006 static int
1007 bgp_cluster_filter (struct peer *peer, struct attr *attr)
1008 {
1009 struct in_addr cluster_id;
1010
1011 if (attr->extra && attr->extra->cluster)
1012 {
1013 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1014 cluster_id = peer->bgp->cluster_id;
1015 else
1016 cluster_id = peer->bgp->router_id;
1017
1018 if (cluster_loop_check (attr->extra->cluster, cluster_id))
1019 return 1;
1020 }
1021 return 0;
1022 }
1023
1024 static int
1025 bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
1026 afi_t afi, safi_t safi, const char *rmap_name)
1027 {
1028 struct bgp_filter *filter;
1029 struct bgp_info info;
1030 route_map_result_t ret;
1031 struct route_map *rmap = NULL;
1032
1033 filter = &peer->filter[afi][safi];
1034
1035 /* Apply default weight value. */
1036 if (peer->weight[afi][safi])
1037 (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
1038
1039 if (rmap_name)
1040 {
1041 rmap = route_map_lookup_by_name(rmap_name);
1042
1043 if (rmap == NULL)
1044 return RMAP_DENY;
1045 }
1046 else
1047 {
1048 if (ROUTE_MAP_IN_NAME(filter))
1049 {
1050 rmap = ROUTE_MAP_IN (filter);
1051
1052 if (rmap == NULL)
1053 return RMAP_DENY;
1054 }
1055 }
1056
1057 /* Route map apply. */
1058 if (rmap)
1059 {
1060 /* Duplicate current value to new strucutre for modification. */
1061 info.peer = peer;
1062 info.attr = attr;
1063
1064 SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);
1065
1066 /* Apply BGP route map to the attribute. */
1067 ret = route_map_apply (rmap, p, RMAP_BGP, &info);
1068
1069 peer->rmap_type = 0;
1070
1071 if (ret == RMAP_DENYMATCH)
1072 {
1073 /* Free newly generated AS path and community by route-map. */
1074 bgp_attr_flush (attr);
1075 return RMAP_DENY;
1076 }
1077 }
1078 return RMAP_PERMIT;
1079 }
1080
1081 static int
1082 bgp_output_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
1083 afi_t afi, safi_t safi, const char *rmap_name)
1084 {
1085 struct bgp_filter *filter;
1086 struct bgp_info info;
1087 route_map_result_t ret;
1088 struct route_map *rmap = NULL;
1089
1090 filter = &peer->filter[afi][safi];
1091
1092 /* Apply default weight value. */
1093 if (peer->weight[afi][safi])
1094 (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
1095
1096 if (rmap_name)
1097 {
1098 rmap = route_map_lookup_by_name(rmap_name);
1099
1100 if (rmap == NULL)
1101 return RMAP_DENY;
1102 }
1103 else
1104 {
1105 if (ROUTE_MAP_OUT_NAME(filter))
1106 {
1107 rmap = ROUTE_MAP_OUT (filter);
1108
1109 if (rmap == NULL)
1110 return RMAP_DENY;
1111 }
1112 }
1113
1114 /* Route map apply. */
1115 if (rmap)
1116 {
1117 /* Duplicate current value to new strucutre for modification. */
1118 info.peer = peer;
1119 info.attr = attr;
1120
1121 SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
1122
1123 /* Apply BGP route map to the attribute. */
1124 ret = route_map_apply (rmap, p, RMAP_BGP, &info);
1125
1126 peer->rmap_type = 0;
1127
1128 if (ret == RMAP_DENYMATCH)
1129 /* caller has multiple error paths with bgp_attr_flush() */
1130 return RMAP_DENY;
1131 }
1132 return RMAP_PERMIT;
1133 }
1134
1135 /* If this is an EBGP peer with remove-private-AS */
1136 static void
1137 bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1138 struct peer *peer, struct attr *attr)
1139 {
1140 if (peer->sort == BGP_PEER_EBGP &&
1141 (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
1142 peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE) ||
1143 peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) ||
1144 peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)))
1145 {
1146 // Take action on the entire aspath
1147 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
1148 peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
1149 {
1150 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1151 attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
1152
1153 // The entire aspath consists of private ASNs so create an empty aspath
1154 else if (aspath_private_as_check (attr->aspath))
1155 attr->aspath = aspath_empty_get ();
1156
1157 // There are some public and some private ASNs, remove the private ASNs
1158 else
1159 attr->aspath = aspath_remove_private_asns (attr->aspath);
1160 }
1161
1162 // 'all' was not specified so the entire aspath must be private ASNs
1163 // for us to do anything
1164 else if (aspath_private_as_check (attr->aspath))
1165 {
1166 if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1167 attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
1168 else
1169 attr->aspath = aspath_empty_get ();
1170 }
1171 }
1172 }
1173
1174 /* If this is an EBGP peer with as-override */
1175 static void
1176 bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1177 struct peer *peer, struct attr *attr)
1178 {
1179 if (peer->sort == BGP_PEER_EBGP &&
1180 peer_af_flag_check (peer, afi, safi, PEER_FLAG_AS_OVERRIDE))
1181 {
1182 if (aspath_single_asn_check (attr->aspath, peer->as))
1183 attr->aspath = aspath_replace_specific_asn (attr->aspath, peer->as, bgp->as);
1184 }
1185 }
1186
1187 static void
1188 subgroup_announce_reset_nhop (u_char family, struct attr *attr)
1189 {
1190 if (family == AF_INET)
1191 attr->nexthop.s_addr = 0;
1192 if (family == AF_INET6)
1193 memset (&attr->extra->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1194 }
1195
1196 int
1197 subgroup_announce_check (struct bgp_node *rn, struct bgp_info *ri,
1198 struct update_subgroup *subgrp,
1199 struct prefix *p, struct attr *attr)
1200 {
1201 struct bgp_filter *filter;
1202 struct peer *from;
1203 struct peer *peer;
1204 struct peer *onlypeer;
1205 struct bgp *bgp;
1206 struct attr *riattr;
1207 struct peer_af *paf;
1208 char buf[PREFIX_STRLEN];
1209 int ret;
1210 int transparent;
1211 int reflect;
1212 afi_t afi;
1213 safi_t safi;
1214 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1215
1216 if (DISABLE_BGP_ANNOUNCE)
1217 return 0;
1218
1219 afi = SUBGRP_AFI(subgrp);
1220 safi = SUBGRP_SAFI(subgrp);
1221 peer = SUBGRP_PEER(subgrp);
1222 onlypeer = NULL;
1223 if (CHECK_FLAG (peer->flags, PEER_FLAG_LONESOUL))
1224 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1225
1226 from = ri->peer;
1227 filter = &peer->filter[afi][safi];
1228 bgp = SUBGRP_INST(subgrp);
1229 riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
1230
1231 #if ENABLE_BGP_VNC
1232 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN) &&
1233 ((ri->type == ZEBRA_ROUTE_BGP_DIRECT) ||
1234 (ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1235
1236 /*
1237 * direct and direct_ext type routes originate internally even
1238 * though they can have peer pointers that reference other systems
1239 */
1240 prefix2str(p, buf, PREFIX_STRLEN);
1241 zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__, buf);
1242 samepeer_safe = 1;
1243 }
1244 #endif
1245
1246 /* With addpath we may be asked to TX all kinds of paths so make sure
1247 * ri is valid */
1248 if (!CHECK_FLAG (ri->flags, BGP_INFO_VALID) ||
1249 CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) ||
1250 CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
1251 {
1252 return 0;
1253 }
1254
1255 /* If this is not the bestpath then check to see if there is an enabled addpath
1256 * feature that requires us to advertise it */
1257 if (! CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
1258 {
1259 if (! bgp_addpath_tx_path(peer, afi, safi, ri))
1260 {
1261 return 0;
1262 }
1263 }
1264
1265 /* Aggregate-address suppress check. */
1266 if (ri->extra && ri->extra->suppress)
1267 if (! UNSUPPRESS_MAP_NAME (filter))
1268 {
1269 return 0;
1270 }
1271
1272 /* If it's labeled safi, make sure the route has a valid label. */
1273 if (bgp_labeled_safi(safi))
1274 {
1275 u_char *tag = bgp_adv_label(rn, ri, peer, afi, safi);
1276 if (!bgp_is_valid_label(tag))
1277 {
1278 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1279 zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s/%d is filtered - no label (%p)",
1280 subgrp->update_group->id, subgrp->id,
1281 inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
1282 p->prefixlen, tag);
1283 return 0;
1284 }
1285 }
1286
1287 /* Do not send back route to sender. */
1288 if (onlypeer && from == onlypeer)
1289 {
1290 return 0;
1291 }
1292
1293 /* Do not send the default route in the BGP table if the neighbor is
1294 * configured for default-originate */
1295 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE))
1296 {
1297 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1298 return 0;
1299 else if (p->family == AF_INET6 && p->prefixlen == 0)
1300 return 0;
1301 }
1302
1303 /* Transparency check. */
1304 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1305 && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1306 transparent = 1;
1307 else
1308 transparent = 0;
1309
1310 /* If community is not disabled check the no-export and local. */
1311 if (! transparent && bgp_community_filter (peer, riattr))
1312 {
1313 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1314 zlog_debug ("subgrpannouncecheck: community filter check fail");
1315 return 0;
1316 }
1317
1318 /* If the attribute has originator-id and it is same as remote
1319 peer's id. */
1320 if (onlypeer &&
1321 riattr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID) &&
1322 (IPV4_ADDR_SAME (&onlypeer->remote_id, &riattr->extra->originator_id)))
1323 {
1324 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1325 zlog_debug ("%s [Update:SEND] %s originator-id is same as "
1326 "remote router-id",
1327 onlypeer->host, prefix2str (p, buf, sizeof (buf)));
1328 return 0;
1329 }
1330
1331 /* ORF prefix-list filter check */
1332 if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1333 && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1334 || CHECK_FLAG (peer->af_cap[afi][safi],
1335 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1336 if (peer->orf_plist[afi][safi])
1337 {
1338 if (prefix_list_apply (peer->orf_plist[afi][safi], p) == PREFIX_DENY)
1339 {
1340 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1341 zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
1342 peer->host, prefix2str (p, buf, sizeof (buf)));
1343 return 0;
1344 }
1345 }
1346
1347 /* Output filter check. */
1348 if (bgp_output_filter (peer, p, riattr, afi, safi) == FILTER_DENY)
1349 {
1350 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1351 zlog_debug ("%s [Update:SEND] %s is filtered",
1352 peer->host, prefix2str (p, buf, sizeof (buf)));
1353 return 0;
1354 }
1355
1356 #ifdef BGP_SEND_ASPATH_CHECK
1357 /* AS path loop check. */
1358 if (onlypeer && aspath_loop_check (riattr->aspath, onlypeer->as))
1359 {
1360 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1361 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
1362 "that is part of AS path.",
1363 onlypeer->host, onlypeer->as);
1364 return 0;
1365 }
1366 #endif /* BGP_SEND_ASPATH_CHECK */
1367
1368 /* If we're a CONFED we need to loop check the CONFED ID too */
1369 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
1370 {
1371 if (aspath_loop_check(riattr->aspath, bgp->confed_id))
1372 {
1373 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1374 zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
1375 " is AS path.",
1376 peer->host,
1377 bgp->confed_id);
1378 return 0;
1379 }
1380 }
1381
1382 /* Route-Reflect check. */
1383 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1384 reflect = 1;
1385 else
1386 reflect = 0;
1387
1388 /* IBGP reflection check. */
1389 if (reflect && !samepeer_safe)
1390 {
1391 /* A route from a Client peer. */
1392 if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
1393 {
1394 /* Reflect to all the Non-Client peers and also to the
1395 Client peers other than the originator. Originator check
1396 is already done. So there is noting to do. */
1397 /* no bgp client-to-client reflection check. */
1398 if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
1399 if (CHECK_FLAG (peer->af_flags[afi][safi],
1400 PEER_FLAG_REFLECTOR_CLIENT))
1401 return 0;
1402 }
1403 else
1404 {
1405 /* A route from a Non-client peer. Reflect to all other
1406 clients. */
1407 if (! CHECK_FLAG (peer->af_flags[afi][safi],
1408 PEER_FLAG_REFLECTOR_CLIENT))
1409 return 0;
1410 }
1411 }
1412
1413 /* For modify attribute, copy it to temporary structure. */
1414 bgp_attr_dup (attr, riattr);
1415
1416 /* If local-preference is not set. */
1417 if ((peer->sort == BGP_PEER_IBGP
1418 || peer->sort == BGP_PEER_CONFED)
1419 && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
1420 {
1421 attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
1422 attr->local_pref = bgp->default_local_pref;
1423 }
1424
1425 /* If originator-id is not set and the route is to be reflected,
1426 set the originator id */
1427 if (reflect && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))))
1428 {
1429 attr->extra = bgp_attr_extra_get(attr);
1430 IPV4_ADDR_COPY(&(attr->extra->originator_id), &(from->remote_id));
1431 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
1432 }
1433
1434 /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
1435 if (peer->sort == BGP_PEER_EBGP
1436 && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
1437 {
1438 if (from != bgp->peer_self && ! transparent
1439 && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
1440 attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC));
1441 }
1442
1443 /* Since the nexthop attribute can vary per peer, it is not explicitly set
1444 * in announce check, only certain flags and length (or number of nexthops
1445 * -- for IPv6/MP_REACH) are set here in order to guide the update formation
1446 * code in setting the nexthop(s) on a per peer basis in reformat_peer().
1447 * Typically, the source nexthop in the attribute is preserved but in the
1448 * scenarios where we know it will always be overwritten, we reset the
1449 * nexthop to "0" in an attempt to achieve better Update packing. An
1450 * example of this is when a prefix from each of 2 IBGP peers needs to be
1451 * announced to an EBGP peer (and they have the same attributes barring
1452 * their nexthop).
1453 */
1454 if (reflect)
1455 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
1456
1457 #define NEXTHOP_IS_V6 (\
1458 (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
1459 (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
1460 ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
1461 attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
1462
1463 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
1464 * the peer (group) is configured to receive link-local nexthop unchanged
1465 * and it is available in the prefix OR we're not reflecting the route and
1466 * the peer (group) to whom we're going to announce is on a shared network
1467 * and this is either a self-originated route or the peer is EBGP.
1468 */
1469 if (NEXTHOP_IS_V6)
1470 {
1471 attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
1472 if ((CHECK_FLAG (peer->af_flags[afi][safi],
1473 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) &&
1474 IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_local)) ||
1475 (!reflect && peer->shared_network &&
1476 (from == bgp->peer_self || peer->sort == BGP_PEER_EBGP)))
1477 {
1478 attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
1479 }
1480
1481 /* Clear off link-local nexthop in source, whenever it is not needed to
1482 * ensure more prefixes share the same attribute for announcement.
1483 */
1484 if (!(CHECK_FLAG (peer->af_flags[afi][safi],
1485 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
1486 memset (&attr->extra->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
1487 }
1488
1489 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
1490 bgp_peer_as_override(bgp, afi, safi, peer, attr);
1491
1492 /* Route map & unsuppress-map apply. */
1493 if (ROUTE_MAP_OUT_NAME (filter)
1494 || (ri->extra && ri->extra->suppress) )
1495 {
1496 struct bgp_info info;
1497 struct attr dummy_attr;
1498 struct attr_extra dummy_extra;
1499
1500 dummy_attr.extra = &dummy_extra;
1501
1502 info.peer = peer;
1503 info.attr = attr;
1504 /* don't confuse inbound and outbound setting */
1505 RESET_FLAG(attr->rmap_change_flags);
1506
1507 /*
1508 * The route reflector is not allowed to modify the attributes
1509 * of the reflected IBGP routes unless explicitly allowed.
1510 */
1511 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1512 && !bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY))
1513 {
1514 bgp_attr_dup (&dummy_attr, attr);
1515 info.attr = &dummy_attr;
1516 }
1517
1518 SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
1519
1520 if (ri->extra && ri->extra->suppress)
1521 ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
1522 else
1523 ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
1524
1525 peer->rmap_type = 0;
1526
1527 if (ret == RMAP_DENYMATCH)
1528 {
1529 bgp_attr_flush (attr);
1530 return 0;
1531 }
1532 }
1533
1534 /* After route-map has been applied, we check to see if the nexthop to
1535 * be carried in the attribute (that is used for the announcement) can
1536 * be cleared off or not. We do this in all cases where we would be
1537 * setting the nexthop to "ourselves". For IPv6, we only need to consider
1538 * the global nexthop here; the link-local nexthop would have been cleared
1539 * already, and if not, it is required by the update formation code.
1540 * Also see earlier comments in this function.
1541 */
1542 /*
1543 * If route-map has performed some operation on the nexthop or the peer
1544 * configuration says to pass it unchanged, we cannot reset the nexthop
1545 * here, so only attempt to do it if these aren't true. Note that the
1546 * route-map handler itself might have cleared the nexthop, if for example,
1547 * it is configured as 'peer-address'.
1548 */
1549 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
1550 riattr->rmap_change_flags) &&
1551 !transparent &&
1552 !CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
1553 {
1554 /* We can reset the nexthop, if setting (or forcing) it to 'self' */
1555 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) ||
1556 CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF))
1557 {
1558 if (!reflect ||
1559 CHECK_FLAG (peer->af_flags[afi][safi],
1560 PEER_FLAG_FORCE_NEXTHOP_SELF))
1561 subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ?
1562 AF_INET6 : p->family), attr);
1563 }
1564 else if (peer->sort == BGP_PEER_EBGP)
1565 {
1566 /* Can also reset the nexthop if announcing to EBGP, but only if
1567 * no peer in the subgroup is on a shared subnet.
1568 * Note: 3rd party nexthop currently implemented for IPv4 only.
1569 */
1570 SUBGRP_FOREACH_PEER (subgrp, paf)
1571 {
1572 if (bgp_multiaccess_check_v4 (riattr->nexthop, paf->peer))
1573 break;
1574 }
1575 if (!paf)
1576 subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ? AF_INET6 : p->family), attr);
1577 }
1578 /* If IPv6/MP and nexthop does not have any override and happens to
1579 * be a link-local address, reset it so that we don't pass along the
1580 * source's link-local IPv6 address to recipients who may not be on
1581 * the same interface.
1582 */
1583 if (p->family == AF_INET6 || peer_cap_enhe(peer))
1584 {
1585 if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
1586 subgroup_announce_reset_nhop (AF_INET6, attr);
1587 }
1588 }
1589
1590 return 1;
1591 }
1592
1593 struct bgp_info_pair
1594 {
1595 struct bgp_info *old;
1596 struct bgp_info *new;
1597 };
1598
1599 static void
1600 bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
1601 struct bgp_maxpaths_cfg *mpath_cfg,
1602 struct bgp_info_pair *result)
1603 {
1604 struct bgp_info *new_select;
1605 struct bgp_info *old_select;
1606 struct bgp_info *ri;
1607 struct bgp_info *ri1;
1608 struct bgp_info *ri2;
1609 struct bgp_info *nextri = NULL;
1610 int paths_eq, do_mpath, debug;
1611 struct list mp_list;
1612 char pfx_buf[PREFIX2STR_BUFFER];
1613 char path_buf[PATH_ADDPATH_STR_BUFFER];
1614
1615 bgp_mp_list_init (&mp_list);
1616 do_mpath = (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
1617
1618 debug = bgp_debug_bestpath(&rn->p);
1619
1620 if (debug)
1621 prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf));
1622
1623 /* bgp deterministic-med */
1624 new_select = NULL;
1625 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
1626 {
1627
1628 /* Clear BGP_INFO_DMED_SELECTED for all paths */
1629 for (ri1 = rn->info; ri1; ri1 = ri1->next)
1630 bgp_info_unset_flag (rn, ri1, BGP_INFO_DMED_SELECTED);
1631
1632 for (ri1 = rn->info; ri1; ri1 = ri1->next)
1633 {
1634 if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
1635 continue;
1636 if (BGP_INFO_HOLDDOWN (ri1))
1637 continue;
1638 if (ri1->peer && ri1->peer != bgp->peer_self)
1639 if (ri1->peer->status != Established)
1640 continue;
1641
1642 new_select = ri1;
1643 if (ri1->next)
1644 {
1645 for (ri2 = ri1->next; ri2; ri2 = ri2->next)
1646 {
1647 if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
1648 continue;
1649 if (BGP_INFO_HOLDDOWN (ri2))
1650 continue;
1651 if (ri2->peer &&
1652 ri2->peer != bgp->peer_self &&
1653 !CHECK_FLAG (ri2->peer->sflags, PEER_STATUS_NSF_WAIT))
1654 if (ri2->peer->status != Established)
1655 continue;
1656
1657 if (aspath_cmp_left (ri1->attr->aspath, ri2->attr->aspath)
1658 || aspath_cmp_left_confed (ri1->attr->aspath,
1659 ri2->attr->aspath))
1660 {
1661 if (bgp_info_cmp (bgp, ri2, new_select, &paths_eq,
1662 mpath_cfg, debug, pfx_buf))
1663 {
1664 bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
1665 new_select = ri2;
1666 }
1667
1668 bgp_info_set_flag (rn, ri2, BGP_INFO_DMED_CHECK);
1669 }
1670 }
1671 }
1672 bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_CHECK);
1673 bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
1674
1675 if (debug)
1676 {
1677 bgp_info_path_with_addpath_rx_str (new_select, path_buf);
1678 zlog_debug("%s: %s is the bestpath from AS %d",
1679 pfx_buf, path_buf, aspath_get_first_as(new_select->attr->aspath));
1680 }
1681 }
1682 }
1683
1684 /* Check old selected route and new selected route. */
1685 old_select = NULL;
1686 new_select = NULL;
1687 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
1688 {
1689 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
1690 old_select = ri;
1691
1692 if (BGP_INFO_HOLDDOWN (ri))
1693 {
1694 /* reap REMOVED routes, if needs be
1695 * selected route must stay for a while longer though
1696 */
1697 if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
1698 && (ri != old_select))
1699 bgp_info_reap (rn, ri);
1700
1701 continue;
1702 }
1703
1704 if (ri->peer &&
1705 ri->peer != bgp->peer_self &&
1706 !CHECK_FLAG (ri->peer->sflags, PEER_STATUS_NSF_WAIT))
1707 if (ri->peer->status != Established)
1708 continue;
1709
1710 if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)
1711 && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED)))
1712 {
1713 bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
1714 continue;
1715 }
1716
1717 bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
1718
1719 if (bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf))
1720 {
1721 new_select = ri;
1722 }
1723 }
1724
1725 /* Now that we know which path is the bestpath see if any of the other paths
1726 * qualify as multipaths
1727 */
1728 if (debug)
1729 {
1730 if (new_select)
1731 bgp_info_path_with_addpath_rx_str (new_select, path_buf);
1732 else
1733 sprintf (path_buf, "NONE");
1734 zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
1735 pfx_buf, path_buf,
1736 old_select ? old_select->peer->host : "NONE");
1737 }
1738
1739 if (do_mpath && new_select)
1740 {
1741 for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
1742 {
1743
1744 if (debug)
1745 bgp_info_path_with_addpath_rx_str (ri, path_buf);
1746
1747 if (ri == new_select)
1748 {
1749 if (debug)
1750 zlog_debug("%s: %s is the bestpath, add to the multipath list",
1751 pfx_buf, path_buf);
1752 bgp_mp_list_add (&mp_list, ri);
1753 continue;
1754 }
1755
1756 if (BGP_INFO_HOLDDOWN (ri))
1757 continue;
1758
1759 if (ri->peer &&
1760 ri->peer != bgp->peer_self &&
1761 !CHECK_FLAG (ri->peer->sflags, PEER_STATUS_NSF_WAIT))
1762 if (ri->peer->status != Established)
1763 continue;
1764
1765 if (!bgp_info_nexthop_cmp (ri, new_select))
1766 {
1767 if (debug)
1768 zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
1769 pfx_buf, path_buf);
1770 continue;
1771 }
1772
1773 bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf);
1774
1775 if (paths_eq)
1776 {
1777 if (debug)
1778 zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
1779 pfx_buf, path_buf);
1780 bgp_mp_list_add (&mp_list, ri);
1781 }
1782 }
1783 }
1784
1785 bgp_info_mpath_update (rn, new_select, old_select, &mp_list, mpath_cfg);
1786 bgp_info_mpath_aggregate_update (new_select, old_select);
1787 bgp_mp_list_clear (&mp_list);
1788
1789 result->old = old_select;
1790 result->new = new_select;
1791
1792 return;
1793 }
1794
1795 /*
1796 * A new route/change in bestpath of an existing route. Evaluate the path
1797 * for advertisement to the subgroup.
1798 */
1799 int
1800 subgroup_process_announce_selected (struct update_subgroup *subgrp,
1801 struct bgp_info *selected,
1802 struct bgp_node *rn,
1803 u_int32_t addpath_tx_id)
1804 {
1805 struct prefix *p;
1806 struct peer *onlypeer;
1807 struct attr attr;
1808 struct attr_extra extra;
1809 afi_t afi;
1810 safi_t safi;
1811
1812 p = &rn->p;
1813 afi = SUBGRP_AFI(subgrp);
1814 safi = SUBGRP_SAFI(subgrp);
1815 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ?
1816 (SUBGRP_PFIRST(subgrp))->peer : NULL);
1817
1818 /* First update is deferred until ORF or ROUTE-REFRESH is received */
1819 if (onlypeer && CHECK_FLAG (onlypeer->af_sflags[afi][safi],
1820 PEER_STATUS_ORF_WAIT_REFRESH))
1821 return 0;
1822
1823 memset(&extra, 0, sizeof(struct attr_extra));
1824 /* It's initialized in bgp_announce_check() */
1825 attr.extra = &extra;
1826
1827 /* Announcement to the subgroup. If the route is filtered withdraw it. */
1828 if (selected)
1829 {
1830 if (subgroup_announce_check(rn, selected, subgrp, p, &attr))
1831 bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
1832 else
1833 bgp_adj_out_unset_subgroup(rn, subgrp, 1, selected->addpath_tx_id);
1834 }
1835
1836 /* If selected is NULL we must withdraw the path using addpath_tx_id */
1837 else
1838 {
1839 bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
1840 }
1841
1842 return 0;
1843 }
1844
1845 /*
1846 * Clear IGP changed flag and attribute changed flag for a route (all paths).
1847 * This is called at the end of route processing.
1848 */
1849 static void
1850 bgp_zebra_clear_route_change_flags (struct bgp_node *rn)
1851 {
1852 struct bgp_info *ri;
1853
1854 for (ri = rn->info; ri; ri = ri->next)
1855 {
1856 if (BGP_INFO_HOLDDOWN (ri))
1857 continue;
1858 UNSET_FLAG (ri->flags, BGP_INFO_IGP_CHANGED);
1859 UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
1860 }
1861 }
1862
1863 /*
1864 * Has the route changed from the RIB's perspective? This is invoked only
1865 * if the route selection returns the same best route as earlier - to
1866 * determine if we need to update zebra or not.
1867 */
1868 static int
1869 bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected)
1870 {
1871 struct bgp_info *mpinfo;
1872
1873 /* If this is multipath, check all selected paths for any nexthop change or
1874 * attribute change. Some attribute changes (e.g., community) aren't of
1875 * relevance to the RIB, but we'll update zebra to ensure we handle the
1876 * case of BGP nexthop change. This is the behavior when the best path has
1877 * an attribute change anyway.
1878 */
1879 if (CHECK_FLAG (selected->flags, BGP_INFO_IGP_CHANGED) ||
1880 CHECK_FLAG (selected->flags, BGP_INFO_MULTIPATH_CHG))
1881 return 1;
1882
1883 /* If this is multipath, check all selected paths for any nexthop change */
1884 for (mpinfo = bgp_info_mpath_first (selected); mpinfo;
1885 mpinfo = bgp_info_mpath_next (mpinfo))
1886 {
1887 if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED)
1888 || CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
1889 return 1;
1890 }
1891
1892 /* Nothing has changed from the RIB's perspective. */
1893 return 0;
1894 }
1895
1896 struct bgp_process_queue
1897 {
1898 struct bgp *bgp;
1899 struct bgp_node *rn;
1900 afi_t afi;
1901 safi_t safi;
1902 };
1903
1904 static wq_item_status
1905 bgp_process_main (struct work_queue *wq, void *data)
1906 {
1907 struct bgp_process_queue *pq = data;
1908 struct bgp *bgp = pq->bgp;
1909 struct bgp_node *rn = pq->rn;
1910 afi_t afi = pq->afi;
1911 safi_t safi = pq->safi;
1912 struct prefix *p = &rn->p;
1913 struct bgp_info *new_select;
1914 struct bgp_info *old_select;
1915 struct bgp_info_pair old_and_new;
1916
1917 /* Is it end of initial update? (after startup) */
1918 if (!rn)
1919 {
1920 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
1921 sizeof(bgp->update_delay_zebra_resume_time));
1922
1923 bgp->main_zebra_update_hold = 0;
1924 for (afi = AFI_IP; afi < AFI_MAX; afi++)
1925 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
1926 {
1927 bgp_zebra_announce_table(bgp, afi, safi);
1928 }
1929 bgp->main_peers_update_hold = 0;
1930
1931 bgp_start_routeadv(bgp);
1932 return WQ_SUCCESS;
1933 }
1934
1935 /* Best path selection. */
1936 bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
1937 old_select = old_and_new.old;
1938 new_select = old_and_new.new;
1939
1940 /* Do we need to allocate or free labels?
1941 * Right now, since we only deal with per-prefix labels, it is not necessary
1942 * to do this upon changes to best path except of the label index changes.
1943 */
1944 bgp_table_lock (bgp_node_table (rn));
1945 if (bgp_labeled_safi (safi))
1946 {
1947 if (new_select)
1948 {
1949 if (!old_select ||
1950 bgp_label_index_differs (new_select, old_select) ||
1951 new_select->sub_type != old_select->sub_type)
1952 {
1953 if (new_select->sub_type == BGP_ROUTE_STATIC &&
1954 new_select->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID) &&
1955 new_select->attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
1956 {
1957 if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
1958 bgp_unregister_for_label (rn);
1959 label_ntop (MPLS_IMP_NULL_LABEL, 1, rn->local_label);
1960 bgp_set_valid_label(rn->local_label);
1961 }
1962 else
1963 bgp_register_for_label (rn, new_select);
1964 }
1965 }
1966 else if (CHECK_FLAG (rn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
1967 bgp_unregister_for_label (rn);
1968 }
1969
1970 /* If best route remains the same and this is not due to user-initiated
1971 * clear, see exactly what needs to be done.
1972 */
1973
1974 if (old_select && old_select == new_select &&
1975 !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) &&
1976 !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
1977 !bgp->addpath_tx_used[afi][safi])
1978 {
1979 if (bgp_zebra_has_route_changed (rn, old_select))
1980 {
1981 #if ENABLE_BGP_VNC
1982 vnc_import_bgp_add_route(bgp, p, old_select);
1983 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
1984 #endif
1985 if (bgp_fibupd_safi(safi) &&
1986 !bgp->name &&
1987 !bgp_option_check (BGP_OPT_NO_FIB) &&
1988 new_select->type == ZEBRA_ROUTE_BGP &&
1989 new_select->sub_type == BGP_ROUTE_NORMAL)
1990 bgp_zebra_announce (rn, p, old_select, bgp, afi, safi);
1991 }
1992 UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
1993 bgp_zebra_clear_route_change_flags (rn);
1994
1995 /* If there is a change of interest to peers, reannounce the route. */
1996 if (CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED) ||
1997 CHECK_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED))
1998 {
1999 group_announce_route(bgp, afi, safi, rn, new_select);
2000
2001 UNSET_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED);
2002 UNSET_FLAG (rn->flags, BGP_NODE_LABEL_CHANGED);
2003 }
2004
2005 UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2006 return WQ_SUCCESS;
2007 }
2008
2009 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
2010 UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
2011
2012 /* bestpath has changed; bump version */
2013 if (old_select || new_select)
2014 {
2015 bgp_bump_version(rn);
2016
2017 if (!bgp->t_rmap_def_originate_eval)
2018 {
2019 bgp_lock (bgp);
2020 THREAD_TIMER_ON(bm->master, bgp->t_rmap_def_originate_eval,
2021 update_group_refresh_default_originate_route_map,
2022 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
2023 }
2024 }
2025
2026 if (old_select)
2027 bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
2028 if (new_select)
2029 {
2030 bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
2031 bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
2032 UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
2033 }
2034
2035 #if ENABLE_BGP_VNC
2036 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2037 if (old_select != new_select) {
2038 if (old_select) {
2039 vnc_import_bgp_exterior_del_route(bgp, p, old_select);
2040 vnc_import_bgp_del_route(bgp, p, old_select);
2041 }
2042 if (new_select) {
2043 vnc_import_bgp_exterior_add_route(bgp, p, new_select);
2044 vnc_import_bgp_add_route(bgp, p, new_select);
2045 }
2046 }
2047 }
2048 #endif
2049
2050 group_announce_route(bgp, afi, safi, rn, new_select);
2051
2052 /* FIB update. */
2053 if (bgp_fibupd_safi(safi) &&
2054 (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
2055 !bgp_option_check (BGP_OPT_NO_FIB))
2056 {
2057 if (new_select
2058 && new_select->type == ZEBRA_ROUTE_BGP
2059 && (new_select->sub_type == BGP_ROUTE_NORMAL ||
2060 new_select->sub_type == BGP_ROUTE_AGGREGATE))
2061 bgp_zebra_announce (rn, p, new_select, bgp, afi, safi);
2062 else
2063 {
2064 /* Withdraw the route from the kernel. */
2065 if (old_select
2066 && old_select->type == ZEBRA_ROUTE_BGP
2067 && (old_select->sub_type == BGP_ROUTE_NORMAL ||
2068 old_select->sub_type == BGP_ROUTE_AGGREGATE))
2069 bgp_zebra_withdraw (p, old_select, safi);
2070 }
2071 }
2072
2073 /* Clear any route change flags. */
2074 bgp_zebra_clear_route_change_flags (rn);
2075
2076 /* Reap old select bgp_info, if it has been removed */
2077 if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
2078 bgp_info_reap (rn, old_select);
2079
2080 UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2081 return WQ_SUCCESS;
2082 }
2083
2084 static void
2085 bgp_processq_del (struct work_queue *wq, void *data)
2086 {
2087 struct bgp_process_queue *pq = data;
2088 struct bgp_table *table;
2089
2090 bgp_unlock (pq->bgp);
2091 if (pq->rn)
2092 {
2093 table = bgp_node_table (pq->rn);
2094 bgp_unlock_node (pq->rn);
2095 bgp_table_unlock (table);
2096 }
2097 XFREE (MTYPE_BGP_PROCESS_QUEUE, pq);
2098 }
2099
2100 void
2101 bgp_process_queue_init (void)
2102 {
2103 if (!bm->process_main_queue)
2104 {
2105 bm->process_main_queue
2106 = work_queue_new (bm->master, "process_main_queue");
2107
2108 if ( !bm->process_main_queue)
2109 {
2110 zlog_err ("%s: Failed to allocate work queue", __func__);
2111 exit (1);
2112 }
2113 }
2114
2115 bm->process_main_queue->spec.workfunc = &bgp_process_main;
2116 bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
2117 bm->process_main_queue->spec.max_retries = 0;
2118 bm->process_main_queue->spec.hold = 50;
2119 /* Use a higher yield value of 50ms for main queue processing */
2120 bm->process_main_queue->spec.yield = 50 * 1000L;
2121 }
2122
2123 void
2124 bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
2125 {
2126 struct bgp_process_queue *pqnode;
2127
2128 /* already scheduled for processing? */
2129 if (CHECK_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED))
2130 return;
2131
2132 if (bm->process_main_queue == NULL)
2133 return;
2134
2135 pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
2136 sizeof (struct bgp_process_queue));
2137 if (!pqnode)
2138 return;
2139
2140 /* all unlocked in bgp_processq_del */
2141 bgp_table_lock (bgp_node_table (rn));
2142 pqnode->rn = bgp_lock_node (rn);
2143 pqnode->bgp = bgp;
2144 bgp_lock (bgp);
2145 pqnode->afi = afi;
2146 pqnode->safi = safi;
2147 work_queue_add (bm->process_main_queue, pqnode);
2148 SET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
2149 return;
2150 }
2151
2152 void
2153 bgp_add_eoiu_mark (struct bgp *bgp)
2154 {
2155 struct bgp_process_queue *pqnode;
2156
2157 if (bm->process_main_queue == NULL)
2158 return;
2159
2160 pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
2161 sizeof (struct bgp_process_queue));
2162 if (!pqnode)
2163 return;
2164
2165 pqnode->rn = NULL;
2166 pqnode->bgp = bgp;
2167 bgp_lock (bgp);
2168 work_queue_add (bm->process_main_queue, pqnode);
2169 }
2170
2171 static int
2172 bgp_maximum_prefix_restart_timer (struct thread *thread)
2173 {
2174 struct peer *peer;
2175
2176 peer = THREAD_ARG (thread);
2177 peer->t_pmax_restart = NULL;
2178
2179 if (bgp_debug_neighbor_events(peer))
2180 zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
2181 peer->host);
2182
2183 peer_clear (peer, NULL);
2184
2185 return 0;
2186 }
2187
2188 int
2189 bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
2190 safi_t safi, int always)
2191 {
2192 iana_afi_t pkt_afi;
2193 safi_t pkt_safi;
2194
2195 if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
2196 return 0;
2197
2198 if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
2199 {
2200 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT)
2201 && ! always)
2202 return 0;
2203
2204 zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
2205 "limit %ld", afi_safi_print (afi, safi), peer->host,
2206 peer->pcount[afi][safi], peer->pmax[afi][safi]);
2207 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2208
2209 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
2210 return 0;
2211
2212 /* Convert AFI, SAFI to values for packet. */
2213 pkt_afi = afi_int2iana (afi);
2214 pkt_safi = safi_int2iana (safi);
2215 {
2216 u_int8_t ndata[7];
2217
2218 ndata[0] = (pkt_afi >> 8);
2219 ndata[1] = pkt_afi;
2220 ndata[2] = pkt_safi;
2221 ndata[3] = (peer->pmax[afi][safi] >> 24);
2222 ndata[4] = (peer->pmax[afi][safi] >> 16);
2223 ndata[5] = (peer->pmax[afi][safi] >> 8);
2224 ndata[6] = (peer->pmax[afi][safi]);
2225
2226 SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
2227 bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
2228 BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
2229 }
2230
2231 /* Dynamic peers will just close their connection. */
2232 if (peer_dynamic_neighbor (peer))
2233 return 1;
2234
2235 /* restart timer start */
2236 if (peer->pmax_restart[afi][safi])
2237 {
2238 peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
2239
2240 if (bgp_debug_neighbor_events(peer))
2241 zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
2242 peer->host, peer->v_pmax_restart);
2243
2244 BGP_TIMER_ON (peer->t_pmax_restart, bgp_maximum_prefix_restart_timer,
2245 peer->v_pmax_restart);
2246 }
2247
2248 return 1;
2249 }
2250 else
2251 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
2252
2253 if (peer->pcount[afi][safi] > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100))
2254 {
2255 if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD)
2256 && ! always)
2257 return 0;
2258
2259 zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
2260 afi_safi_print (afi, safi), peer->host, peer->pcount[afi][safi],
2261 peer->pmax[afi][safi]);
2262 SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
2263 }
2264 else
2265 UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
2266 return 0;
2267 }
2268
2269 /* Unconditionally remove the route from the RIB, without taking
2270 * damping into consideration (eg, because the session went down)
2271 */
2272 static void
2273 bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
2274 afi_t afi, safi_t safi)
2275 {
2276 bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
2277
2278 if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
2279 bgp_info_delete (rn, ri); /* keep historical info */
2280
2281 bgp_process (peer->bgp, rn, afi, safi);
2282 }
2283
2284 static void
2285 bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
2286 afi_t afi, safi_t safi, struct prefix_rd *prd)
2287 {
2288 int status = BGP_DAMP_NONE;
2289
2290 /* apply dampening, if result is suppressed, we'll be retaining
2291 * the bgp_info in the RIB for historical reference.
2292 */
2293 if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2294 && peer->sort == BGP_PEER_EBGP)
2295 if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0))
2296 == BGP_DAMP_SUPPRESSED)
2297 {
2298 bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
2299 return;
2300 }
2301
2302 #if ENABLE_BGP_VNC
2303 if (safi == SAFI_MPLS_VPN) {
2304 struct bgp_node *prn = NULL;
2305 struct bgp_table *table = NULL;
2306
2307 prn = bgp_node_get(peer->bgp->rib[afi][safi], (struct prefix *) prd);
2308 if (prn->info) {
2309 table = (struct bgp_table *)(prn->info);
2310
2311 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2312 peer->bgp,
2313 prd,
2314 table,
2315 &rn->p,
2316 ri);
2317 }
2318 bgp_unlock_node(prn);
2319 }
2320 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2321 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
2322
2323 vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
2324 vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p, ri);
2325 }
2326 }
2327 #endif
2328 bgp_rib_remove (rn, ri, peer, afi, safi);
2329 }
2330
2331 static struct bgp_info *
2332 info_make (int type, int sub_type, u_short instance, struct peer *peer, struct attr *attr,
2333 struct bgp_node *rn)
2334 {
2335 struct bgp_info *new;
2336
2337 /* Make new BGP info. */
2338 new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
2339 new->type = type;
2340 new->instance = instance;
2341 new->sub_type = sub_type;
2342 new->peer = peer;
2343 new->attr = attr;
2344 new->uptime = bgp_clock ();
2345 new->net = rn;
2346 new->addpath_tx_id = ++peer->bgp->addpath_tx_id;
2347 return new;
2348 }
2349
2350 static void
2351 overlay_index_update(struct attr *attr, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
2352 {
2353 struct attr_extra *extra;
2354
2355 if(!attr)
2356 return;
2357 extra = bgp_attr_extra_get(attr);
2358
2359 if(eth_s_id == NULL)
2360 {
2361 memset(&(extra->evpn_overlay.eth_s_id),0, sizeof(struct eth_segment_id));
2362 }
2363 else
2364 {
2365 memcpy(&(extra->evpn_overlay.eth_s_id), eth_s_id, sizeof(struct eth_segment_id));
2366 }
2367 if(gw_ip == NULL)
2368 {
2369 memset(&(extra->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
2370 }
2371 else
2372 {
2373 memcpy(&(extra->evpn_overlay.gw_ip),gw_ip, sizeof(union gw_addr));
2374 }
2375 }
2376
2377 static bool
2378 overlay_index_equal(afi_t afi, struct bgp_info *info, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
2379 {
2380 struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
2381 union gw_addr *info_gw_ip, *info_gw_ip_remote;
2382 char temp[16];
2383
2384 if(afi != AFI_L2VPN)
2385 return true;
2386 if (!info->attr || !info->attr->extra)
2387 {
2388 memset(&temp, 0, 16);
2389 info_eth_s_id = (struct eth_segment_id *)&temp;
2390 info_gw_ip = (union gw_addr *)&temp;
2391 if(eth_s_id == NULL && gw_ip == NULL)
2392 return true;
2393 }
2394 else
2395 {
2396 info_eth_s_id = &(info->attr->extra->evpn_overlay.eth_s_id);
2397 info_gw_ip = &(info->attr->extra->evpn_overlay.gw_ip);
2398 }
2399 if(gw_ip == NULL)
2400 info_gw_ip_remote = (union gw_addr *)&temp;
2401 else
2402 info_gw_ip_remote = gw_ip;
2403 if(eth_s_id == NULL)
2404 info_eth_s_id_remote = (struct eth_segment_id *)&temp;
2405 else
2406 info_eth_s_id_remote = eth_s_id;
2407 if(!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
2408 return false;
2409 return !memcmp(info_eth_s_id, info_eth_s_id_remote, sizeof(struct eth_segment_id));
2410 }
2411
2412 /* Check if received nexthop is valid or not. */
2413 static int
2414 bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr *attr)
2415 {
2416 struct attr_extra *attre = attr->extra;
2417 int ret = 0;
2418
2419 /* Only validated for unicast and multicast currently. */
2420 if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST)
2421 return 0;
2422
2423 /* If NEXT_HOP is present, validate it. */
2424 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
2425 {
2426 if (attr->nexthop.s_addr == 0 ||
2427 IPV4_CLASS_DE (ntohl (attr->nexthop.s_addr)) ||
2428 bgp_nexthop_self (bgp, attr))
2429 ret = 1;
2430 }
2431
2432 /* If MP_NEXTHOP is present, validate it. */
2433 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
2434 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
2435 * it is not an IPv6 link-local address.
2436 */
2437 if (attre && attre->mp_nexthop_len)
2438 {
2439 switch (attre->mp_nexthop_len)
2440 {
2441 case BGP_ATTR_NHLEN_IPV4:
2442 case BGP_ATTR_NHLEN_VPNV4:
2443 ret = (attre->mp_nexthop_global_in.s_addr == 0 ||
2444 IPV4_CLASS_DE (ntohl (attre->mp_nexthop_global_in.s_addr)));
2445 break;
2446
2447 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
2448 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
2449 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
2450 ret = (IN6_IS_ADDR_UNSPECIFIED(&attre->mp_nexthop_global) ||
2451 IN6_IS_ADDR_LOOPBACK(&attre->mp_nexthop_global) ||
2452 IN6_IS_ADDR_MULTICAST(&attre->mp_nexthop_global));
2453 break;
2454
2455 default:
2456 ret = 1;
2457 break;
2458 }
2459 }
2460
2461 return ret;
2462 }
2463
2464 int
2465 bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
2466 struct attr *attr, afi_t afi, safi_t safi, int type,
2467 int sub_type, struct prefix_rd *prd, u_char *tag,
2468 int soft_reconfig, struct bgp_route_evpn* evpn)
2469 {
2470 int ret;
2471 int aspath_loop_count = 0;
2472 struct bgp_node *rn;
2473 struct bgp *bgp;
2474 struct attr new_attr;
2475 struct attr_extra new_extra;
2476 struct attr *attr_new;
2477 struct bgp_info *ri;
2478 struct bgp_info *new;
2479 const char *reason;
2480 char pfx_buf[BGP_PRD_PATH_STRLEN];
2481 char label_buf[20];
2482 int connected = 0;
2483 int do_loop_check = 1;
2484 #if ENABLE_BGP_VNC
2485 int vnc_implicit_withdraw = 0;
2486 #endif
2487
2488 memset (&new_attr, 0, sizeof(struct attr));
2489 memset (&new_extra, 0, sizeof(struct attr_extra));
2490
2491 bgp = peer->bgp;
2492 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
2493 label_buf[0] = '\0';
2494 if (bgp_labeled_safi(safi))
2495 sprintf (label_buf, "label %u", label_pton(tag));
2496
2497 /* When peer's soft reconfiguration enabled. Record input packet in
2498 Adj-RIBs-In. */
2499 if (! soft_reconfig && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
2500 && peer != bgp->peer_self)
2501 bgp_adj_in_set (rn, peer, attr, addpath_id);
2502
2503 /* Check previously received route. */
2504 for (ri = rn->info; ri; ri = ri->next)
2505 if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
2506 ri->addpath_rx_id == addpath_id)
2507 break;
2508
2509 /* AS path local-as loop check. */
2510 if (peer->change_local_as)
2511 {
2512 if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
2513 aspath_loop_count = 1;
2514
2515 if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count)
2516 {
2517 reason = "as-path contains our own AS;";
2518 goto filtered;
2519 }
2520 }
2521
2522 /* If the peer is configured for "allowas-in origin" and the last ASN in the
2523 * as-path is our ASN then we do not need to call aspath_loop_check
2524 */
2525 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
2526 if (aspath_get_last_as(attr->aspath) == bgp->as)
2527 do_loop_check = 0;
2528
2529 /* AS path loop check. */
2530 if (do_loop_check)
2531 {
2532 if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
2533 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
2534 && aspath_loop_check(attr->aspath, bgp->confed_id) > peer->allowas_in[afi][safi]))
2535 {
2536 reason = "as-path contains our own AS;";
2537 goto filtered;
2538 }
2539 }
2540
2541 /* Route reflector originator ID check. */
2542 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
2543 && IPV4_ADDR_SAME (&bgp->router_id, &attr->extra->originator_id))
2544 {
2545 reason = "originator is us;";
2546 goto filtered;
2547 }
2548
2549 /* Route reflector cluster ID check. */
2550 if (bgp_cluster_filter (peer, attr))
2551 {
2552 reason = "reflected from the same cluster;";
2553 goto filtered;
2554 }
2555
2556 /* Apply incoming filter. */
2557 if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)
2558 {
2559 reason = "filter;";
2560 goto filtered;
2561 }
2562
2563 new_attr.extra = &new_extra;
2564 bgp_attr_dup (&new_attr, attr);
2565
2566 /* Apply incoming route-map.
2567 * NB: new_attr may now contain newly allocated values from route-map "set"
2568 * commands, so we need bgp_attr_flush in the error paths, until we intern
2569 * the attr (which takes over the memory references) */
2570 if (bgp_input_modifier (peer, p, &new_attr, afi, safi, NULL) == RMAP_DENY)
2571 {
2572 reason = "route-map;";
2573 bgp_attr_flush (&new_attr);
2574 goto filtered;
2575 }
2576
2577 /* next hop check. */
2578 if (bgp_update_martian_nexthop (bgp, afi, safi, &new_attr))
2579 {
2580 reason = "martian or self next-hop;";
2581 bgp_attr_flush (&new_attr);
2582 goto filtered;
2583 }
2584
2585 attr_new = bgp_attr_intern (&new_attr);
2586
2587 /* If the update is implicit withdraw. */
2588 if (ri)
2589 {
2590 ri->uptime = bgp_clock ();
2591
2592 /* Same attribute comes in. */
2593 if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
2594 && attrhash_cmp (ri->attr, attr_new)
2595 && (!bgp_labeled_safi(safi) ||
2596 memcmp ((bgp_info_extra_get (ri))->tag, tag, 3) == 0)
2597 && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
2598 evpn==NULL?NULL:&evpn->gw_ip)))
2599 {
2600 if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2601 && peer->sort == BGP_PEER_EBGP
2602 && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
2603 {
2604 if (bgp_debug_update(peer, p, NULL, 1))
2605 zlog_debug ("%s rcvd %s %s", peer->host,
2606 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
2607 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
2608
2609 if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
2610 {
2611 bgp_aggregate_increment (bgp, p, ri, afi, safi);
2612 bgp_process (bgp, rn, afi, safi);
2613 }
2614 }
2615 else /* Duplicate - odd */
2616 {
2617 if (bgp_debug_update(peer, p, NULL, 1))
2618 {
2619 if (!peer->rcvd_attr_printed)
2620 {
2621 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
2622 peer->rcvd_attr_printed = 1;
2623 }
2624
2625 zlog_debug ("%s rcvd %s %s...duplicate ignored",
2626 peer->host,
2627 bgp_debug_rdpfxpath2str (prd, p, addpath_id ?
2628 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
2629 }
2630
2631 /* graceful restart STALE flag unset. */
2632 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
2633 {
2634 bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
2635 bgp_process (bgp, rn, afi, safi);
2636 }
2637 }
2638
2639 bgp_unlock_node (rn);
2640 bgp_attr_unintern (&attr_new);
2641
2642 return 0;
2643 }
2644
2645 /* Withdraw/Announce before we fully processed the withdraw */
2646 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
2647 {
2648 if (bgp_debug_update(peer, p, NULL, 1))
2649 zlog_debug ("%s rcvd %s %s, flapped quicker than processing",
2650 peer->host,
2651 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
2652 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
2653 bgp_info_restore (rn, ri);
2654 }
2655
2656 /* Received Logging. */
2657 if (bgp_debug_update(peer, p, NULL, 1))
2658 zlog_debug ("%s rcvd %s %s", peer->host,
2659 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
2660 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
2661
2662 /* graceful restart STALE flag unset. */
2663 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
2664 bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
2665
2666 /* The attribute is changed. */
2667 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
2668
2669 /* implicit withdraw, decrement aggregate and pcount here.
2670 * only if update is accepted, they'll increment below.
2671 */
2672 bgp_aggregate_decrement (bgp, p, ri, afi, safi);
2673
2674 /* Update bgp route dampening information. */
2675 if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2676 && peer->sort == BGP_PEER_EBGP)
2677 {
2678 /* This is implicit withdraw so we should update dampening
2679 information. */
2680 if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
2681 bgp_damp_withdraw (ri, rn, afi, safi, 1);
2682 }
2683 #if ENABLE_BGP_VNC
2684 if (safi == SAFI_MPLS_VPN) {
2685 struct bgp_node *prn = NULL;
2686 struct bgp_table *table = NULL;
2687
2688 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
2689 if (prn->info) {
2690 table = (struct bgp_table *)(prn->info);
2691
2692 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
2693 bgp,
2694 prd,
2695 table,
2696 p,
2697 ri);
2698 }
2699 bgp_unlock_node(prn);
2700 }
2701 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2702 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
2703 /*
2704 * Implicit withdraw case.
2705 */
2706 ++vnc_implicit_withdraw;
2707 vnc_import_bgp_del_route(bgp, p, ri);
2708 vnc_import_bgp_exterior_del_route(bgp, p, ri);
2709 }
2710 }
2711 #endif
2712
2713 /* Update to new attribute. */
2714 bgp_attr_unintern (&ri->attr);
2715 ri->attr = attr_new;
2716
2717 /* Update MPLS tag. */
2718 if (bgp_labeled_safi(safi))
2719 memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
2720
2721 #if ENABLE_BGP_VNC
2722 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
2723 {
2724 if (vnc_implicit_withdraw)
2725 {
2726 /*
2727 * Add back the route with its new attributes (e.g., nexthop).
2728 * The route is still selected, until the route selection
2729 * queued by bgp_process actually runs. We have to make this
2730 * update to the VNC side immediately to avoid racing against
2731 * configuration changes (e.g., route-map changes) which
2732 * trigger re-importation of the entire RIB.
2733 */
2734 vnc_import_bgp_add_route(bgp, p, ri);
2735 vnc_import_bgp_exterior_add_route(bgp, p, ri);
2736 }
2737 }
2738 #endif
2739 /* Update Overlay Index */
2740 if(afi == AFI_L2VPN)
2741 {
2742 overlay_index_update(ri->attr, evpn==NULL?NULL:&evpn->eth_s_id,
2743 evpn==NULL?NULL:&evpn->gw_ip);
2744 }
2745
2746 /* Update bgp route dampening information. */
2747 if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
2748 && peer->sort == BGP_PEER_EBGP)
2749 {
2750 /* Now we do normal update dampening. */
2751 ret = bgp_damp_update (ri, rn, afi, safi);
2752 if (ret == BGP_DAMP_SUPPRESSED)
2753 {
2754 bgp_unlock_node (rn);
2755 return 0;
2756 }
2757 }
2758
2759 /* Nexthop reachability check - for unicast and labeled-unicast.. */
2760 if ((afi == AFI_IP || afi == AFI_IP6) &&
2761 (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
2762 {
2763 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
2764 ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
2765 && ! bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
2766 connected = 1;
2767 else
2768 connected = 0;
2769
2770 if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, connected))
2771 bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
2772 else
2773 {
2774 if (BGP_DEBUG(nht, NHT))
2775 {
2776 char buf1[INET6_ADDRSTRLEN];
2777 inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
2778 zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
2779 }
2780 bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
2781 }
2782 }
2783 else
2784 bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
2785
2786 #if ENABLE_BGP_VNC
2787 if (safi == SAFI_MPLS_VPN)
2788 {
2789 struct bgp_node *prn = NULL;
2790 struct bgp_table *table = NULL;
2791
2792 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
2793 if (prn->info)
2794 {
2795 table = (struct bgp_table *)(prn->info);
2796
2797 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2798 bgp,
2799 prd,
2800 table,
2801 p,
2802 ri);
2803 }
2804 bgp_unlock_node(prn);
2805 }
2806 #endif
2807
2808 /* Process change. */
2809 bgp_aggregate_increment (bgp, p, ri, afi, safi);
2810
2811 bgp_process (bgp, rn, afi, safi);
2812 bgp_unlock_node (rn);
2813
2814 #if ENABLE_BGP_VNC
2815 if (SAFI_MPLS_VPN == safi)
2816 {
2817 uint32_t label = decode_label(tag);
2818
2819 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
2820 &label);
2821 }
2822 if (SAFI_ENCAP == safi)
2823 {
2824 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
2825 NULL);
2826 }
2827 #endif
2828
2829 return 0;
2830 } // End of implicit withdraw
2831
2832 /* Received Logging. */
2833 if (bgp_debug_update(peer, p, NULL, 1))
2834 {
2835 if (!peer->rcvd_attr_printed)
2836 {
2837 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
2838 peer->rcvd_attr_printed = 1;
2839 }
2840
2841 zlog_debug ("%s rcvd %s%s ", peer->host,
2842 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
2843 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf);
2844 }
2845
2846 /* Make new BGP info. */
2847 new = info_make(type, sub_type, 0, peer, attr_new, rn);
2848
2849 /* Update MPLS tag. */
2850 if (bgp_labeled_safi(safi) || safi == SAFI_EVPN)
2851 memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
2852
2853 /* Update Overlay Index */
2854 if(afi == AFI_L2VPN)
2855 {
2856 overlay_index_update(new->attr, evpn==NULL?NULL:&evpn->eth_s_id,
2857 evpn==NULL?NULL:&evpn->gw_ip);
2858 }
2859 /* Nexthop reachability check. */
2860 if ((afi == AFI_IP || afi == AFI_IP6) &&
2861 (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
2862 {
2863 if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
2864 ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
2865 && ! bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
2866 connected = 1;
2867 else
2868 connected = 0;
2869
2870 if (bgp_find_or_add_nexthop (bgp, afi, new, NULL, connected))
2871 bgp_info_set_flag (rn, new, BGP_INFO_VALID);
2872 else
2873 {
2874 if (BGP_DEBUG(nht, NHT))
2875 {
2876 char buf1[INET6_ADDRSTRLEN];
2877 inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
2878 zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
2879 }
2880 bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
2881 }
2882 }
2883 else
2884 bgp_info_set_flag (rn, new, BGP_INFO_VALID);
2885
2886 /* Addpath ID */
2887 new->addpath_rx_id = addpath_id;
2888
2889 /* Increment prefix */
2890 bgp_aggregate_increment (bgp, p, new, afi, safi);
2891
2892 /* Register new BGP information. */
2893 bgp_info_add (rn, new);
2894
2895 /* route_node_get lock */
2896 bgp_unlock_node (rn);
2897
2898 #if ENABLE_BGP_VNC
2899 if (safi == SAFI_MPLS_VPN)
2900 {
2901 struct bgp_node *prn = NULL;
2902 struct bgp_table *table = NULL;
2903
2904 prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
2905 if (prn->info)
2906 {
2907 table = (struct bgp_table *)(prn->info);
2908
2909 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
2910 bgp,
2911 prd,
2912 table,
2913 p,
2914 new);
2915 }
2916 bgp_unlock_node(prn);
2917 }
2918 #endif
2919
2920 /* If maximum prefix count is configured and current prefix
2921 count exeed it. */
2922 if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
2923 return -1;
2924
2925 /* Process change. */
2926 bgp_process (bgp, rn, afi, safi);
2927
2928 #if ENABLE_BGP_VNC
2929 if (SAFI_MPLS_VPN == safi)
2930 {
2931 uint32_t label = decode_label(tag);
2932
2933 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
2934 &label);
2935 }
2936 if (SAFI_ENCAP == safi)
2937 {
2938 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
2939 NULL);
2940 }
2941 #endif
2942
2943 return 0;
2944
2945 /* This BGP update is filtered. Log the reason then update BGP
2946 entry. */
2947 filtered:
2948 if (bgp_debug_update(peer, p, NULL, 1))
2949 {
2950 if (!peer->rcvd_attr_printed)
2951 {
2952 zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
2953 peer->rcvd_attr_printed = 1;
2954 }
2955
2956 zlog_debug ("%s rcvd UPDATE about %s %s -- DENIED due to: %s",
2957 peer->host,
2958 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
2959 addpath_id, pfx_buf, sizeof (pfx_buf)), label_buf, reason);
2960 }
2961
2962 if (ri)
2963 bgp_rib_remove (rn, ri, peer, afi, safi);
2964
2965 bgp_unlock_node (rn);
2966
2967 #if ENABLE_BGP_VNC
2968 /*
2969 * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
2970 * a few lines above)
2971 */
2972 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
2973 {
2974 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
2975 }
2976 #endif
2977
2978 return 0;
2979 }
2980
2981 int
2982 bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
2983 struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type,
2984 struct prefix_rd *prd, u_char *tag, struct bgp_route_evpn *evpn)
2985 {
2986 struct bgp *bgp;
2987 char pfx_buf[BGP_PRD_PATH_STRLEN];
2988 struct bgp_node *rn;
2989 struct bgp_info *ri;
2990
2991 #if ENABLE_BGP_VNC
2992 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
2993 {
2994 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
2995 }
2996 #endif
2997
2998 bgp = peer->bgp;
2999
3000 /* Lookup node. */
3001 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
3002
3003 /* If peer is soft reconfiguration enabled. Record input packet for
3004 * further calculation.
3005 *
3006 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
3007 * routes that are filtered. This tanks out Quagga RS pretty badly due to
3008 * the iteration over all RS clients.
3009 * Since we need to remove the entry from adj_in anyway, do that first and
3010 * if there was no entry, we don't need to do anything more.
3011 */
3012 if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3013 && peer != bgp->peer_self)
3014 if (!bgp_adj_in_unset (rn, peer, addpath_id))
3015 {
3016 if (bgp_debug_update (peer, p, NULL, 1))
3017 zlog_debug ("%s withdrawing route %s not in adj-in",
3018 peer->host,
3019 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
3020 addpath_id, pfx_buf, sizeof (pfx_buf)));
3021 bgp_unlock_node (rn);
3022 return 0;
3023 }
3024
3025 /* Lookup withdrawn route. */
3026 for (ri = rn->info; ri; ri = ri->next)
3027 if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
3028 ri->addpath_rx_id == addpath_id)
3029 break;
3030
3031 /* Logging. */
3032 if (bgp_debug_update(peer, p, NULL, 1))
3033 {
3034 zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
3035 peer->host,
3036 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
3037 addpath_id, pfx_buf, sizeof (pfx_buf)));
3038 }
3039
3040 /* Withdraw specified route from routing table. */
3041 if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
3042 bgp_rib_withdraw (rn, ri, peer, afi, safi, prd);
3043 else if (bgp_debug_update(peer, p, NULL, 1))
3044 zlog_debug ("%s Can't find the route %s",
3045 peer->host,
3046 bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
3047 addpath_id, pfx_buf, sizeof (pfx_buf)));
3048
3049 /* Unlock bgp_node_get() lock. */
3050 bgp_unlock_node (rn);
3051
3052 return 0;
3053 }
3054
3055 void
3056 bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
3057 {
3058 struct update_subgroup *subgrp;
3059 subgrp = peer_subgroup(peer, afi, safi);
3060 subgroup_default_originate(subgrp, withdraw);
3061 }
3062
3063
3064 /*
3065 * bgp_stop_announce_route_timer
3066 */
3067 void
3068 bgp_stop_announce_route_timer (struct peer_af *paf)
3069 {
3070 if (!paf->t_announce_route)
3071 return;
3072
3073 THREAD_TIMER_OFF (paf->t_announce_route);
3074 }
3075
3076 /*
3077 * bgp_announce_route_timer_expired
3078 *
3079 * Callback that is invoked when the route announcement timer for a
3080 * peer_af expires.
3081 */
3082 static int
3083 bgp_announce_route_timer_expired (struct thread *t)
3084 {
3085 struct peer_af *paf;
3086 struct peer *peer;
3087
3088 paf = THREAD_ARG (t);
3089 peer = paf->peer;
3090
3091 assert (paf->t_announce_route);
3092 paf->t_announce_route = NULL;
3093
3094 if (peer->status != Established)
3095 return 0;
3096
3097 if (!peer->afc_nego[paf->afi][paf->safi])
3098 return 0;
3099
3100 peer_af_announce_route (paf, 1);
3101 return 0;
3102 }
3103
3104 /*
3105 * bgp_announce_route
3106 *
3107 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
3108 */
3109 void
3110 bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
3111 {
3112 struct peer_af *paf;
3113 struct update_subgroup *subgrp;
3114
3115 paf = peer_af_find (peer, afi, safi);
3116 if (!paf)
3117 return;
3118 subgrp = PAF_SUBGRP(paf);
3119
3120 /*
3121 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
3122 * or a refresh has already been triggered.
3123 */
3124 if (!subgrp || paf->t_announce_route)
3125 return;
3126
3127 /*
3128 * Start a timer to stagger/delay the announce. This serves
3129 * two purposes - announcement can potentially be combined for
3130 * multiple peers and the announcement doesn't happen in the
3131 * vty context.
3132 */
3133 THREAD_TIMER_MSEC_ON (bm->master, paf->t_announce_route,
3134 bgp_announce_route_timer_expired, paf,
3135 (subgrp->peer_count == 1) ?
3136 BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS :
3137 BGP_ANNOUNCE_ROUTE_DELAY_MS);
3138 }
3139
3140 /*
3141 * Announce routes from all AF tables to a peer.
3142 *
3143 * This should ONLY be called when there is a need to refresh the
3144 * routes to the peer based on a policy change for this peer alone
3145 * or a route refresh request received from the peer.
3146 * The operation will result in splitting the peer from its existing
3147 * subgroups and putting it in new subgroups.
3148 */
3149 void
3150 bgp_announce_route_all (struct peer *peer)
3151 {
3152 afi_t afi;
3153 safi_t safi;
3154
3155 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3156 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3157 bgp_announce_route (peer, afi, safi);
3158 }
3159
3160 static void
3161 bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
3162 struct bgp_table *table, struct prefix_rd *prd)
3163 {
3164 int ret;
3165 struct bgp_node *rn;
3166 struct bgp_adj_in *ain;
3167
3168 if (! table)
3169 table = peer->bgp->rib[afi][safi];
3170
3171 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
3172 for (ain = rn->adj_in; ain; ain = ain->next)
3173 {
3174 if (ain->peer == peer)
3175 {
3176 struct bgp_info *ri = rn->info;
3177 u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
3178
3179 ret = bgp_update (peer, &rn->p, ain->addpath_rx_id, ain->attr,
3180 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
3181 prd, tag, 1, NULL);
3182
3183 if (ret < 0)
3184 {
3185 bgp_unlock_node (rn);
3186 return;
3187 }
3188 }
3189 }
3190 }
3191
3192 void
3193 bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
3194 {
3195 struct bgp_node *rn;
3196 struct bgp_table *table;
3197
3198 if (peer->status != Established)
3199 return;
3200
3201 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP) && (safi != SAFI_EVPN))
3202 bgp_soft_reconfig_table (peer, afi, safi, NULL, NULL);
3203 else
3204 for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
3205 rn = bgp_route_next (rn))
3206 if ((table = rn->info) != NULL)
3207 {
3208 struct prefix_rd prd;
3209 prd.family = AF_UNSPEC;
3210 prd.prefixlen = 64;
3211 memcpy(&prd.val, rn->p.u.val, 8);
3212
3213 bgp_soft_reconfig_table (peer, afi, safi, table, &prd);
3214 }
3215 }
3216
3217
3218 struct bgp_clear_node_queue
3219 {
3220 struct bgp_node *rn;
3221 };
3222
3223 static wq_item_status
3224 bgp_clear_route_node (struct work_queue *wq, void *data)
3225 {
3226 struct bgp_clear_node_queue *cnq = data;
3227 struct bgp_node *rn = cnq->rn;
3228 struct peer *peer = wq->spec.data;
3229 struct bgp_info *ri;
3230 afi_t afi = bgp_node_table (rn)->afi;
3231 safi_t safi = bgp_node_table (rn)->safi;
3232
3233 assert (rn && peer);
3234
3235 /* It is possible that we have multiple paths for a prefix from a peer
3236 * if that peer is using AddPath.
3237 */
3238 for (ri = rn->info; ri; ri = ri->next)
3239 if (ri->peer == peer)
3240 {
3241 /* graceful restart STALE flag set. */
3242 if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)
3243 && peer->nsf[afi][safi]
3244 && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
3245 && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
3246 bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
3247 else
3248 bgp_rib_remove (rn, ri, peer, afi, safi);
3249 }
3250 return WQ_SUCCESS;
3251 }
3252
3253 static void
3254 bgp_clear_node_queue_del (struct work_queue *wq, void *data)
3255 {
3256 struct bgp_clear_node_queue *cnq = data;
3257 struct bgp_node *rn = cnq->rn;
3258 struct bgp_table *table = bgp_node_table (rn);
3259
3260 bgp_unlock_node (rn);
3261 bgp_table_unlock (table);
3262 XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
3263 }
3264
3265 static void
3266 bgp_clear_node_complete (struct work_queue *wq)
3267 {
3268 struct peer *peer = wq->spec.data;
3269
3270 /* Tickle FSM to start moving again */
3271 BGP_EVENT_ADD (peer, Clearing_Completed);
3272
3273 peer_unlock (peer); /* bgp_clear_route */
3274 }
3275
3276 static void
3277 bgp_clear_node_queue_init (struct peer *peer)
3278 {
3279 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
3280
3281 snprintf (wname, sizeof(wname), "clear %s", peer->host);
3282 #undef CLEAR_QUEUE_NAME_LEN
3283
3284 if ( (peer->clear_node_queue = work_queue_new (bm->master, wname)) == NULL)
3285 {
3286 zlog_err ("%s: Failed to allocate work queue", __func__);
3287 exit (1);
3288 }
3289 peer->clear_node_queue->spec.hold = 10;
3290 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
3291 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
3292 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
3293 peer->clear_node_queue->spec.max_retries = 0;
3294
3295 /* we only 'lock' this peer reference when the queue is actually active */
3296 peer->clear_node_queue->spec.data = peer;
3297 }
3298
3299 static void
3300 bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
3301 struct bgp_table *table)
3302 {
3303 struct bgp_node *rn;
3304 int force = bm->process_main_queue ? 0 : 1;
3305
3306 if (! table)
3307 table = peer->bgp->rib[afi][safi];
3308
3309 /* If still no table => afi/safi isn't configured at all or smth. */
3310 if (! table)
3311 return;
3312
3313 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
3314 {
3315 struct bgp_info *ri, *next;
3316 struct bgp_adj_in *ain;
3317 struct bgp_adj_in *ain_next;
3318
3319 /* XXX:TODO: This is suboptimal, every non-empty route_node is
3320 * queued for every clearing peer, regardless of whether it is
3321 * relevant to the peer at hand.
3322 *
3323 * Overview: There are 3 different indices which need to be
3324 * scrubbed, potentially, when a peer is removed:
3325 *
3326 * 1 peer's routes visible via the RIB (ie accepted routes)
3327 * 2 peer's routes visible by the (optional) peer's adj-in index
3328 * 3 other routes visible by the peer's adj-out index
3329 *
3330 * 3 there is no hurry in scrubbing, once the struct peer is
3331 * removed from bgp->peer, we could just GC such deleted peer's
3332 * adj-outs at our leisure.
3333 *
3334 * 1 and 2 must be 'scrubbed' in some way, at least made
3335 * invisible via RIB index before peer session is allowed to be
3336 * brought back up. So one needs to know when such a 'search' is
3337 * complete.
3338 *
3339 * Ideally:
3340 *
3341 * - there'd be a single global queue or a single RIB walker
3342 * - rather than tracking which route_nodes still need to be
3343 * examined on a peer basis, we'd track which peers still
3344 * aren't cleared
3345 *
3346 * Given that our per-peer prefix-counts now should be reliable,
3347 * this may actually be achievable. It doesn't seem to be a huge
3348 * problem at this time,
3349 *
3350 * It is possible that we have multiple paths for a prefix from a peer
3351 * if that peer is using AddPath.
3352 */
3353 ain = rn->adj_in;
3354 while (ain)
3355 {
3356 ain_next = ain->next;
3357
3358 if (ain->peer == peer)
3359 {
3360 bgp_adj_in_remove (rn, ain);
3361 bgp_unlock_node (rn);
3362 }
3363
3364 ain = ain_next;
3365 }
3366
3367 for (ri = rn->info; ri; ri = next)
3368 {
3369 next = ri->next;
3370 if (ri->peer != peer)
3371 continue;
3372
3373 if (force)
3374 bgp_info_reap (rn, ri);
3375 else
3376 {
3377 struct bgp_clear_node_queue *cnq;
3378
3379 /* both unlocked in bgp_clear_node_queue_del */
3380 bgp_table_lock (bgp_node_table (rn));
3381 bgp_lock_node (rn);
3382 cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
3383 sizeof (struct bgp_clear_node_queue));
3384 cnq->rn = rn;
3385 work_queue_add (peer->clear_node_queue, cnq);
3386 break;
3387 }
3388 }
3389 }
3390 return;
3391 }
3392
3393 void
3394 bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
3395 {
3396 struct bgp_node *rn;
3397 struct bgp_table *table;
3398
3399 if (peer->clear_node_queue == NULL)
3400 bgp_clear_node_queue_init (peer);
3401
3402 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
3403 * Idle until it receives a Clearing_Completed event. This protects
3404 * against peers which flap faster than we can we clear, which could
3405 * lead to:
3406 *
3407 * a) race with routes from the new session being installed before
3408 * clear_route_node visits the node (to delete the route of that
3409 * peer)
3410 * b) resource exhaustion, clear_route_node likely leads to an entry
3411 * on the process_main queue. Fast-flapping could cause that queue
3412 * to grow and grow.
3413 */
3414
3415 /* lock peer in assumption that clear-node-queue will get nodes; if so,
3416 * the unlock will happen upon work-queue completion; other wise, the
3417 * unlock happens at the end of this function.
3418 */
3419 if (!peer->clear_node_queue->thread)
3420 peer_lock (peer);
3421
3422 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
3423 bgp_clear_route_table (peer, afi, safi, NULL);
3424 else
3425 for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
3426 rn = bgp_route_next (rn))
3427 if ((table = rn->info) != NULL)
3428 bgp_clear_route_table (peer, afi, safi, table);
3429
3430 /* unlock if no nodes got added to the clear-node-queue. */
3431 if (!peer->clear_node_queue->thread)
3432 peer_unlock (peer);
3433
3434 }
3435
3436 void
3437 bgp_clear_route_all (struct peer *peer)
3438 {
3439 afi_t afi;
3440 safi_t safi;
3441
3442 for (afi = AFI_IP; afi < AFI_MAX; afi++)
3443 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
3444 bgp_clear_route (peer, afi, safi);
3445
3446 #if ENABLE_BGP_VNC
3447 rfapiProcessPeerDown(peer);
3448 #endif
3449 }
3450
3451 void
3452 bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
3453 {
3454 struct bgp_table *table;
3455 struct bgp_node *rn;
3456 struct bgp_adj_in *ain;
3457 struct bgp_adj_in *ain_next;
3458
3459 table = peer->bgp->rib[afi][safi];
3460
3461 /* It is possible that we have multiple paths for a prefix from a peer
3462 * if that peer is using AddPath.
3463 */
3464 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
3465 {
3466 ain = rn->adj_in;
3467
3468 while (ain)
3469 {
3470 ain_next = ain->next;
3471
3472 if (ain->peer == peer)
3473 {
3474 bgp_adj_in_remove (rn, ain);
3475 bgp_unlock_node (rn);
3476 }
3477
3478 ain = ain_next;
3479 }
3480 }
3481 }
3482
3483 void
3484 bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
3485 {
3486 struct bgp_node *rn;
3487 struct bgp_info *ri;
3488 struct bgp_table *table;
3489
3490 if ( safi == SAFI_MPLS_VPN)
3491 {
3492 for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
3493 {
3494 struct bgp_node *rm;
3495 struct bgp_info *ri;
3496
3497 /* look for neighbor in tables */
3498 if ((table = rn->info) != NULL)
3499 {
3500 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
3501 for (ri = rm->info; ri; ri = ri->next)
3502 if (ri->peer == peer)
3503 {
3504 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
3505 bgp_rib_remove (rm, ri, peer, afi, safi);
3506 break;
3507 }
3508 }
3509 }
3510 }
3511 else
3512 {
3513 for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
3514 for (ri = rn->info; ri; ri = ri->next)
3515 if (ri->peer == peer)
3516 {
3517 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
3518 bgp_rib_remove (rn, ri, peer, afi, safi);
3519 break;
3520 }
3521 }
3522 }
3523
3524 static void
3525 bgp_cleanup_table(struct bgp_table *table, safi_t safi)
3526 {
3527 struct bgp_node *rn;
3528 struct bgp_info *ri;
3529 struct bgp_info *next;
3530
3531 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
3532 for (ri = rn->info; ri; ri = next)
3533 {
3534 next = ri->next;
3535 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
3536 && ri->type == ZEBRA_ROUTE_BGP
3537 && (ri->sub_type == BGP_ROUTE_NORMAL ||
3538 ri->sub_type == BGP_ROUTE_AGGREGATE))
3539 {
3540 #if ENABLE_BGP_VNC
3541 if (table->owner && table->owner->bgp)
3542 vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
3543 #endif
3544 bgp_zebra_withdraw (&rn->p, ri, safi);
3545 bgp_info_reap (rn, ri);
3546 }
3547 }
3548 }
3549
3550 /* Delete all kernel routes. */
3551 void
3552 bgp_cleanup_routes (struct bgp *bgp)
3553 {
3554 afi_t afi;
3555 struct bgp_node *rn;
3556
3557 for (afi = AFI_IP; afi < AFI_MAX; ++afi)
3558 {
3559 if (afi == AFI_L2VPN)
3560 continue;
3561 bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
3562 /*
3563 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
3564 */
3565 if (afi != AFI_L2VPN)
3566 {
3567 safi_t safi;
3568 safi = SAFI_MPLS_VPN;
3569 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3570 rn = bgp_route_next (rn))
3571 {
3572 if (rn->info)
3573 {
3574 bgp_cleanup_table((struct bgp_table *)(rn->info), safi);
3575 bgp_table_finish ((struct bgp_table **)&(rn->info));
3576 rn->info = NULL;
3577 bgp_unlock_node(rn);
3578 }
3579 }
3580 safi = SAFI_ENCAP;
3581 for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
3582 rn = bgp_route_next (rn))
3583 {
3584 if (rn->info)
3585 {
3586 bgp_cleanup_table((struct bgp_table *)(rn->info), safi);
3587 bgp_table_finish ((struct bgp_table **)&(rn->info));
3588 rn->info = NULL;
3589 bgp_unlock_node(rn);
3590 }
3591 }
3592 }
3593 }
3594 for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
3595 rn = bgp_route_next (rn))
3596 {
3597 if (rn->info)
3598 {
3599 bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_EVPN);
3600 bgp_table_finish ((struct bgp_table **)&(rn->info));
3601 rn->info = NULL;
3602 bgp_unlock_node(rn);
3603 }
3604 }
3605 }
3606
3607 void
3608 bgp_reset (void)
3609 {
3610 vty_reset ();
3611 bgp_zclient_reset ();
3612 access_list_reset ();
3613 prefix_list_reset ();
3614 }
3615
3616 static int
3617 bgp_addpath_encode_rx (struct peer *peer, afi_t afi, safi_t safi)
3618 {
3619 return (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
3620 CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
3621 }
3622
3623 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
3624 value. */
3625 int
3626 bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
3627 struct bgp_nlri *packet)
3628 {
3629 u_char *pnt;
3630 u_char *lim;
3631 struct prefix p;
3632 int psize;
3633 int ret;
3634 afi_t afi;
3635 safi_t safi;
3636 int addpath_encoded;
3637 u_int32_t addpath_id;
3638
3639 /* Check peer status. */
3640 if (peer->status != Established)
3641 return 0;
3642
3643 pnt = packet->nlri;
3644 lim = pnt + packet->length;
3645 afi = packet->afi;
3646 safi = packet->safi;
3647 addpath_id = 0;
3648 addpath_encoded = bgp_addpath_encode_rx (peer, afi, safi);
3649
3650 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
3651 syntactic validity. If the field is syntactically incorrect,
3652 then the Error Subcode is set to Invalid Network Field. */
3653 for (; pnt < lim; pnt += psize)
3654 {
3655 /* Clear prefix structure. */
3656 memset (&p, 0, sizeof (struct prefix));
3657
3658 if (addpath_encoded)
3659 {
3660
3661 /* When packet overflow occurs return immediately. */
3662 if (pnt + BGP_ADDPATH_ID_LEN > lim)
3663 return -1;
3664
3665 addpath_id = ntohl(*((uint32_t*) pnt));
3666 pnt += BGP_ADDPATH_ID_LEN;
3667 }
3668
3669 /* Fetch prefix length. */
3670 p.prefixlen = *pnt++;
3671 /* afi/safi validity already verified by caller, bgp_update_receive */
3672 p.family = afi2family (afi);
3673
3674 /* Prefix length check. */
3675 if (p.prefixlen > prefix_blen (&p) * 8)
3676 {
3677 zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
3678 peer->host, p.prefixlen, packet->afi);
3679 return -1;
3680 }
3681
3682 /* Packet size overflow check. */
3683 psize = PSIZE (p.prefixlen);
3684
3685 /* When packet overflow occur return immediately. */
3686 if (pnt + psize > lim)
3687 {
3688 zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
3689 peer->host, p.prefixlen);
3690 return -1;
3691 }
3692
3693 /* Defensive coding, double-check the psize fits in a struct prefix */
3694 if (psize > (ssize_t) sizeof(p.u))
3695 {
3696 zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
3697 peer->host, p.prefixlen, sizeof(p.u));
3698 return -1;
3699 }
3700
3701 /* Fetch prefix from NLRI packet. */
3702 memcpy (&p.u.prefix, pnt, psize);
3703
3704 /* Check address. */
3705 if (afi == AFI_IP && safi == SAFI_UNICAST)
3706 {
3707 if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
3708 {
3709 /* From RFC4271 Section 6.3:
3710 *
3711 * If a prefix in the NLRI field is semantically incorrect
3712 * (e.g., an unexpected multicast IP address), an error SHOULD
3713 * be logged locally, and the prefix SHOULD be ignored.
3714 */
3715 zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
3716 peer->host, inet_ntoa (p.u.prefix4));
3717 continue;
3718 }
3719 }
3720
3721 /* Check address. */
3722 if (afi == AFI_IP6 && safi == SAFI_UNICAST)
3723 {
3724 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
3725 {
3726 char buf[BUFSIZ];
3727
3728 zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
3729 peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
3730
3731 continue;
3732 }
3733 if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
3734 {
3735 char buf[BUFSIZ];
3736
3737 zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
3738 peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
3739
3740 continue;
3741 }
3742 }
3743
3744 /* Normal process. */
3745 if (attr)
3746 ret = bgp_update (peer, &p, addpath_id, attr, afi, safi,
3747 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0, NULL);
3748 else
3749 ret = bgp_withdraw (peer, &p, addpath_id, attr, afi, safi,
3750 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, NULL);
3751
3752 /* Address family configuration mismatch or maximum-prefix count
3753 overflow. */
3754 if (ret < 0)
3755 return -1;
3756 }
3757
3758 /* Packet length consistency check. */
3759 if (pnt != lim)
3760 {
3761 zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
3762 peer->host);
3763 return -1;
3764 }
3765
3766 return 0;
3767 }
3768
3769 static struct bgp_static *
3770 bgp_static_new (void)
3771 {
3772 return XCALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));
3773 }
3774
3775 static void
3776 bgp_static_free (struct bgp_static *bgp_static)
3777 {
3778 if (bgp_static->rmap.name)
3779 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
3780 if(bgp_static->eth_s_id)
3781 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
3782 XFREE (MTYPE_BGP_STATIC, bgp_static);
3783 }
3784
3785 void
3786 bgp_static_update (struct bgp *bgp, struct prefix *p,
3787 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
3788 {
3789 struct bgp_node *rn;
3790 struct bgp_info *ri;
3791 struct bgp_info *new;
3792 struct bgp_info info;
3793 struct attr attr;
3794 struct attr *attr_new;
3795 int ret;
3796 #if ENABLE_BGP_VNC
3797 int vnc_implicit_withdraw = 0;
3798 #endif
3799
3800 assert (bgp_static);
3801 if (!bgp_static)
3802 return;
3803
3804 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
3805
3806 bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
3807
3808 attr.nexthop = bgp_static->igpnexthop;
3809 attr.med = bgp_static->igpmetric;
3810 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
3811
3812 if (bgp_static->atomic)
3813 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
3814
3815 /* Store label index, if required. */
3816 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
3817 {
3818 (bgp_attr_extra_get (&attr))->label_index = bgp_static->label_index;
3819 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_PREFIX_SID);
3820 }
3821
3822 /* Apply route-map. */
3823 if (bgp_static->rmap.name)
3824 {
3825 struct attr attr_tmp = attr;
3826 info.peer = bgp->peer_self;
3827 info.attr = &attr_tmp;
3828
3829 SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
3830
3831 ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
3832
3833 bgp->peer_self->rmap_type = 0;
3834
3835 if (ret == RMAP_DENYMATCH)
3836 {
3837 /* Free uninterned attribute. */
3838 bgp_attr_flush (&attr_tmp);
3839
3840 /* Unintern original. */
3841 aspath_unintern (&attr.aspath);
3842 bgp_attr_extra_free (&attr);
3843 bgp_static_withdraw (bgp, p, afi, safi);
3844 return;
3845 }
3846 attr_new = bgp_attr_intern (&attr_tmp);
3847 }
3848 else
3849 attr_new = bgp_attr_intern (&attr);
3850
3851 for (ri = rn->info; ri; ri = ri->next)
3852 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
3853 && ri->sub_type == BGP_ROUTE_STATIC)
3854 break;
3855
3856 if (ri)
3857 {
3858 if (attrhash_cmp (ri->attr, attr_new) &&
3859 !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED) &&
3860 !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS))
3861 {
3862 bgp_unlock_node (rn);
3863 bgp_attr_unintern (&attr_new);
3864 aspath_unintern (&attr.aspath);
3865 bgp_attr_extra_free (&attr);
3866 return;
3867 }
3868 else
3869 {
3870 /* The attribute is changed. */
3871 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
3872
3873 /* Rewrite BGP route information. */
3874 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
3875 bgp_info_restore(rn, ri);
3876 else
3877 bgp_aggregate_decrement (bgp, p, ri, afi, safi);
3878 #if ENABLE_BGP_VNC
3879 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
3880 {
3881 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
3882 {
3883 /*
3884 * Implicit withdraw case.
3885 * We have to do this before ri is changed
3886 */
3887 ++vnc_implicit_withdraw;
3888 vnc_import_bgp_del_route(bgp, p, ri);
3889 vnc_import_bgp_exterior_del_route(bgp, p, ri);
3890 }
3891 }
3892 #endif
3893 bgp_attr_unintern (&ri->attr);
3894 ri->attr = attr_new;
3895 ri->uptime = bgp_clock ();
3896 #if ENABLE_BGP_VNC
3897 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
3898 {
3899 if (vnc_implicit_withdraw)
3900 {
3901 vnc_import_bgp_add_route(bgp, p, ri);
3902 vnc_import_bgp_exterior_add_route(bgp, p, ri);
3903 }
3904 }
3905 #endif
3906
3907 /* Nexthop reachability check. */
3908 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK) &&
3909 safi == SAFI_UNICAST)
3910 {
3911 if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0) &&
3912 safi == SAFI_UNICAST)
3913 bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
3914 else
3915 {
3916 if (BGP_DEBUG(nht, NHT))
3917 {
3918 char buf1[INET6_ADDRSTRLEN];
3919 inet_ntop(p->family, &p->u.prefix, buf1,
3920 INET6_ADDRSTRLEN);
3921 zlog_debug("%s(%s): Route not in table, not advertising",
3922 __FUNCTION__, buf1);
3923 }
3924 bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
3925 }
3926 }
3927 else
3928 {
3929 /* Delete the NHT structure if any, if we're toggling between
3930 * enabling/disabling import check. We deregister the route
3931 * from NHT to avoid overloading NHT and the process interaction
3932 */
3933 bgp_unlink_nexthop(ri);
3934 bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
3935 }
3936 /* Process change. */
3937 bgp_aggregate_increment (bgp, p, ri, afi, safi);
3938 bgp_process (bgp, rn, afi, safi);
3939 bgp_unlock_node (rn);
3940 aspath_unintern (&attr.aspath);
3941 bgp_attr_extra_free (&attr);
3942 return;
3943 }
3944 }
3945
3946 /* Make new BGP info. */
3947 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
3948 rn);
3949 /* Nexthop reachability check. */
3950 if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
3951 {
3952 if (bgp_find_or_add_nexthop (bgp, afi, new, NULL, 0))
3953 bgp_info_set_flag (rn, new, BGP_INFO_VALID);
3954 else
3955 {
3956 if (BGP_DEBUG(nht, NHT))
3957 {
3958 char buf1[INET6_ADDRSTRLEN];
3959 inet_ntop(p->family, &p->u.prefix, buf1,
3960 INET6_ADDRSTRLEN);
3961 zlog_debug("%s(%s): Route not in table, not advertising",
3962 __FUNCTION__, buf1);
3963 }
3964 bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
3965 }
3966 }
3967 else
3968 {
3969 /* Delete the NHT structure if any, if we're toggling between
3970 * enabling/disabling import check. We deregister the route
3971 * from NHT to avoid overloading NHT and the process interaction
3972 */
3973 bgp_unlink_nexthop(new);
3974
3975 bgp_info_set_flag (rn, new, BGP_INFO_VALID);
3976 }
3977
3978 /* Aggregate address increment. */
3979 bgp_aggregate_increment (bgp, p, new, afi, safi);
3980
3981 /* Register new BGP information. */
3982 bgp_info_add (rn, new);
3983
3984 /* route_node_get lock */
3985 bgp_unlock_node (rn);
3986
3987 /* Process change. */
3988 bgp_process (bgp, rn, afi, safi);
3989
3990 /* Unintern original. */
3991 aspath_unintern (&attr.aspath);
3992 bgp_attr_extra_free (&attr);
3993 }
3994
3995 void
3996 bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
3997 safi_t safi)
3998 {
3999 struct bgp_node *rn;
4000 struct bgp_info *ri;
4001
4002 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
4003
4004 /* Check selected route and self inserted route. */
4005 for (ri = rn->info; ri; ri = ri->next)
4006 if (ri->peer == bgp->peer_self
4007 && ri->type == ZEBRA_ROUTE_BGP
4008 && ri->sub_type == BGP_ROUTE_STATIC)
4009 break;
4010
4011 /* Withdraw static BGP route from routing table. */
4012 if (ri)
4013 {
4014 bgp_aggregate_decrement (bgp, p, ri, afi, safi);
4015 bgp_unlink_nexthop(ri);
4016 bgp_info_delete (rn, ri);
4017 bgp_process (bgp, rn, afi, safi);
4018 }
4019
4020 /* Unlock bgp_node_lookup. */
4021 bgp_unlock_node (rn);
4022 }
4023
4024 /*
4025 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
4026 */
4027 static void
4028 bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
4029 safi_t safi, struct prefix_rd *prd, u_char *tag)
4030 {
4031 struct bgp_node *rn;
4032 struct bgp_info *ri;
4033
4034 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
4035
4036 /* Check selected route and self inserted route. */
4037 for (ri = rn->info; ri; ri = ri->next)
4038 if (ri->peer == bgp->peer_self
4039 && ri->type == ZEBRA_ROUTE_BGP
4040 && ri->sub_type == BGP_ROUTE_STATIC)
4041 break;
4042
4043 /* Withdraw static BGP route from routing table. */
4044 if (ri)
4045 {
4046 #if ENABLE_BGP_VNC
4047 rfapiProcessWithdraw(
4048 ri->peer,
4049 NULL,
4050 p,
4051 prd,
4052 ri->attr,
4053 afi,
4054 safi,
4055 ri->type,
4056 1); /* Kill, since it is an administrative change */
4057 #endif
4058 bgp_aggregate_decrement (bgp, p, ri, afi, safi);
4059 bgp_info_delete (rn, ri);
4060 bgp_process (bgp, rn, afi, safi);
4061 }
4062
4063 /* Unlock bgp_node_lookup. */
4064 bgp_unlock_node (rn);
4065 }
4066
4067 static void
4068 bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
4069 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
4070 {
4071 struct bgp_node *rn;
4072 struct bgp_info *new;
4073 struct attr *attr_new;
4074 struct attr attr = { 0 };
4075 struct bgp_info *ri;
4076 #if ENABLE_BGP_VNC
4077 u_int32_t label = 0;
4078 #endif
4079 union gw_addr add;
4080
4081 assert (bgp_static);
4082
4083 rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd);
4084
4085 bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
4086
4087 attr.nexthop = bgp_static->igpnexthop;
4088 attr.med = bgp_static->igpmetric;
4089 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
4090
4091 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
4092 {
4093 if (bgp_static->igpnexthop.s_addr)
4094 {
4095 bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
4096 bgp_attr_extra_get (&attr)->mp_nexthop_len = IPV4_MAX_BYTELEN;
4097 }
4098 }
4099 if(afi == AFI_L2VPN)
4100 {
4101 if (bgp_static->gatewayIp.family == AF_INET)
4102 add.ipv4.s_addr = bgp_static->gatewayIp.u.prefix4.s_addr;
4103 else if (bgp_static->gatewayIp.family == AF_INET6)
4104 memcpy( &(add.ipv6), &(bgp_static->gatewayIp.u.prefix6), sizeof (struct in6_addr));
4105 overlay_index_update(&attr, bgp_static->eth_s_id, &add);
4106 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN)
4107 {
4108 struct bgp_encap_type_vxlan bet;
4109 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
4110 bet.vnid = p->u.prefix_evpn.eth_tag;
4111 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
4112 }
4113 if (bgp_static->router_mac)
4114 {
4115 bgp_add_routermac_ecom (&attr, bgp_static->router_mac);
4116 }
4117 }
4118 /* Apply route-map. */
4119 if (bgp_static->rmap.name)
4120 {
4121 struct attr attr_tmp = attr;
4122 struct bgp_info info;
4123 int ret;
4124
4125 info.peer = bgp->peer_self;
4126 info.attr = &attr_tmp;
4127
4128 SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
4129
4130 ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
4131
4132 bgp->peer_self->rmap_type = 0;
4133
4134 if (ret == RMAP_DENYMATCH)
4135 {
4136 /* Free uninterned attribute. */
4137 bgp_attr_flush (&attr_tmp);
4138
4139 /* Unintern original. */
4140 aspath_unintern (&attr.aspath);
4141 bgp_attr_extra_free (&attr);
4142 bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd,
4143 bgp_static->tag);
4144 return;
4145 }
4146
4147 attr_new = bgp_attr_intern (&attr_tmp);
4148 }
4149 else
4150 {
4151 attr_new = bgp_attr_intern (&attr);
4152 }
4153
4154 for (ri = rn->info; ri; ri = ri->next)
4155 if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
4156 && ri->sub_type == BGP_ROUTE_STATIC)
4157 break;
4158
4159 if (ri)
4160 {
4161 union gw_addr add;
4162 memset(&add, 0, sizeof(union gw_addr));
4163 if (attrhash_cmp (ri->attr, attr_new) &&
4164 overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add) &&
4165 !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4166 {
4167 bgp_unlock_node (rn);
4168 bgp_attr_unintern (&attr_new);
4169 aspath_unintern (&attr.aspath);
4170 bgp_attr_extra_free (&attr);
4171 return;
4172 }
4173 else
4174 {
4175 /* The attribute is changed. */
4176 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
4177
4178 /* Rewrite BGP route information. */
4179 if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
4180 bgp_info_restore(rn, ri);
4181 else
4182 bgp_aggregate_decrement (bgp, p, ri, afi, safi);
4183 bgp_attr_unintern (&ri->attr);
4184 ri->attr = attr_new;
4185 ri->uptime = bgp_clock ();
4186 #if ENABLE_BGP_VNC
4187 if (ri->extra)
4188 label = decode_label (ri->extra->tag);
4189 #endif
4190
4191 /* Process change. */
4192 bgp_aggregate_increment (bgp, p, ri, afi, safi);
4193 bgp_process (bgp, rn, afi, safi);
4194 #if ENABLE_BGP_VNC
4195 rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
4196 ri->attr, afi, safi,
4197 ri->type, ri->sub_type, &label);
4198 #endif
4199 bgp_unlock_node (rn);
4200 aspath_unintern (&attr.aspath);
4201 bgp_attr_extra_free (&attr);
4202 return;
4203 }
4204 }
4205
4206
4207 /* Make new BGP info. */
4208 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
4209 rn);
4210 SET_FLAG (new->flags, BGP_INFO_VALID);
4211 new->extra = bgp_info_extra_new();
4212 memcpy (new->extra->tag, bgp_static->tag, 3);
4213 #if ENABLE_BGP_VNC
4214 label = decode_label (bgp_static->tag);
4215 #endif
4216
4217 /* Aggregate address increment. */
4218 bgp_aggregate_increment (bgp, p, new, afi, safi);
4219
4220 /* Register new BGP information. */
4221 bgp_info_add (rn, new);
4222 /* route_node_get lock */
4223 bgp_unlock_node (rn);
4224
4225 /* Process change. */
4226 bgp_process (bgp, rn, afi, safi);
4227
4228 #if ENABLE_BGP_VNC
4229 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd,
4230 new->attr, afi, safi,
4231 new->type, new->sub_type, &label);
4232 #endif
4233
4234 /* Unintern original. */
4235 aspath_unintern (&attr.aspath);
4236 bgp_attr_extra_free (&attr);
4237 }
4238
4239 /* Configure static BGP network. When user don't run zebra, static
4240 route should be installed as valid. */
4241 static int
4242 bgp_static_set (struct vty *vty, const char *ip_str,
4243 afi_t afi, safi_t safi, const char *rmap, int backdoor,
4244 u_int32_t label_index)
4245 {
4246 VTY_DECLVAR_CONTEXT(bgp, bgp);
4247 int ret;
4248 struct prefix p;
4249 struct bgp_static *bgp_static;
4250 struct bgp_node *rn;
4251 u_char need_update = 0;
4252
4253 /* Convert IP prefix string to struct prefix. */
4254 ret = str2prefix (ip_str, &p);
4255 if (! ret)
4256 {
4257 vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
4258 return CMD_WARNING;
4259 }
4260 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
4261 {
4262 vty_out (vty, "%% Malformed prefix (link-local address)%s",
4263 VTY_NEWLINE);
4264 return CMD_WARNING;
4265 }
4266
4267 apply_mask (&p);
4268
4269 /* Set BGP static route configuration. */
4270 rn = bgp_node_get (bgp->route[afi][safi], &p);
4271
4272 if (rn->info)
4273 {
4274 /* Configuration change. */
4275 bgp_static = rn->info;
4276
4277 /* Label index cannot be changed. */
4278 if (bgp_static->label_index != label_index)
4279 {
4280 vty_out (vty, "%% Label index cannot be changed%s", VTY_NEWLINE);
4281 return CMD_WARNING;
4282 }
4283
4284 /* Check previous routes are installed into BGP. */
4285 if (bgp_static->valid && bgp_static->backdoor != backdoor)
4286 need_update = 1;
4287
4288 bgp_static->backdoor = backdoor;
4289
4290 if (rmap)
4291 {
4292 if (bgp_static->rmap.name)
4293 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4294 bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4295 bgp_static->rmap.map = route_map_lookup_by_name (rmap);
4296 }
4297 else
4298 {
4299 if (bgp_static->rmap.name)
4300 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4301 bgp_static->rmap.name = NULL;
4302 bgp_static->rmap.map = NULL;
4303 bgp_static->valid = 0;
4304 }
4305 bgp_unlock_node (rn);
4306 }
4307 else
4308 {
4309 /* New configuration. */
4310 bgp_static = bgp_static_new ();
4311 bgp_static->backdoor = backdoor;
4312 bgp_static->valid = 0;
4313 bgp_static->igpmetric = 0;
4314 bgp_static->igpnexthop.s_addr = 0;
4315 bgp_static->label_index = label_index;
4316
4317 if (rmap)
4318 {
4319 if (bgp_static->rmap.name)
4320 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4321 bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
4322 bgp_static->rmap.map = route_map_lookup_by_name (rmap);
4323 }
4324 rn->info = bgp_static;
4325 }
4326
4327 bgp_static->valid = 1;
4328 if (need_update)
4329 bgp_static_withdraw (bgp, &p, afi, safi);
4330
4331 if (! bgp_static->backdoor)
4332 bgp_static_update (bgp, &p, bgp_static, afi, safi);
4333
4334 return CMD_SUCCESS;
4335 }
4336
4337 /* Configure static BGP network. */
4338 static int
4339 bgp_static_unset (struct vty *vty, const char *ip_str,
4340 afi_t afi, safi_t safi)
4341 {
4342 VTY_DECLVAR_CONTEXT(bgp, bgp);
4343 int ret;
4344 struct prefix p;
4345 struct bgp_static *bgp_static;
4346 struct bgp_node *rn;
4347
4348 /* Convert IP prefix string to struct prefix. */
4349 ret = str2prefix (ip_str, &p);
4350 if (! ret)
4351 {
4352 vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
4353 return CMD_WARNING;
4354 }
4355 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
4356 {
4357 vty_out (vty, "%% Malformed prefix (link-local address)%s",
4358 VTY_NEWLINE);
4359 return CMD_WARNING;
4360 }
4361
4362 apply_mask (&p);
4363
4364 rn = bgp_node_lookup (bgp->route[afi][safi], &p);
4365 if (! rn)
4366 {
4367 vty_out (vty, "%% Can't find specified static route configuration.%s",
4368 VTY_NEWLINE);
4369 return CMD_WARNING;
4370 }
4371
4372 bgp_static = rn->info;
4373
4374 /* Update BGP RIB. */
4375 if (! bgp_static->backdoor)
4376 bgp_static_withdraw (bgp, &p, afi, safi);
4377
4378 /* Clear configuration. */
4379 bgp_static_free (bgp_static);
4380 rn->info = NULL;
4381 bgp_unlock_node (rn);
4382 bgp_unlock_node (rn);
4383
4384 return CMD_SUCCESS;
4385 }
4386
4387 void
4388 bgp_static_add (struct bgp *bgp)
4389 {
4390 afi_t afi;
4391 safi_t safi;
4392 struct bgp_node *rn;
4393 struct bgp_node *rm;
4394 struct bgp_table *table;
4395 struct bgp_static *bgp_static;
4396
4397 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4398 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4399 for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
4400 if (rn->info != NULL)
4401 {
4402 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
4403 {
4404 table = rn->info;
4405
4406 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
4407 {
4408 bgp_static = rn->info;
4409 bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
4410 }
4411 }
4412 else
4413 {
4414 bgp_static_update (bgp, &rn->p, rn->info, afi, safi);
4415 }
4416 }
4417 }
4418
4419 /* Called from bgp_delete(). Delete all static routes from the BGP
4420 instance. */
4421 void
4422 bgp_static_delete (struct bgp *bgp)
4423 {
4424 afi_t afi;
4425 safi_t safi;
4426 struct bgp_node *rn;
4427 struct bgp_node *rm;
4428 struct bgp_table *table;
4429 struct bgp_static *bgp_static;
4430
4431 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4432 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4433 for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
4434 if (rn->info != NULL)
4435 {
4436 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
4437 {
4438 table = rn->info;
4439
4440 for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
4441 {
4442 bgp_static = rn->info;
4443 bgp_static_withdraw_safi (bgp, &rm->p,
4444 AFI_IP, safi,
4445 (struct prefix_rd *)&rn->p,
4446 bgp_static->tag);
4447 bgp_static_free (bgp_static);
4448 rn->info = NULL;
4449 bgp_unlock_node (rn);
4450 }
4451 }
4452 else
4453 {
4454 bgp_static = rn->info;
4455 bgp_static_withdraw (bgp, &rn->p, afi, safi);
4456 bgp_static_free (bgp_static);
4457 rn->info = NULL;
4458 bgp_unlock_node (rn);
4459 }
4460 }
4461 }
4462
4463 void
4464 bgp_static_redo_import_check (struct bgp *bgp)
4465 {
4466 afi_t afi;
4467 safi_t safi;
4468 struct bgp_node *rn;
4469 struct bgp_static *bgp_static;
4470
4471 /* Use this flag to force reprocessing of the route */
4472 bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
4473 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4474 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4475 for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
4476 if (rn->info != NULL)
4477 {
4478 bgp_static = rn->info;
4479 bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
4480 }
4481 bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
4482 }
4483
4484 static void
4485 bgp_purge_af_static_redist_routes (struct bgp *bgp, afi_t afi, safi_t safi)
4486 {
4487 struct bgp_table *table;
4488 struct bgp_node *rn;
4489 struct bgp_info *ri;
4490
4491 table = bgp->rib[afi][safi];
4492 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
4493 {
4494 for (ri = rn->info; ri; ri = ri->next)
4495 {
4496 if (ri->peer == bgp->peer_self &&
4497 ((ri->type == ZEBRA_ROUTE_BGP &&
4498 ri->sub_type == BGP_ROUTE_STATIC) ||
4499 (ri->type != ZEBRA_ROUTE_BGP &&
4500 ri->sub_type == BGP_ROUTE_REDISTRIBUTE)))
4501 {
4502 bgp_aggregate_decrement (bgp, &rn->p, ri, afi, safi);
4503 bgp_unlink_nexthop(ri);
4504 bgp_info_delete (rn, ri);
4505 bgp_process (bgp, rn, afi, safi);
4506 }
4507 }
4508 }
4509 }
4510
4511 /*
4512 * Purge all networks and redistributed routes from routing table.
4513 * Invoked upon the instance going down.
4514 */
4515 void
4516 bgp_purge_static_redist_routes (struct bgp *bgp)
4517 {
4518 afi_t afi;
4519 safi_t safi;
4520
4521 for (afi = AFI_IP; afi < AFI_MAX; afi++)
4522 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
4523 bgp_purge_af_static_redist_routes (bgp, afi, safi);
4524 }
4525
4526 /*
4527 * gpz 110624
4528 * Currently this is used to set static routes for VPN and ENCAP.
4529 * I think it can probably be factored with bgp_static_set.
4530 */
4531 int
4532 bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,
4533 const char *rd_str, const char *tag_str,
4534 const char *rmap_str, int evpn_type, const char *esi, const char *gwip,
4535 const char *ethtag, const char *routermac)
4536 {
4537 VTY_DECLVAR_CONTEXT(bgp, bgp);
4538 int ret;
4539 struct prefix p;
4540 struct prefix_rd prd;
4541 struct bgp_node *prn;
4542 struct bgp_node *rn;
4543 struct bgp_table *table;
4544 struct bgp_static *bgp_static;
4545 u_char tag[3];
4546 afi_t afi;
4547 struct prefix gw_ip;
4548
4549 if(safi == SAFI_EVPN)
4550 afi = AFI_L2VPN;
4551 else
4552 afi = AFI_IP;
4553
4554 /* validate ip prefix */
4555 ret = str2prefix (ip_str, &p);
4556 if (! ret)
4557 {
4558 vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
4559 return CMD_WARNING;
4560 }
4561 apply_mask (&p);
4562 if ( (afi == AFI_L2VPN) &&
4563 (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p)))
4564 {
4565 vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE);
4566 return CMD_WARNING;
4567 }
4568
4569 ret = str2prefix_rd (rd_str, &prd);
4570 if (! ret)
4571 {
4572 vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
4573 return CMD_WARNING;
4574 }
4575
4576 if (tag_str)
4577 {
4578 ret = str2tag (tag_str, tag);
4579 if (! ret)
4580 {
4581 vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
4582 return CMD_WARNING;
4583 }
4584 }
4585 else
4586 {
4587 encode_label (0, tag);
4588 }
4589 if (safi == SAFI_EVPN)
4590 {
4591 if( esi && str2esi (esi, NULL) == 0)
4592 {
4593 vty_out (vty, "%% Malformed ESI%s", VTY_NEWLINE);
4594 return CMD_WARNING;
4595 }
4596 if( routermac && prefix_str2mac (routermac, NULL) == 0)
4597 {
4598 vty_out (vty, "%% Malformed Router MAC%s", VTY_NEWLINE);
4599 return CMD_WARNING;
4600 }
4601 if (gwip)
4602 {
4603 memset (&gw_ip, 0, sizeof (struct prefix));
4604 ret = str2prefix (gwip, &gw_ip);
4605 if (! ret)
4606 {
4607 vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
4608 return CMD_WARNING;
4609 }
4610 if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6))
4611 || (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4)))
4612 {
4613 vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
4614 return CMD_WARNING;
4615 }
4616 }
4617 }
4618 prn = bgp_node_get (bgp->route[afi][safi],
4619 (struct prefix *)&prd);
4620 if (prn->info == NULL)
4621 prn->info = bgp_table_init (afi, safi);
4622 else
4623 bgp_unlock_node (prn);
4624 table = prn->info;
4625
4626 rn = bgp_node_get (table, &p);
4627
4628 if (rn->info)
4629 {
4630 vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
4631 bgp_unlock_node (rn);
4632 }
4633 else
4634 {
4635 /* New configuration. */
4636 bgp_static = bgp_static_new ();
4637 bgp_static->backdoor = 0;
4638 bgp_static->valid = 0;
4639 bgp_static->igpmetric = 0;
4640 bgp_static->igpnexthop.s_addr = 0;
4641 memcpy(bgp_static->tag, tag, 3);
4642 bgp_static->prd = prd;
4643
4644 if (rmap_str)
4645 {
4646 if (bgp_static->rmap.name)
4647 free (bgp_static->rmap.name);
4648 bgp_static->rmap.name = strdup (rmap_str);
4649 bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
4650 }
4651
4652 if (safi == SAFI_EVPN)
4653 {
4654 if(esi)
4655 {
4656 bgp_static->eth_s_id = XCALLOC (MTYPE_ATTR, sizeof(struct eth_segment_id));
4657 str2esi (esi, bgp_static->eth_s_id);
4658 }
4659 if( routermac)
4660 {
4661 bgp_static->router_mac = XCALLOC (MTYPE_ATTR, ETHER_ADDR_LEN+1);
4662 prefix_str2mac (routermac, bgp_static->router_mac);
4663 }
4664 if (gwip)
4665 prefix_copy (&bgp_static->gatewayIp, &gw_ip);
4666 }
4667 rn->info = bgp_static;
4668
4669 bgp_static->valid = 1;
4670 bgp_static_update_safi (bgp, &p, bgp_static, afi, safi);
4671 }
4672
4673 return CMD_SUCCESS;
4674 }
4675
4676 /* Configure static BGP network. */
4677 int
4678 bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,
4679 const char *rd_str, const char *tag_str,
4680 int evpn_type, const char *esi, const char *gwip, const char *ethtag)
4681 {
4682 VTY_DECLVAR_CONTEXT(bgp, bgp);
4683 int ret;
4684 struct prefix p;
4685 struct prefix_rd prd;
4686 struct bgp_node *prn;
4687 struct bgp_node *rn;
4688 struct bgp_table *table;
4689 struct bgp_static *bgp_static;
4690 u_char tag[3];
4691 afi_t afi;
4692
4693 if(safi == SAFI_EVPN)
4694 afi = AFI_L2VPN;
4695 else
4696 afi = AFI_IP;
4697
4698 /* Convert IP prefix string to struct prefix. */
4699 ret = str2prefix (ip_str, &p);
4700 if (! ret)
4701 {
4702 vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
4703 return CMD_WARNING;
4704 }
4705 apply_mask (&p);
4706 if ( (afi == AFI_L2VPN) &&
4707 (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p)))
4708 {
4709 vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE);
4710 return CMD_WARNING;
4711 }
4712 ret = str2prefix_rd (rd_str, &prd);
4713 if (! ret)
4714 {
4715 vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
4716 return CMD_WARNING;
4717 }
4718
4719 ret = str2tag (tag_str, tag);
4720 if (! ret)
4721 {
4722 vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE);
4723 return CMD_WARNING;
4724 }
4725
4726 prn = bgp_node_get (bgp->route[afi][safi],
4727 (struct prefix *)&prd);
4728 if (prn->info == NULL)
4729 prn->info = bgp_table_init (afi, safi);
4730 else
4731 bgp_unlock_node (prn);
4732 table = prn->info;
4733
4734 rn = bgp_node_lookup (table, &p);
4735
4736 if (rn)
4737 {
4738 bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd, tag);
4739
4740 bgp_static = rn->info;
4741 bgp_static_free (bgp_static);
4742 rn->info = NULL;
4743 bgp_unlock_node (rn);
4744 bgp_unlock_node (rn);
4745 }
4746 else
4747 vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
4748
4749 return CMD_SUCCESS;
4750 }
4751
4752 static int
4753 bgp_table_map_set (struct vty *vty, afi_t afi, safi_t safi,
4754 const char *rmap_name)
4755 {
4756 VTY_DECLVAR_CONTEXT(bgp, bgp);
4757 struct bgp_rmap *rmap;
4758
4759 rmap = &bgp->table_map[afi][safi];
4760 if (rmap_name)
4761 {
4762 if (rmap->name)
4763 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4764 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
4765 rmap->map = route_map_lookup_by_name (rmap_name);
4766 }
4767 else
4768 {
4769 if (rmap->name)
4770 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4771 rmap->name = NULL;
4772 rmap->map = NULL;
4773 }
4774
4775 bgp_zebra_announce_table(bgp, afi, safi);
4776
4777 return CMD_SUCCESS;
4778 }
4779
4780 static int
4781 bgp_table_map_unset (struct vty *vty, afi_t afi, safi_t safi,
4782 const char *rmap_name)
4783 {
4784 VTY_DECLVAR_CONTEXT(bgp, bgp);
4785 struct bgp_rmap *rmap;
4786
4787 rmap = &bgp->table_map[afi][safi];
4788 if (rmap->name)
4789 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4790 rmap->name = NULL;
4791 rmap->map = NULL;
4792
4793 bgp_zebra_announce_table(bgp, afi, safi);
4794
4795 return CMD_SUCCESS;
4796 }
4797
4798 int
4799 bgp_config_write_table_map (struct vty *vty, struct bgp *bgp, afi_t afi,
4800 safi_t safi, int *write)
4801 {
4802 if (bgp->table_map[afi][safi].name)
4803 {
4804 bgp_config_write_family_header (vty, afi, safi, write);
4805 vty_out (vty, " table-map %s%s",
4806 bgp->table_map[afi][safi].name, VTY_NEWLINE);
4807 }
4808
4809 return 0;
4810 }
4811
4812 DEFUN (bgp_table_map,
4813 bgp_table_map_cmd,
4814 "table-map WORD",
4815 "BGP table to RIB route download filter\n"
4816 "Name of the route map\n")
4817 {
4818 int idx_word = 1;
4819 return bgp_table_map_set (vty,
4820 bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
4821 }
4822 DEFUN (no_bgp_table_map,
4823 no_bgp_table_map_cmd,
4824 "no table-map WORD",
4825 NO_STR
4826 "BGP table to RIB route download filter\n"
4827 "Name of the route map\n")
4828 {
4829 int idx_word = 2;
4830 return bgp_table_map_unset (vty,
4831 bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
4832 }
4833
4834 DEFUN (bgp_network,
4835 bgp_network_cmd,
4836 "network A.B.C.D/M",
4837 "Specify a network to announce via BGP\n"
4838 "IPv4 prefix\n")
4839 {
4840 int idx_ipv4_prefixlen = 1;
4841 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
4842 AFI_IP, bgp_node_safi (vty), NULL, 0,
4843 BGP_INVALID_LABEL_INDEX);
4844 }
4845
4846 DEFUN (bgp_network_route_map,
4847 bgp_network_route_map_cmd,
4848 "network A.B.C.D/M route-map WORD",
4849 "Specify a network to announce via BGP\n"
4850 "IPv4 prefix\n"
4851 "Route-map to modify the attributes\n"
4852 "Name of the route map\n")
4853 {
4854 int idx_ipv4_prefixlen = 1;
4855 int idx_word = 3;
4856 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
4857 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
4858 BGP_INVALID_LABEL_INDEX);
4859 }
4860
4861 DEFUN (bgp_network_backdoor,
4862 bgp_network_backdoor_cmd,
4863 "network A.B.C.D/M backdoor",
4864 "Specify a network to announce via BGP\n"
4865 "IPv4 prefix\n"
4866 "Specify a BGP backdoor route\n")
4867 {
4868 int idx_ipv4_prefixlen = 1;
4869 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
4870 NULL, 1, BGP_INVALID_LABEL_INDEX);
4871 }
4872
4873 DEFUN (bgp_network_mask,
4874 bgp_network_mask_cmd,
4875 "network A.B.C.D mask A.B.C.D",
4876 "Specify a network to announce via BGP\n"
4877 "Network number\n"
4878 "Network mask\n"
4879 "Network mask\n")
4880 {
4881 int idx_ipv4 = 1;
4882 int idx_ipv4_2 = 3;
4883 int ret;
4884 char prefix_str[BUFSIZ];
4885
4886 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4887 if (! ret)
4888 {
4889 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4890 return CMD_WARNING;
4891 }
4892
4893 return bgp_static_set (vty, prefix_str,
4894 AFI_IP, bgp_node_safi (vty), NULL, 0, BGP_INVALID_LABEL_INDEX);
4895 }
4896
4897 DEFUN (bgp_network_mask_route_map,
4898 bgp_network_mask_route_map_cmd,
4899 "network A.B.C.D mask A.B.C.D route-map WORD",
4900 "Specify a network to announce via BGP\n"
4901 "Network number\n"
4902 "Network mask\n"
4903 "Network mask\n"
4904 "Route-map to modify the attributes\n"
4905 "Name of the route map\n")
4906 {
4907 int idx_ipv4 = 1;
4908 int idx_ipv4_2 = 3;
4909 int idx_word = 5;
4910 int ret;
4911 char prefix_str[BUFSIZ];
4912
4913 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4914 if (! ret)
4915 {
4916 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4917 return CMD_WARNING;
4918 }
4919
4920 return bgp_static_set (vty, prefix_str,
4921 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0, BGP_INVALID_LABEL_INDEX);
4922 }
4923
4924 DEFUN (bgp_network_mask_backdoor,
4925 bgp_network_mask_backdoor_cmd,
4926 "network A.B.C.D mask A.B.C.D backdoor",
4927 "Specify a network to announce via BGP\n"
4928 "Network number\n"
4929 "Network mask\n"
4930 "Network mask\n"
4931 "Specify a BGP backdoor route\n")
4932 {
4933 int idx_ipv4 = 1;
4934 int idx_ipv4_2 = 3;
4935 int ret;
4936 char prefix_str[BUFSIZ];
4937
4938 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4939 if (! ret)
4940 {
4941 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4942 return CMD_WARNING;
4943 }
4944
4945 return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
4946 NULL, 1,
4947 BGP_INVALID_LABEL_INDEX);
4948 }
4949
4950 DEFUN (bgp_network_mask_natural,
4951 bgp_network_mask_natural_cmd,
4952 "network A.B.C.D",
4953 "Specify a network to announce via BGP\n"
4954 "Network number\n")
4955 {
4956 int idx_ipv4 = 1;
4957 int ret;
4958 char prefix_str[BUFSIZ];
4959
4960 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4961 if (! ret)
4962 {
4963 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4964 return CMD_WARNING;
4965 }
4966
4967 return bgp_static_set (vty, prefix_str,
4968 AFI_IP, bgp_node_safi (vty), NULL, 0,
4969 BGP_INVALID_LABEL_INDEX);
4970 }
4971
4972 DEFUN (bgp_network_mask_natural_route_map,
4973 bgp_network_mask_natural_route_map_cmd,
4974 "network A.B.C.D route-map WORD",
4975 "Specify a network to announce via BGP\n"
4976 "Network number\n"
4977 "Route-map to modify the attributes\n"
4978 "Name of the route map\n")
4979 {
4980 int idx_ipv4 = 1;
4981 int idx_word = 3;
4982 int ret;
4983 char prefix_str[BUFSIZ];
4984
4985 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4986 if (! ret)
4987 {
4988 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4989 return CMD_WARNING;
4990 }
4991
4992 return bgp_static_set (vty, prefix_str,
4993 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0,
4994 BGP_INVALID_LABEL_INDEX);
4995 }
4996
4997 DEFUN (bgp_network_mask_natural_backdoor,
4998 bgp_network_mask_natural_backdoor_cmd,
4999 "network A.B.C.D backdoor",
5000 "Specify a network to announce via BGP\n"
5001 "Network number\n"
5002 "Specify a BGP backdoor route\n")
5003 {
5004 int idx_ipv4 = 1;
5005 int ret;
5006 char prefix_str[BUFSIZ];
5007
5008 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
5009 if (! ret)
5010 {
5011 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5012 return CMD_WARNING;
5013 }
5014
5015 return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
5016 NULL, 1, BGP_INVALID_LABEL_INDEX);
5017 }
5018
5019 DEFUN (bgp_network_label_index,
5020 bgp_network_label_index_cmd,
5021 "network A.B.C.D/M label-index (0-4294967294)",
5022 "Specify a network to announce via BGP\n"
5023 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5024 "Label index to associate with the prefix\n"
5025 "Label index value\n")
5026 {
5027 u_int32_t label_index;
5028
5029 VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
5030 return bgp_static_set (vty, argv[1]->arg,
5031 AFI_IP, bgp_node_safi (vty), NULL, 0, label_index);
5032 }
5033
5034 DEFUN (bgp_network_label_index_route_map,
5035 bgp_network_label_index_route_map_cmd,
5036 "network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5037 "Specify a network to announce via BGP\n"
5038 "IP prefix\n"
5039 "Label index to associate with the prefix\n"
5040 "Label index value\n"
5041 "Route-map to modify the attributes\n"
5042 "Name of the route map\n")
5043 {
5044 u_int32_t label_index;
5045
5046 VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
5047 return bgp_static_set (vty, argv[1]->arg,
5048 AFI_IP, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
5049 }
5050
5051 DEFUN (no_bgp_network,
5052 no_bgp_network_cmd,
5053 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
5054 NO_STR
5055 "Specify a network to announce via BGP\n"
5056 "IPv4 prefix\n"
5057 "Specify a BGP backdoor route\n"
5058 "Route-map to modify the attributes\n"
5059 "Name of the route map\n")
5060 {
5061 int idx_ipv4_prefixlen = 2;
5062 return bgp_static_unset (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
5063 bgp_node_safi (vty));
5064 }
5065
5066 DEFUN (no_bgp_network_mask,
5067 no_bgp_network_mask_cmd,
5068 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
5069 NO_STR
5070 "Specify a network to announce via BGP\n"
5071 "Network number\n"
5072 "Network mask\n"
5073 "Network mask\n"
5074 "Specify a BGP backdoor route\n"
5075 "Route-map to modify the attributes\n"
5076 "Name of the route map\n")
5077 {
5078 int idx_ipv4 = 2;
5079 int idx_ipv4_2 = 4;
5080 int ret;
5081 char prefix_str[BUFSIZ];
5082
5083 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
5084 if (! ret)
5085 {
5086 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5087 return CMD_WARNING;
5088 }
5089
5090 return bgp_static_unset (vty, prefix_str, AFI_IP,
5091 bgp_node_safi (vty));
5092 }
5093
5094 DEFUN (no_bgp_network_mask_natural,
5095 no_bgp_network_mask_natural_cmd,
5096 "no network A.B.C.D [<backdoor|route-map WORD>]",
5097 NO_STR
5098 "Specify a network to announce via BGP\n"
5099 "Network number\n"
5100 "Specify a BGP backdoor route\n"
5101 "Route-map to modify the attributes\n"
5102 "Name of the route map\n")
5103 {
5104 int idx_ipv4 = 2;
5105 int ret;
5106 char prefix_str[BUFSIZ];
5107
5108 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
5109 if (! ret)
5110 {
5111 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5112 return CMD_WARNING;
5113 }
5114
5115 return bgp_static_unset (vty, prefix_str, AFI_IP,
5116 bgp_node_safi (vty));
5117 }
5118
5119 ALIAS (no_bgp_network,
5120 no_bgp_network_label_index_cmd,
5121 "no network A.B.C.D/M label-index (0-4294967294)",
5122 NO_STR
5123 "Specify a network to announce via BGP\n"
5124 "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
5125 "Label index to associate with the prefix\n"
5126 "Label index value\n")
5127
5128 ALIAS (no_bgp_network,
5129 no_bgp_network_label_index_route_map_cmd,
5130 "no network A.B.C.D/M label-index (0-4294967294) route-map WORD",
5131 NO_STR
5132 "Specify a network to announce via BGP\n"
5133 "IP prefix\n"
5134 "Label index to associate with the prefix\n"
5135 "Label index value\n"
5136 "Route-map to modify the attributes\n"
5137 "Name of the route map\n")
5138
5139 DEFUN (ipv6_bgp_network,
5140 ipv6_bgp_network_cmd,
5141 "network X:X::X:X/M",
5142 "Specify a network to announce via BGP\n"
5143 "IPv6 prefix\n")
5144 {
5145 int idx_ipv6_prefixlen = 1;
5146 return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
5147 NULL, 0,
5148 BGP_INVALID_LABEL_INDEX);
5149 }
5150
5151 DEFUN (ipv6_bgp_network_route_map,
5152 ipv6_bgp_network_route_map_cmd,
5153 "network X:X::X:X/M route-map WORD",
5154 "Specify a network to announce via BGP\n"
5155 "IPv6 prefix\n"
5156 "Route-map to modify the attributes\n"
5157 "Name of the route map\n")
5158 {
5159 int idx_ipv6_prefixlen = 1;
5160 int idx_word = 3;
5161 return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
5162 bgp_node_safi (vty), argv[idx_word]->arg, 0,
5163 BGP_INVALID_LABEL_INDEX);
5164 }
5165
5166 DEFUN (ipv6_bgp_network_label_index,
5167 ipv6_bgp_network_label_index_cmd,
5168 "network X:X::X:X/M label-index (0-4294967294)",
5169 "Specify a network to announce via BGP\n"
5170 "IPv6 prefix <network>/<length>\n"
5171 "Label index to associate with the prefix\n"
5172 "Label index value\n")
5173 {
5174 u_int32_t label_index;
5175
5176 VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
5177 return bgp_static_set (vty, argv[1]->arg,
5178 AFI_IP6, bgp_node_safi (vty), NULL, 0, label_index);
5179 }
5180
5181 DEFUN (ipv6_bgp_network_label_index_route_map,
5182 ipv6_bgp_network_label_index_route_map_cmd,
5183 "network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5184 "Specify a network to announce via BGP\n"
5185 "IPv6 prefix\n"
5186 "Label index to associate with the prefix\n"
5187 "Label index value\n"
5188 "Route-map to modify the attributes\n"
5189 "Name of the route map\n")
5190 {
5191 u_int32_t label_index;
5192
5193 VTY_GET_INTEGER ("label-index", label_index, argv[3]->arg);
5194 return bgp_static_set (vty, argv[1]->arg,
5195 AFI_IP6, bgp_node_safi (vty), argv[5]->arg, 0, label_index);
5196 }
5197
5198 DEFUN (no_ipv6_bgp_network,
5199 no_ipv6_bgp_network_cmd,
5200 "no network X:X::X:X/M [route-map WORD]",
5201 NO_STR
5202 "Specify a network to announce via BGP\n"
5203 "IPv6 prefix\n"
5204 "Route-map to modify the attributes\n"
5205 "Name of the route map\n")
5206 {
5207 int idx_ipv6_prefixlen = 2;
5208 return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
5209 }
5210
5211 ALIAS (no_ipv6_bgp_network,
5212 no_ipv6_bgp_network_label_index_cmd,
5213 "no network X:X::X:X/M label-index (0-4294967294)",
5214 NO_STR
5215 "Specify a network to announce via BGP\n"
5216 "IPv6 prefix <network>/<length>\n"
5217 "Label index to associate with the prefix\n"
5218 "Label index value\n")
5219
5220 ALIAS (no_ipv6_bgp_network,
5221 no_ipv6_bgp_network_label_index_route_map_cmd,
5222 "no network X:X::X:X/M label-index (0-4294967294) route-map WORD",
5223 NO_STR
5224 "Specify a network to announce via BGP\n"
5225 "IPv6 prefix\n"
5226 "Label index to associate with the prefix\n"
5227 "Label index value\n"
5228 "Route-map to modify the attributes\n"
5229 "Name of the route map\n")
5230
5231 /* Aggreagete address:
5232
5233 advertise-map Set condition to advertise attribute
5234 as-set Generate AS set path information
5235 attribute-map Set attributes of aggregate
5236 route-map Set parameters of aggregate
5237 summary-only Filter more specific routes from updates
5238 suppress-map Conditionally filter more specific routes from updates
5239 <cr>
5240 */
5241 struct bgp_aggregate
5242 {
5243 /* Summary-only flag. */
5244 u_char summary_only;
5245
5246 /* AS set generation. */
5247 u_char as_set;
5248
5249 /* Route-map for aggregated route. */
5250 struct route_map *map;
5251
5252 /* Suppress-count. */
5253 unsigned long count;
5254
5255 /* SAFI configuration. */
5256 safi_t safi;
5257 };
5258
5259 static struct bgp_aggregate *
5260 bgp_aggregate_new (void)
5261 {
5262 return XCALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
5263 }
5264
5265 static void
5266 bgp_aggregate_free (struct bgp_aggregate *aggregate)
5267 {
5268 XFREE (MTYPE_BGP_AGGREGATE, aggregate);
5269 }
5270
5271 /* Update an aggregate as routes are added/removed from the BGP table */
5272 static void
5273 bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
5274 afi_t afi, safi_t safi, struct bgp_info *del,
5275 struct bgp_aggregate *aggregate)
5276 {
5277 struct bgp_table *table;
5278 struct bgp_node *top;
5279 struct bgp_node *rn;
5280 u_char origin;
5281 struct aspath *aspath = NULL;
5282 struct aspath *asmerge = NULL;
5283 struct community *community = NULL;
5284 struct community *commerge = NULL;
5285 #if defined(AGGREGATE_NEXTHOP_CHECK)
5286 struct in_addr nexthop;
5287 u_int32_t med = 0;
5288 #endif
5289 struct bgp_info *ri;
5290 struct bgp_info *new;
5291 int first = 1;
5292 unsigned long match = 0;
5293 u_char atomic_aggregate = 0;
5294
5295 /* Record adding route's nexthop and med. */
5296 if (rinew)
5297 {
5298 #if defined(AGGREGATE_NEXTHOP_CHECK)
5299 nexthop = rinew->attr->nexthop;
5300 med = rinew->attr->med;
5301 #endif
5302 }
5303
5304 /* ORIGIN attribute: If at least one route among routes that are
5305 aggregated has ORIGIN with the value INCOMPLETE, then the
5306 aggregated route must have the ORIGIN attribute with the value
5307 INCOMPLETE. Otherwise, if at least one route among routes that
5308 are aggregated has ORIGIN with the value EGP, then the aggregated
5309 route must have the origin attribute with the value EGP. In all
5310 other case the value of the ORIGIN attribute of the aggregated
5311 route is INTERNAL. */
5312 origin = BGP_ORIGIN_IGP;
5313
5314 table = bgp->rib[afi][safi];
5315
5316 top = bgp_node_get (table, p);
5317 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5318 if (rn->p.prefixlen > p->prefixlen)
5319 {
5320 match = 0;
5321
5322 for (ri = rn->info; ri; ri = ri->next)
5323 {
5324 if (BGP_INFO_HOLDDOWN (ri))
5325 continue;
5326
5327 if (del && ri == del)
5328 continue;
5329
5330 if (! rinew && first)
5331 {
5332 #if defined(AGGREGATE_NEXTHOP_CHECK)
5333 nexthop = ri->attr->nexthop;
5334 med = ri->attr->med;
5335 #endif
5336 first = 0;
5337 }
5338
5339 #ifdef AGGREGATE_NEXTHOP_CHECK
5340 if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
5341 || ri->attr->med != med)
5342 {
5343 if (aspath)
5344 aspath_free (aspath);
5345 if (community)
5346 community_free (community);
5347 bgp_unlock_node (rn);
5348 bgp_unlock_node (top);
5349 return;
5350 }
5351 #endif /* AGGREGATE_NEXTHOP_CHECK */
5352
5353 if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5354 atomic_aggregate = 1;
5355
5356 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5357 {
5358 if (aggregate->summary_only)
5359 {
5360 (bgp_info_extra_get (ri))->suppress++;
5361 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5362 match++;
5363 }
5364
5365 aggregate->count++;
5366
5367 if (origin < ri->attr->origin)
5368 origin = ri->attr->origin;
5369
5370 if (aggregate->as_set)
5371 {
5372 if (aspath)
5373 {
5374 asmerge = aspath_aggregate (aspath, ri->attr->aspath);
5375 aspath_free (aspath);
5376 aspath = asmerge;
5377 }
5378 else
5379 aspath = aspath_dup (ri->attr->aspath);
5380
5381 if (ri->attr->community)
5382 {
5383 if (community)
5384 {
5385 commerge = community_merge (community,
5386 ri->attr->community);
5387 community = community_uniq_sort (commerge);
5388 community_free (commerge);
5389 }
5390 else
5391 community = community_dup (ri->attr->community);
5392 }
5393 }
5394 }
5395 }
5396 if (match)
5397 bgp_process (bgp, rn, afi, safi);
5398 }
5399 bgp_unlock_node (top);
5400
5401 if (rinew)
5402 {
5403 aggregate->count++;
5404
5405 if (aggregate->summary_only)
5406 (bgp_info_extra_get (rinew))->suppress++;
5407
5408 if (origin < rinew->attr->origin)
5409 origin = rinew->attr->origin;
5410
5411 if (aggregate->as_set)
5412 {
5413 if (aspath)
5414 {
5415 asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
5416 aspath_free (aspath);
5417 aspath = asmerge;
5418 }
5419 else
5420 aspath = aspath_dup (rinew->attr->aspath);
5421
5422 if (rinew->attr->community)
5423 {
5424 if (community)
5425 {
5426 commerge = community_merge (community,
5427 rinew->attr->community);
5428 community = community_uniq_sort (commerge);
5429 community_free (commerge);
5430 }
5431 else
5432 community = community_dup (rinew->attr->community);
5433 }
5434 }
5435 }
5436
5437 if (aggregate->count > 0)
5438 {
5439 rn = bgp_node_get (table, p);
5440 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5441 bgp_attr_aggregate_intern(bgp, origin, aspath, community,
5442 aggregate->as_set,
5443 atomic_aggregate), rn);
5444 SET_FLAG (new->flags, BGP_INFO_VALID);
5445
5446 bgp_info_add (rn, new);
5447 bgp_unlock_node (rn);
5448 bgp_process (bgp, rn, afi, safi);
5449 }
5450 else
5451 {
5452 if (aspath)
5453 aspath_free (aspath);
5454 if (community)
5455 community_free (community);
5456 }
5457 }
5458
5459 void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
5460 struct bgp_aggregate *);
5461
5462 void
5463 bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
5464 struct bgp_info *ri, afi_t afi, safi_t safi)
5465 {
5466 struct bgp_node *child;
5467 struct bgp_node *rn;
5468 struct bgp_aggregate *aggregate;
5469 struct bgp_table *table;
5470
5471 /* MPLS-VPN aggregation is not yet supported. */
5472 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
5473 return;
5474
5475 table = bgp->aggregate[afi][safi];
5476
5477 /* No aggregates configured. */
5478 if (bgp_table_top_nolock (table) == NULL)
5479 return;
5480
5481 if (p->prefixlen == 0)
5482 return;
5483
5484 if (BGP_INFO_HOLDDOWN (ri))
5485 return;
5486
5487 child = bgp_node_get (table, p);
5488
5489 /* Aggregate address configuration check. */
5490 for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
5491 if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
5492 {
5493 bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
5494 bgp_aggregate_route (bgp, &rn->p, ri, afi, safi, NULL, aggregate);
5495 }
5496 bgp_unlock_node (child);
5497 }
5498
5499 void
5500 bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
5501 struct bgp_info *del, afi_t afi, safi_t safi)
5502 {
5503 struct bgp_node *child;
5504 struct bgp_node *rn;
5505 struct bgp_aggregate *aggregate;
5506 struct bgp_table *table;
5507
5508 /* MPLS-VPN aggregation is not yet supported. */
5509 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
5510 return;
5511
5512 table = bgp->aggregate[afi][safi];
5513
5514 /* No aggregates configured. */
5515 if (bgp_table_top_nolock (table) == NULL)
5516 return;
5517
5518 if (p->prefixlen == 0)
5519 return;
5520
5521 child = bgp_node_get (table, p);
5522
5523 /* Aggregate address configuration check. */
5524 for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
5525 if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
5526 {
5527 bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
5528 bgp_aggregate_route (bgp, &rn->p, NULL, afi, safi, del, aggregate);
5529 }
5530 bgp_unlock_node (child);
5531 }
5532
5533 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5534 static void
5535 bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
5536 struct bgp_aggregate *aggregate)
5537 {
5538 struct bgp_table *table;
5539 struct bgp_node *top;
5540 struct bgp_node *rn;
5541 struct bgp_info *new;
5542 struct bgp_info *ri;
5543 unsigned long match;
5544 u_char origin = BGP_ORIGIN_IGP;
5545 struct aspath *aspath = NULL;
5546 struct aspath *asmerge = NULL;
5547 struct community *community = NULL;
5548 struct community *commerge = NULL;
5549 u_char atomic_aggregate = 0;
5550
5551 table = bgp->rib[afi][safi];
5552
5553 /* Sanity check. */
5554 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5555 return;
5556 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5557 return;
5558
5559 /* If routes exists below this node, generate aggregate routes. */
5560 top = bgp_node_get (table, p);
5561 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5562 if (rn->p.prefixlen > p->prefixlen)
5563 {
5564 match = 0;
5565
5566 for (ri = rn->info; ri; ri = ri->next)
5567 {
5568 if (BGP_INFO_HOLDDOWN (ri))
5569 continue;
5570
5571 if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5572 atomic_aggregate = 1;
5573
5574 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5575 {
5576 /* summary-only aggregate route suppress aggregated
5577 route announcement. */
5578 if (aggregate->summary_only)
5579 {
5580 (bgp_info_extra_get (ri))->suppress++;
5581 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5582 match++;
5583 }
5584
5585 /* If at least one route among routes that are aggregated has
5586 * ORIGIN with the value INCOMPLETE, then the aggregated route
5587 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5588 * Otherwise, if at least one route among routes that are
5589 * aggregated has ORIGIN with the value EGP, then the aggregated
5590 * route MUST have the ORIGIN attribute with the value EGP.
5591 */
5592 if (origin < ri->attr->origin)
5593 origin = ri->attr->origin;
5594
5595 /* as-set aggregate route generate origin, as path,
5596 community aggregation. */
5597 if (aggregate->as_set)
5598 {
5599 if (aspath)
5600 {
5601 asmerge = aspath_aggregate (aspath, ri->attr->aspath);
5602 aspath_free (aspath);
5603 aspath = asmerge;
5604 }
5605 else
5606 aspath = aspath_dup (ri->attr->aspath);
5607
5608 if (ri->attr->community)
5609 {
5610 if (community)
5611 {
5612 commerge = community_merge (community,
5613 ri->attr->community);
5614 community = community_uniq_sort (commerge);
5615 community_free (commerge);
5616 }
5617 else
5618 community = community_dup (ri->attr->community);
5619 }
5620 }
5621 aggregate->count++;
5622 }
5623 }
5624
5625 /* If this node is suppressed, process the change. */
5626 if (match)
5627 bgp_process (bgp, rn, afi, safi);
5628 }
5629 bgp_unlock_node (top);
5630
5631 /* Add aggregate route to BGP table. */
5632 if (aggregate->count)
5633 {
5634 rn = bgp_node_get (table, p);
5635 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5636 bgp_attr_aggregate_intern(bgp, origin, aspath, community,
5637 aggregate->as_set,
5638 atomic_aggregate), rn);
5639 SET_FLAG (new->flags, BGP_INFO_VALID);
5640
5641 bgp_info_add (rn, new);
5642 bgp_unlock_node (rn);
5643
5644 /* Process change. */
5645 bgp_process (bgp, rn, afi, safi);
5646 }
5647 else
5648 {
5649 if (aspath)
5650 aspath_free (aspath);
5651 if (community)
5652 community_free (community);
5653 }
5654 }
5655
5656 void
5657 bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
5658 safi_t safi, struct bgp_aggregate *aggregate)
5659 {
5660 struct bgp_table *table;
5661 struct bgp_node *top;
5662 struct bgp_node *rn;
5663 struct bgp_info *ri;
5664 unsigned long match;
5665
5666 table = bgp->rib[afi][safi];
5667
5668 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5669 return;
5670 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5671 return;
5672
5673 /* If routes exists below this node, generate aggregate routes. */
5674 top = bgp_node_get (table, p);
5675 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5676 if (rn->p.prefixlen > p->prefixlen)
5677 {
5678 match = 0;
5679
5680 for (ri = rn->info; ri; ri = ri->next)
5681 {
5682 if (BGP_INFO_HOLDDOWN (ri))
5683 continue;
5684
5685 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5686 {
5687 if (aggregate->summary_only && ri->extra)
5688 {
5689 ri->extra->suppress--;
5690
5691 if (ri->extra->suppress == 0)
5692 {
5693 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5694 match++;
5695 }
5696 }
5697 aggregate->count--;
5698 }
5699 }
5700
5701 /* If this node was suppressed, process the change. */
5702 if (match)
5703 bgp_process (bgp, rn, afi, safi);
5704 }
5705 bgp_unlock_node (top);
5706
5707 /* Delete aggregate route from BGP table. */
5708 rn = bgp_node_get (table, p);
5709
5710 for (ri = rn->info; ri; ri = ri->next)
5711 if (ri->peer == bgp->peer_self
5712 && ri->type == ZEBRA_ROUTE_BGP
5713 && ri->sub_type == BGP_ROUTE_AGGREGATE)
5714 break;
5715
5716 /* Withdraw static BGP route from routing table. */
5717 if (ri)
5718 {
5719 bgp_info_delete (rn, ri);
5720 bgp_process (bgp, rn, afi, safi);
5721 }
5722
5723 /* Unlock bgp_node_lookup. */
5724 bgp_unlock_node (rn);
5725 }
5726
5727 /* Aggregate route attribute. */
5728 #define AGGREGATE_SUMMARY_ONLY 1
5729 #define AGGREGATE_AS_SET 1
5730
5731 static int
5732 bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
5733 afi_t afi, safi_t safi)
5734 {
5735 VTY_DECLVAR_CONTEXT(bgp, bgp);
5736 int ret;
5737 struct prefix p;
5738 struct bgp_node *rn;
5739 struct bgp_aggregate *aggregate;
5740
5741 /* Convert string to prefix structure. */
5742 ret = str2prefix (prefix_str, &p);
5743 if (!ret)
5744 {
5745 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
5746 return CMD_WARNING;
5747 }
5748 apply_mask (&p);
5749
5750 /* Old configuration check. */
5751 rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
5752 if (! rn)
5753 {
5754 vty_out (vty, "%% There is no aggregate-address configuration.%s",
5755 VTY_NEWLINE);
5756 return CMD_WARNING;
5757 }
5758
5759 aggregate = rn->info;
5760 if (aggregate->safi & SAFI_UNICAST)
5761 bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
5762 if (aggregate->safi & SAFI_LABELED_UNICAST)
5763 bgp_aggregate_delete (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
5764 if (aggregate->safi & SAFI_MULTICAST)
5765 bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
5766
5767 /* Unlock aggregate address configuration. */
5768 rn->info = NULL;
5769 bgp_aggregate_free (aggregate);
5770 bgp_unlock_node (rn);
5771 bgp_unlock_node (rn);
5772
5773 return CMD_SUCCESS;
5774 }
5775
5776 static int
5777 bgp_aggregate_set (struct vty *vty, const char *prefix_str,
5778 afi_t afi, safi_t safi,
5779 u_char summary_only, u_char as_set)
5780 {
5781 VTY_DECLVAR_CONTEXT(bgp, bgp);
5782 int ret;
5783 struct prefix p;
5784 struct bgp_node *rn;
5785 struct bgp_aggregate *aggregate;
5786
5787 /* Convert string to prefix structure. */
5788 ret = str2prefix (prefix_str, &p);
5789 if (!ret)
5790 {
5791 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
5792 return CMD_WARNING;
5793 }
5794 apply_mask (&p);
5795
5796 /* Old configuration check. */
5797 rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
5798
5799 if (rn->info)
5800 {
5801 vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
5802 /* try to remove the old entry */
5803 ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
5804 if (ret)
5805 {
5806 vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
5807 bgp_unlock_node (rn);
5808 return CMD_WARNING;
5809 }
5810 }
5811
5812 /* Make aggregate address structure. */
5813 aggregate = bgp_aggregate_new ();
5814 aggregate->summary_only = summary_only;
5815 aggregate->as_set = as_set;
5816 aggregate->safi = safi;
5817 rn->info = aggregate;
5818
5819 /* Aggregate address insert into BGP routing table. */
5820 if (safi & SAFI_UNICAST)
5821 bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
5822 if (safi & SAFI_LABELED_UNICAST)
5823 bgp_aggregate_add (bgp, &p, afi, SAFI_LABELED_UNICAST, aggregate);
5824 if (safi & SAFI_MULTICAST)
5825 bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
5826
5827 return CMD_SUCCESS;
5828 }
5829
5830 DEFUN (aggregate_address,
5831 aggregate_address_cmd,
5832 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5833 "Configure BGP aggregate entries\n"
5834 "Aggregate prefix\n"
5835 "Generate AS set path information\n"
5836 "Filter more specific routes from updates\n"
5837 "Filter more specific routes from updates\n"
5838 "Generate AS set path information\n")
5839 {
5840 int idx = 0;
5841 argv_find (argv, argc, "A.B.C.D/M", &idx);
5842 char *prefix = argv[idx]->arg;
5843 int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5844 idx = 0;
5845 int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5846
5847 return bgp_aggregate_set (vty, prefix, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
5848 }
5849
5850 DEFUN (aggregate_address_mask,
5851 aggregate_address_mask_cmd,
5852 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5853 "Configure BGP aggregate entries\n"
5854 "Aggregate address\n"
5855 "Aggregate mask\n"
5856 "Generate AS set path information\n"
5857 "Filter more specific routes from updates\n"
5858 "Filter more specific routes from updates\n"
5859 "Generate AS set path information\n")
5860 {
5861 int idx = 0;
5862 argv_find (argv, argc, "A.B.C.D", &idx);
5863 char *prefix = argv[idx++]->arg;
5864 argv_find (argv, argc, "A.B.C.D", &idx);
5865 char *mask = argv[idx]->arg;
5866 int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5867 idx = 0;
5868 int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5869
5870 char prefix_str[BUFSIZ];
5871 int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
5872
5873 if (! ret)
5874 {
5875 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5876 return CMD_WARNING;
5877 }
5878
5879 return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
5880 }
5881
5882 DEFUN (no_aggregate_address,
5883 no_aggregate_address_cmd,
5884 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5885 NO_STR
5886 "Configure BGP aggregate entries\n"
5887 "Aggregate prefix\n"
5888 "Generate AS set path information\n"
5889 "Filter more specific routes from updates\n"
5890 "Filter more specific routes from updates\n"
5891 "Generate AS set path information\n")
5892 {
5893 int idx = 0;
5894 argv_find (argv, argc, "A.B.C.D/M", &idx);
5895 char *prefix = argv[idx]->arg;
5896 return bgp_aggregate_unset (vty, prefix, AFI_IP, bgp_node_safi (vty));
5897 }
5898
5899 DEFUN (no_aggregate_address_mask,
5900 no_aggregate_address_mask_cmd,
5901 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5902 NO_STR
5903 "Configure BGP aggregate entries\n"
5904 "Aggregate address\n"
5905 "Aggregate mask\n"
5906 "Generate AS set path information\n"
5907 "Filter more specific routes from updates\n"
5908 "Filter more specific routes from updates\n"
5909 "Generate AS set path information\n")
5910 {
5911 int idx = 0;
5912 argv_find (argv, argc, "A.B.C.D", &idx);
5913 char *prefix = argv[idx++]->arg;
5914 argv_find (argv, argc, "A.B.C.D", &idx);
5915 char *mask = argv[idx]->arg;
5916
5917 char prefix_str[BUFSIZ];
5918 int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
5919
5920 if (! ret)
5921 {
5922 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5923 return CMD_WARNING;
5924 }
5925
5926 return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
5927 }
5928
5929 DEFUN (ipv6_aggregate_address,
5930 ipv6_aggregate_address_cmd,
5931 "aggregate-address X:X::X:X/M [summary-only]",
5932 "Configure BGP aggregate entries\n"
5933 "Aggregate prefix\n"
5934 "Filter more specific routes from updates\n")
5935 {
5936 int idx = 0;
5937 argv_find (argv, argc, "X:X::X:X/M", &idx);
5938 char *prefix = argv[idx]->arg;
5939 int sum_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5940 return bgp_aggregate_set (vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only, 0);
5941 }
5942
5943 DEFUN (no_ipv6_aggregate_address,
5944 no_ipv6_aggregate_address_cmd,
5945 "no aggregate-address X:X::X:X/M [summary-only]",
5946 NO_STR
5947 "Configure BGP aggregate entries\n"
5948 "Aggregate prefix\n"
5949 "Filter more specific routes from updates\n")
5950 {
5951 int idx = 0;
5952 argv_find (argv, argc, "X:X::X:X/M", &idx);
5953 char *prefix = argv[idx]->arg;
5954 return bgp_aggregate_unset (vty, prefix, AFI_IP6, SAFI_UNICAST);
5955 }
5956
5957 /* Redistribute route treatment. */
5958 void
5959 bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
5960 const struct in6_addr *nexthop6, unsigned int ifindex,
5961 u_int32_t metric, u_char type, u_short instance, route_tag_t tag)
5962 {
5963 struct bgp_info *new;
5964 struct bgp_info *bi;
5965 struct bgp_info info;
5966 struct bgp_node *bn;
5967 struct attr attr;
5968 struct attr *new_attr;
5969 afi_t afi;
5970 int ret;
5971 struct bgp_redist *red;
5972
5973 /* Make default attribute. */
5974 bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
5975 if (nexthop)
5976 attr.nexthop = *nexthop;
5977 attr.nh_ifindex = ifindex;
5978
5979 if (nexthop6)
5980 {
5981 struct attr_extra *extra = bgp_attr_extra_get(&attr);
5982 extra->mp_nexthop_global = *nexthop6;
5983 extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
5984 }
5985
5986 attr.med = metric;
5987 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
5988 attr.extra->tag = tag;
5989
5990 afi = family2afi (p->family);
5991
5992 red = bgp_redist_lookup(bgp, afi, type, instance);
5993 if (red)
5994 {
5995 struct attr attr_new;
5996 struct attr_extra extra_new;
5997
5998 /* Copy attribute for modification. */
5999 attr_new.extra = &extra_new;
6000 bgp_attr_dup (&attr_new, &attr);
6001
6002 if (red->redist_metric_flag)
6003 attr_new.med = red->redist_metric;
6004
6005 /* Apply route-map. */
6006 if (red->rmap.name)
6007 {
6008 info.peer = bgp->peer_self;
6009 info.attr = &attr_new;
6010
6011 SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
6012
6013 ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
6014
6015 bgp->peer_self->rmap_type = 0;
6016
6017 if (ret == RMAP_DENYMATCH)
6018 {
6019 /* Free uninterned attribute. */
6020 bgp_attr_flush (&attr_new);
6021
6022 /* Unintern original. */
6023 aspath_unintern (&attr.aspath);
6024 bgp_attr_extra_free (&attr);
6025 bgp_redistribute_delete (bgp, p, type, instance);
6026 return;
6027 }
6028 }
6029
6030 bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
6031 afi, SAFI_UNICAST, p, NULL);
6032
6033 new_attr = bgp_attr_intern (&attr_new);
6034
6035 for (bi = bn->info; bi; bi = bi->next)
6036 if (bi->peer == bgp->peer_self
6037 && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
6038 break;
6039
6040 if (bi)
6041 {
6042 /* Ensure the (source route) type is updated. */
6043 bi->type = type;
6044 if (attrhash_cmp (bi->attr, new_attr) &&
6045 !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
6046 {
6047 bgp_attr_unintern (&new_attr);
6048 aspath_unintern (&attr.aspath);
6049 bgp_attr_extra_free (&attr);
6050 bgp_unlock_node (bn);
6051 return;
6052 }
6053 else
6054 {
6055 /* The attribute is changed. */
6056 bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
6057
6058 /* Rewrite BGP route information. */
6059 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
6060 bgp_info_restore(bn, bi);
6061 else
6062 bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
6063 bgp_attr_unintern (&bi->attr);
6064 bi->attr = new_attr;
6065 bi->uptime = bgp_clock ();
6066
6067 /* Process change. */
6068 bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
6069 bgp_process (bgp, bn, afi, SAFI_UNICAST);
6070 bgp_unlock_node (bn);
6071 aspath_unintern (&attr.aspath);
6072 bgp_attr_extra_free (&attr);
6073 return;
6074 }
6075 }
6076
6077 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance, bgp->peer_self,
6078 new_attr, bn);
6079 SET_FLAG (new->flags, BGP_INFO_VALID);
6080
6081 bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
6082 bgp_info_add (bn, new);
6083 bgp_unlock_node (bn);
6084 bgp_process (bgp, bn, afi, SAFI_UNICAST);
6085 }
6086
6087 /* Unintern original. */
6088 aspath_unintern (&attr.aspath);
6089 bgp_attr_extra_free (&attr);
6090 }
6091
6092 void
6093 bgp_redistribute_delete (struct bgp *bgp, struct prefix *p, u_char type, u_short instance)
6094 {
6095 afi_t afi;
6096 struct bgp_node *rn;
6097 struct bgp_info *ri;
6098 struct bgp_redist *red;
6099
6100 afi = family2afi (p->family);
6101
6102 red = bgp_redist_lookup(bgp, afi, type, instance);
6103 if (red)
6104 {
6105 rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
6106
6107 for (ri = rn->info; ri; ri = ri->next)
6108 if (ri->peer == bgp->peer_self
6109 && ri->type == type)
6110 break;
6111
6112 if (ri)
6113 {
6114 bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
6115 bgp_info_delete (rn, ri);
6116 bgp_process (bgp, rn, afi, SAFI_UNICAST);
6117 }
6118 bgp_unlock_node (rn);
6119 }
6120 }
6121
6122 /* Withdraw specified route type's route. */
6123 void
6124 bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type, u_short instance)
6125 {
6126 struct bgp_node *rn;
6127 struct bgp_info *ri;
6128 struct bgp_table *table;
6129
6130 table = bgp->rib[afi][SAFI_UNICAST];
6131
6132 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
6133 {
6134 for (ri = rn->info; ri; ri = ri->next)
6135 if (ri->peer == bgp->peer_self
6136 && ri->type == type
6137 && ri->instance == instance)
6138 break;
6139
6140 if (ri)
6141 {
6142 bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
6143 bgp_info_delete (rn, ri);
6144 bgp_process (bgp, rn, afi, SAFI_UNICAST);
6145 }
6146 }
6147 }
6148
6149 /* Static function to display route. */
6150 static void
6151 route_vty_out_route (struct prefix *p, struct vty *vty)
6152 {
6153 int len;
6154 u_int32_t destination;
6155 char buf[BUFSIZ];
6156
6157 if (p->family == AF_INET)
6158 {
6159 len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
6160 destination = ntohl (p->u.prefix4.s_addr);
6161
6162 if ((IN_CLASSC (destination) && p->prefixlen == 24)
6163 || (IN_CLASSB (destination) && p->prefixlen == 16)
6164 || (IN_CLASSA (destination) && p->prefixlen == 8)
6165 || p->u.prefix4.s_addr == 0)
6166 {
6167 /* When mask is natural, mask is not displayed. */
6168 }
6169 else
6170 len += vty_out (vty, "/%d", p->prefixlen);
6171 }
6172 else if (p->family == AF_ETHERNET)
6173 {
6174 prefix2str(p, buf, PREFIX_STRLEN);
6175 len = vty_out (vty, "%s", buf);
6176 }
6177 else
6178 len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
6179 p->prefixlen);
6180
6181 len = 17 - len;
6182 if (len < 1)
6183 vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
6184 else
6185 vty_out (vty, "%*s", len, " ");
6186 }
6187
6188 enum bgp_display_type
6189 {
6190 normal_list,
6191 };
6192
6193 /* Print the short form route status for a bgp_info */
6194 static void
6195 route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo,
6196 json_object *json_path)
6197 {
6198 if (json_path)
6199 {
6200
6201 /* Route status display. */
6202 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
6203 json_object_boolean_true_add(json_path, "removed");
6204
6205 if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
6206 json_object_boolean_true_add(json_path, "stale");
6207
6208 if (binfo->extra && binfo->extra->suppress)
6209 json_object_boolean_true_add(json_path, "suppressed");
6210
6211 if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
6212 ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6213 json_object_boolean_true_add(json_path, "valid");
6214
6215 /* Selected */
6216 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6217 json_object_boolean_true_add(json_path, "history");
6218
6219 if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
6220 json_object_boolean_true_add(json_path, "damped");
6221
6222 if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
6223 json_object_boolean_true_add(json_path, "bestpath");
6224
6225 if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
6226 json_object_boolean_true_add(json_path, "multipath");
6227
6228 /* Internal route. */
6229 if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
6230 json_object_string_add(json_path, "pathFrom", "internal");
6231 else
6232 json_object_string_add(json_path, "pathFrom", "external");
6233
6234 return;
6235 }
6236
6237 /* Route status display. */
6238 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
6239 vty_out (vty, "R");
6240 else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
6241 vty_out (vty, "S");
6242 else if (binfo->extra && binfo->extra->suppress)
6243 vty_out (vty, "s");
6244 else if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
6245 ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6246 vty_out (vty, "*");
6247 else
6248 vty_out (vty, " ");
6249
6250 /* Selected */
6251 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6252 vty_out (vty, "h");
6253 else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
6254 vty_out (vty, "d");
6255 else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
6256 vty_out (vty, ">");
6257 else if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
6258 vty_out (vty, "=");
6259 else
6260 vty_out (vty, " ");
6261
6262 /* Internal route. */
6263 if (binfo->peer &&
6264 (binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
6265 vty_out (vty, "i");
6266 else
6267 vty_out (vty, " ");
6268 }
6269
6270 /* called from terminal list command */
6271 void
6272 route_vty_out (struct vty *vty, struct prefix *p,
6273 struct bgp_info *binfo, int display, safi_t safi,
6274 json_object *json_paths)
6275 {
6276 struct attr *attr;
6277 json_object *json_path = NULL;
6278 json_object *json_nexthops = NULL;
6279 json_object *json_nexthop_global = NULL;
6280 json_object *json_nexthop_ll = NULL;
6281
6282 if (json_paths)
6283 json_path = json_object_new_object();
6284
6285 /* short status lead text */
6286 route_vty_short_status_out (vty, binfo, json_path);
6287
6288 if (!json_paths)
6289 {
6290 /* print prefix and mask */
6291 if (! display)
6292 route_vty_out_route (p, vty);
6293 else
6294 vty_out (vty, "%*s", 17, " ");
6295 }
6296
6297 /* Print attribute */
6298 attr = binfo->attr;
6299 if (attr)
6300 {
6301 /*
6302 * For ENCAP routes, nexthop address family is not
6303 * neccessarily the same as the prefix address family.
6304 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6305 */
6306 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6307 {
6308 if (attr->extra)
6309 {
6310 char buf[BUFSIZ];
6311 int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
6312
6313 switch (af)
6314 {
6315 case AF_INET:
6316 vty_out (vty, "%s", inet_ntop(af,
6317 &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
6318 break;
6319 case AF_INET6:
6320 vty_out (vty, "%s", inet_ntop(af,
6321 &attr->extra->mp_nexthop_global, buf, BUFSIZ));
6322 break;
6323 default:
6324 vty_out(vty, "?");
6325 break;
6326 }
6327 }
6328 else
6329 vty_out(vty, "?");
6330 }
6331 /* IPv4 Next Hop */
6332 else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6333 {
6334 if (json_paths)
6335 {
6336 json_nexthop_global = json_object_new_object();
6337
6338 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6339 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
6340 else
6341 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
6342
6343 json_object_string_add(json_nexthop_global, "afi", "ipv4");
6344 json_object_boolean_true_add(json_nexthop_global, "used");
6345 }
6346 else
6347 {
6348 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6349 vty_out (vty, "%-16s",
6350 inet_ntoa (attr->extra->mp_nexthop_global_in));
6351 else
6352 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6353 }
6354 }
6355
6356 /* IPv6 Next Hop */
6357 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6358 {
6359 int len;
6360 char buf[BUFSIZ];
6361
6362 if (json_paths)
6363 {
6364 json_nexthop_global = json_object_new_object();
6365 json_object_string_add(json_nexthop_global, "ip",
6366 inet_ntop (AF_INET6,
6367 &attr->extra->mp_nexthop_global,
6368 buf, BUFSIZ));
6369 json_object_string_add(json_nexthop_global, "afi", "ipv6");
6370 json_object_string_add(json_nexthop_global, "scope", "global");
6371
6372 /* We display both LL & GL if both have been received */
6373 if ((attr->extra->mp_nexthop_len == 32) || (binfo->peer->conf_if))
6374 {
6375 json_nexthop_ll = json_object_new_object();
6376 json_object_string_add(json_nexthop_ll, "ip",
6377 inet_ntop (AF_INET6,
6378 &attr->extra->mp_nexthop_local,
6379 buf, BUFSIZ));
6380 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
6381 json_object_string_add(json_nexthop_ll, "scope", "link-local");
6382
6383 if ((IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
6384 &attr->extra->mp_nexthop_local) != 0) &&
6385 !attr->extra->mp_nexthop_prefer_global)
6386 json_object_boolean_true_add(json_nexthop_ll, "used");
6387 else
6388 json_object_boolean_true_add(json_nexthop_global, "used");
6389 }
6390 else
6391 json_object_boolean_true_add(json_nexthop_global, "used");
6392 }
6393 else
6394 {
6395 /* Display LL if LL/Global both in table unless prefer-global is set */
6396 if (((attr->extra->mp_nexthop_len == 32) &&
6397 !attr->extra->mp_nexthop_prefer_global) ||
6398 (binfo->peer->conf_if))
6399 {
6400 if (binfo->peer->conf_if)
6401 {
6402 len = vty_out (vty, "%s",
6403 binfo->peer->conf_if);
6404 len = 7 - len; /* len of IPv6 addr + max len of def ifname */
6405
6406 if (len < 1)
6407 vty_out (vty, "%s%*s", VTY_NEWLINE, 45, " ");
6408 else
6409 vty_out (vty, "%*s", len, " ");
6410 }
6411 else
6412 {
6413 len = vty_out (vty, "%s",
6414 inet_ntop (AF_INET6,
6415 &attr->extra->mp_nexthop_local,
6416 buf, BUFSIZ));
6417 len = 16 - len;
6418
6419 if (len < 1)
6420 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6421 else
6422 vty_out (vty, "%*s", len, " ");
6423 }
6424 }
6425 else
6426 {
6427 len = vty_out (vty, "%s",
6428 inet_ntop (AF_INET6,
6429 &attr->extra->mp_nexthop_global,
6430 buf, BUFSIZ));
6431 len = 16 - len;
6432
6433 if (len < 1)
6434 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6435 else
6436 vty_out (vty, "%*s", len, " ");
6437 }
6438 }
6439 }
6440
6441 /* MED/Metric */
6442 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6443 if (json_paths)
6444 json_object_int_add(json_path, "med", attr->med);
6445 else
6446 vty_out (vty, "%10u", attr->med);
6447 else
6448 if (!json_paths)
6449 vty_out (vty, " ");
6450
6451 /* Local Pref */
6452 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6453 if (json_paths)
6454 json_object_int_add(json_path, "localpref", attr->local_pref);
6455 else
6456 vty_out (vty, "%7u", attr->local_pref);
6457 else
6458 if (!json_paths)
6459 vty_out (vty, " ");
6460
6461 if (json_paths)
6462 {
6463 if (attr->extra)
6464 json_object_int_add(json_path, "weight", attr->extra->weight);
6465 else
6466 json_object_int_add(json_path, "weight", 0);
6467 }
6468 else
6469 vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
6470
6471 if (json_paths) {
6472 char buf[BUFSIZ];
6473 json_object_string_add(json_path, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
6474 }
6475
6476 /* Print aspath */
6477 if (attr->aspath)
6478 {
6479 if (json_paths)
6480 json_object_string_add(json_path, "aspath", attr->aspath->str);
6481 else
6482 aspath_print_vty (vty, "%s", attr->aspath, " ");
6483 }
6484
6485 /* Print origin */
6486 if (json_paths)
6487 json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
6488 else
6489 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6490 }
6491 else
6492 {
6493 if (json_paths)
6494 json_object_string_add(json_path, "alert", "No attributes");
6495 else
6496 vty_out (vty, "No attributes to print%s", VTY_NEWLINE);
6497 }
6498
6499 if (json_paths)
6500 {
6501 if (json_nexthop_global || json_nexthop_ll)
6502 {
6503 json_nexthops = json_object_new_array();
6504
6505 if (json_nexthop_global)
6506 json_object_array_add(json_nexthops, json_nexthop_global);
6507
6508 if (json_nexthop_ll)
6509 json_object_array_add(json_nexthops, json_nexthop_ll);
6510
6511 json_object_object_add(json_path, "nexthops", json_nexthops);
6512 }
6513
6514 json_object_array_add(json_paths, json_path);
6515 }
6516 else
6517 {
6518 vty_out (vty, "%s", VTY_NEWLINE);
6519 #if ENABLE_BGP_VNC
6520 /* prints an additional line, indented, with VNC info, if present */
6521 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
6522 rfapi_vty_out_vncinfo(vty, p, binfo, safi);
6523 #endif
6524 }
6525 }
6526
6527 /* called from terminal list command */
6528 void
6529 route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t safi,
6530 u_char use_json, json_object *json_ar)
6531 {
6532 json_object *json_status = NULL;
6533 json_object *json_net = NULL;
6534 char buff[BUFSIZ];
6535 /* Route status display. */
6536 if (use_json)
6537 {
6538 json_status = json_object_new_object();
6539 json_net = json_object_new_object();
6540 }
6541 else
6542 {
6543 vty_out (vty, "*");
6544 vty_out (vty, ">");
6545 vty_out (vty, " ");
6546 }
6547
6548 /* print prefix and mask */
6549 if (use_json)
6550 json_object_string_add(json_net, "addrPrefix", inet_ntop (p->family, &p->u.prefix, buff, BUFSIZ));
6551 else
6552 route_vty_out_route (p, vty);
6553
6554 /* Print attribute */
6555 if (attr)
6556 {
6557 if (use_json)
6558 {
6559 if (p->family == AF_INET &&
6560 (safi == SAFI_MPLS_VPN ||
6561 safi == SAFI_ENCAP ||
6562 safi == SAFI_EVPN ||
6563 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6564 {
6565 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6566 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in));
6567 else
6568 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
6569 }
6570 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6571 {
6572 char buf[BUFSIZ];
6573
6574 json_object_string_add(json_net, "netHopGloabal", inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6575 buf, BUFSIZ));
6576 }
6577
6578 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6579 json_object_int_add(json_net, "metric", attr->med);
6580
6581 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6582 json_object_int_add(json_net, "localPref", attr->local_pref);
6583
6584 if (attr->extra)
6585 json_object_int_add(json_net, "weight", attr->extra->weight);
6586 else
6587 json_object_int_add(json_net, "weight", 0);
6588
6589 /* Print aspath */
6590 if (attr->aspath)
6591 json_object_string_add(json_net, "asPath", attr->aspath->str);
6592
6593 /* Print origin */
6594 json_object_string_add(json_net, "bgpOriginCode", bgp_origin_str[attr->origin]);
6595 }
6596 else
6597 {
6598 if (p->family == AF_INET &&
6599 (safi == SAFI_MPLS_VPN ||
6600 safi == SAFI_ENCAP ||
6601 safi == SAFI_EVPN ||
6602 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6603 {
6604 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6605 vty_out (vty, "%-16s",
6606 inet_ntoa (attr->extra->mp_nexthop_global_in));
6607 else
6608 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6609 }
6610 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6611 {
6612 int len;
6613 char buf[BUFSIZ];
6614
6615 assert (attr->extra);
6616
6617 len = vty_out (vty, "%s",
6618 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6619 buf, BUFSIZ));
6620 len = 16 - len;
6621 if (len < 1)
6622 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6623 else
6624 vty_out (vty, "%*s", len, " ");
6625 }
6626 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6627 vty_out (vty, "%10u", attr->med);
6628 else
6629 vty_out (vty, " ");
6630
6631 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6632 vty_out (vty, "%7u", attr->local_pref);
6633 else
6634 vty_out (vty, " ");
6635
6636 vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
6637
6638 /* Print aspath */
6639 if (attr->aspath)
6640 aspath_print_vty (vty, "%s", attr->aspath, " ");
6641
6642 /* Print origin */
6643 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6644 }
6645 }
6646 if (use_json)
6647 {
6648 json_object_boolean_true_add(json_status, "*");
6649 json_object_boolean_true_add(json_status, ">");
6650 json_object_object_add(json_net, "appliedStatusSymbols", json_status);
6651 char buf_cut[BUFSIZ];
6652 json_object_object_add(json_ar, inet_ntop (p->family, &p->u.prefix, buf_cut, BUFSIZ), json_net);
6653 }
6654 else
6655 vty_out (vty, "%s", VTY_NEWLINE);
6656 }
6657
6658 void
6659 route_vty_out_tag (struct vty *vty, struct prefix *p,
6660 struct bgp_info *binfo, int display, safi_t safi, json_object *json)
6661 {
6662 json_object *json_out = NULL;
6663 struct attr *attr;
6664 u_int32_t label = 0;
6665
6666 if (!binfo->extra)
6667 return;
6668
6669 if (json)
6670 json_out = json_object_new_object();
6671
6672 /* short status lead text */
6673 route_vty_short_status_out (vty, binfo, json_out);
6674
6675 /* print prefix and mask */
6676 if (json == NULL)
6677 {
6678 if (! display)
6679 route_vty_out_route (p, vty);
6680 else
6681 vty_out (vty, "%*s", 17, " ");
6682 }
6683
6684 /* Print attribute */
6685 attr = binfo->attr;
6686 if (attr)
6687 {
6688 if (((p->family == AF_INET) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6689 || (safi == SAFI_EVPN && p->family == AF_ETHERNET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6690 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6691 {
6692 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6693 {
6694 if (json)
6695 json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in));
6696 else
6697 vty_out (vty, "%-16s", inet_ntoa (attr->extra->mp_nexthop_global_in));
6698 }
6699 else
6700 {
6701 if (json)
6702 json_object_string_add(json_out, "nexthop", inet_ntoa (attr->nexthop));
6703 else
6704 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6705 }
6706 }
6707 else if (((p->family == AF_INET6) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6708 || (safi == SAFI_EVPN && p->family == AF_ETHERNET && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6709 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6710 {
6711 assert (attr->extra);
6712 char buf_a[BUFSIZ];
6713 char buf_b[BUFSIZ];
6714 char buf_c[BUFSIZ];
6715 if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
6716 {
6717 if (json)
6718 json_object_string_add(json_out, "mpNexthopGlobalIn",
6719 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, buf_a, BUFSIZ));
6720 else
6721 vty_out (vty, "%s",
6722 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6723 buf_a, BUFSIZ));
6724 }
6725 else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
6726 {
6727 if (json)
6728 {
6729 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6730 buf_a, BUFSIZ);
6731 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
6732 buf_b, BUFSIZ);
6733 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
6734 json_object_string_add(json_out, "mpNexthopGlobalLocal", buf_c);
6735 }
6736 else
6737 vty_out (vty, "%s(%s)",
6738 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6739 buf_a, BUFSIZ),
6740 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
6741 buf_b, BUFSIZ));
6742 }
6743
6744 }
6745 }
6746
6747 label = decode_label (binfo->extra->tag);
6748
6749 if (json)
6750 {
6751 if (label)
6752 json_object_int_add(json_out, "notag", label);
6753 json_object_array_add(json, json_out);
6754 }
6755 else
6756 {
6757 vty_out (vty, "notag/%d", label);
6758
6759 vty_out (vty, "%s", VTY_NEWLINE);
6760 }
6761 }
6762
6763 void
6764 route_vty_out_overlay (struct vty *vty, struct prefix *p,
6765 struct bgp_info *binfo, int display, json_object *json_paths)
6766 {
6767 struct attr *attr;
6768 char buf[BUFSIZ];
6769 json_object *json_path = NULL;
6770
6771 if (json_paths)
6772 json_path = json_object_new_object();
6773
6774 if (!binfo->extra)
6775 return;
6776
6777 /* short status lead text */
6778 route_vty_short_status_out (vty, binfo, json_path);
6779
6780 /* print prefix and mask */
6781 if (! display)
6782 route_vty_out_route (p, vty);
6783 else
6784 vty_out (vty, "%*s", 17, " ");
6785
6786 /* Print attribute */
6787 attr = binfo->attr;
6788 if (attr)
6789 {
6790 if (attr->extra)
6791 {
6792 char buf1[BUFSIZ];
6793 int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
6794
6795 switch (af) {
6796 case AF_INET:
6797 vty_out (vty, "%-16s", inet_ntop(af,
6798 &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
6799 break;
6800 case AF_INET6:
6801 vty_out (vty, "%s(%s)",
6802 inet_ntop (af,
6803 &attr->extra->mp_nexthop_global, buf, BUFSIZ),
6804 inet_ntop (af,
6805 &attr->extra->mp_nexthop_local, buf1, BUFSIZ));
6806 break;
6807 default:
6808 vty_out(vty, "?");
6809 }
6810 } else {
6811 vty_out(vty, "?");
6812 }
6813 }
6814
6815 if(attr->extra)
6816 {
6817 struct eth_segment_id *id = &(attr->extra->evpn_overlay.eth_s_id);
6818 char *str = esi2str(id);
6819 vty_out (vty, "%s", str);
6820 XFREE (MTYPE_TMP, str);
6821 if (p->u.prefix_evpn.flags & IP_PREFIX_V4)
6822 {
6823 vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
6824 }
6825 else if (p->u.prefix_evpn.flags & IP_PREFIX_V6)
6826 {
6827 vty_out (vty, "/%s",
6828 inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
6829 buf, BUFSIZ));
6830 }
6831 if(attr->extra->ecommunity)
6832 {
6833 char *mac = NULL;
6834 struct ecommunity_val *routermac = ecommunity_lookup (attr->extra->ecommunity,
6835 ECOMMUNITY_ENCODE_EVPN,
6836 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
6837 if(routermac)
6838 mac = ecom_mac2str((char *)routermac->val);
6839 if(mac)
6840 {
6841 vty_out (vty, "/%s",(char *)mac);
6842 XFREE(MTYPE_TMP, mac);
6843 }
6844 }
6845 }
6846 vty_out (vty, "%s", VTY_NEWLINE);
6847 }
6848
6849 /* dampening route */
6850 static void
6851 damp_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6852 int display, safi_t safi, u_char use_json, json_object *json)
6853 {
6854 struct attr *attr;
6855 int len;
6856 char timebuf[BGP_UPTIME_LEN];
6857
6858 /* short status lead text */
6859 route_vty_short_status_out (vty, binfo, json);
6860
6861 /* print prefix and mask */
6862 if (!use_json)
6863 {
6864 if (! display)
6865 route_vty_out_route (p, vty);
6866 else
6867 vty_out (vty, "%*s", 17, " ");
6868 }
6869
6870 len = vty_out (vty, "%s", binfo->peer->host);
6871 len = 17 - len;
6872 if (len < 1)
6873 {
6874 if (!use_json)
6875 vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
6876 }
6877 else
6878 {
6879 if (use_json)
6880 json_object_int_add(json, "peerHost", len);
6881 else
6882 vty_out (vty, "%*s", len, " ");
6883 }
6884
6885 if (use_json)
6886 bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
6887 else
6888 vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
6889
6890 /* Print attribute */
6891 attr = binfo->attr;
6892 if (attr)
6893 {
6894 /* Print aspath */
6895 if (attr->aspath)
6896 {
6897 if (use_json)
6898 json_object_string_add(json, "asPath", attr->aspath->str);
6899 else
6900 aspath_print_vty (vty, "%s", attr->aspath, " ");
6901 }
6902
6903 /* Print origin */
6904 if (use_json)
6905 json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
6906 else
6907 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6908 }
6909 if (!use_json)
6910 vty_out (vty, "%s", VTY_NEWLINE);
6911 }
6912
6913 /* flap route */
6914 static void
6915 flap_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6916 int display, safi_t safi, u_char use_json, json_object *json)
6917 {
6918 struct attr *attr;
6919 struct bgp_damp_info *bdi;
6920 char timebuf[BGP_UPTIME_LEN];
6921 int len;
6922
6923 if (!binfo->extra)
6924 return;
6925
6926 bdi = binfo->extra->damp_info;
6927
6928 /* short status lead text */
6929 route_vty_short_status_out (vty, binfo, json);
6930
6931 /* print prefix and mask */
6932 if (!use_json)
6933 {
6934 if (! display)
6935 route_vty_out_route (p, vty);
6936 else
6937 vty_out (vty, "%*s", 17, " ");
6938 }
6939
6940 len = vty_out (vty, "%s", binfo->peer->host);
6941 len = 16 - len;
6942 if (len < 1)
6943 {
6944 if (!use_json)
6945 vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
6946 }
6947 else
6948 {
6949 if (use_json)
6950 json_object_int_add(json, "peerHost", len);
6951 else
6952 vty_out (vty, "%*s", len, " ");
6953 }
6954
6955 len = vty_out (vty, "%d", bdi->flap);
6956 len = 5 - len;
6957 if (len < 1)
6958 {
6959 if (!use_json)
6960 vty_out (vty, " ");
6961 }
6962 else
6963 {
6964 if (use_json)
6965 json_object_int_add(json, "bdiFlap", len);
6966 else
6967 vty_out (vty, "%*s", len, " ");
6968 }
6969
6970 if (use_json)
6971 peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json);
6972 else
6973 vty_out (vty, "%s ", peer_uptime (bdi->start_time,
6974 timebuf, BGP_UPTIME_LEN, 0, NULL));
6975
6976 if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
6977 && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6978 {
6979 if (use_json)
6980 bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
6981 else
6982 vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
6983 }
6984 else
6985 {
6986 if (!use_json)
6987 vty_out (vty, "%*s ", 8, " ");
6988 }
6989
6990 /* Print attribute */
6991 attr = binfo->attr;
6992 if (attr)
6993 {
6994 /* Print aspath */
6995 if (attr->aspath)
6996 {
6997 if (use_json)
6998 json_object_string_add(json, "asPath", attr->aspath->str);
6999 else
7000 aspath_print_vty (vty, "%s", attr->aspath, " ");
7001 }
7002
7003 /* Print origin */
7004 if (use_json)
7005 json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
7006 else
7007 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
7008 }
7009 if (!use_json)
7010 vty_out (vty, "%s", VTY_NEWLINE);
7011 }
7012
7013 static void
7014 route_vty_out_advertised_to (struct vty *vty, struct peer *peer, int *first,
7015 const char *header, json_object *json_adv_to)
7016 {
7017 char buf1[INET6_ADDRSTRLEN];
7018 json_object *json_peer = NULL;
7019
7020 if (json_adv_to)
7021 {
7022 /* 'advertised-to' is a dictionary of peers we have advertised this
7023 * prefix too. The key is the peer's IP or swpX, the value is the
7024 * hostname if we know it and "" if not.
7025 */
7026 json_peer = json_object_new_object();
7027
7028 if (peer->hostname)
7029 json_object_string_add(json_peer, "hostname", peer->hostname);
7030
7031 if (peer->conf_if)
7032 json_object_object_add(json_adv_to, peer->conf_if, json_peer);
7033 else
7034 json_object_object_add(json_adv_to,
7035 sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN),
7036 json_peer);
7037 }
7038 else
7039 {
7040 if (*first)
7041 {
7042 vty_out (vty, "%s", header);
7043 *first = 0;
7044 }
7045
7046 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7047 {
7048 if (peer->conf_if)
7049 vty_out (vty, " %s(%s)", peer->hostname, peer->conf_if);
7050 else
7051 vty_out (vty, " %s(%s)", peer->hostname,
7052 sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
7053 }
7054 else
7055 {
7056 if (peer->conf_if)
7057 vty_out (vty, " %s", peer->conf_if);
7058 else
7059 vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
7060 }
7061 }
7062 }
7063
7064 static void
7065 route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
7066 struct bgp_info *binfo, afi_t afi, safi_t safi,
7067 json_object *json_paths)
7068 {
7069 char buf[INET6_ADDRSTRLEN];
7070 char buf1[BUFSIZ];
7071 struct attr *attr;
7072 int sockunion_vty_out (struct vty *, union sockunion *);
7073 time_t tbuf;
7074 json_object *json_bestpath = NULL;
7075 json_object *json_cluster_list = NULL;
7076 json_object *json_cluster_list_list = NULL;
7077 json_object *json_ext_community = NULL;
7078 json_object *json_last_update = NULL;
7079 json_object *json_nexthop_global = NULL;
7080 json_object *json_nexthop_ll = NULL;
7081 json_object *json_nexthops = NULL;
7082 json_object *json_path = NULL;
7083 json_object *json_peer = NULL;
7084 json_object *json_string = NULL;
7085 json_object *json_adv_to = NULL;
7086 int first = 0;
7087 struct listnode *node, *nnode;
7088 struct peer *peer;
7089 int addpath_capable;
7090 int has_adj;
7091 unsigned int first_as;
7092
7093 if (json_paths)
7094 {
7095 json_path = json_object_new_object();
7096 json_peer = json_object_new_object();
7097 json_nexthop_global = json_object_new_object();
7098 }
7099
7100 attr = binfo->attr;
7101
7102 if (attr)
7103 {
7104 /* Line1 display AS-path, Aggregator */
7105 if (attr->aspath)
7106 {
7107 if (json_paths)
7108 {
7109 json_object_lock(attr->aspath->json);
7110 json_object_object_add(json_path, "aspath", attr->aspath->json);
7111 }
7112 else
7113 {
7114 if (attr->aspath->segments)
7115 aspath_print_vty (vty, " %s", attr->aspath, "");
7116 else
7117 vty_out (vty, " Local");
7118 }
7119 }
7120
7121 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
7122 {
7123 if (json_paths)
7124 json_object_boolean_true_add(json_path, "removed");
7125 else
7126 vty_out (vty, ", (removed)");
7127 }
7128
7129 if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
7130 {
7131 if (json_paths)
7132 json_object_boolean_true_add(json_path, "stale");
7133 else
7134 vty_out (vty, ", (stale)");
7135 }
7136
7137 if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
7138 {
7139 if (json_paths)
7140 {
7141 json_object_int_add(json_path, "aggregatorAs", attr->extra->aggregator_as);
7142 json_object_string_add(json_path, "aggregatorId", inet_ntoa (attr->extra->aggregator_addr));
7143 }
7144 else
7145 {
7146 vty_out (vty, ", (aggregated by %u %s)",
7147 attr->extra->aggregator_as,
7148 inet_ntoa (attr->extra->aggregator_addr));
7149 }
7150 }
7151
7152 if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
7153 {
7154 if (json_paths)
7155 json_object_boolean_true_add(json_path, "rxedFromRrClient");
7156 else
7157 vty_out (vty, ", (Received from a RR-client)");
7158 }
7159
7160 if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
7161 {
7162 if (json_paths)
7163 json_object_boolean_true_add(json_path, "rxedFromRsClient");
7164 else
7165 vty_out (vty, ", (Received from a RS-client)");
7166 }
7167
7168 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
7169 {
7170 if (json_paths)
7171 json_object_boolean_true_add(json_path, "dampeningHistoryEntry");
7172 else
7173 vty_out (vty, ", (history entry)");
7174 }
7175 else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
7176 {
7177 if (json_paths)
7178 json_object_boolean_true_add(json_path, "dampeningSuppressed");
7179 else
7180 vty_out (vty, ", (suppressed due to dampening)");
7181 }
7182
7183 if (!json_paths)
7184 vty_out (vty, "%s", VTY_NEWLINE);
7185
7186 /* Line2 display Next-hop, Neighbor, Router-id */
7187 /* Display the nexthop */
7188 if (p->family == AF_INET &&
7189 (safi == SAFI_MPLS_VPN ||
7190 safi == SAFI_ENCAP ||
7191 safi == SAFI_EVPN ||
7192 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
7193 {
7194 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
7195 {
7196 if (json_paths)
7197 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
7198 else
7199 vty_out (vty, " %s", inet_ntoa (attr->extra->mp_nexthop_global_in));
7200 }
7201 else
7202 {
7203 if (json_paths)
7204 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
7205 else
7206 vty_out (vty, " %s", inet_ntoa (attr->nexthop));
7207 }
7208
7209 if (json_paths)
7210 json_object_string_add(json_nexthop_global, "afi", "ipv4");
7211 }
7212 else
7213 {
7214 assert (attr->extra);
7215 if (json_paths)
7216 {
7217 json_object_string_add(json_nexthop_global, "ip",
7218 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
7219 buf, INET6_ADDRSTRLEN));
7220 json_object_string_add(json_nexthop_global, "afi", "ipv6");
7221 json_object_string_add(json_nexthop_global, "scope", "global");
7222 }
7223 else
7224 {
7225 vty_out (vty, " %s",
7226 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
7227 buf, INET6_ADDRSTRLEN));
7228 }
7229 }
7230
7231 /* Display the IGP cost or 'inaccessible' */
7232 if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
7233 {
7234 if (json_paths)
7235 json_object_boolean_false_add(json_nexthop_global, "accessible");
7236 else
7237 vty_out (vty, " (inaccessible)");
7238 }
7239 else
7240 {
7241 if (binfo->extra && binfo->extra->igpmetric)
7242 {
7243 if (json_paths)
7244 json_object_int_add(json_nexthop_global, "metric", binfo->extra->igpmetric);
7245 else
7246 vty_out (vty, " (metric %u)", binfo->extra->igpmetric);
7247 }
7248
7249 /* IGP cost is 0, display this only for json */
7250 else
7251 {
7252 if (json_paths)
7253 json_object_int_add(json_nexthop_global, "metric", 0);
7254 }
7255
7256 if (json_paths)
7257 json_object_boolean_true_add(json_nexthop_global, "accessible");
7258 }
7259
7260 /* Display peer "from" output */
7261 /* This path was originated locally */
7262 if (binfo->peer == bgp->peer_self)
7263 {
7264
7265 if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7266 {
7267 if (json_paths)
7268 json_object_string_add(json_peer, "peerId", "0.0.0.0");
7269 else
7270 vty_out (vty, " from 0.0.0.0 ");
7271 }
7272 else
7273 {
7274 if (json_paths)
7275 json_object_string_add(json_peer, "peerId", "::");
7276 else
7277 vty_out (vty, " from :: ");
7278 }
7279
7280 if (json_paths)
7281 json_object_string_add(json_peer, "routerId", inet_ntoa(bgp->router_id));
7282 else
7283 vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
7284 }
7285
7286 /* We RXed this path from one of our peers */
7287 else
7288 {
7289
7290 if (json_paths)
7291 {
7292 json_object_string_add(json_peer, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
7293 json_object_string_add(json_peer, "routerId", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
7294
7295 if (binfo->peer->hostname)
7296 json_object_string_add(json_peer, "hostname", binfo->peer->hostname);
7297
7298 if (binfo->peer->domainname)
7299 json_object_string_add(json_peer, "domainname", binfo->peer->domainname);
7300
7301 if (binfo->peer->conf_if)
7302 json_object_string_add(json_peer, "interface", binfo->peer->conf_if);
7303 }
7304 else
7305 {
7306 if (binfo->peer->conf_if)
7307 {
7308 if (binfo->peer->hostname &&
7309 bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7310 vty_out (vty, " from %s(%s)", binfo->peer->hostname,
7311 binfo->peer->conf_if);
7312 else
7313 vty_out (vty, " from %s", binfo->peer->conf_if);
7314 }
7315 else
7316 {
7317 if (binfo->peer->hostname &&
7318 bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7319 vty_out (vty, " from %s(%s)", binfo->peer->hostname,
7320 binfo->peer->host);
7321 else
7322 vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
7323 }
7324
7325 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7326 vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
7327 else
7328 vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
7329 }
7330 }
7331
7332 if (!json_paths)
7333 vty_out (vty, "%s", VTY_NEWLINE);
7334
7335 /* display the link-local nexthop */
7336 if (attr->extra && attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7337 {
7338 if (json_paths)
7339 {
7340 json_nexthop_ll = json_object_new_object();
7341 json_object_string_add(json_nexthop_ll, "ip",
7342 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
7343 buf, INET6_ADDRSTRLEN));
7344 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
7345 json_object_string_add(json_nexthop_ll, "scope", "link-local");
7346
7347 json_object_boolean_true_add(json_nexthop_ll, "accessible");
7348
7349 if (!attr->extra->mp_nexthop_prefer_global)
7350 json_object_boolean_true_add(json_nexthop_ll, "used");
7351 else
7352 json_object_boolean_true_add(json_nexthop_global, "used");
7353 }
7354 else
7355 {
7356 vty_out (vty, " (%s) %s%s",
7357 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
7358 buf, INET6_ADDRSTRLEN),
7359 attr->extra->mp_nexthop_prefer_global ?
7360 "(prefer-global)" : "(used)",
7361 VTY_NEWLINE);
7362 }
7363 }
7364 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7365 else
7366 {
7367 if (json_paths)
7368 json_object_boolean_true_add(json_nexthop_global, "used");
7369 }
7370
7371 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7372 if (json_paths)
7373 json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
7374 else
7375 vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
7376
7377 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7378 {
7379 if (json_paths)
7380 json_object_int_add(json_path, "med", attr->med);
7381 else
7382 vty_out (vty, ", metric %u", attr->med);
7383 }
7384
7385 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7386 {
7387 if (json_paths)
7388 json_object_int_add(json_path, "localpref", attr->local_pref);
7389 else
7390 vty_out (vty, ", localpref %u", attr->local_pref);
7391 }
7392 else
7393 {
7394 if (json_paths)
7395 json_object_int_add(json_path, "localpref", bgp->default_local_pref);
7396 else
7397 vty_out (vty, ", localpref %u", bgp->default_local_pref);
7398 }
7399
7400 if (attr->extra && attr->extra->weight != 0)
7401 {
7402 if (json_paths)
7403 json_object_int_add(json_path, "weight", attr->extra->weight);
7404 else
7405 vty_out (vty, ", weight %u", attr->extra->weight);
7406 }
7407
7408 if (attr->extra && attr->extra->tag != 0)
7409 {
7410 if (json_paths)
7411 json_object_int_add(json_path, "tag", attr->extra->tag);
7412 else
7413 vty_out (vty, ", tag %"ROUTE_TAG_PRI, attr->extra->tag);
7414 }
7415
7416 if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
7417 {
7418 if (json_paths)
7419 json_object_boolean_false_add(json_path, "valid");
7420 else
7421 vty_out (vty, ", invalid");
7422 }
7423 else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
7424 {
7425 if (json_paths)
7426 json_object_boolean_true_add(json_path, "valid");
7427 else
7428 vty_out (vty, ", valid");
7429 }
7430
7431 if (binfo->peer != bgp->peer_self)
7432 {
7433 if (binfo->peer->as == binfo->peer->local_as)
7434 {
7435 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
7436 {
7437 if (json_paths)
7438 json_object_string_add(json_peer, "type", "confed-internal");
7439 else
7440 vty_out (vty, ", confed-internal");
7441 }
7442 else
7443 {
7444 if (json_paths)
7445 json_object_string_add(json_peer, "type", "internal");
7446 else
7447 vty_out (vty, ", internal");
7448 }
7449 }
7450 else
7451 {
7452 if (bgp_confederation_peers_check(bgp, binfo->peer->as))
7453 {
7454 if (json_paths)
7455 json_object_string_add(json_peer, "type", "confed-external");
7456 else
7457 vty_out (vty, ", confed-external");
7458 }
7459 else
7460 {
7461 if (json_paths)
7462 json_object_string_add(json_peer, "type", "external");
7463 else
7464 vty_out (vty, ", external");
7465 }
7466 }
7467 }
7468 else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
7469 {
7470 if (json_paths)
7471 {
7472 json_object_boolean_true_add(json_path, "aggregated");
7473 json_object_boolean_true_add(json_path, "local");
7474 }
7475 else
7476 {
7477 vty_out (vty, ", aggregated, local");
7478 }
7479 }
7480 else if (binfo->type != ZEBRA_ROUTE_BGP)
7481 {
7482 if (json_paths)
7483 json_object_boolean_true_add(json_path, "sourced");
7484 else
7485 vty_out (vty, ", sourced");
7486 }
7487 else
7488 {
7489 if (json_paths)
7490 {
7491 json_object_boolean_true_add(json_path, "sourced");
7492 json_object_boolean_true_add(json_path, "local");
7493 }
7494 else
7495 {
7496 vty_out (vty, ", sourced, local");
7497 }
7498 }
7499
7500 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7501 {
7502 if (json_paths)
7503 json_object_boolean_true_add(json_path, "atomicAggregate");
7504 else
7505 vty_out (vty, ", atomic-aggregate");
7506 }
7507
7508 if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH) ||
7509 (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED) &&
7510 bgp_info_mpath_count (binfo)))
7511 {
7512 if (json_paths)
7513 json_object_boolean_true_add(json_path, "multipath");
7514 else
7515 vty_out (vty, ", multipath");
7516 }
7517
7518 // Mark the bestpath(s)
7519 if (CHECK_FLAG (binfo->flags, BGP_INFO_DMED_SELECTED))
7520 {
7521 first_as = aspath_get_first_as(attr->aspath);
7522
7523 if (json_paths)
7524 {
7525 if (!json_bestpath)
7526 json_bestpath = json_object_new_object();
7527 json_object_int_add(json_bestpath, "bestpathFromAs", first_as);
7528 }
7529 else
7530 {
7531 if (first_as)
7532 vty_out (vty, ", bestpath-from-AS %d", first_as);
7533 else
7534 vty_out (vty, ", bestpath-from-AS Local");
7535 }
7536 }
7537
7538 if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
7539 {
7540 if (json_paths)
7541 {
7542 if (!json_bestpath)
7543 json_bestpath = json_object_new_object();
7544 json_object_boolean_true_add(json_bestpath, "overall");
7545 }
7546 else
7547 vty_out (vty, ", best");
7548 }
7549
7550 if (json_bestpath)
7551 json_object_object_add(json_path, "bestpath", json_bestpath);
7552
7553 if (!json_paths)
7554 vty_out (vty, "%s", VTY_NEWLINE);
7555
7556 /* Line 4 display Community */
7557 if (attr->community)
7558 {
7559 if (json_paths)
7560 {
7561 json_object_lock(attr->community->json);
7562 json_object_object_add(json_path, "community", attr->community->json);
7563 }
7564 else
7565 {
7566 vty_out (vty, " Community: %s%s", attr->community->str,
7567 VTY_NEWLINE);
7568 }
7569 }
7570
7571 /* Line 5 display Extended-community */
7572 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
7573 {
7574 if (json_paths)
7575 {
7576 json_ext_community = json_object_new_object();
7577 json_object_string_add(json_ext_community, "string", attr->extra->ecommunity->str);
7578 json_object_object_add(json_path, "extendedCommunity", json_ext_community);
7579 }
7580 else
7581 {
7582 vty_out (vty, " Extended Community: %s%s",
7583 attr->extra->ecommunity->str, VTY_NEWLINE);
7584 }
7585 }
7586
7587 /* Line 6 display Large community */
7588 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
7589 vty_out (vty, " Large Community: %s%s",
7590 attr->extra->lcommunity->str, VTY_NEWLINE);
7591
7592 /* Line 7 display Originator, Cluster-id */
7593 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
7594 (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
7595 {
7596 assert (attr->extra);
7597 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7598 {
7599 if (json_paths)
7600 json_object_string_add(json_path, "originatorId", inet_ntoa (attr->extra->originator_id));
7601 else
7602 vty_out (vty, " Originator: %s",
7603 inet_ntoa (attr->extra->originator_id));
7604 }
7605
7606 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
7607 {
7608 int i;
7609
7610 if (json_paths)
7611 {
7612 json_cluster_list = json_object_new_object();
7613 json_cluster_list_list = json_object_new_array();
7614
7615 for (i = 0; i < attr->extra->cluster->length / 4; i++)
7616 {
7617 json_string = json_object_new_string(inet_ntoa (attr->extra->cluster->list[i]));
7618 json_object_array_add(json_cluster_list_list, json_string);
7619 }
7620
7621 /* struct cluster_list does not have "str" variable like
7622 * aspath and community do. Add this someday if someone
7623 * asks for it.
7624 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7625 */
7626 json_object_object_add(json_cluster_list, "list", json_cluster_list_list);
7627 json_object_object_add(json_path, "clusterList", json_cluster_list);
7628 }
7629 else
7630 {
7631 vty_out (vty, ", Cluster list: ");
7632
7633 for (i = 0; i < attr->extra->cluster->length / 4; i++)
7634 {
7635 vty_out (vty, "%s ",
7636 inet_ntoa (attr->extra->cluster->list[i]));
7637 }
7638 }
7639 }
7640
7641 if (!json_paths)
7642 vty_out (vty, "%s", VTY_NEWLINE);
7643 }
7644
7645 if (binfo->extra && binfo->extra->damp_info)
7646 bgp_damp_info_vty (vty, binfo, json_path);
7647
7648 /* Remove Label */
7649 if (bgp_labeled_safi(safi) && binfo->extra)
7650 {
7651 uint32_t label = label_pton(binfo->extra->tag);
7652 if (json_paths)
7653 json_object_int_add(json_path, "remoteLabel", label);
7654 else
7655 vty_out(vty, " Remote label: %d%s", label, VTY_NEWLINE);
7656 }
7657
7658 /* Label Index */
7659 if (attr->extra->label_index != BGP_INVALID_LABEL_INDEX)
7660 {
7661 if (json_paths)
7662 json_object_int_add(json_path, "labelIndex", attr->extra->label_index);
7663 else
7664 vty_out(vty, " Label Index: %d%s", attr->extra->label_index, VTY_NEWLINE);
7665 }
7666
7667 /* Line 8 display Addpath IDs */
7668 if (binfo->addpath_rx_id || binfo->addpath_tx_id)
7669 {
7670 if (json_paths)
7671 {
7672 json_object_int_add(json_path, "addpathRxId", binfo->addpath_rx_id);
7673 json_object_int_add(json_path, "addpathTxId", binfo->addpath_tx_id);
7674 }
7675 else
7676 {
7677 vty_out (vty, " AddPath ID: RX %u, TX %u%s",
7678 binfo->addpath_rx_id, binfo->addpath_tx_id,
7679 VTY_NEWLINE);
7680 }
7681 }
7682
7683 /* If we used addpath to TX a non-bestpath we need to display
7684 * "Advertised to" on a path-by-path basis */
7685 if (bgp->addpath_tx_used[afi][safi])
7686 {
7687 first = 1;
7688
7689 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
7690 {
7691 addpath_capable = bgp_addpath_encode_tx (peer, afi, safi);
7692 has_adj = bgp_adj_out_lookup (peer, binfo->net, binfo->addpath_tx_id);
7693
7694 if ((addpath_capable && has_adj) ||
7695 (!addpath_capable && has_adj && CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)))
7696 {
7697 if (json_path && !json_adv_to)
7698 json_adv_to = json_object_new_object();
7699
7700 route_vty_out_advertised_to(vty, peer, &first,
7701 " Advertised to:",
7702 json_adv_to);
7703 }
7704 }
7705
7706 if (json_path)
7707 {
7708 if (json_adv_to)
7709 {
7710 json_object_object_add(json_path, "advertisedTo", json_adv_to);
7711 }
7712 }
7713 else
7714 {
7715 if (!first)
7716 {
7717 vty_out (vty, "%s", VTY_NEWLINE);
7718 }
7719 }
7720 }
7721
7722 /* Line 9 display Uptime */
7723 tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
7724 if (json_paths)
7725 {
7726 json_last_update = json_object_new_object();
7727 json_object_int_add(json_last_update, "epoch", tbuf);
7728 json_object_string_add(json_last_update, "string", ctime(&tbuf));
7729 json_object_object_add(json_path, "lastUpdate", json_last_update);
7730 }
7731 else
7732 vty_out (vty, " Last update: %s", ctime(&tbuf));
7733 }
7734
7735 /* We've constructed the json object for this path, add it to the json
7736 * array of paths
7737 */
7738 if (json_paths)
7739 {
7740 if (json_nexthop_global || json_nexthop_ll)
7741 {
7742 json_nexthops = json_object_new_array();
7743
7744 if (json_nexthop_global)
7745 json_object_array_add(json_nexthops, json_nexthop_global);
7746
7747 if (json_nexthop_ll)
7748 json_object_array_add(json_nexthops, json_nexthop_ll);
7749
7750 json_object_object_add(json_path, "nexthops", json_nexthops);
7751 }
7752
7753 json_object_object_add(json_path, "peer", json_peer);
7754 json_object_array_add(json_paths, json_path);
7755 }
7756 else
7757 vty_out (vty, "%s", VTY_NEWLINE);
7758 }
7759
7760 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7761 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7762 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7763
7764 static int
7765 bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
7766 const char *prefix_list_str, afi_t afi,
7767 safi_t safi, enum bgp_show_type type);
7768 static int
7769 bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
7770 const char *filter, afi_t afi,
7771 safi_t safi, enum bgp_show_type type);
7772 static int
7773 bgp_show_route_map (struct vty *vty, struct bgp *bgp,
7774 const char *rmap_str, afi_t afi,
7775 safi_t safi, enum bgp_show_type type);
7776 static int
7777 bgp_show_community_list (struct vty *vty, struct bgp *bgp,
7778 const char *com, int exact,
7779 afi_t afi, safi_t safi);
7780 static int
7781 bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
7782 const char *prefix, afi_t afi,
7783 safi_t safi, enum bgp_show_type type);
7784 static int
7785 bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
7786 safi_t safi, enum bgp_show_type type);
7787 static int
7788 bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
7789 struct cmd_token **argv, int exact, afi_t afi, safi_t safi);
7790
7791 static int
7792 bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
7793 enum bgp_show_type type, void *output_arg, u_char use_json)
7794 {
7795 struct bgp_info *ri;
7796 struct bgp_node *rn;
7797 int header = 1;
7798 int display;
7799 unsigned long output_count;
7800 unsigned long total_count;
7801 struct prefix *p;
7802 char buf[BUFSIZ];
7803 char buf2[BUFSIZ];
7804 json_object *json_paths = NULL;
7805 int first = 1;
7806
7807 if (use_json)
7808 {
7809 vty_out (vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ",
7810 bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
7811 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name,
7812 table->version, inet_ntoa (bgp->router_id));
7813 json_paths = json_object_new_object();
7814 }
7815
7816 /* This is first entry point, so reset total line. */
7817 output_count = 0;
7818 total_count = 0;
7819
7820 /* Start processing of routes. */
7821 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
7822 if (rn->info != NULL)
7823 {
7824 display = 0;
7825 if (!first && use_json)
7826 {
7827 vty_out (vty, ",");
7828 }
7829 if (use_json)
7830 json_paths = json_object_new_array();
7831 else
7832 json_paths = NULL;
7833
7834 for (ri = rn->info; ri; ri = ri->next)
7835 {
7836 total_count++;
7837 if (type == bgp_show_type_flap_statistics
7838 || type == bgp_show_type_flap_neighbor
7839 || type == bgp_show_type_dampend_paths
7840 || type == bgp_show_type_damp_neighbor)
7841 {
7842 if (!(ri->extra && ri->extra->damp_info))
7843 continue;
7844 }
7845 if (type == bgp_show_type_regexp)
7846 {
7847 regex_t *regex = output_arg;
7848
7849 if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
7850 continue;
7851 }
7852 if (type == bgp_show_type_prefix_list)
7853 {
7854 struct prefix_list *plist = output_arg;
7855
7856 if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
7857 continue;
7858 }
7859 if (type == bgp_show_type_filter_list)
7860 {
7861 struct as_list *as_list = output_arg;
7862
7863 if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
7864 continue;
7865 }
7866 if (type == bgp_show_type_route_map)
7867 {
7868 struct route_map *rmap = output_arg;
7869 struct bgp_info binfo;
7870 struct attr dummy_attr;
7871 struct attr_extra dummy_extra;
7872 int ret;
7873
7874 dummy_attr.extra = &dummy_extra;
7875 bgp_attr_dup (&dummy_attr, ri->attr);
7876
7877 binfo.peer = ri->peer;
7878 binfo.attr = &dummy_attr;
7879
7880 ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
7881 if (ret == RMAP_DENYMATCH)
7882 continue;
7883 }
7884 if (type == bgp_show_type_neighbor
7885 || type == bgp_show_type_flap_neighbor
7886 || type == bgp_show_type_damp_neighbor)
7887 {
7888 union sockunion *su = output_arg;
7889
7890 if (ri->peer == NULL ||
7891 ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
7892 continue;
7893 }
7894 if (type == bgp_show_type_cidr_only)
7895 {
7896 u_int32_t destination;
7897
7898 destination = ntohl (rn->p.u.prefix4.s_addr);
7899 if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
7900 continue;
7901 if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
7902 continue;
7903 if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
7904 continue;
7905 }
7906 if (type == bgp_show_type_prefix_longer)
7907 {
7908 struct prefix *p = output_arg;
7909
7910 if (! prefix_match (p, &rn->p))
7911 continue;
7912 }
7913 if (type == bgp_show_type_community_all)
7914 {
7915 if (! ri->attr->community)
7916 continue;
7917 }
7918 if (type == bgp_show_type_community)
7919 {
7920 struct community *com = output_arg;
7921
7922 if (! ri->attr->community ||
7923 ! community_match (ri->attr->community, com))
7924 continue;
7925 }
7926 if (type == bgp_show_type_community_exact)
7927 {
7928 struct community *com = output_arg;
7929
7930 if (! ri->attr->community ||
7931 ! community_cmp (ri->attr->community, com))
7932 continue;
7933 }
7934 if (type == bgp_show_type_community_list)
7935 {
7936 struct community_list *list = output_arg;
7937
7938 if (! community_list_match (ri->attr->community, list))
7939 continue;
7940 }
7941 if (type == bgp_show_type_community_list_exact)
7942 {
7943 struct community_list *list = output_arg;
7944
7945 if (! community_list_exact_match (ri->attr->community, list))
7946 continue;
7947 }
7948 if (type == bgp_show_type_lcommunity)
7949 {
7950 struct lcommunity *lcom = output_arg;
7951
7952 if (! ri->attr->extra || ! ri->attr->extra->lcommunity ||
7953 ! lcommunity_match (ri->attr->extra->lcommunity, lcom))
7954 continue;
7955 }
7956 if (type == bgp_show_type_lcommunity_list)
7957 {
7958 struct community_list *list = output_arg;
7959
7960 if (! ri->attr->extra ||
7961 ! lcommunity_list_match (ri->attr->extra->lcommunity, list))
7962 continue;
7963 }
7964 if (type == bgp_show_type_lcommunity_all)
7965 {
7966 if (! ri->attr->extra || ! ri->attr->extra->lcommunity)
7967 continue;
7968 }
7969 if (type == bgp_show_type_dampend_paths
7970 || type == bgp_show_type_damp_neighbor)
7971 {
7972 if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
7973 || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
7974 continue;
7975 }
7976
7977 if (!use_json && header)
7978 {
7979 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
7980 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
7981 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
7982 if (type == bgp_show_type_dampend_paths
7983 || type == bgp_show_type_damp_neighbor)
7984 vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
7985 else if (type == bgp_show_type_flap_statistics
7986 || type == bgp_show_type_flap_neighbor)
7987 vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
7988 else
7989 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
7990 header = 0;
7991 }
7992
7993 if (type == bgp_show_type_dampend_paths
7994 || type == bgp_show_type_damp_neighbor)
7995 damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
7996 else if (type == bgp_show_type_flap_statistics
7997 || type == bgp_show_type_flap_neighbor)
7998 flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
7999 else
8000 route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, json_paths);
8001 display++;
8002 }
8003
8004 if (display)
8005 {
8006 output_count++;
8007 if (use_json)
8008 {
8009 p = &rn->p;
8010 sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
8011 vty_out (vty, "\"%s\": ", buf2);
8012 vty_out (vty, "%s", json_object_to_json_string (json_paths));
8013 json_object_free (json_paths);
8014 first = 0;
8015
8016 }
8017 }
8018 }
8019
8020 if (use_json)
8021 {
8022 json_object_free (json_paths);
8023 vty_out (vty, " } }%s", VTY_NEWLINE);
8024 }
8025 else
8026 {
8027 /* No route is displayed */
8028 if (output_count == 0)
8029 {
8030 if (type == bgp_show_type_normal)
8031 vty_out (vty, "No BGP prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
8032 }
8033 else
8034 vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
8035 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
8036 }
8037
8038 return CMD_SUCCESS;
8039 }
8040
8041 static int
8042 bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
8043 enum bgp_show_type type, void *output_arg, u_char use_json)
8044 {
8045 struct bgp_table *table;
8046
8047 if (bgp == NULL)
8048 {
8049 bgp = bgp_get_default ();
8050 }
8051
8052 if (bgp == NULL)
8053 {
8054 if (!use_json)
8055 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
8056 return CMD_WARNING;
8057 }
8058 /* use MPLS and ENCAP specific shows until they are merged */
8059 if (safi == SAFI_MPLS_VPN)
8060 {
8061 return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg,
8062 0, use_json);
8063 }
8064 if (safi == SAFI_ENCAP)
8065 {
8066 return bgp_show_encap(vty, afi, NULL, type, output_arg,
8067 0);
8068 }
8069
8070
8071 table = bgp->rib[afi][safi];
8072
8073 return bgp_show_table (vty, bgp, table, type, output_arg,
8074 use_json);
8075 }
8076
8077 static void
8078 bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
8079 u_char use_json)
8080 {
8081 struct listnode *node, *nnode;
8082 struct bgp *bgp;
8083 struct bgp_table *table;
8084 int is_first = 1;
8085
8086 if (use_json)
8087 vty_out (vty, "{%s", VTY_NEWLINE);
8088
8089 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
8090 {
8091 if (use_json)
8092 {
8093 if (! is_first)
8094 vty_out (vty, ",%s", VTY_NEWLINE);
8095 else
8096 is_first = 0;
8097
8098 vty_out(vty, "\"%s\":", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8099 ? "Default" : bgp->name);
8100 }
8101 else
8102 {
8103 vty_out (vty, "%sInstance %s:%s",
8104 VTY_NEWLINE,
8105 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8106 ? "Default" : bgp->name,
8107 VTY_NEWLINE);
8108 }
8109 table = bgp->rib[afi][safi];
8110 bgp_show_table (vty, bgp, table,
8111 bgp_show_type_normal, NULL, use_json);
8112
8113 }
8114
8115 if (use_json)
8116 vty_out (vty, "}%s", VTY_NEWLINE);
8117 }
8118
8119 /* Header of detailed BGP route information */
8120 static void
8121 route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
8122 struct bgp_node *rn,
8123 struct prefix_rd *prd, afi_t afi, safi_t safi,
8124 json_object *json)
8125 {
8126 struct bgp_info *ri;
8127 struct prefix *p;
8128 struct peer *peer;
8129 struct listnode *node, *nnode;
8130 char buf1[INET6_ADDRSTRLEN];
8131 char buf2[INET6_ADDRSTRLEN];
8132 int count = 0;
8133 int best = 0;
8134 int suppress = 0;
8135 int no_export = 0;
8136 int no_advertise = 0;
8137 int local_as = 0;
8138 int first = 1;
8139 json_object *json_adv_to = NULL;
8140
8141 p = &rn->p;
8142
8143 if (json)
8144 {
8145 json_object_string_add(json, "prefix", inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN));
8146 json_object_int_add(json, "prefixlen", p->prefixlen);
8147 }
8148 else
8149 {
8150 if (p->family == AF_ETHERNET)
8151 prefix2str (p, buf2, INET6_ADDRSTRLEN);
8152 else
8153 inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN);
8154 vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
8155 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) ?
8156 prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
8157 ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
8158 buf2,
8159 p->prefixlen, VTY_NEWLINE);
8160
8161 if (bgp_labeled_safi(safi))
8162 {
8163 vty_out(vty, "Local label: ");
8164 if (!bgp_is_valid_label(rn->local_label))
8165 vty_out(vty, "not allocated%s", VTY_NEWLINE);
8166 else
8167 {
8168 uint32_t label = label_pton(rn->local_label);
8169 vty_out(vty, "%d%s", label, VTY_NEWLINE);
8170 }
8171 }
8172 }
8173
8174 for (ri = rn->info; ri; ri = ri->next)
8175 {
8176 count++;
8177 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
8178 {
8179 best = count;
8180 if (ri->extra && ri->extra->suppress)
8181 suppress = 1;
8182 if (ri->attr->community != NULL)
8183 {
8184 if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
8185 no_advertise = 1;
8186 if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
8187 no_export = 1;
8188 if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
8189 local_as = 1;
8190 }
8191 }
8192 }
8193
8194 if (!json)
8195 {
8196 vty_out (vty, "Paths: (%d available", count);
8197 if (best)
8198 {
8199 vty_out (vty, ", best #%d", best);
8200 if (safi == SAFI_UNICAST)
8201 vty_out (vty, ", table %s",
8202 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
8203 ? "Default-IP-Routing-Table" : bgp->name);
8204 }
8205 else
8206 vty_out (vty, ", no best path");
8207
8208 if (no_advertise)
8209 vty_out (vty, ", not advertised to any peer");
8210 else if (no_export)
8211 vty_out (vty, ", not advertised to EBGP peer");
8212 else if (local_as)
8213 vty_out (vty, ", not advertised outside local AS");
8214
8215 if (suppress)
8216 vty_out (vty, ", Advertisements suppressed by an aggregate.");
8217 vty_out (vty, ")%s", VTY_NEWLINE);
8218 }
8219
8220 /* If we are not using addpath then we can display Advertised to and that will
8221 * show what peers we advertised the bestpath to. If we are using addpath
8222 * though then we must display Advertised to on a path-by-path basis. */
8223 if (!bgp->addpath_tx_used[afi][safi])
8224 {
8225 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
8226 {
8227 if (bgp_adj_out_lookup (peer, rn, 0))
8228 {
8229 if (json && !json_adv_to)
8230 json_adv_to = json_object_new_object();
8231
8232 route_vty_out_advertised_to(vty, peer, &first,
8233 " Advertised to non peer-group peers:\n ",
8234 json_adv_to);
8235 }
8236 }
8237
8238 if (json)
8239 {
8240 if (json_adv_to)
8241 {
8242 json_object_object_add(json, "advertisedTo", json_adv_to);
8243 }
8244 }
8245 else
8246 {
8247 if (first)
8248 vty_out (vty, " Not advertised to any peer");
8249 vty_out (vty, "%s", VTY_NEWLINE);
8250 }
8251 }
8252 }
8253
8254 /* Display specified route of BGP table. */
8255 static int
8256 bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
8257 struct bgp_table *rib, const char *ip_str,
8258 afi_t afi, safi_t safi, struct prefix_rd *prd,
8259 int prefix_check, enum bgp_path_type pathtype,
8260 u_char use_json)
8261 {
8262 int ret;
8263 int header;
8264 int display = 0;
8265 struct prefix match;
8266 struct bgp_node *rn;
8267 struct bgp_node *rm;
8268 struct bgp_info *ri;
8269 struct bgp_table *table;
8270 json_object *json = NULL;
8271 json_object *json_paths = NULL;
8272
8273 /* Check IP address argument. */
8274 ret = str2prefix (ip_str, &match);
8275 if (! ret)
8276 {
8277 vty_out (vty, "address is malformed%s", VTY_NEWLINE);
8278 return CMD_WARNING;
8279 }
8280
8281 match.family = afi2family (afi);
8282
8283 if (use_json)
8284 {
8285 json = json_object_new_object();
8286 json_paths = json_object_new_array();
8287 }
8288
8289 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
8290 {
8291 for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
8292 {
8293 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
8294 continue;
8295
8296 if ((table = rn->info) != NULL)
8297 {
8298 header = 1;
8299
8300 if ((rm = bgp_node_match (table, &match)) != NULL)
8301 {
8302 if (prefix_check && rm->p.prefixlen != match.prefixlen)
8303 {
8304 bgp_unlock_node (rm);
8305 continue;
8306 }
8307
8308 for (ri = rm->info; ri; ri = ri->next)
8309 {
8310 if (header)
8311 {
8312 route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
8313 AFI_IP, safi, json);
8314 header = 0;
8315 }
8316 display++;
8317
8318 if (pathtype == BGP_PATH_ALL ||
8319 (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
8320 (pathtype == BGP_PATH_MULTIPATH &&
8321 (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
8322 route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, safi, json_paths);
8323 }
8324
8325 bgp_unlock_node (rm);
8326 }
8327 }
8328 }
8329 }
8330 else
8331 {
8332 header = 1;
8333
8334 if ((rn = bgp_node_match (rib, &match)) != NULL)
8335 {
8336 if (! prefix_check || rn->p.prefixlen == match.prefixlen)
8337 {
8338 for (ri = rn->info; ri; ri = ri->next)
8339 {
8340 if (header)
8341 {
8342 route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi, json);
8343 header = 0;
8344 }
8345 display++;
8346
8347 if (pathtype == BGP_PATH_ALL ||
8348 (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
8349 (pathtype == BGP_PATH_MULTIPATH &&
8350 (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
8351 route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi, json_paths);
8352 }
8353 }
8354
8355 bgp_unlock_node (rn);
8356 }
8357 }
8358
8359 if (use_json)
8360 {
8361 if (display)
8362 json_object_object_add(json, "paths", json_paths);
8363
8364 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
8365 json_object_free(json);
8366 }
8367 else
8368 {
8369 if (!display)
8370 {
8371 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
8372 return CMD_WARNING;
8373 }
8374 }
8375
8376 return CMD_SUCCESS;
8377 }
8378
8379 /* Display specified route of Main RIB */
8380 static int
8381 bgp_show_route (struct vty *vty, struct bgp *bgp, const char *ip_str,
8382 afi_t afi, safi_t safi, struct prefix_rd *prd,
8383 int prefix_check, enum bgp_path_type pathtype,
8384 u_char use_json)
8385 {
8386 if (!bgp)
8387 bgp = bgp_get_default ();
8388
8389 return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
8390 afi, safi, prd, prefix_check, pathtype,
8391 use_json);
8392 }
8393
8394 static int
8395 bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc,
8396 struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj)
8397 {
8398 struct lcommunity *lcom;
8399 struct buffer *b;
8400 int i;
8401 char *str;
8402 int first = 0;
8403
8404 b = buffer_new (1024);
8405 for (i = 0; i < argc; i++)
8406 {
8407 if (first)
8408 buffer_putc (b, ' ');
8409 else
8410 {
8411 if (strmatch (argv[i]->text, "AA:BB:CC"))
8412 {
8413 first = 1;
8414 buffer_putstr (b, argv[i]->arg);
8415 }
8416 }
8417 }
8418 buffer_putc (b, '\0');
8419
8420 str = buffer_getstr (b);
8421 buffer_free (b);
8422
8423 lcom = lcommunity_str2com (str);
8424 XFREE (MTYPE_TMP, str);
8425 if (! lcom)
8426 {
8427 vty_out (vty, "%% Large-community malformed%s", VTY_NEWLINE);
8428 return CMD_WARNING;
8429 }
8430
8431 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom, uj);
8432 }
8433
8434 static int
8435 bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
8436 afi_t afi, safi_t safi, u_char uj)
8437 {
8438 struct community_list *list;
8439
8440 list = community_list_lookup (bgp_clist, lcom, LARGE_COMMUNITY_LIST_MASTER);
8441 if (list == NULL)
8442 {
8443 vty_out (vty, "%% %s is not a valid large-community-list name%s", lcom,
8444 VTY_NEWLINE);
8445 return CMD_WARNING;
8446 }
8447
8448 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_list, list, uj);
8449 }
8450
8451 DEFUN (show_ip_bgp_large_community_list,
8452 show_ip_bgp_large_community_list_cmd,
8453 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community-list <(1-500)|WORD> [json]",
8454 SHOW_STR
8455 IP_STR
8456 BGP_STR
8457 BGP_INSTANCE_HELP_STR
8458 "Address Family\n"
8459 "Address Family\n"
8460 "Address Family modifier\n"
8461 "Address Family modifier\n"
8462 "Address Family modifier\n"
8463 "Address Family modifier\n"
8464 "Address Family modifier\n"
8465 "Display routes matching the large-community-list\n"
8466 "large-community-list number\n"
8467 "large-community-list name\n"
8468 JSON_STR)
8469 {
8470 char *vrf = NULL;
8471 afi_t afi = AFI_IP6;
8472 safi_t safi = SAFI_UNICAST;
8473 int idx = 0;
8474
8475 if (argv_find (argv, argc, "ip", &idx))
8476 afi = AFI_IP;
8477 if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
8478 vrf = argv[++idx]->arg;
8479 if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
8480 {
8481 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8482 if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
8483 safi = bgp_vty_safi_from_arg (argv[idx]->text);
8484 }
8485
8486 int uj = use_json (argc, argv);
8487
8488 struct bgp *bgp = bgp_lookup_by_name (vrf);
8489 if (bgp == NULL)
8490 {
8491 vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
8492 return CMD_WARNING;
8493 }
8494
8495 argv_find (argv, argc, "large-community-list", &idx);
8496 return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj);
8497 }
8498 DEFUN (show_ip_bgp_large_community,
8499 show_ip_bgp_large_community_cmd,
8500 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] large-community [AA:BB:CC] [json]",
8501 SHOW_STR
8502 IP_STR
8503 BGP_STR
8504 BGP_INSTANCE_HELP_STR
8505 "Address Family\n"
8506 "Address Family\n"
8507 "Address Family modifier\n"
8508 "Address Family modifier\n"
8509 "Address Family modifier\n"
8510 "Address Family modifier\n"
8511 "Address Family modifier\n"
8512 "Display routes matching the large-communities\n"
8513 "List of large-community numbers\n"
8514 JSON_STR)
8515 {
8516 char *vrf = NULL;
8517 afi_t afi = AFI_IP6;
8518 safi_t safi = SAFI_UNICAST;
8519 int idx = 0;
8520
8521 if (argv_find (argv, argc, "ip", &idx))
8522 afi = AFI_IP;
8523 if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
8524 vrf = argv[++idx]->arg;
8525 if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
8526 {
8527 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8528 if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
8529 safi = bgp_vty_safi_from_arg (argv[idx]->text);
8530 }
8531
8532 int uj = use_json (argc, argv);
8533
8534 struct bgp *bgp = bgp_lookup_by_name (vrf);
8535 if (bgp == NULL)
8536 {
8537 vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
8538 return CMD_WARNING;
8539 }
8540
8541 if (argv_find (argv, argc, "AA:BB:CC", &idx))
8542 return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj);
8543 else
8544 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj);
8545 }
8546
8547 static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi);
8548
8549 /* BGP route print out function. */
8550 DEFUN (show_ip_bgp,
8551 show_ip_bgp_cmd,
8552 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]\
8553 [<\
8554 cidr-only\
8555 |dampening <flap-statistics|dampened-paths|parameters>\
8556 |route-map WORD\
8557 |prefix-list WORD\
8558 |filter-list WORD\
8559 |statistics\
8560 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8561 |community-list <(1-500)|WORD> [exact-match]\
8562 |A.B.C.D/M longer-prefixes\
8563 |X:X::X:X/M longer-prefixes>\
8564 ] [json]",
8565 SHOW_STR
8566 IP_STR
8567 BGP_STR
8568 BGP_INSTANCE_HELP_STR
8569 BGP_AFI_HELP_STR
8570 BGP_SAFI_HELP_STR
8571 "Display only routes with non-natural netmasks\n"
8572 "Display detailed information about dampening\n"
8573 "Display flap statistics of routes\n"
8574 "Display paths suppressed due to dampening\n"
8575 "Display detail of configured dampening parameters\n"
8576 "Display routes matching the route-map\n"
8577 "A route-map to match on\n"
8578 "Display routes conforming to the prefix-list\n"
8579 "Prefix-list name\n"
8580 "Display routes conforming to the filter-list\n"
8581 "Regular expression access list name\n"
8582 "BGP RIB advertisement statistics\n"
8583 "Display routes matching the communities\n"
8584 COMMUNITY_AANN_STR
8585 "Do not send outside local AS (well-known community)\n"
8586 "Do not advertise to any peer (well-known community)\n"
8587 "Do not export to next AS (well-known community)\n"
8588 "Exact match of the communities\n"
8589 "Display routes matching the community-list\n"
8590 "community-list number\n"
8591 "community-list name\n"
8592 "Exact match of the communities\n"
8593 "IPv4 prefix\n"
8594 "Display route and more specific routes\n"
8595 "IPv6 prefix\n"
8596 "Display route and more specific routes\n"
8597 JSON_STR)
8598 {
8599 afi_t afi = AFI_IP6;
8600 safi_t safi = SAFI_UNICAST;
8601 int exact_match = 0;
8602 enum bgp_show_type sh_type = bgp_show_type_normal;
8603 struct bgp *bgp = NULL;
8604 int idx = 0;
8605
8606 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8607 if (!idx)
8608 return CMD_WARNING;
8609
8610 int uj = use_json (argc, argv);
8611 if (uj) argc--;
8612
8613 if (argv_find(argv, argc, "cidr-only", &idx))
8614 return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
8615
8616 if (argv_find(argv, argc, "dampening", &idx))
8617 {
8618 if (argv_find (argv, argc, "dampened-paths", &idx))
8619 return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
8620 else if (argv_find (argv, argc, "flap-statistics", &idx))
8621 return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
8622 else if (argv_find (argv, argc, "parameters", &idx))
8623 return bgp_show_dampening_parameters (vty, afi, safi);
8624 }
8625
8626 if (argv_find(argv, argc, "prefix-list", &idx))
8627 return bgp_show_prefix_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
8628
8629 if (argv_find(argv, argc, "filter-list", &idx))
8630 return bgp_show_filter_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
8631
8632 if (argv_find(argv, argc, "statistics", &idx))
8633 return bgp_table_stats (vty, bgp, afi, safi);
8634
8635 if (argv_find(argv, argc, "route-map", &idx))
8636 return bgp_show_route_map (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
8637
8638 if (argv_find(argv, argc, "community", &idx))
8639 {
8640 /* show a specific community */
8641 if (argv_find (argv, argc, "local-AS", &idx) ||
8642 argv_find (argv, argc, "no-advertise", &idx) ||
8643 argv_find (argv, argc, "no-export", &idx))
8644 {
8645 if (argv_find (argv, argc, "exact_match", &idx))
8646 exact_match = 1;
8647 return bgp_show_community (vty, bgp, argc, argv, exact_match, afi, safi);
8648 }
8649 /* show all communities */
8650 else
8651 return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
8652 }
8653
8654 if (argv_find(argv, argc, "community-list", &idx))
8655 {
8656 const char *clist_number_or_name = argv[++idx]->arg;
8657 if (++idx < argc && strmatch (argv[idx]->text, "exact-match"))
8658 exact_match = 1;
8659 return bgp_show_community_list (vty, bgp, clist_number_or_name, exact_match, afi, safi);
8660 }
8661 /* prefix-longer */
8662 if (argv_find(argv, argc, "A.B.C.D/M", &idx) || argv_find(argv, argc, "X:X::X:X/M", &idx))
8663 return bgp_show_prefix_longer (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_longer);
8664
8665 if (safi == SAFI_MPLS_VPN)
8666 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj);
8667 else if (safi == SAFI_ENCAP)
8668 return bgp_show_encap (vty, afi, NULL, bgp_show_type_normal, NULL, 0);
8669 else
8670 return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
8671 }
8672
8673 DEFUN (show_ip_bgp_route,
8674 show_ip_bgp_route_cmd,
8675 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]"
8676 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8677 SHOW_STR
8678 IP_STR
8679 BGP_STR
8680 BGP_INSTANCE_HELP_STR
8681 BGP_AFI_HELP_STR
8682 BGP_SAFI_HELP_STR
8683 "Network in the BGP routing table to display\n"
8684 "IPv4 prefix\n"
8685 "Network in the BGP routing table to display\n"
8686 "IPv6 prefix\n"
8687 "Display only the bestpath\n"
8688 "Display only multipaths\n"
8689 JSON_STR)
8690 {
8691 int prefix_check = 0;
8692
8693 afi_t afi = AFI_IP6;
8694 safi_t safi = SAFI_UNICAST;
8695 char *prefix = NULL;
8696 struct bgp *bgp = NULL;
8697 enum bgp_path_type path_type;
8698 u_char uj = use_json(argc, argv);
8699
8700 int idx = 0;
8701
8702 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8703 if (!idx)
8704 return CMD_WARNING;
8705
8706 if (!bgp)
8707 {
8708 vty_out (vty, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE);
8709 return CMD_WARNING;
8710 }
8711
8712 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8713 if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
8714 prefix_check = 0;
8715 else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
8716 prefix_check = 1;
8717
8718 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
8719 {
8720 vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
8721 return CMD_WARNING;
8722 }
8723 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
8724 {
8725 vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
8726 return CMD_WARNING;
8727 }
8728
8729 prefix = argv[idx]->arg;
8730
8731 /* [<bestpath|multipath>] */
8732 if (argv_find (argv, argc, "bestpath", &idx))
8733 path_type = BGP_PATH_BESTPATH;
8734 else if (argv_find (argv, argc, "multipath", &idx))
8735 path_type = BGP_PATH_MULTIPATH;
8736 else
8737 path_type = BGP_PATH_ALL;
8738
8739 return bgp_show_route (vty, bgp, prefix, afi, safi, NULL, prefix_check, path_type, uj);
8740 }
8741
8742 DEFUN (show_ip_bgp_regexp,
8743 show_ip_bgp_regexp_cmd,
8744 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] regexp REGEX...",
8745 SHOW_STR
8746 IP_STR
8747 BGP_STR
8748 BGP_INSTANCE_HELP_STR
8749 BGP_AFI_HELP_STR
8750 BGP_SAFI_HELP_STR
8751 "Display routes matching the AS path regular expression\n"
8752 "A regular-expression to match the BGP AS paths\n")
8753 {
8754 afi_t afi = AFI_IP6;
8755 safi_t safi = SAFI_UNICAST;
8756 struct bgp *bgp = NULL;
8757
8758 int idx = 0;
8759 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8760 if (!idx)
8761 return CMD_WARNING;
8762
8763 // get index of regex
8764 argv_find (argv, argc, "regexp", &idx);
8765 idx++;
8766
8767 char *regstr = argv_concat (argv, argc, idx);
8768 int rc = bgp_show_regexp (vty, (const char *) regstr, afi, safi, bgp_show_type_regexp);
8769 XFREE (MTYPE_TMP, regstr);
8770 return rc;
8771 }
8772
8773 DEFUN (show_ip_bgp_instance_all,
8774 show_ip_bgp_instance_all_cmd,
8775 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] [json]",
8776 SHOW_STR
8777 IP_STR
8778 BGP_STR
8779 BGP_INSTANCE_ALL_HELP_STR
8780 BGP_AFI_HELP_STR
8781 BGP_SAFI_HELP_STR
8782 JSON_STR)
8783 {
8784 afi_t afi = AFI_IP;
8785 safi_t safi = SAFI_UNICAST;
8786 struct bgp *bgp = NULL;
8787
8788 int idx = 0;
8789 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8790 if (!idx)
8791 return CMD_WARNING;
8792
8793 int uj = use_json (argc, argv);
8794 if (uj) argc--;
8795
8796 bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
8797 return CMD_SUCCESS;
8798 }
8799
8800 static int
8801 bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
8802 safi_t safi, enum bgp_show_type type)
8803 {
8804 regex_t *regex;
8805 int rc;
8806
8807 regex = bgp_regcomp (regstr);
8808 if (! regex)
8809 {
8810 vty_out (vty, "Can't compile regexp %s%s", regstr, VTY_NEWLINE);
8811 return CMD_WARNING;
8812 }
8813
8814 rc = bgp_show (vty, NULL, afi, safi, type, regex, 0);
8815 bgp_regex_free (regex);
8816 return rc;
8817 }
8818
8819 static int
8820 bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
8821 const char *prefix_list_str, afi_t afi,
8822 safi_t safi, enum bgp_show_type type)
8823 {
8824 struct prefix_list *plist;
8825
8826 plist = prefix_list_lookup (afi, prefix_list_str);
8827 if (plist == NULL)
8828 {
8829 vty_out (vty, "%% %s is not a valid prefix-list name%s",
8830 prefix_list_str, VTY_NEWLINE);
8831 return CMD_WARNING;
8832 }
8833
8834 return bgp_show (vty, bgp, afi, safi, type, plist, 0);
8835 }
8836
8837 static int
8838 bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
8839 const char *filter, afi_t afi,
8840 safi_t safi, enum bgp_show_type type)
8841 {
8842 struct as_list *as_list;
8843
8844 as_list = as_list_lookup (filter);
8845 if (as_list == NULL)
8846 {
8847 vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
8848 return CMD_WARNING;
8849 }
8850
8851 return bgp_show (vty, bgp, afi, safi, type, as_list, 0);
8852 }
8853
8854 static int
8855 bgp_show_route_map (struct vty *vty, struct bgp *bgp,
8856 const char *rmap_str, afi_t afi,
8857 safi_t safi, enum bgp_show_type type)
8858 {
8859 struct route_map *rmap;
8860
8861 rmap = route_map_lookup_by_name (rmap_str);
8862 if (! rmap)
8863 {
8864 vty_out (vty, "%% %s is not a valid route-map name%s",
8865 rmap_str, VTY_NEWLINE);
8866 return CMD_WARNING;
8867 }
8868
8869 return bgp_show (vty, bgp, afi, safi, type, rmap, 0);
8870 }
8871
8872 static int
8873 bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
8874 struct cmd_token **argv, int exact, afi_t afi, safi_t safi)
8875 {
8876 struct community *com;
8877 struct buffer *b;
8878 int i;
8879 char *str;
8880 int first = 0;
8881
8882 b = buffer_new (1024);
8883 for (i = 0; i < argc; i++)
8884 {
8885 if (first)
8886 buffer_putc (b, ' ');
8887 else
8888 {
8889 if ((strcmp (argv[i]->arg, "unicast") == 0) || (strcmp (argv[i]->arg, "multicast") == 0))
8890 continue;
8891 first = 1;
8892 }
8893
8894 buffer_putstr (b, argv[i]->arg);
8895 }
8896 buffer_putc (b, '\0');
8897
8898 str = buffer_getstr (b);
8899 buffer_free (b);
8900
8901 com = community_str2com (str);
8902 XFREE (MTYPE_TMP, str);
8903 if (! com)
8904 {
8905 vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
8906 return CMD_WARNING;
8907 }
8908
8909 return bgp_show (vty, bgp, afi, safi,
8910 (exact ? bgp_show_type_community_exact :
8911 bgp_show_type_community), com, 0);
8912 }
8913
8914 static int
8915 bgp_show_community_list (struct vty *vty, struct bgp *bgp,
8916 const char *com, int exact,
8917 afi_t afi, safi_t safi)
8918 {
8919 struct community_list *list;
8920
8921 list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
8922 if (list == NULL)
8923 {
8924 vty_out (vty, "%% %s is not a valid community-list name%s", com,
8925 VTY_NEWLINE);
8926 return CMD_WARNING;
8927 }
8928
8929 return bgp_show (vty, bgp, afi, safi,
8930 (exact ? bgp_show_type_community_list_exact :
8931 bgp_show_type_community_list), list, 0);
8932 }
8933
8934 static int
8935 bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
8936 const char *prefix, afi_t afi,
8937 safi_t safi, enum bgp_show_type type)
8938 {
8939 int ret;
8940 struct prefix *p;
8941
8942 p = prefix_new();
8943
8944 ret = str2prefix (prefix, p);
8945 if (! ret)
8946 {
8947 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
8948 return CMD_WARNING;
8949 }
8950
8951 ret = bgp_show (vty, bgp, afi, safi, type, p, 0);
8952 prefix_free(p);
8953 return ret;
8954 }
8955
8956 static struct peer *
8957 peer_lookup_in_view (struct vty *vty, struct bgp *bgp,
8958 const char *ip_str, u_char use_json)
8959 {
8960 int ret;
8961 struct peer *peer;
8962 union sockunion su;
8963
8964 /* Get peer sockunion. */
8965 ret = str2sockunion (ip_str, &su);
8966 if (ret < 0)
8967 {
8968 peer = peer_lookup_by_conf_if (bgp, ip_str);
8969 if (!peer)
8970 {
8971 peer = peer_lookup_by_hostname(bgp, ip_str);
8972
8973 if (!peer)
8974 {
8975 if (use_json)
8976 {
8977 json_object *json_no = NULL;
8978 json_no = json_object_new_object();
8979 json_object_string_add(json_no, "malformedAddressOrName", ip_str);
8980 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
8981 json_object_free(json_no);
8982 }
8983 else
8984 vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
8985 return NULL;
8986 }
8987 }
8988 return peer;
8989 }
8990
8991 /* Peer structure lookup. */
8992 peer = peer_lookup (bgp, &su);
8993 if (! peer)
8994 {
8995 if (use_json)
8996 {
8997 json_object *json_no = NULL;
8998 json_no = json_object_new_object();
8999 json_object_string_add(json_no, "warning","No such neighbor");
9000 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
9001 json_object_free(json_no);
9002 }
9003 else
9004 vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
9005 return NULL;
9006 }
9007
9008 return peer;
9009 }
9010
9011 enum bgp_stats
9012 {
9013 BGP_STATS_MAXBITLEN = 0,
9014 BGP_STATS_RIB,
9015 BGP_STATS_PREFIXES,
9016 BGP_STATS_TOTPLEN,
9017 BGP_STATS_UNAGGREGATEABLE,
9018 BGP_STATS_MAX_AGGREGATEABLE,
9019 BGP_STATS_AGGREGATES,
9020 BGP_STATS_SPACE,
9021 BGP_STATS_ASPATH_COUNT,
9022 BGP_STATS_ASPATH_MAXHOPS,
9023 BGP_STATS_ASPATH_TOTHOPS,
9024 BGP_STATS_ASPATH_MAXSIZE,
9025 BGP_STATS_ASPATH_TOTSIZE,
9026 BGP_STATS_ASN_HIGHEST,
9027 BGP_STATS_MAX,
9028 };
9029
9030 static const char *table_stats_strs[] =
9031 {
9032 [BGP_STATS_PREFIXES] = "Total Prefixes",
9033 [BGP_STATS_TOTPLEN] = "Average prefix length",
9034 [BGP_STATS_RIB] = "Total Advertisements",
9035 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
9036 [BGP_STATS_MAX_AGGREGATEABLE] = "Maximum aggregateable prefixes",
9037 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
9038 [BGP_STATS_SPACE] = "Address space advertised",
9039 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
9040 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
9041 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
9042 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
9043 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
9044 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
9045 [BGP_STATS_MAX] = NULL,
9046 };
9047
9048 struct bgp_table_stats
9049 {
9050 struct bgp_table *table;
9051 unsigned long long counts[BGP_STATS_MAX];
9052 };
9053
9054 #if 0
9055 #define TALLY_SIGFIG 100000
9056 static unsigned long
9057 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
9058 {
9059 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
9060 unsigned long res = (newtot * TALLY_SIGFIG) / count;
9061 unsigned long ret = newtot / count;
9062
9063 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
9064 return ret + 1;
9065 else
9066 return ret;
9067 }
9068 #endif
9069
9070 static int
9071 bgp_table_stats_walker (struct thread *t)
9072 {
9073 struct bgp_node *rn;
9074 struct bgp_node *top;
9075 struct bgp_table_stats *ts = THREAD_ARG (t);
9076 unsigned int space = 0;
9077
9078 if (!(top = bgp_table_top (ts->table)))
9079 return 0;
9080
9081 switch (top->p.family)
9082 {
9083 case AF_INET:
9084 space = IPV4_MAX_BITLEN;
9085 break;
9086 case AF_INET6:
9087 space = IPV6_MAX_BITLEN;
9088 break;
9089 }
9090
9091 ts->counts[BGP_STATS_MAXBITLEN] = space;
9092
9093 for (rn = top; rn; rn = bgp_route_next (rn))
9094 {
9095 struct bgp_info *ri;
9096 struct bgp_node *prn = bgp_node_parent_nolock (rn);
9097 unsigned int rinum = 0;
9098
9099 if (rn == top)
9100 continue;
9101
9102 if (!rn->info)
9103 continue;
9104
9105 ts->counts[BGP_STATS_PREFIXES]++;
9106 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
9107
9108 #if 0
9109 ts->counts[BGP_STATS_AVGPLEN]
9110 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
9111 ts->counts[BGP_STATS_AVGPLEN],
9112 rn->p.prefixlen);
9113 #endif
9114
9115 /* check if the prefix is included by any other announcements */
9116 while (prn && !prn->info)
9117 prn = bgp_node_parent_nolock (prn);
9118
9119 if (prn == NULL || prn == top)
9120 {
9121 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
9122 /* announced address space */
9123 if (space)
9124 ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen);
9125 }
9126 else if (prn->info)
9127 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
9128
9129 for (ri = rn->info; ri; ri = ri->next)
9130 {
9131 rinum++;
9132 ts->counts[BGP_STATS_RIB]++;
9133
9134 if (ri->attr &&
9135 (CHECK_FLAG (ri->attr->flag,
9136 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))))
9137 ts->counts[BGP_STATS_AGGREGATES]++;
9138
9139 /* as-path stats */
9140 if (ri->attr && ri->attr->aspath)
9141 {
9142 unsigned int hops = aspath_count_hops (ri->attr->aspath);
9143 unsigned int size = aspath_size (ri->attr->aspath);
9144 as_t highest = aspath_highest (ri->attr->aspath);
9145
9146 ts->counts[BGP_STATS_ASPATH_COUNT]++;
9147
9148 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
9149 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
9150
9151 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
9152 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
9153
9154 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
9155 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
9156 #if 0
9157 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
9158 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9159 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
9160 hops);
9161 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
9162 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
9163 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
9164 size);
9165 #endif
9166 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
9167 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
9168 }
9169 }
9170 }
9171 return 0;
9172 }
9173
9174 static int
9175 bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
9176 {
9177 struct bgp_table_stats ts;
9178 unsigned int i;
9179
9180 if (!bgp->rib[afi][safi])
9181 {
9182 vty_out (vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
9183 afi, safi, VTY_NEWLINE);
9184 return CMD_WARNING;
9185 }
9186
9187 memset (&ts, 0, sizeof (ts));
9188 ts.table = bgp->rib[afi][safi];
9189 thread_execute (bm->master, bgp_table_stats_walker, &ts, 0);
9190
9191 vty_out (vty, "BGP %s RIB statistics%s%s",
9192 afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE);
9193
9194 for (i = 0; i < BGP_STATS_MAX; i++)
9195 {
9196 if (!table_stats_strs[i])
9197 continue;
9198
9199 switch (i)
9200 {
9201 #if 0
9202 case BGP_STATS_ASPATH_AVGHOPS:
9203 case BGP_STATS_ASPATH_AVGSIZE:
9204 case BGP_STATS_AVGPLEN:
9205 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9206 vty_out (vty, "%12.2f",
9207 (float)ts.counts[i] / (float)TALLY_SIGFIG);
9208 break;
9209 #endif
9210 case BGP_STATS_ASPATH_TOTHOPS:
9211 case BGP_STATS_ASPATH_TOTSIZE:
9212 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9213 vty_out (vty, "%12.2f",
9214 ts.counts[i] ?
9215 (float)ts.counts[i] /
9216 (float)ts.counts[BGP_STATS_ASPATH_COUNT]
9217 : 0);
9218 break;
9219 case BGP_STATS_TOTPLEN:
9220 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9221 vty_out (vty, "%12.2f",
9222 ts.counts[i] ?
9223 (float)ts.counts[i] /
9224 (float)ts.counts[BGP_STATS_PREFIXES]
9225 : 0);
9226 break;
9227 case BGP_STATS_SPACE:
9228 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9229 vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
9230 if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
9231 break;
9232 vty_out (vty, "%30s: ", "%% announced ");
9233 vty_out (vty, "%12.2f%s",
9234 100 * (float)ts.counts[BGP_STATS_SPACE] /
9235 (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]),
9236 VTY_NEWLINE);
9237 vty_out (vty, "%30s: ", "/8 equivalent ");
9238 vty_out (vty, "%12.2f%s",
9239 (float)ts.counts[BGP_STATS_SPACE] /
9240 (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)),
9241 VTY_NEWLINE);
9242 if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
9243 break;
9244 vty_out (vty, "%30s: ", "/24 equivalent ");
9245 vty_out (vty, "%12.2f",
9246 (float)ts.counts[BGP_STATS_SPACE] /
9247 (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24)));
9248 break;
9249 default:
9250 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9251 vty_out (vty, "%12llu", ts.counts[i]);
9252 }
9253
9254 vty_out (vty, "%s", VTY_NEWLINE);
9255 }
9256 return CMD_SUCCESS;
9257 }
9258
9259 enum bgp_pcounts
9260 {
9261 PCOUNT_ADJ_IN = 0,
9262 PCOUNT_DAMPED,
9263 PCOUNT_REMOVED,
9264 PCOUNT_HISTORY,
9265 PCOUNT_STALE,
9266 PCOUNT_VALID,
9267 PCOUNT_ALL,
9268 PCOUNT_COUNTED,
9269 PCOUNT_PFCNT, /* the figure we display to users */
9270 PCOUNT_MAX,
9271 };
9272
9273 static const char *pcount_strs[] =
9274 {
9275 [PCOUNT_ADJ_IN] = "Adj-in",
9276 [PCOUNT_DAMPED] = "Damped",
9277 [PCOUNT_REMOVED] = "Removed",
9278 [PCOUNT_HISTORY] = "History",
9279 [PCOUNT_STALE] = "Stale",
9280 [PCOUNT_VALID] = "Valid",
9281 [PCOUNT_ALL] = "All RIB",
9282 [PCOUNT_COUNTED] = "PfxCt counted",
9283 [PCOUNT_PFCNT] = "Useable",
9284 [PCOUNT_MAX] = NULL,
9285 };
9286
9287 struct peer_pcounts
9288 {
9289 unsigned int count[PCOUNT_MAX];
9290 const struct peer *peer;
9291 const struct bgp_table *table;
9292 };
9293
9294 static int
9295 bgp_peer_count_walker (struct thread *t)
9296 {
9297 struct bgp_node *rn;
9298 struct peer_pcounts *pc = THREAD_ARG (t);
9299 const struct peer *peer = pc->peer;
9300
9301 for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn))
9302 {
9303 struct bgp_adj_in *ain;
9304 struct bgp_info *ri;
9305
9306 for (ain = rn->adj_in; ain; ain = ain->next)
9307 if (ain->peer == peer)
9308 pc->count[PCOUNT_ADJ_IN]++;
9309
9310 for (ri = rn->info; ri; ri = ri->next)
9311 {
9312 char buf[SU_ADDRSTRLEN];
9313
9314 if (ri->peer != peer)
9315 continue;
9316
9317 pc->count[PCOUNT_ALL]++;
9318
9319 if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
9320 pc->count[PCOUNT_DAMPED]++;
9321 if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
9322 pc->count[PCOUNT_HISTORY]++;
9323 if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
9324 pc->count[PCOUNT_REMOVED]++;
9325 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
9326 pc->count[PCOUNT_STALE]++;
9327 if (CHECK_FLAG (ri->flags, BGP_INFO_VALID))
9328 pc->count[PCOUNT_VALID]++;
9329 if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9330 pc->count[PCOUNT_PFCNT]++;
9331
9332 if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
9333 {
9334 pc->count[PCOUNT_COUNTED]++;
9335 if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9336 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9337 peer->host,
9338 inet_ntop(rn->p.family, &rn->p.u.prefix,
9339 buf, SU_ADDRSTRLEN),
9340 rn->p.prefixlen,
9341 ri->flags);
9342 }
9343 else
9344 {
9345 if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9346 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9347 peer->host,
9348 inet_ntop(rn->p.family, &rn->p.u.prefix,
9349 buf, SU_ADDRSTRLEN),
9350 rn->p.prefixlen,
9351 ri->flags);
9352 }
9353 }
9354 }
9355 return 0;
9356 }
9357
9358 static int
9359 bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_char use_json)
9360 {
9361 struct peer_pcounts pcounts = { .peer = peer };
9362 unsigned int i;
9363 json_object *json = NULL;
9364 json_object *json_loop = NULL;
9365
9366 if (use_json)
9367 {
9368 json = json_object_new_object();
9369 json_loop = json_object_new_object();
9370 }
9371
9372 if (!peer || !peer->bgp || !peer->afc[afi][safi]
9373 || !peer->bgp->rib[afi][safi])
9374 {
9375 if (use_json)
9376 {
9377 json_object_string_add(json, "warning", "No such neighbor or address family");
9378 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9379 json_object_free(json);
9380 }
9381 else
9382 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9383
9384 return CMD_WARNING;
9385 }
9386
9387 memset (&pcounts, 0, sizeof(pcounts));
9388 pcounts.peer = peer;
9389 pcounts.table = peer->bgp->rib[afi][safi];
9390
9391 /* in-place call via thread subsystem so as to record execution time
9392 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9393 * * on just vty_read()).
9394 * */
9395 thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
9396
9397 if (use_json)
9398 {
9399 json_object_string_add(json, "prefixCountsFor", peer->host);
9400 json_object_string_add(json, "multiProtocol", afi_safi_print (afi, safi));
9401 json_object_int_add(json, "pfxCounter", peer->pcount[afi][safi]);
9402
9403 for (i = 0; i < PCOUNT_MAX; i++)
9404 json_object_int_add(json_loop, pcount_strs[i], pcounts.count[i]);
9405
9406 json_object_object_add(json, "ribTableWalkCounters", json_loop);
9407
9408 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
9409 {
9410 json_object_string_add(json, "pfxctDriftFor", peer->host);
9411 json_object_string_add(json, "recommended", "Please report this bug, with the above command output");
9412 }
9413 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9414 json_object_free(json);
9415 }
9416 else
9417 {
9418
9419 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
9420 {
9421 vty_out (vty, "Prefix counts for %s/%s, %s%s",
9422 peer->hostname, peer->host, afi_safi_print (afi, safi),
9423 VTY_NEWLINE);
9424 }
9425 else
9426 {
9427 vty_out (vty, "Prefix counts for %s, %s%s",
9428 peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
9429 }
9430
9431 vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
9432 vty_out (vty, "%sCounts from RIB table walk:%s%s",
9433 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
9434
9435 for (i = 0; i < PCOUNT_MAX; i++)
9436 vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts.count[i], VTY_NEWLINE);
9437
9438 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
9439 {
9440 vty_out (vty, "%s [pcount] PfxCt drift!%s",
9441 peer->host, VTY_NEWLINE);
9442 vty_out (vty, "Please report this bug, with the above command output%s",
9443 VTY_NEWLINE);
9444 }
9445 }
9446
9447 return CMD_SUCCESS;
9448 }
9449
9450 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
9451 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
9452 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn|encap|labeled-unicast>]] "
9453 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9454 SHOW_STR
9455 IP_STR
9456 BGP_STR
9457 BGP_INSTANCE_HELP_STR
9458 "Address Family\n"
9459 "Address Family\n"
9460 "Address Family modifier\n"
9461 "Address Family modifier\n"
9462 "Address Family modifier\n"
9463 "Address Family modifier\n"
9464 "Address Family modifier\n"
9465 "Detailed information on TCP and BGP neighbor connections\n"
9466 "Neighbor to display information about\n"
9467 "Neighbor to display information about\n"
9468 "Neighbor on BGP configured interface\n"
9469 "Display detailed prefix count information\n"
9470 JSON_STR)
9471 {
9472 afi_t afi = AFI_IP6;
9473 safi_t safi = SAFI_UNICAST;
9474 struct peer *peer;
9475 int idx = 0;
9476 struct bgp *bgp = NULL;
9477
9478 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9479 if (!idx)
9480 return CMD_WARNING;
9481
9482 int uj = use_json (argc, argv);
9483 if (uj) argc--;
9484
9485 argv_find (argv, argc, "neighbors", &idx);
9486 peer = peer_lookup_in_view (vty, bgp, argv[idx+1]->arg, uj);
9487 if (! peer)
9488 return CMD_WARNING;
9489
9490 return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
9491 }
9492
9493 #ifdef KEEP_OLD_VPN_COMMANDS
9494 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
9495 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
9496 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9497 SHOW_STR
9498 IP_STR
9499 BGP_STR
9500 BGP_VPNVX_HELP_STR
9501 "Display information about all VPNv4 NLRIs\n"
9502 "Detailed information on TCP and BGP neighbor connections\n"
9503 "Neighbor to display information about\n"
9504 "Neighbor to display information about\n"
9505 "Neighbor on BGP configured interface\n"
9506 "Display detailed prefix count information\n"
9507 JSON_STR)
9508 {
9509 int idx_peer = 6;
9510 struct peer *peer;
9511 u_char uj = use_json(argc, argv);
9512
9513 peer = peer_lookup_in_view (vty, NULL, argv[idx_peer]->arg, uj);
9514 if (! peer)
9515 return CMD_WARNING;
9516
9517 return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
9518 }
9519
9520 DEFUN (show_ip_bgp_vpn_all_route_prefix,
9521 show_ip_bgp_vpn_all_route_prefix_cmd,
9522 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9523 SHOW_STR
9524 IP_STR
9525 BGP_STR
9526 BGP_VPNVX_HELP_STR
9527 "Display information about all VPNv4 NLRIs\n"
9528 "Network in the BGP routing table to display\n"
9529 "Network in the BGP routing table to display\n"
9530 JSON_STR)
9531 {
9532 int idx = 0;
9533 char *network = NULL;
9534 struct bgp *bgp = bgp_get_default();
9535 if (!bgp)
9536 {
9537 vty_out (vty, "Can't find default instance%s", VTY_NEWLINE);
9538 return CMD_WARNING;
9539 }
9540 network = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
9541 network = argv_find (argv, argc, "A.B.C.D/M", &idx) ? argv[idx]->arg : NULL;
9542 return bgp_show_route (vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
9543 }
9544 #endif /* KEEP_OLD_VPN_COMMANDS */
9545
9546 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
9547 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
9548 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9549 SHOW_STR
9550 IP_STR
9551 BGP_STR
9552 L2VPN_HELP_STR
9553 EVPN_HELP_STR
9554 "Display information about all EVPN NLRIs\n"
9555 "Network in the BGP routing table to display\n"
9556 "Network in the BGP routing table to display\n"
9557 JSON_STR)
9558 {
9559 int idx = 0;
9560 char *network = NULL;
9561 network = argv_find (argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
9562 network = argv_find (argv, argc, "A.B.C.D/M", &idx) ? argv[idx]->arg : NULL;
9563 return bgp_show_route (vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
9564 }
9565
9566 static void
9567 show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
9568 int in, const char *rmap_name, u_char use_json, json_object *json)
9569 {
9570 struct bgp_table *table;
9571 struct bgp_adj_in *ain;
9572 struct bgp_adj_out *adj;
9573 unsigned long output_count;
9574 unsigned long filtered_count;
9575 struct bgp_node *rn;
9576 int header1 = 1;
9577 struct bgp *bgp;
9578 int header2 = 1;
9579 struct attr attr;
9580 struct attr_extra extra;
9581 int ret;
9582 struct update_subgroup *subgrp;
9583 json_object *json_scode = NULL;
9584 json_object *json_ocode = NULL;
9585 json_object *json_ar = NULL;
9586 struct peer_af *paf;
9587
9588 if (use_json)
9589 {
9590 json_scode = json_object_new_object();
9591 json_ocode = json_object_new_object();
9592 json_ar = json_object_new_object();
9593
9594 json_object_string_add(json_scode, "suppressed", "s");
9595 json_object_string_add(json_scode, "damped", "d");
9596 json_object_string_add(json_scode, "history", "h");
9597 json_object_string_add(json_scode, "valid", "*");
9598 json_object_string_add(json_scode, "best", ">");
9599 json_object_string_add(json_scode, "multipath", "=");
9600 json_object_string_add(json_scode, "internal", "i");
9601 json_object_string_add(json_scode, "ribFailure", "r");
9602 json_object_string_add(json_scode, "stale", "S");
9603 json_object_string_add(json_scode, "removed", "R");
9604
9605 json_object_string_add(json_ocode, "igp", "i");
9606 json_object_string_add(json_ocode, "egp", "e");
9607 json_object_string_add(json_ocode, "incomplete", "?");
9608 }
9609
9610 bgp = peer->bgp;
9611
9612 if (! bgp)
9613 {
9614 if (use_json)
9615 {
9616 json_object_string_add(json, "alert", "no BGP");
9617 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9618 json_object_free(json);
9619 }
9620 else
9621 vty_out (vty, "%% No bgp%s", VTY_NEWLINE);
9622 return;
9623 }
9624
9625 table = bgp->rib[afi][safi];
9626
9627 output_count = filtered_count = 0;
9628 subgrp = peer_subgroup(peer, afi, safi);
9629
9630 if (!in && subgrp && CHECK_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
9631 {
9632 if (use_json)
9633 {
9634 json_object_int_add(json, "bgpTableVersion", table->version);
9635 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9636 json_object_object_add(json, "bgpStatusCodes", json_scode);
9637 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9638 json_object_string_add(json, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9639 }
9640 else
9641 {
9642 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
9643 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9644 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9645
9646 vty_out (vty, "Originating default network 0.0.0.0%s%s",
9647 VTY_NEWLINE, VTY_NEWLINE);
9648 }
9649 header1 = 0;
9650 }
9651
9652 attr.extra = &extra;
9653 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
9654 {
9655 if (in)
9656 {
9657 for (ain = rn->adj_in; ain; ain = ain->next)
9658 {
9659 if (ain->peer == peer)
9660 {
9661 if (header1)
9662 {
9663 if (use_json)
9664 {
9665 json_object_int_add(json, "bgpTableVersion", 0);
9666 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9667 json_object_object_add(json, "bgpStatusCodes", json_scode);
9668 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9669 }
9670 else
9671 {
9672 vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
9673 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9674 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9675 }
9676 header1 = 0;
9677 }
9678 if (header2)
9679 {
9680 if (!use_json)
9681 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
9682 header2 = 0;
9683 }
9684 if (ain->attr)
9685 {
9686 bgp_attr_dup(&attr, ain->attr);
9687 if (bgp_input_modifier(peer, &rn->p, &attr, afi, safi, rmap_name) != RMAP_DENY)
9688 {
9689 route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
9690 output_count++;
9691 }
9692 else
9693 filtered_count++;
9694 }
9695 }
9696 }
9697 }
9698 else
9699 {
9700 for (adj = rn->adj_out; adj; adj = adj->next)
9701 SUBGRP_FOREACH_PEER(adj->subgroup, paf)
9702 if (paf->peer == peer)
9703 {
9704 if (header1)
9705 {
9706 if (use_json)
9707 {
9708 json_object_int_add(json, "bgpTableVersion", table->version);
9709 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9710 json_object_object_add(json, "bgpStatusCodes", json_scode);
9711 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9712 }
9713 else
9714 {
9715 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version,
9716 inet_ntoa (bgp->router_id), VTY_NEWLINE);
9717 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9718 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9719 }
9720 header1 = 0;
9721 }
9722
9723 if (header2)
9724 {
9725 if (!use_json)
9726 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
9727 header2 = 0;
9728 }
9729
9730 if (adj->attr)
9731 {
9732 bgp_attr_dup(&attr, adj->attr);
9733 ret = bgp_output_modifier(peer, &rn->p, &attr, afi, safi, rmap_name);
9734 if (ret != RMAP_DENY)
9735 {
9736 route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
9737 output_count++;
9738 }
9739 else
9740 filtered_count++;
9741 }
9742 }
9743 }
9744 }
9745 if (use_json)
9746 json_object_object_add(json, "advertisedRoutes", json_ar);
9747
9748 if (output_count != 0)
9749 {
9750 if (use_json)
9751 json_object_int_add(json, "totalPrefixCounter", output_count);
9752 else
9753 vty_out (vty, "%sTotal number of prefixes %ld%s",
9754 VTY_NEWLINE, output_count, VTY_NEWLINE);
9755 }
9756 if (use_json)
9757 {
9758 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9759 json_object_free(json);
9760 }
9761
9762 }
9763
9764 static int
9765 peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
9766 int in, const char *rmap_name, u_char use_json)
9767 {
9768 json_object *json = NULL;
9769
9770 if (use_json)
9771 json = json_object_new_object();
9772
9773 if (!peer || !peer->afc[afi][safi])
9774 {
9775 if (use_json)
9776 {
9777 json_object_string_add(json, "warning", "No such neighbor or address family");
9778 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9779 json_object_free(json);
9780 }
9781 else
9782 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9783
9784 return CMD_WARNING;
9785 }
9786
9787 if (in && !CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
9788 {
9789 if (use_json)
9790 {
9791 json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled");
9792 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9793 json_object_free(json);
9794 }
9795 else
9796 vty_out (vty, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE);
9797
9798 return CMD_WARNING;
9799 }
9800
9801 show_adj_route (vty, peer, afi, safi, in, rmap_name, use_json, json);
9802
9803 return CMD_SUCCESS;
9804 }
9805
9806 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
9807 show_ip_bgp_instance_neighbor_advertised_route_cmd,
9808 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9809 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9810 SHOW_STR
9811 IP_STR
9812 BGP_STR
9813 BGP_INSTANCE_HELP_STR
9814 BGP_AFI_HELP_STR
9815 BGP_SAFI_HELP_STR
9816 "Detailed information on TCP and BGP neighbor connections\n"
9817 "Neighbor to display information about\n"
9818 "Neighbor to display information about\n"
9819 "Neighbor on BGP configured interface\n"
9820 "Display the received routes from neighbor\n"
9821 "Display the routes advertised to a BGP neighbor\n"
9822 "Route-map to modify the attributes\n"
9823 "Name of the route map\n"
9824 JSON_STR)
9825 {
9826 afi_t afi = AFI_IP6;
9827 safi_t safi = SAFI_UNICAST;
9828 char *rmap_name = NULL;
9829 char *peerstr = NULL;
9830 int rcvd = 0;
9831 struct bgp *bgp = NULL;
9832 struct peer *peer;
9833
9834 int idx = 0;
9835
9836 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9837 if (!idx)
9838 return CMD_WARNING;
9839
9840 int uj = use_json (argc, argv);
9841 if (uj) argc--;
9842
9843 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9844 argv_find (argv, argc, "neighbors", &idx);
9845 peerstr = argv[++idx]->arg;
9846
9847 peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
9848 if (! peer)
9849 return CMD_WARNING;
9850
9851 if (argv_find (argv, argc, "received-routes", &idx))
9852 rcvd = 1;
9853 if (argv_find (argv, argc, "advertised-routes", &idx))
9854 rcvd = 0;
9855 if (argv_find (argv, argc, "route-map", &idx))
9856 rmap_name = argv[++idx]->arg;
9857
9858 return peer_adj_routes (vty, peer, afi, safi, rcvd, rmap_name, uj);
9859 }
9860
9861 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
9862 show_ip_bgp_neighbor_received_prefix_filter_cmd,
9863 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9864 SHOW_STR
9865 IP_STR
9866 BGP_STR
9867 "Address Family\n"
9868 "Address Family\n"
9869 "Address Family modifier\n"
9870 "Detailed information on TCP and BGP neighbor connections\n"
9871 "Neighbor to display information about\n"
9872 "Neighbor to display information about\n"
9873 "Neighbor on BGP configured interface\n"
9874 "Display information received from a BGP neighbor\n"
9875 "Display the prefixlist filter\n"
9876 JSON_STR)
9877 {
9878 afi_t afi = AFI_IP6;
9879 safi_t safi = SAFI_UNICAST;
9880 char *peerstr = NULL;
9881
9882 char name[BUFSIZ];
9883 union sockunion su;
9884 struct peer *peer;
9885 int count, ret;
9886
9887 int idx = 0;
9888
9889 /* show [ip] bgp */
9890 if (argv_find (argv, argc, "ip", &idx))
9891 afi = AFI_IP;
9892 /* [<ipv4|ipv6> [unicast]] */
9893 if (argv_find (argv, argc, "ipv4", &idx))
9894 afi = AFI_IP;
9895 if (argv_find (argv, argc, "ipv6", &idx))
9896 afi = AFI_IP6;
9897 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9898 argv_find (argv, argc, "neighbors", &idx);
9899 peerstr = argv[++idx]->arg;
9900
9901 u_char uj = use_json(argc, argv);
9902
9903 ret = str2sockunion (peerstr, &su);
9904 if (ret < 0)
9905 {
9906 peer = peer_lookup_by_conf_if (NULL, peerstr);
9907 if (! peer)
9908 {
9909 if (uj)
9910 vty_out (vty, "{}%s", VTY_NEWLINE);
9911 else
9912 vty_out (vty, "%% Malformed address or name: %s%s", peerstr, VTY_NEWLINE);
9913 return CMD_WARNING;
9914 }
9915 }
9916 else
9917 {
9918 peer = peer_lookup (NULL, &su);
9919 if (! peer)
9920 {
9921 if (uj)
9922 vty_out (vty, "{}%s", VTY_NEWLINE);
9923 else
9924 vty_out (vty, "No peer%s", VTY_NEWLINE);
9925 return CMD_WARNING;
9926 }
9927 }
9928
9929 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
9930 count = prefix_bgp_show_prefix_list (NULL, afi, name, uj);
9931 if (count)
9932 {
9933 if (!uj)
9934 vty_out (vty, "Address Family: %s%s", afi_safi_print(afi, safi), VTY_NEWLINE);
9935 prefix_bgp_show_prefix_list (vty, afi, name, uj);
9936 }
9937 else
9938 {
9939 if (uj)
9940 vty_out (vty, "{}%s", VTY_NEWLINE);
9941 else
9942 vty_out (vty, "No functional output%s", VTY_NEWLINE);
9943 }
9944
9945 return CMD_SUCCESS;
9946 }
9947
9948 static int
9949 bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
9950 safi_t safi, enum bgp_show_type type, u_char use_json)
9951 {
9952 if (! peer || ! peer->afc[afi][safi])
9953 {
9954 if (use_json)
9955 {
9956 json_object *json_no = NULL;
9957 json_no = json_object_new_object();
9958 json_object_string_add(json_no, "warning", "No such neighbor or address family");
9959 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
9960 json_object_free(json_no);
9961 }
9962 else
9963 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9964 return CMD_WARNING;
9965 }
9966
9967 return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su, use_json);
9968 }
9969
9970 DEFUN (show_ip_bgp_neighbor_routes,
9971 show_ip_bgp_neighbor_routes_cmd,
9972 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9973 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9974 SHOW_STR
9975 IP_STR
9976 BGP_STR
9977 BGP_INSTANCE_HELP_STR
9978 BGP_AFI_HELP_STR
9979 BGP_SAFI_HELP_STR
9980 "Detailed information on TCP and BGP neighbor connections\n"
9981 "Neighbor to display information about\n"
9982 "Neighbor to display information about\n"
9983 "Neighbor on BGP configured interface\n"
9984 "Display flap statistics of the routes learned from neighbor\n"
9985 "Display the dampened routes received from neighbor\n"
9986 "Display routes learned from neighbor\n"
9987 JSON_STR)
9988 {
9989 char *peerstr = NULL;
9990 struct bgp *bgp = NULL;
9991 afi_t afi = AFI_IP6;
9992 safi_t safi = SAFI_UNICAST;
9993 struct peer *peer;
9994 enum bgp_show_type sh_type = bgp_show_type_neighbor;
9995
9996 int idx = 0;
9997
9998 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9999 if (!idx)
10000 return CMD_WARNING;
10001
10002 int uj = use_json (argc, argv);
10003 if (uj) argc--;
10004
10005 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
10006 argv_find (argv, argc, "neighbors", &idx);
10007 peerstr = argv[++idx]->arg;
10008
10009 peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
10010 if (! peer)
10011 {
10012 vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
10013 return CMD_WARNING;
10014 }
10015
10016 if (argv_find (argv, argc, "flap-statistics", &idx))
10017 sh_type = bgp_show_type_flap_neighbor;
10018 else if (argv_find (argv, argc, "dampened-routes", &idx))
10019 sh_type = bgp_show_type_damp_neighbor;
10020 else if (argv_find (argv, argc, "routes", &idx))
10021 sh_type = bgp_show_type_neighbor;
10022
10023 return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj);
10024 }
10025
10026 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
10027
10028 struct bgp_distance
10029 {
10030 /* Distance value for the IP source prefix. */
10031 u_char distance;
10032
10033 /* Name of the access-list to be matched. */
10034 char *access_list;
10035 };
10036
10037 DEFUN (show_bgp_afi_vpn_rd_route,
10038 show_bgp_afi_vpn_rd_route_cmd,
10039 "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:nn_or_IP-address:nn <A.B.C.D/M|X:X::X:X/M> [json]",
10040 SHOW_STR
10041 BGP_STR
10042 BGP_AFI_HELP_STR
10043 "Address Family modifier\n"
10044 "Display information for a route distinguisher\n"
10045 "Route Distinguisher\n"
10046 "Network in the BGP routing table to display\n"
10047 "Network in the BGP routing table to display\n"
10048 JSON_STR)
10049 {
10050 int ret;
10051 struct prefix_rd prd;
10052 afi_t afi = AFI_MAX;
10053 int idx = 0;
10054
10055 argv_find_and_parse_afi (argv, argc, &idx, &afi);
10056 ret = str2prefix_rd (argv[5]->arg, &prd);
10057 if (! ret)
10058 {
10059 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
10060 return CMD_WARNING;
10061 }
10062 return bgp_show_route (vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
10063 }
10064
10065 static struct bgp_distance *
10066 bgp_distance_new (void)
10067 {
10068 return XCALLOC (MTYPE_BGP_DISTANCE, sizeof (struct bgp_distance));
10069 }
10070
10071 static void
10072 bgp_distance_free (struct bgp_distance *bdistance)
10073 {
10074 XFREE (MTYPE_BGP_DISTANCE, bdistance);
10075 }
10076
10077 static int
10078 bgp_distance_set (struct vty *vty, const char *distance_str,
10079 const char *ip_str, const char *access_list_str)
10080 {
10081 int ret;
10082 afi_t afi;
10083 safi_t safi;
10084 struct prefix p;
10085 u_char distance;
10086 struct bgp_node *rn;
10087 struct bgp_distance *bdistance;
10088
10089 afi = bgp_node_afi (vty);
10090 safi = bgp_node_safi (vty);
10091
10092 ret = str2prefix (ip_str, &p);
10093 if (ret == 0)
10094 {
10095 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
10096 return CMD_WARNING;
10097 }
10098
10099 distance = atoi (distance_str);
10100
10101 /* Get BGP distance node. */
10102 rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p);
10103 if (rn->info)
10104 {
10105 bdistance = rn->info;
10106 bgp_unlock_node (rn);
10107 }
10108 else
10109 {
10110 bdistance = bgp_distance_new ();
10111 rn->info = bdistance;
10112 }
10113
10114 /* Set distance value. */
10115 bdistance->distance = distance;
10116
10117 /* Reset access-list configuration. */
10118 if (bdistance->access_list)
10119 {
10120 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10121 bdistance->access_list = NULL;
10122 }
10123 if (access_list_str)
10124 bdistance->access_list = XSTRDUP(MTYPE_AS_LIST, access_list_str);
10125
10126 return CMD_SUCCESS;
10127 }
10128
10129 static int
10130 bgp_distance_unset (struct vty *vty, const char *distance_str,
10131 const char *ip_str, const char *access_list_str)
10132 {
10133 int ret;
10134 afi_t afi;
10135 safi_t safi;
10136 struct prefix p;
10137 int distance;
10138 struct bgp_node *rn;
10139 struct bgp_distance *bdistance;
10140
10141 afi = bgp_node_afi (vty);
10142 safi = bgp_node_safi (vty);
10143
10144 ret = str2prefix (ip_str, &p);
10145 if (ret == 0)
10146 {
10147 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
10148 return CMD_WARNING;
10149 }
10150
10151 rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p);
10152 if (! rn)
10153 {
10154 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
10155 return CMD_WARNING;
10156 }
10157
10158 bdistance = rn->info;
10159 distance = atoi(distance_str);
10160
10161 if (bdistance->distance != distance)
10162 {
10163 vty_out (vty, "Distance does not match configured%s", VTY_NEWLINE);
10164 return CMD_WARNING;
10165 }
10166
10167 if (bdistance->access_list)
10168 XFREE(MTYPE_AS_LIST, bdistance->access_list);
10169 bgp_distance_free (bdistance);
10170
10171 rn->info = NULL;
10172 bgp_unlock_node (rn);
10173 bgp_unlock_node (rn);
10174
10175 return CMD_SUCCESS;
10176 }
10177
10178 /* Apply BGP information to distance method. */
10179 u_char
10180 bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
10181 safi_t safi, struct bgp *bgp)
10182 {
10183 struct bgp_node *rn;
10184 struct prefix q;
10185 struct peer *peer;
10186 struct bgp_distance *bdistance;
10187 struct access_list *alist;
10188 struct bgp_static *bgp_static;
10189
10190 if (! bgp)
10191 return 0;
10192
10193 peer = rinfo->peer;
10194
10195 /* Check source address. */
10196 sockunion2hostprefix (&peer->su, &q);
10197 rn = bgp_node_match (bgp_distance_table[afi][safi], &q);
10198 if (rn)
10199 {
10200 bdistance = rn->info;
10201 bgp_unlock_node (rn);
10202
10203 if (bdistance->access_list)
10204 {
10205 alist = access_list_lookup (afi, bdistance->access_list);
10206 if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
10207 return bdistance->distance;
10208 }
10209 else
10210 return bdistance->distance;
10211 }
10212
10213 /* Backdoor check. */
10214 rn = bgp_node_lookup (bgp->route[afi][safi], p);
10215 if (rn)
10216 {
10217 bgp_static = rn->info;
10218 bgp_unlock_node (rn);
10219
10220 if (bgp_static->backdoor)
10221 {
10222 if (bgp->distance_local[afi][safi])
10223 return bgp->distance_local[afi][safi];
10224 else
10225 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10226 }
10227 }
10228
10229 if (peer->sort == BGP_PEER_EBGP)
10230 {
10231 if (bgp->distance_ebgp[afi][safi])
10232 return bgp->distance_ebgp[afi][safi];
10233 return ZEBRA_EBGP_DISTANCE_DEFAULT;
10234 }
10235 else
10236 {
10237 if (bgp->distance_ibgp[afi][safi])
10238 return bgp->distance_ibgp[afi][safi];
10239 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10240 }
10241 }
10242
10243 DEFUN (bgp_distance,
10244 bgp_distance_cmd,
10245 "distance bgp (1-255) (1-255) (1-255)",
10246 "Define an administrative distance\n"
10247 "BGP distance\n"
10248 "Distance for routes external to the AS\n"
10249 "Distance for routes internal to the AS\n"
10250 "Distance for local routes\n")
10251 {
10252 VTY_DECLVAR_CONTEXT(bgp, bgp);
10253 int idx_number = 2;
10254 int idx_number_2 = 3;
10255 int idx_number_3 = 4;
10256 afi_t afi;
10257 safi_t safi;
10258
10259 afi = bgp_node_afi (vty);
10260 safi = bgp_node_safi (vty);
10261
10262 bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg);
10263 bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg);
10264 bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg);
10265 return CMD_SUCCESS;
10266 }
10267
10268 DEFUN (no_bgp_distance,
10269 no_bgp_distance_cmd,
10270 "no distance bgp [(1-255) (1-255) (1-255)]",
10271 NO_STR
10272 "Define an administrative distance\n"
10273 "BGP distance\n"
10274 "Distance for routes external to the AS\n"
10275 "Distance for routes internal to the AS\n"
10276 "Distance for local routes\n")
10277 {
10278 VTY_DECLVAR_CONTEXT(bgp, bgp);
10279 afi_t afi;
10280 safi_t safi;
10281
10282 afi = bgp_node_afi (vty);
10283 safi = bgp_node_safi (vty);
10284
10285 bgp->distance_ebgp[afi][safi] = 0;
10286 bgp->distance_ibgp[afi][safi] = 0;
10287 bgp->distance_local[afi][safi] = 0;
10288 return CMD_SUCCESS;
10289 }
10290
10291
10292 DEFUN (bgp_distance_source,
10293 bgp_distance_source_cmd,
10294 "distance (1-255) A.B.C.D/M",
10295 "Define an administrative distance\n"
10296 "Administrative distance\n"
10297 "IP source prefix\n")
10298 {
10299 int idx_number = 1;
10300 int idx_ipv4_prefixlen = 2;
10301 bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
10302 return CMD_SUCCESS;
10303 }
10304
10305 DEFUN (no_bgp_distance_source,
10306 no_bgp_distance_source_cmd,
10307 "no distance (1-255) A.B.C.D/M",
10308 NO_STR
10309 "Define an administrative distance\n"
10310 "Administrative distance\n"
10311 "IP source prefix\n")
10312 {
10313 int idx_number = 2;
10314 int idx_ipv4_prefixlen = 3;
10315 bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
10316 return CMD_SUCCESS;
10317 }
10318
10319 DEFUN (bgp_distance_source_access_list,
10320 bgp_distance_source_access_list_cmd,
10321 "distance (1-255) A.B.C.D/M WORD",
10322 "Define an administrative distance\n"
10323 "Administrative distance\n"
10324 "IP source prefix\n"
10325 "Access list name\n")
10326 {
10327 int idx_number = 1;
10328 int idx_ipv4_prefixlen = 2;
10329 int idx_word = 3;
10330 bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10331 return CMD_SUCCESS;
10332 }
10333
10334 DEFUN (no_bgp_distance_source_access_list,
10335 no_bgp_distance_source_access_list_cmd,
10336 "no distance (1-255) A.B.C.D/M WORD",
10337 NO_STR
10338 "Define an administrative distance\n"
10339 "Administrative distance\n"
10340 "IP source prefix\n"
10341 "Access list name\n")
10342 {
10343 int idx_number = 2;
10344 int idx_ipv4_prefixlen = 3;
10345 int idx_word = 4;
10346 bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10347 return CMD_SUCCESS;
10348 }
10349
10350 DEFUN (ipv6_bgp_distance_source,
10351 ipv6_bgp_distance_source_cmd,
10352 "distance (1-255) X:X::X:X/M",
10353 "Define an administrative distance\n"
10354 "Administrative distance\n"
10355 "IP source prefix\n")
10356 {
10357 bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL);
10358 return CMD_SUCCESS;
10359 }
10360
10361 DEFUN (no_ipv6_bgp_distance_source,
10362 no_ipv6_bgp_distance_source_cmd,
10363 "no distance (1-255) X:X::X:X/M",
10364 NO_STR
10365 "Define an administrative distance\n"
10366 "Administrative distance\n"
10367 "IP source prefix\n")
10368 {
10369 bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL);
10370 return CMD_SUCCESS;
10371 }
10372
10373 DEFUN (ipv6_bgp_distance_source_access_list,
10374 ipv6_bgp_distance_source_access_list_cmd,
10375 "distance (1-255) X:X::X:X/M WORD",
10376 "Define an administrative distance\n"
10377 "Administrative distance\n"
10378 "IP source prefix\n"
10379 "Access list name\n")
10380 {
10381 bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
10382 return CMD_SUCCESS;
10383 }
10384
10385 DEFUN (no_ipv6_bgp_distance_source_access_list,
10386 no_ipv6_bgp_distance_source_access_list_cmd,
10387 "no distance (1-255) X:X::X:X/M WORD",
10388 NO_STR
10389 "Define an administrative distance\n"
10390 "Administrative distance\n"
10391 "IP source prefix\n"
10392 "Access list name\n")
10393 {
10394 bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
10395 return CMD_SUCCESS;
10396 }
10397
10398 DEFUN (bgp_damp_set,
10399 bgp_damp_set_cmd,
10400 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10401 "BGP Specific commands\n"
10402 "Enable route-flap dampening\n"
10403 "Half-life time for the penalty\n"
10404 "Value to start reusing a route\n"
10405 "Value to start suppressing a route\n"
10406 "Maximum duration to suppress a stable route\n")
10407 {
10408 VTY_DECLVAR_CONTEXT(bgp, bgp);
10409 int idx_half_life = 2;
10410 int idx_reuse = 3;
10411 int idx_suppress = 4;
10412 int idx_max_suppress = 5;
10413 int half = DEFAULT_HALF_LIFE * 60;
10414 int reuse = DEFAULT_REUSE;
10415 int suppress = DEFAULT_SUPPRESS;
10416 int max = 4 * half;
10417
10418 if (argc == 6)
10419 {
10420 half = atoi (argv[idx_half_life]->arg) * 60;
10421 reuse = atoi (argv[idx_reuse]->arg);
10422 suppress = atoi (argv[idx_suppress]->arg);
10423 max = atoi (argv[idx_max_suppress]->arg) * 60;
10424 }
10425 else if (argc == 3)
10426 {
10427 half = atoi (argv[idx_half_life]->arg) * 60;
10428 max = 4 * half;
10429 }
10430
10431 if (suppress < reuse)
10432 {
10433 vty_out (vty, "Suppress value cannot be less than reuse value %s",
10434 VTY_NEWLINE);
10435 return 0;
10436 }
10437
10438 return bgp_damp_enable (bgp, bgp_node_afi (vty), bgp_node_safi (vty),
10439 half, reuse, suppress, max);
10440 }
10441
10442 DEFUN (bgp_damp_unset,
10443 bgp_damp_unset_cmd,
10444 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10445 NO_STR
10446 "BGP Specific commands\n"
10447 "Enable route-flap dampening\n"
10448 "Half-life time for the penalty\n"
10449 "Value to start reusing a route\n"
10450 "Value to start suppressing a route\n"
10451 "Maximum duration to suppress a stable route\n")
10452 {
10453 VTY_DECLVAR_CONTEXT(bgp, bgp);
10454 return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
10455 }
10456
10457 /* Display specified route of BGP table. */
10458 static int
10459 bgp_clear_damp_route (struct vty *vty, const char *view_name,
10460 const char *ip_str, afi_t afi, safi_t safi,
10461 struct prefix_rd *prd, int prefix_check)
10462 {
10463 int ret;
10464 struct prefix match;
10465 struct bgp_node *rn;
10466 struct bgp_node *rm;
10467 struct bgp_info *ri;
10468 struct bgp_info *ri_temp;
10469 struct bgp *bgp;
10470 struct bgp_table *table;
10471
10472 /* BGP structure lookup. */
10473 if (view_name)
10474 {
10475 bgp = bgp_lookup_by_name (view_name);
10476 if (bgp == NULL)
10477 {
10478 vty_out (vty, "%% Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
10479 return CMD_WARNING;
10480 }
10481 }
10482 else
10483 {
10484 bgp = bgp_get_default ();
10485 if (bgp == NULL)
10486 {
10487 vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
10488 return CMD_WARNING;
10489 }
10490 }
10491
10492 /* Check IP address argument. */
10493 ret = str2prefix (ip_str, &match);
10494 if (! ret)
10495 {
10496 vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
10497 return CMD_WARNING;
10498 }
10499
10500 match.family = afi2family (afi);
10501
10502 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
10503 {
10504 for (rn = bgp_table_top (bgp->rib[AFI_IP][safi]); rn; rn = bgp_route_next (rn))
10505 {
10506 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
10507 continue;
10508
10509 if ((table = rn->info) != NULL)
10510 if ((rm = bgp_node_match (table, &match)) != NULL)
10511 {
10512 if (! prefix_check || rm->p.prefixlen == match.prefixlen)
10513 {
10514 ri = rm->info;
10515 while (ri)
10516 {
10517 if (ri->extra && ri->extra->damp_info)
10518 {
10519 ri_temp = ri->next;
10520 bgp_damp_info_free (ri->extra->damp_info, 1);
10521 ri = ri_temp;
10522 }
10523 else
10524 ri = ri->next;
10525 }
10526 }
10527
10528 bgp_unlock_node (rm);
10529 }
10530 }
10531 }
10532 else
10533 {
10534 if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
10535 {
10536 if (! prefix_check || rn->p.prefixlen == match.prefixlen)
10537 {
10538 ri = rn->info;
10539 while (ri)
10540 {
10541 if (ri->extra && ri->extra->damp_info)
10542 {
10543 ri_temp = ri->next;
10544 bgp_damp_info_free (ri->extra->damp_info, 1);
10545 ri = ri_temp;
10546 }
10547 else
10548 ri = ri->next;
10549 }
10550 }
10551
10552 bgp_unlock_node (rn);
10553 }
10554 }
10555
10556 return CMD_SUCCESS;
10557 }
10558
10559 DEFUN (clear_ip_bgp_dampening,
10560 clear_ip_bgp_dampening_cmd,
10561 "clear ip bgp dampening",
10562 CLEAR_STR
10563 IP_STR
10564 BGP_STR
10565 "Clear route flap dampening information\n")
10566 {
10567 bgp_damp_info_clean ();
10568 return CMD_SUCCESS;
10569 }
10570
10571 DEFUN (clear_ip_bgp_dampening_prefix,
10572 clear_ip_bgp_dampening_prefix_cmd,
10573 "clear ip bgp dampening A.B.C.D/M",
10574 CLEAR_STR
10575 IP_STR
10576 BGP_STR
10577 "Clear route flap dampening information\n"
10578 "IPv4 prefix\n")
10579 {
10580 int idx_ipv4_prefixlen = 4;
10581 return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
10582 SAFI_UNICAST, NULL, 1);
10583 }
10584
10585 DEFUN (clear_ip_bgp_dampening_address,
10586 clear_ip_bgp_dampening_address_cmd,
10587 "clear ip bgp dampening A.B.C.D",
10588 CLEAR_STR
10589 IP_STR
10590 BGP_STR
10591 "Clear route flap dampening information\n"
10592 "Network to clear damping information\n")
10593 {
10594 int idx_ipv4 = 4;
10595 return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
10596 SAFI_UNICAST, NULL, 0);
10597 }
10598
10599 DEFUN (clear_ip_bgp_dampening_address_mask,
10600 clear_ip_bgp_dampening_address_mask_cmd,
10601 "clear ip bgp dampening A.B.C.D A.B.C.D",
10602 CLEAR_STR
10603 IP_STR
10604 BGP_STR
10605 "Clear route flap dampening information\n"
10606 "Network to clear damping information\n"
10607 "Network mask\n")
10608 {
10609 int idx_ipv4 = 4;
10610 int idx_ipv4_2 = 5;
10611 int ret;
10612 char prefix_str[BUFSIZ];
10613
10614 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
10615 if (! ret)
10616 {
10617 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
10618 return CMD_WARNING;
10619 }
10620
10621 return bgp_clear_damp_route (vty, NULL, prefix_str, AFI_IP,
10622 SAFI_UNICAST, NULL, 0);
10623 }
10624
10625 /* also used for encap safi */
10626 static int
10627 bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
10628 afi_t afi, safi_t safi, int *write)
10629 {
10630 struct bgp_node *prn;
10631 struct bgp_node *rn;
10632 struct bgp_table *table;
10633 struct prefix *p;
10634 struct prefix_rd *prd;
10635 struct bgp_static *bgp_static;
10636 u_int32_t label;
10637 char buf[SU_ADDRSTRLEN];
10638 char rdbuf[RD_ADDRSTRLEN];
10639
10640 /* Network configuration. */
10641 for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
10642 if ((table = prn->info) != NULL)
10643 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
10644 if ((bgp_static = rn->info) != NULL)
10645 {
10646 p = &rn->p;
10647 prd = (struct prefix_rd *) &prn->p;
10648
10649 /* "address-family" display. */
10650 bgp_config_write_family_header (vty, afi, safi, write);
10651
10652 /* "network" configuration display. */
10653 prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
10654 label = decode_label (bgp_static->tag);
10655
10656 vty_out (vty, " network %s/%d rd %s tag %d",
10657 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10658 p->prefixlen,
10659 rdbuf, label);
10660 vty_out (vty, "%s", VTY_NEWLINE);
10661 }
10662 return 0;
10663 }
10664
10665 static int
10666 bgp_config_write_network_evpn (struct vty *vty, struct bgp *bgp,
10667 afi_t afi, safi_t safi, int *write)
10668 {
10669 struct bgp_node *prn;
10670 struct bgp_node *rn;
10671 struct bgp_table *table;
10672 struct prefix *p;
10673 struct prefix_rd *prd;
10674 struct bgp_static *bgp_static;
10675 char buf[PREFIX_STRLEN];
10676 char buf2[SU_ADDRSTRLEN];
10677 char rdbuf[RD_ADDRSTRLEN];
10678
10679 /* Network configuration. */
10680 for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
10681 if ((table = prn->info) != NULL)
10682 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
10683 if ((bgp_static = rn->info) != NULL)
10684 {
10685 char *macrouter = NULL;
10686 char *esi = NULL;
10687
10688 if(bgp_static->router_mac)
10689 macrouter = prefix_mac2str(bgp_static->router_mac, NULL, 0);
10690 if(bgp_static->eth_s_id)
10691 esi = esi2str(bgp_static->eth_s_id);
10692 p = &rn->p;
10693 prd = (struct prefix_rd *) &prn->p;
10694
10695 /* "address-family" display. */
10696 bgp_config_write_family_header (vty, afi, safi, write);
10697
10698 /* "network" configuration display. */
10699 prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
10700
10701 inet_ntop (AF_INET, &bgp_static->igpnexthop, buf2, SU_ADDRSTRLEN);
10702
10703 prefix2str (p, buf, sizeof (buf)),
10704 vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10705 buf, rdbuf, p->u.prefix_evpn.eth_tag,
10706 decode_label (bgp_static->tag), esi, buf2 , macrouter);
10707 vty_out (vty, "%s", VTY_NEWLINE);
10708 if (macrouter)
10709 XFREE (MTYPE_TMP, macrouter);
10710 if (esi)
10711 XFREE (MTYPE_TMP, esi);
10712 }
10713 return 0;
10714 }
10715
10716 /* Configuration of static route announcement and aggregate
10717 information. */
10718 int
10719 bgp_config_write_network (struct vty *vty, struct bgp *bgp,
10720 afi_t afi, safi_t safi, int *write)
10721 {
10722 struct bgp_node *rn;
10723 struct prefix *p;
10724 struct bgp_static *bgp_static;
10725 struct bgp_aggregate *bgp_aggregate;
10726 char buf[SU_ADDRSTRLEN];
10727
10728 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
10729 return bgp_config_write_network_vpn (vty, bgp, afi, safi, write);
10730
10731 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
10732 return bgp_config_write_network_evpn (vty, bgp, afi, safi, write);
10733
10734 /* Network configuration. */
10735 for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
10736 if ((bgp_static = rn->info) != NULL)
10737 {
10738 p = &rn->p;
10739
10740 /* "address-family" display. */
10741 bgp_config_write_family_header (vty, afi, safi, write);
10742
10743 /* "network" configuration display. */
10744 if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
10745 {
10746 u_int32_t destination;
10747 struct in_addr netmask;
10748
10749 destination = ntohl (p->u.prefix4.s_addr);
10750 masklen2ip (p->prefixlen, &netmask);
10751 vty_out (vty, " network %s",
10752 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN));
10753
10754 if ((IN_CLASSC (destination) && p->prefixlen == 24)
10755 || (IN_CLASSB (destination) && p->prefixlen == 16)
10756 || (IN_CLASSA (destination) && p->prefixlen == 8)
10757 || p->u.prefix4.s_addr == 0)
10758 {
10759 /* Natural mask is not display. */
10760 }
10761 else
10762 vty_out (vty, " mask %s", inet_ntoa (netmask));
10763 }
10764 else
10765 {
10766 vty_out (vty, " network %s/%d",
10767 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10768 p->prefixlen);
10769 }
10770
10771 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
10772 vty_out (vty, " label-index %u", bgp_static->label_index);
10773
10774 if (bgp_static->rmap.name)
10775 vty_out (vty, " route-map %s", bgp_static->rmap.name);
10776 else
10777 {
10778 if (bgp_static->backdoor)
10779 vty_out (vty, " backdoor");
10780 }
10781
10782 vty_out (vty, "%s", VTY_NEWLINE);
10783 }
10784
10785 /* Aggregate-address configuration. */
10786 for (rn = bgp_table_top (bgp->aggregate[afi][safi]); rn; rn = bgp_route_next (rn))
10787 if ((bgp_aggregate = rn->info) != NULL)
10788 {
10789 p = &rn->p;
10790
10791 /* "address-family" display. */
10792 bgp_config_write_family_header (vty, afi, safi, write);
10793
10794 if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
10795 {
10796 struct in_addr netmask;
10797
10798 masklen2ip (p->prefixlen, &netmask);
10799 vty_out (vty, " aggregate-address %s %s",
10800 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10801 inet_ntoa (netmask));
10802 }
10803 else
10804 {
10805 vty_out (vty, " aggregate-address %s/%d",
10806 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10807 p->prefixlen);
10808 }
10809
10810 if (bgp_aggregate->as_set)
10811 vty_out (vty, " as-set");
10812
10813 if (bgp_aggregate->summary_only)
10814 vty_out (vty, " summary-only");
10815
10816 vty_out (vty, "%s", VTY_NEWLINE);
10817 }
10818
10819 return 0;
10820 }
10821
10822 int
10823 bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi,
10824 safi_t safi, int *write)
10825 {
10826 struct bgp_node *rn;
10827 struct bgp_distance *bdistance;
10828
10829 /* Distance configuration. */
10830 if (bgp->distance_ebgp[afi][safi]
10831 && bgp->distance_ibgp[afi][safi]
10832 && bgp->distance_local[afi][safi]
10833 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
10834 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
10835 || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT))
10836 {
10837 bgp_config_write_family_header (vty, afi, safi, write);
10838 vty_out (vty, " distance bgp %d %d %d%s",
10839 bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi],
10840 bgp->distance_local[afi][safi], VTY_NEWLINE);
10841 }
10842
10843 for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn;
10844 rn = bgp_route_next (rn))
10845 if ((bdistance = rn->info) != NULL)
10846 {
10847 char buf[PREFIX_STRLEN];
10848
10849 bgp_config_write_family_header (vty, afi, safi, write);
10850 vty_out (vty, " distance %d %s %s%s", bdistance->distance,
10851 prefix2str (&rn->p, buf, sizeof (buf)),
10852 bdistance->access_list ? bdistance->access_list : "",
10853 VTY_NEWLINE);
10854 }
10855
10856 return *write;
10857 }
10858
10859 /* Allocate routing table structure and install commands. */
10860 void
10861 bgp_route_init (void)
10862 {
10863 afi_t afi;
10864 safi_t safi;
10865
10866 /* Init BGP distance table. */
10867 for (afi = AFI_IP; afi < AFI_MAX; afi++)
10868 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
10869 bgp_distance_table[afi][safi] = bgp_table_init (afi, safi);
10870
10871 /* IPv4 BGP commands. */
10872 install_element (BGP_NODE, &bgp_table_map_cmd);
10873 install_element (BGP_NODE, &bgp_network_cmd);
10874 install_element (BGP_NODE, &bgp_network_mask_cmd);
10875 install_element (BGP_NODE, &bgp_network_mask_natural_cmd);
10876 install_element (BGP_NODE, &bgp_network_route_map_cmd);
10877 install_element (BGP_NODE, &bgp_network_mask_route_map_cmd);
10878 install_element (BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
10879 install_element (BGP_NODE, &bgp_network_backdoor_cmd);
10880 install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
10881 install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
10882 install_element (BGP_NODE, &no_bgp_table_map_cmd);
10883 install_element (BGP_NODE, &no_bgp_network_cmd);
10884 install_element (BGP_NODE, &no_bgp_network_mask_cmd);
10885 install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
10886
10887 install_element (BGP_NODE, &aggregate_address_cmd);
10888 install_element (BGP_NODE, &aggregate_address_mask_cmd);
10889 install_element (BGP_NODE, &no_aggregate_address_cmd);
10890 install_element (BGP_NODE, &no_aggregate_address_mask_cmd);
10891
10892 /* IPv4 unicast configuration. */
10893 install_element (BGP_IPV4_NODE, &bgp_table_map_cmd);
10894 install_element (BGP_IPV4_NODE, &bgp_network_cmd);
10895 install_element (BGP_IPV4_NODE, &bgp_network_mask_cmd);
10896 install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
10897 install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
10898 install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
10899 install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
10900 install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_cmd);
10901 install_element (BGP_IPV4L_NODE, &no_bgp_network_label_index_route_map_cmd);
10902 install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
10903 install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
10904 install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
10905 install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
10906
10907 install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
10908 install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
10909 install_element (BGP_IPV4_NODE, &no_aggregate_address_cmd);
10910 install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
10911
10912 /* IPv4 multicast configuration. */
10913 install_element (BGP_IPV4M_NODE, &bgp_table_map_cmd);
10914 install_element (BGP_IPV4M_NODE, &bgp_network_cmd);
10915 install_element (BGP_IPV4M_NODE, &bgp_network_mask_cmd);
10916 install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
10917 install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
10918 install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
10919 install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
10920 install_element (BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
10921 install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
10922 install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
10923 install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
10924 install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
10925 install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
10926 install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
10927 install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
10928
10929 /* IPv4 labeled-unicast configuration. */
10930 install_element (BGP_IPV4L_NODE, &bgp_table_map_cmd);
10931 install_element (BGP_IPV4L_NODE, &bgp_network_cmd);
10932 install_element (BGP_IPV4L_NODE, &bgp_network_mask_cmd);
10933 install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_cmd);
10934 install_element (BGP_IPV4L_NODE, &bgp_network_route_map_cmd);
10935 install_element (BGP_IPV4L_NODE, &bgp_network_mask_route_map_cmd);
10936 install_element (BGP_IPV4L_NODE, &bgp_network_mask_natural_route_map_cmd);
10937 install_element (BGP_IPV4L_NODE, &bgp_network_label_index_cmd);
10938 install_element (BGP_IPV4L_NODE, &bgp_network_label_index_route_map_cmd);
10939 install_element (BGP_IPV4L_NODE, &no_bgp_table_map_cmd);
10940 install_element (BGP_IPV4L_NODE, &no_bgp_network_cmd);
10941 install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_cmd);
10942 install_element (BGP_IPV4L_NODE, &no_bgp_network_mask_natural_cmd);
10943
10944 install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
10945 install_element (VIEW_NODE, &show_ip_bgp_cmd);
10946 install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
10947 install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
10948
10949 install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
10950 install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
10951 install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
10952 #ifdef KEEP_OLD_VPN_COMMANDS
10953 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
10954 #endif /* KEEP_OLD_VPN_COMMANDS */
10955 install_element (VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
10956 install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
10957
10958 /* BGP dampening clear commands */
10959 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
10960 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
10961
10962 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
10963 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
10964
10965 /* prefix count */
10966 install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
10967 #ifdef KEEP_OLD_VPN_COMMANDS
10968 install_element (ENABLE_NODE, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
10969 #endif /* KEEP_OLD_VPN_COMMANDS */
10970
10971 /* New config IPv6 BGP commands. */
10972 install_element (BGP_IPV6_NODE, &bgp_table_map_cmd);
10973 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
10974 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
10975 install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
10976 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
10977 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_cmd);
10978 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_cmd);
10979 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_label_index_route_map_cmd);
10980 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_label_index_route_map_cmd);
10981
10982 install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
10983 install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
10984
10985 install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
10986 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
10987
10988 install_element (BGP_IPV6L_NODE, &bgp_table_map_cmd);
10989 install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
10990 install_element (BGP_IPV6L_NODE, &ipv6_bgp_network_route_map_cmd);
10991 install_element (BGP_IPV6L_NODE, &no_bgp_table_map_cmd);
10992 install_element (BGP_IPV6L_NODE, &no_ipv6_bgp_network_cmd);
10993
10994 install_element (BGP_NODE, &bgp_distance_cmd);
10995 install_element (BGP_NODE, &no_bgp_distance_cmd);
10996 install_element (BGP_NODE, &bgp_distance_source_cmd);
10997 install_element (BGP_NODE, &no_bgp_distance_source_cmd);
10998 install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
10999 install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
11000 install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
11001 install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
11002 install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
11003 install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
11004 install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
11005 install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
11006 install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
11007 install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
11008 install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
11009 install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
11010 install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
11011 install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
11012 install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
11013 install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
11014 install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
11015 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
11016 install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
11017 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
11018 install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
11019 install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
11020 install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
11021 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
11022 install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
11023 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
11024
11025 install_element (BGP_NODE, &bgp_damp_set_cmd);
11026 install_element (BGP_NODE, &bgp_damp_unset_cmd);
11027 install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd);
11028 install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
11029
11030 /* IPv4 Multicast Mode */
11031 install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
11032 install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
11033
11034 /* Large Communities */
11035 install_element (VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
11036 install_element (VIEW_NODE, &show_ip_bgp_large_community_cmd);
11037 }
11038
11039 void
11040 bgp_route_finish (void)
11041 {
11042 afi_t afi;
11043 safi_t safi;
11044
11045 for (afi = AFI_IP; afi < AFI_MAX; afi++)
11046 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
11047 {
11048 bgp_table_unlock (bgp_distance_table[afi][safi]);
11049 bgp_distance_table[afi][safi] = NULL;
11050 }
11051 }