diff options
Diffstat (limited to 'net/core/sock.c')
| -rw-r--r-- | net/core/sock.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 305cba401ae6..c5812bbc2cc9 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -340,8 +340,12 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested) | |||
| 340 | rc = sk_backlog_rcv(sk, skb); | 340 | rc = sk_backlog_rcv(sk, skb); |
| 341 | 341 | ||
| 342 | mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); | 342 | mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); |
| 343 | } else | 343 | } else if (sk_add_backlog(sk, skb)) { |
| 344 | sk_add_backlog(sk, skb); | 344 | bh_unlock_sock(sk); |
| 345 | atomic_inc(&sk->sk_drops); | ||
| 346 | goto discard_and_relse; | ||
| 347 | } | ||
| 348 | |||
| 345 | bh_unlock_sock(sk); | 349 | bh_unlock_sock(sk); |
| 346 | out: | 350 | out: |
| 347 | sock_put(sk); | 351 | sock_put(sk); |
| @@ -741,7 +745,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
| 741 | struct timeval tm; | 745 | struct timeval tm; |
| 742 | } v; | 746 | } v; |
| 743 | 747 | ||
| 744 | unsigned int lv = sizeof(int); | 748 | int lv = sizeof(int); |
| 745 | int len; | 749 | int len; |
| 746 | 750 | ||
| 747 | if (get_user(len, optlen)) | 751 | if (get_user(len, optlen)) |
| @@ -1139,6 +1143,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | |||
| 1139 | sock_lock_init(newsk); | 1143 | sock_lock_init(newsk); |
| 1140 | bh_lock_sock(newsk); | 1144 | bh_lock_sock(newsk); |
| 1141 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; | 1145 | newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; |
| 1146 | newsk->sk_backlog.len = 0; | ||
| 1142 | 1147 | ||
| 1143 | atomic_set(&newsk->sk_rmem_alloc, 0); | 1148 | atomic_set(&newsk->sk_rmem_alloc, 0); |
| 1144 | /* | 1149 | /* |
| @@ -1542,6 +1547,12 @@ static void __release_sock(struct sock *sk) | |||
| 1542 | 1547 | ||
| 1543 | bh_lock_sock(sk); | 1548 | bh_lock_sock(sk); |
| 1544 | } while ((skb = sk->sk_backlog.head) != NULL); | 1549 | } while ((skb = sk->sk_backlog.head) != NULL); |
| 1550 | |||
| 1551 | /* | ||
| 1552 | * Doing the zeroing here guarantee we can not loop forever | ||
| 1553 | * while a wild producer attempts to flood us. | ||
| 1554 | */ | ||
| 1555 | sk->sk_backlog.len = 0; | ||
| 1545 | } | 1556 | } |
| 1546 | 1557 | ||
| 1547 | /** | 1558 | /** |
| @@ -1874,6 +1885,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
| 1874 | sk->sk_allocation = GFP_KERNEL; | 1885 | sk->sk_allocation = GFP_KERNEL; |
| 1875 | sk->sk_rcvbuf = sysctl_rmem_default; | 1886 | sk->sk_rcvbuf = sysctl_rmem_default; |
| 1876 | sk->sk_sndbuf = sysctl_wmem_default; | 1887 | sk->sk_sndbuf = sysctl_wmem_default; |
| 1888 | sk->sk_backlog.limit = sk->sk_rcvbuf << 1; | ||
| 1877 | sk->sk_state = TCP_CLOSE; | 1889 | sk->sk_state = TCP_CLOSE; |
| 1878 | sk_set_socket(sk, sock); | 1890 | sk_set_socket(sk, sock); |
| 1879 | 1891 | ||
| @@ -2141,13 +2153,13 @@ int sock_prot_inuse_get(struct net *net, struct proto *prot) | |||
| 2141 | } | 2153 | } |
| 2142 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); | 2154 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); |
| 2143 | 2155 | ||
| 2144 | static int sock_inuse_init_net(struct net *net) | 2156 | static int __net_init sock_inuse_init_net(struct net *net) |
| 2145 | { | 2157 | { |
| 2146 | net->core.inuse = alloc_percpu(struct prot_inuse); | 2158 | net->core.inuse = alloc_percpu(struct prot_inuse); |
| 2147 | return net->core.inuse ? 0 : -ENOMEM; | 2159 | return net->core.inuse ? 0 : -ENOMEM; |
| 2148 | } | 2160 | } |
| 2149 | 2161 | ||
| 2150 | static void sock_inuse_exit_net(struct net *net) | 2162 | static void __net_exit sock_inuse_exit_net(struct net *net) |
| 2151 | { | 2163 | { |
| 2152 | free_percpu(net->core.inuse); | 2164 | free_percpu(net->core.inuse); |
| 2153 | } | 2165 | } |
| @@ -2229,13 +2241,10 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 2229 | } | 2241 | } |
| 2230 | 2242 | ||
| 2231 | if (prot->rsk_prot != NULL) { | 2243 | if (prot->rsk_prot != NULL) { |
| 2232 | static const char mask[] = "request_sock_%s"; | 2244 | prot->rsk_prot->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", prot->name); |
| 2233 | |||
| 2234 | prot->rsk_prot->slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); | ||
| 2235 | if (prot->rsk_prot->slab_name == NULL) | 2245 | if (prot->rsk_prot->slab_name == NULL) |
| 2236 | goto out_free_sock_slab; | 2246 | goto out_free_sock_slab; |
| 2237 | 2247 | ||
| 2238 | sprintf(prot->rsk_prot->slab_name, mask, prot->name); | ||
| 2239 | prot->rsk_prot->slab = kmem_cache_create(prot->rsk_prot->slab_name, | 2248 | prot->rsk_prot->slab = kmem_cache_create(prot->rsk_prot->slab_name, |
| 2240 | prot->rsk_prot->obj_size, 0, | 2249 | prot->rsk_prot->obj_size, 0, |
| 2241 | SLAB_HWCACHE_ALIGN, NULL); | 2250 | SLAB_HWCACHE_ALIGN, NULL); |
| @@ -2248,14 +2257,11 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 2248 | } | 2257 | } |
| 2249 | 2258 | ||
| 2250 | if (prot->twsk_prot != NULL) { | 2259 | if (prot->twsk_prot != NULL) { |
| 2251 | static const char mask[] = "tw_sock_%s"; | 2260 | prot->twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", prot->name); |
| 2252 | |||
| 2253 | prot->twsk_prot->twsk_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); | ||
| 2254 | 2261 | ||
| 2255 | if (prot->twsk_prot->twsk_slab_name == NULL) | 2262 | if (prot->twsk_prot->twsk_slab_name == NULL) |
| 2256 | goto out_free_request_sock_slab; | 2263 | goto out_free_request_sock_slab; |
| 2257 | 2264 | ||
| 2258 | sprintf(prot->twsk_prot->twsk_slab_name, mask, prot->name); | ||
| 2259 | prot->twsk_prot->twsk_slab = | 2265 | prot->twsk_prot->twsk_slab = |
| 2260 | kmem_cache_create(prot->twsk_prot->twsk_slab_name, | 2266 | kmem_cache_create(prot->twsk_prot->twsk_slab_name, |
| 2261 | prot->twsk_prot->twsk_obj_size, | 2267 | prot->twsk_prot->twsk_obj_size, |
| @@ -2282,7 +2288,8 @@ out_free_request_sock_slab: | |||
| 2282 | prot->rsk_prot->slab = NULL; | 2288 | prot->rsk_prot->slab = NULL; |
| 2283 | } | 2289 | } |
| 2284 | out_free_request_sock_slab_name: | 2290 | out_free_request_sock_slab_name: |
| 2285 | kfree(prot->rsk_prot->slab_name); | 2291 | if (prot->rsk_prot) |
| 2292 | kfree(prot->rsk_prot->slab_name); | ||
| 2286 | out_free_sock_slab: | 2293 | out_free_sock_slab: |
| 2287 | kmem_cache_destroy(prot->slab); | 2294 | kmem_cache_destroy(prot->slab); |
| 2288 | prot->slab = NULL; | 2295 | prot->slab = NULL; |
