Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf356d69 authored by Julian Anastasov's avatar Julian Anastasov Committed by Simon Horman
Browse files

ipvs: switch to notrack mode



 	Change skb->ipvs_property semantic. This is preparation
to support ip_vs_out processing in LOCAL_OUT. ipvs_property=1
will be used to avoid expensive lookups for traffic sent by
transmitters. Now when conntrack support is not used we call
ip_vs_notrack method to avoid problems in OUTPUT and
POST_ROUTING hooks instead of exiting POST_ROUTING as before.

Signed-off-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 8b27b10f
Loading
Loading
Loading
Loading
+19 −1
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/ipv6.h>			/* for struct ipv6hdr */
#include <linux/ipv6.h>			/* for struct ipv6hdr */
#include <net/ipv6.h>			/* for ipv6_addr_copy */
#include <net/ipv6.h>			/* for ipv6_addr_copy */
#ifdef CONFIG_IP_VS_NFCT
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack.h>
#endif
#endif


@@ -1021,6 +1021,24 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
	return csum_partial(diff, sizeof(diff), oldsum);
	return csum_partial(diff, sizeof(diff), oldsum);
}
}


/*
 * Forget current conntrack (unconfirmed) and attach notrack entry
 */
static inline void ip_vs_notrack(struct sk_buff *skb)
{
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
	enum ip_conntrack_info ctinfo;
	struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);

	if (!ct || !nf_ct_is_untracked(ct)) {
		nf_reset(skb);
		skb->nfct = &nf_ct_untracked_get()->ct_general;
		skb->nfctinfo = IP_CT_NEW;
		nf_conntrack_get(skb->nfct);
	}
#endif
}

#ifdef CONFIG_IP_VS_NFCT
#ifdef CONFIG_IP_VS_NFCT
/*
/*
 *      Netfilter connection tracking
 *      Netfilter connection tracking
+4 −35
Original line number Original line Diff line number Diff line
@@ -507,23 +507,6 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
	return NF_DROP;
	return NF_DROP;
}
}


/*
 * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING
 * chain and is used to avoid double NAT and confirmation when we do
 * not want to keep the conntrack structure
 */
static unsigned int ip_vs_post_routing(unsigned int hooknum,
				       struct sk_buff *skb,
				       const struct net_device *in,
				       const struct net_device *out,
				       int (*okfn)(struct sk_buff *))
{
	if (!skb->ipvs_property)
		return NF_ACCEPT;
	/* The packet was sent from IPVS, exit this chain */
	return NF_STOP;
}

__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
{
{
	return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
	return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
@@ -682,8 +665,9 @@ static int handle_response_icmp(int af, struct sk_buff *skb,
	/* do the statistics and put it back */
	/* do the statistics and put it back */
	ip_vs_out_stats(cp, skb);
	ip_vs_out_stats(cp, skb);


	if (!(cp->flags & IP_VS_CONN_F_NFCT))
	skb->ipvs_property = 1;
	skb->ipvs_property = 1;
	if (!(cp->flags & IP_VS_CONN_F_NFCT))
		ip_vs_notrack(skb);
	else
	else
		ip_vs_update_conntrack(skb, cp, 0);
		ip_vs_update_conntrack(skb, cp, 0);
	verdict = NF_ACCEPT;
	verdict = NF_ACCEPT;
@@ -929,8 +913,9 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,


	ip_vs_out_stats(cp, skb);
	ip_vs_out_stats(cp, skb);
	ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
	ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
	if (!(cp->flags & IP_VS_CONN_F_NFCT))
	skb->ipvs_property = 1;
	skb->ipvs_property = 1;
	if (!(cp->flags & IP_VS_CONN_F_NFCT))
		ip_vs_notrack(skb);
	else
	else
		ip_vs_update_conntrack(skb, cp, 0);
		ip_vs_update_conntrack(skb, cp, 0);
	ip_vs_conn_put(cp);
	ip_vs_conn_put(cp);
@@ -1496,14 +1481,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
		.hooknum        = NF_INET_FORWARD,
		.hooknum        = NF_INET_FORWARD,
		.priority       = 99,
		.priority       = 99,
	},
	},
	/* Before the netfilter connection tracking, exit from POST_ROUTING */
	{
		.hook		= ip_vs_post_routing,
		.owner		= THIS_MODULE,
		.pf		= PF_INET,
		.hooknum        = NF_INET_POST_ROUTING,
		.priority       = NF_IP_PRI_NAT_SRC-1,
	},
#ifdef CONFIG_IP_VS_IPV6
#ifdef CONFIG_IP_VS_IPV6
	/* After packet filtering, forward packet through VS/DR, VS/TUN,
	/* After packet filtering, forward packet through VS/DR, VS/TUN,
	 * or VS/NAT(change destination), so that filtering rules can be
	 * or VS/NAT(change destination), so that filtering rules can be
@@ -1532,14 +1509,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
		.hooknum        = NF_INET_FORWARD,
		.hooknum        = NF_INET_FORWARD,
		.priority       = 99,
		.priority       = 99,
	},
	},
	/* Before the netfilter connection tracking, exit from POST_ROUTING */
	{
		.hook		= ip_vs_post_routing,
		.owner		= THIS_MODULE,
		.pf		= PF_INET6,
		.hooknum        = NF_INET_POST_ROUTING,
		.priority       = NF_IP6_PRI_NAT_SRC-1,
	},
#endif
#endif
};
};


+5 −2
Original line number Original line Diff line number Diff line
@@ -217,6 +217,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
({								\
({								\
	int __ret = NF_ACCEPT;					\
	int __ret = NF_ACCEPT;					\
								\
								\
	(skb)->ipvs_property = 1;				\
	if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT))		\
	if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT))		\
		__ret = ip_vs_confirm_conntrack(skb, cp);	\
		__ret = ip_vs_confirm_conntrack(skb, cp);	\
	if (__ret == NF_ACCEPT) {				\
	if (__ret == NF_ACCEPT) {				\
@@ -228,8 +229,9 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)


#define IP_VS_XMIT_NAT(pf, skb, cp)				\
#define IP_VS_XMIT_NAT(pf, skb, cp)				\
do {							\
do {							\
	if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT)))	\
	(skb)->ipvs_property = 1;			\
	(skb)->ipvs_property = 1;			\
	if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT)))	\
		ip_vs_notrack(skb);			\
	else						\
	else						\
		ip_vs_update_conntrack(skb, cp, 1);	\
		ip_vs_update_conntrack(skb, cp, 1);	\
	skb_forward_csum(skb);				\
	skb_forward_csum(skb);				\
@@ -239,8 +241,9 @@ do { \


#define IP_VS_XMIT(pf, skb, cp)				\
#define IP_VS_XMIT(pf, skb, cp)				\
do {							\
do {							\
	if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT)))	\
	(skb)->ipvs_property = 1;			\
	(skb)->ipvs_property = 1;			\
	if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT)))	\
		ip_vs_notrack(skb);			\
	skb_forward_csum(skb);				\
	skb_forward_csum(skb);				\
	NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL,	\
	NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL,	\
		skb_dst(skb)->dev, dst_output);		\
		skb_dst(skb)->dev, dst_output);		\