diff options
Diffstat (limited to 'net')
53 files changed, 424 insertions, 253 deletions
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index e23449094188..9cb7044d0801 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -582,7 +582,7 @@ int br_set_ageing_time(struct net_bridge *br, u32 ageing_time) | |||
582 | int err; | 582 | int err; |
583 | 583 | ||
584 | err = switchdev_port_attr_set(br->dev, &attr); | 584 | err = switchdev_port_attr_set(br->dev, &attr); |
585 | if (err) | 585 | if (err && err != -EOPNOTSUPP) |
586 | return err; | 586 | return err; |
587 | 587 | ||
588 | br->ageing_time = t; | 588 | br->ageing_time = t; |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 67b2e27999aa..8570bc7744c2 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1521,6 +1521,8 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
1521 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 1521 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
1522 | return -EFAULT; | 1522 | return -EFAULT; |
1523 | 1523 | ||
1524 | tmp.name[sizeof(tmp.name) - 1] = '\0'; | ||
1525 | |||
1524 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); | 1526 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
1525 | if (!t) | 1527 | if (!t) |
1526 | return ret; | 1528 | return ret; |
@@ -2332,6 +2334,8 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd, | |||
2332 | if (copy_from_user(&tmp, user, sizeof(tmp))) | 2334 | if (copy_from_user(&tmp, user, sizeof(tmp))) |
2333 | return -EFAULT; | 2335 | return -EFAULT; |
2334 | 2336 | ||
2337 | tmp.name[sizeof(tmp.name) - 1] = '\0'; | ||
2338 | |||
2335 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); | 2339 | t = find_table_lock(net, tmp.name, &ret, &ebt_mutex); |
2336 | if (!t) | 2340 | if (!t) |
2337 | return ret; | 2341 | return ret; |
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c index adc8d7221dbb..77f7e7a9ebe1 100644 --- a/net/bridge/netfilter/nft_reject_bridge.c +++ b/net/bridge/netfilter/nft_reject_bridge.c | |||
@@ -40,7 +40,8 @@ static void nft_reject_br_push_etherhdr(struct sk_buff *oldskb, | |||
40 | /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) | 40 | /* We cannot use oldskb->dev, it can be either bridge device (NF_BRIDGE INPUT) |
41 | * or the bridge port (NF_BRIDGE PREROUTING). | 41 | * or the bridge port (NF_BRIDGE PREROUTING). |
42 | */ | 42 | */ |
43 | static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | 43 | static void nft_reject_br_send_v4_tcp_reset(struct net *net, |
44 | struct sk_buff *oldskb, | ||
44 | const struct net_device *dev, | 45 | const struct net_device *dev, |
45 | int hook) | 46 | int hook) |
46 | { | 47 | { |
@@ -48,7 +49,6 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | |||
48 | struct iphdr *niph; | 49 | struct iphdr *niph; |
49 | const struct tcphdr *oth; | 50 | const struct tcphdr *oth; |
50 | struct tcphdr _oth; | 51 | struct tcphdr _oth; |
51 | struct net *net = sock_net(oldskb->sk); | ||
52 | 52 | ||
53 | if (!nft_bridge_iphdr_validate(oldskb)) | 53 | if (!nft_bridge_iphdr_validate(oldskb)) |
54 | return; | 54 | return; |
@@ -75,7 +75,8 @@ static void nft_reject_br_send_v4_tcp_reset(struct sk_buff *oldskb, | |||
75 | br_deliver(br_port_get_rcu(dev), nskb); | 75 | br_deliver(br_port_get_rcu(dev), nskb); |
76 | } | 76 | } |
77 | 77 | ||
78 | static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, | 78 | static void nft_reject_br_send_v4_unreach(struct net *net, |
79 | struct sk_buff *oldskb, | ||
79 | const struct net_device *dev, | 80 | const struct net_device *dev, |
80 | int hook, u8 code) | 81 | int hook, u8 code) |
81 | { | 82 | { |
@@ -86,7 +87,6 @@ static void nft_reject_br_send_v4_unreach(struct sk_buff *oldskb, | |||
86 | void *payload; | 87 | void *payload; |
87 | __wsum csum; | 88 | __wsum csum; |
88 | u8 proto; | 89 | u8 proto; |
89 | struct net *net = sock_net(oldskb->sk); | ||
90 | 90 | ||
91 | if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) | 91 | if (oldskb->csum_bad || !nft_bridge_iphdr_validate(oldskb)) |
92 | return; | 92 | return; |
@@ -273,17 +273,17 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr, | |||
273 | case htons(ETH_P_IP): | 273 | case htons(ETH_P_IP): |
274 | switch (priv->type) { | 274 | switch (priv->type) { |
275 | case NFT_REJECT_ICMP_UNREACH: | 275 | case NFT_REJECT_ICMP_UNREACH: |
276 | nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, | 276 | nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, |
277 | pkt->hook, | 277 | pkt->in, pkt->hook, |
278 | priv->icmp_code); | 278 | priv->icmp_code); |
279 | break; | 279 | break; |
280 | case NFT_REJECT_TCP_RST: | 280 | case NFT_REJECT_TCP_RST: |
281 | nft_reject_br_send_v4_tcp_reset(pkt->skb, pkt->in, | 281 | nft_reject_br_send_v4_tcp_reset(pkt->net, pkt->skb, |
282 | pkt->hook); | 282 | pkt->in, pkt->hook); |
283 | break; | 283 | break; |
284 | case NFT_REJECT_ICMPX_UNREACH: | 284 | case NFT_REJECT_ICMPX_UNREACH: |
285 | nft_reject_br_send_v4_unreach(pkt->skb, pkt->in, | 285 | nft_reject_br_send_v4_unreach(pkt->net, pkt->skb, |
286 | pkt->hook, | 286 | pkt->in, pkt->hook, |
287 | nft_reject_icmp_code(priv->icmp_code)); | 287 | nft_reject_icmp_code(priv->icmp_code)); |
288 | break; | 288 | break; |
289 | } | 289 | } |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 1831f6353622..a5502898ea33 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -269,7 +269,7 @@ static void _ceph_msgr_exit(void) | |||
269 | } | 269 | } |
270 | 270 | ||
271 | BUG_ON(zero_page == NULL); | 271 | BUG_ON(zero_page == NULL); |
272 | page_cache_release(zero_page); | 272 | put_page(zero_page); |
273 | zero_page = NULL; | 273 | zero_page = NULL; |
274 | 274 | ||
275 | ceph_msgr_slab_exit(); | 275 | ceph_msgr_slab_exit(); |
@@ -282,7 +282,7 @@ int ceph_msgr_init(void) | |||
282 | 282 | ||
283 | BUG_ON(zero_page != NULL); | 283 | BUG_ON(zero_page != NULL); |
284 | zero_page = ZERO_PAGE(0); | 284 | zero_page = ZERO_PAGE(0); |
285 | page_cache_get(zero_page); | 285 | get_page(zero_page); |
286 | 286 | ||
287 | /* | 287 | /* |
288 | * The number of active work items is limited by the number of | 288 | * The number of active work items is limited by the number of |
@@ -1602,7 +1602,7 @@ static int write_partial_skip(struct ceph_connection *con) | |||
1602 | 1602 | ||
1603 | dout("%s %p %d left\n", __func__, con, con->out_skip); | 1603 | dout("%s %p %d left\n", __func__, con, con->out_skip); |
1604 | while (con->out_skip > 0) { | 1604 | while (con->out_skip > 0) { |
1605 | size_t size = min(con->out_skip, (int) PAGE_CACHE_SIZE); | 1605 | size_t size = min(con->out_skip, (int) PAGE_SIZE); |
1606 | 1606 | ||
1607 | ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, true); | 1607 | ret = ceph_tcp_sendpage(con->sock, zero_page, 0, size, true); |
1608 | if (ret <= 0) | 1608 | if (ret <= 0) |
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c index c7c220a736e5..6864007e64fc 100644 --- a/net/ceph/pagelist.c +++ b/net/ceph/pagelist.c | |||
@@ -56,7 +56,7 @@ int ceph_pagelist_append(struct ceph_pagelist *pl, const void *buf, size_t len) | |||
56 | size_t bit = pl->room; | 56 | size_t bit = pl->room; |
57 | int ret; | 57 | int ret; |
58 | 58 | ||
59 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), | 59 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_MASK), |
60 | buf, bit); | 60 | buf, bit); |
61 | pl->length += bit; | 61 | pl->length += bit; |
62 | pl->room -= bit; | 62 | pl->room -= bit; |
@@ -67,7 +67,7 @@ int ceph_pagelist_append(struct ceph_pagelist *pl, const void *buf, size_t len) | |||
67 | return ret; | 67 | return ret; |
68 | } | 68 | } |
69 | 69 | ||
70 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_CACHE_MASK), buf, len); | 70 | memcpy(pl->mapped_tail + (pl->length & ~PAGE_MASK), buf, len); |
71 | pl->length += len; | 71 | pl->length += len; |
72 | pl->room -= len; | 72 | pl->room -= len; |
73 | return 0; | 73 | return 0; |
diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index 10297f7a89ba..00d2601407c5 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c | |||
@@ -95,19 +95,19 @@ int ceph_copy_user_to_page_vector(struct page **pages, | |||
95 | loff_t off, size_t len) | 95 | loff_t off, size_t len) |
96 | { | 96 | { |
97 | int i = 0; | 97 | int i = 0; |
98 | int po = off & ~PAGE_CACHE_MASK; | 98 | int po = off & ~PAGE_MASK; |
99 | int left = len; | 99 | int left = len; |
100 | int l, bad; | 100 | int l, bad; |
101 | 101 | ||
102 | while (left > 0) { | 102 | while (left > 0) { |
103 | l = min_t(int, PAGE_CACHE_SIZE-po, left); | 103 | l = min_t(int, PAGE_SIZE-po, left); |
104 | bad = copy_from_user(page_address(pages[i]) + po, data, l); | 104 | bad = copy_from_user(page_address(pages[i]) + po, data, l); |
105 | if (bad == l) | 105 | if (bad == l) |
106 | return -EFAULT; | 106 | return -EFAULT; |
107 | data += l - bad; | 107 | data += l - bad; |
108 | left -= l - bad; | 108 | left -= l - bad; |
109 | po += l - bad; | 109 | po += l - bad; |
110 | if (po == PAGE_CACHE_SIZE) { | 110 | if (po == PAGE_SIZE) { |
111 | po = 0; | 111 | po = 0; |
112 | i++; | 112 | i++; |
113 | } | 113 | } |
@@ -121,17 +121,17 @@ void ceph_copy_to_page_vector(struct page **pages, | |||
121 | loff_t off, size_t len) | 121 | loff_t off, size_t len) |
122 | { | 122 | { |
123 | int i = 0; | 123 | int i = 0; |
124 | size_t po = off & ~PAGE_CACHE_MASK; | 124 | size_t po = off & ~PAGE_MASK; |
125 | size_t left = len; | 125 | size_t left = len; |
126 | 126 | ||
127 | while (left > 0) { | 127 | while (left > 0) { |
128 | size_t l = min_t(size_t, PAGE_CACHE_SIZE-po, left); | 128 | size_t l = min_t(size_t, PAGE_SIZE-po, left); |
129 | 129 | ||
130 | memcpy(page_address(pages[i]) + po, data, l); | 130 | memcpy(page_address(pages[i]) + po, data, l); |
131 | data += l; | 131 | data += l; |
132 | left -= l; | 132 | left -= l; |
133 | po += l; | 133 | po += l; |
134 | if (po == PAGE_CACHE_SIZE) { | 134 | if (po == PAGE_SIZE) { |
135 | po = 0; | 135 | po = 0; |
136 | i++; | 136 | i++; |
137 | } | 137 | } |
@@ -144,17 +144,17 @@ void ceph_copy_from_page_vector(struct page **pages, | |||
144 | loff_t off, size_t len) | 144 | loff_t off, size_t len) |
145 | { | 145 | { |
146 | int i = 0; | 146 | int i = 0; |
147 | size_t po = off & ~PAGE_CACHE_MASK; | 147 | size_t po = off & ~PAGE_MASK; |
148 | size_t left = len; | 148 | size_t left = len; |
149 | 149 | ||
150 | while (left > 0) { | 150 | while (left > 0) { |
151 | size_t l = min_t(size_t, PAGE_CACHE_SIZE-po, left); | 151 | size_t l = min_t(size_t, PAGE_SIZE-po, left); |
152 | 152 | ||
153 | memcpy(data, page_address(pages[i]) + po, l); | 153 | memcpy(data, page_address(pages[i]) + po, l); |
154 | data += l; | 154 | data += l; |
155 | left -= l; | 155 | left -= l; |
156 | po += l; | 156 | po += l; |
157 | if (po == PAGE_CACHE_SIZE) { | 157 | if (po == PAGE_SIZE) { |
158 | po = 0; | 158 | po = 0; |
159 | i++; | 159 | i++; |
160 | } | 160 | } |
@@ -168,25 +168,25 @@ EXPORT_SYMBOL(ceph_copy_from_page_vector); | |||
168 | */ | 168 | */ |
169 | void ceph_zero_page_vector_range(int off, int len, struct page **pages) | 169 | void ceph_zero_page_vector_range(int off, int len, struct page **pages) |
170 | { | 170 | { |
171 | int i = off >> PAGE_CACHE_SHIFT; | 171 | int i = off >> PAGE_SHIFT; |
172 | 172 | ||
173 | off &= ~PAGE_CACHE_MASK; | 173 | off &= ~PAGE_MASK; |
174 | 174 | ||
175 | dout("zero_page_vector_page %u~%u\n", off, len); | 175 | dout("zero_page_vector_page %u~%u\n", off, len); |
176 | 176 | ||
177 | /* leading partial page? */ | 177 | /* leading partial page? */ |
178 | if (off) { | 178 | if (off) { |
179 | int end = min((int)PAGE_CACHE_SIZE, off + len); | 179 | int end = min((int)PAGE_SIZE, off + len); |
180 | dout("zeroing %d %p head from %d\n", i, pages[i], | 180 | dout("zeroing %d %p head from %d\n", i, pages[i], |
181 | (int)off); | 181 | (int)off); |
182 | zero_user_segment(pages[i], off, end); | 182 | zero_user_segment(pages[i], off, end); |
183 | len -= (end - off); | 183 | len -= (end - off); |
184 | i++; | 184 | i++; |
185 | } | 185 | } |
186 | while (len >= PAGE_CACHE_SIZE) { | 186 | while (len >= PAGE_SIZE) { |
187 | dout("zeroing %d %p len=%d\n", i, pages[i], len); | 187 | dout("zeroing %d %p len=%d\n", i, pages[i], len); |
188 | zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE); | 188 | zero_user_segment(pages[i], 0, PAGE_SIZE); |
189 | len -= PAGE_CACHE_SIZE; | 189 | len -= PAGE_SIZE; |
190 | i++; | 190 | i++; |
191 | } | 191 | } |
192 | /* trailing partial page? */ | 192 | /* trailing partial page? */ |
diff --git a/net/core/dev.c b/net/core/dev.c index b9bcbe77d913..77a71cd68535 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4439,6 +4439,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff | |||
4439 | NAPI_GRO_CB(skb)->flush = 0; | 4439 | NAPI_GRO_CB(skb)->flush = 0; |
4440 | NAPI_GRO_CB(skb)->free = 0; | 4440 | NAPI_GRO_CB(skb)->free = 0; |
4441 | NAPI_GRO_CB(skb)->encap_mark = 0; | 4441 | NAPI_GRO_CB(skb)->encap_mark = 0; |
4442 | NAPI_GRO_CB(skb)->is_fou = 0; | ||
4442 | NAPI_GRO_CB(skb)->gro_remcsum_start = 0; | 4443 | NAPI_GRO_CB(skb)->gro_remcsum_start = 0; |
4443 | 4444 | ||
4444 | /* Setup for GRO checksum validation */ | 4445 | /* Setup for GRO checksum validation */ |
diff --git a/net/core/filter.c b/net/core/filter.c index b7177d01ecb0..ca7f832b2980 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -1149,7 +1149,8 @@ void bpf_prog_destroy(struct bpf_prog *fp) | |||
1149 | } | 1149 | } |
1150 | EXPORT_SYMBOL_GPL(bpf_prog_destroy); | 1150 | EXPORT_SYMBOL_GPL(bpf_prog_destroy); |
1151 | 1151 | ||
1152 | static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk) | 1152 | static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk, |
1153 | bool locked) | ||
1153 | { | 1154 | { |
1154 | struct sk_filter *fp, *old_fp; | 1155 | struct sk_filter *fp, *old_fp; |
1155 | 1156 | ||
@@ -1165,10 +1166,8 @@ static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk) | |||
1165 | return -ENOMEM; | 1166 | return -ENOMEM; |
1166 | } | 1167 | } |
1167 | 1168 | ||
1168 | old_fp = rcu_dereference_protected(sk->sk_filter, | 1169 | old_fp = rcu_dereference_protected(sk->sk_filter, locked); |
1169 | sock_owned_by_user(sk)); | ||
1170 | rcu_assign_pointer(sk->sk_filter, fp); | 1170 | rcu_assign_pointer(sk->sk_filter, fp); |
1171 | |||
1172 | if (old_fp) | 1171 | if (old_fp) |
1173 | sk_filter_uncharge(sk, old_fp); | 1172 | sk_filter_uncharge(sk, old_fp); |
1174 | 1173 | ||
@@ -1247,7 +1246,8 @@ struct bpf_prog *__get_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1247 | * occurs or there is insufficient memory for the filter a negative | 1246 | * occurs or there is insufficient memory for the filter a negative |
1248 | * errno code is returned. On success the return is zero. | 1247 | * errno code is returned. On success the return is zero. |
1249 | */ | 1248 | */ |
1250 | int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | 1249 | int __sk_attach_filter(struct sock_fprog *fprog, struct sock *sk, |
1250 | bool locked) | ||
1251 | { | 1251 | { |
1252 | struct bpf_prog *prog = __get_filter(fprog, sk); | 1252 | struct bpf_prog *prog = __get_filter(fprog, sk); |
1253 | int err; | 1253 | int err; |
@@ -1255,7 +1255,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1255 | if (IS_ERR(prog)) | 1255 | if (IS_ERR(prog)) |
1256 | return PTR_ERR(prog); | 1256 | return PTR_ERR(prog); |
1257 | 1257 | ||
1258 | err = __sk_attach_prog(prog, sk); | 1258 | err = __sk_attach_prog(prog, sk, locked); |
1259 | if (err < 0) { | 1259 | if (err < 0) { |
1260 | __bpf_prog_release(prog); | 1260 | __bpf_prog_release(prog); |
1261 | return err; | 1261 | return err; |
@@ -1263,7 +1263,12 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
1263 | 1263 | ||
1264 | return 0; | 1264 | return 0; |
1265 | } | 1265 | } |
1266 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 1266 | EXPORT_SYMBOL_GPL(__sk_attach_filter); |
1267 | |||
1268 | int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | ||
1269 | { | ||
1270 | return __sk_attach_filter(fprog, sk, sock_owned_by_user(sk)); | ||
1271 | } | ||
1267 | 1272 | ||
1268 | int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk) | 1273 | int sk_reuseport_attach_filter(struct sock_fprog *fprog, struct sock *sk) |
1269 | { | 1274 | { |
@@ -1309,7 +1314,7 @@ int sk_attach_bpf(u32 ufd, struct sock *sk) | |||
1309 | if (IS_ERR(prog)) | 1314 | if (IS_ERR(prog)) |
1310 | return PTR_ERR(prog); | 1315 | return PTR_ERR(prog); |
1311 | 1316 | ||
1312 | err = __sk_attach_prog(prog, sk); | 1317 | err = __sk_attach_prog(prog, sk, sock_owned_by_user(sk)); |
1313 | if (err < 0) { | 1318 | if (err < 0) { |
1314 | bpf_prog_put(prog); | 1319 | bpf_prog_put(prog); |
1315 | return err; | 1320 | return err; |
@@ -1764,6 +1769,7 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1764 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { | 1769 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { |
1765 | switch (size) { | 1770 | switch (size) { |
1766 | case offsetof(struct bpf_tunnel_key, tunnel_label): | 1771 | case offsetof(struct bpf_tunnel_key, tunnel_label): |
1772 | case offsetof(struct bpf_tunnel_key, tunnel_ext): | ||
1767 | goto set_compat; | 1773 | goto set_compat; |
1768 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): | 1774 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): |
1769 | /* Fixup deprecated structure layouts here, so we have | 1775 | /* Fixup deprecated structure layouts here, so we have |
@@ -1849,6 +1855,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1849 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { | 1855 | if (unlikely(size != sizeof(struct bpf_tunnel_key))) { |
1850 | switch (size) { | 1856 | switch (size) { |
1851 | case offsetof(struct bpf_tunnel_key, tunnel_label): | 1857 | case offsetof(struct bpf_tunnel_key, tunnel_label): |
1858 | case offsetof(struct bpf_tunnel_key, tunnel_ext): | ||
1852 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): | 1859 | case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): |
1853 | /* Fixup deprecated structure layouts here, so we have | 1860 | /* Fixup deprecated structure layouts here, so we have |
1854 | * a common path later on. | 1861 | * a common path later on. |
@@ -1861,7 +1868,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) | |||
1861 | return -EINVAL; | 1868 | return -EINVAL; |
1862 | } | 1869 | } |
1863 | } | 1870 | } |
1864 | if (unlikely(!(flags & BPF_F_TUNINFO_IPV6) && from->tunnel_label)) | 1871 | if (unlikely((!(flags & BPF_F_TUNINFO_IPV6) && from->tunnel_label) || |
1872 | from->tunnel_ext)) | ||
1865 | return -EINVAL; | 1873 | return -EINVAL; |
1866 | 1874 | ||
1867 | skb_dst_drop(skb); | 1875 | skb_dst_drop(skb); |
@@ -2247,7 +2255,7 @@ static int __init register_sk_filter_ops(void) | |||
2247 | } | 2255 | } |
2248 | late_initcall(register_sk_filter_ops); | 2256 | late_initcall(register_sk_filter_ops); |
2249 | 2257 | ||
2250 | int sk_detach_filter(struct sock *sk) | 2258 | int __sk_detach_filter(struct sock *sk, bool locked) |
2251 | { | 2259 | { |
2252 | int ret = -ENOENT; | 2260 | int ret = -ENOENT; |
2253 | struct sk_filter *filter; | 2261 | struct sk_filter *filter; |
@@ -2255,8 +2263,7 @@ int sk_detach_filter(struct sock *sk) | |||
2255 | if (sock_flag(sk, SOCK_FILTER_LOCKED)) | 2263 | if (sock_flag(sk, SOCK_FILTER_LOCKED)) |
2256 | return -EPERM; | 2264 | return -EPERM; |
2257 | 2265 | ||
2258 | filter = rcu_dereference_protected(sk->sk_filter, | 2266 | filter = rcu_dereference_protected(sk->sk_filter, locked); |
2259 | sock_owned_by_user(sk)); | ||
2260 | if (filter) { | 2267 | if (filter) { |
2261 | RCU_INIT_POINTER(sk->sk_filter, NULL); | 2268 | RCU_INIT_POINTER(sk->sk_filter, NULL); |
2262 | sk_filter_uncharge(sk, filter); | 2269 | sk_filter_uncharge(sk, filter); |
@@ -2265,7 +2272,12 @@ int sk_detach_filter(struct sock *sk) | |||
2265 | 2272 | ||
2266 | return ret; | 2273 | return ret; |
2267 | } | 2274 | } |
2268 | EXPORT_SYMBOL_GPL(sk_detach_filter); | 2275 | EXPORT_SYMBOL_GPL(__sk_detach_filter); |
2276 | |||
2277 | int sk_detach_filter(struct sock *sk) | ||
2278 | { | ||
2279 | return __sk_detach_filter(sk, sock_owned_by_user(sk)); | ||
2280 | } | ||
2269 | 2281 | ||
2270 | int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, | 2282 | int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf, |
2271 | unsigned int len) | 2283 | unsigned int len) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f2066772d0f3..a75f7e94b445 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -909,6 +909,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, | |||
909 | + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */ | 909 | + rtnl_link_get_af_size(dev, ext_filter_mask) /* IFLA_AF_SPEC */ |
910 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ | 910 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */ |
911 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ | 911 | + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_SWITCH_ID */ |
912 | + nla_total_size(IFNAMSIZ) /* IFLA_PHYS_PORT_NAME */ | ||
912 | + nla_total_size(1); /* IFLA_PROTO_DOWN */ | 913 | + nla_total_size(1); /* IFLA_PROTO_DOWN */ |
913 | 914 | ||
914 | } | 915 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index b67b9aedb230..7e73c26b6bb4 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -221,7 +221,8 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
221 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 221 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
222 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 222 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
223 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | 223 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
224 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" | 224 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_KCM" , |
225 | "sk_lock-AF_MAX" | ||
225 | }; | 226 | }; |
226 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 227 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
227 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 228 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
@@ -237,7 +238,8 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
237 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 238 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
238 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 239 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
239 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | 240 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
240 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" | 241 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_KCM" , |
242 | "slock-AF_MAX" | ||
241 | }; | 243 | }; |
242 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 244 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
243 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 245 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
@@ -253,7 +255,8 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
253 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 255 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
254 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 256 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
255 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | 257 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
256 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" | 258 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_KCM" , |
259 | "clock-AF_MAX" | ||
257 | }; | 260 | }; |
258 | 261 | ||
259 | /* | 262 | /* |
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index a0586b4a197d..a39068b4a4d9 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c | |||
@@ -195,6 +195,17 @@ static struct sk_buff **fou_gro_receive(struct sk_buff **head, | |||
195 | u8 proto = NAPI_GRO_CB(skb)->proto; | 195 | u8 proto = NAPI_GRO_CB(skb)->proto; |
196 | const struct net_offload **offloads; | 196 | const struct net_offload **offloads; |
197 | 197 | ||
198 | /* We can clear the encap_mark for FOU as we are essentially doing | ||
199 | * one of two possible things. We are either adding an L4 tunnel | ||
200 | * header to the outer L3 tunnel header, or we are are simply | ||
201 | * treating the GRE tunnel header as though it is a UDP protocol | ||
202 | * specific header such as VXLAN or GENEVE. | ||
203 | */ | ||
204 | NAPI_GRO_CB(skb)->encap_mark = 0; | ||
205 | |||
206 | /* Flag this frame as already having an outer encap header */ | ||
207 | NAPI_GRO_CB(skb)->is_fou = 1; | ||
208 | |||
198 | rcu_read_lock(); | 209 | rcu_read_lock(); |
199 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | 210 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; |
200 | ops = rcu_dereference(offloads[proto]); | 211 | ops = rcu_dereference(offloads[proto]); |
@@ -352,6 +363,17 @@ static struct sk_buff **gue_gro_receive(struct sk_buff **head, | |||
352 | } | 363 | } |
353 | } | 364 | } |
354 | 365 | ||
366 | /* We can clear the encap_mark for GUE as we are essentially doing | ||
367 | * one of two possible things. We are either adding an L4 tunnel | ||
368 | * header to the outer L3 tunnel header, or we are are simply | ||
369 | * treating the GRE tunnel header as though it is a UDP protocol | ||
370 | * specific header such as VXLAN or GENEVE. | ||
371 | */ | ||
372 | NAPI_GRO_CB(skb)->encap_mark = 0; | ||
373 | |||
374 | /* Flag this frame as already having an outer encap header */ | ||
375 | NAPI_GRO_CB(skb)->is_fou = 1; | ||
376 | |||
355 | rcu_read_lock(); | 377 | rcu_read_lock(); |
356 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; | 378 | offloads = NAPI_GRO_CB(skb)->is_ipv6 ? inet6_offloads : inet_offloads; |
357 | ops = rcu_dereference(offloads[guehdr->proto_ctype]); | 379 | ops = rcu_dereference(offloads[guehdr->proto_ctype]); |
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c index c47539d04b88..6a5bd4317866 100644 --- a/net/ipv4/gre_offload.c +++ b/net/ipv4/gre_offload.c | |||
@@ -150,6 +150,14 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head, | |||
150 | if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0) | 150 | if ((greh->flags & ~(GRE_KEY|GRE_CSUM)) != 0) |
151 | goto out; | 151 | goto out; |
152 | 152 | ||
153 | /* We can only support GRE_CSUM if we can track the location of | ||
154 | * the GRE header. In the case of FOU/GUE we cannot because the | ||
155 | * outer UDP header displaces the GRE header leaving us in a state | ||
156 | * of limbo. | ||
157 | */ | ||
158 | if ((greh->flags & GRE_CSUM) && NAPI_GRO_CB(skb)->is_fou) | ||
159 | goto out; | ||
160 | |||
153 | type = greh->protocol; | 161 | type = greh->protocol; |
154 | 162 | ||
155 | rcu_read_lock(); | 163 | rcu_read_lock(); |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 31936d387cfd..af5d1f38217f 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -862,9 +862,16 @@ static void __gre_tunnel_init(struct net_device *dev) | |||
862 | dev->hw_features |= GRE_FEATURES; | 862 | dev->hw_features |= GRE_FEATURES; |
863 | 863 | ||
864 | if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) { | 864 | if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) { |
865 | /* TCP offload with GRE SEQ is not supported. */ | 865 | /* TCP offload with GRE SEQ is not supported, nor |
866 | dev->features |= NETIF_F_GSO_SOFTWARE; | 866 | * can we support 2 levels of outer headers requiring |
867 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | 867 | * an update. |
868 | */ | ||
869 | if (!(tunnel->parms.o_flags & TUNNEL_CSUM) || | ||
870 | (tunnel->encap.type == TUNNEL_ENCAP_NONE)) { | ||
871 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
872 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
873 | } | ||
874 | |||
868 | /* Can use a lockless transmit, unless we generate | 875 | /* Can use a lockless transmit, unless we generate |
869 | * output sequences | 876 | * output sequences |
870 | */ | 877 | */ |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 02dd990af542..6165f30c4d72 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
@@ -372,8 +372,8 @@ static int ip6_tun_fill_encap_info(struct sk_buff *skb, | |||
372 | if (nla_put_be64(skb, LWTUNNEL_IP6_ID, tun_info->key.tun_id) || | 372 | if (nla_put_be64(skb, LWTUNNEL_IP6_ID, tun_info->key.tun_id) || |
373 | nla_put_in6_addr(skb, LWTUNNEL_IP6_DST, &tun_info->key.u.ipv6.dst) || | 373 | nla_put_in6_addr(skb, LWTUNNEL_IP6_DST, &tun_info->key.u.ipv6.dst) || |
374 | nla_put_in6_addr(skb, LWTUNNEL_IP6_SRC, &tun_info->key.u.ipv6.src) || | 374 | nla_put_in6_addr(skb, LWTUNNEL_IP6_SRC, &tun_info->key.u.ipv6.src) || |
375 | nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.tos) || | 375 | nla_put_u8(skb, LWTUNNEL_IP6_TC, tun_info->key.tos) || |
376 | nla_put_u8(skb, LWTUNNEL_IP6_TC, tun_info->key.ttl) || | 376 | nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.ttl) || |
377 | nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags)) | 377 | nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags)) |
378 | return -ENOMEM; | 378 | return -ENOMEM; |
379 | 379 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index bf081927e06b..4133b0f513af 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -359,11 +359,12 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
359 | } | 359 | } |
360 | 360 | ||
361 | /* All zeroes == unconditional rule. */ | 361 | /* All zeroes == unconditional rule. */ |
362 | static inline bool unconditional(const struct arpt_arp *arp) | 362 | static inline bool unconditional(const struct arpt_entry *e) |
363 | { | 363 | { |
364 | static const struct arpt_arp uncond; | 364 | static const struct arpt_arp uncond; |
365 | 365 | ||
366 | return memcmp(arp, &uncond, sizeof(uncond)) == 0; | 366 | return e->target_offset == sizeof(struct arpt_entry) && |
367 | memcmp(&e->arp, &uncond, sizeof(uncond)) == 0; | ||
367 | } | 368 | } |
368 | 369 | ||
369 | /* Figures out from what hook each rule can be called: returns 0 if | 370 | /* Figures out from what hook each rule can be called: returns 0 if |
@@ -402,11 +403,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, | |||
402 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); | 403 | |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); |
403 | 404 | ||
404 | /* Unconditional return/END. */ | 405 | /* Unconditional return/END. */ |
405 | if ((e->target_offset == sizeof(struct arpt_entry) && | 406 | if ((unconditional(e) && |
406 | (strcmp(t->target.u.user.name, | 407 | (strcmp(t->target.u.user.name, |
407 | XT_STANDARD_TARGET) == 0) && | 408 | XT_STANDARD_TARGET) == 0) && |
408 | t->verdict < 0 && unconditional(&e->arp)) || | 409 | t->verdict < 0) || visited) { |
409 | visited) { | ||
410 | unsigned int oldpos, size; | 410 | unsigned int oldpos, size; |
411 | 411 | ||
412 | if ((strcmp(t->target.u.user.name, | 412 | if ((strcmp(t->target.u.user.name, |
@@ -474,14 +474,12 @@ next: | |||
474 | return 1; | 474 | return 1; |
475 | } | 475 | } |
476 | 476 | ||
477 | static inline int check_entry(const struct arpt_entry *e, const char *name) | 477 | static inline int check_entry(const struct arpt_entry *e) |
478 | { | 478 | { |
479 | const struct xt_entry_target *t; | 479 | const struct xt_entry_target *t; |
480 | 480 | ||
481 | if (!arp_checkentry(&e->arp)) { | 481 | if (!arp_checkentry(&e->arp)) |
482 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); | ||
483 | return -EINVAL; | 482 | return -EINVAL; |
484 | } | ||
485 | 483 | ||
486 | if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) | 484 | if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) |
487 | return -EINVAL; | 485 | return -EINVAL; |
@@ -522,10 +520,6 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) | |||
522 | struct xt_target *target; | 520 | struct xt_target *target; |
523 | int ret; | 521 | int ret; |
524 | 522 | ||
525 | ret = check_entry(e, name); | ||
526 | if (ret) | ||
527 | return ret; | ||
528 | |||
529 | e->counters.pcnt = xt_percpu_counter_alloc(); | 523 | e->counters.pcnt = xt_percpu_counter_alloc(); |
530 | if (IS_ERR_VALUE(e->counters.pcnt)) | 524 | if (IS_ERR_VALUE(e->counters.pcnt)) |
531 | return -ENOMEM; | 525 | return -ENOMEM; |
@@ -557,7 +551,7 @@ static bool check_underflow(const struct arpt_entry *e) | |||
557 | const struct xt_entry_target *t; | 551 | const struct xt_entry_target *t; |
558 | unsigned int verdict; | 552 | unsigned int verdict; |
559 | 553 | ||
560 | if (!unconditional(&e->arp)) | 554 | if (!unconditional(e)) |
561 | return false; | 555 | return false; |
562 | t = arpt_get_target_c(e); | 556 | t = arpt_get_target_c(e); |
563 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 557 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -576,9 +570,11 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
576 | unsigned int valid_hooks) | 570 | unsigned int valid_hooks) |
577 | { | 571 | { |
578 | unsigned int h; | 572 | unsigned int h; |
573 | int err; | ||
579 | 574 | ||
580 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || | 575 | if ((unsigned long)e % __alignof__(struct arpt_entry) != 0 || |
581 | (unsigned char *)e + sizeof(struct arpt_entry) >= limit) { | 576 | (unsigned char *)e + sizeof(struct arpt_entry) >= limit || |
577 | (unsigned char *)e + e->next_offset > limit) { | ||
582 | duprintf("Bad offset %p\n", e); | 578 | duprintf("Bad offset %p\n", e); |
583 | return -EINVAL; | 579 | return -EINVAL; |
584 | } | 580 | } |
@@ -590,6 +586,10 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
590 | return -EINVAL; | 586 | return -EINVAL; |
591 | } | 587 | } |
592 | 588 | ||
589 | err = check_entry(e); | ||
590 | if (err) | ||
591 | return err; | ||
592 | |||
593 | /* Check hooks & underflows */ | 593 | /* Check hooks & underflows */ |
594 | for (h = 0; h < NF_ARP_NUMHOOKS; h++) { | 594 | for (h = 0; h < NF_ARP_NUMHOOKS; h++) { |
595 | if (!(valid_hooks & (1 << h))) | 595 | if (!(valid_hooks & (1 << h))) |
@@ -598,9 +598,9 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, | |||
598 | newinfo->hook_entry[h] = hook_entries[h]; | 598 | newinfo->hook_entry[h] = hook_entries[h]; |
599 | if ((unsigned char *)e - base == underflows[h]) { | 599 | if ((unsigned char *)e - base == underflows[h]) { |
600 | if (!check_underflow(e)) { | 600 | if (!check_underflow(e)) { |
601 | pr_err("Underflows must be unconditional and " | 601 | pr_debug("Underflows must be unconditional and " |
602 | "use the STANDARD target with " | 602 | "use the STANDARD target with " |
603 | "ACCEPT/DROP\n"); | 603 | "ACCEPT/DROP\n"); |
604 | return -EINVAL; | 604 | return -EINVAL; |
605 | } | 605 | } |
606 | newinfo->underflow[h] = underflows[h]; | 606 | newinfo->underflow[h] = underflows[h]; |
@@ -969,6 +969,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr, | |||
969 | sizeof(struct arpt_get_entries) + get.size); | 969 | sizeof(struct arpt_get_entries) + get.size); |
970 | return -EINVAL; | 970 | return -EINVAL; |
971 | } | 971 | } |
972 | get.name[sizeof(get.name) - 1] = '\0'; | ||
972 | 973 | ||
973 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); | 974 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
974 | if (!IS_ERR_OR_NULL(t)) { | 975 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1233,7 +1234,8 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1233 | 1234 | ||
1234 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1235 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1235 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || | 1236 | if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 || |
1236 | (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit) { | 1237 | (unsigned char *)e + sizeof(struct compat_arpt_entry) >= limit || |
1238 | (unsigned char *)e + e->next_offset > limit) { | ||
1237 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1239 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1238 | return -EINVAL; | 1240 | return -EINVAL; |
1239 | } | 1241 | } |
@@ -1246,7 +1248,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, | |||
1246 | } | 1248 | } |
1247 | 1249 | ||
1248 | /* For purposes of check_entry casting the compat entry is fine */ | 1250 | /* For purposes of check_entry casting the compat entry is fine */ |
1249 | ret = check_entry((struct arpt_entry *)e, name); | 1251 | ret = check_entry((struct arpt_entry *)e); |
1250 | if (ret) | 1252 | if (ret) |
1251 | return ret; | 1253 | return ret; |
1252 | 1254 | ||
@@ -1662,6 +1664,7 @@ static int compat_get_entries(struct net *net, | |||
1662 | *len, sizeof(get) + get.size); | 1664 | *len, sizeof(get) + get.size); |
1663 | return -EINVAL; | 1665 | return -EINVAL; |
1664 | } | 1666 | } |
1667 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1665 | 1668 | ||
1666 | xt_compat_lock(NFPROTO_ARP); | 1669 | xt_compat_lock(NFPROTO_ARP); |
1667 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); | 1670 | t = xt_find_table_lock(net, NFPROTO_ARP, get.name); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e53f8d6f326d..631c100a1338 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -168,11 +168,12 @@ get_entry(const void *base, unsigned int offset) | |||
168 | 168 | ||
169 | /* All zeroes == unconditional rule. */ | 169 | /* All zeroes == unconditional rule. */ |
170 | /* Mildly perf critical (only if packet tracing is on) */ | 170 | /* Mildly perf critical (only if packet tracing is on) */ |
171 | static inline bool unconditional(const struct ipt_ip *ip) | 171 | static inline bool unconditional(const struct ipt_entry *e) |
172 | { | 172 | { |
173 | static const struct ipt_ip uncond; | 173 | static const struct ipt_ip uncond; |
174 | 174 | ||
175 | return memcmp(ip, &uncond, sizeof(uncond)) == 0; | 175 | return e->target_offset == sizeof(struct ipt_entry) && |
176 | memcmp(&e->ip, &uncond, sizeof(uncond)) == 0; | ||
176 | #undef FWINV | 177 | #undef FWINV |
177 | } | 178 | } |
178 | 179 | ||
@@ -229,11 +230,10 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, | |||
229 | } else if (s == e) { | 230 | } else if (s == e) { |
230 | (*rulenum)++; | 231 | (*rulenum)++; |
231 | 232 | ||
232 | if (s->target_offset == sizeof(struct ipt_entry) && | 233 | if (unconditional(s) && |
233 | strcmp(t->target.u.kernel.target->name, | 234 | strcmp(t->target.u.kernel.target->name, |
234 | XT_STANDARD_TARGET) == 0 && | 235 | XT_STANDARD_TARGET) == 0 && |
235 | t->verdict < 0 && | 236 | t->verdict < 0) { |
236 | unconditional(&s->ip)) { | ||
237 | /* Tail of chains: STANDARD target (return/policy) */ | 237 | /* Tail of chains: STANDARD target (return/policy) */ |
238 | *comment = *chainname == hookname | 238 | *comment = *chainname == hookname |
239 | ? comments[NF_IP_TRACE_COMMENT_POLICY] | 239 | ? comments[NF_IP_TRACE_COMMENT_POLICY] |
@@ -476,11 +476,10 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
476 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 476 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
477 | 477 | ||
478 | /* Unconditional return/END. */ | 478 | /* Unconditional return/END. */ |
479 | if ((e->target_offset == sizeof(struct ipt_entry) && | 479 | if ((unconditional(e) && |
480 | (strcmp(t->target.u.user.name, | 480 | (strcmp(t->target.u.user.name, |
481 | XT_STANDARD_TARGET) == 0) && | 481 | XT_STANDARD_TARGET) == 0) && |
482 | t->verdict < 0 && unconditional(&e->ip)) || | 482 | t->verdict < 0) || visited) { |
483 | visited) { | ||
484 | unsigned int oldpos, size; | 483 | unsigned int oldpos, size; |
485 | 484 | ||
486 | if ((strcmp(t->target.u.user.name, | 485 | if ((strcmp(t->target.u.user.name, |
@@ -569,14 +568,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) | |||
569 | } | 568 | } |
570 | 569 | ||
571 | static int | 570 | static int |
572 | check_entry(const struct ipt_entry *e, const char *name) | 571 | check_entry(const struct ipt_entry *e) |
573 | { | 572 | { |
574 | const struct xt_entry_target *t; | 573 | const struct xt_entry_target *t; |
575 | 574 | ||
576 | if (!ip_checkentry(&e->ip)) { | 575 | if (!ip_checkentry(&e->ip)) |
577 | duprintf("ip check failed %p %s.\n", e, name); | ||
578 | return -EINVAL; | 576 | return -EINVAL; |
579 | } | ||
580 | 577 | ||
581 | if (e->target_offset + sizeof(struct xt_entry_target) > | 578 | if (e->target_offset + sizeof(struct xt_entry_target) > |
582 | e->next_offset) | 579 | e->next_offset) |
@@ -666,10 +663,6 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, | |||
666 | struct xt_mtchk_param mtpar; | 663 | struct xt_mtchk_param mtpar; |
667 | struct xt_entry_match *ematch; | 664 | struct xt_entry_match *ematch; |
668 | 665 | ||
669 | ret = check_entry(e, name); | ||
670 | if (ret) | ||
671 | return ret; | ||
672 | |||
673 | e->counters.pcnt = xt_percpu_counter_alloc(); | 666 | e->counters.pcnt = xt_percpu_counter_alloc(); |
674 | if (IS_ERR_VALUE(e->counters.pcnt)) | 667 | if (IS_ERR_VALUE(e->counters.pcnt)) |
675 | return -ENOMEM; | 668 | return -ENOMEM; |
@@ -721,7 +714,7 @@ static bool check_underflow(const struct ipt_entry *e) | |||
721 | const struct xt_entry_target *t; | 714 | const struct xt_entry_target *t; |
722 | unsigned int verdict; | 715 | unsigned int verdict; |
723 | 716 | ||
724 | if (!unconditional(&e->ip)) | 717 | if (!unconditional(e)) |
725 | return false; | 718 | return false; |
726 | t = ipt_get_target_c(e); | 719 | t = ipt_get_target_c(e); |
727 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 720 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -741,9 +734,11 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
741 | unsigned int valid_hooks) | 734 | unsigned int valid_hooks) |
742 | { | 735 | { |
743 | unsigned int h; | 736 | unsigned int h; |
737 | int err; | ||
744 | 738 | ||
745 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || | 739 | if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 || |
746 | (unsigned char *)e + sizeof(struct ipt_entry) >= limit) { | 740 | (unsigned char *)e + sizeof(struct ipt_entry) >= limit || |
741 | (unsigned char *)e + e->next_offset > limit) { | ||
747 | duprintf("Bad offset %p\n", e); | 742 | duprintf("Bad offset %p\n", e); |
748 | return -EINVAL; | 743 | return -EINVAL; |
749 | } | 744 | } |
@@ -755,6 +750,10 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
755 | return -EINVAL; | 750 | return -EINVAL; |
756 | } | 751 | } |
757 | 752 | ||
753 | err = check_entry(e); | ||
754 | if (err) | ||
755 | return err; | ||
756 | |||
758 | /* Check hooks & underflows */ | 757 | /* Check hooks & underflows */ |
759 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { | 758 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { |
760 | if (!(valid_hooks & (1 << h))) | 759 | if (!(valid_hooks & (1 << h))) |
@@ -763,9 +762,9 @@ check_entry_size_and_hooks(struct ipt_entry *e, | |||
763 | newinfo->hook_entry[h] = hook_entries[h]; | 762 | newinfo->hook_entry[h] = hook_entries[h]; |
764 | if ((unsigned char *)e - base == underflows[h]) { | 763 | if ((unsigned char *)e - base == underflows[h]) { |
765 | if (!check_underflow(e)) { | 764 | if (!check_underflow(e)) { |
766 | pr_err("Underflows must be unconditional and " | 765 | pr_debug("Underflows must be unconditional and " |
767 | "use the STANDARD target with " | 766 | "use the STANDARD target with " |
768 | "ACCEPT/DROP\n"); | 767 | "ACCEPT/DROP\n"); |
769 | return -EINVAL; | 768 | return -EINVAL; |
770 | } | 769 | } |
771 | newinfo->underflow[h] = underflows[h]; | 770 | newinfo->underflow[h] = underflows[h]; |
@@ -1157,6 +1156,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, | |||
1157 | *len, sizeof(get) + get.size); | 1156 | *len, sizeof(get) + get.size); |
1158 | return -EINVAL; | 1157 | return -EINVAL; |
1159 | } | 1158 | } |
1159 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1160 | 1160 | ||
1161 | t = xt_find_table_lock(net, AF_INET, get.name); | 1161 | t = xt_find_table_lock(net, AF_INET, get.name); |
1162 | if (!IS_ERR_OR_NULL(t)) { | 1162 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1493,7 +1493,8 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1493 | 1493 | ||
1494 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1494 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1495 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || | 1495 | if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 || |
1496 | (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) { | 1496 | (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit || |
1497 | (unsigned char *)e + e->next_offset > limit) { | ||
1497 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1498 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1498 | return -EINVAL; | 1499 | return -EINVAL; |
1499 | } | 1500 | } |
@@ -1506,7 +1507,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, | |||
1506 | } | 1507 | } |
1507 | 1508 | ||
1508 | /* For purposes of check_entry casting the compat entry is fine */ | 1509 | /* For purposes of check_entry casting the compat entry is fine */ |
1509 | ret = check_entry((struct ipt_entry *)e, name); | 1510 | ret = check_entry((struct ipt_entry *)e); |
1510 | if (ret) | 1511 | if (ret) |
1511 | return ret; | 1512 | return ret; |
1512 | 1513 | ||
@@ -1935,6 +1936,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr, | |||
1935 | *len, sizeof(get) + get.size); | 1936 | *len, sizeof(get) + get.size); |
1936 | return -EINVAL; | 1937 | return -EINVAL; |
1937 | } | 1938 | } |
1939 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1938 | 1940 | ||
1939 | xt_compat_lock(AF_INET); | 1941 | xt_compat_lock(AF_INET); |
1940 | t = xt_find_table_lock(net, AF_INET, get.name); | 1942 | t = xt_find_table_lock(net, AF_INET, get.name); |
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c index 7b8fbb352877..db5b87509446 100644 --- a/net/ipv4/netfilter/ipt_SYNPROXY.c +++ b/net/ipv4/netfilter/ipt_SYNPROXY.c | |||
@@ -18,10 +18,10 @@ | |||
18 | #include <net/netfilter/nf_conntrack_synproxy.h> | 18 | #include <net/netfilter/nf_conntrack_synproxy.h> |
19 | 19 | ||
20 | static struct iphdr * | 20 | static struct iphdr * |
21 | synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) | 21 | synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, |
22 | __be32 daddr) | ||
22 | { | 23 | { |
23 | struct iphdr *iph; | 24 | struct iphdr *iph; |
24 | struct net *net = sock_net(skb->sk); | ||
25 | 25 | ||
26 | skb_reset_network_header(skb); | 26 | skb_reset_network_header(skb); |
27 | iph = (struct iphdr *)skb_put(skb, sizeof(*iph)); | 27 | iph = (struct iphdr *)skb_put(skb, sizeof(*iph)); |
@@ -40,14 +40,12 @@ synproxy_build_ip(struct sk_buff *skb, __be32 saddr, __be32 daddr) | |||
40 | } | 40 | } |
41 | 41 | ||
42 | static void | 42 | static void |
43 | synproxy_send_tcp(const struct synproxy_net *snet, | 43 | synproxy_send_tcp(struct net *net, |
44 | const struct sk_buff *skb, struct sk_buff *nskb, | 44 | const struct sk_buff *skb, struct sk_buff *nskb, |
45 | struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, | 45 | struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, |
46 | struct iphdr *niph, struct tcphdr *nth, | 46 | struct iphdr *niph, struct tcphdr *nth, |
47 | unsigned int tcp_hdr_size) | 47 | unsigned int tcp_hdr_size) |
48 | { | 48 | { |
49 | struct net *net = nf_ct_net(snet->tmpl); | ||
50 | |||
51 | nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); | 49 | nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); |
52 | nskb->ip_summed = CHECKSUM_PARTIAL; | 50 | nskb->ip_summed = CHECKSUM_PARTIAL; |
53 | nskb->csum_start = (unsigned char *)nth - nskb->head; | 51 | nskb->csum_start = (unsigned char *)nth - nskb->head; |
@@ -72,7 +70,7 @@ free_nskb: | |||
72 | } | 70 | } |
73 | 71 | ||
74 | static void | 72 | static void |
75 | synproxy_send_client_synack(const struct synproxy_net *snet, | 73 | synproxy_send_client_synack(struct net *net, |
76 | const struct sk_buff *skb, const struct tcphdr *th, | 74 | const struct sk_buff *skb, const struct tcphdr *th, |
77 | const struct synproxy_options *opts) | 75 | const struct synproxy_options *opts) |
78 | { | 76 | { |
@@ -91,7 +89,7 @@ synproxy_send_client_synack(const struct synproxy_net *snet, | |||
91 | return; | 89 | return; |
92 | skb_reserve(nskb, MAX_TCP_HEADER); | 90 | skb_reserve(nskb, MAX_TCP_HEADER); |
93 | 91 | ||
94 | niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); | 92 | niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); |
95 | 93 | ||
96 | skb_reset_transport_header(nskb); | 94 | skb_reset_transport_header(nskb); |
97 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 95 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -109,15 +107,16 @@ synproxy_send_client_synack(const struct synproxy_net *snet, | |||
109 | 107 | ||
110 | synproxy_build_options(nth, opts); | 108 | synproxy_build_options(nth, opts); |
111 | 109 | ||
112 | synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, | 110 | synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, |
113 | niph, nth, tcp_hdr_size); | 111 | niph, nth, tcp_hdr_size); |
114 | } | 112 | } |
115 | 113 | ||
116 | static void | 114 | static void |
117 | synproxy_send_server_syn(const struct synproxy_net *snet, | 115 | synproxy_send_server_syn(struct net *net, |
118 | const struct sk_buff *skb, const struct tcphdr *th, | 116 | const struct sk_buff *skb, const struct tcphdr *th, |
119 | const struct synproxy_options *opts, u32 recv_seq) | 117 | const struct synproxy_options *opts, u32 recv_seq) |
120 | { | 118 | { |
119 | struct synproxy_net *snet = synproxy_pernet(net); | ||
121 | struct sk_buff *nskb; | 120 | struct sk_buff *nskb; |
122 | struct iphdr *iph, *niph; | 121 | struct iphdr *iph, *niph; |
123 | struct tcphdr *nth; | 122 | struct tcphdr *nth; |
@@ -132,7 +131,7 @@ synproxy_send_server_syn(const struct synproxy_net *snet, | |||
132 | return; | 131 | return; |
133 | skb_reserve(nskb, MAX_TCP_HEADER); | 132 | skb_reserve(nskb, MAX_TCP_HEADER); |
134 | 133 | ||
135 | niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); | 134 | niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); |
136 | 135 | ||
137 | skb_reset_transport_header(nskb); | 136 | skb_reset_transport_header(nskb); |
138 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 137 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -153,12 +152,12 @@ synproxy_send_server_syn(const struct synproxy_net *snet, | |||
153 | 152 | ||
154 | synproxy_build_options(nth, opts); | 153 | synproxy_build_options(nth, opts); |
155 | 154 | ||
156 | synproxy_send_tcp(snet, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, | 155 | synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, |
157 | niph, nth, tcp_hdr_size); | 156 | niph, nth, tcp_hdr_size); |
158 | } | 157 | } |
159 | 158 | ||
160 | static void | 159 | static void |
161 | synproxy_send_server_ack(const struct synproxy_net *snet, | 160 | synproxy_send_server_ack(struct net *net, |
162 | const struct ip_ct_tcp *state, | 161 | const struct ip_ct_tcp *state, |
163 | const struct sk_buff *skb, const struct tcphdr *th, | 162 | const struct sk_buff *skb, const struct tcphdr *th, |
164 | const struct synproxy_options *opts) | 163 | const struct synproxy_options *opts) |
@@ -177,7 +176,7 @@ synproxy_send_server_ack(const struct synproxy_net *snet, | |||
177 | return; | 176 | return; |
178 | skb_reserve(nskb, MAX_TCP_HEADER); | 177 | skb_reserve(nskb, MAX_TCP_HEADER); |
179 | 178 | ||
180 | niph = synproxy_build_ip(nskb, iph->daddr, iph->saddr); | 179 | niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); |
181 | 180 | ||
182 | skb_reset_transport_header(nskb); | 181 | skb_reset_transport_header(nskb); |
183 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 182 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -193,11 +192,11 @@ synproxy_send_server_ack(const struct synproxy_net *snet, | |||
193 | 192 | ||
194 | synproxy_build_options(nth, opts); | 193 | synproxy_build_options(nth, opts); |
195 | 194 | ||
196 | synproxy_send_tcp(snet, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); | 195 | synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); |
197 | } | 196 | } |
198 | 197 | ||
199 | static void | 198 | static void |
200 | synproxy_send_client_ack(const struct synproxy_net *snet, | 199 | synproxy_send_client_ack(struct net *net, |
201 | const struct sk_buff *skb, const struct tcphdr *th, | 200 | const struct sk_buff *skb, const struct tcphdr *th, |
202 | const struct synproxy_options *opts) | 201 | const struct synproxy_options *opts) |
203 | { | 202 | { |
@@ -215,7 +214,7 @@ synproxy_send_client_ack(const struct synproxy_net *snet, | |||
215 | return; | 214 | return; |
216 | skb_reserve(nskb, MAX_TCP_HEADER); | 215 | skb_reserve(nskb, MAX_TCP_HEADER); |
217 | 216 | ||
218 | niph = synproxy_build_ip(nskb, iph->saddr, iph->daddr); | 217 | niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); |
219 | 218 | ||
220 | skb_reset_transport_header(nskb); | 219 | skb_reset_transport_header(nskb); |
221 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); | 220 | nth = (struct tcphdr *)skb_put(nskb, tcp_hdr_size); |
@@ -231,15 +230,16 @@ synproxy_send_client_ack(const struct synproxy_net *snet, | |||
231 | 230 | ||
232 | synproxy_build_options(nth, opts); | 231 | synproxy_build_options(nth, opts); |
233 | 232 | ||
234 | synproxy_send_tcp(snet, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, | 233 | synproxy_send_tcp(net, skb, nskb, skb->nfct, IP_CT_ESTABLISHED_REPLY, |
235 | niph, nth, tcp_hdr_size); | 234 | niph, nth, tcp_hdr_size); |
236 | } | 235 | } |
237 | 236 | ||
238 | static bool | 237 | static bool |
239 | synproxy_recv_client_ack(const struct synproxy_net *snet, | 238 | synproxy_recv_client_ack(struct net *net, |
240 | const struct sk_buff *skb, const struct tcphdr *th, | 239 | const struct sk_buff *skb, const struct tcphdr *th, |
241 | struct synproxy_options *opts, u32 recv_seq) | 240 | struct synproxy_options *opts, u32 recv_seq) |
242 | { | 241 | { |
242 | struct synproxy_net *snet = synproxy_pernet(net); | ||
243 | int mss; | 243 | int mss; |
244 | 244 | ||
245 | mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); | 245 | mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); |
@@ -255,7 +255,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet, | |||
255 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) | 255 | if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) |
256 | synproxy_check_timestamp_cookie(opts); | 256 | synproxy_check_timestamp_cookie(opts); |
257 | 257 | ||
258 | synproxy_send_server_syn(snet, skb, th, opts, recv_seq); | 258 | synproxy_send_server_syn(net, skb, th, opts, recv_seq); |
259 | return true; | 259 | return true; |
260 | } | 260 | } |
261 | 261 | ||
@@ -263,7 +263,8 @@ static unsigned int | |||
263 | synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) | 263 | synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) |
264 | { | 264 | { |
265 | const struct xt_synproxy_info *info = par->targinfo; | 265 | const struct xt_synproxy_info *info = par->targinfo; |
266 | struct synproxy_net *snet = synproxy_pernet(par->net); | 266 | struct net *net = par->net; |
267 | struct synproxy_net *snet = synproxy_pernet(net); | ||
267 | struct synproxy_options opts = {}; | 268 | struct synproxy_options opts = {}; |
268 | struct tcphdr *th, _th; | 269 | struct tcphdr *th, _th; |
269 | 270 | ||
@@ -292,12 +293,12 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) | |||
292 | XT_SYNPROXY_OPT_SACK_PERM | | 293 | XT_SYNPROXY_OPT_SACK_PERM | |
293 | XT_SYNPROXY_OPT_ECN); | 294 | XT_SYNPROXY_OPT_ECN); |
294 | 295 | ||
295 | synproxy_send_client_synack(snet, skb, th, &opts); | 296 | synproxy_send_client_synack(net, skb, th, &opts); |
296 | return NF_DROP; | 297 | return NF_DROP; |
297 | 298 | ||
298 | } else if (th->ack && !(th->fin || th->rst || th->syn)) { | 299 | } else if (th->ack && !(th->fin || th->rst || th->syn)) { |
299 | /* ACK from client */ | 300 | /* ACK from client */ |
300 | synproxy_recv_client_ack(snet, skb, th, &opts, ntohl(th->seq)); | 301 | synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq)); |
301 | return NF_DROP; | 302 | return NF_DROP; |
302 | } | 303 | } |
303 | 304 | ||
@@ -308,7 +309,8 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
308 | struct sk_buff *skb, | 309 | struct sk_buff *skb, |
309 | const struct nf_hook_state *nhs) | 310 | const struct nf_hook_state *nhs) |
310 | { | 311 | { |
311 | struct synproxy_net *snet = synproxy_pernet(nhs->net); | 312 | struct net *net = nhs->net; |
313 | struct synproxy_net *snet = synproxy_pernet(net); | ||
312 | enum ip_conntrack_info ctinfo; | 314 | enum ip_conntrack_info ctinfo; |
313 | struct nf_conn *ct; | 315 | struct nf_conn *ct; |
314 | struct nf_conn_synproxy *synproxy; | 316 | struct nf_conn_synproxy *synproxy; |
@@ -365,7 +367,7 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
365 | * therefore we need to add 1 to make the SYN sequence | 367 | * therefore we need to add 1 to make the SYN sequence |
366 | * number match the one of first SYN. | 368 | * number match the one of first SYN. |
367 | */ | 369 | */ |
368 | if (synproxy_recv_client_ack(snet, skb, th, &opts, | 370 | if (synproxy_recv_client_ack(net, skb, th, &opts, |
369 | ntohl(th->seq) + 1)) | 371 | ntohl(th->seq) + 1)) |
370 | this_cpu_inc(snet->stats->cookie_retrans); | 372 | this_cpu_inc(snet->stats->cookie_retrans); |
371 | 373 | ||
@@ -391,12 +393,12 @@ static unsigned int ipv4_synproxy_hook(void *priv, | |||
391 | XT_SYNPROXY_OPT_SACK_PERM); | 393 | XT_SYNPROXY_OPT_SACK_PERM); |
392 | 394 | ||
393 | swap(opts.tsval, opts.tsecr); | 395 | swap(opts.tsval, opts.tsecr); |
394 | synproxy_send_server_ack(snet, state, skb, th, &opts); | 396 | synproxy_send_server_ack(net, state, skb, th, &opts); |
395 | 397 | ||
396 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); | 398 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); |
397 | 399 | ||
398 | swap(opts.tsval, opts.tsecr); | 400 | swap(opts.tsval, opts.tsecr); |
399 | synproxy_send_client_ack(snet, skb, th, &opts); | 401 | synproxy_send_client_ack(net, skb, th, &opts); |
400 | 402 | ||
401 | consume_skb(skb); | 403 | consume_skb(skb); |
402 | return NF_STOLEN; | 404 | return NF_STOLEN; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 9428345d3a07..bc972e7152c7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1090,8 +1090,8 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1090 | int getfrag(void *from, char *to, int offset, int len, | 1090 | int getfrag(void *from, char *to, int offset, int len, |
1091 | int odd, struct sk_buff *skb), | 1091 | int odd, struct sk_buff *skb), |
1092 | void *from, int length, int hh_len, int fragheaderlen, | 1092 | void *from, int length, int hh_len, int fragheaderlen, |
1093 | int transhdrlen, int mtu, unsigned int flags, | 1093 | int exthdrlen, int transhdrlen, int mtu, |
1094 | const struct flowi6 *fl6) | 1094 | unsigned int flags, const struct flowi6 *fl6) |
1095 | 1095 | ||
1096 | { | 1096 | { |
1097 | struct sk_buff *skb; | 1097 | struct sk_buff *skb; |
@@ -1116,7 +1116,7 @@ static inline int ip6_ufo_append_data(struct sock *sk, | |||
1116 | skb_put(skb, fragheaderlen + transhdrlen); | 1116 | skb_put(skb, fragheaderlen + transhdrlen); |
1117 | 1117 | ||
1118 | /* initialize network header pointer */ | 1118 | /* initialize network header pointer */ |
1119 | skb_reset_network_header(skb); | 1119 | skb_set_network_header(skb, exthdrlen); |
1120 | 1120 | ||
1121 | /* initialize protocol header pointer */ | 1121 | /* initialize protocol header pointer */ |
1122 | skb->transport_header = skb->network_header + fragheaderlen; | 1122 | skb->transport_header = skb->network_header + fragheaderlen; |
@@ -1358,7 +1358,7 @@ emsgsize: | |||
1358 | (rt->dst.dev->features & NETIF_F_UFO) && | 1358 | (rt->dst.dev->features & NETIF_F_UFO) && |
1359 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { | 1359 | (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) { |
1360 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, | 1360 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, |
1361 | hh_len, fragheaderlen, | 1361 | hh_len, fragheaderlen, exthdrlen, |
1362 | transhdrlen, mtu, flags, fl6); | 1362 | transhdrlen, mtu, flags, fl6); |
1363 | if (err) | 1363 | if (err) |
1364 | goto error; | 1364 | goto error; |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index eb2ac4bb09ce..1f20345cbc97 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -252,12 +252,12 @@ static int ip6_tnl_create2(struct net_device *dev) | |||
252 | 252 | ||
253 | t = netdev_priv(dev); | 253 | t = netdev_priv(dev); |
254 | 254 | ||
255 | dev->rtnl_link_ops = &ip6_link_ops; | ||
255 | err = register_netdevice(dev); | 256 | err = register_netdevice(dev); |
256 | if (err < 0) | 257 | if (err < 0) |
257 | goto out; | 258 | goto out; |
258 | 259 | ||
259 | strcpy(t->parms.name, dev->name); | 260 | strcpy(t->parms.name, dev->name); |
260 | dev->rtnl_link_ops = &ip6_link_ops; | ||
261 | 261 | ||
262 | dev_hold(dev); | 262 | dev_hold(dev); |
263 | ip6_tnl_link(ip6n, t); | 263 | ip6_tnl_link(ip6n, t); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 84f9baf7aee8..86b67b70b626 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -198,11 +198,12 @@ get_entry(const void *base, unsigned int offset) | |||
198 | 198 | ||
199 | /* All zeroes == unconditional rule. */ | 199 | /* All zeroes == unconditional rule. */ |
200 | /* Mildly perf critical (only if packet tracing is on) */ | 200 | /* Mildly perf critical (only if packet tracing is on) */ |
201 | static inline bool unconditional(const struct ip6t_ip6 *ipv6) | 201 | static inline bool unconditional(const struct ip6t_entry *e) |
202 | { | 202 | { |
203 | static const struct ip6t_ip6 uncond; | 203 | static const struct ip6t_ip6 uncond; |
204 | 204 | ||
205 | return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; | 205 | return e->target_offset == sizeof(struct ip6t_entry) && |
206 | memcmp(&e->ipv6, &uncond, sizeof(uncond)) == 0; | ||
206 | } | 207 | } |
207 | 208 | ||
208 | static inline const struct xt_entry_target * | 209 | static inline const struct xt_entry_target * |
@@ -258,11 +259,10 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, | |||
258 | } else if (s == e) { | 259 | } else if (s == e) { |
259 | (*rulenum)++; | 260 | (*rulenum)++; |
260 | 261 | ||
261 | if (s->target_offset == sizeof(struct ip6t_entry) && | 262 | if (unconditional(s) && |
262 | strcmp(t->target.u.kernel.target->name, | 263 | strcmp(t->target.u.kernel.target->name, |
263 | XT_STANDARD_TARGET) == 0 && | 264 | XT_STANDARD_TARGET) == 0 && |
264 | t->verdict < 0 && | 265 | t->verdict < 0) { |
265 | unconditional(&s->ipv6)) { | ||
266 | /* Tail of chains: STANDARD target (return/policy) */ | 266 | /* Tail of chains: STANDARD target (return/policy) */ |
267 | *comment = *chainname == hookname | 267 | *comment = *chainname == hookname |
268 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] | 268 | ? comments[NF_IP6_TRACE_COMMENT_POLICY] |
@@ -488,11 +488,10 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
488 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); | 488 | e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS)); |
489 | 489 | ||
490 | /* Unconditional return/END. */ | 490 | /* Unconditional return/END. */ |
491 | if ((e->target_offset == sizeof(struct ip6t_entry) && | 491 | if ((unconditional(e) && |
492 | (strcmp(t->target.u.user.name, | 492 | (strcmp(t->target.u.user.name, |
493 | XT_STANDARD_TARGET) == 0) && | 493 | XT_STANDARD_TARGET) == 0) && |
494 | t->verdict < 0 && | 494 | t->verdict < 0) || visited) { |
495 | unconditional(&e->ipv6)) || visited) { | ||
496 | unsigned int oldpos, size; | 495 | unsigned int oldpos, size; |
497 | 496 | ||
498 | if ((strcmp(t->target.u.user.name, | 497 | if ((strcmp(t->target.u.user.name, |
@@ -581,14 +580,12 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net) | |||
581 | } | 580 | } |
582 | 581 | ||
583 | static int | 582 | static int |
584 | check_entry(const struct ip6t_entry *e, const char *name) | 583 | check_entry(const struct ip6t_entry *e) |
585 | { | 584 | { |
586 | const struct xt_entry_target *t; | 585 | const struct xt_entry_target *t; |
587 | 586 | ||
588 | if (!ip6_checkentry(&e->ipv6)) { | 587 | if (!ip6_checkentry(&e->ipv6)) |
589 | duprintf("ip_tables: ip check failed %p %s.\n", e, name); | ||
590 | return -EINVAL; | 588 | return -EINVAL; |
591 | } | ||
592 | 589 | ||
593 | if (e->target_offset + sizeof(struct xt_entry_target) > | 590 | if (e->target_offset + sizeof(struct xt_entry_target) > |
594 | e->next_offset) | 591 | e->next_offset) |
@@ -679,10 +676,6 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, | |||
679 | struct xt_mtchk_param mtpar; | 676 | struct xt_mtchk_param mtpar; |
680 | struct xt_entry_match *ematch; | 677 | struct xt_entry_match *ematch; |
681 | 678 | ||
682 | ret = check_entry(e, name); | ||
683 | if (ret) | ||
684 | return ret; | ||
685 | |||
686 | e->counters.pcnt = xt_percpu_counter_alloc(); | 679 | e->counters.pcnt = xt_percpu_counter_alloc(); |
687 | if (IS_ERR_VALUE(e->counters.pcnt)) | 680 | if (IS_ERR_VALUE(e->counters.pcnt)) |
688 | return -ENOMEM; | 681 | return -ENOMEM; |
@@ -733,7 +726,7 @@ static bool check_underflow(const struct ip6t_entry *e) | |||
733 | const struct xt_entry_target *t; | 726 | const struct xt_entry_target *t; |
734 | unsigned int verdict; | 727 | unsigned int verdict; |
735 | 728 | ||
736 | if (!unconditional(&e->ipv6)) | 729 | if (!unconditional(e)) |
737 | return false; | 730 | return false; |
738 | t = ip6t_get_target_c(e); | 731 | t = ip6t_get_target_c(e); |
739 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) | 732 | if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) |
@@ -753,9 +746,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
753 | unsigned int valid_hooks) | 746 | unsigned int valid_hooks) |
754 | { | 747 | { |
755 | unsigned int h; | 748 | unsigned int h; |
749 | int err; | ||
756 | 750 | ||
757 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || | 751 | if ((unsigned long)e % __alignof__(struct ip6t_entry) != 0 || |
758 | (unsigned char *)e + sizeof(struct ip6t_entry) >= limit) { | 752 | (unsigned char *)e + sizeof(struct ip6t_entry) >= limit || |
753 | (unsigned char *)e + e->next_offset > limit) { | ||
759 | duprintf("Bad offset %p\n", e); | 754 | duprintf("Bad offset %p\n", e); |
760 | return -EINVAL; | 755 | return -EINVAL; |
761 | } | 756 | } |
@@ -767,6 +762,10 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
767 | return -EINVAL; | 762 | return -EINVAL; |
768 | } | 763 | } |
769 | 764 | ||
765 | err = check_entry(e); | ||
766 | if (err) | ||
767 | return err; | ||
768 | |||
770 | /* Check hooks & underflows */ | 769 | /* Check hooks & underflows */ |
771 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { | 770 | for (h = 0; h < NF_INET_NUMHOOKS; h++) { |
772 | if (!(valid_hooks & (1 << h))) | 771 | if (!(valid_hooks & (1 << h))) |
@@ -775,9 +774,9 @@ check_entry_size_and_hooks(struct ip6t_entry *e, | |||
775 | newinfo->hook_entry[h] = hook_entries[h]; | 774 | newinfo->hook_entry[h] = hook_entries[h]; |
776 | if ((unsigned char *)e - base == underflows[h]) { | 775 | if ((unsigned char *)e - base == underflows[h]) { |
777 | if (!check_underflow(e)) { | 776 | if (!check_underflow(e)) { |
778 | pr_err("Underflows must be unconditional and " | 777 | pr_debug("Underflows must be unconditional and " |
779 | "use the STANDARD target with " | 778 | "use the STANDARD target with " |
780 | "ACCEPT/DROP\n"); | 779 | "ACCEPT/DROP\n"); |
781 | return -EINVAL; | 780 | return -EINVAL; |
782 | } | 781 | } |
783 | newinfo->underflow[h] = underflows[h]; | 782 | newinfo->underflow[h] = underflows[h]; |
@@ -1169,6 +1168,7 @@ get_entries(struct net *net, struct ip6t_get_entries __user *uptr, | |||
1169 | *len, sizeof(get) + get.size); | 1168 | *len, sizeof(get) + get.size); |
1170 | return -EINVAL; | 1169 | return -EINVAL; |
1171 | } | 1170 | } |
1171 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1172 | 1172 | ||
1173 | t = xt_find_table_lock(net, AF_INET6, get.name); | 1173 | t = xt_find_table_lock(net, AF_INET6, get.name); |
1174 | if (!IS_ERR_OR_NULL(t)) { | 1174 | if (!IS_ERR_OR_NULL(t)) { |
@@ -1505,7 +1505,8 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1505 | 1505 | ||
1506 | duprintf("check_compat_entry_size_and_hooks %p\n", e); | 1506 | duprintf("check_compat_entry_size_and_hooks %p\n", e); |
1507 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || | 1507 | if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 || |
1508 | (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit) { | 1508 | (unsigned char *)e + sizeof(struct compat_ip6t_entry) >= limit || |
1509 | (unsigned char *)e + e->next_offset > limit) { | ||
1509 | duprintf("Bad offset %p, limit = %p\n", e, limit); | 1510 | duprintf("Bad offset %p, limit = %p\n", e, limit); |
1510 | return -EINVAL; | 1511 | return -EINVAL; |
1511 | } | 1512 | } |
@@ -1518,7 +1519,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, | |||
1518 | } | 1519 | } |
1519 | 1520 | ||
1520 | /* For purposes of check_entry casting the compat entry is fine */ | 1521 | /* For purposes of check_entry casting the compat entry is fine */ |
1521 | ret = check_entry((struct ip6t_entry *)e, name); | 1522 | ret = check_entry((struct ip6t_entry *)e); |
1522 | if (ret) | 1523 | if (ret) |
1523 | return ret; | 1524 | return ret; |
1524 | 1525 | ||
@@ -1944,6 +1945,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr, | |||
1944 | *len, sizeof(get) + get.size); | 1945 | *len, sizeof(get) + get.size); |
1945 | return -EINVAL; | 1946 | return -EINVAL; |
1946 | } | 1947 | } |
1948 | get.name[sizeof(get.name) - 1] = '\0'; | ||
1947 | 1949 | ||
1948 | xt_compat_lock(AF_INET6); | 1950 | xt_compat_lock(AF_INET6); |
1949 | t = xt_find_table_lock(net, AF_INET6, get.name); | 1951 | t = xt_find_table_lock(net, AF_INET6, get.name); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fd25e447a5fa..8125931106be 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -843,8 +843,8 @@ start_lookup: | |||
843 | flush_stack(stack, count, skb, count - 1); | 843 | flush_stack(stack, count, skb, count - 1); |
844 | } else { | 844 | } else { |
845 | if (!inner_flushed) | 845 | if (!inner_flushed) |
846 | UDP_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, | 846 | UDP6_INC_STATS_BH(net, UDP_MIB_IGNOREDMULTI, |
847 | proto == IPPROTO_UDPLITE); | 847 | proto == IPPROTO_UDPLITE); |
848 | consume_skb(skb); | 848 | consume_skb(skb); |
849 | } | 849 | } |
850 | return 0; | 850 | return 0; |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index ec22078b0914..42de4ccd159f 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -123,12 +123,11 @@ static int l2tp_ip_recv(struct sk_buff *skb) | |||
123 | struct l2tp_tunnel *tunnel = NULL; | 123 | struct l2tp_tunnel *tunnel = NULL; |
124 | int length; | 124 | int length; |
125 | 125 | ||
126 | /* Point to L2TP header */ | ||
127 | optr = ptr = skb->data; | ||
128 | |||
129 | if (!pskb_may_pull(skb, 4)) | 126 | if (!pskb_may_pull(skb, 4)) |
130 | goto discard; | 127 | goto discard; |
131 | 128 | ||
129 | /* Point to L2TP header */ | ||
130 | optr = ptr = skb->data; | ||
132 | session_id = ntohl(*((__be32 *) ptr)); | 131 | session_id = ntohl(*((__be32 *) ptr)); |
133 | ptr += 4; | 132 | ptr += 4; |
134 | 133 | ||
@@ -156,6 +155,9 @@ static int l2tp_ip_recv(struct sk_buff *skb) | |||
156 | if (!pskb_may_pull(skb, length)) | 155 | if (!pskb_may_pull(skb, length)) |
157 | goto discard; | 156 | goto discard; |
158 | 157 | ||
158 | /* Point to L2TP header */ | ||
159 | optr = ptr = skb->data; | ||
160 | ptr += 4; | ||
159 | pr_debug("%s: ip recv\n", tunnel->name); | 161 | pr_debug("%s: ip recv\n", tunnel->name); |
160 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); | 162 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
161 | } | 163 | } |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 6b54ff3ff4cb..cd479903d943 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -136,12 +136,11 @@ static int l2tp_ip6_recv(struct sk_buff *skb) | |||
136 | struct l2tp_tunnel *tunnel = NULL; | 136 | struct l2tp_tunnel *tunnel = NULL; |
137 | int length; | 137 | int length; |
138 | 138 | ||
139 | /* Point to L2TP header */ | ||
140 | optr = ptr = skb->data; | ||
141 | |||
142 | if (!pskb_may_pull(skb, 4)) | 139 | if (!pskb_may_pull(skb, 4)) |
143 | goto discard; | 140 | goto discard; |
144 | 141 | ||
142 | /* Point to L2TP header */ | ||
143 | optr = ptr = skb->data; | ||
145 | session_id = ntohl(*((__be32 *) ptr)); | 144 | session_id = ntohl(*((__be32 *) ptr)); |
146 | ptr += 4; | 145 | ptr += 4; |
147 | 146 | ||
@@ -169,6 +168,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb) | |||
169 | if (!pskb_may_pull(skb, length)) | 168 | if (!pskb_may_pull(skb, length)) |
170 | goto discard; | 169 | goto discard; |
171 | 170 | ||
171 | /* Point to L2TP header */ | ||
172 | optr = ptr = skb->data; | ||
173 | ptr += 4; | ||
172 | pr_debug("%s: ip recv\n", tunnel->name); | 174 | pr_debug("%s: ip recv\n", tunnel->name); |
173 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); | 175 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
174 | } | 176 | } |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 283981108ca8..74142d07ad31 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -343,8 +343,10 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local, | |||
343 | struct ieee80211_chanctx *ctx, | 343 | struct ieee80211_chanctx *ctx, |
344 | const struct cfg80211_chan_def *chandef) | 344 | const struct cfg80211_chan_def *chandef) |
345 | { | 345 | { |
346 | if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) | 346 | if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) { |
347 | ieee80211_recalc_chanctx_min_def(local, ctx); | ||
347 | return; | 348 | return; |
349 | } | ||
348 | 350 | ||
349 | WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); | 351 | WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); |
350 | 352 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 804575ff7af5..422003540169 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1719,6 +1719,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, | |||
1719 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta); | 1719 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta); |
1720 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); | 1720 | enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta); |
1721 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | 1721 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); |
1722 | enum ieee80211_sta_rx_bandwidth | ||
1723 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width); | ||
1724 | enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta); | ||
1725 | void ieee80211_sta_set_rx_nss(struct sta_info *sta); | ||
1722 | void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, | 1726 | void ieee80211_process_mu_groups(struct ieee80211_sub_if_data *sdata, |
1723 | struct ieee80211_mgmt *mgmt); | 1727 | struct ieee80211_mgmt *mgmt); |
1724 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, | 1728 | u32 __ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 5b6aec1a0630..002244bca948 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -530,7 +530,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
530 | const u8 *target_addr, *orig_addr; | 530 | const u8 *target_addr, *orig_addr; |
531 | const u8 *da; | 531 | const u8 *da; |
532 | u8 target_flags, ttl, flags; | 532 | u8 target_flags, ttl, flags; |
533 | u32 orig_sn, target_sn, lifetime, target_metric; | 533 | u32 orig_sn, target_sn, lifetime, target_metric = 0; |
534 | bool reply = false; | 534 | bool reply = false; |
535 | bool forward = true; | 535 | bool forward = true; |
536 | bool root_is_gate; | 536 | bool root_is_gate; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d20bab5c146c..861b93ffbe92 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -67,6 +67,7 @@ | |||
67 | 67 | ||
68 | static const struct rhashtable_params sta_rht_params = { | 68 | static const struct rhashtable_params sta_rht_params = { |
69 | .nelem_hint = 3, /* start small */ | 69 | .nelem_hint = 3, /* start small */ |
70 | .insecure_elasticity = true, /* Disable chain-length checks. */ | ||
70 | .automatic_shrinking = true, | 71 | .automatic_shrinking = true, |
71 | .head_offset = offsetof(struct sta_info, hash_node), | 72 | .head_offset = offsetof(struct sta_info, hash_node), |
72 | .key_offset = offsetof(struct sta_info, addr), | 73 | .key_offset = offsetof(struct sta_info, addr), |
@@ -258,11 +259,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | |||
258 | } | 259 | } |
259 | 260 | ||
260 | /* Caller must hold local->sta_mtx */ | 261 | /* Caller must hold local->sta_mtx */ |
261 | static void sta_info_hash_add(struct ieee80211_local *local, | 262 | static int sta_info_hash_add(struct ieee80211_local *local, |
262 | struct sta_info *sta) | 263 | struct sta_info *sta) |
263 | { | 264 | { |
264 | rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, | 265 | return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, |
265 | sta_rht_params); | 266 | sta_rht_params); |
266 | } | 267 | } |
267 | 268 | ||
268 | static void sta_deliver_ps_frames(struct work_struct *wk) | 269 | static void sta_deliver_ps_frames(struct work_struct *wk) |
@@ -524,7 +525,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
524 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | 525 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
525 | 526 | ||
526 | /* make the station visible */ | 527 | /* make the station visible */ |
527 | sta_info_hash_add(local, sta); | 528 | err = sta_info_hash_add(local, sta); |
529 | if (err) | ||
530 | goto out_drop_sta; | ||
528 | 531 | ||
529 | list_add_tail_rcu(&sta->list, &local->sta_list); | 532 | list_add_tail_rcu(&sta->list, &local->sta_list); |
530 | 533 | ||
@@ -557,6 +560,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
557 | out_remove: | 560 | out_remove: |
558 | sta_info_hash_del(local, sta); | 561 | sta_info_hash_del(local, sta); |
559 | list_del_rcu(&sta->list); | 562 | list_del_rcu(&sta->list); |
563 | out_drop_sta: | ||
560 | local->num_sta--; | 564 | local->num_sta--; |
561 | synchronize_net(); | 565 | synchronize_net(); |
562 | __cleanup_single_sta(sta); | 566 | __cleanup_single_sta(sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 053f5c4fa495..62193f4bc37b 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -377,7 +377,6 @@ DECLARE_EWMA(signal, 1024, 8) | |||
377 | * @uploaded: set to true when sta is uploaded to the driver | 377 | * @uploaded: set to true when sta is uploaded to the driver |
378 | * @sta: station information we share with the driver | 378 | * @sta: station information we share with the driver |
379 | * @sta_state: duplicates information about station state (for debug) | 379 | * @sta_state: duplicates information about station state (for debug) |
380 | * @beacon_loss_count: number of times beacon loss has triggered | ||
381 | * @rcu_head: RCU head used for freeing this station struct | 380 | * @rcu_head: RCU head used for freeing this station struct |
382 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, | 381 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, |
383 | * taken from HT/VHT capabilities or VHT operating mode notification | 382 | * taken from HT/VHT capabilities or VHT operating mode notification |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index c9eeb3f12808..a29ea813b7d5 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2014, Intel Corporation | 5 | * Copyright 2014, Intel Corporation |
6 | * Copyright 2014 Intel Mobile Communications GmbH | 6 | * Copyright 2014 Intel Mobile Communications GmbH |
7 | * Copyright 2015 Intel Deutschland GmbH | 7 | * Copyright 2015 - 2016 Intel Deutschland GmbH |
8 | * | 8 | * |
9 | * This file is GPLv2 as found in COPYING. | 9 | * This file is GPLv2 as found in COPYING. |
10 | */ | 10 | */ |
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/rtnetlink.h> | 15 | #include <linux/rtnetlink.h> |
16 | #include "ieee80211_i.h" | 16 | #include "ieee80211_i.h" |
17 | #include "driver-ops.h" | 17 | #include "driver-ops.h" |
18 | #include "rate.h" | ||
18 | 19 | ||
19 | /* give usermode some time for retries in setting up the TDLS session */ | 20 | /* give usermode some time for retries in setting up the TDLS session */ |
20 | #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) | 21 | #define TDLS_PEER_SETUP_TIMEOUT (15 * HZ) |
@@ -302,7 +303,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
302 | /* IEEE802.11ac-2013 Table E-4 */ | 303 | /* IEEE802.11ac-2013 Table E-4 */ |
303 | u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 }; | 304 | u16 centers_80mhz[] = { 5210, 5290, 5530, 5610, 5690, 5775 }; |
304 | struct cfg80211_chan_def uc = sta->tdls_chandef; | 305 | struct cfg80211_chan_def uc = sta->tdls_chandef; |
305 | enum nl80211_chan_width max_width = ieee80211_get_sta_bw(&sta->sta); | 306 | enum nl80211_chan_width max_width = ieee80211_sta_cap_chan_bw(sta); |
306 | int i; | 307 | int i; |
307 | 308 | ||
308 | /* only support upgrading non-narrow channels up to 80Mhz */ | 309 | /* only support upgrading non-narrow channels up to 80Mhz */ |
@@ -313,7 +314,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
313 | if (max_width > NL80211_CHAN_WIDTH_80) | 314 | if (max_width > NL80211_CHAN_WIDTH_80) |
314 | max_width = NL80211_CHAN_WIDTH_80; | 315 | max_width = NL80211_CHAN_WIDTH_80; |
315 | 316 | ||
316 | if (uc.width == max_width) | 317 | if (uc.width >= max_width) |
317 | return; | 318 | return; |
318 | /* | 319 | /* |
319 | * Channel usage constrains in the IEEE802.11ac-2013 specification only | 320 | * Channel usage constrains in the IEEE802.11ac-2013 specification only |
@@ -324,6 +325,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
324 | for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++) | 325 | for (i = 0; i < ARRAY_SIZE(centers_80mhz); i++) |
325 | if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) { | 326 | if (abs(uc.chan->center_freq - centers_80mhz[i]) <= 30) { |
326 | uc.center_freq1 = centers_80mhz[i]; | 327 | uc.center_freq1 = centers_80mhz[i]; |
328 | uc.center_freq2 = 0; | ||
327 | uc.width = NL80211_CHAN_WIDTH_80; | 329 | uc.width = NL80211_CHAN_WIDTH_80; |
328 | break; | 330 | break; |
329 | } | 331 | } |
@@ -332,7 +334,7 @@ ieee80211_tdls_chandef_vht_upgrade(struct ieee80211_sub_if_data *sdata, | |||
332 | return; | 334 | return; |
333 | 335 | ||
334 | /* proceed to downgrade the chandef until usable or the same */ | 336 | /* proceed to downgrade the chandef until usable or the same */ |
335 | while (uc.width > max_width && | 337 | while (uc.width > max_width || |
336 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, | 338 | !cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &uc, |
337 | sdata->wdev.iftype)) | 339 | sdata->wdev.iftype)) |
338 | ieee80211_chandef_downgrade(&uc); | 340 | ieee80211_chandef_downgrade(&uc); |
@@ -1242,18 +1244,44 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1242 | return ret; | 1244 | return ret; |
1243 | } | 1245 | } |
1244 | 1246 | ||
1245 | static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata) | 1247 | static void iee80211_tdls_recalc_chanctx(struct ieee80211_sub_if_data *sdata, |
1248 | struct sta_info *sta) | ||
1246 | { | 1249 | { |
1247 | struct ieee80211_local *local = sdata->local; | 1250 | struct ieee80211_local *local = sdata->local; |
1248 | struct ieee80211_chanctx_conf *conf; | 1251 | struct ieee80211_chanctx_conf *conf; |
1249 | struct ieee80211_chanctx *ctx; | 1252 | struct ieee80211_chanctx *ctx; |
1253 | enum nl80211_chan_width width; | ||
1254 | struct ieee80211_supported_band *sband; | ||
1250 | 1255 | ||
1251 | mutex_lock(&local->chanctx_mtx); | 1256 | mutex_lock(&local->chanctx_mtx); |
1252 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | 1257 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
1253 | lockdep_is_held(&local->chanctx_mtx)); | 1258 | lockdep_is_held(&local->chanctx_mtx)); |
1254 | if (conf) { | 1259 | if (conf) { |
1260 | width = conf->def.width; | ||
1261 | sband = local->hw.wiphy->bands[conf->def.chan->band]; | ||
1255 | ctx = container_of(conf, struct ieee80211_chanctx, conf); | 1262 | ctx = container_of(conf, struct ieee80211_chanctx, conf); |
1256 | ieee80211_recalc_chanctx_chantype(local, ctx); | 1263 | ieee80211_recalc_chanctx_chantype(local, ctx); |
1264 | |||
1265 | /* if width changed and a peer is given, update its BW */ | ||
1266 | if (width != conf->def.width && sta && | ||
1267 | test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) { | ||
1268 | enum ieee80211_sta_rx_bandwidth bw; | ||
1269 | |||
1270 | bw = ieee80211_chan_width_to_rx_bw(conf->def.width); | ||
1271 | bw = min(bw, ieee80211_sta_cap_rx_bw(sta)); | ||
1272 | if (bw != sta->sta.bandwidth) { | ||
1273 | sta->sta.bandwidth = bw; | ||
1274 | rate_control_rate_update(local, sband, sta, | ||
1275 | IEEE80211_RC_BW_CHANGED); | ||
1276 | /* | ||
1277 | * if a TDLS peer BW was updated, we need to | ||
1278 | * recalc the chandef width again, to get the | ||
1279 | * correct chanctx min_def | ||
1280 | */ | ||
1281 | ieee80211_recalc_chanctx_chantype(local, ctx); | ||
1282 | } | ||
1283 | } | ||
1284 | |||
1257 | } | 1285 | } |
1258 | mutex_unlock(&local->chanctx_mtx); | 1286 | mutex_unlock(&local->chanctx_mtx); |
1259 | } | 1287 | } |
@@ -1350,8 +1378,6 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1350 | break; | 1378 | break; |
1351 | } | 1379 | } |
1352 | 1380 | ||
1353 | iee80211_tdls_recalc_chanctx(sdata); | ||
1354 | |||
1355 | mutex_lock(&local->sta_mtx); | 1381 | mutex_lock(&local->sta_mtx); |
1356 | sta = sta_info_get(sdata, peer); | 1382 | sta = sta_info_get(sdata, peer); |
1357 | if (!sta) { | 1383 | if (!sta) { |
@@ -1360,6 +1386,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1360 | break; | 1386 | break; |
1361 | } | 1387 | } |
1362 | 1388 | ||
1389 | iee80211_tdls_recalc_chanctx(sdata, sta); | ||
1363 | iee80211_tdls_recalc_ht_protection(sdata, sta); | 1390 | iee80211_tdls_recalc_ht_protection(sdata, sta); |
1364 | 1391 | ||
1365 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); | 1392 | set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); |
@@ -1390,7 +1417,7 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
1390 | iee80211_tdls_recalc_ht_protection(sdata, NULL); | 1417 | iee80211_tdls_recalc_ht_protection(sdata, NULL); |
1391 | mutex_unlock(&local->sta_mtx); | 1418 | mutex_unlock(&local->sta_mtx); |
1392 | 1419 | ||
1393 | iee80211_tdls_recalc_chanctx(sdata); | 1420 | iee80211_tdls_recalc_chanctx(sdata, NULL); |
1394 | break; | 1421 | break; |
1395 | default: | 1422 | default: |
1396 | ret = -ENOTSUPP; | 1423 | ret = -ENOTSUPP; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 62ad5321257d..21f6602395f7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1116,11 +1116,15 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, | |||
1116 | reset_agg_timer = true; | 1116 | reset_agg_timer = true; |
1117 | } else { | 1117 | } else { |
1118 | queued = true; | 1118 | queued = true; |
1119 | if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) { | ||
1120 | clear_sta_flag(tx->sta, WLAN_STA_SP); | ||
1121 | ps_dbg(tx->sta->sdata, | ||
1122 | "STA %pM aid %d: SP frame queued, close the SP w/o telling the peer\n", | ||
1123 | tx->sta->sta.addr, tx->sta->sta.aid); | ||
1124 | } | ||
1119 | info->control.vif = &tx->sdata->vif; | 1125 | info->control.vif = &tx->sdata->vif; |
1120 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1126 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1121 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS | | 1127 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; |
1122 | IEEE80211_TX_CTL_NO_PS_BUFFER | | ||
1123 | IEEE80211_TX_STATUS_EOSP; | ||
1124 | __skb_queue_tail(&tid_tx->pending, skb); | 1128 | __skb_queue_tail(&tid_tx->pending, skb); |
1125 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) | 1129 | if (skb_queue_len(&tid_tx->pending) > STA_MAX_TX_BUFFER) |
1126 | purge_skb = __skb_dequeue(&tid_tx->pending); | 1130 | purge_skb = __skb_dequeue(&tid_tx->pending); |
@@ -1247,7 +1251,8 @@ static void ieee80211_drv_tx(struct ieee80211_local *local, | |||
1247 | struct txq_info *txqi; | 1251 | struct txq_info *txqi; |
1248 | u8 ac; | 1252 | u8 ac; |
1249 | 1253 | ||
1250 | if (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE) | 1254 | if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || |
1255 | (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) | ||
1251 | goto tx_normal; | 1256 | goto tx_normal; |
1252 | 1257 | ||
1253 | if (!ieee80211_is_data(hdr->frame_control)) | 1258 | if (!ieee80211_is_data(hdr->frame_control)) |
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c index 89e04d55aa18..e590e2ef9eaf 100644 --- a/net/mac80211/vht.c +++ b/net/mac80211/vht.c | |||
@@ -319,7 +319,30 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cap_rx_bw(struct sta_info *sta) | |||
319 | return IEEE80211_STA_RX_BW_80; | 319 | return IEEE80211_STA_RX_BW_80; |
320 | } | 320 | } |
321 | 321 | ||
322 | static enum ieee80211_sta_rx_bandwidth | 322 | enum nl80211_chan_width ieee80211_sta_cap_chan_bw(struct sta_info *sta) |
323 | { | ||
324 | struct ieee80211_sta_vht_cap *vht_cap = &sta->sta.vht_cap; | ||
325 | u32 cap_width; | ||
326 | |||
327 | if (!vht_cap->vht_supported) { | ||
328 | if (!sta->sta.ht_cap.ht_supported) | ||
329 | return NL80211_CHAN_WIDTH_20_NOHT; | ||
330 | |||
331 | return sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ? | ||
332 | NL80211_CHAN_WIDTH_40 : NL80211_CHAN_WIDTH_20; | ||
333 | } | ||
334 | |||
335 | cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK; | ||
336 | |||
337 | if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ) | ||
338 | return NL80211_CHAN_WIDTH_160; | ||
339 | else if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) | ||
340 | return NL80211_CHAN_WIDTH_80P80; | ||
341 | |||
342 | return NL80211_CHAN_WIDTH_80; | ||
343 | } | ||
344 | |||
345 | enum ieee80211_sta_rx_bandwidth | ||
323 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) | 346 | ieee80211_chan_width_to_rx_bw(enum nl80211_chan_width width) |
324 | { | 347 | { |
325 | switch (width) { | 348 | switch (width) { |
@@ -347,10 +370,7 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) | |||
347 | 370 | ||
348 | bw = ieee80211_sta_cap_rx_bw(sta); | 371 | bw = ieee80211_sta_cap_rx_bw(sta); |
349 | bw = min(bw, sta->cur_max_bandwidth); | 372 | bw = min(bw, sta->cur_max_bandwidth); |
350 | 373 | bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width)); | |
351 | /* do not cap the BW of TDLS WIDER_BW peers by the bss */ | ||
352 | if (!test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW)) | ||
353 | bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width)); | ||
354 | 374 | ||
355 | return bw; | 375 | return bw; |
356 | } | 376 | } |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index b18c5ed42d95..0b80a7140cc4 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -543,6 +543,9 @@ static struct net_device *find_outdev(struct net *net, | |||
543 | if (!dev) | 543 | if (!dev) |
544 | return ERR_PTR(-ENODEV); | 544 | return ERR_PTR(-ENODEV); |
545 | 545 | ||
546 | if (IS_ERR(dev)) | ||
547 | return dev; | ||
548 | |||
546 | /* The caller is holding rtnl anyways, so release the dev reference */ | 549 | /* The caller is holding rtnl anyways, so release the dev reference */ |
547 | dev_put(dev); | 550 | dev_put(dev); |
548 | 551 | ||
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h index b0bc475f641e..2e8e7e5fb4a6 100644 --- a/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/net/netfilter/ipset/ip_set_bitmap_gen.h | |||
@@ -95,7 +95,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) | |||
95 | if (!nested) | 95 | if (!nested) |
96 | goto nla_put_failure; | 96 | goto nla_put_failure; |
97 | if (mtype_do_head(skb, map) || | 97 | if (mtype_do_head(skb, map) || |
98 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 98 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
99 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) | 99 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) |
100 | goto nla_put_failure; | 100 | goto nla_put_failure; |
101 | if (unlikely(ip_set_put_flags(skb, set))) | 101 | if (unlikely(ip_set_put_flags(skb, set))) |
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index 7e6568cad494..a748b0c2c981 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c | |||
@@ -497,6 +497,26 @@ __ip_set_put(struct ip_set *set) | |||
497 | write_unlock_bh(&ip_set_ref_lock); | 497 | write_unlock_bh(&ip_set_ref_lock); |
498 | } | 498 | } |
499 | 499 | ||
500 | /* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need | ||
501 | * a separate reference counter | ||
502 | */ | ||
503 | static inline void | ||
504 | __ip_set_get_netlink(struct ip_set *set) | ||
505 | { | ||
506 | write_lock_bh(&ip_set_ref_lock); | ||
507 | set->ref_netlink++; | ||
508 | write_unlock_bh(&ip_set_ref_lock); | ||
509 | } | ||
510 | |||
511 | static inline void | ||
512 | __ip_set_put_netlink(struct ip_set *set) | ||
513 | { | ||
514 | write_lock_bh(&ip_set_ref_lock); | ||
515 | BUG_ON(set->ref_netlink == 0); | ||
516 | set->ref_netlink--; | ||
517 | write_unlock_bh(&ip_set_ref_lock); | ||
518 | } | ||
519 | |||
500 | /* Add, del and test set entries from kernel. | 520 | /* Add, del and test set entries from kernel. |
501 | * | 521 | * |
502 | * The set behind the index must exist and must be referenced | 522 | * The set behind the index must exist and must be referenced |
@@ -1002,7 +1022,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, | |||
1002 | if (!attr[IPSET_ATTR_SETNAME]) { | 1022 | if (!attr[IPSET_ATTR_SETNAME]) { |
1003 | for (i = 0; i < inst->ip_set_max; i++) { | 1023 | for (i = 0; i < inst->ip_set_max; i++) { |
1004 | s = ip_set(inst, i); | 1024 | s = ip_set(inst, i); |
1005 | if (s && s->ref) { | 1025 | if (s && (s->ref || s->ref_netlink)) { |
1006 | ret = -IPSET_ERR_BUSY; | 1026 | ret = -IPSET_ERR_BUSY; |
1007 | goto out; | 1027 | goto out; |
1008 | } | 1028 | } |
@@ -1024,7 +1044,7 @@ static int ip_set_destroy(struct net *net, struct sock *ctnl, | |||
1024 | if (!s) { | 1044 | if (!s) { |
1025 | ret = -ENOENT; | 1045 | ret = -ENOENT; |
1026 | goto out; | 1046 | goto out; |
1027 | } else if (s->ref) { | 1047 | } else if (s->ref || s->ref_netlink) { |
1028 | ret = -IPSET_ERR_BUSY; | 1048 | ret = -IPSET_ERR_BUSY; |
1029 | goto out; | 1049 | goto out; |
1030 | } | 1050 | } |
@@ -1171,6 +1191,9 @@ static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb, | |||
1171 | from->family == to->family)) | 1191 | from->family == to->family)) |
1172 | return -IPSET_ERR_TYPE_MISMATCH; | 1192 | return -IPSET_ERR_TYPE_MISMATCH; |
1173 | 1193 | ||
1194 | if (from->ref_netlink || to->ref_netlink) | ||
1195 | return -EBUSY; | ||
1196 | |||
1174 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); | 1197 | strncpy(from_name, from->name, IPSET_MAXNAMELEN); |
1175 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); | 1198 | strncpy(from->name, to->name, IPSET_MAXNAMELEN); |
1176 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); | 1199 | strncpy(to->name, from_name, IPSET_MAXNAMELEN); |
@@ -1206,7 +1229,7 @@ ip_set_dump_done(struct netlink_callback *cb) | |||
1206 | if (set->variant->uref) | 1229 | if (set->variant->uref) |
1207 | set->variant->uref(set, cb, false); | 1230 | set->variant->uref(set, cb, false); |
1208 | pr_debug("release set %s\n", set->name); | 1231 | pr_debug("release set %s\n", set->name); |
1209 | __ip_set_put_byindex(inst, index); | 1232 | __ip_set_put_netlink(set); |
1210 | } | 1233 | } |
1211 | return 0; | 1234 | return 0; |
1212 | } | 1235 | } |
@@ -1328,7 +1351,7 @@ dump_last: | |||
1328 | if (!cb->args[IPSET_CB_ARG0]) { | 1351 | if (!cb->args[IPSET_CB_ARG0]) { |
1329 | /* Start listing: make sure set won't be destroyed */ | 1352 | /* Start listing: make sure set won't be destroyed */ |
1330 | pr_debug("reference set\n"); | 1353 | pr_debug("reference set\n"); |
1331 | set->ref++; | 1354 | set->ref_netlink++; |
1332 | } | 1355 | } |
1333 | write_unlock_bh(&ip_set_ref_lock); | 1356 | write_unlock_bh(&ip_set_ref_lock); |
1334 | nlh = start_msg(skb, NETLINK_CB(cb->skb).portid, | 1357 | nlh = start_msg(skb, NETLINK_CB(cb->skb).portid, |
@@ -1396,7 +1419,7 @@ release_refcount: | |||
1396 | if (set->variant->uref) | 1419 | if (set->variant->uref) |
1397 | set->variant->uref(set, cb, false); | 1420 | set->variant->uref(set, cb, false); |
1398 | pr_debug("release set %s\n", set->name); | 1421 | pr_debug("release set %s\n", set->name); |
1399 | __ip_set_put_byindex(inst, index); | 1422 | __ip_set_put_netlink(set); |
1400 | cb->args[IPSET_CB_ARG0] = 0; | 1423 | cb->args[IPSET_CB_ARG0] = 0; |
1401 | } | 1424 | } |
1402 | out: | 1425 | out: |
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index e5336ab36d67..d32fd6b036bf 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h | |||
@@ -1082,7 +1082,7 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) | |||
1082 | if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask)) | 1082 | if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask)) |
1083 | goto nla_put_failure; | 1083 | goto nla_put_failure; |
1084 | #endif | 1084 | #endif |
1085 | if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 1085 | if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
1086 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) | 1086 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) |
1087 | goto nla_put_failure; | 1087 | goto nla_put_failure; |
1088 | if (unlikely(ip_set_put_flags(skb, set))) | 1088 | if (unlikely(ip_set_put_flags(skb, set))) |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 24c6c1962aea..a2a89e4e0a14 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
@@ -458,7 +458,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb) | |||
458 | if (!nested) | 458 | if (!nested) |
459 | goto nla_put_failure; | 459 | goto nla_put_failure; |
460 | if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || | 460 | if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || |
461 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || | 461 | nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref)) || |
462 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, | 462 | nla_put_net32(skb, IPSET_ATTR_MEMSIZE, |
463 | htonl(sizeof(*map) + n * set->dsize))) | 463 | htonl(sizeof(*map) + n * set->dsize))) |
464 | goto nla_put_failure; | 464 | goto nla_put_failure; |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 75429997ed41..cb5b630a645b 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -582,7 +582,12 @@ __nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue, | |||
582 | /* nfnetlink_unicast will either free the nskb or add it to a socket */ | 582 | /* nfnetlink_unicast will either free the nskb or add it to a socket */ |
583 | err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT); | 583 | err = nfnetlink_unicast(nskb, net, queue->peer_portid, MSG_DONTWAIT); |
584 | if (err < 0) { | 584 | if (err < 0) { |
585 | queue->queue_user_dropped++; | 585 | if (queue->flags & NFQA_CFG_F_FAIL_OPEN) { |
586 | failopen = 1; | ||
587 | err = 0; | ||
588 | } else { | ||
589 | queue->queue_user_dropped++; | ||
590 | } | ||
586 | goto err_out_unlock; | 591 | goto err_out_unlock; |
587 | } | 592 | } |
588 | 593 | ||
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig index 234a73344c6e..ce947292ae77 100644 --- a/net/openvswitch/Kconfig +++ b/net/openvswitch/Kconfig | |||
@@ -7,7 +7,9 @@ config OPENVSWITCH | |||
7 | depends on INET | 7 | depends on INET |
8 | depends on !NF_CONNTRACK || \ | 8 | depends on !NF_CONNTRACK || \ |
9 | (NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \ | 9 | (NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \ |
10 | (!NF_NAT || NF_NAT))) | 10 | (!NF_NAT || NF_NAT) && \ |
11 | (!NF_NAT_IPV4 || NF_NAT_IPV4) && \ | ||
12 | (!NF_NAT_IPV6 || NF_NAT_IPV6))) | ||
11 | select LIBCRC32C | 13 | select LIBCRC32C |
12 | select MPLS | 14 | select MPLS |
13 | select NET_MPLS_GSO | 15 | select NET_MPLS_GSO |
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index dc5eb29fe7d6..1b9d286756be 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c | |||
@@ -535,14 +535,15 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, | |||
535 | switch (ctinfo) { | 535 | switch (ctinfo) { |
536 | case IP_CT_RELATED: | 536 | case IP_CT_RELATED: |
537 | case IP_CT_RELATED_REPLY: | 537 | case IP_CT_RELATED_REPLY: |
538 | if (skb->protocol == htons(ETH_P_IP) && | 538 | if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && |
539 | skb->protocol == htons(ETH_P_IP) && | ||
539 | ip_hdr(skb)->protocol == IPPROTO_ICMP) { | 540 | ip_hdr(skb)->protocol == IPPROTO_ICMP) { |
540 | if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, | 541 | if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo, |
541 | hooknum)) | 542 | hooknum)) |
542 | err = NF_DROP; | 543 | err = NF_DROP; |
543 | goto push; | 544 | goto push; |
544 | #if IS_ENABLED(CONFIG_NF_NAT_IPV6) | 545 | } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && |
545 | } else if (skb->protocol == htons(ETH_P_IPV6)) { | 546 | skb->protocol == htons(ETH_P_IPV6)) { |
546 | __be16 frag_off; | 547 | __be16 frag_off; |
547 | u8 nexthdr = ipv6_hdr(skb)->nexthdr; | 548 | u8 nexthdr = ipv6_hdr(skb)->nexthdr; |
548 | int hdrlen = ipv6_skip_exthdr(skb, | 549 | int hdrlen = ipv6_skip_exthdr(skb, |
@@ -557,7 +558,6 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, | |||
557 | err = NF_DROP; | 558 | err = NF_DROP; |
558 | goto push; | 559 | goto push; |
559 | } | 560 | } |
560 | #endif | ||
561 | } | 561 | } |
562 | /* Non-ICMP, fall thru to initialize if needed. */ | 562 | /* Non-ICMP, fall thru to initialize if needed. */ |
563 | case IP_CT_NEW: | 563 | case IP_CT_NEW: |
@@ -664,11 +664,12 @@ static int ovs_ct_nat(struct net *net, struct sw_flow_key *key, | |||
664 | 664 | ||
665 | /* Determine NAT type. | 665 | /* Determine NAT type. |
666 | * Check if the NAT type can be deduced from the tracked connection. | 666 | * Check if the NAT type can be deduced from the tracked connection. |
667 | * Make sure expected traffic is NATted only when committing. | 667 | * Make sure new expected connections (IP_CT_RELATED) are NATted only |
668 | * when committing. | ||
668 | */ | 669 | */ |
669 | if (info->nat & OVS_CT_NAT && ctinfo != IP_CT_NEW && | 670 | if (info->nat & OVS_CT_NAT && ctinfo != IP_CT_NEW && |
670 | ct->status & IPS_NAT_MASK && | 671 | ct->status & IPS_NAT_MASK && |
671 | (!(ct->status & IPS_EXPECTED_BIT) || info->commit)) { | 672 | (ctinfo != IP_CT_RELATED || info->commit)) { |
672 | /* NAT an established or related connection like before. */ | 673 | /* NAT an established or related connection like before. */ |
673 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) | 674 | if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) |
674 | /* This is the REPLY direction for a connection | 675 | /* This is the REPLY direction for a connection |
@@ -968,7 +969,8 @@ static int parse_nat(const struct nlattr *attr, | |||
968 | break; | 969 | break; |
969 | 970 | ||
970 | case OVS_NAT_ATTR_IP_MIN: | 971 | case OVS_NAT_ATTR_IP_MIN: |
971 | nla_memcpy(&info->range.min_addr, a, nla_len(a)); | 972 | nla_memcpy(&info->range.min_addr, a, |
973 | sizeof(info->range.min_addr)); | ||
972 | info->range.flags |= NF_NAT_RANGE_MAP_IPS; | 974 | info->range.flags |= NF_NAT_RANGE_MAP_IPS; |
973 | break; | 975 | break; |
974 | 976 | ||
@@ -1238,7 +1240,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1238 | } | 1240 | } |
1239 | 1241 | ||
1240 | if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { | 1242 | if (info->range.flags & NF_NAT_RANGE_MAP_IPS) { |
1241 | if (info->family == NFPROTO_IPV4) { | 1243 | if (IS_ENABLED(CONFIG_NF_NAT_IPV4) && |
1244 | info->family == NFPROTO_IPV4) { | ||
1242 | if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN, | 1245 | if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN, |
1243 | info->range.min_addr.ip) || | 1246 | info->range.min_addr.ip) || |
1244 | (info->range.max_addr.ip | 1247 | (info->range.max_addr.ip |
@@ -1246,8 +1249,8 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1246 | (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX, | 1249 | (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX, |
1247 | info->range.max_addr.ip)))) | 1250 | info->range.max_addr.ip)))) |
1248 | return false; | 1251 | return false; |
1249 | #if IS_ENABLED(CONFIG_NF_NAT_IPV6) | 1252 | } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) && |
1250 | } else if (info->family == NFPROTO_IPV6) { | 1253 | info->family == NFPROTO_IPV6) { |
1251 | if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN, | 1254 | if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN, |
1252 | &info->range.min_addr.in6) || | 1255 | &info->range.min_addr.in6) || |
1253 | (memcmp(&info->range.max_addr.in6, | 1256 | (memcmp(&info->range.max_addr.in6, |
@@ -1256,7 +1259,6 @@ static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info, | |||
1256 | (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX, | 1259 | (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MAX, |
1257 | &info->range.max_addr.in6)))) | 1260 | &info->range.max_addr.in6)))) |
1258 | return false; | 1261 | return false; |
1259 | #endif | ||
1260 | } else { | 1262 | } else { |
1261 | return false; | 1263 | return false; |
1262 | } | 1264 | } |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1ecfa710ca98..f12c17f355d9 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -4151,7 +4151,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, | |||
4151 | 4151 | ||
4152 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ | 4152 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ |
4153 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { | 4153 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { |
4154 | WARN(1, "Tx-ring is not supported.\n"); | 4154 | net_warn_ratelimited("Tx-ring is not supported.\n"); |
4155 | goto out; | 4155 | goto out; |
4156 | } | 4156 | } |
4157 | 4157 | ||
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 977fb86065b7..abc8cc805e8d 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
@@ -796,7 +796,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, | |||
796 | 796 | ||
797 | addr = kmap_atomic(sg_page(&frag->f_sg)); | 797 | addr = kmap_atomic(sg_page(&frag->f_sg)); |
798 | 798 | ||
799 | src = addr + frag_off; | 799 | src = addr + frag->f_sg.offset + frag_off; |
800 | dst = (void *)map->m_page_addrs[map_page] + map_off; | 800 | dst = (void *)map->m_page_addrs[map_page] + map_off; |
801 | for (k = 0; k < to_copy; k += 8) { | 801 | for (k = 0; k < to_copy; k += 8) { |
802 | /* Record ports that became uncongested, ie | 802 | /* Record ports that became uncongested, ie |
diff --git a/net/rds/page.c b/net/rds/page.c index 616f21f4e7d7..e2b5a5832d3d 100644 --- a/net/rds/page.c +++ b/net/rds/page.c | |||
@@ -135,8 +135,8 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, | |||
135 | if (rem->r_offset != 0) | 135 | if (rem->r_offset != 0) |
136 | rds_stats_inc(s_page_remainder_hit); | 136 | rds_stats_inc(s_page_remainder_hit); |
137 | 137 | ||
138 | rem->r_offset += bytes; | 138 | rem->r_offset += ALIGN(bytes, 8); |
139 | if (rem->r_offset == PAGE_SIZE) { | 139 | if (rem->r_offset >= PAGE_SIZE) { |
140 | __free_page(rem->r_page); | 140 | __free_page(rem->r_page); |
141 | rem->r_page = NULL; | 141 | rem->r_page = NULL; |
142 | } | 142 | } |
diff --git a/net/sctp/output.c b/net/sctp/output.c index 736c004abfbc..9844fe573029 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -401,7 +401,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
401 | sk = chunk->skb->sk; | 401 | sk = chunk->skb->sk; |
402 | 402 | ||
403 | /* Allocate the new skb. */ | 403 | /* Allocate the new skb. */ |
404 | nskb = alloc_skb(packet->size + MAX_HEADER, GFP_ATOMIC); | 404 | nskb = alloc_skb(packet->size + MAX_HEADER, gfp); |
405 | if (!nskb) | 405 | if (!nskb) |
406 | goto nomem; | 406 | goto nomem; |
407 | 407 | ||
@@ -523,8 +523,8 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp) | |||
523 | */ | 523 | */ |
524 | if (auth) | 524 | if (auth) |
525 | sctp_auth_calculate_hmac(asoc, nskb, | 525 | sctp_auth_calculate_hmac(asoc, nskb, |
526 | (struct sctp_auth_chunk *)auth, | 526 | (struct sctp_auth_chunk *)auth, |
527 | GFP_ATOMIC); | 527 | gfp); |
528 | 528 | ||
529 | /* 2) Calculate the Adler-32 checksum of the whole packet, | 529 | /* 2) Calculate the Adler-32 checksum of the whole packet, |
530 | * including the SCTP common header and all the | 530 | * including the SCTP common header and all the |
@@ -705,7 +705,8 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet, | |||
705 | /* Check whether this chunk and all the rest of pending data will fit | 705 | /* Check whether this chunk and all the rest of pending data will fit |
706 | * or delay in hopes of bundling a full sized packet. | 706 | * or delay in hopes of bundling a full sized packet. |
707 | */ | 707 | */ |
708 | if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead) | 708 | if (chunk->skb->len + q->out_qlen > |
709 | transport->pathmtu - packet->overhead - sizeof(sctp_data_chunk_t) - 4) | ||
709 | /* Enough data queued to fill a packet */ | 710 | /* Enough data queued to fill a packet */ |
710 | return SCTP_XMIT_OK; | 711 | return SCTP_XMIT_OK; |
711 | 712 | ||
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 8c6bc795f060..15612ffa8d57 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -1728,8 +1728,8 @@ alloc_enc_pages(struct rpc_rqst *rqstp) | |||
1728 | return 0; | 1728 | return 0; |
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | first = snd_buf->page_base >> PAGE_CACHE_SHIFT; | 1731 | first = snd_buf->page_base >> PAGE_SHIFT; |
1732 | last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT; | 1732 | last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; |
1733 | rqstp->rq_enc_pages_num = last - first + 1 + 1; | 1733 | rqstp->rq_enc_pages_num = last - first + 1 + 1; |
1734 | rqstp->rq_enc_pages | 1734 | rqstp->rq_enc_pages |
1735 | = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), | 1735 | = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), |
@@ -1775,10 +1775,10 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, | |||
1775 | status = alloc_enc_pages(rqstp); | 1775 | status = alloc_enc_pages(rqstp); |
1776 | if (status) | 1776 | if (status) |
1777 | return status; | 1777 | return status; |
1778 | first = snd_buf->page_base >> PAGE_CACHE_SHIFT; | 1778 | first = snd_buf->page_base >> PAGE_SHIFT; |
1779 | inpages = snd_buf->pages + first; | 1779 | inpages = snd_buf->pages + first; |
1780 | snd_buf->pages = rqstp->rq_enc_pages; | 1780 | snd_buf->pages = rqstp->rq_enc_pages; |
1781 | snd_buf->page_base -= first << PAGE_CACHE_SHIFT; | 1781 | snd_buf->page_base -= first << PAGE_SHIFT; |
1782 | /* | 1782 | /* |
1783 | * Give the tail its own page, in case we need extra space in the | 1783 | * Give the tail its own page, in case we need extra space in the |
1784 | * head when wrapping: | 1784 | * head when wrapping: |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index d94a8e1e9f05..045e11ecd332 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -465,7 +465,7 @@ encryptor(struct scatterlist *sg, void *data) | |||
465 | page_pos = desc->pos - outbuf->head[0].iov_len; | 465 | page_pos = desc->pos - outbuf->head[0].iov_len; |
466 | if (page_pos >= 0 && page_pos < outbuf->page_len) { | 466 | if (page_pos >= 0 && page_pos < outbuf->page_len) { |
467 | /* pages are not in place: */ | 467 | /* pages are not in place: */ |
468 | int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT; | 468 | int i = (page_pos + outbuf->page_base) >> PAGE_SHIFT; |
469 | in_page = desc->pages[i]; | 469 | in_page = desc->pages[i]; |
470 | } else { | 470 | } else { |
471 | in_page = sg_page(sg); | 471 | in_page = sg_page(sg); |
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c index 765088e4ad84..a737c2da0837 100644 --- a/net/sunrpc/auth_gss/gss_krb5_wrap.c +++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c | |||
@@ -79,9 +79,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize) | |||
79 | len -= buf->head[0].iov_len; | 79 | len -= buf->head[0].iov_len; |
80 | if (len <= buf->page_len) { | 80 | if (len <= buf->page_len) { |
81 | unsigned int last = (buf->page_base + len - 1) | 81 | unsigned int last = (buf->page_base + len - 1) |
82 | >>PAGE_CACHE_SHIFT; | 82 | >>PAGE_SHIFT; |
83 | unsigned int offset = (buf->page_base + len - 1) | 83 | unsigned int offset = (buf->page_base + len - 1) |
84 | & (PAGE_CACHE_SIZE - 1); | 84 | & (PAGE_SIZE - 1); |
85 | ptr = kmap_atomic(buf->pages[last]); | 85 | ptr = kmap_atomic(buf->pages[last]); |
86 | pad = *(ptr + offset); | 86 | pad = *(ptr + offset); |
87 | kunmap_atomic(ptr); | 87 | kunmap_atomic(ptr); |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 008c25d1b9f9..553bf95f7003 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -881,7 +881,7 @@ static ssize_t cache_downcall(struct address_space *mapping, | |||
881 | char *kaddr; | 881 | char *kaddr; |
882 | ssize_t ret = -ENOMEM; | 882 | ssize_t ret = -ENOMEM; |
883 | 883 | ||
884 | if (count >= PAGE_CACHE_SIZE) | 884 | if (count >= PAGE_SIZE) |
885 | goto out_slow; | 885 | goto out_slow; |
886 | 886 | ||
887 | page = find_or_create_page(mapping, 0, GFP_KERNEL); | 887 | page = find_or_create_page(mapping, 0, GFP_KERNEL); |
@@ -892,7 +892,7 @@ static ssize_t cache_downcall(struct address_space *mapping, | |||
892 | ret = cache_do_downcall(kaddr, buf, count, cd); | 892 | ret = cache_do_downcall(kaddr, buf, count, cd); |
893 | kunmap(page); | 893 | kunmap(page); |
894 | unlock_page(page); | 894 | unlock_page(page); |
895 | page_cache_release(page); | 895 | put_page(page); |
896 | return ret; | 896 | return ret; |
897 | out_slow: | 897 | out_slow: |
898 | return cache_slow_downcall(buf, count, cd); | 898 | return cache_slow_downcall(buf, count, cd); |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef3e614..fc48eca21fd2 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -1390,8 +1390,8 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
1390 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | 1390 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
1391 | int err; | 1391 | int err; |
1392 | 1392 | ||
1393 | sb->s_blocksize = PAGE_CACHE_SIZE; | 1393 | sb->s_blocksize = PAGE_SIZE; |
1394 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 1394 | sb->s_blocksize_bits = PAGE_SHIFT; |
1395 | sb->s_magic = RPCAUTH_GSSMAGIC; | 1395 | sb->s_magic = RPCAUTH_GSSMAGIC; |
1396 | sb->s_op = &s_ops; | 1396 | sb->s_op = &s_ops; |
1397 | sb->s_d_op = &simple_dentry_operations; | 1397 | sb->s_d_op = &simple_dentry_operations; |
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c index 2df87f78e518..de70c78025d7 100644 --- a/net/sunrpc/socklib.c +++ b/net/sunrpc/socklib.c | |||
@@ -96,8 +96,8 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct | |||
96 | if (base || xdr->page_base) { | 96 | if (base || xdr->page_base) { |
97 | pglen -= base; | 97 | pglen -= base; |
98 | base += xdr->page_base; | 98 | base += xdr->page_base; |
99 | ppage += base >> PAGE_CACHE_SHIFT; | 99 | ppage += base >> PAGE_SHIFT; |
100 | base &= ~PAGE_CACHE_MASK; | 100 | base &= ~PAGE_MASK; |
101 | } | 101 | } |
102 | do { | 102 | do { |
103 | char *kaddr; | 103 | char *kaddr; |
@@ -113,7 +113,7 @@ ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | len = PAGE_CACHE_SIZE; | 116 | len = PAGE_SIZE; |
117 | kaddr = kmap_atomic(*ppage); | 117 | kaddr = kmap_atomic(*ppage); |
118 | if (base) { | 118 | if (base) { |
119 | len -= base; | 119 | len -= base; |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4c1b53..6bdb3865212d 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(xdr_inline_pages); | |||
164 | * Note: the addresses pgto_base and pgfrom_base are both calculated in | 164 | * Note: the addresses pgto_base and pgfrom_base are both calculated in |
165 | * the same way: | 165 | * the same way: |
166 | * if a memory area starts at byte 'base' in page 'pages[i]', | 166 | * if a memory area starts at byte 'base' in page 'pages[i]', |
167 | * then its address is given as (i << PAGE_CACHE_SHIFT) + base | 167 | * then its address is given as (i << PAGE_SHIFT) + base |
168 | * Also note: pgfrom_base must be < pgto_base, but the memory areas | 168 | * Also note: pgfrom_base must be < pgto_base, but the memory areas |
169 | * they point to may overlap. | 169 | * they point to may overlap. |
170 | */ | 170 | */ |
@@ -181,20 +181,20 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, | |||
181 | pgto_base += len; | 181 | pgto_base += len; |
182 | pgfrom_base += len; | 182 | pgfrom_base += len; |
183 | 183 | ||
184 | pgto = pages + (pgto_base >> PAGE_CACHE_SHIFT); | 184 | pgto = pages + (pgto_base >> PAGE_SHIFT); |
185 | pgfrom = pages + (pgfrom_base >> PAGE_CACHE_SHIFT); | 185 | pgfrom = pages + (pgfrom_base >> PAGE_SHIFT); |
186 | 186 | ||
187 | pgto_base &= ~PAGE_CACHE_MASK; | 187 | pgto_base &= ~PAGE_MASK; |
188 | pgfrom_base &= ~PAGE_CACHE_MASK; | 188 | pgfrom_base &= ~PAGE_MASK; |
189 | 189 | ||
190 | do { | 190 | do { |
191 | /* Are any pointers crossing a page boundary? */ | 191 | /* Are any pointers crossing a page boundary? */ |
192 | if (pgto_base == 0) { | 192 | if (pgto_base == 0) { |
193 | pgto_base = PAGE_CACHE_SIZE; | 193 | pgto_base = PAGE_SIZE; |
194 | pgto--; | 194 | pgto--; |
195 | } | 195 | } |
196 | if (pgfrom_base == 0) { | 196 | if (pgfrom_base == 0) { |
197 | pgfrom_base = PAGE_CACHE_SIZE; | 197 | pgfrom_base = PAGE_SIZE; |
198 | pgfrom--; | 198 | pgfrom--; |
199 | } | 199 | } |
200 | 200 | ||
@@ -236,11 +236,11 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len) | |||
236 | char *vto; | 236 | char *vto; |
237 | size_t copy; | 237 | size_t copy; |
238 | 238 | ||
239 | pgto = pages + (pgbase >> PAGE_CACHE_SHIFT); | 239 | pgto = pages + (pgbase >> PAGE_SHIFT); |
240 | pgbase &= ~PAGE_CACHE_MASK; | 240 | pgbase &= ~PAGE_MASK; |
241 | 241 | ||
242 | for (;;) { | 242 | for (;;) { |
243 | copy = PAGE_CACHE_SIZE - pgbase; | 243 | copy = PAGE_SIZE - pgbase; |
244 | if (copy > len) | 244 | if (copy > len) |
245 | copy = len; | 245 | copy = len; |
246 | 246 | ||
@@ -253,7 +253,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len) | |||
253 | break; | 253 | break; |
254 | 254 | ||
255 | pgbase += copy; | 255 | pgbase += copy; |
256 | if (pgbase == PAGE_CACHE_SIZE) { | 256 | if (pgbase == PAGE_SIZE) { |
257 | flush_dcache_page(*pgto); | 257 | flush_dcache_page(*pgto); |
258 | pgbase = 0; | 258 | pgbase = 0; |
259 | pgto++; | 259 | pgto++; |
@@ -280,11 +280,11 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) | |||
280 | char *vfrom; | 280 | char *vfrom; |
281 | size_t copy; | 281 | size_t copy; |
282 | 282 | ||
283 | pgfrom = pages + (pgbase >> PAGE_CACHE_SHIFT); | 283 | pgfrom = pages + (pgbase >> PAGE_SHIFT); |
284 | pgbase &= ~PAGE_CACHE_MASK; | 284 | pgbase &= ~PAGE_MASK; |
285 | 285 | ||
286 | do { | 286 | do { |
287 | copy = PAGE_CACHE_SIZE - pgbase; | 287 | copy = PAGE_SIZE - pgbase; |
288 | if (copy > len) | 288 | if (copy > len) |
289 | copy = len; | 289 | copy = len; |
290 | 290 | ||
@@ -293,7 +293,7 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len) | |||
293 | kunmap_atomic(vfrom); | 293 | kunmap_atomic(vfrom); |
294 | 294 | ||
295 | pgbase += copy; | 295 | pgbase += copy; |
296 | if (pgbase == PAGE_CACHE_SIZE) { | 296 | if (pgbase == PAGE_SIZE) { |
297 | pgbase = 0; | 297 | pgbase = 0; |
298 | pgfrom++; | 298 | pgfrom++; |
299 | } | 299 | } |
@@ -1038,8 +1038,8 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, | |||
1038 | if (base < buf->page_len) { | 1038 | if (base < buf->page_len) { |
1039 | subbuf->page_len = min(buf->page_len - base, len); | 1039 | subbuf->page_len = min(buf->page_len - base, len); |
1040 | base += buf->page_base; | 1040 | base += buf->page_base; |
1041 | subbuf->page_base = base & ~PAGE_CACHE_MASK; | 1041 | subbuf->page_base = base & ~PAGE_MASK; |
1042 | subbuf->pages = &buf->pages[base >> PAGE_CACHE_SHIFT]; | 1042 | subbuf->pages = &buf->pages[base >> PAGE_SHIFT]; |
1043 | len -= subbuf->page_len; | 1043 | len -= subbuf->page_len; |
1044 | base = 0; | 1044 | base = 0; |
1045 | } else { | 1045 | } else { |
@@ -1297,9 +1297,9 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, | |||
1297 | todo -= avail_here; | 1297 | todo -= avail_here; |
1298 | 1298 | ||
1299 | base += buf->page_base; | 1299 | base += buf->page_base; |
1300 | ppages = buf->pages + (base >> PAGE_CACHE_SHIFT); | 1300 | ppages = buf->pages + (base >> PAGE_SHIFT); |
1301 | base &= ~PAGE_CACHE_MASK; | 1301 | base &= ~PAGE_MASK; |
1302 | avail_page = min_t(unsigned int, PAGE_CACHE_SIZE - base, | 1302 | avail_page = min_t(unsigned int, PAGE_SIZE - base, |
1303 | avail_here); | 1303 | avail_here); |
1304 | c = kmap(*ppages) + base; | 1304 | c = kmap(*ppages) + base; |
1305 | 1305 | ||
@@ -1383,7 +1383,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base, | |||
1383 | } | 1383 | } |
1384 | 1384 | ||
1385 | avail_page = min(avail_here, | 1385 | avail_page = min(avail_here, |
1386 | (unsigned int) PAGE_CACHE_SIZE); | 1386 | (unsigned int) PAGE_SIZE); |
1387 | } | 1387 | } |
1388 | base = buf->page_len; /* align to start of tail */ | 1388 | base = buf->page_len; /* align to start of tail */ |
1389 | } | 1389 | } |
@@ -1479,9 +1479,9 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | |||
1479 | if (page_len > len) | 1479 | if (page_len > len) |
1480 | page_len = len; | 1480 | page_len = len; |
1481 | len -= page_len; | 1481 | len -= page_len; |
1482 | page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1); | 1482 | page_offset = (offset + buf->page_base) & (PAGE_SIZE - 1); |
1483 | i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT; | 1483 | i = (offset + buf->page_base) >> PAGE_SHIFT; |
1484 | thislen = PAGE_CACHE_SIZE - page_offset; | 1484 | thislen = PAGE_SIZE - page_offset; |
1485 | do { | 1485 | do { |
1486 | if (thislen > page_len) | 1486 | if (thislen > page_len) |
1487 | thislen = page_len; | 1487 | thislen = page_len; |
@@ -1492,7 +1492,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len, | |||
1492 | page_len -= thislen; | 1492 | page_len -= thislen; |
1493 | i++; | 1493 | i++; |
1494 | page_offset = 0; | 1494 | page_offset = 0; |
1495 | thislen = PAGE_CACHE_SIZE; | 1495 | thislen = PAGE_SIZE; |
1496 | } while (page_len != 0); | 1496 | } while (page_len != 0); |
1497 | offset = 0; | 1497 | offset = 0; |
1498 | } | 1498 | } |
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 8b5833c1ff2e..2b9b98f1c2ff 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c | |||
@@ -1079,7 +1079,7 @@ nla_put_failure: | |||
1079 | * @filter_dev: filter device | 1079 | * @filter_dev: filter device |
1080 | * @idx: | 1080 | * @idx: |
1081 | * | 1081 | * |
1082 | * Delete FDB entry from switch device. | 1082 | * Dump FDB entries from switch device. |
1083 | */ | 1083 | */ |
1084 | int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, | 1084 | int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, |
1085 | struct net_device *dev, | 1085 | struct net_device *dev, |
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index 0a369bb440e7..662bdd20a748 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c | |||
@@ -842,7 +842,7 @@ static void vmci_transport_peer_detach_cb(u32 sub_id, | |||
842 | * qp_handle. | 842 | * qp_handle. |
843 | */ | 843 | */ |
844 | if (vmci_handle_is_invalid(e_payload->handle) || | 844 | if (vmci_handle_is_invalid(e_payload->handle) || |
845 | vmci_handle_is_equal(trans->qp_handle, e_payload->handle)) | 845 | !vmci_handle_is_equal(trans->qp_handle, e_payload->handle)) |
846 | return; | 846 | return; |
847 | 847 | ||
848 | /* We don't ask for delayed CBs when we subscribe to this event (we | 848 | /* We don't ask for delayed CBs when we subscribe to this event (we |
@@ -2154,7 +2154,7 @@ module_exit(vmci_transport_exit); | |||
2154 | 2154 | ||
2155 | MODULE_AUTHOR("VMware, Inc."); | 2155 | MODULE_AUTHOR("VMware, Inc."); |
2156 | MODULE_DESCRIPTION("VMCI transport for Virtual Sockets"); | 2156 | MODULE_DESCRIPTION("VMCI transport for Virtual Sockets"); |
2157 | MODULE_VERSION("1.0.2.0-k"); | 2157 | MODULE_VERSION("1.0.3.0-k"); |
2158 | MODULE_LICENSE("GPL v2"); | 2158 | MODULE_LICENSE("GPL v2"); |
2159 | MODULE_ALIAS("vmware_vsock"); | 2159 | MODULE_ALIAS("vmware_vsock"); |
2160 | MODULE_ALIAS_NETPROTO(PF_VSOCK); | 2160 | MODULE_ALIAS_NETPROTO(PF_VSOCK); |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index ad7f5b3f9b61..1c4ad477ce93 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -292,12 +292,15 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
292 | XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; | 292 | XFRM_SKB_CB(skb)->seq.input.hi = seq_hi; |
293 | 293 | ||
294 | skb_dst_force(skb); | 294 | skb_dst_force(skb); |
295 | dev_hold(skb->dev); | ||
295 | 296 | ||
296 | nexthdr = x->type->input(x, skb); | 297 | nexthdr = x->type->input(x, skb); |
297 | 298 | ||
298 | if (nexthdr == -EINPROGRESS) | 299 | if (nexthdr == -EINPROGRESS) |
299 | return 0; | 300 | return 0; |
300 | resume: | 301 | resume: |
302 | dev_put(skb->dev); | ||
303 | |||
301 | spin_lock(&x->lock); | 304 | spin_lock(&x->lock); |
302 | if (nexthdr <= 0) { | 305 | if (nexthdr <= 0) { |
303 | if (nexthdr == -EBADMSG) { | 306 | if (nexthdr == -EBADMSG) { |