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