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