Hello list!

Currently there are some unnecessary code residing in netinet6/in6_rmx.c causing performance degradation for IPv6 forwarding.

Initially it was merged from netinet/in_rmx.c but it seems it is totally unused now due to different approach used in IPv6 redirects.

Code calls mtx_lock() on rte per each routing lookup in in6_matroute().
Initially I plan to make someting like r241406 for IPv6, but after some investigation I found that no one is currently setting RTF_DYNAMIC flag for IPv6 routes.

the question is: can we remove this entirely (patch attached) or we still needs some parts of this due to incomplete RFC 4861 implementation?




--
WBR, Alexander

Index: sys/netinet6/in6_rmx.c
===================================================================
--- sys/netinet6/in6_rmx.c      (revision 241408)
+++ sys/netinet6/in6_rmx.c      (working copy)
@@ -111,8 +111,6 @@ extern int  in6_inithead(void **head, int off);
 extern int     in6_detachhead(void **head, int off);
 #endif
 
-#define RTPRF_OURS             RTF_PROTO3      /* set on routes we manage */
-
 /*
  * Do what we need to do when inserting a route.
  */
@@ -183,42 +181,8 @@ in6_addroute(void *v_arg, void *n_arg, struct radi
        return (ret);
 }
 
-/*
- * This code is the inverse of in6_clsroute: on first reference, if we
- * were managing the route, stop doing so and set the expiration timer
- * back off again.
- */
-static struct radix_node *
-in6_matroute(void *v_arg, struct radix_node_head *head)
-{
-       struct radix_node *rn = rn_match(v_arg, head);
-       struct rtentry *rt = (struct rtentry *)rn;
-
-       if (rt) {
-               RT_LOCK(rt);
-               if (rt->rt_flags & RTPRF_OURS) {
-                       rt->rt_flags &= ~RTPRF_OURS;
-                       rt->rt_rmx.rmx_expire = 0;
-               }
-               RT_UNLOCK(rt);
-       }
-       return rn;
-}
-
 SYSCTL_DECL(_net_inet6_ip6);
 
-static VNET_DEFINE(int, rtq_reallyold6) = 60*60;
-       /* one hour is ``really old'' */
-#define        V_rtq_reallyold6                VNET(rtq_reallyold6)
-SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_RTEXPIRE, rtexpire, CTLFLAG_RW,
-    &VNET_NAME(rtq_reallyold6) , 0, "");
-
-static VNET_DEFINE(int, rtq_minreallyold6) = 10;
-       /* never automatically crank down to less */
-#define        V_rtq_minreallyold6             VNET(rtq_minreallyold6)
-SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_RTMINEXPIRE, rtminexpire, CTLFLAG_RW,
-    &VNET_NAME(rtq_minreallyold6) , 0, "");
-
 static VNET_DEFINE(int, rtq_toomany6) = 128;
        /* 128 cached routes is ``too many'' */
 #define        V_rtq_toomany6                  VNET(rtq_toomany6)
