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