aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2013-11-06 11:52:20 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-11 00:19:35 -0500
commit6aafeef03b9d9ecf255f3a80ed85ee070260e1ae (patch)
tree48c7f8ff1709c9874342c02c7039d4431a00b333 /include
parent9037c3579a277f3a23ba476664629fda8c35f7c4 (diff)
netfilter: push reasm skb through instead of original frag skbs
Pushing original fragments through causes several problems. For example for matching, frags may not be matched correctly. Take following example: <example> On HOSTA do: ip6tables -I INPUT -p icmpv6 -j DROP ip6tables -I INPUT -p icmpv6 -m icmp6 --icmpv6-type 128 -j ACCEPT and on HOSTB you do: ping6 HOSTA -s2000 (MTU is 1500) Incoming echo requests will be filtered out on HOSTA. This issue does not occur with smaller packets than MTU (where fragmentation does not happen) </example> As was discussed previously, the only correct solution seems to be to use reassembled skb instead of separete frags. Doing this has positive side effects in reducing sk_buff by one pointer (nfct_reasm) and also the reams dances in ipvs and conntrack can be removed. Future plan is to remove net/ipv6/netfilter/nf_conntrack_reasm.c entirely and use code in net/ipv6/reassembly.c instead. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/skbuff.h32
-rw-r--r--include/net/ip_vs.h32
-rw-r--r--include/net/netfilter/ipv6/nf_defrag_ipv6.h4
3 files changed, 2 insertions, 66 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 036ec7d8a83a..215b5ea1cb30 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -337,11 +337,6 @@ typedef unsigned int sk_buff_data_t;
337typedef unsigned char *sk_buff_data_t; 337typedef unsigned char *sk_buff_data_t;
338#endif 338#endif
339 339
340#if defined(CONFIG_NF_DEFRAG_IPV4) || defined(CONFIG_NF_DEFRAG_IPV4_MODULE) || \
341 defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
342#define NET_SKBUFF_NF_DEFRAG_NEEDED 1
343#endif
344
345/** 340/**
346 * struct sk_buff - socket buffer 341 * struct sk_buff - socket buffer
347 * @next: Next buffer in list 342 * @next: Next buffer in list
@@ -374,7 +369,6 @@ typedef unsigned char *sk_buff_data_t;
374 * @protocol: Packet protocol from driver 369 * @protocol: Packet protocol from driver
375 * @destructor: Destruct function 370 * @destructor: Destruct function
376 * @nfct: Associated connection, if any 371 * @nfct: Associated connection, if any
377 * @nfct_reasm: netfilter conntrack re-assembly pointer
378 * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c 372 * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
379 * @skb_iif: ifindex of device we arrived on 373 * @skb_iif: ifindex of device we arrived on
380 * @tc_index: Traffic control index 374 * @tc_index: Traffic control index
@@ -463,9 +457,6 @@ struct sk_buff {
463#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 457#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
464 struct nf_conntrack *nfct; 458 struct nf_conntrack *nfct;
465#endif 459#endif
466#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
467 struct sk_buff *nfct_reasm;
468#endif
469#ifdef CONFIG_BRIDGE_NETFILTER 460#ifdef CONFIG_BRIDGE_NETFILTER
470 struct nf_bridge_info *nf_bridge; 461 struct nf_bridge_info *nf_bridge;
471#endif 462#endif
@@ -2595,18 +2586,6 @@ static inline void nf_conntrack_get(struct nf_conntrack *nfct)
2595 atomic_inc(&nfct->use); 2586 atomic_inc(&nfct->use);
2596} 2587}
2597#endif 2588#endif
2598#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
2599static inline void nf_conntrack_get_reasm(struct sk_buff *skb)
2600{
2601 if (skb)
2602 atomic_inc(&skb->users);
2603}
2604static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
2605{
2606 if (skb)
2607 kfree_skb(skb);
2608}
2609#endif
2610#ifdef CONFIG_BRIDGE_NETFILTER 2589#ifdef CONFIG_BRIDGE_NETFILTER
2611static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) 2590static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
2612{ 2591{
@@ -2625,10 +2604,6 @@ static inline void nf_reset(struct sk_buff *skb)
2625 nf_conntrack_put(skb->nfct); 2604 nf_conntrack_put(skb->nfct);
2626 skb->nfct = NULL; 2605 skb->nfct = NULL;
2627#endif 2606#endif
2628#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
2629 nf_conntrack_put_reasm(skb->nfct_reasm);
2630 skb->nfct_reasm = NULL;
2631#endif
2632#ifdef CONFIG_BRIDGE_NETFILTER 2607#ifdef CONFIG_BRIDGE_NETFILTER
2633 nf_bridge_put(skb->nf_bridge); 2608 nf_bridge_put(skb->nf_bridge);
2634 skb->nf_bridge = NULL; 2609 skb->nf_bridge = NULL;
@@ -2650,10 +2625,6 @@ static inline void __nf_copy(struct sk_buff *dst, const struct sk_buff *src)
2650 nf_conntrack_get(src->nfct); 2625 nf_conntrack_get(src->nfct);
2651 dst->nfctinfo = src->nfctinfo; 2626 dst->nfctinfo = src->nfctinfo;
2652#endif 2627#endif
2653#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
2654 dst->nfct_reasm = src->nfct_reasm;
2655 nf_conntrack_get_reasm(src->nfct_reasm);
2656#endif
2657#ifdef CONFIG_BRIDGE_NETFILTER 2628#ifdef CONFIG_BRIDGE_NETFILTER
2658 dst->nf_bridge = src->nf_bridge; 2629 dst->nf_bridge = src->nf_bridge;
2659 nf_bridge_get(src->nf_bridge); 2630 nf_bridge_get(src->nf_bridge);
@@ -2665,9 +2636,6 @@ static inline void nf_copy(struct sk_buff *dst, const struct sk_buff *src)
2665#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 2636#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
2666 nf_conntrack_put(dst->nfct); 2637 nf_conntrack_put(dst->nfct);
2667#endif 2638#endif
2668#ifdef NET_SKBUFF_NF_DEFRAG_NEEDED
2669 nf_conntrack_put_reasm(dst->nfct_reasm);
2670#endif
2671#ifdef CONFIG_BRIDGE_NETFILTER 2639#ifdef CONFIG_BRIDGE_NETFILTER
2672 nf_bridge_put(dst->nf_bridge); 2640 nf_bridge_put(dst->nf_bridge);
2673#endif 2641#endif
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index cd7275f9c463..5679d927562b 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -109,7 +109,6 @@ extern int ip_vs_conn_tab_size;
109struct ip_vs_iphdr { 109struct ip_vs_iphdr {
110 __u32 len; /* IPv4 simply where L4 starts 110 __u32 len; /* IPv4 simply where L4 starts
111 IPv6 where L4 Transport Header starts */ 111 IPv6 where L4 Transport Header starts */
112 __u32 thoff_reasm; /* Transport Header Offset in nfct_reasm skb */
113 __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/ 112 __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/
114 __s16 protocol; 113 __s16 protocol;
115 __s32 flags; 114 __s32 flags;
@@ -117,34 +116,12 @@ struct ip_vs_iphdr {
117 union nf_inet_addr daddr; 116 union nf_inet_addr daddr;
118}; 117};
119 118
120/* Dependency to module: nf_defrag_ipv6 */
121#if defined(CONFIG_NF_DEFRAG_IPV6) || defined(CONFIG_NF_DEFRAG_IPV6_MODULE)
122static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
123{
124 return skb->nfct_reasm;
125}
126static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
127 int len, void *buffer,
128 const struct ip_vs_iphdr *ipvsh)
129{
130 if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb)))
131 return skb_header_pointer(skb_nfct_reasm(skb),
132 ipvsh->thoff_reasm, len, buffer);
133
134 return skb_header_pointer(skb, offset, len, buffer);
135}
136#else
137static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
138{
139 return NULL;
140}
141static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, 119static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
142 int len, void *buffer, 120 int len, void *buffer,
143 const struct ip_vs_iphdr *ipvsh) 121 const struct ip_vs_iphdr *ipvsh)
144{ 122{
145 return skb_header_pointer(skb, offset, len, buffer); 123 return skb_header_pointer(skb, offset, len, buffer);
146} 124}
147#endif
148 125
149static inline void 126static inline void
150ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr) 127ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr)
@@ -171,19 +148,12 @@ ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr)
171 (struct ipv6hdr *)skb_network_header(skb); 148 (struct ipv6hdr *)skb_network_header(skb);
172 iphdr->saddr.in6 = iph->saddr; 149 iphdr->saddr.in6 = iph->saddr;
173 iphdr->daddr.in6 = iph->daddr; 150 iphdr->daddr.in6 = iph->daddr;
174 /* ipv6_find_hdr() updates len, flags, thoff_reasm */ 151 /* ipv6_find_hdr() updates len, flags */
175 iphdr->thoff_reasm = 0;
176 iphdr->len = 0; 152 iphdr->len = 0;
177 iphdr->flags = 0; 153 iphdr->flags = 0;
178 iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1, 154 iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1,
179 &iphdr->fragoffs, 155 &iphdr->fragoffs,
180 &iphdr->flags); 156 &iphdr->flags);
181 /* get proto from re-assembled packet and it's offset */
182 if (skb_nfct_reasm(skb))
183 iphdr->protocol = ipv6_find_hdr(skb_nfct_reasm(skb),
184 &iphdr->thoff_reasm,
185 -1, NULL, NULL);
186
187 } else 157 } else
188#endif 158#endif
189 { 159 {
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
index 5613412e7dc2..27666d8a0bd0 100644
--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
@@ -6,9 +6,7 @@ void nf_defrag_ipv6_enable(void);
6int nf_ct_frag6_init(void); 6int nf_ct_frag6_init(void);
7void nf_ct_frag6_cleanup(void); 7void nf_ct_frag6_cleanup(void);
8struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user); 8struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
9void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, 9void nf_ct_frag6_consume_orig(struct sk_buff *skb);
10 struct net_device *in, struct net_device *out,
11 int (*okfn)(struct sk_buff *));
12 10
13struct inet_frags_ctl; 11struct inet_frags_ctl;
14 12