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
This commit is contained in:
parent
627995dcde
commit
3c2824b9ef
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241406
@ -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);
|
||||
|
@ -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 *, struct sockaddr *,
|
||||
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);
|
||||
|
@ -108,11 +108,7 @@ SYSCTL_VNET_UINT(_net_inet_icmp, OID_AUTO, maskfake, CTLFLAG_RW,
|
||||
&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 *, struct mbuf *);
|
||||
|
||||
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
|
||||
|
@ -188,6 +188,7 @@ VNET_DECLARE(struct socket *, ip_mrouter); /* multicast routing daemon */
|
||||
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 *);
|
||||
|
Loading…
Reference in New Issue
Block a user