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