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