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