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