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