Date: Mon, 30 Nov 2015 05:51:14 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r291466 - in head/sys: net netinet netinet6 Message-ID: <201511300551.tAU5pELW085961@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Mon Nov 30 05:51:14 2015 New Revision: 291466 URL: https://svnweb.freebsd.org/changeset/base/291466 Log: Add new rt_foreach_fib_walk_del() function for deleting route entries by filter function instead of picking into routing table details in each consumer. Remove now-unused rt_expunge() (eliminating last external RTF_RNH_LOCKED user). This simplifies future nexthops/mulitipath changes and rtrequest1_fib() locking refactoring. Actual changes: Add "rt_chain" field to permit rte grouping while doing batched delete from routing table (thus growing rte 200->208 on amd64). Add "rti_filter" / "rti_filterdata" / "rti_spare" fields to rt_addrinfo to pass filter function to various routing subsystems in standard way. Convert all rt_expunge() customers to new rt_addinfo-based api and eliminate rt_expunge(). Modified: head/sys/net/route.c head/sys/net/route.h head/sys/netinet/in_rmx.c head/sys/netinet6/nd6.c head/sys/netinet6/nd6_rtr.c Modified: head/sys/net/route.c ============================================================================== --- head/sys/net/route.c Mon Nov 30 04:59:01 2015 (r291465) +++ head/sys/net/route.c Mon Nov 30 05:51:14 2015 (r291466) @@ -139,7 +139,14 @@ static VNET_DEFINE(uma_zone_t, rtzone); static int rtrequest1_fib_change(struct radix_node_head *, struct rt_addrinfo *, struct rtentry **, u_int); static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *); -static int rt_ifdelroute(struct rtentry *rt, void *arg); +static int rt_ifdelroute(const struct rtentry *rt, void *arg); +static struct rtentry *rt_unlinkrte(struct radix_node_head *rnh, + struct rt_addrinfo *info, int *perror); +static void rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info); +#ifdef RADIX_MPATH +static struct radix_node *rt_mpath_unlink(struct radix_node_head *rnh, + struct rt_addrinfo *info, struct rtentry *rto, int *perror); +#endif struct if_mtuinfo { @@ -237,6 +244,7 @@ rtentry_ctor(void *mem, int size, void * bzero(rt, offsetof(struct rtentry, rt_endzero)); counter_u64_zero(rt->rt_pksent); + rt->rt_chain = NULL; return (0); } @@ -867,6 +875,108 @@ rt_foreach_fib_walk(int af, rt_setwarg_t } } +struct rt_delinfo +{ + struct rt_addrinfo info; + struct radix_node_head *rnh; + struct rtentry *head; +}; + +/* + * Conditionally unlinks @rn from radix tree based + * on info data passed in @arg. + */ +static int +rt_checkdelroute(struct radix_node *rn, void *arg) +{ + struct rt_delinfo *di; + struct rt_addrinfo *info; + struct rtentry *rt; + int error; + + di = (struct rt_delinfo *)arg; + rt = (struct rtentry *)rn; + info = &di->info; + error = 0; + + info->rti_info[RTAX_DST] = rt_key(rt); + info->rti_info[RTAX_NETMASK] = rt_mask(rt); + info->rti_info[RTAX_GATEWAY] = rt->rt_gateway; + + rt = rt_unlinkrte(di->rnh, info, &error); + if (rt == NULL) { + /* Either not allowed or not matched. Skip entry */ + return (0); + } + + /* Entry was unlinked. Add to the list and return */ + rt->rt_chain = di->head; + di->head = rt; + + return (0); +} + +/* + * Iterates over all existing fibs in system. + * Deletes each element for which @filter_f function returned + * non-zero value. + * If @af is not AF_UNSPEC, iterates over fibs in particular + * address family. + */ +void +rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg) +{ + struct radix_node_head *rnh; + struct rt_delinfo di; + struct rtentry *rt; + uint32_t fibnum; + int i, start, end; + + bzero(&di, sizeof(di)); + di.info.rti_filter = filter_f; + di.info.rti_filterdata = arg; + + for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { + /* Do we want some specific family? */ + if (af != AF_UNSPEC) { + start = af; + end = af; + } else { + start = 1; + end = AF_MAX; + } + + for (i = start; i <= end; i++) { + rnh = rt_tables_get_rnh(fibnum, i); + if (rnh == NULL) + continue; + di.rnh = rnh; + + RADIX_NODE_HEAD_LOCK(rnh); + rnh->rnh_walktree(rnh, rt_checkdelroute, &di); + RADIX_NODE_HEAD_UNLOCK(rnh); + + if (di.head == NULL) + continue; + + /* We might have something to reclaim */ + while (di.head != NULL) { + rt = di.head; + di.head = rt->rt_chain; + rt->rt_chain = NULL; + + /* TODO std rt -> rt_addrinfo export */ + di.info.rti_info[RTAX_DST] = rt_key(rt); + di.info.rti_info[RTAX_NETMASK] = rt_mask(rt); + + rt_notifydelete(rt, &di.info); + RTFREE_LOCKED(rt); + } + + } + } +} + /* * Delete Routes for a Network Interface * @@ -882,10 +992,9 @@ rt_foreach_fib_walk(int af, rt_setwarg_t * errno failed - reason indicated */ static int -rt_ifdelroute(struct rtentry *rt, void *arg) +rt_ifdelroute(const struct rtentry *rt, void *arg) { struct ifnet *ifp = arg; - int err; if (rt->rt_ifp != ifp) return (0); @@ -897,14 +1006,7 @@ rt_ifdelroute(struct rtentry *rt, void * if ((rt->rt_flags & RTF_UP) == 0) return (0); - err = rtrequest_fib(RTM_DELETE, rt_key(rt), rt->rt_gateway, - rt_mask(rt), - rt->rt_flags | RTF_RNH_LOCKED | RTF_PINNED, - (struct rtentry **) NULL, rt->rt_fibnum); - if (err != 0) - log(LOG_WARNING, "rt_ifdelroute: error %d\n", err); - - return (0); + return (1); } /* @@ -917,9 +1019,105 @@ void rt_flushifroutes(struct ifnet *ifp) { - rt_foreach_fib_walk(AF_UNSPEC, NULL, rt_ifdelroute, ifp); + rt_foreach_fib_walk_del(AF_UNSPEC, rt_ifdelroute, ifp); +} + +/* + * Conditionally unlinks rtentry matching data inside @info from @rnh. + * Returns unlinked, locked and referenced @rtentry on success, + * Returns NULL and sets @perror to: + * ESRCH - if prefix was not found, + * EADDRINUSE - if trying to delete PINNED route without appropriate flag. + * ENOENT - if supplied filter function returned 0 (not matched). + */ +static struct rtentry * +rt_unlinkrte(struct radix_node_head *rnh, struct rt_addrinfo *info, int *perror) +{ + struct sockaddr *dst, *netmask; + struct rtentry *rt; + struct radix_node *rn; + + dst = info->rti_info[RTAX_DST]; + netmask = info->rti_info[RTAX_NETMASK]; + + rt = (struct rtentry *)rnh->rnh_lookup(dst, netmask, rnh); + if (rt == NULL) { + *perror = ESRCH; + return (NULL); + } + + if ((info->rti_flags & RTF_PINNED) == 0) { + /* Check if target route can be deleted */ + if (rt->rt_flags & RTF_PINNED) { + *perror = EADDRINUSE; + return (NULL); + } + } + + if (info->rti_filter != NULL) { + if (info->rti_filter(rt, info->rti_filterdata) == 0) { + /* Not matched */ + *perror = ENOENT; + return (NULL); + } + + /* + * Filter function requested rte deletion. + * Ease the caller work by filling in remaining info + * from that particular entry. + */ + info->rti_info[RTAX_GATEWAY] = rt->rt_gateway; + } + + /* + * Remove the item from the tree and return it. + * Complain if it is not there and do no more processing. + */ + *perror = ESRCH; +#ifdef RADIX_MPATH + if (rn_mpath_capable(rnh)) + rn = rt_mpath_unlink(rnh, info, rt, perror); + else +#endif + rn = rnh->rnh_deladdr(dst, netmask, rnh); + if (rn == NULL) + return (NULL); + + if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) + panic ("rtrequest delete"); + + rt = RNTORT(rn); + RT_LOCK(rt); + RT_ADDREF(rt); + + *perror = 0; + + return (rt); +} + +static void +rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info) +{ + struct ifaddr *ifa; + + rt->rt_flags &= ~RTF_UP; + + /* + * give the protocol a chance to keep things in sync. + */ + ifa = rt->rt_ifa; + if (ifa != NULL && ifa->ifa_rtrequest != NULL) + ifa->ifa_rtrequest(RTM_DELETE, rt, info); + + /* + * One more rtentry floating around that is not + * linked to the routing table. rttrash will be decremented + * when RTFREE(rt) is eventually called. + */ + V_rttrash++; } + /* * These (questionable) definitions of apparent local variables apply * to the next two functions. XXXXXX!!! @@ -975,87 +1173,6 @@ rt_getifa_fib(struct rt_addrinfo *info, return (error); } -/* - * Expunges references to a route that's about to be reclaimed. - * The route must be locked. - */ -int -rt_expunge(struct radix_node_head *rnh, struct rtentry *rt) -{ -#if !defined(RADIX_MPATH) - struct radix_node *rn; -#else - struct rt_addrinfo info; - int fib; - struct rtentry *rt0; -#endif - struct ifaddr *ifa; - int error = 0; - - RT_LOCK_ASSERT(rt); - RADIX_NODE_HEAD_LOCK_ASSERT(rnh); - -#ifdef RADIX_MPATH - fib = rt->rt_fibnum; - bzero(&info, sizeof(info)); - info.rti_ifp = rt->rt_ifp; - info.rti_flags = RTF_RNH_LOCKED; - info.rti_info[RTAX_DST] = rt_key(rt); - info.rti_info[RTAX_GATEWAY] = rt->rt_ifa->ifa_addr; - - RT_UNLOCK(rt); - error = rtrequest1_fib(RTM_DELETE, &info, &rt0, fib); - - if (error == 0 && rt0 != NULL) { - rt = rt0; - RT_LOCK(rt); - } else if (error != 0) { - RT_LOCK(rt); - return (error); - } -#else - /* - * Remove the item from the tree; it should be there, - * but when callers invoke us blindly it may not (sigh). - */ - rn = rnh->rnh_deladdr(rt_key(rt), rt_mask(rt), rnh); - if (rn == NULL) { - error = ESRCH; - goto bad; - } - KASSERT((rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) == 0, - ("unexpected flags 0x%x", rn->rn_flags)); - KASSERT(rt == RNTORT(rn), - ("lookup mismatch, rt %p rn %p", rt, rn)); -#endif /* RADIX_MPATH */ - - rt->rt_flags &= ~RTF_UP; - - /* - * Give the protocol a chance to keep things in sync. - */ - if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) { - struct rt_addrinfo info; - - bzero((caddr_t)&info, sizeof(info)); - info.rti_flags = rt->rt_flags; - info.rti_info[RTAX_DST] = rt_key(rt); - info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; - info.rti_info[RTAX_NETMASK] = rt_mask(rt); - ifa->ifa_rtrequest(RTM_DELETE, rt, &info); - } - - /* - * one more rtentry floating around that is not - * linked to the routing table. - */ - V_rttrash++; -#if !defined(RADIX_MPATH) -bad: -#endif - return (error); -} - static int if_updatemtu_cb(struct radix_node *rn, void *arg) { @@ -1172,26 +1289,32 @@ rt_print(char *buf, int buflen, struct r #endif #ifdef RADIX_MPATH -static int -rn_mpath_update(int req, struct rt_addrinfo *info, - struct radix_node_head *rnh, struct rtentry **ret_nrt) +/* + * Deletes key for single-path routes, unlinks rtentry with + * gateway specified in @info from multi-path routes. + * + * Returnes unlinked entry. In case of failure, returns NULL + * and sets @perror to ESRCH. + */ +static struct radix_node * +rt_mpath_unlink(struct radix_node_head *rnh, struct rt_addrinfo *info, + struct rtentry *rto, int *perror) { /* * if we got multipath routes, we require users to specify * a matching RTAX_GATEWAY. */ - struct rtentry *rt, *rto = NULL; + struct rtentry *rt; // *rto = NULL; struct radix_node *rn; - int error = 0; + struct sockaddr *gw; - rn = rnh->rnh_lookup(dst, netmask, rnh); - if (rn == NULL) - return (ESRCH); - rto = rt = RNTORT(rn); + gw = info->rti_info[RTAX_GATEWAY]; + rt = rt_mpath_matchgate(rto, gw); + if (rt == NULL) { + *perror = ESRCH; + return (NULL); + } - rt = rt_mpath_matchgate(rt, gateway); - if (rt == NULL) - return (ESRCH); /* * this is the first entry in the chain */ @@ -1214,67 +1337,31 @@ rn_mpath_update(int req, struct rt_addri * check the case when there is only * one route in the chain. */ - if (gateway && - (rt->rt_gateway->sa_len != gateway->sa_len || - memcmp(rt->rt_gateway, gateway, gateway->sa_len))) - error = ESRCH; - else { - /* - * remove from tree before returning it - * to the caller - */ - rn = rnh->rnh_deladdr(dst, netmask, rnh); - KASSERT(rt == RNTORT(rn), ("radix node disappeared")); - goto gwdelete; + if (gw && + (rt->rt_gateway->sa_len != gw->sa_len || + memcmp(rt->rt_gateway, gw, gw->sa_len))) { + *perror = ESRCH; + return (NULL); } - } + /* * use the normal delete code to remove * the first entry */ - if (req != RTM_DELETE) - goto nondelete; - - error = ENOENT; - goto done; + rn = rnh->rnh_deladdr(dst, netmask, rnh); + *perror = 0; + return (rn); } /* * if the entry is 2nd and on up */ - if ((req == RTM_DELETE) && !rt_mpath_deldup(rto, rt)) + if (rt_mpath_deldup(rto, rt) == 0) panic ("rtrequest1: rt_mpath_deldup"); -gwdelete: - RT_LOCK(rt); - RT_ADDREF(rt); - if (req == RTM_DELETE) { - rt->rt_flags &= ~RTF_UP; - /* - * One more rtentry floating around that is not - * linked to the routing table. rttrash will be decremented - * when RTFREE(rt) is eventually called. - */ - V_rttrash++; - } - -nondelete: - if (req != RTM_DELETE) - panic("unrecognized request %d", req); - - - /* - * If the caller wants it, then it can have it, - * but it's up to it to free the rtentry as we won't be - * doing it. - */ - if (ret_nrt) { - *ret_nrt = rt; - RT_UNLOCK(rt); - } else - RTFREE_LOCKED(rt); -done: - return (error); + *perror = 0; + rn = (struct radix_node *)rt; + return (rn); } #endif @@ -1330,52 +1417,12 @@ rtrequest1_fib(int req, struct rt_addrin rt_maskedcopy(dst, (struct sockaddr *)&mdst, netmask); dst = (struct sockaddr *)&mdst; } -#ifdef RADIX_MPATH - if (rn_mpath_capable(rnh)) { - error = rn_mpath_update(req, info, rnh, ret_nrt); - /* - * "bad" holds true for the success case - * as well - */ - if (error != ENOENT) - goto bad; - error = 0; - } -#endif - if ((flags & RTF_PINNED) == 0) { - /* Check if target route can be deleted */ - rt = (struct rtentry *)rnh->rnh_lookup(dst, - netmask, rnh); - if ((rt != NULL) && (rt->rt_flags & RTF_PINNED)) - senderr(EADDRINUSE); - } - /* - * Remove the item from the tree and return it. - * Complain if it is not there and do no more processing. - */ - rn = rnh->rnh_deladdr(dst, netmask, rnh); - if (rn == NULL) - senderr(ESRCH); - if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT)) - panic ("rtrequest delete"); - rt = RNTORT(rn); - RT_LOCK(rt); - RT_ADDREF(rt); - rt->rt_flags &= ~RTF_UP; - - /* - * give the protocol a chance to keep things in sync. - */ - if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest) - ifa->ifa_rtrequest(RTM_DELETE, rt, info); + rt = rt_unlinkrte(rnh, info, &error); + if (error != 0) + goto bad; - /* - * One more rtentry floating around that is not - * linked to the routing table. rttrash will be decremented - * when RTFREE(rt) is eventually called. - */ - V_rttrash++; + rt_notifydelete(rt, info); /* * If the caller wants it, then it can have it, Modified: head/sys/net/route.h ============================================================================== --- head/sys/net/route.h Mon Nov 30 04:59:01 2015 (r291465) +++ head/sys/net/route.h Mon Nov 30 05:51:14 2015 (r291466) @@ -128,6 +128,7 @@ struct rtentry { #define rt_endzero rt_pksent counter_u64_t rt_pksent; /* packets sent using this route */ struct mtx rt_mtx; /* mutex for routing entry */ + struct rtentry *rt_chain; /* pointer to next rtentry to delete */ }; #endif /* _KERNEL || _WANT_RTENTRY */ @@ -259,14 +260,19 @@ struct rt_msghdr { #define RTAX_BRD 7 /* for NEWADDR, broadcast or p-p dest addr */ #define RTAX_MAX 8 /* size of array to allocate */ +typedef int rt_filter_f_t(const struct rtentry *, void *); + struct rt_addrinfo { - int rti_addrs; - struct sockaddr *rti_info[RTAX_MAX]; - int rti_flags; - struct ifaddr *rti_ifa; - struct ifnet *rti_ifp; - u_long rti_mflags; - struct rt_metrics *rti_rmx; + int rti_addrs; /* Route RTF_ flags */ + int rti_flags; /* Route RTF_ flags */ + struct sockaddr *rti_info[RTAX_MAX]; /* Sockaddr data */ + struct ifaddr *rti_ifa; /* value of rt_ifa addr */ + struct ifnet *rti_ifp; /* route interface */ + rt_filter_f_t *rti_filter; /* filter function */ + void *rti_filterdata; /* filter paramenters */ + u_long rti_mflags; /* metrics RTV_ flags */ + u_long rti_spare; /* Will be used for fib */ + struct rt_metrics *rti_rmx; /* Pointer to route metrics */ }; /* @@ -383,6 +389,7 @@ void rt_updatemtu(struct ifnet *); typedef int rt_walktree_f_t(struct rtentry *, void *); typedef void rt_setwarg_t(struct radix_node_head *, uint32_t, int, void *); void rt_foreach_fib_walk(int af, rt_setwarg_t *, rt_walktree_f_t *, void *); +void rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg); void rt_flushifroutes(struct ifnet *ifp); /* XXX MRT COMPAT VERSIONS THAT SET UNIVERSE to 0 */ Modified: head/sys/netinet/in_rmx.c ============================================================================== --- head/sys/netinet/in_rmx.c Mon Nov 30 04:59:01 2015 (r291465) +++ head/sys/netinet/in_rmx.c Mon Nov 30 05:51:14 2015 (r291466) @@ -150,56 +150,22 @@ in_detachhead(void **head, int off) * plug back in. */ struct in_ifadown_arg { - struct radix_node_head *rnh; struct ifaddr *ifa; int del; }; static int -in_ifadownkill(struct rtentry *rt, void *xap) +in_ifadownkill(const struct rtentry *rt, void *xap) { struct in_ifadown_arg *ap = xap; - RT_LOCK(rt); - if (rt->rt_ifa == ap->ifa && - (ap->del || !(rt->rt_flags & RTF_STATIC))) { - /* - * Aquire a reference so that it can later be freed - * as the refcount would be 0 here in case of at least - * ap->del. - */ - RT_ADDREF(rt); - /* - * Disconnect it from the tree and permit protocols - * to cleanup. - */ - rt_expunge(ap->rnh, rt); - /* - * At this point it is an rttrash node, and in case - * the above is the only reference we must free it. - * If we do not noone will have a pointer and the - * rtentry will be leaked forever. - * In case someone else holds a reference, we are - * fine as we only decrement the refcount. In that - * case if the other entity calls RT_REMREF, we - * will still be leaking but at least we tried. - */ - RTFREE_LOCKED(rt); + if (rt->rt_ifa != ap->ifa) return (0); - } - RT_UNLOCK(rt); - return 0; -} - -static void -in_setifarnh(struct radix_node_head *rnh, uint32_t fibnum, int af, - void *_arg) -{ - struct in_ifadown_arg *arg; - arg = (struct in_ifadown_arg *)_arg; + if ((rt->rt_flags & RTF_STATIC) != 0 && ap->del == 0) + return (0); - arg->rnh = rnh; + return (1); } void @@ -213,7 +179,7 @@ in_ifadown(struct ifaddr *ifa, int delet arg.ifa = ifa; arg.del = delete; - rt_foreach_fib_walk(AF_INET, in_setifarnh, in_ifadownkill, &arg); + rt_foreach_fib_walk_del(AF_INET, in_ifadownkill, &arg); ifa->ifa_flags &= ~IFA_ROUTE; /* XXXlocking? */ } Modified: head/sys/netinet6/nd6.c ============================================================================== --- head/sys/netinet6/nd6.c Mon Nov 30 04:59:01 2015 (r291465) +++ head/sys/netinet6/nd6.c Mon Nov 30 05:51:14 2015 (r291466) @@ -1307,6 +1307,15 @@ nd6_free(struct llentry *ln, int gc) llentry_free(ln); } +static int +nd6_isdynrte(const struct rtentry *rt, void *xap) +{ + + if (rt->rt_flags == (RTF_UP | RTF_HOST | RTF_DYNAMIC)) + return (1); + + return (0); +} /* * Remove the rtentry for the given llentry, * both of which were installed by a redirect. @@ -1315,26 +1324,16 @@ static void nd6_free_redirect(const struct llentry *ln) { int fibnum; - struct rtentry *rt; - struct radix_node_head *rnh; struct sockaddr_in6 sin6; + struct rt_addrinfo info; lltable_fill_sa_entry(ln, (struct sockaddr *)&sin6); - for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { - rnh = rt_tables_get_rnh(fibnum, AF_INET6); - if (rnh == NULL) - continue; + memset(&info, 0, sizeof(info)); + info.rti_info[RTAX_DST] = (struct sockaddr *)&sin6; + info.rti_filter = nd6_isdynrte; - RADIX_NODE_HEAD_LOCK(rnh); - rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, - RTF_RNH_LOCKED, fibnum); - if (rt) { - if (rt->rt_flags == (RTF_UP | RTF_HOST | RTF_DYNAMIC)) - rt_expunge(rnh, rt); - RTFREE_LOCKED(rt); - } - RADIX_NODE_HEAD_UNLOCK(rnh); - } + for (fibnum = 0; fibnum < rt_numfibs; fibnum++) + rtrequest1_fib(RTM_DELETE, &info, NULL, fibnum); } /* Modified: head/sys/netinet6/nd6_rtr.c ============================================================================== --- head/sys/netinet6/nd6_rtr.c Mon Nov 30 04:59:01 2015 (r291465) +++ head/sys/netinet6/nd6_rtr.c Mon Nov 30 05:51:14 2015 (r291466) @@ -88,7 +88,7 @@ static void in6_init_address_ltimes(stru static int nd6_prefix_onlink(struct nd_prefix *); static int nd6_prefix_offlink(struct nd_prefix *); -static int rt6_deleteroute(struct rtentry *, void *); +static int rt6_deleteroute(const struct rtentry *, void *); VNET_DECLARE(int, nd6_recalc_reachtm_interval); #define V_nd6_recalc_reachtm_interval VNET(nd6_recalc_reachtm_interval) @@ -2073,11 +2073,11 @@ rt6_flush(struct in6_addr *gateway, stru return; /* XXX Do we really need to walk any but the default FIB? */ - rt_foreach_fib_walk(AF_INET6, NULL, rt6_deleteroute, (void *)gateway); + rt_foreach_fib_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway); } static int -rt6_deleteroute(struct rtentry *rt, void *arg) +rt6_deleteroute(const struct rtentry *rt, void *arg) { #define SIN6(s) ((struct sockaddr_in6 *)s) struct in6_addr *gate = (struct in6_addr *)arg; @@ -2104,8 +2104,7 @@ rt6_deleteroute(struct rtentry *rt, void if ((rt->rt_flags & RTF_HOST) == 0) return (0); - return (in6_rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, - rt_mask(rt), rt->rt_flags | RTF_RNH_LOCKED, NULL, rt->rt_fibnum)); + return (1); #undef SIN6 }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201511300551.tAU5pELW085961>