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