diff options
| author | David S. Miller <davem@davemloft.net> | 2011-02-19 19:42:37 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-02-19 19:42:37 -0500 |
| commit | ece639caa33c85c8805fa4a0a5955b8de9c95346 (patch) | |
| tree | 5b8d613601c2e01e876a7d241923e90a0e759c3b | |
| parent | 0cc9d5257857608ba85885b75fcada13d359b5d1 (diff) | |
| parent | 0af320fb4627033e49cbc6e8138e7aa75ab8352a (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
| -rw-r--r-- | include/net/netfilter/nf_tproxy_core.h | 12 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_LOG.c | 2 | ||||
| -rw-r--r-- | net/netfilter/nf_tproxy_core.c | 27 | ||||
| -rw-r--r-- | net/netfilter/xt_TPROXY.c | 22 | ||||
| -rw-r--r-- | net/netfilter/xt_socket.c | 13 |
5 files changed, 45 insertions, 31 deletions
diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index cd85b3bc8327..e505358d8999 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h | |||
| @@ -201,18 +201,8 @@ nf_tproxy_get_sock_v6(struct net *net, const u8 protocol, | |||
| 201 | } | 201 | } |
| 202 | #endif | 202 | #endif |
| 203 | 203 | ||
| 204 | static inline void | ||
| 205 | nf_tproxy_put_sock(struct sock *sk) | ||
| 206 | { | ||
| 207 | /* TIME_WAIT inet sockets have to be handled differently */ | ||
| 208 | if ((sk->sk_protocol == IPPROTO_TCP) && (sk->sk_state == TCP_TIME_WAIT)) | ||
| 209 | inet_twsk_put(inet_twsk(sk)); | ||
| 210 | else | ||
| 211 | sock_put(sk); | ||
| 212 | } | ||
| 213 | |||
| 214 | /* assign a socket to the skb -- consumes sk */ | 204 | /* assign a socket to the skb -- consumes sk */ |
| 215 | int | 205 | void |
| 216 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk); | 206 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk); |
| 217 | 207 | ||
| 218 | #endif | 208 | #endif |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 09c88891a753..de338037a736 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
| @@ -410,7 +410,7 @@ fallback: | |||
| 410 | if (p != NULL) { | 410 | if (p != NULL) { |
| 411 | sb_add(m, "%02x", *p++); | 411 | sb_add(m, "%02x", *p++); |
| 412 | for (i = 1; i < len; i++) | 412 | for (i = 1; i < len; i++) |
| 413 | sb_add(m, ":%02x", p[i]); | 413 | sb_add(m, ":%02x", *p++); |
| 414 | } | 414 | } |
| 415 | sb_add(m, " "); | 415 | sb_add(m, " "); |
| 416 | 416 | ||
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index 4d87befb04c0..474d621cbc2e 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c | |||
| @@ -28,26 +28,23 @@ nf_tproxy_destructor(struct sk_buff *skb) | |||
| 28 | skb->destructor = NULL; | 28 | skb->destructor = NULL; |
| 29 | 29 | ||
| 30 | if (sk) | 30 | if (sk) |
| 31 | nf_tproxy_put_sock(sk); | 31 | sock_put(sk); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | /* consumes sk */ | 34 | /* consumes sk */ |
| 35 | int | 35 | void |
| 36 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) | 36 | nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk) |
| 37 | { | 37 | { |
| 38 | bool transparent = (sk->sk_state == TCP_TIME_WAIT) ? | 38 | /* assigning tw sockets complicates things; most |
| 39 | inet_twsk(sk)->tw_transparent : | 39 | * skb->sk->X checks would have to test sk->sk_state first */ |
| 40 | inet_sk(sk)->transparent; | 40 | if (sk->sk_state == TCP_TIME_WAIT) { |
| 41 | 41 | inet_twsk_put(inet_twsk(sk)); | |
| 42 | if (transparent) { | 42 | return; |
| 43 | skb_orphan(skb); | 43 | } |
| 44 | skb->sk = sk; | 44 | |
| 45 | skb->destructor = nf_tproxy_destructor; | 45 | skb_orphan(skb); |
| 46 | return 1; | 46 | skb->sk = sk; |
| 47 | } else | 47 | skb->destructor = nf_tproxy_destructor; |
| 48 | nf_tproxy_put_sock(sk); | ||
| 49 | |||
| 50 | return 0; | ||
| 51 | } | 48 | } |
| 52 | EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock); | 49 | EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock); |
| 53 | 50 | ||
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index 640678f47a2a..dcfd57eb9d02 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c | |||
| @@ -33,6 +33,20 @@ | |||
| 33 | #include <net/netfilter/nf_tproxy_core.h> | 33 | #include <net/netfilter/nf_tproxy_core.h> |
| 34 | #include <linux/netfilter/xt_TPROXY.h> | 34 | #include <linux/netfilter/xt_TPROXY.h> |
| 35 | 35 | ||
| 36 | static bool tproxy_sk_is_transparent(struct sock *sk) | ||
| 37 | { | ||
| 38 | if (sk->sk_state != TCP_TIME_WAIT) { | ||
| 39 | if (inet_sk(sk)->transparent) | ||
| 40 | return true; | ||
| 41 | sock_put(sk); | ||
| 42 | } else { | ||
| 43 | if (inet_twsk(sk)->tw_transparent) | ||
| 44 | return true; | ||
| 45 | inet_twsk_put(inet_twsk(sk)); | ||
| 46 | } | ||
| 47 | return false; | ||
| 48 | } | ||
| 49 | |||
| 36 | static inline __be32 | 50 | static inline __be32 |
| 37 | tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr) | 51 | tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr) |
| 38 | { | 52 | { |
| @@ -141,7 +155,7 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, | |||
| 141 | skb->dev, NFT_LOOKUP_LISTENER); | 155 | skb->dev, NFT_LOOKUP_LISTENER); |
| 142 | 156 | ||
| 143 | /* NOTE: assign_sock consumes our sk reference */ | 157 | /* NOTE: assign_sock consumes our sk reference */ |
| 144 | if (sk && nf_tproxy_assign_sock(skb, sk)) { | 158 | if (sk && tproxy_sk_is_transparent(sk)) { |
| 145 | /* This should be in a separate target, but we don't do multiple | 159 | /* This should be in a separate target, but we don't do multiple |
| 146 | targets on the same rule yet */ | 160 | targets on the same rule yet */ |
| 147 | skb->mark = (skb->mark & ~mark_mask) ^ mark_value; | 161 | skb->mark = (skb->mark & ~mark_mask) ^ mark_value; |
| @@ -149,6 +163,8 @@ tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, | |||
| 149 | pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", | 163 | pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", |
| 150 | iph->protocol, &iph->daddr, ntohs(hp->dest), | 164 | iph->protocol, &iph->daddr, ntohs(hp->dest), |
| 151 | &laddr, ntohs(lport), skb->mark); | 165 | &laddr, ntohs(lport), skb->mark); |
| 166 | |||
| 167 | nf_tproxy_assign_sock(skb, sk); | ||
| 152 | return NF_ACCEPT; | 168 | return NF_ACCEPT; |
| 153 | } | 169 | } |
| 154 | 170 | ||
| @@ -306,7 +322,7 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 306 | par->in, NFT_LOOKUP_LISTENER); | 322 | par->in, NFT_LOOKUP_LISTENER); |
| 307 | 323 | ||
| 308 | /* NOTE: assign_sock consumes our sk reference */ | 324 | /* NOTE: assign_sock consumes our sk reference */ |
| 309 | if (sk && nf_tproxy_assign_sock(skb, sk)) { | 325 | if (sk && tproxy_sk_is_transparent(sk)) { |
| 310 | /* This should be in a separate target, but we don't do multiple | 326 | /* This should be in a separate target, but we don't do multiple |
| 311 | targets on the same rule yet */ | 327 | targets on the same rule yet */ |
| 312 | skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value; | 328 | skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value; |
| @@ -314,6 +330,8 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) | |||
| 314 | pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", | 330 | pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", |
| 315 | tproto, &iph->saddr, ntohs(hp->source), | 331 | tproto, &iph->saddr, ntohs(hp->source), |
| 316 | laddr, ntohs(lport), skb->mark); | 332 | laddr, ntohs(lport), skb->mark); |
| 333 | |||
| 334 | nf_tproxy_assign_sock(skb, sk); | ||
| 317 | return NF_ACCEPT; | 335 | return NF_ACCEPT; |
| 318 | } | 336 | } |
| 319 | 337 | ||
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 00d6ae838303..9cc46356b577 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
| @@ -35,6 +35,15 @@ | |||
| 35 | #include <net/netfilter/nf_conntrack.h> | 35 | #include <net/netfilter/nf_conntrack.h> |
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | static void | ||
| 39 | xt_socket_put_sk(struct sock *sk) | ||
| 40 | { | ||
| 41 | if (sk->sk_state == TCP_TIME_WAIT) | ||
| 42 | inet_twsk_put(inet_twsk(sk)); | ||
| 43 | else | ||
| 44 | sock_put(sk); | ||
| 45 | } | ||
| 46 | |||
| 38 | static int | 47 | static int |
| 39 | extract_icmp4_fields(const struct sk_buff *skb, | 48 | extract_icmp4_fields(const struct sk_buff *skb, |
| 40 | u8 *protocol, | 49 | u8 *protocol, |
| @@ -164,7 +173,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, | |||
| 164 | (sk->sk_state == TCP_TIME_WAIT && | 173 | (sk->sk_state == TCP_TIME_WAIT && |
| 165 | inet_twsk(sk)->tw_transparent)); | 174 | inet_twsk(sk)->tw_transparent)); |
| 166 | 175 | ||
| 167 | nf_tproxy_put_sock(sk); | 176 | xt_socket_put_sk(sk); |
| 168 | 177 | ||
| 169 | if (wildcard || !transparent) | 178 | if (wildcard || !transparent) |
| 170 | sk = NULL; | 179 | sk = NULL; |
| @@ -298,7 +307,7 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) | |||
| 298 | (sk->sk_state == TCP_TIME_WAIT && | 307 | (sk->sk_state == TCP_TIME_WAIT && |
| 299 | inet_twsk(sk)->tw_transparent)); | 308 | inet_twsk(sk)->tw_transparent)); |
| 300 | 309 | ||
| 301 | nf_tproxy_put_sock(sk); | 310 | xt_socket_put_sk(sk); |
| 302 | 311 | ||
| 303 | if (wildcard || !transparent) | 312 | if (wildcard || !transparent) |
| 304 | sk = NULL; | 313 | sk = NULL; |
