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