#include <linux/ip.h>
#include <linux/ipv6.h> /* for struct ipv6hdr */
#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>
#endif
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
/*
* Netfilter connection tracking
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)
{
return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
/* do the statistics and put it back */
ip_vs_out_stats(cp, skb);
+ skb->ipvs_property = 1;
if (!(cp->flags & IP_VS_CONN_F_NFCT))
- skb->ipvs_property = 1;
+ ip_vs_notrack(skb);
else
ip_vs_update_conntrack(skb, cp, 0);
verdict = NF_ACCEPT;
ip_vs_out_stats(cp, skb);
ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
+ skb->ipvs_property = 1;
if (!(cp->flags & IP_VS_CONN_F_NFCT))
- skb->ipvs_property = 1;
+ ip_vs_notrack(skb);
else
ip_vs_update_conntrack(skb, cp, 0);
ip_vs_conn_put(cp);
.hooknum = NF_INET_FORWARD,
.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
/* After packet filtering, forward packet through VS/DR, VS/TUN,
* or VS/NAT(change destination), so that filtering rules can be
.hooknum = NF_INET_FORWARD,
.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
};
({ \
int __ret = NF_ACCEPT; \
\
+ (skb)->ipvs_property = 1; \
if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \
__ret = ip_vs_confirm_conntrack(skb, cp); \
if (__ret == NF_ACCEPT) { \
#define IP_VS_XMIT_NAT(pf, skb, cp) \
do { \
+ (skb)->ipvs_property = 1; \
if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
- (skb)->ipvs_property = 1; \
+ ip_vs_notrack(skb); \
else \
ip_vs_update_conntrack(skb, cp, 1); \
skb_forward_csum(skb); \
#define IP_VS_XMIT(pf, skb, cp) \
do { \
+ (skb)->ipvs_property = 1; \
if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \
- (skb)->ipvs_property = 1; \
+ ip_vs_notrack(skb); \
skb_forward_csum(skb); \
NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
skb_dst(skb)->dev, dst_output); \