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