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