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