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