Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107170353
D22988.id66207.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D22988.id66207.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -4098,6 +4098,7 @@
net/raw_cb.c standard
net/raw_usrreq.c standard
net/route.c standard
+net/route_temporal.c standard
net/rss_config.c optional inet rss | inet6 rss
net/rtsock.c standard
net/slcompress.c optional netgraph_vjc | sppp | \
Index: sys/net/radix_mpath.h
===================================================================
--- sys/net/radix_mpath.h
+++ sys/net/radix_mpath.h
@@ -57,8 +57,8 @@
void rtalloc_mpath_fib(struct route *, u_int32_t, u_int);
struct rtentry *rt_mpath_select(struct rtentry *, uint32_t);
int rt_mpath_deldup(struct rtentry *, struct rtentry *);
-int rn4_mpath_inithead(void **, int);
-int rn6_mpath_inithead(void **, int);
+int rn4_mpath_inithead(void **, int, u_int);
+int rn6_mpath_inithead(void **, int, u_int);
#endif
Index: sys/net/radix_mpath.c
===================================================================
--- sys/net/radix_mpath.c
+++ sys/net/radix_mpath.c
@@ -290,17 +290,17 @@
RT_UNLOCK(ro->ro_rt);
}
-extern int in6_inithead(void **head, int off);
-extern int in_inithead(void **head, int off);
+extern int in6_inithead(void **head, int off, u_int fibnum);
+extern int in_inithead(void **head, int off, u_int fibnum);
#ifdef INET
int
-rn4_mpath_inithead(void **head, int off)
+rn4_mpath_inithead(void **head, int off, u_int fibnum)
{
struct rib_head *rnh;
hashjitter = arc4random();
- if (in_inithead(head, off) == 1) {
+ if (in_inithead(head, off, fibnum) == 1) {
rnh = (struct rib_head *)*head;
rnh->rnh_multipath = 1;
return 1;
@@ -311,12 +311,12 @@
#ifdef INET6
int
-rn6_mpath_inithead(void **head, int off)
+rn6_mpath_inithead(void **head, int off, u_int fibnum)
{
struct rib_head *rnh;
hashjitter = arc4random();
- if (in6_inithead(head, off) == 1) {
+ if (in6_inithead(head, off, fibnum) == 1) {
rnh = (struct rib_head *)*head;
rnh->rnh_multipath = 1;
return 1;
Index: sys/net/route.h
===================================================================
--- sys/net/route.h
+++ sys/net/route.h
@@ -455,7 +455,7 @@
void rt_newmaddrmsg(int, struct ifmultiaddr *);
int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
-struct rib_head *rt_table_init(int);
+struct rib_head *rt_table_init(int, int, u_int);
void rt_table_destroy(struct rib_head *);
u_int rt_tables_get_gen(int table, int fam);
@@ -477,6 +477,8 @@
typedef int rt_walktree_f_t(struct rtentry *, void *);
typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *);
+void rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f,
+ void *arg, int report);
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_af(struct ifnet *, int);
@@ -494,8 +496,8 @@
void rtalloc_ign_fib(struct route *ro, u_long ignflags, u_int fibnum);
struct rtentry *rtalloc1_fib(struct sockaddr *, int, u_long, u_int);
int rtioctl_fib(u_long, caddr_t, u_int);
-void rtredirect_fib(struct sockaddr *, struct sockaddr *,
- struct sockaddr *, int, struct sockaddr *, u_int);
+int rtredirect_fib(struct sockaddr *, struct sockaddr *,
+ int, struct sockaddr *, int, u_int);
int rtrequest_fib(int, struct sockaddr *,
struct sockaddr *, struct sockaddr *, int, struct rtentry **, u_int);
int rtrequest1_fib(int, struct rt_addrinfo *, struct rtentry **, u_int);
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -187,10 +187,11 @@
{
struct rib_head **rnh;
- KASSERT(table >= 0 && table < rt_numfibs, ("%s: table out of bounds.",
- __func__));
- KASSERT(fam >= 0 && fam < (AF_MAX+1), ("%s: fam out of bounds.",
- __func__));
+ KASSERT(table >= 0 && table < rt_numfibs,
+ ("%s: table out of bounds (0 < %d < %d)", __func__, table,
+ rt_numfibs));
+ KASSERT(fam >= 0 && fam < (AF_MAX + 1),
+ ("%s: fam out of bounds (0 < %d < %d)", __func__, fam, AF_MAX + 1));
/* rnh is [fib=0][af=0]. */
rnh = (struct rib_head **)V_rt_tables;
@@ -304,7 +305,7 @@
rnh = rt_tables_get_rnh_ptr(table, fam);
if (rnh == NULL)
panic("%s: rnh NULL", __func__);
- dom->dom_rtattach((void **)rnh, 0);
+ dom->dom_rtattach((void **)rnh, 0, table);
}
}
}
@@ -345,7 +346,7 @@
#endif
struct rib_head *
-rt_table_init(int offset)
+rt_table_init(int offset, int family, u_int fibnum)
{
struct rib_head *rh;
@@ -357,9 +358,19 @@
rn_inithead_internal(&rh->rmhead.head, rh->rmhead.mask_nodes, 0);
rh->head.rnh_masks = &rh->rmhead;
+ rh->rib_family = family;
+ rh->rib_fibnum = fibnum;
+
/* Init locks */
RIB_LOCK_INIT(rh);
+ tmproutes_init(rh);
+
+ /* Save vnet pointer for callouts */
+#ifdef VIMAGE
+ rh->rib_vnet = curvnet;
+#endif
+
/* Finally, set base callbacks */
rh->rnh_addaddr = rn_addroute;
rh->rnh_deladdr = rn_delete;
@@ -387,6 +398,8 @@
rt_table_destroy(struct rib_head *rh)
{
+ tmproutes_destroy(rh);
+
rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head);
/* Assume table is already empty */
@@ -578,131 +591,125 @@
}
-/*
- * Force a routing table entry to the specified
- * destination to go through the given gateway.
- * Normally called as a result of a routing redirect
- * message from the network layer.
- */
-void
-rtredirect_fib(struct sockaddr *dst,
- struct sockaddr *gateway,
- struct sockaddr *netmask,
- int flags,
- struct sockaddr *src,
- u_int fibnum)
+static int
+verify_redirect_gateway(struct sockaddr *src, struct sockaddr *dst,
+ struct sockaddr *gateway, int flags, u_int fibnum)
{
struct rtentry *rt;
- int error = 0;
- struct rt_addrinfo info;
struct ifaddr *ifa;
- struct rib_head *rnh;
NET_EPOCH_ASSERT();
- ifa = NULL;
- rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
- if (rnh == NULL) {
- error = EAFNOSUPPORT;
- goto out;
- }
/* verify the gateway is directly reachable */
- if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL) {
- error = ENETUNREACH;
- goto out;
- }
- rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
+ if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL)
+ return (ENETUNREACH);
+
+ /* TODO: fib-aware */
+ if ((flags & RTF_GATEWAY) && ifa_ifwithaddr_check(gateway))
+ return (EHOSTUNREACH);
+
+ rt = rtalloc1_fib(dst, 0, 0UL, fibnum); /* NB: rt is locked */
+
/*
* If the redirect isn't from our current router for this dst,
* it's either old or wrong. If it redirects us to ourselves,
* we have a routing loop, perhaps as a result of an interface
* going down recently.
*/
- if (!(flags & RTF_DONE) && rt) {
+ if (rt != NULL) {
if (!sa_equal(src, rt->rt_gateway)) {
- error = EINVAL;
- goto done;
+ RTFREE(rt);
+ return (EINVAL);
}
if (rt->rt_ifa != ifa && ifa->ifa_addr->sa_family != AF_LINK) {
- error = EINVAL;
- goto done;
+ RTFREE(rt);
+ return (EINVAL);
}
}
- if ((flags & RTF_GATEWAY) && ifa_ifwithaddr_check(gateway)) {
- error = EHOSTUNREACH;
- goto done;
+
+ /* If host route already exists, ignore redirect. */
+ if (rt != NULL && (rt->rt_flags & RTF_HOST)) {
+ RTFREE(rt);
+ return (EEXIST);
}
- /*
- * Create a new entry if we just got back a wildcard entry
- * or the lookup failed. This is necessary for hosts
- * which use routing redirects generated by smart gateways
- * to dynamically build the routing tables.
- */
- if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
- goto create;
- /*
- * Don't listen to the redirect if it's
- * for a route to an interface.
- */
- if (rt->rt_flags & RTF_GATEWAY) {
- if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
- /*
- * Changing from route to net => route to host.
- * Create new route, rather than smashing route to net.
- */
- create:
- if (rt != NULL)
- RTFREE_LOCKED(rt);
-
- flags |= RTF_DYNAMIC;
- bzero((caddr_t)&info, sizeof(info));
- info.rti_info[RTAX_DST] = dst;
- info.rti_info[RTAX_GATEWAY] = gateway;
- info.rti_info[RTAX_NETMASK] = netmask;
- ifa_ref(ifa);
- info.rti_ifa = ifa;
- info.rti_flags = flags;
- error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
- if (rt != NULL) {
- RT_LOCK(rt);
- flags = rt->rt_flags;
- }
- if (error == 0)
- RTSTAT_INC(rts_dynamic);
- } else {
- /*
- * Smash the current notion of the gateway to
- * this destination. Should check about netmask!!!
- */
- if ((flags & RTF_GATEWAY) == 0)
- rt->rt_flags &= ~RTF_GATEWAY;
- rt->rt_flags |= RTF_MODIFIED;
- flags |= RTF_MODIFIED;
- RTSTAT_INC(rts_newgateway);
- /*
- * add the key and gateway (in one malloc'd chunk).
- */
- RT_UNLOCK(rt);
- RIB_WLOCK(rnh);
- RT_LOCK(rt);
- rt_setgate(rt, rt_key(rt), gateway);
- RIB_WUNLOCK(rnh);
- }
- } else
- error = EHOSTUNREACH;
-done:
- if (rt)
- RTFREE_LOCKED(rt);
- out:
- if (error)
+ /* If the prefix is directly reachable, ignore redirect */
+ if (rt != NULL && !(rt->rt_flags & RTF_GATEWAY)) {
+ RTFREE(rt);
+ return (EEXIST);
+ }
+
+ RTFREE(rt);
+ return (0);
+}
+
+
+/*
+ * Force a routing table entry to the specified
+ * destination to go through the given gateway.
+ * Normally called as a result of a routing redirect
+ * message from the network layer.
+ */
+int
+rtredirect_fib(struct sockaddr *dst, struct sockaddr *gateway,
+ int flags, struct sockaddr *src, int expire_sec, u_int fibnum)
+{
+ struct rtentry *rt;
+ int error = 0;
+ struct rt_addrinfo info;
+ struct rt_metrics rti_rmx;
+ struct ifaddr *ifa;
+
+ NET_EPOCH_ASSERT();
+
+ if (rt_tables_get_rnh(fibnum, dst->sa_family) == NULL)
+ return (error);
+
+ error = verify_redirect_gateway(src, dst, gateway, flags, fibnum);
+ if (error != 0)
+ return (error);
+
+ /* verify the gateway is directly reachable */
+ if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL)
+ return (ENETUNREACH);
+ ifa_ref(ifa);
+
+ flags |= RTF_DYNAMIC;
+
+ bzero(&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_GATEWAY] = gateway;
+ info.rti_ifa = ifa;
+ info.rti_flags = flags;
+
+ /* Setup route metrics to define expire time */
+ bzero(&rti_rmx, sizeof(rti_rmx));
+ /* Define expire time as absolute */
+ rti_rmx.rmx_expire = expire_sec + time_second;
+ info.rti_mflags |= RTV_EXPIRE;
+ info.rti_rmx = &rti_rmx;
+
+ error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
+ ifa_free(ifa);
+
+ if (error != 0) {
RTSTAT_INC(rts_badredirect);
- bzero((caddr_t)&info, sizeof(info));
+ return (error);
+ }
+
+ RT_LOCK(rt);
+ flags = rt->rt_flags;
+ RTFREE_LOCKED(rt);
+
+ RTSTAT_INC(rts_dynamic);
+
+ bzero(&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
info.rti_info[RTAX_GATEWAY] = gateway;
- info.rti_info[RTAX_NETMASK] = netmask;
info.rti_info[RTAX_AUTHOR] = src;
rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum);
+
+ return (0);
}
/*
@@ -1052,6 +1059,56 @@
}
/*
+ * Iterates over rtable specified by @fibnum and @af and deletes elements
+ * marked by @filter_f.
+ * @fibnum: rtable id
+ * @family: AF_ address family
+ * @filter_f: lambda function returning non-zero value for items to delete
+ * @arg: data to pass to the @filter_f
+ * @report: true if rtsock notification is needed.
+ */
+void
+rib_walk_del(u_int fibnum, int family, rt_filter_f_t *filter_f, void *arg, int report)
+{
+ struct rib_head *rnh;
+ struct rt_delinfo di;
+ struct rtentry *rt;
+
+ rnh = rt_tables_get_rnh(fibnum, family);
+ if (rnh == NULL)
+ return;
+
+ bzero(&di, sizeof(di));
+ di.info.rti_filter = filter_f;
+ di.info.rti_filterdata = arg;
+ di.rnh = rnh;
+
+ RIB_WLOCK(rnh);
+ rnh->rnh_walktree(&rnh->head, rt_checkdelroute, &di);
+ RIB_WUNLOCK(rnh);
+
+ if (di.head == NULL)
+ return;
+
+ /* 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);
+
+ if (report)
+ rt_routemsg(RTM_DELETE, rt->rt_ifp, 0, rt, fibnum);
+ RTFREE_LOCKED(rt);
+ }
+}
+
+/*
* Iterates over all existing fibs in system.
* Deletes each element for which @filter_f function returned
* non-zero value.
@@ -1061,16 +1118,9 @@
void
rt_foreach_fib_walk_del(int af, rt_filter_f_t *filter_f, void *arg)
{
- struct rib_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) {
@@ -1082,32 +1132,10 @@
}
for (i = start; i <= end; i++) {
- rnh = rt_tables_get_rnh(fibnum, i);
- if (rnh == NULL)
+ if (rt_tables_get_rnh(fibnum, i) == NULL)
continue;
- di.rnh = rnh;
- RIB_WLOCK(rnh);
- rnh->rnh_walktree(&rnh->head, rt_checkdelroute, &di);
- RIB_WUNLOCK(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);
- }
-
+ rib_walk_del(fibnum, i, filter_f, arg, 0);
}
}
}
@@ -1692,6 +1720,9 @@
/* XXX mtu manipulation will be done in rnh_addaddr -- itojun */
rn = rnh->rnh_addaddr(ndst, netmask, &rnh->head, rt->rt_nodes);
+
+ if (rn != NULL && rt->rt_expire > 0)
+ tmproutes_update(rnh, rt);
rt_old = NULL;
if (rn == NULL && (info->rti_flags & RTF_PINNED) != 0) {
Index: sys/net/route_var.h
===================================================================
--- sys/net/route_var.h
+++ sys/net/route_var.h
@@ -46,6 +46,11 @@
struct radix_node rnh_nodes[3]; /* empty tree for common case */
struct rmlock rib_lock; /* config/data path lock */
struct radix_mask_head rmhead; /* masks radix head */
+ struct vnet *rib_vnet; /* vnet pointer */
+ int rib_family; /* AF of the rtable */
+ u_int rib_fibnum; /* tableid */
+ struct callout expire_callout; /* Callout for expiring dynamic routes */
+ time_t next_expire; /* Next expire run ts */
};
#define RIB_RLOCK_TRACKER struct rm_priotracker _rib_tracker
@@ -76,5 +81,8 @@
return (res);
}
+void tmproutes_update(struct rib_head *rnh, struct rtentry *rt);
+void tmproutes_init(struct rib_head *rh);
+void tmproutes_destroy(struct rib_head *rh);
#endif
Index: sys/netinet/in_proto.c
===================================================================
--- sys/netinet/in_proto.c
+++ sys/netinet/in_proto.c
@@ -297,7 +297,7 @@
},
};
-extern int in_inithead(void **, int);
+extern int in_inithead(void **, int, u_int);
extern int in_detachhead(void **, int);
struct domain inetdomain = {
Index: sys/netinet/in_rmx.c
===================================================================
--- sys/netinet/in_rmx.c
+++ sys/netinet/in_rmx.c
@@ -49,7 +49,7 @@
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
-extern int in_inithead(void **head, int off);
+extern int in_inithead(void **head, int off, u_int fibnum);
#ifdef VIMAGE
extern int in_detachhead(void **head, int off);
#endif
@@ -116,11 +116,11 @@
* Initialize our routing tree.
*/
int
-in_inithead(void **head, int off)
+in_inithead(void **head, int off, u_int fibnum)
{
struct rib_head *rh;
- rh = rt_table_init(32);
+ rh = rt_table_init(32, AF_INET, fibnum);
if (rh == NULL)
return (0);
@@ -197,14 +197,3 @@
rtalloc_ign_fib(ro, ignflags, fibnum);
}
-void
-in_rtredirect(struct sockaddr *dst,
- struct sockaddr *gateway,
- struct sockaddr *netmask,
- int flags,
- struct sockaddr *src,
- u_int fibnum)
-{
- rtredirect_fib(dst, gateway, netmask, flags, src, fibnum);
-}
-
Index: sys/netinet/in_var.h
===================================================================
--- sys/netinet/in_var.h
+++ sys/netinet/in_var.h
@@ -474,8 +474,6 @@
/* XXX */
void in_rtalloc_ign(struct route *ro, u_long ignflags, u_int fibnum);
-void in_rtredirect(struct sockaddr *, struct sockaddr *,
- struct sockaddr *, int, struct sockaddr *, u_int);
#endif /* _KERNEL */
/* INET6 stuff */
Index: sys/netinet/ip_icmp.c
===================================================================
--- sys/netinet/ip_icmp.c
+++ sys/netinet/ip_icmp.c
@@ -128,6 +128,12 @@
&VNET_NAME(log_redirect), 0,
"Log ICMP redirects to the console");
+VNET_DEFINE_STATIC(int, redirtimeout) = 60 * 10; /* 10 minutes */
+#define V_redirtimeout VNET(redirtimeout)
+SYSCTL_INT(_net_inet_icmp, OID_AUTO, redirtimeout, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(redirtimeout), 0,
+ "Delay in seconds before expiring redirect route");
+
VNET_DEFINE_STATIC(char, reply_src[IFNAMSIZ]);
#define V_reply_src VNET(reply_src)
SYSCTL_STRING(_net_inet_icmp, OID_AUTO, reply_src, CTLFLAG_VNET | CTLFLAG_RW,
@@ -690,10 +696,10 @@
#endif
icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
- in_rtredirect((struct sockaddr *)&icmpsrc,
+ rtredirect_fib((struct sockaddr *)&icmpsrc,
(struct sockaddr *)&icmpdst,
- (struct sockaddr *)0, RTF_GATEWAY | RTF_HOST,
- (struct sockaddr *)&icmpgw, fibnum);
+ RTF_GATEWAY | RTF_HOST, (struct sockaddr *)&icmpgw,
+ V_redirtimeout, fibnum);
}
pfctlinput(PRC_REDIRECT_HOST, (struct sockaddr *)&icmpsrc);
break;
Index: sys/netinet6/icmp6.c
===================================================================
--- sys/netinet6/icmp6.c
+++ sys/netinet6/icmp6.c
@@ -2387,9 +2387,9 @@
} else
gw = ifp->if_addr->ifa_addr;
for (fibnum = 0; fibnum < rt_numfibs; fibnum++)
- in6_rtredirect((struct sockaddr *)&sdst, gw,
- (struct sockaddr *)NULL, rt_flags,
- (struct sockaddr *)&ssrc, fibnum);
+ rtredirect_fib((struct sockaddr *)&sdst, gw,
+ rt_flags, (struct sockaddr *)&ssrc,
+ V_icmp6_redirtimeout, fibnum);
}
/* finally update cached route in each socket via pfctlinput */
{
Index: sys/netinet6/in6_proto.c
===================================================================
--- sys/netinet6/in6_proto.c
+++ sys/netinet6/in6_proto.c
@@ -336,7 +336,7 @@
},
};
-extern int in6_inithead(void **, int);
+extern int in6_inithead(void **, int, u_int);
#ifdef VIMAGE
extern int in6_detachhead(void **, int);
#endif
@@ -566,7 +566,7 @@
"Accept ICMPv6 redirect messages");
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRTIMEOUT, redirtimeout,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(icmp6_redirtimeout), 0,
- ""); /* XXX unused */
+ "Delay in seconds before expiring redirect route");
SYSCTL_VNET_PCPUSTAT(_net_inet6_icmp6, ICMPV6CTL_STATS, stats,
struct icmp6stat, icmp6stat,
"ICMPv6 statistics (struct icmp6stat, netinet/icmp6.h)");
Index: sys/netinet6/in6_rmx.c
===================================================================
--- sys/netinet6/in6_rmx.c
+++ sys/netinet6/in6_rmx.c
@@ -96,7 +96,7 @@
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
-extern int in6_inithead(void **head, int off);
+extern int in6_inithead(void **head, int off, u_int fibnum);
#ifdef VIMAGE
extern int in6_detachhead(void **head, int off);
#endif
@@ -157,11 +157,12 @@
*/
int
-in6_inithead(void **head, int off)
+in6_inithead(void **head, int off, u_int fibnum)
{
struct rib_head *rh;
- rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3);
+ rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3,
+ AF_INET6, fibnum);
if (rh == NULL)
return (0);
@@ -185,14 +186,6 @@
/*
* Extended API for IPv6 FIB support.
*/
-void
-in6_rtredirect(struct sockaddr *dst, struct sockaddr *gw, struct sockaddr *nm,
- int flags, struct sockaddr *src, u_int fibnum)
-{
-
- rtredirect_fib(dst, gw, nm, flags, src, fibnum);
-}
-
int
in6_rtrequest(int req, struct sockaddr *dst, struct sockaddr *gw,
struct sockaddr *mask, int flags, struct rtentry **ret_nrt, u_int fibnum)
Index: sys/netinet6/in6_var.h
===================================================================
--- sys/netinet6/in6_var.h
+++ sys/netinet6/in6_var.h
@@ -917,8 +917,6 @@
* Extended API for IPv6 FIB support.
*/
struct mbuf *ip6_tryforward(struct mbuf *);
-void in6_rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *,
- int, struct sockaddr *, u_int);
int in6_rtrequest(int, struct sockaddr *, struct sockaddr *,
struct sockaddr *, int, struct rtentry **, u_int);
void in6_rtalloc(struct route_in6 *, u_int);
Index: sys/sys/domain.h
===================================================================
--- sys/sys/domain.h
+++ sys/sys/domain.h
@@ -60,7 +60,7 @@
struct protosw *dom_protosw, *dom_protoswNPROTOSW;
struct domain *dom_next;
int (*dom_rtattach) /* initialize routing table */
- (void **, int);
+ (void **, int, u_int);
int (*dom_rtdetach) /* clean up routing table */
(void **, int);
void *(*dom_ifattach)(struct ifnet *);
Index: usr.bin/netstat/route.c
===================================================================
--- usr.bin/netstat/route.c
+++ usr.bin/netstat/route.c
@@ -104,7 +104,7 @@
};
static struct ifmap_entry *ifmap;
static int ifmap_size;
-static struct timespec uptime;
+static struct timeval curr_time;
static const char *netname4(in_addr_t, in_addr_t);
#ifdef INET6
@@ -142,12 +142,11 @@
if (fibnum < 0 || fibnum > numfibs - 1)
errx(EX_USAGE, "%d: invalid fib", fibnum);
/*
- * Since kernel & userland use different timebase
- * (time_uptime vs time_second) and we are reading kernel memory
- * directly we should do rt_expire --> expire_time conversion.
+ * Kernel returns route expiration time as absolute time,
+ * cache current time to fasten conversion.
*/
- if (clock_gettime(CLOCK_UPTIME, &uptime) < 0)
- err(EX_OSERR, "clock_gettime() failed");
+ if (gettimeofday(&curr_time, NULL) < 0)
+ err(EX_OSERR, "gettimeofday() failed");
xo_open_container("route-information");
xo_emit("{T:Routing tables}");
@@ -401,7 +400,7 @@
if (rtm->rtm_rmx.rmx_expire) {
time_t expire_time;
- if ((expire_time = rtm->rtm_rmx.rmx_expire - uptime.tv_sec) > 0)
+ if ((expire_time = rtm->rtm_rmx.rmx_expire - curr_time.tv_sec) > 0)
xo_emit(" {:expire-time/%*d}", wid_expire,
(int)expire_time);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 12, 4:58 AM (18 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15761452
Default Alt Text
D22988.id66207.diff (22 KB)
Attached To
Mode
D22988: Bring back redirect route expiration.
Attached
Detach File
Event Timeline
Log In to Comment