2 Copyright (C) 2000 Kunihiro Ishiguro
4 This file is part of GNU Zebra.
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
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.
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
36 #include "bgpd/bgpd.h"
37 #include "bgpd/bgp_table.h"
38 #include "bgpd/bgp_route.h"
39 #include "bgpd/bgp_attr.h"
40 #include "bgpd/bgp_nexthop.h"
41 #include "bgpd/bgp_nht.h"
42 #include "bgpd/bgp_debug.h"
43 #include "bgpd/bgp_damp.h"
44 #include "zebra/rib.h"
45 #include "zebra/zserv.h" /* For ZEBRA_SERV_PATH. */
48 /* Route table for next-hop lookup cache. */
49 struct bgp_table *bgp_nexthop_cache_table[AFI_MAX];
50 static struct bgp_table *cache1_table[AFI_MAX];
52 /* Route table for connected route. */
53 static struct bgp_table *bgp_connected_table[AFI_MAX];
56 bnc_str (struct bgp_nexthop_cache *bnc, char *buf, int size)
58 prefix2str(&(bnc->node->p), buf, size);
63 bnc_nexthop_free (struct bgp_nexthop_cache *bnc)
65 struct nexthop *nexthop;
66 struct nexthop *next = NULL;
68 for (nexthop = bnc->nexthop; nexthop; nexthop = next)
71 XFREE (MTYPE_NEXTHOP, nexthop);
75 struct bgp_nexthop_cache *
78 struct bgp_nexthop_cache *bnc;
80 bnc = XCALLOC (MTYPE_BGP_NEXTHOP_CACHE, sizeof (struct bgp_nexthop_cache));
81 LIST_INIT(&(bnc->paths));
86 bnc_free (struct bgp_nexthop_cache *bnc)
88 bnc_nexthop_free (bnc);
89 XFREE (MTYPE_BGP_NEXTHOP_CACHE, bnc);
92 /* If nexthop exists on connected network return 1. */
94 bgp_nexthop_onlink (afi_t afi, struct attr *attr)
98 /* Lookup the address is onlink or not. */
101 rn = bgp_node_match_ipv4 (bgp_connected_table[AFI_IP], &attr->nexthop);
104 bgp_unlock_node (rn);
108 else if (afi == AFI_IP6)
110 if (attr->extra->mp_nexthop_len == 32)
112 else if (attr->extra->mp_nexthop_len == 16)
114 if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
117 rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
118 &attr->extra->mp_nexthop_global);
121 bgp_unlock_node (rn);
129 /* BGP own address structure */
136 static struct hash *bgp_address_hash;
139 bgp_address_hash_alloc (void *p)
141 struct in_addr *val = p;
142 struct bgp_addr *addr;
144 addr = XMALLOC (MTYPE_BGP_ADDR, sizeof (struct bgp_addr));
146 addr->addr.s_addr = val->s_addr;
152 bgp_address_hash_key_make (void *p)
154 const struct bgp_addr *addr = p;
156 return jhash_1word(addr->addr.s_addr, 0);
160 bgp_address_hash_cmp (const void *p1, const void *p2)
162 const struct bgp_addr *addr1 = p1;
163 const struct bgp_addr *addr2 = p2;
165 return addr1->addr.s_addr == addr2->addr.s_addr;
169 bgp_address_init (void)
171 bgp_address_hash = hash_create (bgp_address_hash_key_make,
172 bgp_address_hash_cmp);
176 bgp_address_destroy (void)
178 if (bgp_address_hash == NULL)
181 hash_clean(bgp_address_hash, NULL);
182 hash_free(bgp_address_hash);
183 bgp_address_hash = NULL;
187 bgp_address_add (struct prefix *p)
190 struct bgp_addr *addr;
192 tmp.addr = p->u.prefix4;
194 addr = hash_get (bgp_address_hash, &tmp, bgp_address_hash_alloc);
202 bgp_address_del (struct prefix *p)
205 struct bgp_addr *addr;
207 tmp.addr = p->u.prefix4;
209 addr = hash_lookup (bgp_address_hash, &tmp);
210 /* may have been deleted earlier by bgp_interface_down() */
216 if (addr->refcnt == 0)
218 hash_release (bgp_address_hash, addr);
219 XFREE (MTYPE_BGP_ADDR, addr);
224 struct bgp_connected_ref
230 bgp_connected_add (struct connected *ifc)
234 struct interface *ifp;
236 struct bgp_connected_ref *bc;
243 if (if_is_loopback (ifp))
248 p = *(CONNECTED_PREFIX(ifc));
249 if (addr->family == AF_INET)
251 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
253 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
256 bgp_address_add (addr);
258 rn = bgp_node_get (bgp_connected_table[AFI_IP], (struct prefix *) &p);
266 bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
271 else if (addr->family == AF_INET6)
273 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
275 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
278 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
281 rn = bgp_node_get (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
289 bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref));
297 bgp_connected_delete (struct connected *ifc)
301 struct interface *ifp;
303 struct bgp_connected_ref *bc;
307 if (if_is_loopback (ifp))
312 p = *(CONNECTED_PREFIX(ifc));
313 if (addr->family == AF_INET)
315 apply_mask_ipv4 ((struct prefix_ipv4 *) &p);
317 if (prefix_ipv4_any ((struct prefix_ipv4 *) &p))
320 bgp_address_del (addr);
322 rn = bgp_node_lookup (bgp_connected_table[AFI_IP], &p);
330 XFREE (MTYPE_BGP_CONN, bc);
333 bgp_unlock_node (rn);
334 bgp_unlock_node (rn);
336 else if (addr->family == AF_INET6)
338 apply_mask_ipv6 ((struct prefix_ipv6 *) &p);
340 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
343 if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
346 rn = bgp_node_lookup (bgp_connected_table[AFI_IP6], (struct prefix *) &p);
354 XFREE (MTYPE_BGP_CONN, bc);
357 bgp_unlock_node (rn);
358 bgp_unlock_node (rn);
363 bgp_nexthop_self (struct attr *attr)
365 struct bgp_addr tmp, *addr;
367 tmp.addr = attr->nexthop;
369 addr = hash_lookup (bgp_address_hash, &tmp);
377 bgp_multiaccess_check_v4 (struct in_addr nexthop, struct peer *peer)
379 struct bgp_node *rn1;
380 struct bgp_node *rn2;
385 p.prefixlen = IPV4_MAX_BITLEN;
386 p.u.prefix4 = nexthop;
388 rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p);
393 p.prefixlen = IPV4_MAX_BITLEN;
394 p.u.prefix4 = peer->su.sin.sin_addr;
396 rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p);
399 bgp_unlock_node(rn1);
403 ret = (rn1 == rn2) ? 1 : 0;
405 bgp_unlock_node(rn1);
406 bgp_unlock_node(rn2);
412 show_ip_bgp_nexthop_table (struct vty *vty, int detail)
415 struct bgp_nexthop_cache *bnc;
416 char buf[INET6_ADDRSTRLEN];
417 struct nexthop *nexthop;
421 vty_out (vty, "Current BGP nexthop cache:%s", VTY_NEWLINE);
422 for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
424 if (!bgp_nexthop_cache_table[afi])
427 for (rn = bgp_table_top (bgp_nexthop_cache_table[afi]); rn; rn = bgp_route_next (rn))
429 if ((bnc = rn->info) != NULL)
431 if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID))
433 vty_out (vty, " %s valid [IGP metric %d], #paths %d%s",
434 inet_ntop (rn->p.family, &rn->p.u.prefix, buf, sizeof (buf)),
435 bnc->metric, bnc->path_count, VTY_NEWLINE);
437 for (nexthop = bnc->nexthop ; nexthop; nexthop = nexthop->next)
438 switch (nexthop->type)
440 case NEXTHOP_TYPE_IPV6:
441 vty_out (vty, " gate %s%s",
442 inet_ntop (AF_INET6, &nexthop->gate.ipv6,
443 buf, INET6_ADDRSTRLEN), VTY_NEWLINE);
445 case NEXTHOP_TYPE_IPV6_IFINDEX:
446 vty_out(vty, " gate %s, if %s%s",
447 inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf,
449 ifindex2ifname(nexthop->ifindex),
452 case NEXTHOP_TYPE_IPV4:
453 vty_out (vty, " gate %s%s",
454 inet_ntop (AF_INET, &nexthop->gate.ipv4, buf,
455 INET6_ADDRSTRLEN), VTY_NEWLINE);
457 case NEXTHOP_TYPE_IFINDEX:
458 vty_out (vty, " if %s%s",
459 ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
461 case NEXTHOP_TYPE_IPV4_IFINDEX:
462 vty_out (vty, " gate %s, if %s%s",
463 inet_ntop(AF_INET, &nexthop->gate.ipv4, buf,
465 ifindex2ifname(nexthop->ifindex), VTY_NEWLINE);
468 vty_out (vty, " invalid nexthop type %u%s",
469 nexthop->type, VTY_NEWLINE);
473 vty_out (vty, " %s invalid%s",
474 inet_ntop (AF_INET, &rn->p.u.prefix, buf, sizeof (buf)), VTY_NEWLINE);
475 #ifdef HAVE_CLOCK_MONOTONIC
476 tbuf = time(NULL) - (bgp_clock() - bnc->last_update);
477 vty_out (vty, " Last update: %s", ctime(&tbuf));
479 vty_out (vty, " Last update: %s", ctime(&bnc->uptime));
480 #endif /* HAVE_CLOCK_MONOTONIC */
481 vty_out(vty, "%s", VTY_NEWLINE);
488 DEFUN (show_ip_bgp_nexthop,
489 show_ip_bgp_nexthop_cmd,
490 "show ip bgp nexthop",
494 "BGP nexthop table\n")
496 return show_ip_bgp_nexthop_table (vty, 0);
499 DEFUN (show_ip_bgp_nexthop_detail,
500 show_ip_bgp_nexthop_detail_cmd,
501 "show ip bgp nexthop detail",
505 "BGP nexthop table\n")
507 return show_ip_bgp_nexthop_table (vty, 1);
513 cache1_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
514 bgp_nexthop_cache_table[AFI_IP] = cache1_table[AFI_IP];
516 bgp_connected_table[AFI_IP] = bgp_table_init (AFI_IP, SAFI_UNICAST);
518 cache1_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
519 bgp_nexthop_cache_table[AFI_IP6] = cache1_table[AFI_IP6];
520 bgp_connected_table[AFI_IP6] = bgp_table_init (AFI_IP6, SAFI_UNICAST);
522 cache1_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
523 bgp_nexthop_cache_table[AFI_ETHER] = cache1_table[AFI_ETHER];
524 bgp_connected_table[AFI_ETHER] = bgp_table_init (AFI_ETHER, SAFI_UNICAST);
530 install_element (VIEW_NODE, &show_ip_bgp_nexthop_cmd);
531 install_element (VIEW_NODE, &show_ip_bgp_nexthop_detail_cmd);
535 bgp_scan_finish (void)
537 if (cache1_table[AFI_IP])
538 bgp_table_unlock (cache1_table[AFI_IP]);
539 cache1_table[AFI_IP] = NULL;
541 if (bgp_connected_table[AFI_IP])
542 bgp_table_unlock (bgp_connected_table[AFI_IP]);
543 bgp_connected_table[AFI_IP] = NULL;
545 if (cache1_table[AFI_IP6])
546 bgp_table_unlock (cache1_table[AFI_IP6]);
547 cache1_table[AFI_IP6] = NULL;
549 if (bgp_connected_table[AFI_IP6])
550 bgp_table_unlock (bgp_connected_table[AFI_IP6]);
551 bgp_connected_table[AFI_IP6] = NULL;
553 if (cache1_table[AFI_ETHER])
554 bgp_table_unlock (cache1_table[AFI_ETHER]);
555 cache1_table[AFI_ETHER] = NULL;
557 if (bgp_connected_table[AFI_ETHER])
558 bgp_table_unlock (bgp_connected_table[AFI_ETHER]);
559 bgp_connected_table[AFI_ETHER] = NULL;
564 bgp_scan_destroy (void)