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