diff options
author | Julian Anastasov <ja@ssi.bg> | 2010-10-17 09:21:07 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2010-10-21 04:50:20 -0400 |
commit | cf356d69db0afef692cd640917bc70f708c27f14 (patch) | |
tree | 1c1e0a277ba783066e639524bbdef0c19996e8c0 | |
parent | 8b27b10f5863a5b63e46304a71aa01463d1efac4 (diff) |
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: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | include/net/ip_vs.h | 20 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 39 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_xmit.c | 7 |
3 files changed, 28 insertions, 38 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index adcdba9dd183..0e4618470cee 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
26 | #include <linux/ipv6.h> /* for struct ipv6hdr */ | 26 | #include <linux/ipv6.h> /* for struct ipv6hdr */ |
27 | #include <net/ipv6.h> /* for ipv6_addr_copy */ | 27 | #include <net/ipv6.h> /* for ipv6_addr_copy */ |
28 | #ifdef CONFIG_IP_VS_NFCT | 28 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
29 | #include <net/netfilter/nf_conntrack.h> | 29 | #include <net/netfilter/nf_conntrack.h> |
30 | #endif | 30 | #endif |
31 | 31 | ||
@@ -1021,6 +1021,24 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) | |||
1021 | return csum_partial(diff, sizeof(diff), oldsum); | 1021 | return csum_partial(diff, sizeof(diff), oldsum); |
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | /* | ||
1025 | * Forget current conntrack (unconfirmed) and attach notrack entry | ||
1026 | */ | ||
1027 | static inline void ip_vs_notrack(struct sk_buff *skb) | ||
1028 | { | ||
1029 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | ||
1030 | enum ip_conntrack_info ctinfo; | ||
1031 | struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); | ||
1032 | |||
1033 | if (!ct || !nf_ct_is_untracked(ct)) { | ||
1034 | nf_reset(skb); | ||
1035 | skb->nfct = &nf_ct_untracked_get()->ct_general; | ||
1036 | skb->nfctinfo = IP_CT_NEW; | ||
1037 | nf_conntrack_get(skb->nfct); | ||
1038 | } | ||
1039 | #endif | ||
1040 | } | ||
1041 | |||
1024 | #ifdef CONFIG_IP_VS_NFCT | 1042 | #ifdef CONFIG_IP_VS_NFCT |
1025 | /* | 1043 | /* |
1026 | * Netfilter connection tracking | 1044 | * Netfilter connection tracking |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index e5fef7aef0d4..222453029b9e 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -507,23 +507,6 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, | |||
507 | return NF_DROP; | 507 | return NF_DROP; |
508 | } | 508 | } |
509 | 509 | ||
510 | /* | ||
511 | * It is hooked before NF_IP_PRI_NAT_SRC at the NF_INET_POST_ROUTING | ||
512 | * chain and is used to avoid double NAT and confirmation when we do | ||
513 | * not want to keep the conntrack structure | ||
514 | */ | ||
515 | static unsigned int ip_vs_post_routing(unsigned int hooknum, | ||
516 | struct sk_buff *skb, | ||
517 | const struct net_device *in, | ||
518 | const struct net_device *out, | ||
519 | int (*okfn)(struct sk_buff *)) | ||
520 | { | ||
521 | if (!skb->ipvs_property) | ||
522 | return NF_ACCEPT; | ||
523 | /* The packet was sent from IPVS, exit this chain */ | ||
524 | return NF_STOP; | ||
525 | } | ||
526 | |||
527 | __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) | 510 | __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) |
528 | { | 511 | { |
529 | return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); | 512 | 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, | |||
682 | /* do the statistics and put it back */ | 665 | /* do the statistics and put it back */ |
683 | ip_vs_out_stats(cp, skb); | 666 | ip_vs_out_stats(cp, skb); |
684 | 667 | ||
668 | skb->ipvs_property = 1; | ||
685 | if (!(cp->flags & IP_VS_CONN_F_NFCT)) | 669 | if (!(cp->flags & IP_VS_CONN_F_NFCT)) |
686 | skb->ipvs_property = 1; | 670 | ip_vs_notrack(skb); |
687 | else | 671 | else |
688 | ip_vs_update_conntrack(skb, cp, 0); | 672 | ip_vs_update_conntrack(skb, cp, 0); |
689 | verdict = NF_ACCEPT; | 673 | verdict = NF_ACCEPT; |
@@ -929,8 +913,9 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, | |||
929 | 913 | ||
930 | ip_vs_out_stats(cp, skb); | 914 | ip_vs_out_stats(cp, skb); |
931 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); | 915 | ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); |
916 | skb->ipvs_property = 1; | ||
932 | if (!(cp->flags & IP_VS_CONN_F_NFCT)) | 917 | if (!(cp->flags & IP_VS_CONN_F_NFCT)) |
933 | skb->ipvs_property = 1; | 918 | ip_vs_notrack(skb); |
934 | else | 919 | else |
935 | ip_vs_update_conntrack(skb, cp, 0); | 920 | ip_vs_update_conntrack(skb, cp, 0); |
936 | ip_vs_conn_put(cp); | 921 | ip_vs_conn_put(cp); |
@@ -1496,14 +1481,6 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { | |||
1496 | .hooknum = NF_INET_FORWARD, | 1481 | .hooknum = NF_INET_FORWARD, |
1497 | .priority = 99, | 1482 | .priority = 99, |
1498 | }, | 1483 | }, |
1499 | /* Before the netfilter connection tracking, exit from POST_ROUTING */ | ||
1500 | { | ||
1501 | .hook = ip_vs_post_routing, | ||
1502 | .owner = THIS_MODULE, | ||
1503 | .pf = PF_INET, | ||
1504 | .hooknum = NF_INET_POST_ROUTING, | ||
1505 | .priority = NF_IP_PRI_NAT_SRC-1, | ||
1506 | }, | ||
1507 | #ifdef CONFIG_IP_VS_IPV6 | 1484 | #ifdef CONFIG_IP_VS_IPV6 |
1508 | /* After packet filtering, forward packet through VS/DR, VS/TUN, | 1485 | /* After packet filtering, forward packet through VS/DR, VS/TUN, |
1509 | * or VS/NAT(change destination), so that filtering rules can be | 1486 | * 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 = { | |||
1532 | .hooknum = NF_INET_FORWARD, | 1509 | .hooknum = NF_INET_FORWARD, |
1533 | .priority = 99, | 1510 | .priority = 99, |
1534 | }, | 1511 | }, |
1535 | /* Before the netfilter connection tracking, exit from POST_ROUTING */ | ||
1536 | { | ||
1537 | .hook = ip_vs_post_routing, | ||
1538 | .owner = THIS_MODULE, | ||
1539 | .pf = PF_INET6, | ||
1540 | .hooknum = NF_INET_POST_ROUTING, | ||
1541 | .priority = NF_IP6_PRI_NAT_SRC-1, | ||
1542 | }, | ||
1543 | #endif | 1512 | #endif |
1544 | }; | 1513 | }; |
1545 | 1514 | ||
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index b0bd8afbf368..94b53b441028 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -217,6 +217,7 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) | |||
217 | ({ \ | 217 | ({ \ |
218 | int __ret = NF_ACCEPT; \ | 218 | int __ret = NF_ACCEPT; \ |
219 | \ | 219 | \ |
220 | (skb)->ipvs_property = 1; \ | ||
220 | if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \ | 221 | if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \ |
221 | __ret = ip_vs_confirm_conntrack(skb, cp); \ | 222 | __ret = ip_vs_confirm_conntrack(skb, cp); \ |
222 | if (__ret == NF_ACCEPT) { \ | 223 | if (__ret == NF_ACCEPT) { \ |
@@ -228,8 +229,9 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) | |||
228 | 229 | ||
229 | #define IP_VS_XMIT_NAT(pf, skb, cp) \ | 230 | #define IP_VS_XMIT_NAT(pf, skb, cp) \ |
230 | do { \ | 231 | do { \ |
232 | (skb)->ipvs_property = 1; \ | ||
231 | if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ | 233 | if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ |
232 | (skb)->ipvs_property = 1; \ | 234 | ip_vs_notrack(skb); \ |
233 | else \ | 235 | else \ |
234 | ip_vs_update_conntrack(skb, cp, 1); \ | 236 | ip_vs_update_conntrack(skb, cp, 1); \ |
235 | skb_forward_csum(skb); \ | 237 | skb_forward_csum(skb); \ |
@@ -239,8 +241,9 @@ do { \ | |||
239 | 241 | ||
240 | #define IP_VS_XMIT(pf, skb, cp) \ | 242 | #define IP_VS_XMIT(pf, skb, cp) \ |
241 | do { \ | 243 | do { \ |
244 | (skb)->ipvs_property = 1; \ | ||
242 | if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ | 245 | if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ |
243 | (skb)->ipvs_property = 1; \ | 246 | ip_vs_notrack(skb); \ |
244 | skb_forward_csum(skb); \ | 247 | skb_forward_csum(skb); \ |
245 | NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ | 248 | NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ |
246 | skb_dst(skb)->dev, dst_output); \ | 249 | skb_dst(skb)->dev, dst_output); \ |