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