Author: melifaro
Date: Tue Nov  6 00:49:52 2012
New Revision: 242640
URL: http://svnweb.freebsd.org/changeset/base/242640

Log:
  MFC r241406.
  
  Do not check if found IPv4 rte is dynamic if net.inet.icmp.drop_redirect is
  enabled. This eliminates one mtx_lock() per each routing lookup thus improving
  performance in several cases (routing to directly connected interface or 
routing
  to default gateway).
  
  Icmp redirects should not be used to provide routing direction nowadays, even
  for end hosts. Routers should not use them too (and this is explicitly 
restricted
  in IPv6, see RFC 4861, clause 8.2).
  
  Current commit changes rnh_machaddr function to 'stock' rn_match (and back) 
for every
  AF_INET routing table in given VNET instance on drop_redirect sysctl change.
  
  This change is part of bigger patch eliminating rte locking.
  
  Sponsored by: Yandex LLC

Modified:
  stable/9/sys/netinet/in_rmx.c
  stable/9/sys/netinet/in_var.h
  stable/9/sys/netinet/ip_icmp.c
  stable/9/sys/netinet/ip_var.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/netinet/in_rmx.c
==============================================================================
--- stable/9/sys/netinet/in_rmx.c       Tue Nov  6 00:41:59 2012        
(r242639)
+++ stable/9/sys/netinet/in_rmx.c       Tue Nov  6 00:49:52 2012        
(r242640)
@@ -58,6 +58,8 @@ __FBSDID("$FreeBSD$");
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
 #include <netinet/ip_var.h>
 
 extern int     in_inithead(void **head, int off);
@@ -340,6 +342,13 @@ in_rtqdrain(void)
        VNET_LIST_RUNLOCK_NOSLEEP();
 }
 
+void
+in_setmatchfunc(struct radix_node_head *rnh, int val)
+{
+
+       rnh->rnh_matchaddr = (val != 0) ? rn_match : in_matroute;
+}
+
 static int _in_rt_was_here;
 /*
  * Initialize our routing tree.
@@ -365,7 +374,7 @@ in_inithead(void **head, int off)
 
        rnh = *head;
        rnh->rnh_addaddr = in_addroute;
-       rnh->rnh_matchaddr = in_matroute;
+       in_setmatchfunc(rnh, V_drop_redirect);
        rnh->rnh_close = in_clsroute;
        if (_in_rt_was_here == 0 ) {
                callout_init(&V_rtq_timer, CALLOUT_MPSAFE);

Modified: stable/9/sys/netinet/in_var.h
==============================================================================
--- stable/9/sys/netinet/in_var.h       Tue Nov  6 00:41:59 2012        
(r242639)
+++ stable/9/sys/netinet/in_var.h       Tue Nov  6 00:49:52 2012        
(r242640)
@@ -422,6 +422,7 @@ inm_acquire_locked(struct in_multi *inm)
 struct rtentry;
 struct route;
 struct ip_moptions;
+struct radix_node_head;
 
 int    imo_multi_filter(const struct ip_moptions *, const struct ifnet *,
            const struct sockaddr *, const struct sockaddr *);
@@ -460,6 +461,7 @@ void         in_rtredirect(struct sockaddr *, s
            struct sockaddr *, int, struct sockaddr *, u_int);
 int     in_rtrequest(int, struct sockaddr *,
            struct sockaddr *, struct sockaddr *, int, struct rtentry **, 
u_int);
+void   in_setmatchfunc(struct radix_node_head *, int);
 
 #if 0
 int     in_rt_getifa(struct rt_addrinfo *, u_int fibnum);

Modified: stable/9/sys/netinet/ip_icmp.c
==============================================================================
--- stable/9/sys/netinet/ip_icmp.c      Tue Nov  6 00:41:59 2012        
(r242639)
+++ stable/9/sys/netinet/ip_icmp.c      Tue Nov  6 00:49:52 2012        
(r242640)
@@ -108,11 +108,7 @@ SYSCTL_VNET_UINT(_net_inet_icmp, OID_AUT
        &VNET_NAME(icmpmaskfake), 0,
        "Fake reply to ICMP Address Mask Request packets.");
 
-static VNET_DEFINE(int, drop_redirect) = 0;
-#define        V_drop_redirect                 VNET(drop_redirect)
-SYSCTL_VNET_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_RW,
-       &VNET_NAME(drop_redirect), 0,
-       "Ignore ICMP redirects");
+VNET_DEFINE(int, drop_redirect) = 0;
 
 static VNET_DEFINE(int, log_redirect) = 0;
 #define        V_log_redirect                  VNET(log_redirect)
@@ -157,6 +153,39 @@ static void        icmp_send(struct mbuf *, str
 
 extern struct protosw inetsw[];
 
+static int
+sysctl_net_icmp_drop_redir(SYSCTL_HANDLER_ARGS)
+{
+       int error, new;
+       int i;
+       struct radix_node_head *rnh;
+
+       new = V_drop_redirect;
+       error = sysctl_handle_int(oidp, &new, 0, req);
+       if (error == 0 && req->newptr) {
+               new = (new != 0) ? 1 : 0;
+
+               if (new == V_drop_redirect)
+                       return (0);
+
+               for (i = 0; i < rt_numfibs; i++) {
+                       if ((rnh = rt_tables_get_rnh(i, AF_INET)) == NULL)
+                               continue;
+                       RADIX_NODE_HEAD_LOCK(rnh);
+                       in_setmatchfunc(rnh, new);
+                       RADIX_NODE_HEAD_UNLOCK(rnh);
+               }
+               
+               V_drop_redirect = new;
+       }
+
+       return (error);
+}
+
+SYSCTL_VNET_PROC(_net_inet_icmp, OID_AUTO, drop_redirect,
+    CTLTYPE_INT|CTLFLAG_RW, 0, 0,
+    sysctl_net_icmp_drop_redir, "I", "Ignore ICMP redirects");
+
 /*
  * Kernel module interface for updating icmpstat.  The argument is an index
  * into icmpstat treated as an array of u_long.  While this encodes the

Modified: stable/9/sys/netinet/ip_var.h
==============================================================================
--- stable/9/sys/netinet/ip_var.h       Tue Nov  6 00:41:59 2012        
(r242639)
+++ stable/9/sys/netinet/ip_var.h       Tue Nov  6 00:49:52 2012        
(r242640)
@@ -187,6 +187,7 @@ VNET_DECLARE(struct socket *, ip_mrouter
 extern int     (*legal_vif_num)(int);
 extern u_long  (*ip_mcast_src)(int);
 VNET_DECLARE(int, rsvp_on);
+VNET_DECLARE(int, drop_redirect);
 extern struct  pr_usrreqs rip_usrreqs;
 
 #define        V_ipstat                VNET(ipstat)
@@ -199,6 +200,7 @@ extern struct       pr_usrreqs rip_usrreqs;
 #define        V_ip_rsvpd              VNET(ip_rsvpd)
 #define        V_ip_mrouter            VNET(ip_mrouter)
 #define        V_rsvp_on               VNET(rsvp_on)
+#define        V_drop_redirect         VNET(drop_redirect)
 
 void   inp_freemoptions(struct ip_moptions *);
 int    inp_getmoptions(struct inpcb *, struct sockopt *);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to