@@ -236,122 +200,6 @@ struct rtqk_arg {
 };
 
 /*
- * Get rid of old routes.  When draining, this deletes everything, even when
- * the timeout is not expired yet.  When updating, this makes sure that
- * nothing has a timeout longer than the current value of rtq_reallyold6.
- */
-static int
-in6_rtqkill(struct radix_node *rn, void *rock)
-{
-       struct rtqk_arg *ap = rock;
-       struct rtentry *rt = (struct rtentry *)rn;
-       int err;
-
-       RADIX_NODE_HEAD_WLOCK_ASSERT(ap->rnh);
-
-       if (rt->rt_flags & RTPRF_OURS) {
-               ap->found++;
-
-               if (ap->draining || rt->rt_rmx.rmx_expire <= time_uptime) {
-                       if (rt->rt_refcnt > 0)
-                               panic("rtqkill route really not free");
-
-                       err = in6_rtrequest(RTM_DELETE,
-                                       (struct sockaddr *)rt_key(rt),
-                                       rt->rt_gateway, rt_mask(rt),
-                                       rt->rt_flags|RTF_RNH_LOCKED, 0,
-                                       rt->rt_fibnum);
-                       if (err) {
-                               log(LOG_WARNING, "in6_rtqkill: error %d", err);
-                       } else {
-                               ap->killed++;
-                       }
-               } else {
-                       if (ap->updating
-                          && (rt->rt_rmx.rmx_expire - time_uptime
-                              > V_rtq_reallyold6)) {
-                               rt->rt_rmx.rmx_expire = time_uptime
-                                       + V_rtq_reallyold6;
-                       }
-                       ap->nextstop = lmin(ap->nextstop,
-                                           rt->rt_rmx.rmx_expire);
-               }
-       }
-
-       return 0;
-}
-
-#define RTQ_TIMEOUT    60*10   /* run no less than once every ten minutes */
-static VNET_DEFINE(int, rtq_timeout6) = RTQ_TIMEOUT;
-static VNET_DEFINE(struct callout, rtq_timer6);
-
-#define        V_rtq_timeout6                  VNET(rtq_timeout6)
-#define        V_rtq_timer6                    VNET(rtq_timer6)
-
-static void
-in6_rtqtimo_one(struct radix_node_head *rnh)
-{
-       struct rtqk_arg arg;
-       static time_t last_adjusted_timeout = 0;
-
-       arg.found = arg.killed = 0;
-       arg.rnh = rnh;
-       arg.nextstop = time_uptime + V_rtq_timeout6;
-       arg.draining = arg.updating = 0;
-       RADIX_NODE_HEAD_LOCK(rnh);
-       rnh->rnh_walktree(rnh, in6_rtqkill, &arg);
-       RADIX_NODE_HEAD_UNLOCK(rnh);
-
-       /*
-        * Attempt to be somewhat dynamic about this:
-        * If there are ``too many'' routes sitting around taking up space,
-        * then crank down the timeout, and see if we can't make some more
-        * go away.  However, we make sure that we will never adjust more
-        * than once in rtq_timeout6 seconds, to keep from cranking down too
-        * hard.
-        */
-       if ((arg.found - arg.killed > V_rtq_toomany6)
-          && (time_uptime - last_adjusted_timeout >= V_rtq_timeout6)
-          && V_rtq_reallyold6 > V_rtq_minreallyold6) {
-               V_rtq_reallyold6 = 2*V_rtq_reallyold6 / 3;
-               if (V_rtq_reallyold6 < V_rtq_minreallyold6) {
-                       V_rtq_reallyold6 = V_rtq_minreallyold6;
-               }
-
-               last_adjusted_timeout = time_uptime;
-#ifdef DIAGNOSTIC
-               log(LOG_DEBUG, "in6_rtqtimo: adjusted rtq_reallyold6 to %d",
-                   V_rtq_reallyold6);
-#endif
-               arg.found = arg.killed = 0;
-               arg.updating = 1;
-               RADIX_NODE_HEAD_LOCK(rnh);
-               rnh->rnh_walktree(rnh, in6_rtqkill, &arg);
-               RADIX_NODE_HEAD_UNLOCK(rnh);
-       }
-}
-
-static void
-in6_rtqtimo(void *rock)
-{
-       CURVNET_SET_QUIET((struct vnet *) rock);
-       struct radix_node_head *rnh;
-       struct timeval atv;
-       u_int fibnum;
-
-       for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
-               rnh = rt_tables_get_rnh(fibnum, AF_INET6);
-               if (rnh != NULL)
-                       in6_rtqtimo_one(rnh);
-       }
-
-       atv.tv_usec = 0;
-       atv.tv_sec = V_rtq_timeout6;
-       callout_reset(&V_rtq_timer6, tvtohz(&atv), in6_rtqtimo, rock);
-       CURVNET_RESTORE();
-}
-
-/*
  * Age old PMTUs.
  */
 struct mtuex_arg {
@@ -440,12 +288,9 @@ in6_inithead(void **head, int off)
 
        rnh = *head;
        rnh->rnh_addaddr = in6_addroute;
-       rnh->rnh_matchaddr = in6_matroute;
 
        if (V__in6_rt_was_here == 0) {
-               callout_init(&V_rtq_timer6, CALLOUT_MPSAFE);
                callout_init(&V_rtq_mtutimer, CALLOUT_MPSAFE);
-               in6_rtqtimo(curvnet);   /* kick off timeout first time */
                in6_mtutimo(curvnet);   /* kick off timeout first time */
                V__in6_rt_was_here = 1;
        }
@@ -458,7 +303,6 @@ int
 in6_detachhead(void **head, int off)
 {
 
-       callout_drain(&V_rtq_timer6);
        callout_drain(&V_rtq_mtutimer);
        return (1);
 }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[email protected]"

Reply via email to