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