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