diff options
-rw-r--r-- | bgpd/bgp_nexthop.c | 82 | ||||
-rw-r--r-- | bgpd/bgp_nexthop.h | 7 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 12 |
3 files changed, 73 insertions, 28 deletions
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 15f42e26d..64453987d 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -171,20 +171,62 @@ void bgp_tip_del(struct bgp *bgp, struct in_addr *tip) } } +/* BGP own address structure */ +struct bgp_addr { + struct in_addr addr; + struct list *ifp_name_list; +}; + +static void show_address_entry(struct hash_backet *backet, void *args) +{ + struct vty *vty = (struct vty *)args; + struct bgp_addr *addr = (struct bgp_addr *)backet->data; + char *name; + struct listnode *node; + + vty_out(vty, "addr: %s, count: %d : ", inet_ntoa(addr->addr), + addr->ifp_name_list->count); + + for (ALL_LIST_ELEMENTS_RO(addr->ifp_name_list, node, name)) { + vty_out(vty, " %s,", name); + } + + vty_out(vty, "\n"); +} + +void bgp_nexthop_show_address_hash(struct vty *vty, struct bgp *bgp) +{ + hash_iterate(bgp->address_hash, + (void (*)(struct hash_backet *, void *))show_address_entry, + vty); +} + +static void bgp_address_hash_string_del(void *val) +{ + char *data = val; + + XFREE(MTYPE_TMP, data); +} + static void *bgp_address_hash_alloc(void *p) { const struct in_addr *val = (const struct in_addr *)p; struct bgp_addr *addr; addr = XMALLOC(MTYPE_BGP_ADDR, sizeof(struct bgp_addr)); - addr->refcnt = 0; addr->addr.s_addr = val->s_addr; + addr->ifp_name_list = list_new(); + addr->ifp_name_list->del = bgp_address_hash_string_del; + return addr; } -static void bgp_address_hash_free(void *addr) +static void bgp_address_hash_free(void *data) { + struct bgp_addr *addr = data; + + list_delete_and_null(&addr->ifp_name_list); XFREE(MTYPE_BGP_ADDR, addr); } @@ -219,24 +261,35 @@ void bgp_address_destroy(struct bgp *bgp) bgp->address_hash = NULL; } -static void bgp_address_add(struct bgp *bgp, struct prefix *p) +static void bgp_address_add(struct bgp *bgp, struct connected *ifc, + struct prefix *p) { struct bgp_addr tmp; struct bgp_addr *addr; + struct listnode *node; + char *name; tmp.addr = p->u.prefix4; addr = hash_get(bgp->address_hash, &tmp, bgp_address_hash_alloc); - if (!addr) - return; - addr->refcnt++; + for (ALL_LIST_ELEMENTS_RO(addr->ifp_name_list, node, name)) { + if (strcmp(ifc->ifp->name, name) == 0) + break; + } + if (!node) { + name = XSTRDUP(MTYPE_TMP, ifc->ifp->name); + listnode_add(addr->ifp_name_list, name); + } } -static void bgp_address_del(struct bgp *bgp, struct prefix *p) +static void bgp_address_del(struct bgp *bgp, struct connected *ifc, + struct prefix *p) { struct bgp_addr tmp; struct bgp_addr *addr; + struct listnode *node; + char *name; tmp.addr = p->u.prefix4; @@ -245,10 +298,17 @@ static void bgp_address_del(struct bgp *bgp, struct prefix *p) if (addr == NULL) return; - addr->refcnt--; + for (ALL_LIST_ELEMENTS_RO(addr->ifp_name_list, node, name)) { + if (strcmp(ifc->ifp->name, name) == 0) + break; + } - if (addr->refcnt == 0) { + if (node) + list_delete_node(addr->ifp_name_list, node); + + if (addr->ifp_name_list->count == 0) { hash_release(bgp->address_hash, addr); + list_delete_and_null(&addr->ifp_name_list); XFREE(MTYPE_BGP_ADDR, addr); } } @@ -276,7 +336,7 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) return; - bgp_address_add(bgp, addr); + bgp_address_add(bgp, ifc, addr); rn = bgp_node_get(bgp->connected_table[AFI_IP], (struct prefix *)&p); @@ -340,7 +400,7 @@ void bgp_connected_delete(struct bgp *bgp, struct connected *ifc) if (prefix_ipv4_any((struct prefix_ipv4 *)&p)) return; - bgp_address_del(bgp, addr); + bgp_address_del(bgp, ifc, addr); rn = bgp_node_lookup(bgp->connected_table[AFI_IP], &p); } else if (addr->family == AF_INET6) { diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h index a771bead2..1cb05bc85 100644 --- a/bgpd/bgp_nexthop.h +++ b/bgpd/bgp_nexthop.h @@ -68,12 +68,6 @@ struct bgp_nexthop_cache { struct bgp *bgp; }; -/* BGP own address structure */ -struct bgp_addr { - struct in_addr addr; - int refcnt; -}; - /* Own tunnel-ip address structure */ struct tip_addr { struct in_addr addr; @@ -103,4 +97,5 @@ extern void bgp_tip_del(struct bgp *bgp, struct in_addr *tip); extern void bgp_tip_hash_init(struct bgp *bgp); extern void bgp_tip_hash_destroy(struct bgp *bgp); +extern void bgp_nexthop_show_address_hash(struct vty *vty, struct bgp *bgp); #endif /* _QUAGGA_BGP_NEXTHOP_H */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e6d44c1a2..58f23fd2f 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -7451,14 +7451,6 @@ DEFUN (show_bgp_vrfs, return CMD_SUCCESS; } -static void show_address_entry(struct hash_backet *backet, void *args) -{ - struct vty *vty = (struct vty *)args; - struct bgp_addr *addr = (struct bgp_addr *)backet->data; - - vty_out(vty, "addr: %s, count: %d\n", inet_ntoa(addr->addr), - addr->refcnt); -} static void show_tip_entry(struct hash_backet *backet, void *args) { @@ -7472,9 +7464,7 @@ static void show_tip_entry(struct hash_backet *backet, void *args) static void bgp_show_martian_nexthops(struct vty *vty, struct bgp *bgp) { vty_out(vty, "self nexthop database:\n"); - hash_iterate(bgp->address_hash, - (void (*)(struct hash_backet *, void *))show_address_entry, - vty); + bgp_nexthop_show_address_hash(vty, bgp); vty_out(vty, "Tunnel-ip database:\n"); hash_iterate(bgp->tip_hash, |