diff options
author | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:13:53 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-08-17 00:13:53 -0400 |
commit | 4eebf60b7452fbd551fd7dece855ba7825a49cbc (patch) | |
tree | 490b4d194ba09c90e10201ab7fc084a0bda0ed27 /net/ipv4 | |
parent | 8f9cb50789e76f3e224e8861adf650e55c747af4 (diff) | |
parent | 2c6625cd545bdd66acff14f3394865d43920a5c7 (diff) |
Merge tag 'v4.2-rc7' into drm-next
Linux 4.2-rc7
Backmerge master for i915 fixes
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/arp.c | 16 | ||||
-rw-r--r-- | net/ipv4/datagram.c | 16 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 1 | ||||
-rw-r--r-- | net/ipv4/fib_lookup.h | 1 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 41 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 7 | ||||
-rw-r--r-- | net/ipv4/inet_connection_sock.c | 2 | ||||
-rw-r--r-- | net/ipv4/inet_fragment.c | 40 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 11 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 18 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_SYNPROXY.c | 3 | ||||
-rw-r--r-- | net/ipv4/route.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 11 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/udp.c | 13 |
16 files changed, 107 insertions, 80 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 933a92820d26..6c8b1fbafce8 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1017,14 +1017,16 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) | |||
1017 | 1017 | ||
1018 | neigh = neigh_lookup(&arp_tbl, &ip, dev); | 1018 | neigh = neigh_lookup(&arp_tbl, &ip, dev); |
1019 | if (neigh) { | 1019 | if (neigh) { |
1020 | read_lock_bh(&neigh->lock); | 1020 | if (!(neigh->nud_state & NUD_NOARP)) { |
1021 | memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); | 1021 | read_lock_bh(&neigh->lock); |
1022 | r->arp_flags = arp_state_to_flags(neigh); | 1022 | memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); |
1023 | read_unlock_bh(&neigh->lock); | 1023 | r->arp_flags = arp_state_to_flags(neigh); |
1024 | r->arp_ha.sa_family = dev->type; | 1024 | read_unlock_bh(&neigh->lock); |
1025 | strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); | 1025 | r->arp_ha.sa_family = dev->type; |
1026 | strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); | ||
1027 | err = 0; | ||
1028 | } | ||
1026 | neigh_release(neigh); | 1029 | neigh_release(neigh); |
1027 | err = 0; | ||
1028 | } | 1030 | } |
1029 | return err; | 1031 | return err; |
1030 | } | 1032 | } |
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 90c0e8386116..574fad9cca05 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <net/route.h> | 20 | #include <net/route.h> |
21 | #include <net/tcp_states.h> | 21 | #include <net/tcp_states.h> |
22 | 22 | ||
23 | int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 23 | int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
24 | { | 24 | { |
25 | struct inet_sock *inet = inet_sk(sk); | 25 | struct inet_sock *inet = inet_sk(sk); |
26 | struct sockaddr_in *usin = (struct sockaddr_in *) uaddr; | 26 | struct sockaddr_in *usin = (struct sockaddr_in *) uaddr; |
@@ -39,8 +39,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
39 | 39 | ||
40 | sk_dst_reset(sk); | 40 | sk_dst_reset(sk); |
41 | 41 | ||
42 | lock_sock(sk); | ||
43 | |||
44 | oif = sk->sk_bound_dev_if; | 42 | oif = sk->sk_bound_dev_if; |
45 | saddr = inet->inet_saddr; | 43 | saddr = inet->inet_saddr; |
46 | if (ipv4_is_multicast(usin->sin_addr.s_addr)) { | 44 | if (ipv4_is_multicast(usin->sin_addr.s_addr)) { |
@@ -82,9 +80,19 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
82 | sk_dst_set(sk, &rt->dst); | 80 | sk_dst_set(sk, &rt->dst); |
83 | err = 0; | 81 | err = 0; |
84 | out: | 82 | out: |
85 | release_sock(sk); | ||
86 | return err; | 83 | return err; |
87 | } | 84 | } |
85 | EXPORT_SYMBOL(__ip4_datagram_connect); | ||
86 | |||
87 | int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | ||
88 | { | ||
89 | int res; | ||
90 | |||
91 | lock_sock(sk); | ||
92 | res = __ip4_datagram_connect(sk, uaddr, addr_len); | ||
93 | release_sock(sk); | ||
94 | return res; | ||
95 | } | ||
88 | EXPORT_SYMBOL(ip4_datagram_connect); | 96 | EXPORT_SYMBOL(ip4_datagram_connect); |
89 | 97 | ||
90 | /* Because UDP xmit path can manipulate sk_dst_cache without holding | 98 | /* Because UDP xmit path can manipulate sk_dst_cache without holding |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index e813196c91c7..2d9cb1748f81 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -882,7 +882,6 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
882 | queue_delayed_work(system_power_efficient_wq, | 882 | queue_delayed_work(system_power_efficient_wq, |
883 | &check_lifetime_work, 0); | 883 | &check_lifetime_work, 0); |
884 | rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); | 884 | rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); |
885 | blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); | ||
886 | } | 885 | } |
887 | return 0; | 886 | return 0; |
888 | } | 887 | } |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index c6211ed60b03..9c02920725db 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
@@ -13,6 +13,7 @@ struct fib_alias { | |||
13 | u8 fa_state; | 13 | u8 fa_state; |
14 | u8 fa_slen; | 14 | u8 fa_slen; |
15 | u32 tb_id; | 15 | u32 tb_id; |
16 | s16 fa_default; | ||
16 | struct rcu_head rcu; | 17 | struct rcu_head rcu; |
17 | }; | 18 | }; |
18 | 19 | ||
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index c7358ea4ae93..3a06586b170c 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -1202,23 +1202,40 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event) | |||
1202 | } | 1202 | } |
1203 | 1203 | ||
1204 | /* Must be invoked inside of an RCU protected region. */ | 1204 | /* Must be invoked inside of an RCU protected region. */ |
1205 | void fib_select_default(struct fib_result *res) | 1205 | void fib_select_default(const struct flowi4 *flp, struct fib_result *res) |
1206 | { | 1206 | { |
1207 | struct fib_info *fi = NULL, *last_resort = NULL; | 1207 | struct fib_info *fi = NULL, *last_resort = NULL; |
1208 | struct hlist_head *fa_head = res->fa_head; | 1208 | struct hlist_head *fa_head = res->fa_head; |
1209 | struct fib_table *tb = res->table; | 1209 | struct fib_table *tb = res->table; |
1210 | u8 slen = 32 - res->prefixlen; | ||
1210 | int order = -1, last_idx = -1; | 1211 | int order = -1, last_idx = -1; |
1211 | struct fib_alias *fa; | 1212 | struct fib_alias *fa, *fa1 = NULL; |
1213 | u32 last_prio = res->fi->fib_priority; | ||
1214 | u8 last_tos = 0; | ||
1212 | 1215 | ||
1213 | hlist_for_each_entry_rcu(fa, fa_head, fa_list) { | 1216 | hlist_for_each_entry_rcu(fa, fa_head, fa_list) { |
1214 | struct fib_info *next_fi = fa->fa_info; | 1217 | struct fib_info *next_fi = fa->fa_info; |
1215 | 1218 | ||
1219 | if (fa->fa_slen != slen) | ||
1220 | continue; | ||
1221 | if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) | ||
1222 | continue; | ||
1223 | if (fa->tb_id != tb->tb_id) | ||
1224 | continue; | ||
1225 | if (next_fi->fib_priority > last_prio && | ||
1226 | fa->fa_tos == last_tos) { | ||
1227 | if (last_tos) | ||
1228 | continue; | ||
1229 | break; | ||
1230 | } | ||
1231 | if (next_fi->fib_flags & RTNH_F_DEAD) | ||
1232 | continue; | ||
1233 | last_tos = fa->fa_tos; | ||
1234 | last_prio = next_fi->fib_priority; | ||
1235 | |||
1216 | if (next_fi->fib_scope != res->scope || | 1236 | if (next_fi->fib_scope != res->scope || |
1217 | fa->fa_type != RTN_UNICAST) | 1237 | fa->fa_type != RTN_UNICAST) |
1218 | continue; | 1238 | continue; |
1219 | |||
1220 | if (next_fi->fib_priority > res->fi->fib_priority) | ||
1221 | break; | ||
1222 | if (!next_fi->fib_nh[0].nh_gw || | 1239 | if (!next_fi->fib_nh[0].nh_gw || |
1223 | next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) | 1240 | next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) |
1224 | continue; | 1241 | continue; |
@@ -1228,10 +1245,11 @@ void fib_select_default(struct fib_result *res) | |||
1228 | if (!fi) { | 1245 | if (!fi) { |
1229 | if (next_fi != res->fi) | 1246 | if (next_fi != res->fi) |
1230 | break; | 1247 | break; |
1248 | fa1 = fa; | ||
1231 | } else if (!fib_detect_death(fi, order, &last_resort, | 1249 | } else if (!fib_detect_death(fi, order, &last_resort, |
1232 | &last_idx, tb->tb_default)) { | 1250 | &last_idx, fa1->fa_default)) { |
1233 | fib_result_assign(res, fi); | 1251 | fib_result_assign(res, fi); |
1234 | tb->tb_default = order; | 1252 | fa1->fa_default = order; |
1235 | goto out; | 1253 | goto out; |
1236 | } | 1254 | } |
1237 | fi = next_fi; | 1255 | fi = next_fi; |
@@ -1239,20 +1257,21 @@ void fib_select_default(struct fib_result *res) | |||
1239 | } | 1257 | } |
1240 | 1258 | ||
1241 | if (order <= 0 || !fi) { | 1259 | if (order <= 0 || !fi) { |
1242 | tb->tb_default = -1; | 1260 | if (fa1) |
1261 | fa1->fa_default = -1; | ||
1243 | goto out; | 1262 | goto out; |
1244 | } | 1263 | } |
1245 | 1264 | ||
1246 | if (!fib_detect_death(fi, order, &last_resort, &last_idx, | 1265 | if (!fib_detect_death(fi, order, &last_resort, &last_idx, |
1247 | tb->tb_default)) { | 1266 | fa1->fa_default)) { |
1248 | fib_result_assign(res, fi); | 1267 | fib_result_assign(res, fi); |
1249 | tb->tb_default = order; | 1268 | fa1->fa_default = order; |
1250 | goto out; | 1269 | goto out; |
1251 | } | 1270 | } |
1252 | 1271 | ||
1253 | if (last_idx >= 0) | 1272 | if (last_idx >= 0) |
1254 | fib_result_assign(res, last_resort); | 1273 | fib_result_assign(res, last_resort); |
1255 | tb->tb_default = last_idx; | 1274 | fa1->fa_default = last_idx; |
1256 | out: | 1275 | out: |
1257 | return; | 1276 | return; |
1258 | } | 1277 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 15d32612e3c6..37c4bb89a708 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1171,6 +1171,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1171 | new_fa->fa_state = state & ~FA_S_ACCESSED; | 1171 | new_fa->fa_state = state & ~FA_S_ACCESSED; |
1172 | new_fa->fa_slen = fa->fa_slen; | 1172 | new_fa->fa_slen = fa->fa_slen; |
1173 | new_fa->tb_id = tb->tb_id; | 1173 | new_fa->tb_id = tb->tb_id; |
1174 | new_fa->fa_default = -1; | ||
1174 | 1175 | ||
1175 | err = switchdev_fib_ipv4_add(key, plen, fi, | 1176 | err = switchdev_fib_ipv4_add(key, plen, fi, |
1176 | new_fa->fa_tos, | 1177 | new_fa->fa_tos, |
@@ -1222,6 +1223,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1222 | new_fa->fa_state = 0; | 1223 | new_fa->fa_state = 0; |
1223 | new_fa->fa_slen = slen; | 1224 | new_fa->fa_slen = slen; |
1224 | new_fa->tb_id = tb->tb_id; | 1225 | new_fa->tb_id = tb->tb_id; |
1226 | new_fa->fa_default = -1; | ||
1225 | 1227 | ||
1226 | /* (Optionally) offload fib entry to switch hardware. */ | 1228 | /* (Optionally) offload fib entry to switch hardware. */ |
1227 | err = switchdev_fib_ipv4_add(key, plen, fi, tos, cfg->fc_type, | 1229 | err = switchdev_fib_ipv4_add(key, plen, fi, tos, cfg->fc_type, |
@@ -1791,8 +1793,6 @@ void fib_table_flush_external(struct fib_table *tb) | |||
1791 | if (hlist_empty(&n->leaf)) { | 1793 | if (hlist_empty(&n->leaf)) { |
1792 | put_child_root(pn, n->key, NULL); | 1794 | put_child_root(pn, n->key, NULL); |
1793 | node_free(n); | 1795 | node_free(n); |
1794 | } else { | ||
1795 | leaf_pull_suffix(pn, n); | ||
1796 | } | 1796 | } |
1797 | } | 1797 | } |
1798 | } | 1798 | } |
@@ -1862,8 +1862,6 @@ int fib_table_flush(struct fib_table *tb) | |||
1862 | if (hlist_empty(&n->leaf)) { | 1862 | if (hlist_empty(&n->leaf)) { |
1863 | put_child_root(pn, n->key, NULL); | 1863 | put_child_root(pn, n->key, NULL); |
1864 | node_free(n); | 1864 | node_free(n); |
1865 | } else { | ||
1866 | leaf_pull_suffix(pn, n); | ||
1867 | } | 1865 | } |
1868 | } | 1866 | } |
1869 | 1867 | ||
@@ -1990,7 +1988,6 @@ struct fib_table *fib_trie_table(u32 id, struct fib_table *alias) | |||
1990 | return NULL; | 1988 | return NULL; |
1991 | 1989 | ||
1992 | tb->tb_id = id; | 1990 | tb->tb_id = id; |
1993 | tb->tb_default = -1; | ||
1994 | tb->tb_num_default = 0; | 1991 | tb->tb_num_default = 0; |
1995 | tb->tb_data = (alias ? alias->__data : tb->__data); | 1992 | tb->tb_data = (alias ? alias->__data : tb->__data); |
1996 | 1993 | ||
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 60021d0d9326..05e3145f7dc3 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -593,7 +593,7 @@ static bool reqsk_queue_unlink(struct request_sock_queue *queue, | |||
593 | } | 593 | } |
594 | 594 | ||
595 | spin_unlock(&queue->syn_wait_lock); | 595 | spin_unlock(&queue->syn_wait_lock); |
596 | if (del_timer(&req->rsk_timer)) | 596 | if (del_timer_sync(&req->rsk_timer)) |
597 | reqsk_put(req); | 597 | reqsk_put(req); |
598 | return found; | 598 | return found; |
599 | } | 599 | } |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 5e346a082e5f..d0a7c0319e3d 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -131,34 +131,22 @@ inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb) | |||
131 | unsigned int evicted = 0; | 131 | unsigned int evicted = 0; |
132 | HLIST_HEAD(expired); | 132 | HLIST_HEAD(expired); |
133 | 133 | ||
134 | evict_again: | ||
135 | spin_lock(&hb->chain_lock); | 134 | spin_lock(&hb->chain_lock); |
136 | 135 | ||
137 | hlist_for_each_entry_safe(fq, n, &hb->chain, list) { | 136 | hlist_for_each_entry_safe(fq, n, &hb->chain, list) { |
138 | if (!inet_fragq_should_evict(fq)) | 137 | if (!inet_fragq_should_evict(fq)) |
139 | continue; | 138 | continue; |
140 | 139 | ||
141 | if (!del_timer(&fq->timer)) { | 140 | if (!del_timer(&fq->timer)) |
142 | /* q expiring right now thus increment its refcount so | 141 | continue; |
143 | * it won't be freed under us and wait until the timer | ||
144 | * has finished executing then destroy it | ||
145 | */ | ||
146 | atomic_inc(&fq->refcnt); | ||
147 | spin_unlock(&hb->chain_lock); | ||
148 | del_timer_sync(&fq->timer); | ||
149 | inet_frag_put(fq, f); | ||
150 | goto evict_again; | ||
151 | } | ||
152 | 142 | ||
153 | fq->flags |= INET_FRAG_EVICTED; | 143 | hlist_add_head(&fq->list_evictor, &expired); |
154 | hlist_del(&fq->list); | ||
155 | hlist_add_head(&fq->list, &expired); | ||
156 | ++evicted; | 144 | ++evicted; |
157 | } | 145 | } |
158 | 146 | ||
159 | spin_unlock(&hb->chain_lock); | 147 | spin_unlock(&hb->chain_lock); |
160 | 148 | ||
161 | hlist_for_each_entry_safe(fq, n, &expired, list) | 149 | hlist_for_each_entry_safe(fq, n, &expired, list_evictor) |
162 | f->frag_expire((unsigned long) fq); | 150 | f->frag_expire((unsigned long) fq); |
163 | 151 | ||
164 | return evicted; | 152 | return evicted; |
@@ -240,18 +228,20 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) | |||
240 | int i; | 228 | int i; |
241 | 229 | ||
242 | nf->low_thresh = 0; | 230 | nf->low_thresh = 0; |
243 | local_bh_disable(); | ||
244 | 231 | ||
245 | evict_again: | 232 | evict_again: |
233 | local_bh_disable(); | ||
246 | seq = read_seqbegin(&f->rnd_seqlock); | 234 | seq = read_seqbegin(&f->rnd_seqlock); |
247 | 235 | ||
248 | for (i = 0; i < INETFRAGS_HASHSZ ; i++) | 236 | for (i = 0; i < INETFRAGS_HASHSZ ; i++) |
249 | inet_evict_bucket(f, &f->hash[i]); | 237 | inet_evict_bucket(f, &f->hash[i]); |
250 | 238 | ||
251 | if (read_seqretry(&f->rnd_seqlock, seq)) | ||
252 | goto evict_again; | ||
253 | |||
254 | local_bh_enable(); | 239 | local_bh_enable(); |
240 | cond_resched(); | ||
241 | |||
242 | if (read_seqretry(&f->rnd_seqlock, seq) || | ||
243 | percpu_counter_sum(&nf->mem)) | ||
244 | goto evict_again; | ||
255 | 245 | ||
256 | percpu_counter_destroy(&nf->mem); | 246 | percpu_counter_destroy(&nf->mem); |
257 | } | 247 | } |
@@ -284,8 +274,8 @@ static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f) | |||
284 | struct inet_frag_bucket *hb; | 274 | struct inet_frag_bucket *hb; |
285 | 275 | ||
286 | hb = get_frag_bucket_locked(fq, f); | 276 | hb = get_frag_bucket_locked(fq, f); |
287 | if (!(fq->flags & INET_FRAG_EVICTED)) | 277 | hlist_del(&fq->list); |
288 | hlist_del(&fq->list); | 278 | fq->flags |= INET_FRAG_COMPLETE; |
289 | spin_unlock(&hb->chain_lock); | 279 | spin_unlock(&hb->chain_lock); |
290 | } | 280 | } |
291 | 281 | ||
@@ -297,7 +287,6 @@ void inet_frag_kill(struct inet_frag_queue *fq, struct inet_frags *f) | |||
297 | if (!(fq->flags & INET_FRAG_COMPLETE)) { | 287 | if (!(fq->flags & INET_FRAG_COMPLETE)) { |
298 | fq_unlink(fq, f); | 288 | fq_unlink(fq, f); |
299 | atomic_dec(&fq->refcnt); | 289 | atomic_dec(&fq->refcnt); |
300 | fq->flags |= INET_FRAG_COMPLETE; | ||
301 | } | 290 | } |
302 | } | 291 | } |
303 | EXPORT_SYMBOL(inet_frag_kill); | 292 | EXPORT_SYMBOL(inet_frag_kill); |
@@ -330,11 +319,12 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f) | |||
330 | fp = xp; | 319 | fp = xp; |
331 | } | 320 | } |
332 | sum = sum_truesize + f->qsize; | 321 | sum = sum_truesize + f->qsize; |
333 | sub_frag_mem_limit(q, sum); | ||
334 | 322 | ||
335 | if (f->destructor) | 323 | if (f->destructor) |
336 | f->destructor(q); | 324 | f->destructor(q); |
337 | kmem_cache_free(f->frags_cachep, q); | 325 | kmem_cache_free(f->frags_cachep, q); |
326 | |||
327 | sub_frag_mem_limit(nf, sum); | ||
338 | } | 328 | } |
339 | EXPORT_SYMBOL(inet_frag_destroy); | 329 | EXPORT_SYMBOL(inet_frag_destroy); |
340 | 330 | ||
@@ -390,7 +380,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, | |||
390 | 380 | ||
391 | q->net = nf; | 381 | q->net = nf; |
392 | f->constructor(q, arg); | 382 | f->constructor(q, arg); |
393 | add_frag_mem_limit(q, f->qsize); | 383 | add_frag_mem_limit(nf, f->qsize); |
394 | 384 | ||
395 | setup_timer(&q->timer, f->frag_expire, (unsigned long)q); | 385 | setup_timer(&q->timer, f->frag_expire, (unsigned long)q); |
396 | spin_lock_init(&q->lock); | 386 | spin_lock_init(&q->lock); |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 5f9b063bbe8a..0cb9165421d4 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -624,22 +624,21 @@ EXPORT_SYMBOL_GPL(inet_hashinfo_init); | |||
624 | 624 | ||
625 | int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo) | 625 | int inet_ehash_locks_alloc(struct inet_hashinfo *hashinfo) |
626 | { | 626 | { |
627 | unsigned int locksz = sizeof(spinlock_t); | ||
627 | unsigned int i, nblocks = 1; | 628 | unsigned int i, nblocks = 1; |
628 | 629 | ||
629 | if (sizeof(spinlock_t) != 0) { | 630 | if (locksz != 0) { |
630 | /* allocate 2 cache lines or at least one spinlock per cpu */ | 631 | /* allocate 2 cache lines or at least one spinlock per cpu */ |
631 | nblocks = max_t(unsigned int, | 632 | nblocks = max(2U * L1_CACHE_BYTES / locksz, 1U); |
632 | 2 * L1_CACHE_BYTES / sizeof(spinlock_t), | ||
633 | 1); | ||
634 | nblocks = roundup_pow_of_two(nblocks * num_possible_cpus()); | 633 | nblocks = roundup_pow_of_two(nblocks * num_possible_cpus()); |
635 | 634 | ||
636 | /* no more locks than number of hash buckets */ | 635 | /* no more locks than number of hash buckets */ |
637 | nblocks = min(nblocks, hashinfo->ehash_mask + 1); | 636 | nblocks = min(nblocks, hashinfo->ehash_mask + 1); |
638 | 637 | ||
639 | hashinfo->ehash_locks = kmalloc_array(nblocks, sizeof(spinlock_t), | 638 | hashinfo->ehash_locks = kmalloc_array(nblocks, locksz, |
640 | GFP_KERNEL | __GFP_NOWARN); | 639 | GFP_KERNEL | __GFP_NOWARN); |
641 | if (!hashinfo->ehash_locks) | 640 | if (!hashinfo->ehash_locks) |
642 | hashinfo->ehash_locks = vmalloc(nblocks * sizeof(spinlock_t)); | 641 | hashinfo->ehash_locks = vmalloc(nblocks * locksz); |
643 | 642 | ||
644 | if (!hashinfo->ehash_locks) | 643 | if (!hashinfo->ehash_locks) |
645 | return -ENOMEM; | 644 | return -ENOMEM; |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index a50dc6d408d1..921138f6c97c 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -202,7 +202,7 @@ static void ip_expire(unsigned long arg) | |||
202 | ipq_kill(qp); | 202 | ipq_kill(qp); |
203 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); | 203 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
204 | 204 | ||
205 | if (!(qp->q.flags & INET_FRAG_EVICTED)) { | 205 | if (!inet_frag_evicting(&qp->q)) { |
206 | struct sk_buff *head = qp->q.fragments; | 206 | struct sk_buff *head = qp->q.fragments; |
207 | const struct iphdr *iph; | 207 | const struct iphdr *iph; |
208 | int err; | 208 | int err; |
@@ -309,7 +309,7 @@ static int ip_frag_reinit(struct ipq *qp) | |||
309 | kfree_skb(fp); | 309 | kfree_skb(fp); |
310 | fp = xp; | 310 | fp = xp; |
311 | } while (fp); | 311 | } while (fp); |
312 | sub_frag_mem_limit(&qp->q, sum_truesize); | 312 | sub_frag_mem_limit(qp->q.net, sum_truesize); |
313 | 313 | ||
314 | qp->q.flags = 0; | 314 | qp->q.flags = 0; |
315 | qp->q.len = 0; | 315 | qp->q.len = 0; |
@@ -351,7 +351,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | |||
351 | ihl = ip_hdrlen(skb); | 351 | ihl = ip_hdrlen(skb); |
352 | 352 | ||
353 | /* Determine the position of this fragment. */ | 353 | /* Determine the position of this fragment. */ |
354 | end = offset + skb->len - ihl; | 354 | end = offset + skb->len - skb_network_offset(skb) - ihl; |
355 | err = -EINVAL; | 355 | err = -EINVAL; |
356 | 356 | ||
357 | /* Is this the final fragment? */ | 357 | /* Is this the final fragment? */ |
@@ -381,7 +381,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | |||
381 | goto err; | 381 | goto err; |
382 | 382 | ||
383 | err = -ENOMEM; | 383 | err = -ENOMEM; |
384 | if (!pskb_pull(skb, ihl)) | 384 | if (!pskb_pull(skb, skb_network_offset(skb) + ihl)) |
385 | goto err; | 385 | goto err; |
386 | 386 | ||
387 | err = pskb_trim_rcsum(skb, end - offset); | 387 | err = pskb_trim_rcsum(skb, end - offset); |
@@ -455,7 +455,7 @@ found: | |||
455 | qp->q.fragments = next; | 455 | qp->q.fragments = next; |
456 | 456 | ||
457 | qp->q.meat -= free_it->len; | 457 | qp->q.meat -= free_it->len; |
458 | sub_frag_mem_limit(&qp->q, free_it->truesize); | 458 | sub_frag_mem_limit(qp->q.net, free_it->truesize); |
459 | kfree_skb(free_it); | 459 | kfree_skb(free_it); |
460 | } | 460 | } |
461 | } | 461 | } |
@@ -479,7 +479,7 @@ found: | |||
479 | qp->q.stamp = skb->tstamp; | 479 | qp->q.stamp = skb->tstamp; |
480 | qp->q.meat += skb->len; | 480 | qp->q.meat += skb->len; |
481 | qp->ecn |= ecn; | 481 | qp->ecn |= ecn; |
482 | add_frag_mem_limit(&qp->q, skb->truesize); | 482 | add_frag_mem_limit(qp->q.net, skb->truesize); |
483 | if (offset == 0) | 483 | if (offset == 0) |
484 | qp->q.flags |= INET_FRAG_FIRST_IN; | 484 | qp->q.flags |= INET_FRAG_FIRST_IN; |
485 | 485 | ||
@@ -587,7 +587,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
587 | head->len -= clone->len; | 587 | head->len -= clone->len; |
588 | clone->csum = 0; | 588 | clone->csum = 0; |
589 | clone->ip_summed = head->ip_summed; | 589 | clone->ip_summed = head->ip_summed; |
590 | add_frag_mem_limit(&qp->q, clone->truesize); | 590 | add_frag_mem_limit(qp->q.net, clone->truesize); |
591 | } | 591 | } |
592 | 592 | ||
593 | skb_push(head, head->data - skb_network_header(head)); | 593 | skb_push(head, head->data - skb_network_header(head)); |
@@ -615,7 +615,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
615 | } | 615 | } |
616 | fp = next; | 616 | fp = next; |
617 | } | 617 | } |
618 | sub_frag_mem_limit(&qp->q, sum_truesize); | 618 | sub_frag_mem_limit(qp->q.net, sum_truesize); |
619 | 619 | ||
620 | head->next = NULL; | 620 | head->next = NULL; |
621 | head->dev = dev; | 621 | head->dev = dev; |
@@ -641,6 +641,8 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, | |||
641 | iph->frag_off = 0; | 641 | iph->frag_off = 0; |
642 | } | 642 | } |
643 | 643 | ||
644 | ip_send_check(iph); | ||
645 | |||
644 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); | 646 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS); |
645 | qp->q.fragments = NULL; | 647 | qp->q.fragments = NULL; |
646 | qp->q.fragments_tail = NULL; | 648 | qp->q.fragments_tail = NULL; |
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index fe8cc183411e..95ea633e8356 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
@@ -226,7 +226,8 @@ synproxy_send_client_ack(const struct synproxy_net *snet, | |||
226 | 226 | ||
227 | synproxy_build_options(nth, opts); | 227 | synproxy_build_options(nth, opts); |
228 | 228 | ||
229 | synproxy_send_tcp(skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); | 229 | synproxy_send_tcp(skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, |
230 | niph, nth, tcp_hdr_size); | ||
230 | } | 231 | } |
231 | 232 | ||
232 | static bool | 233 | static bool |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d0362a2de3d3..e681b852ced1 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2176,7 +2176,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4) | |||
2176 | if (!res.prefixlen && | 2176 | if (!res.prefixlen && |
2177 | res.table->tb_num_default > 1 && | 2177 | res.table->tb_num_default > 1 && |
2178 | res.type == RTN_UNICAST && !fl4->flowi4_oif) | 2178 | res.type == RTN_UNICAST && !fl4->flowi4_oif) |
2179 | fib_select_default(&res); | 2179 | fib_select_default(fl4, &res); |
2180 | 2180 | ||
2181 | if (!fl4->saddr) | 2181 | if (!fl4->saddr) |
2182 | fl4->saddr = FIB_RES_PREFSRC(net, res); | 2182 | fl4->saddr = FIB_RES_PREFSRC(net, res); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 7f4056785acc..45534a5ab430 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -780,7 +780,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos, | |||
780 | ret = -EAGAIN; | 780 | ret = -EAGAIN; |
781 | break; | 781 | break; |
782 | } | 782 | } |
783 | sk_wait_data(sk, &timeo); | 783 | sk_wait_data(sk, &timeo, NULL); |
784 | if (signal_pending(current)) { | 784 | if (signal_pending(current)) { |
785 | ret = sock_intr_errno(timeo); | 785 | ret = sock_intr_errno(timeo); |
786 | break; | 786 | break; |
@@ -1575,7 +1575,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, | |||
1575 | int target; /* Read at least this many bytes */ | 1575 | int target; /* Read at least this many bytes */ |
1576 | long timeo; | 1576 | long timeo; |
1577 | struct task_struct *user_recv = NULL; | 1577 | struct task_struct *user_recv = NULL; |
1578 | struct sk_buff *skb; | 1578 | struct sk_buff *skb, *last; |
1579 | u32 urg_hole = 0; | 1579 | u32 urg_hole = 0; |
1580 | 1580 | ||
1581 | if (unlikely(flags & MSG_ERRQUEUE)) | 1581 | if (unlikely(flags & MSG_ERRQUEUE)) |
@@ -1635,7 +1635,9 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, | |||
1635 | 1635 | ||
1636 | /* Next get a buffer. */ | 1636 | /* Next get a buffer. */ |
1637 | 1637 | ||
1638 | last = skb_peek_tail(&sk->sk_receive_queue); | ||
1638 | skb_queue_walk(&sk->sk_receive_queue, skb) { | 1639 | skb_queue_walk(&sk->sk_receive_queue, skb) { |
1640 | last = skb; | ||
1639 | /* Now that we have two receive queues this | 1641 | /* Now that we have two receive queues this |
1640 | * shouldn't happen. | 1642 | * shouldn't happen. |
1641 | */ | 1643 | */ |
@@ -1754,8 +1756,9 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, | |||
1754 | /* Do not sleep, just process backlog. */ | 1756 | /* Do not sleep, just process backlog. */ |
1755 | release_sock(sk); | 1757 | release_sock(sk); |
1756 | lock_sock(sk); | 1758 | lock_sock(sk); |
1757 | } else | 1759 | } else { |
1758 | sk_wait_data(sk, &timeo); | 1760 | sk_wait_data(sk, &timeo, last); |
1761 | } | ||
1759 | 1762 | ||
1760 | if (user_recv) { | 1763 | if (user_recv) { |
1761 | int chunk; | 1764 | int chunk; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 684f095d196e..728f5b3d3c64 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1917,14 +1917,13 @@ void tcp_enter_loss(struct sock *sk) | |||
1917 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1917 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1918 | struct tcp_sock *tp = tcp_sk(sk); | 1918 | struct tcp_sock *tp = tcp_sk(sk); |
1919 | struct sk_buff *skb; | 1919 | struct sk_buff *skb; |
1920 | bool new_recovery = false; | 1920 | bool new_recovery = icsk->icsk_ca_state < TCP_CA_Recovery; |
1921 | bool is_reneg; /* is receiver reneging on SACKs? */ | 1921 | bool is_reneg; /* is receiver reneging on SACKs? */ |
1922 | 1922 | ||
1923 | /* Reduce ssthresh if it has not yet been made inside this window. */ | 1923 | /* Reduce ssthresh if it has not yet been made inside this window. */ |
1924 | if (icsk->icsk_ca_state <= TCP_CA_Disorder || | 1924 | if (icsk->icsk_ca_state <= TCP_CA_Disorder || |
1925 | !after(tp->high_seq, tp->snd_una) || | 1925 | !after(tp->high_seq, tp->snd_una) || |
1926 | (icsk->icsk_ca_state == TCP_CA_Loss && !icsk->icsk_retransmits)) { | 1926 | (icsk->icsk_ca_state == TCP_CA_Loss && !icsk->icsk_retransmits)) { |
1927 | new_recovery = true; | ||
1928 | tp->prior_ssthresh = tcp_current_ssthresh(sk); | 1927 | tp->prior_ssthresh = tcp_current_ssthresh(sk); |
1929 | tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); | 1928 | tp->snd_ssthresh = icsk->icsk_ca_ops->ssthresh(sk); |
1930 | tcp_ca_event(sk, CA_EVENT_LOSS); | 1929 | tcp_ca_event(sk, CA_EVENT_LOSS); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d7d4c2b79cf2..0ea2e1c5d395 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1348,7 +1348,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) | |||
1348 | req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr); | 1348 | req = inet_csk_search_req(sk, th->source, iph->saddr, iph->daddr); |
1349 | if (req) { | 1349 | if (req) { |
1350 | nsk = tcp_check_req(sk, skb, req, false); | 1350 | nsk = tcp_check_req(sk, skb, req, false); |
1351 | if (!nsk) | 1351 | if (!nsk || nsk == sk) |
1352 | reqsk_put(req); | 1352 | reqsk_put(req); |
1353 | return nsk; | 1353 | return nsk; |
1354 | } | 1354 | } |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 83aa604f9273..1b8c5ba7d5f7 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1995,12 +1995,19 @@ void udp_v4_early_demux(struct sk_buff *skb) | |||
1995 | 1995 | ||
1996 | skb->sk = sk; | 1996 | skb->sk = sk; |
1997 | skb->destructor = sock_efree; | 1997 | skb->destructor = sock_efree; |
1998 | dst = sk->sk_rx_dst; | 1998 | dst = READ_ONCE(sk->sk_rx_dst); |
1999 | 1999 | ||
2000 | if (dst) | 2000 | if (dst) |
2001 | dst = dst_check(dst, 0); | 2001 | dst = dst_check(dst, 0); |
2002 | if (dst) | 2002 | if (dst) { |
2003 | skb_dst_set_noref(skb, dst); | 2003 | /* DST_NOCACHE can not be used without taking a reference */ |
2004 | if (dst->flags & DST_NOCACHE) { | ||
2005 | if (likely(atomic_inc_not_zero(&dst->__refcnt))) | ||
2006 | skb_dst_set(skb, dst); | ||
2007 | } else { | ||
2008 | skb_dst_set_noref(skb, dst); | ||
2009 | } | ||
2010 | } | ||
2004 | } | 2011 | } |
2005 | 2012 | ||
2006 | int udp_rcv(struct sk_buff *skb) | 2013 | int udp_rcv(struct sk_buff *skb) |