diff options
-rw-r--r-- | include/net/ip_vs.h | 1 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_app.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_core.c | 42 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_ftp.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_tcp.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_proto_udp.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_xmit.c | 4 |
7 files changed, 16 insertions, 51 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 672564e5a81d..5da3b4a40aa2 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -984,7 +984,6 @@ static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp) | |||
984 | return fwd; | 984 | return fwd; |
985 | } | 985 | } |
986 | 986 | ||
987 | extern int ip_vs_make_skb_writable(struct sk_buff **pskb, int len); | ||
988 | extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, | 987 | extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, |
989 | struct ip_vs_conn *cp, int dir); | 988 | struct ip_vs_conn *cp, int dir); |
990 | 989 | ||
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c index 341474eefa55..8ca5f4806a63 100644 --- a/net/ipv4/ipvs/ip_vs_app.c +++ b/net/ipv4/ipvs/ip_vs_app.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/skbuff.h> | 25 | #include <linux/skbuff.h> |
26 | #include <linux/in.h> | 26 | #include <linux/in.h> |
27 | #include <linux/ip.h> | 27 | #include <linux/ip.h> |
28 | #include <linux/netfilter.h> | ||
28 | #include <net/net_namespace.h> | 29 | #include <net/net_namespace.h> |
29 | #include <net/protocol.h> | 30 | #include <net/protocol.h> |
30 | #include <net/tcp.h> | 31 | #include <net/tcp.h> |
@@ -336,7 +337,7 @@ static inline int app_tcp_pkt_out(struct ip_vs_conn *cp, struct sk_buff **pskb, | |||
336 | struct tcphdr *th; | 337 | struct tcphdr *th; |
337 | __u32 seq; | 338 | __u32 seq; |
338 | 339 | ||
339 | if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th))) | 340 | if (!skb_make_writable(*pskb, tcp_offset + sizeof(*th))) |
340 | return 0; | 341 | return 0; |
341 | 342 | ||
342 | th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset); | 343 | th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset); |
@@ -411,7 +412,7 @@ static inline int app_tcp_pkt_in(struct ip_vs_conn *cp, struct sk_buff **pskb, | |||
411 | struct tcphdr *th; | 412 | struct tcphdr *th; |
412 | __u32 seq; | 413 | __u32 seq; |
413 | 414 | ||
414 | if (!ip_vs_make_skb_writable(pskb, tcp_offset + sizeof(*th))) | 415 | if (!skb_make_writable(*pskb, tcp_offset + sizeof(*th))) |
415 | return 0; | 416 | return 0; |
416 | 417 | ||
417 | th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset); | 418 | th = (struct tcphdr *)(skb_network_header(*pskb) + tcp_offset); |
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 3487337192c6..09cac38580fe 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
@@ -58,7 +58,6 @@ EXPORT_SYMBOL(ip_vs_conn_put); | |||
58 | #ifdef CONFIG_IP_VS_DEBUG | 58 | #ifdef CONFIG_IP_VS_DEBUG |
59 | EXPORT_SYMBOL(ip_vs_get_debug_level); | 59 | EXPORT_SYMBOL(ip_vs_get_debug_level); |
60 | #endif | 60 | #endif |
61 | EXPORT_SYMBOL(ip_vs_make_skb_writable); | ||
62 | 61 | ||
63 | 62 | ||
64 | /* ID used in ICMP lookups */ | 63 | /* ID used in ICMP lookups */ |
@@ -163,42 +162,6 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, | |||
163 | } | 162 | } |
164 | 163 | ||
165 | 164 | ||
166 | int ip_vs_make_skb_writable(struct sk_buff **pskb, int writable_len) | ||
167 | { | ||
168 | struct sk_buff *skb = *pskb; | ||
169 | |||
170 | /* skb is already used, better copy skb and its payload */ | ||
171 | if (unlikely(skb_shared(skb) || skb->sk)) | ||
172 | goto copy_skb; | ||
173 | |||
174 | /* skb data is already used, copy it */ | ||
175 | if (unlikely(skb_cloned(skb))) | ||
176 | goto copy_data; | ||
177 | |||
178 | return pskb_may_pull(skb, writable_len); | ||
179 | |||
180 | copy_data: | ||
181 | if (unlikely(writable_len > skb->len)) | ||
182 | return 0; | ||
183 | return !pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | ||
184 | |||
185 | copy_skb: | ||
186 | if (unlikely(writable_len > skb->len)) | ||
187 | return 0; | ||
188 | skb = skb_copy(skb, GFP_ATOMIC); | ||
189 | if (!skb) | ||
190 | return 0; | ||
191 | BUG_ON(skb_is_nonlinear(skb)); | ||
192 | |||
193 | /* Rest of kernel will get very unhappy if we pass it a | ||
194 | suddenly-orphaned skbuff */ | ||
195 | if ((*pskb)->sk) | ||
196 | skb_set_owner_w(skb, (*pskb)->sk); | ||
197 | kfree_skb(*pskb); | ||
198 | *pskb = skb; | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | /* | 165 | /* |
203 | * IPVS persistent scheduling function | 166 | * IPVS persistent scheduling function |
204 | * It creates a connection entry according to its template if exists, | 167 | * It creates a connection entry according to its template if exists, |
@@ -689,9 +652,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related) | |||
689 | 652 | ||
690 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) | 653 | if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) |
691 | offset += 2 * sizeof(__u16); | 654 | offset += 2 * sizeof(__u16); |
692 | if (!ip_vs_make_skb_writable(pskb, offset)) | 655 | if (!skb_make_writable(skb, offset)) |
693 | goto out; | 656 | goto out; |
694 | skb = *pskb; | ||
695 | 657 | ||
696 | ip_vs_nat_icmp(skb, pp, cp, 1); | 658 | ip_vs_nat_icmp(skb, pp, cp, 1); |
697 | 659 | ||
@@ -799,7 +761,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb, | |||
799 | 761 | ||
800 | IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet"); | 762 | IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet"); |
801 | 763 | ||
802 | if (!ip_vs_make_skb_writable(pskb, ihl)) | 764 | if (!skb_make_writable(skb, ihl)) |
803 | goto drop; | 765 | goto drop; |
804 | 766 | ||
805 | /* mangle the packet */ | 767 | /* mangle the packet */ |
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/ipv4/ipvs/ip_vs_ftp.c index 344ddbbdc756..4167d419b666 100644 --- a/net/ipv4/ipvs/ip_vs_ftp.c +++ b/net/ipv4/ipvs/ip_vs_ftp.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/skbuff.h> | 30 | #include <linux/skbuff.h> |
31 | #include <linux/in.h> | 31 | #include <linux/in.h> |
32 | #include <linux/ip.h> | 32 | #include <linux/ip.h> |
33 | #include <linux/netfilter.h> | ||
33 | #include <net/protocol.h> | 34 | #include <net/protocol.h> |
34 | #include <net/tcp.h> | 35 | #include <net/tcp.h> |
35 | #include <asm/unaligned.h> | 36 | #include <asm/unaligned.h> |
@@ -155,7 +156,7 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
155 | return 1; | 156 | return 1; |
156 | 157 | ||
157 | /* Linear packets are much easier to deal with. */ | 158 | /* Linear packets are much easier to deal with. */ |
158 | if (!ip_vs_make_skb_writable(pskb, (*pskb)->len)) | 159 | if (!skb_make_writable(*pskb, (*pskb)->len)) |
159 | return 0; | 160 | return 0; |
160 | 161 | ||
161 | if (cp->app_data == &ip_vs_ftp_pasv) { | 162 | if (cp->app_data == &ip_vs_ftp_pasv) { |
@@ -256,7 +257,7 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, | |||
256 | return 1; | 257 | return 1; |
257 | 258 | ||
258 | /* Linear packets are much easier to deal with. */ | 259 | /* Linear packets are much easier to deal with. */ |
259 | if (!ip_vs_make_skb_writable(pskb, (*pskb)->len)) | 260 | if (!skb_make_writable(*pskb, (*pskb)->len)) |
260 | return 0; | 261 | return 0; |
261 | 262 | ||
262 | /* | 263 | /* |
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index e65577a77006..b65b1a352ba3 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/tcp.h> /* for tcphdr */ | 20 | #include <linux/tcp.h> /* for tcphdr */ |
21 | #include <net/ip.h> | 21 | #include <net/ip.h> |
22 | #include <net/tcp.h> /* for csum_tcpudp_magic */ | 22 | #include <net/tcp.h> /* for csum_tcpudp_magic */ |
23 | #include <linux/netfilter.h> | ||
23 | #include <linux/netfilter_ipv4.h> | 24 | #include <linux/netfilter_ipv4.h> |
24 | 25 | ||
25 | #include <net/ip_vs.h> | 26 | #include <net/ip_vs.h> |
@@ -129,7 +130,7 @@ tcp_snat_handler(struct sk_buff **pskb, | |||
129 | const unsigned int tcphoff = ip_hdrlen(*pskb); | 130 | const unsigned int tcphoff = ip_hdrlen(*pskb); |
130 | 131 | ||
131 | /* csum_check requires unshared skb */ | 132 | /* csum_check requires unshared skb */ |
132 | if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph))) | 133 | if (!skb_make_writable(*pskb, tcphoff+sizeof(*tcph))) |
133 | return 0; | 134 | return 0; |
134 | 135 | ||
135 | if (unlikely(cp->app != NULL)) { | 136 | if (unlikely(cp->app != NULL)) { |
@@ -177,7 +178,7 @@ tcp_dnat_handler(struct sk_buff **pskb, | |||
177 | const unsigned int tcphoff = ip_hdrlen(*pskb); | 178 | const unsigned int tcphoff = ip_hdrlen(*pskb); |
178 | 179 | ||
179 | /* csum_check requires unshared skb */ | 180 | /* csum_check requires unshared skb */ |
180 | if (!ip_vs_make_skb_writable(pskb, tcphoff+sizeof(*tcph))) | 181 | if (!skb_make_writable(*pskb, tcphoff+sizeof(*tcph))) |
181 | return 0; | 182 | return 0; |
182 | 183 | ||
183 | if (unlikely(cp->app != NULL)) { | 184 | if (unlikely(cp->app != NULL)) { |
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c index 8ee5fe6a101d..c70aa40e2c9d 100644 --- a/net/ipv4/ipvs/ip_vs_proto_udp.c +++ b/net/ipv4/ipvs/ip_vs_proto_udp.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/in.h> | 18 | #include <linux/in.h> |
19 | #include <linux/ip.h> | 19 | #include <linux/ip.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/netfilter.h> | ||
21 | #include <linux/netfilter_ipv4.h> | 22 | #include <linux/netfilter_ipv4.h> |
22 | #include <linux/udp.h> | 23 | #include <linux/udp.h> |
23 | 24 | ||
@@ -136,7 +137,7 @@ udp_snat_handler(struct sk_buff **pskb, | |||
136 | const unsigned int udphoff = ip_hdrlen(*pskb); | 137 | const unsigned int udphoff = ip_hdrlen(*pskb); |
137 | 138 | ||
138 | /* csum_check requires unshared skb */ | 139 | /* csum_check requires unshared skb */ |
139 | if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph))) | 140 | if (!skb_make_writable(*pskb, udphoff+sizeof(*udph))) |
140 | return 0; | 141 | return 0; |
141 | 142 | ||
142 | if (unlikely(cp->app != NULL)) { | 143 | if (unlikely(cp->app != NULL)) { |
@@ -190,7 +191,7 @@ udp_dnat_handler(struct sk_buff **pskb, | |||
190 | unsigned int udphoff = ip_hdrlen(*pskb); | 191 | unsigned int udphoff = ip_hdrlen(*pskb); |
191 | 192 | ||
192 | /* csum_check requires unshared skb */ | 193 | /* csum_check requires unshared skb */ |
193 | if (!ip_vs_make_skb_writable(pskb, udphoff+sizeof(*udph))) | 194 | if (!skb_make_writable(*pskb, udphoff+sizeof(*udph))) |
194 | return 0; | 195 | return 0; |
195 | 196 | ||
196 | if (unlikely(cp->app != NULL)) { | 197 | if (unlikely(cp->app != NULL)) { |
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index 666e080a74a3..afd90d4d7399 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
@@ -253,7 +253,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
253 | } | 253 | } |
254 | 254 | ||
255 | /* copy-on-write the packet before mangling it */ | 255 | /* copy-on-write the packet before mangling it */ |
256 | if (!ip_vs_make_skb_writable(&skb, sizeof(struct iphdr))) | 256 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
257 | goto tx_error_put; | 257 | goto tx_error_put; |
258 | 258 | ||
259 | if (skb_cow(skb, rt->u.dst.dev->hard_header_len)) | 259 | if (skb_cow(skb, rt->u.dst.dev->hard_header_len)) |
@@ -529,7 +529,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
529 | } | 529 | } |
530 | 530 | ||
531 | /* copy-on-write the packet before mangling it */ | 531 | /* copy-on-write the packet before mangling it */ |
532 | if (!ip_vs_make_skb_writable(&skb, offset)) | 532 | if (!skb_make_writable(skb, offset)) |
533 | goto tx_error_put; | 533 | goto tx_error_put; |
534 | 534 | ||
535 | if (skb_cow(skb, rt->u.dst.dev->hard_header_len)) | 535 | if (skb_cow(skb, rt->u.dst.dev->hard_header_len)) |