svn commit: r241406 - head/sys/netinet

Alexander V. Chernikov melifaro at FreeBSD.org
Wed Oct 10 19:06:12 UTC 2012


Author: melifaro
Date: Wed Oct 10 19:06:11 2012
New Revision: 241406
URL: http://svn.freebsd.org/changeset/base/241406

Log:
  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
  MFC after:	2 weeks

Modified:
  head/sys/netinet/in_rmx.c
  head/sys/netinet/in_var.h
  head/sys/netinet/ip_icmp.c
  head/sys/netinet/ip_var.h

Modified: head/sys/netinet/in_rmx.c
==============================================================================
--- head/sys/netinet/in_rmx.c	Wed Oct 10 18:34:15 2012	(r241405)
+++ head/sys/netinet/in_rmx.c	Wed Oct 10 19:06:11 2012	(r241406)
@@ -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: head/sys/netinet/in_var.h
==============================================================================
--- head/sys/netinet/in_var.h	Wed Oct 10 18:34:15 2012	(r241405)
+++ head/sys/netinet/in_var.h	Wed Oct 10 19:06:11 2012	(r241406)
@@ -424,6 +424,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 *);
@@ -464,6 +465,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: head/sys/netinet/ip_icmp.c
==============================================================================
--- head/sys/netinet/ip_icmp.c	Wed Oct 10 18:34:15 2012	(r241405)
+++ head/sys/netinet/ip_icmp.c	Wed Oct 10 19:06:11 2012	(r241406)
@@ -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: head/sys/netinet/ip_var.h
==============================================================================
--- head/sys/netinet/ip_var.h	Wed Oct 10 18:34:15 2012	(r241405)
+++ head/sys/netinet/ip_var.h	Wed Oct 10 19:06:11 2012	(r241406)
@@ -188,6 +188,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)
@@ -200,6 +201,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 *);


More information about the svn-src-head mailing list