]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: remove encap safi show commands
[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 (afi == AFI_IP)
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 *label_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 (label_str)
4495 {
4496 unsigned long label_val;
4497 VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, 16777215);
4498 encode_label (label_val, tag);
4499 }
4500 else
4501 {
4502 memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
4503 }
4504 if (safi == SAFI_EVPN)
4505 {
4506 if( esi && str2esi (esi, NULL) == 0)
4507 {
4508 vty_out (vty, "%% Malformed ESI%s", VTY_NEWLINE);
4509 return CMD_WARNING;
4510 }
4511 if( routermac && prefix_str2mac (routermac, NULL) == 0)
4512 {
4513 vty_out (vty, "%% Malformed Router MAC%s", VTY_NEWLINE);
4514 return CMD_WARNING;
4515 }
4516 if (gwip)
4517 {
4518 memset (&gw_ip, 0, sizeof (struct prefix));
4519 ret = str2prefix (gwip, &gw_ip);
4520 if (! ret)
4521 {
4522 vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
4523 return CMD_WARNING;
4524 }
4525 if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6))
4526 || (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4)))
4527 {
4528 vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
4529 return CMD_WARNING;
4530 }
4531 }
4532 }
4533 prn = bgp_node_get (bgp->route[afi][safi],
4534 (struct prefix *)&prd);
4535 if (prn->info == NULL)
4536 prn->info = bgp_table_init (afi, safi);
4537 else
4538 bgp_unlock_node (prn);
4539 table = prn->info;
4540
4541 rn = bgp_node_get (table, &p);
4542
4543 if (rn->info)
4544 {
4545 vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
4546 bgp_unlock_node (rn);
4547 }
4548 else
4549 {
4550 /* New configuration. */
4551 bgp_static = bgp_static_new ();
4552 bgp_static->backdoor = 0;
4553 bgp_static->valid = 0;
4554 bgp_static->igpmetric = 0;
4555 bgp_static->igpnexthop.s_addr = 0;
4556 memcpy(bgp_static->tag, tag, 3);
4557 bgp_static->prd = prd;
4558
4559 if (rmap_str)
4560 {
4561 if (bgp_static->rmap.name)
4562 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
4563 bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
4564 bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
4565 }
4566
4567 if (safi == SAFI_EVPN)
4568 {
4569 if(esi)
4570 {
4571 bgp_static->eth_s_id = XCALLOC (MTYPE_ATTR, sizeof(struct eth_segment_id));
4572 str2esi (esi, bgp_static->eth_s_id);
4573 }
4574 if( routermac)
4575 {
4576 bgp_static->router_mac = XCALLOC (MTYPE_ATTR, ETHER_ADDR_LEN+1);
4577 prefix_str2mac (routermac, bgp_static->router_mac);
4578 }
4579 if (gwip)
4580 prefix_copy (&bgp_static->gatewayIp, &gw_ip);
4581 }
4582 rn->info = bgp_static;
4583
4584 bgp_static->valid = 1;
4585 bgp_static_update_safi (bgp, &p, bgp_static, afi, safi);
4586 }
4587
4588 return CMD_SUCCESS;
4589 }
4590
4591 /* Configure static BGP network. */
4592 int
4593 bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
4594 const char *rd_str, const char *label_str,
4595 int evpn_type, const char *esi, const char *gwip, const char *ethtag)
4596 {
4597 VTY_DECLVAR_CONTEXT(bgp, bgp);
4598 int ret;
4599 struct prefix p;
4600 struct prefix_rd prd;
4601 struct bgp_node *prn;
4602 struct bgp_node *rn;
4603 struct bgp_table *table;
4604 struct bgp_static *bgp_static;
4605 u_char tag[3];
4606
4607 /* Convert IP prefix string to struct prefix. */
4608 ret = str2prefix (ip_str, &p);
4609 if (! ret)
4610 {
4611 vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
4612 return CMD_WARNING;
4613 }
4614 apply_mask (&p);
4615 if ( (afi == AFI_L2VPN) &&
4616 (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p)))
4617 {
4618 vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE);
4619 return CMD_WARNING;
4620 }
4621 ret = str2prefix_rd (rd_str, &prd);
4622 if (! ret)
4623 {
4624 vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
4625 return CMD_WARNING;
4626 }
4627
4628 if (label_str)
4629 {
4630 unsigned long label_val;
4631 VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, MPLS_LABEL_MAX);
4632 encode_label (label_val, tag);
4633 }
4634 else
4635 {
4636 memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
4637 }
4638
4639 prn = bgp_node_get (bgp->route[afi][safi],
4640 (struct prefix *)&prd);
4641 if (prn->info == NULL)
4642 prn->info = bgp_table_init (afi, safi);
4643 else
4644 bgp_unlock_node (prn);
4645 table = prn->info;
4646
4647 rn = bgp_node_lookup (table, &p);
4648
4649 if (rn)
4650 {
4651 bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd, tag);
4652
4653 bgp_static = rn->info;
4654 bgp_static_free (bgp_static);
4655 rn->info = NULL;
4656 bgp_unlock_node (rn);
4657 bgp_unlock_node (rn);
4658 }
4659 else
4660 vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
4661
4662 return CMD_SUCCESS;
4663 }
4664
4665 static int
4666 bgp_table_map_set (struct vty *vty, afi_t afi, safi_t safi,
4667 const char *rmap_name)
4668 {
4669 VTY_DECLVAR_CONTEXT(bgp, bgp);
4670 struct bgp_rmap *rmap;
4671
4672 rmap = &bgp->table_map[afi][safi];
4673 if (rmap_name)
4674 {
4675 if (rmap->name)
4676 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4677 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
4678 rmap->map = route_map_lookup_by_name (rmap_name);
4679 }
4680 else
4681 {
4682 if (rmap->name)
4683 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4684 rmap->name = NULL;
4685 rmap->map = NULL;
4686 }
4687
4688 bgp_zebra_announce_table(bgp, afi, safi);
4689
4690 return CMD_SUCCESS;
4691 }
4692
4693 static int
4694 bgp_table_map_unset (struct vty *vty, afi_t afi, safi_t safi,
4695 const char *rmap_name)
4696 {
4697 VTY_DECLVAR_CONTEXT(bgp, bgp);
4698 struct bgp_rmap *rmap;
4699
4700 rmap = &bgp->table_map[afi][safi];
4701 if (rmap->name)
4702 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
4703 rmap->name = NULL;
4704 rmap->map = NULL;
4705
4706 bgp_zebra_announce_table(bgp, afi, safi);
4707
4708 return CMD_SUCCESS;
4709 }
4710
4711 int
4712 bgp_config_write_table_map (struct vty *vty, struct bgp *bgp, afi_t afi,
4713 safi_t safi, int *write)
4714 {
4715 if (bgp->table_map[afi][safi].name)
4716 {
4717 bgp_config_write_family_header (vty, afi, safi, write);
4718 vty_out (vty, " table-map %s%s",
4719 bgp->table_map[afi][safi].name, VTY_NEWLINE);
4720 }
4721
4722 return 0;
4723 }
4724
4725 DEFUN (bgp_table_map,
4726 bgp_table_map_cmd,
4727 "table-map WORD",
4728 "BGP table to RIB route download filter\n"
4729 "Name of the route map\n")
4730 {
4731 int idx_word = 1;
4732 return bgp_table_map_set (vty,
4733 bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
4734 }
4735 DEFUN (no_bgp_table_map,
4736 no_bgp_table_map_cmd,
4737 "no table-map WORD",
4738 NO_STR
4739 "BGP table to RIB route download filter\n"
4740 "Name of the route map\n")
4741 {
4742 int idx_word = 2;
4743 return bgp_table_map_unset (vty,
4744 bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
4745 }
4746
4747 DEFUN (bgp_network,
4748 bgp_network_cmd,
4749 "network A.B.C.D/M",
4750 "Specify a network to announce via BGP\n"
4751 "IPv4 prefix\n")
4752 {
4753 int idx_ipv4_prefixlen = 1;
4754 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
4755 AFI_IP, bgp_node_safi (vty), NULL, 0);
4756 }
4757
4758 DEFUN (bgp_network_route_map,
4759 bgp_network_route_map_cmd,
4760 "network A.B.C.D/M route-map WORD",
4761 "Specify a network to announce via BGP\n"
4762 "IPv4 prefix\n"
4763 "Route-map to modify the attributes\n"
4764 "Name of the route map\n")
4765 {
4766 int idx_ipv4_prefixlen = 1;
4767 int idx_word = 3;
4768 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
4769 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
4770 }
4771
4772 DEFUN (bgp_network_backdoor,
4773 bgp_network_backdoor_cmd,
4774 "network A.B.C.D/M backdoor",
4775 "Specify a network to announce via BGP\n"
4776 "IPv4 prefix\n"
4777 "Specify a BGP backdoor route\n")
4778 {
4779 int idx_ipv4_prefixlen = 1;
4780 return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
4781 NULL, 1);
4782 }
4783
4784 DEFUN (bgp_network_mask,
4785 bgp_network_mask_cmd,
4786 "network A.B.C.D mask A.B.C.D",
4787 "Specify a network to announce via BGP\n"
4788 "Network number\n"
4789 "Network mask\n"
4790 "Network mask\n")
4791 {
4792 int idx_ipv4 = 1;
4793 int idx_ipv4_2 = 3;
4794 int ret;
4795 char prefix_str[BUFSIZ];
4796
4797 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4798 if (! ret)
4799 {
4800 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4801 return CMD_WARNING;
4802 }
4803
4804 return bgp_static_set (vty, prefix_str,
4805 AFI_IP, bgp_node_safi (vty), NULL, 0);
4806 }
4807
4808 DEFUN (bgp_network_mask_route_map,
4809 bgp_network_mask_route_map_cmd,
4810 "network A.B.C.D mask A.B.C.D route-map WORD",
4811 "Specify a network to announce via BGP\n"
4812 "Network number\n"
4813 "Network mask\n"
4814 "Network mask\n"
4815 "Route-map to modify the attributes\n"
4816 "Name of the route map\n")
4817 {
4818 int idx_ipv4 = 1;
4819 int idx_ipv4_2 = 3;
4820 int idx_word = 5;
4821 int ret;
4822 char prefix_str[BUFSIZ];
4823
4824 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4825 if (! ret)
4826 {
4827 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4828 return CMD_WARNING;
4829 }
4830
4831 return bgp_static_set (vty, prefix_str,
4832 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
4833 }
4834
4835 DEFUN (bgp_network_mask_backdoor,
4836 bgp_network_mask_backdoor_cmd,
4837 "network A.B.C.D mask A.B.C.D backdoor",
4838 "Specify a network to announce via BGP\n"
4839 "Network number\n"
4840 "Network mask\n"
4841 "Network mask\n"
4842 "Specify a BGP backdoor route\n")
4843 {
4844 int idx_ipv4 = 1;
4845 int idx_ipv4_2 = 3;
4846 int ret;
4847 char prefix_str[BUFSIZ];
4848
4849 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4850 if (! ret)
4851 {
4852 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4853 return CMD_WARNING;
4854 }
4855
4856 return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
4857 NULL, 1);
4858 }
4859
4860 DEFUN (bgp_network_mask_natural,
4861 bgp_network_mask_natural_cmd,
4862 "network A.B.C.D",
4863 "Specify a network to announce via BGP\n"
4864 "Network number\n")
4865 {
4866 int idx_ipv4 = 1;
4867 int ret;
4868 char prefix_str[BUFSIZ];
4869
4870 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4871 if (! ret)
4872 {
4873 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4874 return CMD_WARNING;
4875 }
4876
4877 return bgp_static_set (vty, prefix_str,
4878 AFI_IP, bgp_node_safi (vty), NULL, 0);
4879 }
4880
4881 DEFUN (bgp_network_mask_natural_route_map,
4882 bgp_network_mask_natural_route_map_cmd,
4883 "network A.B.C.D route-map WORD",
4884 "Specify a network to announce via BGP\n"
4885 "Network number\n"
4886 "Route-map to modify the attributes\n"
4887 "Name of the route map\n")
4888 {
4889 int idx_ipv4 = 1;
4890 int idx_word = 3;
4891 int ret;
4892 char prefix_str[BUFSIZ];
4893
4894 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4895 if (! ret)
4896 {
4897 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4898 return CMD_WARNING;
4899 }
4900
4901 return bgp_static_set (vty, prefix_str,
4902 AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
4903 }
4904
4905 DEFUN (bgp_network_mask_natural_backdoor,
4906 bgp_network_mask_natural_backdoor_cmd,
4907 "network A.B.C.D backdoor",
4908 "Specify a network to announce via BGP\n"
4909 "Network number\n"
4910 "Specify a BGP backdoor route\n")
4911 {
4912 int idx_ipv4 = 1;
4913 int ret;
4914 char prefix_str[BUFSIZ];
4915
4916 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4917 if (! ret)
4918 {
4919 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4920 return CMD_WARNING;
4921 }
4922
4923 return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
4924 NULL, 1);
4925 }
4926
4927 DEFUN (no_bgp_network,
4928 no_bgp_network_cmd,
4929 "no network A.B.C.D/M [<backdoor|route-map WORD>]",
4930 NO_STR
4931 "Specify a network to announce via BGP\n"
4932 "IPv4 prefix\n"
4933 "Specify a BGP backdoor route\n"
4934 "Route-map to modify the attributes\n"
4935 "Name of the route map\n")
4936 {
4937 int idx_ipv4_prefixlen = 2;
4938 return bgp_static_unset (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
4939 bgp_node_safi (vty));
4940 }
4941
4942 DEFUN (no_bgp_network_mask,
4943 no_bgp_network_mask_cmd,
4944 "no network A.B.C.D mask A.B.C.D [<backdoor|route-map WORD>]",
4945 NO_STR
4946 "Specify a network to announce via BGP\n"
4947 "Network number\n"
4948 "Network mask\n"
4949 "Network mask\n"
4950 "Specify a BGP backdoor route\n"
4951 "Route-map to modify the attributes\n"
4952 "Name of the route map\n")
4953 {
4954 int idx_ipv4 = 2;
4955 int idx_ipv4_2 = 4;
4956 int ret;
4957 char prefix_str[BUFSIZ];
4958
4959 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
4960 if (! ret)
4961 {
4962 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4963 return CMD_WARNING;
4964 }
4965
4966 return bgp_static_unset (vty, prefix_str, AFI_IP,
4967 bgp_node_safi (vty));
4968 }
4969
4970 DEFUN (no_bgp_network_mask_natural,
4971 no_bgp_network_mask_natural_cmd,
4972 "no network A.B.C.D [<backdoor|route-map WORD>]",
4973 NO_STR
4974 "Specify a network to announce via BGP\n"
4975 "Network number\n"
4976 "Specify a BGP backdoor route\n"
4977 "Route-map to modify the attributes\n"
4978 "Name of the route map\n")
4979 {
4980 int idx_ipv4 = 2;
4981 int ret;
4982 char prefix_str[BUFSIZ];
4983
4984 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
4985 if (! ret)
4986 {
4987 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
4988 return CMD_WARNING;
4989 }
4990
4991 return bgp_static_unset (vty, prefix_str, AFI_IP,
4992 bgp_node_safi (vty));
4993 }
4994
4995 DEFUN (ipv6_bgp_network,
4996 ipv6_bgp_network_cmd,
4997 "network X:X::X:X/M",
4998 "Specify a network to announce via BGP\n"
4999 "IPv6 prefix\n")
5000 {
5001 int idx_ipv6_prefixlen = 1;
5002 return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
5003 NULL, 0);
5004 }
5005
5006 DEFUN (ipv6_bgp_network_route_map,
5007 ipv6_bgp_network_route_map_cmd,
5008 "network X:X::X:X/M route-map WORD",
5009 "Specify a network to announce via BGP\n"
5010 "IPv6 prefix\n"
5011 "Route-map to modify the attributes\n"
5012 "Name of the route map\n")
5013 {
5014 int idx_ipv6_prefixlen = 1;
5015 int idx_word = 3;
5016 return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
5017 bgp_node_safi (vty), argv[idx_word]->arg, 0);
5018 }
5019
5020 DEFUN (no_ipv6_bgp_network,
5021 no_ipv6_bgp_network_cmd,
5022 "no network X:X::X:X/M [route-map WORD]",
5023 NO_STR
5024 "Specify a network to announce via BGP\n"
5025 "IPv6 prefix\n"
5026 "Route-map to modify the attributes\n"
5027 "Name of the route map\n")
5028 {
5029 int idx_ipv6_prefixlen = 2;
5030 return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
5031 }
5032
5033 /* Aggreagete address:
5034
5035 advertise-map Set condition to advertise attribute
5036 as-set Generate AS set path information
5037 attribute-map Set attributes of aggregate
5038 route-map Set parameters of aggregate
5039 summary-only Filter more specific routes from updates
5040 suppress-map Conditionally filter more specific routes from updates
5041 <cr>
5042 */
5043 struct bgp_aggregate
5044 {
5045 /* Summary-only flag. */
5046 u_char summary_only;
5047
5048 /* AS set generation. */
5049 u_char as_set;
5050
5051 /* Route-map for aggregated route. */
5052 struct route_map *map;
5053
5054 /* Suppress-count. */
5055 unsigned long count;
5056
5057 /* SAFI configuration. */
5058 safi_t safi;
5059 };
5060
5061 static struct bgp_aggregate *
5062 bgp_aggregate_new (void)
5063 {
5064 return XCALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
5065 }
5066
5067 static void
5068 bgp_aggregate_free (struct bgp_aggregate *aggregate)
5069 {
5070 XFREE (MTYPE_BGP_AGGREGATE, aggregate);
5071 }
5072
5073 /* Update an aggregate as routes are added/removed from the BGP table */
5074 static void
5075 bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
5076 afi_t afi, safi_t safi, struct bgp_info *del,
5077 struct bgp_aggregate *aggregate)
5078 {
5079 struct bgp_table *table;
5080 struct bgp_node *top;
5081 struct bgp_node *rn;
5082 u_char origin;
5083 struct aspath *aspath = NULL;
5084 struct aspath *asmerge = NULL;
5085 struct community *community = NULL;
5086 struct community *commerge = NULL;
5087 #if defined(AGGREGATE_NEXTHOP_CHECK)
5088 struct in_addr nexthop;
5089 u_int32_t med = 0;
5090 #endif
5091 struct bgp_info *ri;
5092 struct bgp_info *new;
5093 int first = 1;
5094 unsigned long match = 0;
5095 u_char atomic_aggregate = 0;
5096
5097 /* Record adding route's nexthop and med. */
5098 if (rinew)
5099 {
5100 #if defined(AGGREGATE_NEXTHOP_CHECK)
5101 nexthop = rinew->attr->nexthop;
5102 med = rinew->attr->med;
5103 #endif
5104 }
5105
5106 /* ORIGIN attribute: If at least one route among routes that are
5107 aggregated has ORIGIN with the value INCOMPLETE, then the
5108 aggregated route must have the ORIGIN attribute with the value
5109 INCOMPLETE. Otherwise, if at least one route among routes that
5110 are aggregated has ORIGIN with the value EGP, then the aggregated
5111 route must have the origin attribute with the value EGP. In all
5112 other case the value of the ORIGIN attribute of the aggregated
5113 route is INTERNAL. */
5114 origin = BGP_ORIGIN_IGP;
5115
5116 table = bgp->rib[afi][safi];
5117
5118 top = bgp_node_get (table, p);
5119 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5120 if (rn->p.prefixlen > p->prefixlen)
5121 {
5122 match = 0;
5123
5124 for (ri = rn->info; ri; ri = ri->next)
5125 {
5126 if (BGP_INFO_HOLDDOWN (ri))
5127 continue;
5128
5129 if (del && ri == del)
5130 continue;
5131
5132 if (! rinew && first)
5133 {
5134 #if defined(AGGREGATE_NEXTHOP_CHECK)
5135 nexthop = ri->attr->nexthop;
5136 med = ri->attr->med;
5137 #endif
5138 first = 0;
5139 }
5140
5141 #ifdef AGGREGATE_NEXTHOP_CHECK
5142 if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
5143 || ri->attr->med != med)
5144 {
5145 if (aspath)
5146 aspath_free (aspath);
5147 if (community)
5148 community_free (community);
5149 bgp_unlock_node (rn);
5150 bgp_unlock_node (top);
5151 return;
5152 }
5153 #endif /* AGGREGATE_NEXTHOP_CHECK */
5154
5155 if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5156 atomic_aggregate = 1;
5157
5158 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5159 {
5160 if (aggregate->summary_only)
5161 {
5162 (bgp_info_extra_get (ri))->suppress++;
5163 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5164 match++;
5165 }
5166
5167 aggregate->count++;
5168
5169 if (origin < ri->attr->origin)
5170 origin = ri->attr->origin;
5171
5172 if (aggregate->as_set)
5173 {
5174 if (aspath)
5175 {
5176 asmerge = aspath_aggregate (aspath, ri->attr->aspath);
5177 aspath_free (aspath);
5178 aspath = asmerge;
5179 }
5180 else
5181 aspath = aspath_dup (ri->attr->aspath);
5182
5183 if (ri->attr->community)
5184 {
5185 if (community)
5186 {
5187 commerge = community_merge (community,
5188 ri->attr->community);
5189 community = community_uniq_sort (commerge);
5190 community_free (commerge);
5191 }
5192 else
5193 community = community_dup (ri->attr->community);
5194 }
5195 }
5196 }
5197 }
5198 if (match)
5199 bgp_process (bgp, rn, afi, safi);
5200 }
5201 bgp_unlock_node (top);
5202
5203 if (rinew)
5204 {
5205 aggregate->count++;
5206
5207 if (aggregate->summary_only)
5208 (bgp_info_extra_get (rinew))->suppress++;
5209
5210 if (origin < rinew->attr->origin)
5211 origin = rinew->attr->origin;
5212
5213 if (aggregate->as_set)
5214 {
5215 if (aspath)
5216 {
5217 asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
5218 aspath_free (aspath);
5219 aspath = asmerge;
5220 }
5221 else
5222 aspath = aspath_dup (rinew->attr->aspath);
5223
5224 if (rinew->attr->community)
5225 {
5226 if (community)
5227 {
5228 commerge = community_merge (community,
5229 rinew->attr->community);
5230 community = community_uniq_sort (commerge);
5231 community_free (commerge);
5232 }
5233 else
5234 community = community_dup (rinew->attr->community);
5235 }
5236 }
5237 }
5238
5239 if (aggregate->count > 0)
5240 {
5241 rn = bgp_node_get (table, p);
5242 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5243 bgp_attr_aggregate_intern(bgp, origin, aspath, community,
5244 aggregate->as_set,
5245 atomic_aggregate), rn);
5246 SET_FLAG (new->flags, BGP_INFO_VALID);
5247
5248 bgp_info_add (rn, new);
5249 bgp_unlock_node (rn);
5250 bgp_process (bgp, rn, afi, safi);
5251 }
5252 else
5253 {
5254 if (aspath)
5255 aspath_free (aspath);
5256 if (community)
5257 community_free (community);
5258 }
5259 }
5260
5261 void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
5262 struct bgp_aggregate *);
5263
5264 void
5265 bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
5266 struct bgp_info *ri, afi_t afi, safi_t safi)
5267 {
5268 struct bgp_node *child;
5269 struct bgp_node *rn;
5270 struct bgp_aggregate *aggregate;
5271 struct bgp_table *table;
5272
5273 /* MPLS-VPN aggregation is not yet supported. */
5274 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
5275 return;
5276
5277 table = bgp->aggregate[afi][safi];
5278
5279 /* No aggregates configured. */
5280 if (bgp_table_top_nolock (table) == NULL)
5281 return;
5282
5283 if (p->prefixlen == 0)
5284 return;
5285
5286 if (BGP_INFO_HOLDDOWN (ri))
5287 return;
5288
5289 child = bgp_node_get (table, p);
5290
5291 /* Aggregate address configuration check. */
5292 for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
5293 if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
5294 {
5295 bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
5296 bgp_aggregate_route (bgp, &rn->p, ri, afi, safi, NULL, aggregate);
5297 }
5298 bgp_unlock_node (child);
5299 }
5300
5301 void
5302 bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
5303 struct bgp_info *del, afi_t afi, safi_t safi)
5304 {
5305 struct bgp_node *child;
5306 struct bgp_node *rn;
5307 struct bgp_aggregate *aggregate;
5308 struct bgp_table *table;
5309
5310 /* MPLS-VPN aggregation is not yet supported. */
5311 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
5312 return;
5313
5314 table = bgp->aggregate[afi][safi];
5315
5316 /* No aggregates configured. */
5317 if (bgp_table_top_nolock (table) == NULL)
5318 return;
5319
5320 if (p->prefixlen == 0)
5321 return;
5322
5323 child = bgp_node_get (table, p);
5324
5325 /* Aggregate address configuration check. */
5326 for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
5327 if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
5328 {
5329 bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
5330 bgp_aggregate_route (bgp, &rn->p, NULL, afi, safi, del, aggregate);
5331 }
5332 bgp_unlock_node (child);
5333 }
5334
5335 /* Called via bgp_aggregate_set when the user configures aggregate-address */
5336 static void
5337 bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
5338 struct bgp_aggregate *aggregate)
5339 {
5340 struct bgp_table *table;
5341 struct bgp_node *top;
5342 struct bgp_node *rn;
5343 struct bgp_info *new;
5344 struct bgp_info *ri;
5345 unsigned long match;
5346 u_char origin = BGP_ORIGIN_IGP;
5347 struct aspath *aspath = NULL;
5348 struct aspath *asmerge = NULL;
5349 struct community *community = NULL;
5350 struct community *commerge = NULL;
5351 u_char atomic_aggregate = 0;
5352
5353 table = bgp->rib[afi][safi];
5354
5355 /* Sanity check. */
5356 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5357 return;
5358 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5359 return;
5360
5361 /* If routes exists below this node, generate aggregate routes. */
5362 top = bgp_node_get (table, p);
5363 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5364 if (rn->p.prefixlen > p->prefixlen)
5365 {
5366 match = 0;
5367
5368 for (ri = rn->info; ri; ri = ri->next)
5369 {
5370 if (BGP_INFO_HOLDDOWN (ri))
5371 continue;
5372
5373 if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
5374 atomic_aggregate = 1;
5375
5376 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5377 {
5378 /* summary-only aggregate route suppress aggregated
5379 route announcement. */
5380 if (aggregate->summary_only)
5381 {
5382 (bgp_info_extra_get (ri))->suppress++;
5383 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5384 match++;
5385 }
5386
5387 /* If at least one route among routes that are aggregated has
5388 * ORIGIN with the value INCOMPLETE, then the aggregated route
5389 * MUST have the ORIGIN attribute with the value INCOMPLETE.
5390 * Otherwise, if at least one route among routes that are
5391 * aggregated has ORIGIN with the value EGP, then the aggregated
5392 * route MUST have the ORIGIN attribute with the value EGP.
5393 */
5394 if (origin < ri->attr->origin)
5395 origin = ri->attr->origin;
5396
5397 /* as-set aggregate route generate origin, as path,
5398 community aggregation. */
5399 if (aggregate->as_set)
5400 {
5401 if (aspath)
5402 {
5403 asmerge = aspath_aggregate (aspath, ri->attr->aspath);
5404 aspath_free (aspath);
5405 aspath = asmerge;
5406 }
5407 else
5408 aspath = aspath_dup (ri->attr->aspath);
5409
5410 if (ri->attr->community)
5411 {
5412 if (community)
5413 {
5414 commerge = community_merge (community,
5415 ri->attr->community);
5416 community = community_uniq_sort (commerge);
5417 community_free (commerge);
5418 }
5419 else
5420 community = community_dup (ri->attr->community);
5421 }
5422 }
5423 aggregate->count++;
5424 }
5425 }
5426
5427 /* If this node is suppressed, process the change. */
5428 if (match)
5429 bgp_process (bgp, rn, afi, safi);
5430 }
5431 bgp_unlock_node (top);
5432
5433 /* Add aggregate route to BGP table. */
5434 if (aggregate->count)
5435 {
5436 rn = bgp_node_get (table, p);
5437 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
5438 bgp_attr_aggregate_intern(bgp, origin, aspath, community,
5439 aggregate->as_set,
5440 atomic_aggregate), rn);
5441 SET_FLAG (new->flags, BGP_INFO_VALID);
5442
5443 bgp_info_add (rn, new);
5444 bgp_unlock_node (rn);
5445
5446 /* Process change. */
5447 bgp_process (bgp, rn, afi, safi);
5448 }
5449 else
5450 {
5451 if (aspath)
5452 aspath_free (aspath);
5453 if (community)
5454 community_free (community);
5455 }
5456 }
5457
5458 void
5459 bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
5460 safi_t safi, struct bgp_aggregate *aggregate)
5461 {
5462 struct bgp_table *table;
5463 struct bgp_node *top;
5464 struct bgp_node *rn;
5465 struct bgp_info *ri;
5466 unsigned long match;
5467
5468 table = bgp->rib[afi][safi];
5469
5470 if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
5471 return;
5472 if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
5473 return;
5474
5475 /* If routes exists below this node, generate aggregate routes. */
5476 top = bgp_node_get (table, p);
5477 for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
5478 if (rn->p.prefixlen > p->prefixlen)
5479 {
5480 match = 0;
5481
5482 for (ri = rn->info; ri; ri = ri->next)
5483 {
5484 if (BGP_INFO_HOLDDOWN (ri))
5485 continue;
5486
5487 if (ri->sub_type != BGP_ROUTE_AGGREGATE)
5488 {
5489 if (aggregate->summary_only && ri->extra)
5490 {
5491 ri->extra->suppress--;
5492
5493 if (ri->extra->suppress == 0)
5494 {
5495 bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
5496 match++;
5497 }
5498 }
5499 aggregate->count--;
5500 }
5501 }
5502
5503 /* If this node was suppressed, process the change. */
5504 if (match)
5505 bgp_process (bgp, rn, afi, safi);
5506 }
5507 bgp_unlock_node (top);
5508
5509 /* Delete aggregate route from BGP table. */
5510 rn = bgp_node_get (table, p);
5511
5512 for (ri = rn->info; ri; ri = ri->next)
5513 if (ri->peer == bgp->peer_self
5514 && ri->type == ZEBRA_ROUTE_BGP
5515 && ri->sub_type == BGP_ROUTE_AGGREGATE)
5516 break;
5517
5518 /* Withdraw static BGP route from routing table. */
5519 if (ri)
5520 {
5521 bgp_info_delete (rn, ri);
5522 bgp_process (bgp, rn, afi, safi);
5523 }
5524
5525 /* Unlock bgp_node_lookup. */
5526 bgp_unlock_node (rn);
5527 }
5528
5529 /* Aggregate route attribute. */
5530 #define AGGREGATE_SUMMARY_ONLY 1
5531 #define AGGREGATE_AS_SET 1
5532
5533 static int
5534 bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
5535 afi_t afi, safi_t safi)
5536 {
5537 VTY_DECLVAR_CONTEXT(bgp, bgp);
5538 int ret;
5539 struct prefix p;
5540 struct bgp_node *rn;
5541 struct bgp_aggregate *aggregate;
5542
5543 /* Convert string to prefix structure. */
5544 ret = str2prefix (prefix_str, &p);
5545 if (!ret)
5546 {
5547 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
5548 return CMD_WARNING;
5549 }
5550 apply_mask (&p);
5551
5552 /* Old configuration check. */
5553 rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
5554 if (! rn)
5555 {
5556 vty_out (vty, "%% There is no aggregate-address configuration.%s",
5557 VTY_NEWLINE);
5558 return CMD_WARNING;
5559 }
5560
5561 aggregate = rn->info;
5562 if (aggregate->safi & SAFI_UNICAST)
5563 bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
5564 if (aggregate->safi & SAFI_MULTICAST)
5565 bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
5566
5567 /* Unlock aggregate address configuration. */
5568 rn->info = NULL;
5569 bgp_aggregate_free (aggregate);
5570 bgp_unlock_node (rn);
5571 bgp_unlock_node (rn);
5572
5573 return CMD_SUCCESS;
5574 }
5575
5576 static int
5577 bgp_aggregate_set (struct vty *vty, const char *prefix_str,
5578 afi_t afi, safi_t safi,
5579 u_char summary_only, u_char as_set)
5580 {
5581 VTY_DECLVAR_CONTEXT(bgp, bgp);
5582 int ret;
5583 struct prefix p;
5584 struct bgp_node *rn;
5585 struct bgp_aggregate *aggregate;
5586
5587 /* Convert string to prefix structure. */
5588 ret = str2prefix (prefix_str, &p);
5589 if (!ret)
5590 {
5591 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
5592 return CMD_WARNING;
5593 }
5594 apply_mask (&p);
5595
5596 /* Old configuration check. */
5597 rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
5598
5599 if (rn->info)
5600 {
5601 vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
5602 /* try to remove the old entry */
5603 ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
5604 if (ret)
5605 {
5606 vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
5607 bgp_unlock_node (rn);
5608 return CMD_WARNING;
5609 }
5610 }
5611
5612 /* Make aggregate address structure. */
5613 aggregate = bgp_aggregate_new ();
5614 aggregate->summary_only = summary_only;
5615 aggregate->as_set = as_set;
5616 aggregate->safi = safi;
5617 rn->info = aggregate;
5618
5619 /* Aggregate address insert into BGP routing table. */
5620 if (safi & SAFI_UNICAST)
5621 bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
5622 if (safi & SAFI_MULTICAST)
5623 bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
5624
5625 return CMD_SUCCESS;
5626 }
5627
5628 DEFUN (aggregate_address,
5629 aggregate_address_cmd,
5630 "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5631 "Configure BGP aggregate entries\n"
5632 "Aggregate prefix\n"
5633 "Generate AS set path information\n"
5634 "Filter more specific routes from updates\n"
5635 "Filter more specific routes from updates\n"
5636 "Generate AS set path information\n")
5637 {
5638 int idx = 0;
5639 argv_find (argv, argc, "A.B.C.D/M", &idx);
5640 char *prefix = argv[idx]->arg;
5641 int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5642 idx = 0;
5643 int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5644
5645 return bgp_aggregate_set (vty, prefix, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
5646 }
5647
5648 DEFUN (aggregate_address_mask,
5649 aggregate_address_mask_cmd,
5650 "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5651 "Configure BGP aggregate entries\n"
5652 "Aggregate address\n"
5653 "Aggregate mask\n"
5654 "Generate AS set path information\n"
5655 "Filter more specific routes from updates\n"
5656 "Filter more specific routes from updates\n"
5657 "Generate AS set path information\n")
5658 {
5659 int idx = 0;
5660 argv_find (argv, argc, "A.B.C.D", &idx);
5661 char *prefix = argv[idx++]->arg;
5662 argv_find (argv, argc, "A.B.C.D", &idx);
5663 char *mask = argv[idx]->arg;
5664 int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
5665 idx = 0;
5666 int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5667
5668 char prefix_str[BUFSIZ];
5669 int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
5670
5671 if (! ret)
5672 {
5673 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5674 return CMD_WARNING;
5675 }
5676
5677 return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
5678 }
5679
5680 DEFUN (no_aggregate_address,
5681 no_aggregate_address_cmd,
5682 "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>]",
5683 NO_STR
5684 "Configure BGP aggregate entries\n"
5685 "Aggregate prefix\n"
5686 "Generate AS set path information\n"
5687 "Filter more specific routes from updates\n"
5688 "Filter more specific routes from updates\n"
5689 "Generate AS set path information\n")
5690 {
5691 int idx = 0;
5692 argv_find (argv, argc, "A.B.C.D/M", &idx);
5693 char *prefix = argv[idx]->arg;
5694 return bgp_aggregate_unset (vty, prefix, AFI_IP, bgp_node_safi (vty));
5695 }
5696
5697 DEFUN (no_aggregate_address_mask,
5698 no_aggregate_address_mask_cmd,
5699 "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>]",
5700 NO_STR
5701 "Configure BGP aggregate entries\n"
5702 "Aggregate address\n"
5703 "Aggregate mask\n"
5704 "Generate AS set path information\n"
5705 "Filter more specific routes from updates\n"
5706 "Filter more specific routes from updates\n"
5707 "Generate AS set path information\n")
5708 {
5709 int idx = 0;
5710 argv_find (argv, argc, "A.B.C.D", &idx);
5711 char *prefix = argv[idx++]->arg;
5712 argv_find (argv, argc, "A.B.C.D", &idx);
5713 char *mask = argv[idx]->arg;
5714
5715 char prefix_str[BUFSIZ];
5716 int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
5717
5718 if (! ret)
5719 {
5720 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
5721 return CMD_WARNING;
5722 }
5723
5724 return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
5725 }
5726
5727 DEFUN (ipv6_aggregate_address,
5728 ipv6_aggregate_address_cmd,
5729 "aggregate-address X:X::X:X/M [summary-only]",
5730 "Configure BGP aggregate entries\n"
5731 "Aggregate prefix\n"
5732 "Filter more specific routes from updates\n")
5733 {
5734 int idx = 0;
5735 argv_find (argv, argc, "X:X::X:X/M", &idx);
5736 char *prefix = argv[idx]->arg;
5737 int sum_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
5738 return bgp_aggregate_set (vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only, 0);
5739 }
5740
5741 DEFUN (no_ipv6_aggregate_address,
5742 no_ipv6_aggregate_address_cmd,
5743 "no aggregate-address X:X::X:X/M [summary-only]",
5744 NO_STR
5745 "Configure BGP aggregate entries\n"
5746 "Aggregate prefix\n"
5747 "Filter more specific routes from updates\n")
5748 {
5749 int idx = 0;
5750 argv_find (argv, argc, "X:X::X:X/M", &idx);
5751 char *prefix = argv[idx]->arg;
5752 return bgp_aggregate_unset (vty, prefix, AFI_IP6, SAFI_UNICAST);
5753 }
5754
5755 /* Redistribute route treatment. */
5756 void
5757 bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
5758 const struct in6_addr *nexthop6, unsigned int ifindex,
5759 u_int32_t metric, u_char type, u_short instance, route_tag_t tag)
5760 {
5761 struct bgp_info *new;
5762 struct bgp_info *bi;
5763 struct bgp_info info;
5764 struct bgp_node *bn;
5765 struct attr attr;
5766 struct attr *new_attr;
5767 afi_t afi;
5768 int ret;
5769 struct bgp_redist *red;
5770
5771 /* Make default attribute. */
5772 bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
5773 if (nexthop)
5774 attr.nexthop = *nexthop;
5775 attr.nh_ifindex = ifindex;
5776
5777 if (nexthop6)
5778 {
5779 struct attr_extra *extra = bgp_attr_extra_get(&attr);
5780 extra->mp_nexthop_global = *nexthop6;
5781 extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
5782 }
5783
5784 attr.med = metric;
5785 attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
5786 attr.extra->tag = tag;
5787
5788 afi = family2afi (p->family);
5789
5790 red = bgp_redist_lookup(bgp, afi, type, instance);
5791 if (red)
5792 {
5793 struct attr attr_new;
5794 struct attr_extra extra_new;
5795
5796 /* Copy attribute for modification. */
5797 attr_new.extra = &extra_new;
5798 bgp_attr_dup (&attr_new, &attr);
5799
5800 if (red->redist_metric_flag)
5801 attr_new.med = red->redist_metric;
5802
5803 /* Apply route-map. */
5804 if (red->rmap.name)
5805 {
5806 info.peer = bgp->peer_self;
5807 info.attr = &attr_new;
5808
5809 SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
5810
5811 ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
5812
5813 bgp->peer_self->rmap_type = 0;
5814
5815 if (ret == RMAP_DENYMATCH)
5816 {
5817 /* Free uninterned attribute. */
5818 bgp_attr_flush (&attr_new);
5819
5820 /* Unintern original. */
5821 aspath_unintern (&attr.aspath);
5822 bgp_attr_extra_free (&attr);
5823 bgp_redistribute_delete (bgp, p, type, instance);
5824 return;
5825 }
5826 }
5827
5828 bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
5829 afi, SAFI_UNICAST, p, NULL);
5830
5831 new_attr = bgp_attr_intern (&attr_new);
5832
5833 for (bi = bn->info; bi; bi = bi->next)
5834 if (bi->peer == bgp->peer_self
5835 && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
5836 break;
5837
5838 if (bi)
5839 {
5840 /* Ensure the (source route) type is updated. */
5841 bi->type = type;
5842 if (attrhash_cmp (bi->attr, new_attr) &&
5843 !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
5844 {
5845 bgp_attr_unintern (&new_attr);
5846 aspath_unintern (&attr.aspath);
5847 bgp_attr_extra_free (&attr);
5848 bgp_unlock_node (bn);
5849 return;
5850 }
5851 else
5852 {
5853 /* The attribute is changed. */
5854 bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
5855
5856 /* Rewrite BGP route information. */
5857 if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
5858 bgp_info_restore(bn, bi);
5859 else
5860 bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
5861 bgp_attr_unintern (&bi->attr);
5862 bi->attr = new_attr;
5863 bi->uptime = bgp_clock ();
5864
5865 /* Process change. */
5866 bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
5867 bgp_process (bgp, bn, afi, SAFI_UNICAST);
5868 bgp_unlock_node (bn);
5869 aspath_unintern (&attr.aspath);
5870 bgp_attr_extra_free (&attr);
5871 return;
5872 }
5873 }
5874
5875 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance, bgp->peer_self,
5876 new_attr, bn);
5877 SET_FLAG (new->flags, BGP_INFO_VALID);
5878
5879 bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
5880 bgp_info_add (bn, new);
5881 bgp_unlock_node (bn);
5882 bgp_process (bgp, bn, afi, SAFI_UNICAST);
5883 }
5884
5885 /* Unintern original. */
5886 aspath_unintern (&attr.aspath);
5887 bgp_attr_extra_free (&attr);
5888 }
5889
5890 void
5891 bgp_redistribute_delete (struct bgp *bgp, struct prefix *p, u_char type, u_short instance)
5892 {
5893 afi_t afi;
5894 struct bgp_node *rn;
5895 struct bgp_info *ri;
5896 struct bgp_redist *red;
5897
5898 afi = family2afi (p->family);
5899
5900 red = bgp_redist_lookup(bgp, afi, type, instance);
5901 if (red)
5902 {
5903 rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
5904
5905 for (ri = rn->info; ri; ri = ri->next)
5906 if (ri->peer == bgp->peer_self
5907 && ri->type == type)
5908 break;
5909
5910 if (ri)
5911 {
5912 bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
5913 bgp_info_delete (rn, ri);
5914 bgp_process (bgp, rn, afi, SAFI_UNICAST);
5915 }
5916 bgp_unlock_node (rn);
5917 }
5918 }
5919
5920 /* Withdraw specified route type's route. */
5921 void
5922 bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type, u_short instance)
5923 {
5924 struct bgp_node *rn;
5925 struct bgp_info *ri;
5926 struct bgp_table *table;
5927
5928 table = bgp->rib[afi][SAFI_UNICAST];
5929
5930 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
5931 {
5932 for (ri = rn->info; ri; ri = ri->next)
5933 if (ri->peer == bgp->peer_self
5934 && ri->type == type
5935 && ri->instance == instance)
5936 break;
5937
5938 if (ri)
5939 {
5940 bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
5941 bgp_info_delete (rn, ri);
5942 bgp_process (bgp, rn, afi, SAFI_UNICAST);
5943 }
5944 }
5945 }
5946
5947 /* Static function to display route. */
5948 static void
5949 route_vty_out_route (struct prefix *p, struct vty *vty)
5950 {
5951 int len;
5952 u_int32_t destination;
5953 char buf[BUFSIZ];
5954
5955 if (p->family == AF_INET)
5956 {
5957 len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
5958 destination = ntohl (p->u.prefix4.s_addr);
5959
5960 if ((IN_CLASSC (destination) && p->prefixlen == 24)
5961 || (IN_CLASSB (destination) && p->prefixlen == 16)
5962 || (IN_CLASSA (destination) && p->prefixlen == 8)
5963 || p->u.prefix4.s_addr == 0)
5964 {
5965 /* When mask is natural, mask is not displayed. */
5966 }
5967 else
5968 len += vty_out (vty, "/%d", p->prefixlen);
5969 }
5970 else if (p->family == AF_ETHERNET)
5971 {
5972 prefix2str(p, buf, PREFIX_STRLEN);
5973 len = vty_out (vty, "%s", buf);
5974 }
5975 else
5976 len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
5977 p->prefixlen);
5978
5979 len = 17 - len;
5980 if (len < 1)
5981 vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
5982 else
5983 vty_out (vty, "%*s", len, " ");
5984 }
5985
5986 enum bgp_display_type
5987 {
5988 normal_list,
5989 };
5990
5991 /* Print the short form route status for a bgp_info */
5992 static void
5993 route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo,
5994 json_object *json_path)
5995 {
5996 if (json_path)
5997 {
5998
5999 /* Route status display. */
6000 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
6001 json_object_boolean_true_add(json_path, "removed");
6002
6003 if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
6004 json_object_boolean_true_add(json_path, "stale");
6005
6006 if (binfo->extra && binfo->extra->suppress)
6007 json_object_boolean_true_add(json_path, "suppressed");
6008
6009 if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
6010 ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6011 json_object_boolean_true_add(json_path, "valid");
6012
6013 /* Selected */
6014 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6015 json_object_boolean_true_add(json_path, "history");
6016
6017 if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
6018 json_object_boolean_true_add(json_path, "damped");
6019
6020 if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
6021 json_object_boolean_true_add(json_path, "bestpath");
6022
6023 if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
6024 json_object_boolean_true_add(json_path, "multipath");
6025
6026 /* Internal route. */
6027 if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
6028 json_object_string_add(json_path, "pathFrom", "internal");
6029 else
6030 json_object_string_add(json_path, "pathFrom", "external");
6031
6032 return;
6033 }
6034
6035 /* Route status display. */
6036 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
6037 vty_out (vty, "R");
6038 else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
6039 vty_out (vty, "S");
6040 else if (binfo->extra && binfo->extra->suppress)
6041 vty_out (vty, "s");
6042 else if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
6043 ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6044 vty_out (vty, "*");
6045 else
6046 vty_out (vty, " ");
6047
6048 /* Selected */
6049 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6050 vty_out (vty, "h");
6051 else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
6052 vty_out (vty, "d");
6053 else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
6054 vty_out (vty, ">");
6055 else if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
6056 vty_out (vty, "=");
6057 else
6058 vty_out (vty, " ");
6059
6060 /* Internal route. */
6061 if (binfo->peer &&
6062 (binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
6063 vty_out (vty, "i");
6064 else
6065 vty_out (vty, " ");
6066 }
6067
6068 /* called from terminal list command */
6069 void
6070 route_vty_out (struct vty *vty, struct prefix *p,
6071 struct bgp_info *binfo, int display, safi_t safi,
6072 json_object *json_paths)
6073 {
6074 struct attr *attr;
6075 json_object *json_path = NULL;
6076 json_object *json_nexthops = NULL;
6077 json_object *json_nexthop_global = NULL;
6078 json_object *json_nexthop_ll = NULL;
6079
6080 if (json_paths)
6081 json_path = json_object_new_object();
6082
6083 /* short status lead text */
6084 route_vty_short_status_out (vty, binfo, json_path);
6085
6086 if (!json_paths)
6087 {
6088 /* print prefix and mask */
6089 if (! display)
6090 route_vty_out_route (p, vty);
6091 else
6092 vty_out (vty, "%*s", 17, " ");
6093 }
6094
6095 /* Print attribute */
6096 attr = binfo->attr;
6097 if (attr)
6098 {
6099 /*
6100 * For ENCAP routes, nexthop address family is not
6101 * neccessarily the same as the prefix address family.
6102 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
6103 */
6104 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6105 {
6106 if (attr->extra)
6107 {
6108 char buf[BUFSIZ];
6109 int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
6110
6111 switch (af)
6112 {
6113 case AF_INET:
6114 vty_out (vty, "%s", inet_ntop(af,
6115 &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
6116 break;
6117 case AF_INET6:
6118 vty_out (vty, "%s", inet_ntop(af,
6119 &attr->extra->mp_nexthop_global, buf, BUFSIZ));
6120 break;
6121 default:
6122 vty_out(vty, "?");
6123 break;
6124 }
6125 }
6126 else
6127 vty_out(vty, "?");
6128 }
6129 /* IPv4 Next Hop */
6130 else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6131 {
6132 if (json_paths)
6133 {
6134 json_nexthop_global = json_object_new_object();
6135
6136 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6137 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
6138 else
6139 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
6140
6141 json_object_string_add(json_nexthop_global, "afi", "ipv4");
6142 json_object_boolean_true_add(json_nexthop_global, "used");
6143 }
6144 else
6145 {
6146 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
6147 vty_out (vty, "%-16s",
6148 inet_ntoa (attr->extra->mp_nexthop_global_in));
6149 else
6150 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6151 }
6152 }
6153
6154 /* IPv6 Next Hop */
6155 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6156 {
6157 int len;
6158 char buf[BUFSIZ];
6159
6160 if (json_paths)
6161 {
6162 json_nexthop_global = json_object_new_object();
6163 json_object_string_add(json_nexthop_global, "ip",
6164 inet_ntop (AF_INET6,
6165 &attr->extra->mp_nexthop_global,
6166 buf, BUFSIZ));
6167 json_object_string_add(json_nexthop_global, "afi", "ipv6");
6168 json_object_string_add(json_nexthop_global, "scope", "global");
6169
6170 /* We display both LL & GL if both have been received */
6171 if ((attr->extra->mp_nexthop_len == 32) || (binfo->peer->conf_if))
6172 {
6173 json_nexthop_ll = json_object_new_object();
6174 json_object_string_add(json_nexthop_ll, "ip",
6175 inet_ntop (AF_INET6,
6176 &attr->extra->mp_nexthop_local,
6177 buf, BUFSIZ));
6178 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
6179 json_object_string_add(json_nexthop_ll, "scope", "link-local");
6180
6181 if ((IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
6182 &attr->extra->mp_nexthop_local) != 0) &&
6183 !attr->extra->mp_nexthop_prefer_global)
6184 json_object_boolean_true_add(json_nexthop_ll, "used");
6185 else
6186 json_object_boolean_true_add(json_nexthop_global, "used");
6187 }
6188 else
6189 json_object_boolean_true_add(json_nexthop_global, "used");
6190 }
6191 else
6192 {
6193 /* Display LL if LL/Global both in table unless prefer-global is set */
6194 if (((attr->extra->mp_nexthop_len == 32) &&
6195 !attr->extra->mp_nexthop_prefer_global) ||
6196 (binfo->peer->conf_if))
6197 {
6198 if (binfo->peer->conf_if)
6199 {
6200 len = vty_out (vty, "%s",
6201 binfo->peer->conf_if);
6202 len = 7 - len; /* len of IPv6 addr + max len of def ifname */
6203
6204 if (len < 1)
6205 vty_out (vty, "%s%*s", VTY_NEWLINE, 45, " ");
6206 else
6207 vty_out (vty, "%*s", len, " ");
6208 }
6209 else
6210 {
6211 len = vty_out (vty, "%s",
6212 inet_ntop (AF_INET6,
6213 &attr->extra->mp_nexthop_local,
6214 buf, BUFSIZ));
6215 len = 16 - len;
6216
6217 if (len < 1)
6218 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6219 else
6220 vty_out (vty, "%*s", len, " ");
6221 }
6222 }
6223 else
6224 {
6225 len = vty_out (vty, "%s",
6226 inet_ntop (AF_INET6,
6227 &attr->extra->mp_nexthop_global,
6228 buf, BUFSIZ));
6229 len = 16 - len;
6230
6231 if (len < 1)
6232 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6233 else
6234 vty_out (vty, "%*s", len, " ");
6235 }
6236 }
6237 }
6238
6239 /* MED/Metric */
6240 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6241 if (json_paths)
6242 json_object_int_add(json_path, "med", attr->med);
6243 else
6244 vty_out (vty, "%10u", attr->med);
6245 else
6246 if (!json_paths)
6247 vty_out (vty, " ");
6248
6249 /* Local Pref */
6250 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6251 if (json_paths)
6252 json_object_int_add(json_path, "localpref", attr->local_pref);
6253 else
6254 vty_out (vty, "%7u", attr->local_pref);
6255 else
6256 if (!json_paths)
6257 vty_out (vty, " ");
6258
6259 if (json_paths)
6260 {
6261 if (attr->extra)
6262 json_object_int_add(json_path, "weight", attr->extra->weight);
6263 else
6264 json_object_int_add(json_path, "weight", 0);
6265 }
6266 else
6267 vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
6268
6269 if (json_paths) {
6270 char buf[BUFSIZ];
6271 json_object_string_add(json_path, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
6272 }
6273
6274 /* Print aspath */
6275 if (attr->aspath)
6276 {
6277 if (json_paths)
6278 json_object_string_add(json_path, "aspath", attr->aspath->str);
6279 else
6280 aspath_print_vty (vty, "%s", attr->aspath, " ");
6281 }
6282
6283 /* Print origin */
6284 if (json_paths)
6285 json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
6286 else
6287 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6288 }
6289 else
6290 {
6291 if (json_paths)
6292 json_object_string_add(json_path, "alert", "No attributes");
6293 else
6294 vty_out (vty, "No attributes to print%s", VTY_NEWLINE);
6295 }
6296
6297 if (json_paths)
6298 {
6299 if (json_nexthop_global || json_nexthop_ll)
6300 {
6301 json_nexthops = json_object_new_array();
6302
6303 if (json_nexthop_global)
6304 json_object_array_add(json_nexthops, json_nexthop_global);
6305
6306 if (json_nexthop_ll)
6307 json_object_array_add(json_nexthops, json_nexthop_ll);
6308
6309 json_object_object_add(json_path, "nexthops", json_nexthops);
6310 }
6311
6312 json_object_array_add(json_paths, json_path);
6313 }
6314 else
6315 {
6316 vty_out (vty, "%s", VTY_NEWLINE);
6317 #if ENABLE_BGP_VNC
6318 /* prints an additional line, indented, with VNC info, if present */
6319 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
6320 rfapi_vty_out_vncinfo(vty, p, binfo, safi);
6321 #endif
6322 }
6323 }
6324
6325 /* called from terminal list command */
6326 void
6327 route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t safi,
6328 u_char use_json, json_object *json_ar)
6329 {
6330 json_object *json_status = NULL;
6331 json_object *json_net = NULL;
6332 char buff[BUFSIZ];
6333 /* Route status display. */
6334 if (use_json)
6335 {
6336 json_status = json_object_new_object();
6337 json_net = json_object_new_object();
6338 }
6339 else
6340 {
6341 vty_out (vty, "*");
6342 vty_out (vty, ">");
6343 vty_out (vty, " ");
6344 }
6345
6346 /* print prefix and mask */
6347 if (use_json)
6348 json_object_string_add(json_net, "addrPrefix", inet_ntop (p->family, &p->u.prefix, buff, BUFSIZ));
6349 else
6350 route_vty_out_route (p, vty);
6351
6352 /* Print attribute */
6353 if (attr)
6354 {
6355 if (use_json)
6356 {
6357 if (p->family == AF_INET &&
6358 (safi == SAFI_MPLS_VPN ||
6359 safi == SAFI_ENCAP ||
6360 safi == SAFI_EVPN ||
6361 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6362 {
6363 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6364 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in));
6365 else
6366 json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
6367 }
6368 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6369 {
6370 char buf[BUFSIZ];
6371
6372 json_object_string_add(json_net, "netHopGloabal", inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6373 buf, BUFSIZ));
6374 }
6375
6376 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6377 json_object_int_add(json_net, "metric", attr->med);
6378
6379 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6380 json_object_int_add(json_net, "localPref", attr->local_pref);
6381
6382 if (attr->extra)
6383 json_object_int_add(json_net, "weight", attr->extra->weight);
6384 else
6385 json_object_int_add(json_net, "weight", 0);
6386
6387 /* Print aspath */
6388 if (attr->aspath)
6389 json_object_string_add(json_net, "asPath", attr->aspath->str);
6390
6391 /* Print origin */
6392 json_object_string_add(json_net, "bgpOriginCode", bgp_origin_str[attr->origin]);
6393 }
6394 else
6395 {
6396 if (p->family == AF_INET &&
6397 (safi == SAFI_MPLS_VPN ||
6398 safi == SAFI_ENCAP ||
6399 safi == SAFI_EVPN ||
6400 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6401 {
6402 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6403 vty_out (vty, "%-16s",
6404 inet_ntoa (attr->extra->mp_nexthop_global_in));
6405 else
6406 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6407 }
6408 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6409 {
6410 int len;
6411 char buf[BUFSIZ];
6412
6413 assert (attr->extra);
6414
6415 len = vty_out (vty, "%s",
6416 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6417 buf, BUFSIZ));
6418 len = 16 - len;
6419 if (len < 1)
6420 vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
6421 else
6422 vty_out (vty, "%*s", len, " ");
6423 }
6424 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
6425 vty_out (vty, "%10u", attr->med);
6426 else
6427 vty_out (vty, " ");
6428
6429 if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
6430 vty_out (vty, "%7u", attr->local_pref);
6431 else
6432 vty_out (vty, " ");
6433
6434 vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
6435
6436 /* Print aspath */
6437 if (attr->aspath)
6438 aspath_print_vty (vty, "%s", attr->aspath, " ");
6439
6440 /* Print origin */
6441 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6442 }
6443 }
6444 if (use_json)
6445 {
6446 json_object_boolean_true_add(json_status, "*");
6447 json_object_boolean_true_add(json_status, ">");
6448 json_object_object_add(json_net, "appliedStatusSymbols", json_status);
6449 char buf_cut[BUFSIZ];
6450 json_object_object_add(json_ar, inet_ntop (p->family, &p->u.prefix, buf_cut, BUFSIZ), json_net);
6451 }
6452 else
6453 vty_out (vty, "%s", VTY_NEWLINE);
6454 }
6455
6456 void
6457 route_vty_out_tag (struct vty *vty, struct prefix *p,
6458 struct bgp_info *binfo, int display, safi_t safi, json_object *json)
6459 {
6460 json_object *json_out = NULL;
6461 struct attr *attr;
6462 u_int32_t label = 0;
6463
6464 if (!binfo->extra)
6465 return;
6466
6467 if (json)
6468 json_out = json_object_new_object();
6469
6470 /* short status lead text */
6471 route_vty_short_status_out (vty, binfo, json_out);
6472
6473 /* print prefix and mask */
6474 if (json == NULL)
6475 {
6476 if (! display)
6477 route_vty_out_route (p, vty);
6478 else
6479 vty_out (vty, "%*s", 17, " ");
6480 }
6481
6482 /* Print attribute */
6483 attr = binfo->attr;
6484 if (attr)
6485 {
6486 if (((p->family == AF_INET) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6487 || (safi == SAFI_EVPN && p->family == AF_ETHERNET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6488 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6489 {
6490 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6491 {
6492 if (json)
6493 json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in));
6494 else
6495 vty_out (vty, "%-16s", inet_ntoa (attr->extra->mp_nexthop_global_in));
6496 }
6497 else
6498 {
6499 if (json)
6500 json_object_string_add(json_out, "nexthop", inet_ntoa (attr->nexthop));
6501 else
6502 vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
6503 }
6504 }
6505 else if (((p->family == AF_INET6) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
6506 || (safi == SAFI_EVPN && p->family == AF_ETHERNET && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
6507 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6508 {
6509 assert (attr->extra);
6510 char buf_a[BUFSIZ];
6511 char buf_b[BUFSIZ];
6512 char buf_c[BUFSIZ];
6513 if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
6514 {
6515 if (json)
6516 json_object_string_add(json_out, "mpNexthopGlobalIn",
6517 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, buf_a, BUFSIZ));
6518 else
6519 vty_out (vty, "%s",
6520 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6521 buf_a, BUFSIZ));
6522 }
6523 else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
6524 {
6525 if (json)
6526 {
6527 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6528 buf_a, BUFSIZ);
6529 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
6530 buf_b, BUFSIZ);
6531 sprintf(buf_c, "%s(%s)", buf_a, buf_b);
6532 json_object_string_add(json_out, "mpNexthopGlobalLocal", buf_c);
6533 }
6534 else
6535 vty_out (vty, "%s(%s)",
6536 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
6537 buf_a, BUFSIZ),
6538 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
6539 buf_b, BUFSIZ));
6540 }
6541
6542 }
6543 }
6544
6545 label = decode_label (binfo->extra->tag);
6546
6547 if (json)
6548 {
6549 if (label)
6550 json_object_int_add(json_out, "notag", label);
6551 json_object_array_add(json, json_out);
6552 }
6553 else
6554 {
6555 vty_out (vty, "notag/%d", label);
6556
6557 vty_out (vty, "%s", VTY_NEWLINE);
6558 }
6559 }
6560
6561 void
6562 route_vty_out_overlay (struct vty *vty, struct prefix *p,
6563 struct bgp_info *binfo, int display, json_object *json_paths)
6564 {
6565 struct attr *attr;
6566 char buf[BUFSIZ];
6567 json_object *json_path = NULL;
6568
6569 if (json_paths)
6570 json_path = json_object_new_object();
6571
6572 if (!binfo->extra)
6573 return;
6574
6575 /* short status lead text */
6576 route_vty_short_status_out (vty, binfo, json_path);
6577
6578 /* print prefix and mask */
6579 if (! display)
6580 route_vty_out_route (p, vty);
6581 else
6582 vty_out (vty, "%*s", 17, " ");
6583
6584 /* Print attribute */
6585 attr = binfo->attr;
6586 if (attr)
6587 {
6588 if (attr->extra)
6589 {
6590 char buf1[BUFSIZ];
6591 int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
6592
6593 switch (af) {
6594 case AF_INET:
6595 vty_out (vty, "%-16s", inet_ntop(af,
6596 &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
6597 break;
6598 case AF_INET6:
6599 vty_out (vty, "%s(%s)",
6600 inet_ntop (af,
6601 &attr->extra->mp_nexthop_global, buf, BUFSIZ),
6602 inet_ntop (af,
6603 &attr->extra->mp_nexthop_local, buf1, BUFSIZ));
6604 break;
6605 default:
6606 vty_out(vty, "?");
6607 }
6608 } else {
6609 vty_out(vty, "?");
6610 }
6611 }
6612
6613 if(attr->extra)
6614 {
6615 struct eth_segment_id *id = &(attr->extra->evpn_overlay.eth_s_id);
6616 char *str = esi2str(id);
6617 vty_out (vty, "%s", str);
6618 XFREE (MTYPE_TMP, str);
6619 if (p->u.prefix_evpn.flags & IP_PREFIX_V4)
6620 {
6621 vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
6622 }
6623 else if (p->u.prefix_evpn.flags & IP_PREFIX_V6)
6624 {
6625 vty_out (vty, "/%s",
6626 inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
6627 buf, BUFSIZ));
6628 }
6629 if(attr->extra->ecommunity)
6630 {
6631 char *mac = NULL;
6632 struct ecommunity_val *routermac = ecommunity_lookup (attr->extra->ecommunity,
6633 ECOMMUNITY_ENCODE_EVPN,
6634 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
6635 if(routermac)
6636 mac = ecom_mac2str((char *)routermac->val);
6637 if(mac)
6638 {
6639 vty_out (vty, "/%s",(char *)mac);
6640 XFREE(MTYPE_TMP, mac);
6641 }
6642 }
6643 }
6644 vty_out (vty, "%s", VTY_NEWLINE);
6645 }
6646
6647 /* dampening route */
6648 static void
6649 damp_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6650 int display, safi_t safi, u_char use_json, json_object *json)
6651 {
6652 struct attr *attr;
6653 int len;
6654 char timebuf[BGP_UPTIME_LEN];
6655
6656 /* short status lead text */
6657 route_vty_short_status_out (vty, binfo, json);
6658
6659 /* print prefix and mask */
6660 if (!use_json)
6661 {
6662 if (! display)
6663 route_vty_out_route (p, vty);
6664 else
6665 vty_out (vty, "%*s", 17, " ");
6666 }
6667
6668 len = vty_out (vty, "%s", binfo->peer->host);
6669 len = 17 - len;
6670 if (len < 1)
6671 {
6672 if (!use_json)
6673 vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
6674 }
6675 else
6676 {
6677 if (use_json)
6678 json_object_int_add(json, "peerHost", len);
6679 else
6680 vty_out (vty, "%*s", len, " ");
6681 }
6682
6683 if (use_json)
6684 bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
6685 else
6686 vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
6687
6688 /* Print attribute */
6689 attr = binfo->attr;
6690 if (attr)
6691 {
6692 /* Print aspath */
6693 if (attr->aspath)
6694 {
6695 if (use_json)
6696 json_object_string_add(json, "asPath", attr->aspath->str);
6697 else
6698 aspath_print_vty (vty, "%s", attr->aspath, " ");
6699 }
6700
6701 /* Print origin */
6702 if (use_json)
6703 json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
6704 else
6705 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6706 }
6707 if (!use_json)
6708 vty_out (vty, "%s", VTY_NEWLINE);
6709 }
6710
6711 /* flap route */
6712 static void
6713 flap_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
6714 int display, safi_t safi, u_char use_json, json_object *json)
6715 {
6716 struct attr *attr;
6717 struct bgp_damp_info *bdi;
6718 char timebuf[BGP_UPTIME_LEN];
6719 int len;
6720
6721 if (!binfo->extra)
6722 return;
6723
6724 bdi = binfo->extra->damp_info;
6725
6726 /* short status lead text */
6727 route_vty_short_status_out (vty, binfo, json);
6728
6729 /* print prefix and mask */
6730 if (!use_json)
6731 {
6732 if (! display)
6733 route_vty_out_route (p, vty);
6734 else
6735 vty_out (vty, "%*s", 17, " ");
6736 }
6737
6738 len = vty_out (vty, "%s", binfo->peer->host);
6739 len = 16 - len;
6740 if (len < 1)
6741 {
6742 if (!use_json)
6743 vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
6744 }
6745 else
6746 {
6747 if (use_json)
6748 json_object_int_add(json, "peerHost", len);
6749 else
6750 vty_out (vty, "%*s", len, " ");
6751 }
6752
6753 len = vty_out (vty, "%d", bdi->flap);
6754 len = 5 - len;
6755 if (len < 1)
6756 {
6757 if (!use_json)
6758 vty_out (vty, " ");
6759 }
6760 else
6761 {
6762 if (use_json)
6763 json_object_int_add(json, "bdiFlap", len);
6764 else
6765 vty_out (vty, "%*s", len, " ");
6766 }
6767
6768 if (use_json)
6769 peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json);
6770 else
6771 vty_out (vty, "%s ", peer_uptime (bdi->start_time,
6772 timebuf, BGP_UPTIME_LEN, 0, NULL));
6773
6774 if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
6775 && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6776 {
6777 if (use_json)
6778 bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
6779 else
6780 vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
6781 }
6782 else
6783 {
6784 if (!use_json)
6785 vty_out (vty, "%*s ", 8, " ");
6786 }
6787
6788 /* Print attribute */
6789 attr = binfo->attr;
6790 if (attr)
6791 {
6792 /* Print aspath */
6793 if (attr->aspath)
6794 {
6795 if (use_json)
6796 json_object_string_add(json, "asPath", attr->aspath->str);
6797 else
6798 aspath_print_vty (vty, "%s", attr->aspath, " ");
6799 }
6800
6801 /* Print origin */
6802 if (use_json)
6803 json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
6804 else
6805 vty_out (vty, "%s", bgp_origin_str[attr->origin]);
6806 }
6807 if (!use_json)
6808 vty_out (vty, "%s", VTY_NEWLINE);
6809 }
6810
6811 static void
6812 route_vty_out_advertised_to (struct vty *vty, struct peer *peer, int *first,
6813 const char *header, json_object *json_adv_to)
6814 {
6815 char buf1[INET6_ADDRSTRLEN];
6816 json_object *json_peer = NULL;
6817
6818 if (json_adv_to)
6819 {
6820 /* 'advertised-to' is a dictionary of peers we have advertised this
6821 * prefix too. The key is the peer's IP or swpX, the value is the
6822 * hostname if we know it and "" if not.
6823 */
6824 json_peer = json_object_new_object();
6825
6826 if (peer->hostname)
6827 json_object_string_add(json_peer, "hostname", peer->hostname);
6828
6829 if (peer->conf_if)
6830 json_object_object_add(json_adv_to, peer->conf_if, json_peer);
6831 else
6832 json_object_object_add(json_adv_to,
6833 sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN),
6834 json_peer);
6835 }
6836 else
6837 {
6838 if (*first)
6839 {
6840 vty_out (vty, "%s", header);
6841 *first = 0;
6842 }
6843
6844 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
6845 {
6846 if (peer->conf_if)
6847 vty_out (vty, " %s(%s)", peer->hostname, peer->conf_if);
6848 else
6849 vty_out (vty, " %s(%s)", peer->hostname,
6850 sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
6851 }
6852 else
6853 {
6854 if (peer->conf_if)
6855 vty_out (vty, " %s", peer->conf_if);
6856 else
6857 vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
6858 }
6859 }
6860 }
6861
6862 static void
6863 route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
6864 struct bgp_info *binfo, afi_t afi, safi_t safi,
6865 json_object *json_paths)
6866 {
6867 char buf[INET6_ADDRSTRLEN];
6868 char buf1[BUFSIZ];
6869 struct attr *attr;
6870 int sockunion_vty_out (struct vty *, union sockunion *);
6871 time_t tbuf;
6872 json_object *json_bestpath = NULL;
6873 json_object *json_cluster_list = NULL;
6874 json_object *json_cluster_list_list = NULL;
6875 json_object *json_ext_community = NULL;
6876 json_object *json_last_update = NULL;
6877 json_object *json_nexthop_global = NULL;
6878 json_object *json_nexthop_ll = NULL;
6879 json_object *json_nexthops = NULL;
6880 json_object *json_path = NULL;
6881 json_object *json_peer = NULL;
6882 json_object *json_string = NULL;
6883 json_object *json_adv_to = NULL;
6884 int first = 0;
6885 struct listnode *node, *nnode;
6886 struct peer *peer;
6887 int addpath_capable;
6888 int has_adj;
6889 unsigned int first_as;
6890
6891 if (json_paths)
6892 {
6893 json_path = json_object_new_object();
6894 json_peer = json_object_new_object();
6895 json_nexthop_global = json_object_new_object();
6896 }
6897
6898 attr = binfo->attr;
6899
6900 if (attr)
6901 {
6902 /* Line1 display AS-path, Aggregator */
6903 if (attr->aspath)
6904 {
6905 if (json_paths)
6906 {
6907 json_object_lock(attr->aspath->json);
6908 json_object_object_add(json_path, "aspath", attr->aspath->json);
6909 }
6910 else
6911 {
6912 if (attr->aspath->segments)
6913 aspath_print_vty (vty, " %s", attr->aspath, "");
6914 else
6915 vty_out (vty, " Local");
6916 }
6917 }
6918
6919 if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
6920 {
6921 if (json_paths)
6922 json_object_boolean_true_add(json_path, "removed");
6923 else
6924 vty_out (vty, ", (removed)");
6925 }
6926
6927 if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
6928 {
6929 if (json_paths)
6930 json_object_boolean_true_add(json_path, "stale");
6931 else
6932 vty_out (vty, ", (stale)");
6933 }
6934
6935 if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
6936 {
6937 if (json_paths)
6938 {
6939 json_object_int_add(json_path, "aggregatorAs", attr->extra->aggregator_as);
6940 json_object_string_add(json_path, "aggregatorId", inet_ntoa (attr->extra->aggregator_addr));
6941 }
6942 else
6943 {
6944 vty_out (vty, ", (aggregated by %u %s)",
6945 attr->extra->aggregator_as,
6946 inet_ntoa (attr->extra->aggregator_addr));
6947 }
6948 }
6949
6950 if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
6951 {
6952 if (json_paths)
6953 json_object_boolean_true_add(json_path, "rxedFromRrClient");
6954 else
6955 vty_out (vty, ", (Received from a RR-client)");
6956 }
6957
6958 if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
6959 {
6960 if (json_paths)
6961 json_object_boolean_true_add(json_path, "rxedFromRsClient");
6962 else
6963 vty_out (vty, ", (Received from a RS-client)");
6964 }
6965
6966 if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
6967 {
6968 if (json_paths)
6969 json_object_boolean_true_add(json_path, "dampeningHistoryEntry");
6970 else
6971 vty_out (vty, ", (history entry)");
6972 }
6973 else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
6974 {
6975 if (json_paths)
6976 json_object_boolean_true_add(json_path, "dampeningSuppressed");
6977 else
6978 vty_out (vty, ", (suppressed due to dampening)");
6979 }
6980
6981 if (!json_paths)
6982 vty_out (vty, "%s", VTY_NEWLINE);
6983
6984 /* Line2 display Next-hop, Neighbor, Router-id */
6985 /* Display the nexthop */
6986 if (p->family == AF_INET &&
6987 (safi == SAFI_MPLS_VPN ||
6988 safi == SAFI_ENCAP ||
6989 safi == SAFI_EVPN ||
6990 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
6991 {
6992 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
6993 {
6994 if (json_paths)
6995 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
6996 else
6997 vty_out (vty, " %s", inet_ntoa (attr->extra->mp_nexthop_global_in));
6998 }
6999 else
7000 {
7001 if (json_paths)
7002 json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
7003 else
7004 vty_out (vty, " %s", inet_ntoa (attr->nexthop));
7005 }
7006
7007 if (json_paths)
7008 json_object_string_add(json_nexthop_global, "afi", "ipv4");
7009 }
7010 else
7011 {
7012 assert (attr->extra);
7013 if (json_paths)
7014 {
7015 json_object_string_add(json_nexthop_global, "ip",
7016 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
7017 buf, INET6_ADDRSTRLEN));
7018 json_object_string_add(json_nexthop_global, "afi", "ipv6");
7019 json_object_string_add(json_nexthop_global, "scope", "global");
7020 }
7021 else
7022 {
7023 vty_out (vty, " %s",
7024 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
7025 buf, INET6_ADDRSTRLEN));
7026 }
7027 }
7028
7029 /* Display the IGP cost or 'inaccessible' */
7030 if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
7031 {
7032 if (json_paths)
7033 json_object_boolean_false_add(json_nexthop_global, "accessible");
7034 else
7035 vty_out (vty, " (inaccessible)");
7036 }
7037 else
7038 {
7039 if (binfo->extra && binfo->extra->igpmetric)
7040 {
7041 if (json_paths)
7042 json_object_int_add(json_nexthop_global, "metric", binfo->extra->igpmetric);
7043 else
7044 vty_out (vty, " (metric %u)", binfo->extra->igpmetric);
7045 }
7046
7047 /* IGP cost is 0, display this only for json */
7048 else
7049 {
7050 if (json_paths)
7051 json_object_int_add(json_nexthop_global, "metric", 0);
7052 }
7053
7054 if (json_paths)
7055 json_object_boolean_true_add(json_nexthop_global, "accessible");
7056 }
7057
7058 /* Display peer "from" output */
7059 /* This path was originated locally */
7060 if (binfo->peer == bgp->peer_self)
7061 {
7062
7063 if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
7064 {
7065 if (json_paths)
7066 json_object_string_add(json_peer, "peerId", "0.0.0.0");
7067 else
7068 vty_out (vty, " from 0.0.0.0 ");
7069 }
7070 else
7071 {
7072 if (json_paths)
7073 json_object_string_add(json_peer, "peerId", "::");
7074 else
7075 vty_out (vty, " from :: ");
7076 }
7077
7078 if (json_paths)
7079 json_object_string_add(json_peer, "routerId", inet_ntoa(bgp->router_id));
7080 else
7081 vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
7082 }
7083
7084 /* We RXed this path from one of our peers */
7085 else
7086 {
7087
7088 if (json_paths)
7089 {
7090 json_object_string_add(json_peer, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
7091 json_object_string_add(json_peer, "routerId", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
7092
7093 if (binfo->peer->hostname)
7094 json_object_string_add(json_peer, "hostname", binfo->peer->hostname);
7095
7096 if (binfo->peer->domainname)
7097 json_object_string_add(json_peer, "domainname", binfo->peer->domainname);
7098
7099 if (binfo->peer->conf_if)
7100 json_object_string_add(json_peer, "interface", binfo->peer->conf_if);
7101 }
7102 else
7103 {
7104 if (binfo->peer->conf_if)
7105 {
7106 if (binfo->peer->hostname &&
7107 bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7108 vty_out (vty, " from %s(%s)", binfo->peer->hostname,
7109 binfo->peer->conf_if);
7110 else
7111 vty_out (vty, " from %s", binfo->peer->conf_if);
7112 }
7113 else
7114 {
7115 if (binfo->peer->hostname &&
7116 bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
7117 vty_out (vty, " from %s(%s)", binfo->peer->hostname,
7118 binfo->peer->host);
7119 else
7120 vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
7121 }
7122
7123 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7124 vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
7125 else
7126 vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
7127 }
7128 }
7129
7130 if (!json_paths)
7131 vty_out (vty, "%s", VTY_NEWLINE);
7132
7133 /* display the link-local nexthop */
7134 if (attr->extra && attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
7135 {
7136 if (json_paths)
7137 {
7138 json_nexthop_ll = json_object_new_object();
7139 json_object_string_add(json_nexthop_ll, "ip",
7140 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
7141 buf, INET6_ADDRSTRLEN));
7142 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
7143 json_object_string_add(json_nexthop_ll, "scope", "link-local");
7144
7145 json_object_boolean_true_add(json_nexthop_ll, "accessible");
7146
7147 if (!attr->extra->mp_nexthop_prefer_global)
7148 json_object_boolean_true_add(json_nexthop_ll, "used");
7149 else
7150 json_object_boolean_true_add(json_nexthop_global, "used");
7151 }
7152 else
7153 {
7154 vty_out (vty, " (%s) %s%s",
7155 inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
7156 buf, INET6_ADDRSTRLEN),
7157 attr->extra->mp_nexthop_prefer_global ?
7158 "(prefer-global)" : "(used)",
7159 VTY_NEWLINE);
7160 }
7161 }
7162 /* If we do not have a link-local nexthop then we must flag the global as "used" */
7163 else
7164 {
7165 if (json_paths)
7166 json_object_boolean_true_add(json_nexthop_global, "used");
7167 }
7168
7169 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
7170 if (json_paths)
7171 json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
7172 else
7173 vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
7174
7175 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
7176 {
7177 if (json_paths)
7178 json_object_int_add(json_path, "med", attr->med);
7179 else
7180 vty_out (vty, ", metric %u", attr->med);
7181 }
7182
7183 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
7184 {
7185 if (json_paths)
7186 json_object_int_add(json_path, "localpref", attr->local_pref);
7187 else
7188 vty_out (vty, ", localpref %u", attr->local_pref);
7189 }
7190 else
7191 {
7192 if (json_paths)
7193 json_object_int_add(json_path, "localpref", bgp->default_local_pref);
7194 else
7195 vty_out (vty, ", localpref %u", bgp->default_local_pref);
7196 }
7197
7198 if (attr->extra && attr->extra->weight != 0)
7199 {
7200 if (json_paths)
7201 json_object_int_add(json_path, "weight", attr->extra->weight);
7202 else
7203 vty_out (vty, ", weight %u", attr->extra->weight);
7204 }
7205
7206 if (attr->extra && attr->extra->tag != 0)
7207 {
7208 if (json_paths)
7209 json_object_int_add(json_path, "tag", attr->extra->tag);
7210 else
7211 vty_out (vty, ", tag %"ROUTE_TAG_PRI, attr->extra->tag);
7212 }
7213
7214 if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
7215 {
7216 if (json_paths)
7217 json_object_boolean_false_add(json_path, "valid");
7218 else
7219 vty_out (vty, ", invalid");
7220 }
7221 else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
7222 {
7223 if (json_paths)
7224 json_object_boolean_true_add(json_path, "valid");
7225 else
7226 vty_out (vty, ", valid");
7227 }
7228
7229 if (binfo->peer != bgp->peer_self)
7230 {
7231 if (binfo->peer->as == binfo->peer->local_as)
7232 {
7233 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
7234 {
7235 if (json_paths)
7236 json_object_string_add(json_peer, "type", "confed-internal");
7237 else
7238 vty_out (vty, ", confed-internal");
7239 }
7240 else
7241 {
7242 if (json_paths)
7243 json_object_string_add(json_peer, "type", "internal");
7244 else
7245 vty_out (vty, ", internal");
7246 }
7247 }
7248 else
7249 {
7250 if (bgp_confederation_peers_check(bgp, binfo->peer->as))
7251 {
7252 if (json_paths)
7253 json_object_string_add(json_peer, "type", "confed-external");
7254 else
7255 vty_out (vty, ", confed-external");
7256 }
7257 else
7258 {
7259 if (json_paths)
7260 json_object_string_add(json_peer, "type", "external");
7261 else
7262 vty_out (vty, ", external");
7263 }
7264 }
7265 }
7266 else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
7267 {
7268 if (json_paths)
7269 {
7270 json_object_boolean_true_add(json_path, "aggregated");
7271 json_object_boolean_true_add(json_path, "local");
7272 }
7273 else
7274 {
7275 vty_out (vty, ", aggregated, local");
7276 }
7277 }
7278 else if (binfo->type != ZEBRA_ROUTE_BGP)
7279 {
7280 if (json_paths)
7281 json_object_boolean_true_add(json_path, "sourced");
7282 else
7283 vty_out (vty, ", sourced");
7284 }
7285 else
7286 {
7287 if (json_paths)
7288 {
7289 json_object_boolean_true_add(json_path, "sourced");
7290 json_object_boolean_true_add(json_path, "local");
7291 }
7292 else
7293 {
7294 vty_out (vty, ", sourced, local");
7295 }
7296 }
7297
7298 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7299 {
7300 if (json_paths)
7301 json_object_boolean_true_add(json_path, "atomicAggregate");
7302 else
7303 vty_out (vty, ", atomic-aggregate");
7304 }
7305
7306 if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH) ||
7307 (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED) &&
7308 bgp_info_mpath_count (binfo)))
7309 {
7310 if (json_paths)
7311 json_object_boolean_true_add(json_path, "multipath");
7312 else
7313 vty_out (vty, ", multipath");
7314 }
7315
7316 // Mark the bestpath(s)
7317 if (CHECK_FLAG (binfo->flags, BGP_INFO_DMED_SELECTED))
7318 {
7319 first_as = aspath_get_first_as(attr->aspath);
7320
7321 if (json_paths)
7322 {
7323 if (!json_bestpath)
7324 json_bestpath = json_object_new_object();
7325 json_object_int_add(json_bestpath, "bestpathFromAs", first_as);
7326 }
7327 else
7328 {
7329 if (first_as)
7330 vty_out (vty, ", bestpath-from-AS %d", first_as);
7331 else
7332 vty_out (vty, ", bestpath-from-AS Local");
7333 }
7334 }
7335
7336 if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
7337 {
7338 if (json_paths)
7339 {
7340 if (!json_bestpath)
7341 json_bestpath = json_object_new_object();
7342 json_object_boolean_true_add(json_bestpath, "overall");
7343 }
7344 else
7345 vty_out (vty, ", best");
7346 }
7347
7348 if (json_bestpath)
7349 json_object_object_add(json_path, "bestpath", json_bestpath);
7350
7351 if (!json_paths)
7352 vty_out (vty, "%s", VTY_NEWLINE);
7353
7354 /* Line 4 display Community */
7355 if (attr->community)
7356 {
7357 if (json_paths)
7358 {
7359 json_object_lock(attr->community->json);
7360 json_object_object_add(json_path, "community", attr->community->json);
7361 }
7362 else
7363 {
7364 vty_out (vty, " Community: %s%s", attr->community->str,
7365 VTY_NEWLINE);
7366 }
7367 }
7368
7369 /* Line 5 display Extended-community */
7370 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
7371 {
7372 if (json_paths)
7373 {
7374 json_ext_community = json_object_new_object();
7375 json_object_string_add(json_ext_community, "string", attr->extra->ecommunity->str);
7376 json_object_object_add(json_path, "extendedCommunity", json_ext_community);
7377 }
7378 else
7379 {
7380 vty_out (vty, " Extended Community: %s%s",
7381 attr->extra->ecommunity->str, VTY_NEWLINE);
7382 }
7383 }
7384
7385 /* Line 6 display Large community */
7386 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
7387 vty_out (vty, " Large Community: %s%s",
7388 attr->extra->lcommunity->str, VTY_NEWLINE);
7389
7390 /* Line 7 display Originator, Cluster-id */
7391 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
7392 (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
7393 {
7394 assert (attr->extra);
7395 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
7396 {
7397 if (json_paths)
7398 json_object_string_add(json_path, "originatorId", inet_ntoa (attr->extra->originator_id));
7399 else
7400 vty_out (vty, " Originator: %s",
7401 inet_ntoa (attr->extra->originator_id));
7402 }
7403
7404 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
7405 {
7406 int i;
7407
7408 if (json_paths)
7409 {
7410 json_cluster_list = json_object_new_object();
7411 json_cluster_list_list = json_object_new_array();
7412
7413 for (i = 0; i < attr->extra->cluster->length / 4; i++)
7414 {
7415 json_string = json_object_new_string(inet_ntoa (attr->extra->cluster->list[i]));
7416 json_object_array_add(json_cluster_list_list, json_string);
7417 }
7418
7419 /* struct cluster_list does not have "str" variable like
7420 * aspath and community do. Add this someday if someone
7421 * asks for it.
7422 json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
7423 */
7424 json_object_object_add(json_cluster_list, "list", json_cluster_list_list);
7425 json_object_object_add(json_path, "clusterList", json_cluster_list);
7426 }
7427 else
7428 {
7429 vty_out (vty, ", Cluster list: ");
7430
7431 for (i = 0; i < attr->extra->cluster->length / 4; i++)
7432 {
7433 vty_out (vty, "%s ",
7434 inet_ntoa (attr->extra->cluster->list[i]));
7435 }
7436 }
7437 }
7438
7439 if (!json_paths)
7440 vty_out (vty, "%s", VTY_NEWLINE);
7441 }
7442
7443 if (binfo->extra && binfo->extra->damp_info)
7444 bgp_damp_info_vty (vty, binfo, json_path);
7445
7446 /* Line 8 display Addpath IDs */
7447 if (binfo->addpath_rx_id || binfo->addpath_tx_id)
7448 {
7449 if (json_paths)
7450 {
7451 json_object_int_add(json_path, "addpathRxId", binfo->addpath_rx_id);
7452 json_object_int_add(json_path, "addpathTxId", binfo->addpath_tx_id);
7453 }
7454 else
7455 {
7456 vty_out (vty, " AddPath ID: RX %u, TX %u%s",
7457 binfo->addpath_rx_id, binfo->addpath_tx_id,
7458 VTY_NEWLINE);
7459 }
7460 }
7461
7462 /* If we used addpath to TX a non-bestpath we need to display
7463 * "Advertised to" on a path-by-path basis */
7464 if (bgp->addpath_tx_used[afi][safi])
7465 {
7466 first = 1;
7467
7468 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
7469 {
7470 addpath_capable = bgp_addpath_encode_tx (peer, afi, safi);
7471 has_adj = bgp_adj_out_lookup (peer, binfo->net, binfo->addpath_tx_id);
7472
7473 if ((addpath_capable && has_adj) ||
7474 (!addpath_capable && has_adj && CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)))
7475 {
7476 if (json_path && !json_adv_to)
7477 json_adv_to = json_object_new_object();
7478
7479 route_vty_out_advertised_to(vty, peer, &first,
7480 " Advertised to:",
7481 json_adv_to);
7482 }
7483 }
7484
7485 if (json_path)
7486 {
7487 if (json_adv_to)
7488 {
7489 json_object_object_add(json_path, "advertisedTo", json_adv_to);
7490 }
7491 }
7492 else
7493 {
7494 if (!first)
7495 {
7496 vty_out (vty, "%s", VTY_NEWLINE);
7497 }
7498 }
7499 }
7500
7501 /* Line 9 display Uptime */
7502 tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
7503 if (json_paths)
7504 {
7505 json_last_update = json_object_new_object();
7506 json_object_int_add(json_last_update, "epoch", tbuf);
7507 json_object_string_add(json_last_update, "string", ctime(&tbuf));
7508 json_object_object_add(json_path, "lastUpdate", json_last_update);
7509 }
7510 else
7511 vty_out (vty, " Last update: %s", ctime(&tbuf));
7512 }
7513
7514 /* We've constructed the json object for this path, add it to the json
7515 * array of paths
7516 */
7517 if (json_paths)
7518 {
7519 if (json_nexthop_global || json_nexthop_ll)
7520 {
7521 json_nexthops = json_object_new_array();
7522
7523 if (json_nexthop_global)
7524 json_object_array_add(json_nexthops, json_nexthop_global);
7525
7526 if (json_nexthop_ll)
7527 json_object_array_add(json_nexthops, json_nexthop_ll);
7528
7529 json_object_object_add(json_path, "nexthops", json_nexthops);
7530 }
7531
7532 json_object_object_add(json_path, "peer", json_peer);
7533 json_object_array_add(json_paths, json_path);
7534 }
7535 else
7536 vty_out (vty, "%s", VTY_NEWLINE);
7537 }
7538
7539 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
7540 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
7541 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
7542
7543 static int
7544 bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
7545 const char *prefix_list_str, afi_t afi,
7546 safi_t safi, enum bgp_show_type type);
7547 static int
7548 bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
7549 const char *filter, afi_t afi,
7550 safi_t safi, enum bgp_show_type type);
7551 static int
7552 bgp_show_route_map (struct vty *vty, struct bgp *bgp,
7553 const char *rmap_str, afi_t afi,
7554 safi_t safi, enum bgp_show_type type);
7555 static int
7556 bgp_show_community_list (struct vty *vty, struct bgp *bgp,
7557 const char *com, int exact,
7558 afi_t afi, safi_t safi);
7559 static int
7560 bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
7561 const char *prefix, afi_t afi,
7562 safi_t safi, enum bgp_show_type type);
7563 static int
7564 bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
7565 safi_t safi, enum bgp_show_type type);
7566 static int
7567 bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
7568 struct cmd_token **argv, int exact, afi_t afi, safi_t safi);
7569
7570 static int
7571 bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
7572 enum bgp_show_type type, void *output_arg, u_char use_json)
7573 {
7574 struct bgp_info *ri;
7575 struct bgp_node *rn;
7576 int header = 1;
7577 int display;
7578 unsigned long output_count;
7579 unsigned long total_count;
7580 struct prefix *p;
7581 char buf[BUFSIZ];
7582 char buf2[BUFSIZ];
7583 json_object *json_paths = NULL;
7584 int first = 1;
7585
7586 if (use_json)
7587 {
7588 vty_out (vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ",
7589 bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
7590 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name,
7591 table->version, inet_ntoa (bgp->router_id));
7592 json_paths = json_object_new_object();
7593 }
7594
7595 /* This is first entry point, so reset total line. */
7596 output_count = 0;
7597 total_count = 0;
7598
7599 /* Start processing of routes. */
7600 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
7601 if (rn->info != NULL)
7602 {
7603 display = 0;
7604 if (!first && use_json)
7605 {
7606 vty_out (vty, ",");
7607 }
7608 if (use_json)
7609 json_paths = json_object_new_array();
7610 else
7611 json_paths = NULL;
7612
7613 for (ri = rn->info; ri; ri = ri->next)
7614 {
7615 total_count++;
7616 if (type == bgp_show_type_flap_statistics
7617 || type == bgp_show_type_flap_neighbor
7618 || type == bgp_show_type_dampend_paths
7619 || type == bgp_show_type_damp_neighbor)
7620 {
7621 if (!(ri->extra && ri->extra->damp_info))
7622 continue;
7623 }
7624 if (type == bgp_show_type_regexp)
7625 {
7626 regex_t *regex = output_arg;
7627
7628 if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
7629 continue;
7630 }
7631 if (type == bgp_show_type_prefix_list)
7632 {
7633 struct prefix_list *plist = output_arg;
7634
7635 if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
7636 continue;
7637 }
7638 if (type == bgp_show_type_filter_list)
7639 {
7640 struct as_list *as_list = output_arg;
7641
7642 if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
7643 continue;
7644 }
7645 if (type == bgp_show_type_route_map)
7646 {
7647 struct route_map *rmap = output_arg;
7648 struct bgp_info binfo;
7649 struct attr dummy_attr;
7650 struct attr_extra dummy_extra;
7651 int ret;
7652
7653 dummy_attr.extra = &dummy_extra;
7654 bgp_attr_dup (&dummy_attr, ri->attr);
7655
7656 binfo.peer = ri->peer;
7657 binfo.attr = &dummy_attr;
7658
7659 ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
7660 if (ret == RMAP_DENYMATCH)
7661 continue;
7662 }
7663 if (type == bgp_show_type_neighbor
7664 || type == bgp_show_type_flap_neighbor
7665 || type == bgp_show_type_damp_neighbor)
7666 {
7667 union sockunion *su = output_arg;
7668
7669 if (ri->peer == NULL ||
7670 ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
7671 continue;
7672 }
7673 if (type == bgp_show_type_cidr_only)
7674 {
7675 u_int32_t destination;
7676
7677 destination = ntohl (rn->p.u.prefix4.s_addr);
7678 if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
7679 continue;
7680 if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
7681 continue;
7682 if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
7683 continue;
7684 }
7685 if (type == bgp_show_type_prefix_longer)
7686 {
7687 struct prefix *p = output_arg;
7688
7689 if (! prefix_match (p, &rn->p))
7690 continue;
7691 }
7692 if (type == bgp_show_type_community_all)
7693 {
7694 if (! ri->attr->community)
7695 continue;
7696 }
7697 if (type == bgp_show_type_community)
7698 {
7699 struct community *com = output_arg;
7700
7701 if (! ri->attr->community ||
7702 ! community_match (ri->attr->community, com))
7703 continue;
7704 }
7705 if (type == bgp_show_type_community_exact)
7706 {
7707 struct community *com = output_arg;
7708
7709 if (! ri->attr->community ||
7710 ! community_cmp (ri->attr->community, com))
7711 continue;
7712 }
7713 if (type == bgp_show_type_community_list)
7714 {
7715 struct community_list *list = output_arg;
7716
7717 if (! community_list_match (ri->attr->community, list))
7718 continue;
7719 }
7720 if (type == bgp_show_type_community_list_exact)
7721 {
7722 struct community_list *list = output_arg;
7723
7724 if (! community_list_exact_match (ri->attr->community, list))
7725 continue;
7726 }
7727 if (type == bgp_show_type_lcommunity)
7728 {
7729 struct lcommunity *lcom = output_arg;
7730
7731 if (! ri->attr->extra || ! ri->attr->extra->lcommunity ||
7732 ! lcommunity_match (ri->attr->extra->lcommunity, lcom))
7733 continue;
7734 }
7735 if (type == bgp_show_type_lcommunity_list)
7736 {
7737 struct community_list *list = output_arg;
7738
7739 if (! ri->attr->extra ||
7740 ! lcommunity_list_match (ri->attr->extra->lcommunity, list))
7741 continue;
7742 }
7743 if (type == bgp_show_type_lcommunity_all)
7744 {
7745 if (! ri->attr->extra || ! ri->attr->extra->lcommunity)
7746 continue;
7747 }
7748 if (type == bgp_show_type_dampend_paths
7749 || type == bgp_show_type_damp_neighbor)
7750 {
7751 if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
7752 || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
7753 continue;
7754 }
7755
7756 if (!use_json && header)
7757 {
7758 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
7759 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
7760 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
7761 if (type == bgp_show_type_dampend_paths
7762 || type == bgp_show_type_damp_neighbor)
7763 vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
7764 else if (type == bgp_show_type_flap_statistics
7765 || type == bgp_show_type_flap_neighbor)
7766 vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
7767 else
7768 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
7769 header = 0;
7770 }
7771
7772 if (type == bgp_show_type_dampend_paths
7773 || type == bgp_show_type_damp_neighbor)
7774 damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
7775 else if (type == bgp_show_type_flap_statistics
7776 || type == bgp_show_type_flap_neighbor)
7777 flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
7778 else
7779 route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, json_paths);
7780 display++;
7781 }
7782
7783 if (display)
7784 {
7785 output_count++;
7786 if (use_json)
7787 {
7788 p = &rn->p;
7789 sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
7790 vty_out (vty, "\"%s\": ", buf2);
7791 vty_out (vty, "%s", json_object_to_json_string (json_paths));
7792 json_object_free (json_paths);
7793 first = 0;
7794
7795 }
7796 }
7797 }
7798
7799 if (use_json)
7800 {
7801 json_object_free (json_paths);
7802 vty_out (vty, " } }%s", VTY_NEWLINE);
7803 }
7804 else
7805 {
7806 /* No route is displayed */
7807 if (output_count == 0)
7808 {
7809 if (type == bgp_show_type_normal)
7810 vty_out (vty, "No BGP prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
7811 }
7812 else
7813 vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
7814 VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
7815 }
7816
7817 return CMD_SUCCESS;
7818 }
7819
7820 static int
7821 bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
7822 enum bgp_show_type type, void *output_arg, u_char use_json)
7823 {
7824 struct bgp_table *table;
7825
7826 if (bgp == NULL)
7827 {
7828 bgp = bgp_get_default ();
7829 }
7830
7831 if (bgp == NULL)
7832 {
7833 if (!use_json)
7834 vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
7835 return CMD_WARNING;
7836 }
7837 /* use MPLS and ENCAP specific shows until they are merged */
7838 if (safi == SAFI_MPLS_VPN)
7839 {
7840 return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg,
7841 0, use_json);
7842 }
7843
7844 table = bgp->rib[afi][safi];
7845
7846 return bgp_show_table (vty, bgp, table, type, output_arg,
7847 use_json);
7848 }
7849
7850 static void
7851 bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
7852 u_char use_json)
7853 {
7854 struct listnode *node, *nnode;
7855 struct bgp *bgp;
7856 struct bgp_table *table;
7857 int is_first = 1;
7858
7859 if (use_json)
7860 vty_out (vty, "{%s", VTY_NEWLINE);
7861
7862 for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
7863 {
7864 if (use_json)
7865 {
7866 if (! is_first)
7867 vty_out (vty, ",%s", VTY_NEWLINE);
7868 else
7869 is_first = 0;
7870
7871 vty_out(vty, "\"%s\":", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
7872 ? "Default" : bgp->name);
7873 }
7874 else
7875 {
7876 vty_out (vty, "%sInstance %s:%s",
7877 VTY_NEWLINE,
7878 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
7879 ? "Default" : bgp->name,
7880 VTY_NEWLINE);
7881 }
7882 table = bgp->rib[afi][safi];
7883 bgp_show_table (vty, bgp, table,
7884 bgp_show_type_normal, NULL, use_json);
7885
7886 }
7887
7888 if (use_json)
7889 vty_out (vty, "}%s", VTY_NEWLINE);
7890 }
7891
7892 /* Header of detailed BGP route information */
7893 static void
7894 route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
7895 struct bgp_node *rn,
7896 struct prefix_rd *prd, afi_t afi, safi_t safi,
7897 json_object *json)
7898 {
7899 struct bgp_info *ri;
7900 struct prefix *p;
7901 struct peer *peer;
7902 struct listnode *node, *nnode;
7903 char buf1[INET6_ADDRSTRLEN];
7904 char buf2[INET6_ADDRSTRLEN];
7905 int count = 0;
7906 int best = 0;
7907 int suppress = 0;
7908 int no_export = 0;
7909 int no_advertise = 0;
7910 int local_as = 0;
7911 int first = 1;
7912 json_object *json_adv_to = NULL;
7913
7914 p = &rn->p;
7915
7916 if (json)
7917 {
7918 json_object_string_add(json, "prefix", inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN));
7919 json_object_int_add(json, "prefixlen", p->prefixlen);
7920 }
7921 else
7922 {
7923 if (p->family == AF_ETHERNET)
7924 prefix2str (p, buf2, INET6_ADDRSTRLEN);
7925 else
7926 inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN);
7927 vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
7928 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) ?
7929 prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
7930 ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
7931 buf2,
7932 p->prefixlen, VTY_NEWLINE);
7933 }
7934
7935 for (ri = rn->info; ri; ri = ri->next)
7936 {
7937 count++;
7938 if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
7939 {
7940 best = count;
7941 if (ri->extra && ri->extra->suppress)
7942 suppress = 1;
7943 if (ri->attr->community != NULL)
7944 {
7945 if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
7946 no_advertise = 1;
7947 if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
7948 no_export = 1;
7949 if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
7950 local_as = 1;
7951 }
7952 }
7953 }
7954
7955 if (!json)
7956 {
7957 vty_out (vty, "Paths: (%d available", count);
7958 if (best)
7959 {
7960 vty_out (vty, ", best #%d", best);
7961 if (safi == SAFI_UNICAST)
7962 vty_out (vty, ", table %s",
7963 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
7964 ? "Default-IP-Routing-Table" : bgp->name);
7965 }
7966 else
7967 vty_out (vty, ", no best path");
7968
7969 if (no_advertise)
7970 vty_out (vty, ", not advertised to any peer");
7971 else if (no_export)
7972 vty_out (vty, ", not advertised to EBGP peer");
7973 else if (local_as)
7974 vty_out (vty, ", not advertised outside local AS");
7975
7976 if (suppress)
7977 vty_out (vty, ", Advertisements suppressed by an aggregate.");
7978 vty_out (vty, ")%s", VTY_NEWLINE);
7979 }
7980
7981 /* If we are not using addpath then we can display Advertised to and that will
7982 * show what peers we advertised the bestpath to. If we are using addpath
7983 * though then we must display Advertised to on a path-by-path basis. */
7984 if (!bgp->addpath_tx_used[afi][safi])
7985 {
7986 for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
7987 {
7988 if (bgp_adj_out_lookup (peer, rn, 0))
7989 {
7990 if (json && !json_adv_to)
7991 json_adv_to = json_object_new_object();
7992
7993 route_vty_out_advertised_to(vty, peer, &first,
7994 " Advertised to non peer-group peers:\n ",
7995 json_adv_to);
7996 }
7997 }
7998
7999 if (json)
8000 {
8001 if (json_adv_to)
8002 {
8003 json_object_object_add(json, "advertisedTo", json_adv_to);
8004 }
8005 }
8006 else
8007 {
8008 if (first)
8009 vty_out (vty, " Not advertised to any peer");
8010 vty_out (vty, "%s", VTY_NEWLINE);
8011 }
8012 }
8013 }
8014
8015 /* Display specified route of BGP table. */
8016 static int
8017 bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
8018 struct bgp_table *rib, const char *ip_str,
8019 afi_t afi, safi_t safi, struct prefix_rd *prd,
8020 int prefix_check, enum bgp_path_type pathtype,
8021 u_char use_json)
8022 {
8023 int ret;
8024 int header;
8025 int display = 0;
8026 struct prefix match;
8027 struct bgp_node *rn;
8028 struct bgp_node *rm;
8029 struct bgp_info *ri;
8030 struct bgp_table *table;
8031 json_object *json = NULL;
8032 json_object *json_paths = NULL;
8033
8034 /* Check IP address argument. */
8035 ret = str2prefix (ip_str, &match);
8036 if (! ret)
8037 {
8038 vty_out (vty, "address is malformed%s", VTY_NEWLINE);
8039 return CMD_WARNING;
8040 }
8041
8042 match.family = afi2family (afi);
8043
8044 if (use_json)
8045 {
8046 json = json_object_new_object();
8047 json_paths = json_object_new_array();
8048 }
8049
8050 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
8051 {
8052 for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
8053 {
8054 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
8055 continue;
8056
8057 if ((table = rn->info) != NULL)
8058 {
8059 header = 1;
8060
8061 if ((rm = bgp_node_match (table, &match)) != NULL)
8062 {
8063 if (prefix_check && rm->p.prefixlen != match.prefixlen)
8064 {
8065 bgp_unlock_node (rm);
8066 continue;
8067 }
8068
8069 for (ri = rm->info; ri; ri = ri->next)
8070 {
8071 if (header)
8072 {
8073 route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
8074 AFI_IP, safi, json);
8075 header = 0;
8076 }
8077 display++;
8078
8079 if (pathtype == BGP_PATH_ALL ||
8080 (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
8081 (pathtype == BGP_PATH_MULTIPATH &&
8082 (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
8083 route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, safi, json_paths);
8084 }
8085
8086 bgp_unlock_node (rm);
8087 }
8088 }
8089 }
8090 }
8091 else
8092 {
8093 header = 1;
8094
8095 if ((rn = bgp_node_match (rib, &match)) != NULL)
8096 {
8097 if (! prefix_check || rn->p.prefixlen == match.prefixlen)
8098 {
8099 for (ri = rn->info; ri; ri = ri->next)
8100 {
8101 if (header)
8102 {
8103 route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi, json);
8104 header = 0;
8105 }
8106 display++;
8107
8108 if (pathtype == BGP_PATH_ALL ||
8109 (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
8110 (pathtype == BGP_PATH_MULTIPATH &&
8111 (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
8112 route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi, json_paths);
8113 }
8114 }
8115
8116 bgp_unlock_node (rn);
8117 }
8118 }
8119
8120 if (use_json)
8121 {
8122 if (display)
8123 json_object_object_add(json, "paths", json_paths);
8124
8125 vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
8126 json_object_free(json);
8127 }
8128 else
8129 {
8130 if (!display)
8131 {
8132 vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
8133 return CMD_WARNING;
8134 }
8135 }
8136
8137 return CMD_SUCCESS;
8138 }
8139
8140 /* Display specified route of Main RIB */
8141 static int
8142 bgp_show_route (struct vty *vty, struct bgp *bgp, const char *ip_str,
8143 afi_t afi, safi_t safi, struct prefix_rd *prd,
8144 int prefix_check, enum bgp_path_type pathtype,
8145 u_char use_json)
8146 {
8147 if (!bgp)
8148 bgp = bgp_get_default ();
8149
8150 return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
8151 afi, safi, prd, prefix_check, pathtype,
8152 use_json);
8153 }
8154
8155 static int
8156 bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc,
8157 struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj)
8158 {
8159 struct lcommunity *lcom;
8160 struct buffer *b;
8161 int i;
8162 char *str;
8163 int first = 0;
8164
8165 b = buffer_new (1024);
8166 for (i = 0; i < argc; i++)
8167 {
8168 if (first)
8169 buffer_putc (b, ' ');
8170 else
8171 {
8172 if (strmatch (argv[i]->text, "AA:BB:CC"))
8173 {
8174 first = 1;
8175 buffer_putstr (b, argv[i]->arg);
8176 }
8177 }
8178 }
8179 buffer_putc (b, '\0');
8180
8181 str = buffer_getstr (b);
8182 buffer_free (b);
8183
8184 lcom = lcommunity_str2com (str);
8185 XFREE (MTYPE_TMP, str);
8186 if (! lcom)
8187 {
8188 vty_out (vty, "%% Large-community malformed%s", VTY_NEWLINE);
8189 return CMD_WARNING;
8190 }
8191
8192 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom, uj);
8193 }
8194
8195 static int
8196 bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
8197 afi_t afi, safi_t safi, u_char uj)
8198 {
8199 struct community_list *list;
8200
8201 list = community_list_lookup (bgp_clist, lcom, LARGE_COMMUNITY_LIST_MASTER);
8202 if (list == NULL)
8203 {
8204 vty_out (vty, "%% %s is not a valid large-community-list name%s", lcom,
8205 VTY_NEWLINE);
8206 return CMD_WARNING;
8207 }
8208
8209 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_list, list, uj);
8210 }
8211
8212 DEFUN (show_ip_bgp_large_community_list,
8213 show_ip_bgp_large_community_list_cmd,
8214 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn>]] large-community-list <(1-500)|WORD> [json]",
8215 SHOW_STR
8216 IP_STR
8217 BGP_STR
8218 BGP_INSTANCE_HELP_STR
8219 "Address Family\n"
8220 "Address Family\n"
8221 "Address Family modifier\n"
8222 "Address Family modifier\n"
8223 "Address Family modifier\n"
8224 "Display routes matching the large-community-list\n"
8225 "large-community-list number\n"
8226 "large-community-list name\n"
8227 JSON_STR)
8228 {
8229 char *vrf = NULL;
8230 afi_t afi = AFI_IP6;
8231 safi_t safi = SAFI_UNICAST;
8232 int idx = 0;
8233
8234 if (argv_find (argv, argc, "ip", &idx))
8235 afi = AFI_IP;
8236 if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
8237 vrf = argv[++idx]->arg;
8238 if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
8239 {
8240 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8241 if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
8242 safi = bgp_vty_safi_from_arg (argv[idx]->text);
8243 }
8244
8245 int uj = use_json (argc, argv);
8246
8247 struct bgp *bgp = bgp_lookup_by_name (vrf);
8248 if (bgp == NULL)
8249 {
8250 vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
8251 return CMD_WARNING;
8252 }
8253
8254 argv_find (argv, argc, "large-community-list", &idx);
8255 return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj);
8256 }
8257 DEFUN (show_ip_bgp_large_community,
8258 show_ip_bgp_large_community_cmd,
8259 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn>]] large-community [AA:BB:CC] [json]",
8260 SHOW_STR
8261 IP_STR
8262 BGP_STR
8263 BGP_INSTANCE_HELP_STR
8264 "Address Family\n"
8265 "Address Family\n"
8266 "Address Family modifier\n"
8267 "Address Family modifier\n"
8268 "Address Family modifier\n"
8269 "Display routes matching the large-communities\n"
8270 "List of large-community numbers\n"
8271 JSON_STR)
8272 {
8273 char *vrf = NULL;
8274 afi_t afi = AFI_IP6;
8275 safi_t safi = SAFI_UNICAST;
8276 int idx = 0;
8277
8278 if (argv_find (argv, argc, "ip", &idx))
8279 afi = AFI_IP;
8280 if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
8281 vrf = argv[++idx]->arg;
8282 if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
8283 {
8284 afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
8285 if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
8286 safi = bgp_vty_safi_from_arg (argv[idx]->text);
8287 }
8288
8289 int uj = use_json (argc, argv);
8290
8291 struct bgp *bgp = bgp_lookup_by_name (vrf);
8292 if (bgp == NULL)
8293 {
8294 vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
8295 return CMD_WARNING;
8296 }
8297
8298 if (argv_find (argv, argc, "AA:BB:CC", &idx))
8299 return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj);
8300 else
8301 return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj);
8302 }
8303
8304 static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi);
8305
8306 /* BGP route print out function. */
8307 DEFUN (show_ip_bgp,
8308 show_ip_bgp_cmd,
8309 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]\
8310 [<\
8311 cidr-only\
8312 |dampening <flap-statistics|dampened-paths|parameters>\
8313 |route-map WORD\
8314 |prefix-list WORD\
8315 |filter-list WORD\
8316 |statistics\
8317 |community [<AA:NN|local-AS|no-advertise|no-export> [exact-match]]\
8318 |community-list <(1-500)|WORD> [exact-match]\
8319 |A.B.C.D/M longer-prefixes\
8320 |X:X::X:X/M longer-prefixes>\
8321 ] [json]",
8322 SHOW_STR
8323 IP_STR
8324 BGP_STR
8325 BGP_INSTANCE_HELP_STR
8326 BGP_AFI_HELP_STR
8327 BGP_SAFI_HELP_STR
8328 "Display only routes with non-natural netmasks\n"
8329 "Display detailed information about dampening\n"
8330 "Display flap statistics of routes\n"
8331 "Display paths suppressed due to dampening\n"
8332 "Display detail of configured dampening parameters\n"
8333 "Display routes matching the route-map\n"
8334 "A route-map to match on\n"
8335 "Display routes conforming to the prefix-list\n"
8336 "Prefix-list name\n"
8337 "Display routes conforming to the filter-list\n"
8338 "Regular expression access list name\n"
8339 "BGP RIB advertisement statistics\n"
8340 "Display routes matching the communities\n"
8341 COMMUNITY_AANN_STR
8342 "Do not send outside local AS (well-known community)\n"
8343 "Do not advertise to any peer (well-known community)\n"
8344 "Do not export to next AS (well-known community)\n"
8345 "Exact match of the communities\n"
8346 "Display routes matching the community-list\n"
8347 "community-list number\n"
8348 "community-list name\n"
8349 "Exact match of the communities\n"
8350 "IPv4 prefix\n"
8351 "Display route and more specific routes\n"
8352 "IPv6 prefix\n"
8353 "Display route and more specific routes\n"
8354 JSON_STR)
8355 {
8356 afi_t afi = AFI_IP6;
8357 safi_t safi = SAFI_UNICAST;
8358 int exact_match = 0;
8359 enum bgp_show_type sh_type = bgp_show_type_normal;
8360 struct bgp *bgp = NULL;
8361 int idx = 0;
8362
8363 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8364 if (!idx)
8365 return CMD_WARNING;
8366
8367 int uj = use_json (argc, argv);
8368 if (uj) argc--;
8369
8370 if (argv_find(argv, argc, "cidr-only", &idx))
8371 return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
8372
8373 if (argv_find(argv, argc, "dampening", &idx))
8374 {
8375 if (argv_find (argv, argc, "dampened-paths", &idx))
8376 return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
8377 else if (argv_find (argv, argc, "flap-statistics", &idx))
8378 return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
8379 else if (argv_find (argv, argc, "parameters", &idx))
8380 return bgp_show_dampening_parameters (vty, afi, safi);
8381 }
8382
8383 if (argv_find(argv, argc, "prefix-list", &idx))
8384 return bgp_show_prefix_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
8385
8386 if (argv_find(argv, argc, "filter-list", &idx))
8387 return bgp_show_filter_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
8388
8389 if (argv_find(argv, argc, "statistics", &idx))
8390 return bgp_table_stats (vty, bgp, afi, safi);
8391
8392 if (argv_find(argv, argc, "route-map", &idx))
8393 return bgp_show_route_map (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
8394
8395 if (argv_find(argv, argc, "community", &idx))
8396 {
8397 /* show a specific community */
8398 if (argv_find (argv, argc, "local-AS", &idx) ||
8399 argv_find (argv, argc, "no-advertise", &idx) ||
8400 argv_find (argv, argc, "no-export", &idx))
8401 {
8402 if (argv_find (argv, argc, "exact_match", &idx))
8403 exact_match = 1;
8404 return bgp_show_community (vty, bgp, argc, argv, exact_match, afi, safi);
8405 }
8406 /* show all communities */
8407 else
8408 return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
8409 }
8410
8411 if (argv_find(argv, argc, "community-list", &idx))
8412 {
8413 const char *clist_number_or_name = argv[++idx]->arg;
8414 if (++idx < argc && strmatch (argv[idx]->text, "exact-match"))
8415 exact_match = 1;
8416 return bgp_show_community_list (vty, bgp, clist_number_or_name, exact_match, afi, safi);
8417 }
8418 /* prefix-longer */
8419 if (argv_find(argv, argc, "A.B.C.D/M", &idx) || argv_find(argv, argc, "X:X::X:X/M", &idx))
8420 return bgp_show_prefix_longer (vty, bgp, argv[idx]->arg, afi, safi, bgp_show_type_prefix_longer);
8421
8422 if (safi == SAFI_MPLS_VPN)
8423 return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj);
8424 else
8425 return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
8426 }
8427
8428 DEFUN (show_ip_bgp_route,
8429 show_ip_bgp_route_cmd,
8430 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]]"
8431 "<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [json]",
8432 SHOW_STR
8433 IP_STR
8434 BGP_STR
8435 BGP_INSTANCE_HELP_STR
8436 BGP_AFI_HELP_STR
8437 BGP_SAFI_HELP_STR
8438 "Network in the BGP routing table to display\n"
8439 "IPv4 prefix\n"
8440 "Network in the BGP routing table to display\n"
8441 "IPv6 prefix\n"
8442 "Display only the bestpath\n"
8443 "Display only multipaths\n"
8444 JSON_STR)
8445 {
8446 int prefix_check = 0;
8447
8448 afi_t afi = AFI_IP6;
8449 safi_t safi = SAFI_UNICAST;
8450 char *prefix = NULL;
8451 struct bgp *bgp = NULL;
8452 enum bgp_path_type path_type;
8453 u_char uj = use_json(argc, argv);
8454
8455 int idx = 0;
8456
8457 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8458 if (!idx)
8459 return CMD_WARNING;
8460
8461 if (!bgp)
8462 {
8463 vty_out (vty, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE);
8464 return CMD_WARNING;
8465 }
8466
8467 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
8468 if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
8469 prefix_check = 0;
8470 else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
8471 prefix_check = 1;
8472
8473 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
8474 {
8475 vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
8476 return CMD_WARNING;
8477 }
8478 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
8479 {
8480 vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
8481 return CMD_WARNING;
8482 }
8483
8484 prefix = argv[idx]->arg;
8485
8486 /* [<bestpath|multipath>] */
8487 if (argv_find (argv, argc, "bestpath", &idx))
8488 path_type = BGP_PATH_BESTPATH;
8489 else if (argv_find (argv, argc, "multipath", &idx))
8490 path_type = BGP_PATH_MULTIPATH;
8491 else
8492 path_type = BGP_PATH_ALL;
8493
8494 return bgp_show_route (vty, bgp, prefix, afi, safi, NULL, prefix_check, path_type, uj);
8495 }
8496
8497 DEFUN (show_ip_bgp_regexp,
8498 show_ip_bgp_regexp_cmd,
8499 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] regexp REGEX...",
8500 SHOW_STR
8501 IP_STR
8502 BGP_STR
8503 BGP_INSTANCE_HELP_STR
8504 BGP_AFI_HELP_STR
8505 BGP_SAFI_HELP_STR
8506 "Display routes matching the AS path regular expression\n"
8507 "A regular-expression to match the BGP AS paths\n")
8508 {
8509 afi_t afi = AFI_IP6;
8510 safi_t safi = SAFI_UNICAST;
8511 struct bgp *bgp = NULL;
8512
8513 int idx = 0;
8514 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8515 if (!idx)
8516 return CMD_WARNING;
8517
8518 // get index of regex
8519 argv_find (argv, argc, "regexp", &idx);
8520 idx++;
8521
8522 char *regstr = argv_concat (argv, argc, idx);
8523 int rc = bgp_show_regexp (vty, (const char *) regstr, afi, safi, bgp_show_type_regexp);
8524 XFREE (MTYPE_TMP, regstr);
8525 return rc;
8526 }
8527
8528 DEFUN (show_ip_bgp_instance_all,
8529 show_ip_bgp_instance_all_cmd,
8530 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] [json]",
8531 SHOW_STR
8532 IP_STR
8533 BGP_STR
8534 BGP_INSTANCE_ALL_HELP_STR
8535 BGP_AFI_HELP_STR
8536 BGP_SAFI_HELP_STR
8537 JSON_STR)
8538 {
8539 afi_t afi = AFI_IP;
8540 safi_t safi = SAFI_UNICAST;
8541 struct bgp *bgp = NULL;
8542
8543 int idx = 0;
8544 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
8545 if (!idx)
8546 return CMD_WARNING;
8547
8548 int uj = use_json (argc, argv);
8549 if (uj) argc--;
8550
8551 bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
8552 return CMD_SUCCESS;
8553 }
8554
8555 static int
8556 bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
8557 safi_t safi, enum bgp_show_type type)
8558 {
8559 regex_t *regex;
8560 int rc;
8561
8562 regex = bgp_regcomp (regstr);
8563 if (! regex)
8564 {
8565 vty_out (vty, "Can't compile regexp %s%s", regstr, VTY_NEWLINE);
8566 return CMD_WARNING;
8567 }
8568
8569 rc = bgp_show (vty, NULL, afi, safi, type, regex, 0);
8570 bgp_regex_free (regex);
8571 return rc;
8572 }
8573
8574 static int
8575 bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
8576 const char *prefix_list_str, afi_t afi,
8577 safi_t safi, enum bgp_show_type type)
8578 {
8579 struct prefix_list *plist;
8580
8581 plist = prefix_list_lookup (afi, prefix_list_str);
8582 if (plist == NULL)
8583 {
8584 vty_out (vty, "%% %s is not a valid prefix-list name%s",
8585 prefix_list_str, VTY_NEWLINE);
8586 return CMD_WARNING;
8587 }
8588
8589 return bgp_show (vty, bgp, afi, safi, type, plist, 0);
8590 }
8591
8592 static int
8593 bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
8594 const char *filter, afi_t afi,
8595 safi_t safi, enum bgp_show_type type)
8596 {
8597 struct as_list *as_list;
8598
8599 as_list = as_list_lookup (filter);
8600 if (as_list == NULL)
8601 {
8602 vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
8603 return CMD_WARNING;
8604 }
8605
8606 return bgp_show (vty, bgp, afi, safi, type, as_list, 0);
8607 }
8608
8609 static int
8610 bgp_show_route_map (struct vty *vty, struct bgp *bgp,
8611 const char *rmap_str, afi_t afi,
8612 safi_t safi, enum bgp_show_type type)
8613 {
8614 struct route_map *rmap;
8615
8616 rmap = route_map_lookup_by_name (rmap_str);
8617 if (! rmap)
8618 {
8619 vty_out (vty, "%% %s is not a valid route-map name%s",
8620 rmap_str, VTY_NEWLINE);
8621 return CMD_WARNING;
8622 }
8623
8624 return bgp_show (vty, bgp, afi, safi, type, rmap, 0);
8625 }
8626
8627 static int
8628 bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
8629 struct cmd_token **argv, int exact, afi_t afi, safi_t safi)
8630 {
8631 struct community *com;
8632 struct buffer *b;
8633 int i;
8634 char *str;
8635 int first = 0;
8636
8637 b = buffer_new (1024);
8638 for (i = 0; i < argc; i++)
8639 {
8640 if (first)
8641 buffer_putc (b, ' ');
8642 else
8643 {
8644 if ((strcmp (argv[i]->arg, "unicast") == 0) || (strcmp (argv[i]->arg, "multicast") == 0))
8645 continue;
8646 first = 1;
8647 }
8648
8649 buffer_putstr (b, argv[i]->arg);
8650 }
8651 buffer_putc (b, '\0');
8652
8653 str = buffer_getstr (b);
8654 buffer_free (b);
8655
8656 com = community_str2com (str);
8657 XFREE (MTYPE_TMP, str);
8658 if (! com)
8659 {
8660 vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
8661 return CMD_WARNING;
8662 }
8663
8664 return bgp_show (vty, bgp, afi, safi,
8665 (exact ? bgp_show_type_community_exact :
8666 bgp_show_type_community), com, 0);
8667 }
8668
8669 static int
8670 bgp_show_community_list (struct vty *vty, struct bgp *bgp,
8671 const char *com, int exact,
8672 afi_t afi, safi_t safi)
8673 {
8674 struct community_list *list;
8675
8676 list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
8677 if (list == NULL)
8678 {
8679 vty_out (vty, "%% %s is not a valid community-list name%s", com,
8680 VTY_NEWLINE);
8681 return CMD_WARNING;
8682 }
8683
8684 return bgp_show (vty, bgp, afi, safi,
8685 (exact ? bgp_show_type_community_list_exact :
8686 bgp_show_type_community_list), list, 0);
8687 }
8688
8689 static int
8690 bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
8691 const char *prefix, afi_t afi,
8692 safi_t safi, enum bgp_show_type type)
8693 {
8694 int ret;
8695 struct prefix *p;
8696
8697 p = prefix_new();
8698
8699 ret = str2prefix (prefix, p);
8700 if (! ret)
8701 {
8702 vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
8703 return CMD_WARNING;
8704 }
8705
8706 ret = bgp_show (vty, bgp, afi, safi, type, p, 0);
8707 prefix_free(p);
8708 return ret;
8709 }
8710
8711 static struct peer *
8712 peer_lookup_in_view (struct vty *vty, struct bgp *bgp,
8713 const char *ip_str, u_char use_json)
8714 {
8715 int ret;
8716 struct peer *peer;
8717 union sockunion su;
8718
8719 /* Get peer sockunion. */
8720 ret = str2sockunion (ip_str, &su);
8721 if (ret < 0)
8722 {
8723 peer = peer_lookup_by_conf_if (bgp, ip_str);
8724 if (!peer)
8725 {
8726 peer = peer_lookup_by_hostname(bgp, ip_str);
8727
8728 if (!peer)
8729 {
8730 if (use_json)
8731 {
8732 json_object *json_no = NULL;
8733 json_no = json_object_new_object();
8734 json_object_string_add(json_no, "malformedAddressOrName", ip_str);
8735 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
8736 json_object_free(json_no);
8737 }
8738 else
8739 vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
8740 return NULL;
8741 }
8742 }
8743 return peer;
8744 }
8745
8746 /* Peer structure lookup. */
8747 peer = peer_lookup (bgp, &su);
8748 if (! peer)
8749 {
8750 if (use_json)
8751 {
8752 json_object *json_no = NULL;
8753 json_no = json_object_new_object();
8754 json_object_string_add(json_no, "warning","No such neighbor");
8755 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
8756 json_object_free(json_no);
8757 }
8758 else
8759 vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
8760 return NULL;
8761 }
8762
8763 return peer;
8764 }
8765
8766 enum bgp_stats
8767 {
8768 BGP_STATS_MAXBITLEN = 0,
8769 BGP_STATS_RIB,
8770 BGP_STATS_PREFIXES,
8771 BGP_STATS_TOTPLEN,
8772 BGP_STATS_UNAGGREGATEABLE,
8773 BGP_STATS_MAX_AGGREGATEABLE,
8774 BGP_STATS_AGGREGATES,
8775 BGP_STATS_SPACE,
8776 BGP_STATS_ASPATH_COUNT,
8777 BGP_STATS_ASPATH_MAXHOPS,
8778 BGP_STATS_ASPATH_TOTHOPS,
8779 BGP_STATS_ASPATH_MAXSIZE,
8780 BGP_STATS_ASPATH_TOTSIZE,
8781 BGP_STATS_ASN_HIGHEST,
8782 BGP_STATS_MAX,
8783 };
8784
8785 static const char *table_stats_strs[] =
8786 {
8787 [BGP_STATS_PREFIXES] = "Total Prefixes",
8788 [BGP_STATS_TOTPLEN] = "Average prefix length",
8789 [BGP_STATS_RIB] = "Total Advertisements",
8790 [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
8791 [BGP_STATS_MAX_AGGREGATEABLE] = "Maximum aggregateable prefixes",
8792 [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
8793 [BGP_STATS_SPACE] = "Address space advertised",
8794 [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
8795 [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
8796 [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
8797 [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
8798 [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
8799 [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
8800 [BGP_STATS_MAX] = NULL,
8801 };
8802
8803 struct bgp_table_stats
8804 {
8805 struct bgp_table *table;
8806 unsigned long long counts[BGP_STATS_MAX];
8807 };
8808
8809 #if 0
8810 #define TALLY_SIGFIG 100000
8811 static unsigned long
8812 ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
8813 {
8814 unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
8815 unsigned long res = (newtot * TALLY_SIGFIG) / count;
8816 unsigned long ret = newtot / count;
8817
8818 if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
8819 return ret + 1;
8820 else
8821 return ret;
8822 }
8823 #endif
8824
8825 static int
8826 bgp_table_stats_walker (struct thread *t)
8827 {
8828 struct bgp_node *rn;
8829 struct bgp_node *top;
8830 struct bgp_table_stats *ts = THREAD_ARG (t);
8831 unsigned int space = 0;
8832
8833 if (!(top = bgp_table_top (ts->table)))
8834 return 0;
8835
8836 switch (top->p.family)
8837 {
8838 case AF_INET:
8839 space = IPV4_MAX_BITLEN;
8840 break;
8841 case AF_INET6:
8842 space = IPV6_MAX_BITLEN;
8843 break;
8844 }
8845
8846 ts->counts[BGP_STATS_MAXBITLEN] = space;
8847
8848 for (rn = top; rn; rn = bgp_route_next (rn))
8849 {
8850 struct bgp_info *ri;
8851 struct bgp_node *prn = bgp_node_parent_nolock (rn);
8852 unsigned int rinum = 0;
8853
8854 if (rn == top)
8855 continue;
8856
8857 if (!rn->info)
8858 continue;
8859
8860 ts->counts[BGP_STATS_PREFIXES]++;
8861 ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
8862
8863 #if 0
8864 ts->counts[BGP_STATS_AVGPLEN]
8865 = ravg_tally (ts->counts[BGP_STATS_PREFIXES],
8866 ts->counts[BGP_STATS_AVGPLEN],
8867 rn->p.prefixlen);
8868 #endif
8869
8870 /* check if the prefix is included by any other announcements */
8871 while (prn && !prn->info)
8872 prn = bgp_node_parent_nolock (prn);
8873
8874 if (prn == NULL || prn == top)
8875 {
8876 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
8877 /* announced address space */
8878 if (space)
8879 ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen);
8880 }
8881 else if (prn->info)
8882 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
8883
8884 for (ri = rn->info; ri; ri = ri->next)
8885 {
8886 rinum++;
8887 ts->counts[BGP_STATS_RIB]++;
8888
8889 if (ri->attr &&
8890 (CHECK_FLAG (ri->attr->flag,
8891 ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))))
8892 ts->counts[BGP_STATS_AGGREGATES]++;
8893
8894 /* as-path stats */
8895 if (ri->attr && ri->attr->aspath)
8896 {
8897 unsigned int hops = aspath_count_hops (ri->attr->aspath);
8898 unsigned int size = aspath_size (ri->attr->aspath);
8899 as_t highest = aspath_highest (ri->attr->aspath);
8900
8901 ts->counts[BGP_STATS_ASPATH_COUNT]++;
8902
8903 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
8904 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
8905
8906 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
8907 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
8908
8909 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
8910 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
8911 #if 0
8912 ts->counts[BGP_STATS_ASPATH_AVGHOPS]
8913 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
8914 ts->counts[BGP_STATS_ASPATH_AVGHOPS],
8915 hops);
8916 ts->counts[BGP_STATS_ASPATH_AVGSIZE]
8917 = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
8918 ts->counts[BGP_STATS_ASPATH_AVGSIZE],
8919 size);
8920 #endif
8921 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
8922 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
8923 }
8924 }
8925 }
8926 return 0;
8927 }
8928
8929 static int
8930 bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
8931 {
8932 struct bgp_table_stats ts;
8933 unsigned int i;
8934
8935 if (!bgp->rib[afi][safi])
8936 {
8937 vty_out (vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
8938 afi, safi, VTY_NEWLINE);
8939 return CMD_WARNING;
8940 }
8941
8942 memset (&ts, 0, sizeof (ts));
8943 ts.table = bgp->rib[afi][safi];
8944 thread_execute (bm->master, bgp_table_stats_walker, &ts, 0);
8945
8946 vty_out (vty, "BGP %s RIB statistics%s%s",
8947 afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE);
8948
8949 for (i = 0; i < BGP_STATS_MAX; i++)
8950 {
8951 if (!table_stats_strs[i])
8952 continue;
8953
8954 switch (i)
8955 {
8956 #if 0
8957 case BGP_STATS_ASPATH_AVGHOPS:
8958 case BGP_STATS_ASPATH_AVGSIZE:
8959 case BGP_STATS_AVGPLEN:
8960 vty_out (vty, "%-30s: ", table_stats_strs[i]);
8961 vty_out (vty, "%12.2f",
8962 (float)ts.counts[i] / (float)TALLY_SIGFIG);
8963 break;
8964 #endif
8965 case BGP_STATS_ASPATH_TOTHOPS:
8966 case BGP_STATS_ASPATH_TOTSIZE:
8967 vty_out (vty, "%-30s: ", table_stats_strs[i]);
8968 vty_out (vty, "%12.2f",
8969 ts.counts[i] ?
8970 (float)ts.counts[i] /
8971 (float)ts.counts[BGP_STATS_ASPATH_COUNT]
8972 : 0);
8973 break;
8974 case BGP_STATS_TOTPLEN:
8975 vty_out (vty, "%-30s: ", table_stats_strs[i]);
8976 vty_out (vty, "%12.2f",
8977 ts.counts[i] ?
8978 (float)ts.counts[i] /
8979 (float)ts.counts[BGP_STATS_PREFIXES]
8980 : 0);
8981 break;
8982 case BGP_STATS_SPACE:
8983 vty_out (vty, "%-30s: ", table_stats_strs[i]);
8984 vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
8985 if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
8986 break;
8987 vty_out (vty, "%30s: ", "%% announced ");
8988 vty_out (vty, "%12.2f%s",
8989 100 * (float)ts.counts[BGP_STATS_SPACE] /
8990 (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]),
8991 VTY_NEWLINE);
8992 vty_out (vty, "%30s: ", "/8 equivalent ");
8993 vty_out (vty, "%12.2f%s",
8994 (float)ts.counts[BGP_STATS_SPACE] /
8995 (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)),
8996 VTY_NEWLINE);
8997 if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
8998 break;
8999 vty_out (vty, "%30s: ", "/24 equivalent ");
9000 vty_out (vty, "%12.2f",
9001 (float)ts.counts[BGP_STATS_SPACE] /
9002 (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24)));
9003 break;
9004 default:
9005 vty_out (vty, "%-30s: ", table_stats_strs[i]);
9006 vty_out (vty, "%12llu", ts.counts[i]);
9007 }
9008
9009 vty_out (vty, "%s", VTY_NEWLINE);
9010 }
9011 return CMD_SUCCESS;
9012 }
9013
9014 enum bgp_pcounts
9015 {
9016 PCOUNT_ADJ_IN = 0,
9017 PCOUNT_DAMPED,
9018 PCOUNT_REMOVED,
9019 PCOUNT_HISTORY,
9020 PCOUNT_STALE,
9021 PCOUNT_VALID,
9022 PCOUNT_ALL,
9023 PCOUNT_COUNTED,
9024 PCOUNT_PFCNT, /* the figure we display to users */
9025 PCOUNT_MAX,
9026 };
9027
9028 static const char *pcount_strs[] =
9029 {
9030 [PCOUNT_ADJ_IN] = "Adj-in",
9031 [PCOUNT_DAMPED] = "Damped",
9032 [PCOUNT_REMOVED] = "Removed",
9033 [PCOUNT_HISTORY] = "History",
9034 [PCOUNT_STALE] = "Stale",
9035 [PCOUNT_VALID] = "Valid",
9036 [PCOUNT_ALL] = "All RIB",
9037 [PCOUNT_COUNTED] = "PfxCt counted",
9038 [PCOUNT_PFCNT] = "Useable",
9039 [PCOUNT_MAX] = NULL,
9040 };
9041
9042 struct peer_pcounts
9043 {
9044 unsigned int count[PCOUNT_MAX];
9045 const struct peer *peer;
9046 const struct bgp_table *table;
9047 };
9048
9049 static int
9050 bgp_peer_count_walker (struct thread *t)
9051 {
9052 struct bgp_node *rn;
9053 struct peer_pcounts *pc = THREAD_ARG (t);
9054 const struct peer *peer = pc->peer;
9055
9056 for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn))
9057 {
9058 struct bgp_adj_in *ain;
9059 struct bgp_info *ri;
9060
9061 for (ain = rn->adj_in; ain; ain = ain->next)
9062 if (ain->peer == peer)
9063 pc->count[PCOUNT_ADJ_IN]++;
9064
9065 for (ri = rn->info; ri; ri = ri->next)
9066 {
9067 char buf[SU_ADDRSTRLEN];
9068
9069 if (ri->peer != peer)
9070 continue;
9071
9072 pc->count[PCOUNT_ALL]++;
9073
9074 if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
9075 pc->count[PCOUNT_DAMPED]++;
9076 if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
9077 pc->count[PCOUNT_HISTORY]++;
9078 if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
9079 pc->count[PCOUNT_REMOVED]++;
9080 if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
9081 pc->count[PCOUNT_STALE]++;
9082 if (CHECK_FLAG (ri->flags, BGP_INFO_VALID))
9083 pc->count[PCOUNT_VALID]++;
9084 if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9085 pc->count[PCOUNT_PFCNT]++;
9086
9087 if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
9088 {
9089 pc->count[PCOUNT_COUNTED]++;
9090 if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9091 zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
9092 peer->host,
9093 inet_ntop(rn->p.family, &rn->p.u.prefix,
9094 buf, SU_ADDRSTRLEN),
9095 rn->p.prefixlen,
9096 ri->flags);
9097 }
9098 else
9099 {
9100 if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
9101 zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
9102 peer->host,
9103 inet_ntop(rn->p.family, &rn->p.u.prefix,
9104 buf, SU_ADDRSTRLEN),
9105 rn->p.prefixlen,
9106 ri->flags);
9107 }
9108 }
9109 }
9110 return 0;
9111 }
9112
9113 static int
9114 bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_char use_json)
9115 {
9116 struct peer_pcounts pcounts = { .peer = peer };
9117 unsigned int i;
9118 json_object *json = NULL;
9119 json_object *json_loop = NULL;
9120
9121 if (use_json)
9122 {
9123 json = json_object_new_object();
9124 json_loop = json_object_new_object();
9125 }
9126
9127 if (!peer || !peer->bgp || !peer->afc[afi][safi]
9128 || !peer->bgp->rib[afi][safi])
9129 {
9130 if (use_json)
9131 {
9132 json_object_string_add(json, "warning", "No such neighbor or address family");
9133 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9134 json_object_free(json);
9135 }
9136 else
9137 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9138
9139 return CMD_WARNING;
9140 }
9141
9142 memset (&pcounts, 0, sizeof(pcounts));
9143 pcounts.peer = peer;
9144 pcounts.table = peer->bgp->rib[afi][safi];
9145
9146 /* in-place call via thread subsystem so as to record execution time
9147 * * stats for the thread-walk (i.e. ensure this can't be blamed on
9148 * * on just vty_read()).
9149 * */
9150 thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
9151
9152 if (use_json)
9153 {
9154 json_object_string_add(json, "prefixCountsFor", peer->host);
9155 json_object_string_add(json, "multiProtocol", afi_safi_print (afi, safi));
9156 json_object_int_add(json, "pfxCounter", peer->pcount[afi][safi]);
9157
9158 for (i = 0; i < PCOUNT_MAX; i++)
9159 json_object_int_add(json_loop, pcount_strs[i], pcounts.count[i]);
9160
9161 json_object_object_add(json, "ribTableWalkCounters", json_loop);
9162
9163 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
9164 {
9165 json_object_string_add(json, "pfxctDriftFor", peer->host);
9166 json_object_string_add(json, "recommended", "Please report this bug, with the above command output");
9167 }
9168 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9169 json_object_free(json);
9170 }
9171 else
9172 {
9173
9174 if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
9175 {
9176 vty_out (vty, "Prefix counts for %s/%s, %s%s",
9177 peer->hostname, peer->host, afi_safi_print (afi, safi),
9178 VTY_NEWLINE);
9179 }
9180 else
9181 {
9182 vty_out (vty, "Prefix counts for %s, %s%s",
9183 peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
9184 }
9185
9186 vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
9187 vty_out (vty, "%sCounts from RIB table walk:%s%s",
9188 VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
9189
9190 for (i = 0; i < PCOUNT_MAX; i++)
9191 vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts.count[i], VTY_NEWLINE);
9192
9193 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
9194 {
9195 vty_out (vty, "%s [pcount] PfxCt drift!%s",
9196 peer->host, VTY_NEWLINE);
9197 vty_out (vty, "Please report this bug, with the above command output%s",
9198 VTY_NEWLINE);
9199 }
9200 }
9201
9202 return CMD_SUCCESS;
9203 }
9204
9205 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
9206 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
9207 "show [ip] bgp [<view|vrf> WORD] [<ipv4|ipv6> [<unicast|multicast|vpn>]] "
9208 "neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9209 SHOW_STR
9210 IP_STR
9211 BGP_STR
9212 BGP_INSTANCE_HELP_STR
9213 "Address Family\n"
9214 "Address Family\n"
9215 "Address Family modifier\n"
9216 "Address Family modifier\n"
9217 "Address Family modifier\n"
9218 "Detailed information on TCP and BGP neighbor connections\n"
9219 "Neighbor to display information about\n"
9220 "Neighbor to display information about\n"
9221 "Neighbor on BGP configured interface\n"
9222 "Display detailed prefix count information\n"
9223 JSON_STR)
9224 {
9225 afi_t afi = AFI_IP6;
9226 safi_t safi = SAFI_UNICAST;
9227 struct peer *peer;
9228 int idx = 0;
9229 struct bgp *bgp = NULL;
9230
9231 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9232 if (!idx)
9233 return CMD_WARNING;
9234
9235 int uj = use_json (argc, argv);
9236 if (uj) argc--;
9237
9238 argv_find (argv, argc, "neighbors", &idx);
9239 peer = peer_lookup_in_view (vty, bgp, argv[idx+1]->arg, uj);
9240 if (! peer)
9241 return CMD_WARNING;
9242
9243 return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
9244 }
9245
9246 #ifdef KEEP_OLD_VPN_COMMANDS
9247 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
9248 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
9249 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
9250 SHOW_STR
9251 IP_STR
9252 BGP_STR
9253 BGP_VPNVX_HELP_STR
9254 "Display information about all VPNv4 NLRIs\n"
9255 "Detailed information on TCP and BGP neighbor connections\n"
9256 "Neighbor to display information about\n"
9257 "Neighbor to display information about\n"
9258 "Neighbor on BGP configured interface\n"
9259 "Display detailed prefix count information\n"
9260 JSON_STR)
9261 {
9262 int idx_peer = 6;
9263 struct peer *peer;
9264 u_char uj = use_json(argc, argv);
9265
9266 peer = peer_lookup_in_view (vty, NULL, argv[idx_peer]->arg, uj);
9267 if (! peer)
9268 return CMD_WARNING;
9269
9270 return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
9271 }
9272
9273 DEFUN (show_ip_bgp_vpn_all_route_prefix,
9274 show_ip_bgp_vpn_all_route_prefix_cmd,
9275 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
9276 SHOW_STR
9277 IP_STR
9278 BGP_STR
9279 BGP_VPNVX_HELP_STR
9280 "Display information about all VPNv4 NLRIs\n"
9281 "Network in the BGP routing table to display\n"
9282 "Network in the BGP routing table to display\n"
9283 JSON_STR)
9284 {
9285 int idx = 0;
9286 char *network = NULL;
9287 struct bgp *bgp = bgp_get_default();
9288 if (!bgp)
9289 {
9290 vty_out (vty, "Can't find default instance%s", VTY_NEWLINE);
9291 return CMD_WARNING;
9292 }
9293
9294 if (argv_find (argv, argc, "A.B.C.D", &idx))
9295 network = argv[idx]->arg;
9296 else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
9297 network = argv[idx]->arg;
9298 else
9299 {
9300 vty_out (vty, "Unable to figure out Network%s", VTY_NEWLINE);
9301 return CMD_WARNING;
9302 }
9303
9304 return bgp_show_route (vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
9305 }
9306 #endif /* KEEP_OLD_VPN_COMMANDS */
9307
9308 DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
9309 show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd,
9310 "show [ip] bgp l2vpn evpn all <A.B.C.D|A.B.C.D/M> [json]",
9311 SHOW_STR
9312 IP_STR
9313 BGP_STR
9314 L2VPN_HELP_STR
9315 EVPN_HELP_STR
9316 "Display information about all EVPN NLRIs\n"
9317 "Network in the BGP routing table to display\n"
9318 "Network in the BGP routing table to display\n"
9319 JSON_STR)
9320 {
9321 int idx = 0;
9322 char *network = NULL;
9323
9324 if (argv_find (argv, argc, "A.B.C.D", &idx))
9325 network = argv[idx]->arg;
9326 else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
9327 network = argv[idx]->arg;
9328 else
9329 {
9330 vty_out (vty, "Unable to figure out Network%s", VTY_NEWLINE);
9331 return CMD_WARNING;
9332 }
9333 return bgp_show_route (vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
9334 }
9335
9336 static void
9337 show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
9338 int in, const char *rmap_name, u_char use_json, json_object *json)
9339 {
9340 struct bgp_table *table;
9341 struct bgp_adj_in *ain;
9342 struct bgp_adj_out *adj;
9343 unsigned long output_count;
9344 unsigned long filtered_count;
9345 struct bgp_node *rn;
9346 int header1 = 1;
9347 struct bgp *bgp;
9348 int header2 = 1;
9349 struct attr attr;
9350 struct attr_extra extra;
9351 int ret;
9352 struct update_subgroup *subgrp;
9353 json_object *json_scode = NULL;
9354 json_object *json_ocode = NULL;
9355 json_object *json_ar = NULL;
9356 struct peer_af *paf;
9357
9358 if (use_json)
9359 {
9360 json_scode = json_object_new_object();
9361 json_ocode = json_object_new_object();
9362 json_ar = json_object_new_object();
9363
9364 json_object_string_add(json_scode, "suppressed", "s");
9365 json_object_string_add(json_scode, "damped", "d");
9366 json_object_string_add(json_scode, "history", "h");
9367 json_object_string_add(json_scode, "valid", "*");
9368 json_object_string_add(json_scode, "best", ">");
9369 json_object_string_add(json_scode, "multipath", "=");
9370 json_object_string_add(json_scode, "internal", "i");
9371 json_object_string_add(json_scode, "ribFailure", "r");
9372 json_object_string_add(json_scode, "stale", "S");
9373 json_object_string_add(json_scode, "removed", "R");
9374
9375 json_object_string_add(json_ocode, "igp", "i");
9376 json_object_string_add(json_ocode, "egp", "e");
9377 json_object_string_add(json_ocode, "incomplete", "?");
9378 }
9379
9380 bgp = peer->bgp;
9381
9382 if (! bgp)
9383 {
9384 if (use_json)
9385 {
9386 json_object_string_add(json, "alert", "no BGP");
9387 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9388 json_object_free(json);
9389 }
9390 else
9391 vty_out (vty, "%% No bgp%s", VTY_NEWLINE);
9392 return;
9393 }
9394
9395 table = bgp->rib[afi][safi];
9396
9397 output_count = filtered_count = 0;
9398 subgrp = peer_subgroup(peer, afi, safi);
9399
9400 if (!in && subgrp && CHECK_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
9401 {
9402 if (use_json)
9403 {
9404 json_object_int_add(json, "bgpTableVersion", table->version);
9405 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9406 json_object_object_add(json, "bgpStatusCodes", json_scode);
9407 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9408 json_object_string_add(json, "bgpOriginatingDefaultNetwork", "0.0.0.0");
9409 }
9410 else
9411 {
9412 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
9413 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9414 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9415
9416 vty_out (vty, "Originating default network 0.0.0.0%s%s",
9417 VTY_NEWLINE, VTY_NEWLINE);
9418 }
9419 header1 = 0;
9420 }
9421
9422 attr.extra = &extra;
9423 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
9424 {
9425 if (in)
9426 {
9427 for (ain = rn->adj_in; ain; ain = ain->next)
9428 {
9429 if (ain->peer == peer)
9430 {
9431 if (header1)
9432 {
9433 if (use_json)
9434 {
9435 json_object_int_add(json, "bgpTableVersion", 0);
9436 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9437 json_object_object_add(json, "bgpStatusCodes", json_scode);
9438 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9439 }
9440 else
9441 {
9442 vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
9443 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9444 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9445 }
9446 header1 = 0;
9447 }
9448 if (header2)
9449 {
9450 if (!use_json)
9451 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
9452 header2 = 0;
9453 }
9454 if (ain->attr)
9455 {
9456 bgp_attr_dup(&attr, ain->attr);
9457 if (bgp_input_modifier(peer, &rn->p, &attr, afi, safi, rmap_name) != RMAP_DENY)
9458 {
9459 route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
9460 output_count++;
9461 }
9462 else
9463 filtered_count++;
9464 }
9465 }
9466 }
9467 }
9468 else
9469 {
9470 for (adj = rn->adj_out; adj; adj = adj->next)
9471 SUBGRP_FOREACH_PEER(adj->subgroup, paf)
9472 if (paf->peer == peer)
9473 {
9474 if (header1)
9475 {
9476 if (use_json)
9477 {
9478 json_object_int_add(json, "bgpTableVersion", table->version);
9479 json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
9480 json_object_object_add(json, "bgpStatusCodes", json_scode);
9481 json_object_object_add(json, "bgpOriginCodes", json_ocode);
9482 }
9483 else
9484 {
9485 vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version,
9486 inet_ntoa (bgp->router_id), VTY_NEWLINE);
9487 vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9488 vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
9489 }
9490 header1 = 0;
9491 }
9492
9493 if (header2)
9494 {
9495 if (!use_json)
9496 vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
9497 header2 = 0;
9498 }
9499
9500 if (adj->attr)
9501 {
9502 bgp_attr_dup(&attr, adj->attr);
9503 ret = bgp_output_modifier(peer, &rn->p, &attr, afi, safi, rmap_name);
9504 if (ret != RMAP_DENY)
9505 {
9506 route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
9507 output_count++;
9508 }
9509 else
9510 filtered_count++;
9511 }
9512 }
9513 }
9514 }
9515 if (use_json)
9516 json_object_object_add(json, "advertisedRoutes", json_ar);
9517
9518 if (output_count != 0)
9519 {
9520 if (use_json)
9521 json_object_int_add(json, "totalPrefixCounter", output_count);
9522 else
9523 vty_out (vty, "%sTotal number of prefixes %ld%s",
9524 VTY_NEWLINE, output_count, VTY_NEWLINE);
9525 }
9526 if (use_json)
9527 {
9528 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9529 json_object_free(json);
9530 }
9531
9532 }
9533
9534 static int
9535 peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
9536 int in, const char *rmap_name, u_char use_json)
9537 {
9538 json_object *json = NULL;
9539
9540 if (use_json)
9541 json = json_object_new_object();
9542
9543 if (!peer || !peer->afc[afi][safi])
9544 {
9545 if (use_json)
9546 {
9547 json_object_string_add(json, "warning", "No such neighbor or address family");
9548 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9549 json_object_free(json);
9550 }
9551 else
9552 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9553
9554 return CMD_WARNING;
9555 }
9556
9557 if (in && !CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
9558 {
9559 if (use_json)
9560 {
9561 json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled");
9562 vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
9563 json_object_free(json);
9564 }
9565 else
9566 vty_out (vty, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE);
9567
9568 return CMD_WARNING;
9569 }
9570
9571 show_adj_route (vty, peer, afi, safi, in, rmap_name, use_json, json);
9572
9573 return CMD_SUCCESS;
9574 }
9575
9576 DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
9577 show_ip_bgp_instance_neighbor_advertised_route_cmd,
9578 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9579 "neighbors <A.B.C.D|X:X::X:X|WORD> <received-routes|advertised-routes> [route-map WORD] [json]",
9580 SHOW_STR
9581 IP_STR
9582 BGP_STR
9583 BGP_INSTANCE_HELP_STR
9584 BGP_AFI_HELP_STR
9585 BGP_SAFI_HELP_STR
9586 "Detailed information on TCP and BGP neighbor connections\n"
9587 "Neighbor to display information about\n"
9588 "Neighbor to display information about\n"
9589 "Neighbor on BGP configured interface\n"
9590 "Display the received routes from neighbor\n"
9591 "Display the routes advertised to a BGP neighbor\n"
9592 "Route-map to modify the attributes\n"
9593 "Name of the route map\n"
9594 JSON_STR)
9595 {
9596 afi_t afi = AFI_IP6;
9597 safi_t safi = SAFI_UNICAST;
9598 char *rmap_name = NULL;
9599 char *peerstr = NULL;
9600 int rcvd = 0;
9601 struct bgp *bgp = NULL;
9602 struct peer *peer;
9603
9604 int idx = 0;
9605
9606 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9607 if (!idx)
9608 return CMD_WARNING;
9609
9610 int uj = use_json (argc, argv);
9611 if (uj) argc--;
9612
9613 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9614 argv_find (argv, argc, "neighbors", &idx);
9615 peerstr = argv[++idx]->arg;
9616
9617 peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
9618 if (! peer)
9619 return CMD_WARNING;
9620
9621 if (argv_find (argv, argc, "received-routes", &idx))
9622 rcvd = 1;
9623 if (argv_find (argv, argc, "advertised-routes", &idx))
9624 rcvd = 0;
9625 if (argv_find (argv, argc, "route-map", &idx))
9626 rmap_name = argv[++idx]->arg;
9627
9628 return peer_adj_routes (vty, peer, afi, safi, rcvd, rmap_name, uj);
9629 }
9630
9631 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
9632 show_ip_bgp_neighbor_received_prefix_filter_cmd,
9633 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
9634 SHOW_STR
9635 IP_STR
9636 BGP_STR
9637 "Address Family\n"
9638 "Address Family\n"
9639 "Address Family modifier\n"
9640 "Detailed information on TCP and BGP neighbor connections\n"
9641 "Neighbor to display information about\n"
9642 "Neighbor to display information about\n"
9643 "Neighbor on BGP configured interface\n"
9644 "Display information received from a BGP neighbor\n"
9645 "Display the prefixlist filter\n"
9646 JSON_STR)
9647 {
9648 afi_t afi = AFI_IP6;
9649 safi_t safi = SAFI_UNICAST;
9650 char *peerstr = NULL;
9651
9652 char name[BUFSIZ];
9653 union sockunion su;
9654 struct peer *peer;
9655 int count, ret;
9656
9657 int idx = 0;
9658
9659 /* show [ip] bgp */
9660 if (argv_find (argv, argc, "ip", &idx))
9661 afi = AFI_IP;
9662 /* [<ipv4|ipv6> [unicast]] */
9663 if (argv_find (argv, argc, "ipv4", &idx))
9664 afi = AFI_IP;
9665 if (argv_find (argv, argc, "ipv6", &idx))
9666 afi = AFI_IP6;
9667 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9668 argv_find (argv, argc, "neighbors", &idx);
9669 peerstr = argv[++idx]->arg;
9670
9671 u_char uj = use_json(argc, argv);
9672
9673 ret = str2sockunion (peerstr, &su);
9674 if (ret < 0)
9675 {
9676 peer = peer_lookup_by_conf_if (NULL, peerstr);
9677 if (! peer)
9678 {
9679 if (uj)
9680 vty_out (vty, "{}%s", VTY_NEWLINE);
9681 else
9682 vty_out (vty, "%% Malformed address or name: %s%s", peerstr, VTY_NEWLINE);
9683 return CMD_WARNING;
9684 }
9685 }
9686 else
9687 {
9688 peer = peer_lookup (NULL, &su);
9689 if (! peer)
9690 {
9691 if (uj)
9692 vty_out (vty, "{}%s", VTY_NEWLINE);
9693 else
9694 vty_out (vty, "No peer%s", VTY_NEWLINE);
9695 return CMD_WARNING;
9696 }
9697 }
9698
9699 sprintf (name, "%s.%d.%d", peer->host, afi, safi);
9700 count = prefix_bgp_show_prefix_list (NULL, afi, name, uj);
9701 if (count)
9702 {
9703 if (!uj)
9704 vty_out (vty, "Address Family: %s%s", afi_safi_print(afi, safi), VTY_NEWLINE);
9705 prefix_bgp_show_prefix_list (vty, afi, name, uj);
9706 }
9707 else
9708 {
9709 if (uj)
9710 vty_out (vty, "{}%s", VTY_NEWLINE);
9711 else
9712 vty_out (vty, "No functional output%s", VTY_NEWLINE);
9713 }
9714
9715 return CMD_SUCCESS;
9716 }
9717
9718 static int
9719 bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
9720 safi_t safi, enum bgp_show_type type, u_char use_json)
9721 {
9722 if (! peer || ! peer->afc[afi][safi])
9723 {
9724 if (use_json)
9725 {
9726 json_object *json_no = NULL;
9727 json_no = json_object_new_object();
9728 json_object_string_add(json_no, "warning", "No such neighbor or address family");
9729 vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
9730 json_object_free(json_no);
9731 }
9732 else
9733 vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
9734 return CMD_WARNING;
9735 }
9736
9737 return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su, use_json);
9738 }
9739
9740 DEFUN (show_ip_bgp_neighbor_routes,
9741 show_ip_bgp_neighbor_routes_cmd,
9742 "show [ip] bgp [<view|vrf> WORD] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] "
9743 "neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
9744 SHOW_STR
9745 IP_STR
9746 BGP_STR
9747 BGP_INSTANCE_HELP_STR
9748 BGP_AFI_HELP_STR
9749 BGP_SAFI_HELP_STR
9750 "Detailed information on TCP and BGP neighbor connections\n"
9751 "Neighbor to display information about\n"
9752 "Neighbor to display information about\n"
9753 "Neighbor on BGP configured interface\n"
9754 "Display flap statistics of the routes learned from neighbor\n"
9755 "Display the dampened routes received from neighbor\n"
9756 "Display routes learned from neighbor\n"
9757 JSON_STR)
9758 {
9759 char *peerstr = NULL;
9760 struct bgp *bgp = NULL;
9761 afi_t afi = AFI_IP6;
9762 safi_t safi = SAFI_UNICAST;
9763 struct peer *peer;
9764 enum bgp_show_type sh_type = bgp_show_type_neighbor;
9765
9766 int idx = 0;
9767
9768 bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
9769 if (!idx)
9770 return CMD_WARNING;
9771
9772 int uj = use_json (argc, argv);
9773 if (uj) argc--;
9774
9775 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
9776 argv_find (argv, argc, "neighbors", &idx);
9777 peerstr = argv[++idx]->arg;
9778
9779 peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
9780 if (! peer)
9781 {
9782 vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
9783 return CMD_WARNING;
9784 }
9785
9786 if (argv_find (argv, argc, "flap-statistics", &idx))
9787 sh_type = bgp_show_type_flap_neighbor;
9788 else if (argv_find (argv, argc, "dampened-routes", &idx))
9789 sh_type = bgp_show_type_damp_neighbor;
9790 else if (argv_find (argv, argc, "routes", &idx))
9791 sh_type = bgp_show_type_neighbor;
9792
9793 return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj);
9794 }
9795
9796 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
9797
9798 struct bgp_distance
9799 {
9800 /* Distance value for the IP source prefix. */
9801 u_char distance;
9802
9803 /* Name of the access-list to be matched. */
9804 char *access_list;
9805 };
9806
9807 DEFUN (show_bgp_afi_vpn_rd_route,
9808 show_bgp_afi_vpn_rd_route_cmd,
9809 "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]",
9810 SHOW_STR
9811 BGP_STR
9812 BGP_AFI_HELP_STR
9813 "Address Family modifier\n"
9814 "Display information for a route distinguisher\n"
9815 "Route Distinguisher\n"
9816 "Network in the BGP routing table to display\n"
9817 "Network in the BGP routing table to display\n"
9818 JSON_STR)
9819 {
9820 int ret;
9821 struct prefix_rd prd;
9822 afi_t afi = AFI_MAX;
9823 int idx = 0;
9824
9825 argv_find_and_parse_afi (argv, argc, &idx, &afi);
9826 ret = str2prefix_rd (argv[5]->arg, &prd);
9827 if (! ret)
9828 {
9829 vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
9830 return CMD_WARNING;
9831 }
9832 return bgp_show_route (vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
9833 }
9834
9835 static struct bgp_distance *
9836 bgp_distance_new (void)
9837 {
9838 return XCALLOC (MTYPE_BGP_DISTANCE, sizeof (struct bgp_distance));
9839 }
9840
9841 static void
9842 bgp_distance_free (struct bgp_distance *bdistance)
9843 {
9844 XFREE (MTYPE_BGP_DISTANCE, bdistance);
9845 }
9846
9847 static int
9848 bgp_distance_set (struct vty *vty, const char *distance_str,
9849 const char *ip_str, const char *access_list_str)
9850 {
9851 int ret;
9852 afi_t afi;
9853 safi_t safi;
9854 struct prefix p;
9855 u_char distance;
9856 struct bgp_node *rn;
9857 struct bgp_distance *bdistance;
9858
9859 afi = bgp_node_afi (vty);
9860 safi = bgp_node_safi (vty);
9861
9862 ret = str2prefix (ip_str, &p);
9863 if (ret == 0)
9864 {
9865 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
9866 return CMD_WARNING;
9867 }
9868
9869 distance = atoi (distance_str);
9870
9871 /* Get BGP distance node. */
9872 rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p);
9873 if (rn->info)
9874 {
9875 bdistance = rn->info;
9876 bgp_unlock_node (rn);
9877 }
9878 else
9879 {
9880 bdistance = bgp_distance_new ();
9881 rn->info = bdistance;
9882 }
9883
9884 /* Set distance value. */
9885 bdistance->distance = distance;
9886
9887 /* Reset access-list configuration. */
9888 if (bdistance->access_list)
9889 {
9890 XFREE(MTYPE_AS_LIST, bdistance->access_list);
9891 bdistance->access_list = NULL;
9892 }
9893 if (access_list_str)
9894 bdistance->access_list = XSTRDUP(MTYPE_AS_LIST, access_list_str);
9895
9896 return CMD_SUCCESS;
9897 }
9898
9899 static int
9900 bgp_distance_unset (struct vty *vty, const char *distance_str,
9901 const char *ip_str, const char *access_list_str)
9902 {
9903 int ret;
9904 afi_t afi;
9905 safi_t safi;
9906 struct prefix p;
9907 int distance;
9908 struct bgp_node *rn;
9909 struct bgp_distance *bdistance;
9910
9911 afi = bgp_node_afi (vty);
9912 safi = bgp_node_safi (vty);
9913
9914 ret = str2prefix (ip_str, &p);
9915 if (ret == 0)
9916 {
9917 vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
9918 return CMD_WARNING;
9919 }
9920
9921 rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p);
9922 if (! rn)
9923 {
9924 vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
9925 return CMD_WARNING;
9926 }
9927
9928 bdistance = rn->info;
9929 distance = atoi(distance_str);
9930
9931 if (bdistance->distance != distance)
9932 {
9933 vty_out (vty, "Distance does not match configured%s", VTY_NEWLINE);
9934 return CMD_WARNING;
9935 }
9936
9937 if (bdistance->access_list)
9938 XFREE(MTYPE_AS_LIST, bdistance->access_list);
9939 bgp_distance_free (bdistance);
9940
9941 rn->info = NULL;
9942 bgp_unlock_node (rn);
9943 bgp_unlock_node (rn);
9944
9945 return CMD_SUCCESS;
9946 }
9947
9948 /* Apply BGP information to distance method. */
9949 u_char
9950 bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
9951 safi_t safi, struct bgp *bgp)
9952 {
9953 struct bgp_node *rn;
9954 struct prefix q;
9955 struct peer *peer;
9956 struct bgp_distance *bdistance;
9957 struct access_list *alist;
9958 struct bgp_static *bgp_static;
9959
9960 if (! bgp)
9961 return 0;
9962
9963 peer = rinfo->peer;
9964
9965 /* Check source address. */
9966 sockunion2hostprefix (&peer->su, &q);
9967 rn = bgp_node_match (bgp_distance_table[afi][safi], &q);
9968 if (rn)
9969 {
9970 bdistance = rn->info;
9971 bgp_unlock_node (rn);
9972
9973 if (bdistance->access_list)
9974 {
9975 alist = access_list_lookup (afi, bdistance->access_list);
9976 if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
9977 return bdistance->distance;
9978 }
9979 else
9980 return bdistance->distance;
9981 }
9982
9983 /* Backdoor check. */
9984 rn = bgp_node_lookup (bgp->route[afi][safi], p);
9985 if (rn)
9986 {
9987 bgp_static = rn->info;
9988 bgp_unlock_node (rn);
9989
9990 if (bgp_static->backdoor)
9991 {
9992 if (bgp->distance_local[afi][safi])
9993 return bgp->distance_local[afi][safi];
9994 else
9995 return ZEBRA_IBGP_DISTANCE_DEFAULT;
9996 }
9997 }
9998
9999 if (peer->sort == BGP_PEER_EBGP)
10000 {
10001 if (bgp->distance_ebgp[afi][safi])
10002 return bgp->distance_ebgp[afi][safi];
10003 return ZEBRA_EBGP_DISTANCE_DEFAULT;
10004 }
10005 else
10006 {
10007 if (bgp->distance_ibgp[afi][safi])
10008 return bgp->distance_ibgp[afi][safi];
10009 return ZEBRA_IBGP_DISTANCE_DEFAULT;
10010 }
10011 }
10012
10013 DEFUN (bgp_distance,
10014 bgp_distance_cmd,
10015 "distance bgp (1-255) (1-255) (1-255)",
10016 "Define an administrative distance\n"
10017 "BGP distance\n"
10018 "Distance for routes external to the AS\n"
10019 "Distance for routes internal to the AS\n"
10020 "Distance for local routes\n")
10021 {
10022 VTY_DECLVAR_CONTEXT(bgp, bgp);
10023 int idx_number = 2;
10024 int idx_number_2 = 3;
10025 int idx_number_3 = 4;
10026 afi_t afi;
10027 safi_t safi;
10028
10029 afi = bgp_node_afi (vty);
10030 safi = bgp_node_safi (vty);
10031
10032 bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg);
10033 bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg);
10034 bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg);
10035 return CMD_SUCCESS;
10036 }
10037
10038 DEFUN (no_bgp_distance,
10039 no_bgp_distance_cmd,
10040 "no distance bgp [(1-255) (1-255) (1-255)]",
10041 NO_STR
10042 "Define an administrative distance\n"
10043 "BGP distance\n"
10044 "Distance for routes external to the AS\n"
10045 "Distance for routes internal to the AS\n"
10046 "Distance for local routes\n")
10047 {
10048 VTY_DECLVAR_CONTEXT(bgp, bgp);
10049 afi_t afi;
10050 safi_t safi;
10051
10052 afi = bgp_node_afi (vty);
10053 safi = bgp_node_safi (vty);
10054
10055 bgp->distance_ebgp[afi][safi] = 0;
10056 bgp->distance_ibgp[afi][safi] = 0;
10057 bgp->distance_local[afi][safi] = 0;
10058 return CMD_SUCCESS;
10059 }
10060
10061
10062 DEFUN (bgp_distance_source,
10063 bgp_distance_source_cmd,
10064 "distance (1-255) A.B.C.D/M",
10065 "Define an administrative distance\n"
10066 "Administrative distance\n"
10067 "IP source prefix\n")
10068 {
10069 int idx_number = 1;
10070 int idx_ipv4_prefixlen = 2;
10071 bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
10072 return CMD_SUCCESS;
10073 }
10074
10075 DEFUN (no_bgp_distance_source,
10076 no_bgp_distance_source_cmd,
10077 "no distance (1-255) A.B.C.D/M",
10078 NO_STR
10079 "Define an administrative distance\n"
10080 "Administrative distance\n"
10081 "IP source prefix\n")
10082 {
10083 int idx_number = 2;
10084 int idx_ipv4_prefixlen = 3;
10085 bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
10086 return CMD_SUCCESS;
10087 }
10088
10089 DEFUN (bgp_distance_source_access_list,
10090 bgp_distance_source_access_list_cmd,
10091 "distance (1-255) A.B.C.D/M WORD",
10092 "Define an administrative distance\n"
10093 "Administrative distance\n"
10094 "IP source prefix\n"
10095 "Access list name\n")
10096 {
10097 int idx_number = 1;
10098 int idx_ipv4_prefixlen = 2;
10099 int idx_word = 3;
10100 bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10101 return CMD_SUCCESS;
10102 }
10103
10104 DEFUN (no_bgp_distance_source_access_list,
10105 no_bgp_distance_source_access_list_cmd,
10106 "no distance (1-255) A.B.C.D/M WORD",
10107 NO_STR
10108 "Define an administrative distance\n"
10109 "Administrative distance\n"
10110 "IP source prefix\n"
10111 "Access list name\n")
10112 {
10113 int idx_number = 2;
10114 int idx_ipv4_prefixlen = 3;
10115 int idx_word = 4;
10116 bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
10117 return CMD_SUCCESS;
10118 }
10119
10120 DEFUN (ipv6_bgp_distance_source,
10121 ipv6_bgp_distance_source_cmd,
10122 "distance (1-255) X:X::X:X/M",
10123 "Define an administrative distance\n"
10124 "Administrative distance\n"
10125 "IP source prefix\n")
10126 {
10127 bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL);
10128 return CMD_SUCCESS;
10129 }
10130
10131 DEFUN (no_ipv6_bgp_distance_source,
10132 no_ipv6_bgp_distance_source_cmd,
10133 "no distance (1-255) X:X::X:X/M",
10134 NO_STR
10135 "Define an administrative distance\n"
10136 "Administrative distance\n"
10137 "IP source prefix\n")
10138 {
10139 bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL);
10140 return CMD_SUCCESS;
10141 }
10142
10143 DEFUN (ipv6_bgp_distance_source_access_list,
10144 ipv6_bgp_distance_source_access_list_cmd,
10145 "distance (1-255) X:X::X:X/M WORD",
10146 "Define an administrative distance\n"
10147 "Administrative distance\n"
10148 "IP source prefix\n"
10149 "Access list name\n")
10150 {
10151 bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
10152 return CMD_SUCCESS;
10153 }
10154
10155 DEFUN (no_ipv6_bgp_distance_source_access_list,
10156 no_ipv6_bgp_distance_source_access_list_cmd,
10157 "no distance (1-255) X:X::X:X/M WORD",
10158 NO_STR
10159 "Define an administrative distance\n"
10160 "Administrative distance\n"
10161 "IP source prefix\n"
10162 "Access list name\n")
10163 {
10164 bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
10165 return CMD_SUCCESS;
10166 }
10167
10168 DEFUN (bgp_damp_set,
10169 bgp_damp_set_cmd,
10170 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10171 "BGP Specific commands\n"
10172 "Enable route-flap dampening\n"
10173 "Half-life time for the penalty\n"
10174 "Value to start reusing a route\n"
10175 "Value to start suppressing a route\n"
10176 "Maximum duration to suppress a stable route\n")
10177 {
10178 VTY_DECLVAR_CONTEXT(bgp, bgp);
10179 int idx_half_life = 2;
10180 int idx_reuse = 3;
10181 int idx_suppress = 4;
10182 int idx_max_suppress = 5;
10183 int half = DEFAULT_HALF_LIFE * 60;
10184 int reuse = DEFAULT_REUSE;
10185 int suppress = DEFAULT_SUPPRESS;
10186 int max = 4 * half;
10187
10188 if (argc == 6)
10189 {
10190 half = atoi (argv[idx_half_life]->arg) * 60;
10191 reuse = atoi (argv[idx_reuse]->arg);
10192 suppress = atoi (argv[idx_suppress]->arg);
10193 max = atoi (argv[idx_max_suppress]->arg) * 60;
10194 }
10195 else if (argc == 3)
10196 {
10197 half = atoi (argv[idx_half_life]->arg) * 60;
10198 max = 4 * half;
10199 }
10200
10201 if (suppress < reuse)
10202 {
10203 vty_out (vty, "Suppress value cannot be less than reuse value %s",
10204 VTY_NEWLINE);
10205 return 0;
10206 }
10207
10208 return bgp_damp_enable (bgp, bgp_node_afi (vty), bgp_node_safi (vty),
10209 half, reuse, suppress, max);
10210 }
10211
10212 DEFUN (bgp_damp_unset,
10213 bgp_damp_unset_cmd,
10214 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
10215 NO_STR
10216 "BGP Specific commands\n"
10217 "Enable route-flap dampening\n"
10218 "Half-life time for the penalty\n"
10219 "Value to start reusing a route\n"
10220 "Value to start suppressing a route\n"
10221 "Maximum duration to suppress a stable route\n")
10222 {
10223 VTY_DECLVAR_CONTEXT(bgp, bgp);
10224 return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
10225 }
10226
10227 /* Display specified route of BGP table. */
10228 static int
10229 bgp_clear_damp_route (struct vty *vty, const char *view_name,
10230 const char *ip_str, afi_t afi, safi_t safi,
10231 struct prefix_rd *prd, int prefix_check)
10232 {
10233 int ret;
10234 struct prefix match;
10235 struct bgp_node *rn;
10236 struct bgp_node *rm;
10237 struct bgp_info *ri;
10238 struct bgp_info *ri_temp;
10239 struct bgp *bgp;
10240 struct bgp_table *table;
10241
10242 /* BGP structure lookup. */
10243 if (view_name)
10244 {
10245 bgp = bgp_lookup_by_name (view_name);
10246 if (bgp == NULL)
10247 {
10248 vty_out (vty, "%% Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
10249 return CMD_WARNING;
10250 }
10251 }
10252 else
10253 {
10254 bgp = bgp_get_default ();
10255 if (bgp == NULL)
10256 {
10257 vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
10258 return CMD_WARNING;
10259 }
10260 }
10261
10262 /* Check IP address argument. */
10263 ret = str2prefix (ip_str, &match);
10264 if (! ret)
10265 {
10266 vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
10267 return CMD_WARNING;
10268 }
10269
10270 match.family = afi2family (afi);
10271
10272 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
10273 {
10274 for (rn = bgp_table_top (bgp->rib[AFI_IP][safi]); rn; rn = bgp_route_next (rn))
10275 {
10276 if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
10277 continue;
10278
10279 if ((table = rn->info) != NULL)
10280 if ((rm = bgp_node_match (table, &match)) != NULL)
10281 {
10282 if (! prefix_check || rm->p.prefixlen == match.prefixlen)
10283 {
10284 ri = rm->info;
10285 while (ri)
10286 {
10287 if (ri->extra && ri->extra->damp_info)
10288 {
10289 ri_temp = ri->next;
10290 bgp_damp_info_free (ri->extra->damp_info, 1);
10291 ri = ri_temp;
10292 }
10293 else
10294 ri = ri->next;
10295 }
10296 }
10297
10298 bgp_unlock_node (rm);
10299 }
10300 }
10301 }
10302 else
10303 {
10304 if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
10305 {
10306 if (! prefix_check || rn->p.prefixlen == match.prefixlen)
10307 {
10308 ri = rn->info;
10309 while (ri)
10310 {
10311 if (ri->extra && ri->extra->damp_info)
10312 {
10313 ri_temp = ri->next;
10314 bgp_damp_info_free (ri->extra->damp_info, 1);
10315 ri = ri_temp;
10316 }
10317 else
10318 ri = ri->next;
10319 }
10320 }
10321
10322 bgp_unlock_node (rn);
10323 }
10324 }
10325
10326 return CMD_SUCCESS;
10327 }
10328
10329 DEFUN (clear_ip_bgp_dampening,
10330 clear_ip_bgp_dampening_cmd,
10331 "clear ip bgp dampening",
10332 CLEAR_STR
10333 IP_STR
10334 BGP_STR
10335 "Clear route flap dampening information\n")
10336 {
10337 bgp_damp_info_clean ();
10338 return CMD_SUCCESS;
10339 }
10340
10341 DEFUN (clear_ip_bgp_dampening_prefix,
10342 clear_ip_bgp_dampening_prefix_cmd,
10343 "clear ip bgp dampening A.B.C.D/M",
10344 CLEAR_STR
10345 IP_STR
10346 BGP_STR
10347 "Clear route flap dampening information\n"
10348 "IPv4 prefix\n")
10349 {
10350 int idx_ipv4_prefixlen = 4;
10351 return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
10352 SAFI_UNICAST, NULL, 1);
10353 }
10354
10355 DEFUN (clear_ip_bgp_dampening_address,
10356 clear_ip_bgp_dampening_address_cmd,
10357 "clear ip bgp dampening A.B.C.D",
10358 CLEAR_STR
10359 IP_STR
10360 BGP_STR
10361 "Clear route flap dampening information\n"
10362 "Network to clear damping information\n")
10363 {
10364 int idx_ipv4 = 4;
10365 return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
10366 SAFI_UNICAST, NULL, 0);
10367 }
10368
10369 DEFUN (clear_ip_bgp_dampening_address_mask,
10370 clear_ip_bgp_dampening_address_mask_cmd,
10371 "clear ip bgp dampening A.B.C.D A.B.C.D",
10372 CLEAR_STR
10373 IP_STR
10374 BGP_STR
10375 "Clear route flap dampening information\n"
10376 "Network to clear damping information\n"
10377 "Network mask\n")
10378 {
10379 int idx_ipv4 = 4;
10380 int idx_ipv4_2 = 5;
10381 int ret;
10382 char prefix_str[BUFSIZ];
10383
10384 ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
10385 if (! ret)
10386 {
10387 vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
10388 return CMD_WARNING;
10389 }
10390
10391 return bgp_clear_damp_route (vty, NULL, prefix_str, AFI_IP,
10392 SAFI_UNICAST, NULL, 0);
10393 }
10394
10395 /* also used for encap safi */
10396 static int
10397 bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
10398 afi_t afi, safi_t safi, int *write)
10399 {
10400 struct bgp_node *prn;
10401 struct bgp_node *rn;
10402 struct bgp_table *table;
10403 struct prefix *p;
10404 struct prefix_rd *prd;
10405 struct bgp_static *bgp_static;
10406 u_int32_t label;
10407 char buf[SU_ADDRSTRLEN];
10408 char rdbuf[RD_ADDRSTRLEN];
10409
10410 /* Network configuration. */
10411 for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
10412 if ((table = prn->info) != NULL)
10413 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
10414 if ((bgp_static = rn->info) != NULL)
10415 {
10416 p = &rn->p;
10417 prd = (struct prefix_rd *) &prn->p;
10418
10419 /* "address-family" display. */
10420 bgp_config_write_family_header (vty, afi, safi, write);
10421
10422 /* "network" configuration display. */
10423 prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
10424 label = decode_label (bgp_static->tag);
10425
10426 vty_out (vty, " network %s/%d rd %s",
10427 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10428 p->prefixlen, rdbuf);
10429 if (safi == SAFI_MPLS_VPN)
10430 vty_out (vty, " label %u", label);
10431
10432 if (bgp_static->rmap.name)
10433 vty_out (vty, " route-map %s", bgp_static->rmap.name);
10434 else
10435 {
10436 if (bgp_static->backdoor)
10437 vty_out (vty, " backdoor");
10438 }
10439 vty_out (vty, "%s", VTY_NEWLINE);
10440 }
10441 return 0;
10442 }
10443
10444 static int
10445 bgp_config_write_network_evpn (struct vty *vty, struct bgp *bgp,
10446 afi_t afi, safi_t safi, int *write)
10447 {
10448 struct bgp_node *prn;
10449 struct bgp_node *rn;
10450 struct bgp_table *table;
10451 struct prefix *p;
10452 struct prefix_rd *prd;
10453 struct bgp_static *bgp_static;
10454 char buf[PREFIX_STRLEN];
10455 char buf2[SU_ADDRSTRLEN];
10456 char rdbuf[RD_ADDRSTRLEN];
10457
10458 /* Network configuration. */
10459 for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
10460 if ((table = prn->info) != NULL)
10461 for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
10462 if ((bgp_static = rn->info) != NULL)
10463 {
10464 char *macrouter = NULL;
10465 char *esi = NULL;
10466
10467 if(bgp_static->router_mac)
10468 macrouter = prefix_mac2str(bgp_static->router_mac, NULL, 0);
10469 if(bgp_static->eth_s_id)
10470 esi = esi2str(bgp_static->eth_s_id);
10471 p = &rn->p;
10472 prd = (struct prefix_rd *) &prn->p;
10473
10474 /* "address-family" display. */
10475 bgp_config_write_family_header (vty, afi, safi, write);
10476
10477 /* "network" configuration display. */
10478 prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
10479
10480 inet_ntop (AF_INET, &bgp_static->igpnexthop, buf2, SU_ADDRSTRLEN);
10481
10482 prefix2str (p, buf, sizeof (buf)),
10483 vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
10484 buf, rdbuf, p->u.prefix_evpn.eth_tag,
10485 decode_label (bgp_static->tag), esi, buf2 , macrouter);
10486 vty_out (vty, "%s", VTY_NEWLINE);
10487 if (macrouter)
10488 XFREE (MTYPE_TMP, macrouter);
10489 if (esi)
10490 XFREE (MTYPE_TMP, esi);
10491 }
10492 return 0;
10493 }
10494
10495 /* Configuration of static route announcement and aggregate
10496 information. */
10497 int
10498 bgp_config_write_network (struct vty *vty, struct bgp *bgp,
10499 afi_t afi, safi_t safi, int *write)
10500 {
10501 struct bgp_node *rn;
10502 struct prefix *p;
10503 struct bgp_static *bgp_static;
10504 struct bgp_aggregate *bgp_aggregate;
10505 char buf[SU_ADDRSTRLEN];
10506
10507 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
10508 return bgp_config_write_network_vpn (vty, bgp, afi, safi, write);
10509
10510 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
10511 return bgp_config_write_network_evpn (vty, bgp, afi, safi, write);
10512
10513 /* Network configuration. */
10514 for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
10515 if ((bgp_static = rn->info) != NULL)
10516 {
10517 p = &rn->p;
10518
10519 /* "address-family" display. */
10520 bgp_config_write_family_header (vty, afi, safi, write);
10521
10522 /* "network" configuration display. */
10523 if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
10524 {
10525 u_int32_t destination;
10526 struct in_addr netmask;
10527
10528 destination = ntohl (p->u.prefix4.s_addr);
10529 masklen2ip (p->prefixlen, &netmask);
10530 vty_out (vty, " network %s",
10531 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN));
10532
10533 if ((IN_CLASSC (destination) && p->prefixlen == 24)
10534 || (IN_CLASSB (destination) && p->prefixlen == 16)
10535 || (IN_CLASSA (destination) && p->prefixlen == 8)
10536 || p->u.prefix4.s_addr == 0)
10537 {
10538 /* Natural mask is not display. */
10539 }
10540 else
10541 vty_out (vty, " mask %s", inet_ntoa (netmask));
10542 }
10543 else
10544 {
10545 vty_out (vty, " network %s/%d",
10546 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10547 p->prefixlen);
10548 }
10549
10550 if (bgp_static->rmap.name)
10551 vty_out (vty, " route-map %s", bgp_static->rmap.name);
10552 else
10553 {
10554 if (bgp_static->backdoor)
10555 vty_out (vty, " backdoor");
10556 }
10557
10558 vty_out (vty, "%s", VTY_NEWLINE);
10559 }
10560
10561 /* Aggregate-address configuration. */
10562 for (rn = bgp_table_top (bgp->aggregate[afi][safi]); rn; rn = bgp_route_next (rn))
10563 if ((bgp_aggregate = rn->info) != NULL)
10564 {
10565 p = &rn->p;
10566
10567 /* "address-family" display. */
10568 bgp_config_write_family_header (vty, afi, safi, write);
10569
10570 if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
10571 {
10572 struct in_addr netmask;
10573
10574 masklen2ip (p->prefixlen, &netmask);
10575 vty_out (vty, " aggregate-address %s %s",
10576 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10577 inet_ntoa (netmask));
10578 }
10579 else
10580 {
10581 vty_out (vty, " aggregate-address %s/%d",
10582 inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
10583 p->prefixlen);
10584 }
10585
10586 if (bgp_aggregate->as_set)
10587 vty_out (vty, " as-set");
10588
10589 if (bgp_aggregate->summary_only)
10590 vty_out (vty, " summary-only");
10591
10592 vty_out (vty, "%s", VTY_NEWLINE);
10593 }
10594
10595 return 0;
10596 }
10597
10598 int
10599 bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi,
10600 safi_t safi, int *write)
10601 {
10602 struct bgp_node *rn;
10603 struct bgp_distance *bdistance;
10604
10605 /* Distance configuration. */
10606 if (bgp->distance_ebgp[afi][safi]
10607 && bgp->distance_ibgp[afi][safi]
10608 && bgp->distance_local[afi][safi]
10609 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
10610 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
10611 || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT))
10612 {
10613 bgp_config_write_family_header (vty, afi, safi, write);
10614 vty_out (vty, " distance bgp %d %d %d%s",
10615 bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi],
10616 bgp->distance_local[afi][safi], VTY_NEWLINE);
10617 }
10618
10619 for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn;
10620 rn = bgp_route_next (rn))
10621 if ((bdistance = rn->info) != NULL)
10622 {
10623 char buf[PREFIX_STRLEN];
10624
10625 bgp_config_write_family_header (vty, afi, safi, write);
10626 vty_out (vty, " distance %d %s %s%s", bdistance->distance,
10627 prefix2str (&rn->p, buf, sizeof (buf)),
10628 bdistance->access_list ? bdistance->access_list : "",
10629 VTY_NEWLINE);
10630 }
10631
10632 return *write;
10633 }
10634
10635 /* Allocate routing table structure and install commands. */
10636 void
10637 bgp_route_init (void)
10638 {
10639 afi_t afi;
10640 safi_t safi;
10641
10642 /* Init BGP distance table. */
10643 for (afi = AFI_IP; afi < AFI_MAX; afi++)
10644 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
10645 bgp_distance_table[afi][safi] = bgp_table_init (afi, safi);
10646
10647 /* IPv4 BGP commands. */
10648 install_element (BGP_NODE, &bgp_table_map_cmd);
10649 install_element (BGP_NODE, &bgp_network_cmd);
10650 install_element (BGP_NODE, &bgp_network_mask_cmd);
10651 install_element (BGP_NODE, &bgp_network_mask_natural_cmd);
10652 install_element (BGP_NODE, &bgp_network_route_map_cmd);
10653 install_element (BGP_NODE, &bgp_network_mask_route_map_cmd);
10654 install_element (BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
10655 install_element (BGP_NODE, &bgp_network_backdoor_cmd);
10656 install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
10657 install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
10658 install_element (BGP_NODE, &no_bgp_table_map_cmd);
10659 install_element (BGP_NODE, &no_bgp_network_cmd);
10660 install_element (BGP_NODE, &no_bgp_network_mask_cmd);
10661 install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
10662
10663 install_element (BGP_NODE, &aggregate_address_cmd);
10664 install_element (BGP_NODE, &aggregate_address_mask_cmd);
10665 install_element (BGP_NODE, &no_aggregate_address_cmd);
10666 install_element (BGP_NODE, &no_aggregate_address_mask_cmd);
10667
10668 /* IPv4 unicast configuration. */
10669 install_element (BGP_IPV4_NODE, &bgp_table_map_cmd);
10670 install_element (BGP_IPV4_NODE, &bgp_network_cmd);
10671 install_element (BGP_IPV4_NODE, &bgp_network_mask_cmd);
10672 install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
10673 install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
10674 install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
10675 install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
10676 install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
10677 install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
10678 install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
10679 install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
10680
10681 install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
10682 install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
10683 install_element (BGP_IPV4_NODE, &no_aggregate_address_cmd);
10684 install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
10685
10686 /* IPv4 multicast configuration. */
10687 install_element (BGP_IPV4M_NODE, &bgp_table_map_cmd);
10688 install_element (BGP_IPV4M_NODE, &bgp_network_cmd);
10689 install_element (BGP_IPV4M_NODE, &bgp_network_mask_cmd);
10690 install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
10691 install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
10692 install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
10693 install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
10694 install_element (BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
10695 install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
10696 install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
10697 install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
10698 install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
10699 install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
10700 install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
10701 install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
10702
10703 install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
10704 install_element (VIEW_NODE, &show_ip_bgp_cmd);
10705 install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
10706 install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
10707
10708 install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
10709 install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
10710 install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
10711 #ifdef KEEP_OLD_VPN_COMMANDS
10712 install_element (VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
10713 #endif /* KEEP_OLD_VPN_COMMANDS */
10714 install_element (VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
10715 install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
10716
10717 /* BGP dampening clear commands */
10718 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
10719 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
10720
10721 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
10722 install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
10723
10724 /* prefix count */
10725 install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
10726 #ifdef KEEP_OLD_VPN_COMMANDS
10727 install_element (ENABLE_NODE, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
10728 #endif /* KEEP_OLD_VPN_COMMANDS */
10729
10730 /* New config IPv6 BGP commands. */
10731 install_element (BGP_IPV6_NODE, &bgp_table_map_cmd);
10732 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
10733 install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
10734 install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
10735 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
10736
10737 install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
10738 install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
10739
10740 install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
10741 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
10742
10743 install_element (BGP_NODE, &bgp_distance_cmd);
10744 install_element (BGP_NODE, &no_bgp_distance_cmd);
10745 install_element (BGP_NODE, &bgp_distance_source_cmd);
10746 install_element (BGP_NODE, &no_bgp_distance_source_cmd);
10747 install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
10748 install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
10749 install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
10750 install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
10751 install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
10752 install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
10753 install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
10754 install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
10755 install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
10756 install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
10757 install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
10758 install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
10759 install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
10760 install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
10761 install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
10762 install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
10763 install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
10764 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
10765 install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
10766 install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
10767 install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
10768 install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
10769 install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
10770 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
10771 install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
10772 install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
10773
10774 install_element (BGP_NODE, &bgp_damp_set_cmd);
10775 install_element (BGP_NODE, &bgp_damp_unset_cmd);
10776 install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd);
10777 install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
10778
10779 /* IPv4 Multicast Mode */
10780 install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
10781 install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
10782
10783 /* Large Communities */
10784 install_element (VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
10785 install_element (VIEW_NODE, &show_ip_bgp_large_community_cmd);
10786 }
10787
10788 void
10789 bgp_route_finish (void)
10790 {
10791 afi_t afi;
10792 safi_t safi;
10793
10794 for (afi = AFI_IP; afi < AFI_MAX; afi++)
10795 for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
10796 {
10797 bgp_table_unlock (bgp_distance_table[afi][safi]);
10798 bgp_distance_table[afi][safi] = NULL;
10799 }
10800 }