lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 20 Jan 2019 14:12:04 +0200 (EET)
From:   Julian Anastasov <ja@....bg>
To:     Matteo Croce <mcroce@...hat.com>
cc:     lvs-devel@...r.kernel.org, netdev@...r.kernel.org,
        netfilter-devel@...r.kernel.org, coreteam@...filter.org,
        Wensong Zhang <wensong@...ux-vs.org>,
        Simon Horman <horms@...ge.net.au>,
        Paolo Abeni <pabeni@...hat.com>
Subject: Re: [PATCH ipvs-next] ipvs: use indirect call wrappers


	Hello,

On Sat, 19 Jan 2019, Matteo Croce wrote:

> Use the new indirect call wrappers in IPVS when calling the TCP or UDP
> protocol specific functions.
> This avoids an indirect calls in IPVS, and reduces the performance
> impact of the Spectre mitigation.
> 
> Signed-off-by: Matteo Croce <mcroce@...hat.com>

	Looks good to me, thanks!

Acked-by: Julian Anastasov <ja@....bg>

> ---
>  net/netfilter/ipvs/ip_vs_core.c      | 49 +++++++++++++++++++++++-----
>  net/netfilter/ipvs/ip_vs_proto_tcp.c |  3 +-
>  net/netfilter/ipvs/ip_vs_proto_udp.c |  3 +-
>  3 files changed, 45 insertions(+), 10 deletions(-)
> 
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index fe9abf3cc10a..e969dad66991 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -53,6 +53,7 @@
>  #endif
>  
>  #include <net/ip_vs.h>
> +#include <linux/indirect_call_wrapper.h>
>  
>  
>  EXPORT_SYMBOL(register_ip_vs_scheduler);
> @@ -70,6 +71,29 @@ EXPORT_SYMBOL(ip_vs_get_debug_level);
>  #endif
>  EXPORT_SYMBOL(ip_vs_new_conn_out);
>  
> +#ifdef CONFIG_IP_VS_PROTO_TCP
> +INDIRECT_CALLABLE_DECLARE(int
> +	tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
> +			 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph));
> +#endif
> +
> +#ifdef CONFIG_IP_VS_PROTO_UDP
> +INDIRECT_CALLABLE_DECLARE(int
> +	udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
> +			 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph));
> +#endif
> +
> +#if defined(CONFIG_IP_VS_PROTO_TCP) && defined(CONFIG_IP_VS_PROTO_UDP)
> +#define SNAT_CALL(f, ...) \
> +	INDIRECT_CALL_2(f, tcp_snat_handler, udp_snat_handler, __VA_ARGS__)
> +#elif defined(CONFIG_IP_VS_PROTO_TCP)
> +#define SNAT_CALL(f, ...) INDIRECT_CALL_1(f, tcp_snat_handler, __VA_ARGS__)
> +#elif defined(CONFIG_IP_VS_PROTO_UDP)
> +#define SNAT_CALL(f, ...) INDIRECT_CALL_1(f, udp_snat_handler, __VA_ARGS__)
> +#else
> +#define SNAT_CALL(f, ...) f(__VA_ARGS__)
> +#endif
> +
>  static unsigned int ip_vs_net_id __read_mostly;
>  /* netns cnt used for uniqueness */
>  static atomic_t ipvs_netns_cnt = ATOMIC_INIT(0);
> @@ -478,7 +502,9 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
>  	 */
>  	if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK)) {
>  		iph->hdr_flags ^= IP_VS_HDR_INVERSE;
> -		cp = pp->conn_in_get(svc->ipvs, svc->af, skb, iph);
> +		cp = INDIRECT_CALL_1(pp->conn_in_get,
> +				     ip_vs_conn_in_get_proto, svc->ipvs,
> +				     svc->af, skb, iph);
>  		iph->hdr_flags ^= IP_VS_HDR_INVERSE;
>  
>  		if (cp) {
> @@ -972,7 +998,8 @@ static int ip_vs_out_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb,
>  	ip_vs_fill_iph_skb_icmp(AF_INET, skb, offset, true, &ciph);
>  
>  	/* The embedded headers contain source and dest in reverse order */
> -	cp = pp->conn_out_get(ipvs, AF_INET, skb, &ciph);
> +	cp = INDIRECT_CALL_1(pp->conn_out_get, ip_vs_conn_out_get_proto,
> +			     ipvs, AF_INET, skb, &ciph);
>  	if (!cp)
>  		return NF_ACCEPT;
>  
> @@ -1028,7 +1055,8 @@ static int ip_vs_out_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
>  		return NF_ACCEPT;
>  
>  	/* The embedded headers contain source and dest in reverse order */
> -	cp = pp->conn_out_get(ipvs, AF_INET6, skb, &ciph);
> +	cp = INDIRECT_CALL_1(pp->conn_out_get, ip_vs_conn_out_get_proto,
> +			     ipvs, AF_INET6, skb, &ciph);
>  	if (!cp)
>  		return NF_ACCEPT;
>  
> @@ -1263,7 +1291,8 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
>  		goto drop;
>  
>  	/* mangle the packet */
> -	if (pp->snat_handler && !pp->snat_handler(skb, pp, cp, iph))
> +	if (pp->snat_handler &&
> +	    !SNAT_CALL(pp->snat_handler, skb, pp, cp, iph))
>  		goto drop;
>  
>  #ifdef CONFIG_IP_VS_IPV6
> @@ -1389,7 +1418,8 @@ ip_vs_out(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, in
>  	/*
>  	 * Check if the packet belongs to an existing entry
>  	 */
> -	cp = pp->conn_out_get(ipvs, af, skb, &iph);
> +	cp = INDIRECT_CALL_1(pp->conn_out_get, ip_vs_conn_out_get_proto,
> +			     ipvs, af, skb, &iph);
>  
>  	if (likely(cp)) {
>  		if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)
> @@ -1644,7 +1674,8 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
>  	/* The embedded headers contain source and dest in reverse order.
>  	 * For IPIP this is error for request, not for reply.
>  	 */
> -	cp = pp->conn_in_get(ipvs, AF_INET, skb, &ciph);
> +	cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto,
> +			     ipvs, AF_INET, skb, &ciph);
>  
>  	if (!cp) {
>  		int v;
> @@ -1796,7 +1827,8 @@ static int ip_vs_in_icmp_v6(struct netns_ipvs *ipvs, struct sk_buff *skb,
>  	/* The embedded headers contain source and dest in reverse order
>  	 * if not from localhost
>  	 */
> -	cp = pp->conn_in_get(ipvs, AF_INET6, skb, &ciph);
> +	cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto,
> +			     ipvs, AF_INET6, skb, &ciph);
>  
>  	if (!cp) {
>  		int v;
> @@ -1925,7 +1957,8 @@ ip_vs_in(struct netns_ipvs *ipvs, unsigned int hooknum, struct sk_buff *skb, int
>  	/*
>  	 * Check if the packet belongs to an existing connection entry
>  	 */
> -	cp = pp->conn_in_get(ipvs, af, skb, &iph);
> +	cp = INDIRECT_CALL_1(pp->conn_in_get, ip_vs_conn_in_get_proto,
> +			     ipvs, af, skb, &iph);
>  
>  	conn_reuse_mode = sysctl_conn_reuse_mode(ipvs);
>  	if (conn_reuse_mode && !iph.fragoffs && is_new_conn(skb, &iph) && cp) {
> diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
> index 6a275f989085..479419759983 100644
> --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
> +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
> @@ -28,6 +28,7 @@
>  #include <net/ip6_checksum.h>
>  #include <linux/netfilter.h>
>  #include <linux/netfilter_ipv4.h>
> +#include <linux/indirect_call_wrapper.h>
>  
>  #include <net/ip_vs.h>
>  
> @@ -146,7 +147,7 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph,
>  }
>  
>  
> -static int
> +INDIRECT_CALLABLE_SCOPE int
>  tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
>  		 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
>  {
> diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
> index 3285718264d5..646c384910fb 100644
> --- a/net/netfilter/ipvs/ip_vs_proto_udp.c
> +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
> @@ -23,6 +23,7 @@
>  #include <linux/netfilter.h>
>  #include <linux/netfilter_ipv4.h>
>  #include <linux/udp.h>
> +#include <linux/indirect_call_wrapper.h>
>  
>  #include <net/ip_vs.h>
>  #include <net/ip.h>
> @@ -136,7 +137,7 @@ udp_partial_csum_update(int af, struct udphdr *uhdr,
>  }
>  
>  
> -static int
> +INDIRECT_CALLABLE_SCOPE int
>  udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp,
>  		 struct ip_vs_conn *cp, struct ip_vs_iphdr *iph)
>  {
> -- 
> 2.20.1

Regards

--
Julian Anastasov <ja@....bg>

Powered by blists - more mailing lists