aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/appletalk/ddp.c11
-rw-r--r--net/atm/common.c1
-rw-r--r--net/bridge/br_multicast.c2
-rw-r--r--net/bridge/br_stp_if.c2
-rw-r--r--net/ceph/Kconfig1
-rw-r--r--net/ceph/auth.c8
-rw-r--r--net/ceph/auth_x.c8
-rw-r--r--net/ceph/ceph_common.c112
-rw-r--r--net/ceph/crypto.c73
-rw-r--r--net/ceph/crypto.h4
-rw-r--r--net/ceph/mon_client.c2
-rw-r--r--net/ceph/osd_client.c12
-rw-r--r--net/core/dev.c24
-rw-r--r--net/ipv4/arp.c3
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/sctp/protocol.c4
17 files changed, 237 insertions, 34 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 206e771e82d1..956a5302002a 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1051,16 +1051,17 @@ static int atalk_release(struct socket *sock)
1051{ 1051{
1052 struct sock *sk = sock->sk; 1052 struct sock *sk = sock->sk;
1053 1053
1054 sock_hold(sk);
1055 lock_sock(sk);
1056 if (sk) { 1054 if (sk) {
1055 sock_hold(sk);
1056 lock_sock(sk);
1057
1057 sock_orphan(sk); 1058 sock_orphan(sk);
1058 sock->sk = NULL; 1059 sock->sk = NULL;
1059 atalk_destroy_socket(sk); 1060 atalk_destroy_socket(sk);
1060 }
1061 release_sock(sk);
1062 sock_put(sk);
1063 1061
1062 release_sock(sk);
1063 sock_put(sk);
1064 }
1064 return 0; 1065 return 0;
1065} 1066}
1066 1067
diff --git a/net/atm/common.c b/net/atm/common.c
index 1b9c52a02cd3..22b963d06a10 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev)
252 } 252 }
253 write_unlock_irq(&vcc_sklist_lock); 253 write_unlock_irq(&vcc_sklist_lock);
254} 254}
255EXPORT_SYMBOL(atm_dev_release_vccs);
255 256
256static int adjust_tp(struct atm_trafprm *tp, unsigned char aal) 257static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
257{ 258{
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f61eb2eff3fd..59660c909a7c 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
1475 ip6h->payload_len == 0) 1475 ip6h->payload_len == 0)
1476 return 0; 1476 return 0;
1477 1477
1478 len = ntohs(ip6h->payload_len); 1478 len = ntohs(ip6h->payload_len) + sizeof(*ip6h);
1479 if (skb->len < len) 1479 if (skb->len < len)
1480 return -EINVAL; 1480 return -EINVAL;
1481 1481
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 5593f5aec942..9b61d09de9b9 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -213,7 +213,7 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br)
213 213
214 /* user has chosen a value so keep it */ 214 /* user has chosen a value so keep it */
215 if (br->flags & BR_SET_MAC_ADDR) 215 if (br->flags & BR_SET_MAC_ADDR)
216 return; 216 return false;
217 217
218 list_for_each_entry(p, &br->port_list, list) { 218 list_for_each_entry(p, &br->port_list, list) {
219 if (addr == br_mac_zero || 219 if (addr == br_mac_zero ||
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index ad424049b0cf..be683f2d401f 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -4,6 +4,7 @@ config CEPH_LIB
4 select LIBCRC32C 4 select LIBCRC32C
5 select CRYPTO_AES 5 select CRYPTO_AES
6 select CRYPTO 6 select CRYPTO
7 select KEYS
7 default n 8 default n
8 help 9 help
9 Choose Y or M here to include cephlib, which provides the 10 Choose Y or M here to include cephlib, which provides the
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index 549c1f43e1d5..b4bf4ac090f1 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
35/* 35/*
36 * setup, teardown. 36 * setup, teardown.
37 */ 37 */
38struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) 38struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
39{ 39{
40 struct ceph_auth_client *ac; 40 struct ceph_auth_client *ac;
41 int ret; 41 int ret;
42 42
43 dout("auth_init name '%s' secret '%s'\n", name, secret); 43 dout("auth_init name '%s'\n", name);
44 44
45 ret = -ENOMEM; 45 ret = -ENOMEM;
46 ac = kzalloc(sizeof(*ac), GFP_NOFS); 46 ac = kzalloc(sizeof(*ac), GFP_NOFS);
@@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
52 ac->name = name; 52 ac->name = name;
53 else 53 else
54 ac->name = CEPH_AUTH_NAME_DEFAULT; 54 ac->name = CEPH_AUTH_NAME_DEFAULT;
55 dout("auth_init name %s secret %s\n", ac->name, secret); 55 dout("auth_init name %s\n", ac->name);
56 ac->secret = secret; 56 ac->key = key;
57 return ac; 57 return ac;
58 58
59out: 59out:
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 7fd5dfcf6e18..1587dc6010c6 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac)
662 goto out; 662 goto out;
663 663
664 ret = -EINVAL; 664 ret = -EINVAL;
665 if (!ac->secret) { 665 if (!ac->key) {
666 pr_err("no secret set (for auth_x protocol)\n"); 666 pr_err("no secret set (for auth_x protocol)\n");
667 goto out_nomem; 667 goto out_nomem;
668 } 668 }
669 669
670 ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); 670 ret = ceph_crypto_key_clone(&xi->secret, ac->key);
671 if (ret) 671 if (ret < 0) {
672 pr_err("cannot clone key: %d\n", ret);
672 goto out_nomem; 673 goto out_nomem;
674 }
673 675
674 xi->starting = true; 676 xi->starting = true;
675 xi->ticket_handlers = RB_ROOT; 677 xi->ticket_handlers = RB_ROOT;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 95f96ab94bba..132963abc266 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -5,6 +5,8 @@
5#include <linux/fs.h> 5#include <linux/fs.h>
6#include <linux/inet.h> 6#include <linux/inet.h>
7#include <linux/in6.h> 7#include <linux/in6.h>
8#include <linux/key.h>
9#include <keys/ceph-type.h>
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/mount.h> 11#include <linux/mount.h>
10#include <linux/parser.h> 12#include <linux/parser.h>
@@ -20,6 +22,7 @@
20#include <linux/ceph/decode.h> 22#include <linux/ceph/decode.h>
21#include <linux/ceph/mon_client.h> 23#include <linux/ceph/mon_client.h>
22#include <linux/ceph/auth.h> 24#include <linux/ceph/auth.h>
25#include "crypto.h"
23 26
24 27
25 28
@@ -117,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
117 if (ret) 120 if (ret)
118 return ret; 121 return ret;
119 122
120 ret = strcmp_null(opt1->secret, opt2->secret); 123 if (opt1->key && !opt2->key)
121 if (ret) 124 return -1;
122 return ret; 125 if (!opt1->key && opt2->key)
126 return 1;
127 if (opt1->key && opt2->key) {
128 if (opt1->key->type != opt2->key->type)
129 return -1;
130 if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
131 return -1;
132 if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
133 return -1;
134 if (opt1->key->len != opt2->key->len)
135 return -1;
136 if (opt1->key->key && !opt2->key->key)
137 return -1;
138 if (!opt1->key->key && opt2->key->key)
139 return 1;
140 if (opt1->key->key && opt2->key->key) {
141 ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
142 if (ret)
143 return ret;
144 }
145 }
123 146
124 /* any matching mon ip implies a match */ 147 /* any matching mon ip implies a match */
125 for (i = 0; i < opt1->num_mon; i++) { 148 for (i = 0; i < opt1->num_mon; i++) {
@@ -176,6 +199,7 @@ enum {
176 Opt_fsid, 199 Opt_fsid,
177 Opt_name, 200 Opt_name,
178 Opt_secret, 201 Opt_secret,
202 Opt_key,
179 Opt_ip, 203 Opt_ip,
180 Opt_last_string, 204 Opt_last_string,
181 /* string args above */ 205 /* string args above */
@@ -192,6 +216,7 @@ static match_table_t opt_tokens = {
192 {Opt_fsid, "fsid=%s"}, 216 {Opt_fsid, "fsid=%s"},
193 {Opt_name, "name=%s"}, 217 {Opt_name, "name=%s"},
194 {Opt_secret, "secret=%s"}, 218 {Opt_secret, "secret=%s"},
219 {Opt_key, "key=%s"},
195 {Opt_ip, "ip=%s"}, 220 {Opt_ip, "ip=%s"},
196 /* string args above */ 221 /* string args above */
197 {Opt_noshare, "noshare"}, 222 {Opt_noshare, "noshare"},
@@ -203,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt)
203{ 228{
204 dout("destroy_options %p\n", opt); 229 dout("destroy_options %p\n", opt);
205 kfree(opt->name); 230 kfree(opt->name);
206 kfree(opt->secret); 231 if (opt->key) {
232 ceph_crypto_key_destroy(opt->key);
233 kfree(opt->key);
234 }
207 kfree(opt); 235 kfree(opt);
208} 236}
209EXPORT_SYMBOL(ceph_destroy_options); 237EXPORT_SYMBOL(ceph_destroy_options);
210 238
239/* get secret from key store */
240static int get_secret(struct ceph_crypto_key *dst, const char *name) {
241 struct key *ukey;
242 int key_err;
243 int err = 0;
244 struct ceph_crypto_key *ckey;
245
246 ukey = request_key(&key_type_ceph, name, NULL);
247 if (!ukey || IS_ERR(ukey)) {
248 /* request_key errors don't map nicely to mount(2)
249 errors; don't even try, but still printk */
250 key_err = PTR_ERR(ukey);
251 switch (key_err) {
252 case -ENOKEY:
253 pr_warning("ceph: Mount failed due to key not found: %s\n", name);
254 break;
255 case -EKEYEXPIRED:
256 pr_warning("ceph: Mount failed due to expired key: %s\n", name);
257 break;
258 case -EKEYREVOKED:
259 pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
260 break;
261 default:
262 pr_warning("ceph: Mount failed due to unknown key error"
263 " %d: %s\n", key_err, name);
264 }
265 err = -EPERM;
266 goto out;
267 }
268
269 ckey = ukey->payload.data;
270 err = ceph_crypto_key_clone(dst, ckey);
271 if (err)
272 goto out_key;
273 /* pass through, err is 0 */
274
275out_key:
276 key_put(ukey);
277out:
278 return err;
279}
280
211int ceph_parse_options(struct ceph_options **popt, char *options, 281int ceph_parse_options(struct ceph_options **popt, char *options,
212 const char *dev_name, const char *dev_name_end, 282 const char *dev_name, const char *dev_name_end,
213 int (*parse_extra_token)(char *c, void *private), 283 int (*parse_extra_token)(char *c, void *private),
@@ -295,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
295 GFP_KERNEL); 365 GFP_KERNEL);
296 break; 366 break;
297 case Opt_secret: 367 case Opt_secret:
298 opt->secret = kstrndup(argstr[0].from, 368 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
299 argstr[0].to-argstr[0].from, 369 if (!opt->key) {
300 GFP_KERNEL); 370 err = -ENOMEM;
371 goto out;
372 }
373 err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
374 if (err < 0)
375 goto out;
376 break;
377 case Opt_key:
378 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
379 if (!opt->key) {
380 err = -ENOMEM;
381 goto out;
382 }
383 err = get_secret(opt->key, argstr[0].from);
384 if (err < 0)
385 goto out;
301 break; 386 break;
302 387
303 /* misc */ 388 /* misc */
@@ -394,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client)
394 ceph_osdc_stop(&client->osdc); 479 ceph_osdc_stop(&client->osdc);
395 480
396 /* 481 /*
397 * make sure mds and osd connections close out before destroying 482 * make sure osd connections close out before destroying the
398 * the auth module, which is needed to free those connections' 483 * auth module, which is needed to free those connections'
399 * ceph_authorizers. 484 * ceph_authorizers.
400 */ 485 */
401 ceph_msgr_flush(); 486 ceph_msgr_flush();
@@ -496,10 +581,14 @@ static int __init init_ceph_lib(void)
496 if (ret < 0) 581 if (ret < 0)
497 goto out; 582 goto out;
498 583
499 ret = ceph_msgr_init(); 584 ret = ceph_crypto_init();
500 if (ret < 0) 585 if (ret < 0)
501 goto out_debugfs; 586 goto out_debugfs;
502 587
588 ret = ceph_msgr_init();
589 if (ret < 0)
590 goto out_crypto;
591
503 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", 592 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
504 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, 593 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
505 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, 594 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -507,6 +596,8 @@ static int __init init_ceph_lib(void)
507 596
508 return 0; 597 return 0;
509 598
599out_crypto:
600 ceph_crypto_shutdown();
510out_debugfs: 601out_debugfs:
511 ceph_debugfs_cleanup(); 602 ceph_debugfs_cleanup();
512out: 603out:
@@ -517,6 +608,7 @@ static void __exit exit_ceph_lib(void)
517{ 608{
518 dout("exit_ceph_lib\n"); 609 dout("exit_ceph_lib\n");
519 ceph_msgr_exit(); 610 ceph_msgr_exit();
611 ceph_crypto_shutdown();
520 ceph_debugfs_cleanup(); 612 ceph_debugfs_cleanup();
521} 613}
522 614
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 7b505b0c983f..5a8009c9e0cd 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -5,10 +5,23 @@
5#include <linux/scatterlist.h> 5#include <linux/scatterlist.h>
6#include <linux/slab.h> 6#include <linux/slab.h>
7#include <crypto/hash.h> 7#include <crypto/hash.h>
8#include <linux/key-type.h>
8 9
10#include <keys/ceph-type.h>
9#include <linux/ceph/decode.h> 11#include <linux/ceph/decode.h>
10#include "crypto.h" 12#include "crypto.h"
11 13
14int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
15 const struct ceph_crypto_key *src)
16{
17 memcpy(dst, src, sizeof(struct ceph_crypto_key));
18 dst->key = kmalloc(src->len, GFP_NOFS);
19 if (!dst->key)
20 return -ENOMEM;
21 memcpy(dst->key, src->key, src->len);
22 return 0;
23}
24
12int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) 25int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
13{ 26{
14 if (*p + sizeof(u16) + sizeof(key->created) + 27 if (*p + sizeof(u16) + sizeof(key->created) +
@@ -410,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
410 return -EINVAL; 423 return -EINVAL;
411 } 424 }
412} 425}
426
427int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
428{
429 struct ceph_crypto_key *ckey;
430 int ret;
431 void *p;
432
433 ret = -EINVAL;
434 if (datalen <= 0 || datalen > 32767 || !data)
435 goto err;
436
437 ret = key_payload_reserve(key, datalen);
438 if (ret < 0)
439 goto err;
440
441 ret = -ENOMEM;
442 ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
443 if (!ckey)
444 goto err;
445
446 /* TODO ceph_crypto_key_decode should really take const input */
447 p = (void*)data;
448 ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
449 if (ret < 0)
450 goto err_ckey;
451
452 key->payload.data = ckey;
453 return 0;
454
455err_ckey:
456 kfree(ckey);
457err:
458 return ret;
459}
460
461int ceph_key_match(const struct key *key, const void *description)
462{
463 return strcmp(key->description, description) == 0;
464}
465
466void ceph_key_destroy(struct key *key) {
467 struct ceph_crypto_key *ckey = key->payload.data;
468
469 ceph_crypto_key_destroy(ckey);
470}
471
472struct key_type key_type_ceph = {
473 .name = "ceph",
474 .instantiate = ceph_key_instantiate,
475 .match = ceph_key_match,
476 .destroy = ceph_key_destroy,
477};
478
479int ceph_crypto_init(void) {
480 return register_key_type(&key_type_ceph);
481}
482
483void ceph_crypto_shutdown(void) {
484 unregister_key_type(&key_type_ceph);
485}
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index f9eccace592b..1919d1550d75 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
19 kfree(key->key); 19 kfree(key->key);
20} 20}
21 21
22extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
23 const struct ceph_crypto_key *src);
22extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, 24extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
23 void **p, void *end); 25 void **p, void *end);
24extern int ceph_crypto_key_decode(struct ceph_crypto_key *key, 26extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
@@ -40,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret,
40 void *dst, size_t *dst_len, 42 void *dst, size_t *dst_len,
41 const void *src1, size_t src1_len, 43 const void *src1, size_t src1_len,
42 const void *src2, size_t src2_len); 44 const void *src2, size_t src2_len);
45extern int ceph_crypto_init(void);
46extern void ceph_crypto_shutdown(void);
43 47
44/* armor.c */ 48/* armor.c */
45extern int ceph_armor(char *dst, const char *src, const char *end); 49extern int ceph_armor(char *dst, const char *src, const char *end);
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 8a079399174a..cbe31fa45508 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
759 759
760 /* authentication */ 760 /* authentication */
761 monc->auth = ceph_auth_init(cl->options->name, 761 monc->auth = ceph_auth_init(cl->options->name,
762 cl->options->secret); 762 cl->options->key);
763 if (IS_ERR(monc->auth)) 763 if (IS_ERR(monc->auth))
764 return PTR_ERR(monc->auth); 764 return PTR_ERR(monc->auth);
765 monc->auth->want_keys = 765 monc->auth->want_keys =
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 02212ed50852..3b91d651fe08 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -837,8 +837,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
837 dout("moving osd to %p lru\n", req->r_osd); 837 dout("moving osd to %p lru\n", req->r_osd);
838 __move_osd_to_lru(osdc, req->r_osd); 838 __move_osd_to_lru(osdc, req->r_osd);
839 } 839 }
840 if (list_empty(&req->r_osd_item) && 840 if (list_empty(&req->r_linger_item))
841 list_empty(&req->r_linger_item))
842 req->r_osd = NULL; 841 req->r_osd = NULL;
843 } 842 }
844 843
@@ -883,7 +882,8 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc,
883 dout("moving osd to %p lru\n", req->r_osd); 882 dout("moving osd to %p lru\n", req->r_osd);
884 __move_osd_to_lru(osdc, req->r_osd); 883 __move_osd_to_lru(osdc, req->r_osd);
885 } 884 }
886 req->r_osd = NULL; 885 if (list_empty(&req->r_osd_item))
886 req->r_osd = NULL;
887 } 887 }
888} 888}
889 889
@@ -1602,11 +1602,11 @@ void handle_watch_notify(struct ceph_osd_client *osdc, struct ceph_msg *msg)
1602 cookie, ver, event); 1602 cookie, ver, event);
1603 if (event) { 1603 if (event) {
1604 event_work = kmalloc(sizeof(*event_work), GFP_NOIO); 1604 event_work = kmalloc(sizeof(*event_work), GFP_NOIO);
1605 INIT_WORK(&event_work->work, do_event_work);
1606 if (!event_work) { 1605 if (!event_work) {
1607 dout("ERROR: could not allocate event_work\n"); 1606 dout("ERROR: could not allocate event_work\n");
1608 goto done_err; 1607 goto done_err;
1609 } 1608 }
1609 INIT_WORK(&event_work->work, do_event_work);
1610 event_work->event = event; 1610 event_work->event = event;
1611 event_work->ver = ver; 1611 event_work->ver = ver;
1612 event_work->notify_id = notify_id; 1612 event_work->notify_id = notify_id;
@@ -1672,7 +1672,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1672 if (req->r_sent == 0) { 1672 if (req->r_sent == 0) {
1673 rc = __map_request(osdc, req); 1673 rc = __map_request(osdc, req);
1674 if (rc < 0) 1674 if (rc < 0)
1675 return rc; 1675 goto out_unlock;
1676 if (req->r_osd == NULL) { 1676 if (req->r_osd == NULL) {
1677 dout("send_request %p no up osds in pg\n", req); 1677 dout("send_request %p no up osds in pg\n", req);
1678 ceph_monc_request_next_osdmap(&osdc->client->monc); 1678 ceph_monc_request_next_osdmap(&osdc->client->monc);
@@ -1689,6 +1689,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
1689 } 1689 }
1690 } 1690 }
1691 } 1691 }
1692
1693out_unlock:
1692 mutex_unlock(&osdc->request_mutex); 1694 mutex_unlock(&osdc->request_mutex);
1693 up_read(&osdc->map_sem); 1695 up_read(&osdc->map_sem);
1694 return rc; 1696 return rc;
diff --git a/net/core/dev.c b/net/core/dev.c
index 563ddc28139d..3da9fb06d47a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1454,6 +1454,27 @@ static inline void net_timestamp_check(struct sk_buff *skb)
1454 __net_timestamp(skb); 1454 __net_timestamp(skb);
1455} 1455}
1456 1456
1457static inline bool is_skb_forwardable(struct net_device *dev,
1458 struct sk_buff *skb)
1459{
1460 unsigned int len;
1461
1462 if (!(dev->flags & IFF_UP))
1463 return false;
1464
1465 len = dev->mtu + dev->hard_header_len + VLAN_HLEN;
1466 if (skb->len <= len)
1467 return true;
1468
1469 /* if TSO is enabled, we don't care about the length as the packet
1470 * could be forwarded without being segmented before
1471 */
1472 if (skb_is_gso(skb))
1473 return true;
1474
1475 return false;
1476}
1477
1457/** 1478/**
1458 * dev_forward_skb - loopback an skb to another netif 1479 * dev_forward_skb - loopback an skb to another netif
1459 * 1480 *
@@ -1477,8 +1498,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
1477 skb_orphan(skb); 1498 skb_orphan(skb);
1478 nf_reset(skb); 1499 nf_reset(skb);
1479 1500
1480 if (unlikely(!(dev->flags & IFF_UP) || 1501 if (unlikely(!is_skb_forwardable(dev, skb))) {
1481 (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
1482 atomic_long_inc(&dev->rx_dropped); 1502 atomic_long_inc(&dev->rx_dropped);
1483 kfree_skb(skb); 1503 kfree_skb(skb);
1484 return NET_RX_DROP; 1504 return NET_RX_DROP;
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090d273d7865..1b74d3b64371 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
215 case ARPHRD_INFINIBAND: 215 case ARPHRD_INFINIBAND:
216 ip_ib_mc_map(addr, dev->broadcast, haddr); 216 ip_ib_mc_map(addr, dev->broadcast, haddr);
217 return 0; 217 return 0;
218 case ARPHRD_IPGRE:
219 ip_ipgre_mc_map(addr, dev->broadcast, haddr);
220 return 0;
218 default: 221 default:
219 if (dir) { 222 if (dir) {
220 memcpy(haddr, dev->broadcast, dev->addr_len); 223 memcpy(haddr, dev->broadcast, dev->addr_len);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f116ce8f1b46..451088330bbb 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1068,6 +1068,7 @@ static void ip_fib_net_exit(struct net *net)
1068 fib4_rules_exit(net); 1068 fib4_rules_exit(net);
1069#endif 1069#endif
1070 1070
1071 rtnl_lock();
1071 for (i = 0; i < FIB_TABLE_HASHSZ; i++) { 1072 for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
1072 struct fib_table *tb; 1073 struct fib_table *tb;
1073 struct hlist_head *head; 1074 struct hlist_head *head;
@@ -1080,6 +1081,7 @@ static void ip_fib_net_exit(struct net *net)
1080 fib_free_table(tb); 1081 fib_free_table(tb);
1081 } 1082 }
1082 } 1083 }
1084 rtnl_unlock();
1083 kfree(net->ipv4.fib_table_hash); 1085 kfree(net->ipv4.fib_table_hash);
1084} 1086}
1085 1087
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e49c9db3c98..92f952d093db 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
341 case ARPHRD_INFINIBAND: 341 case ARPHRD_INFINIBAND:
342 ipv6_ib_mc_map(addr, dev->broadcast, buf); 342 ipv6_ib_mc_map(addr, dev->broadcast, buf);
343 return 0; 343 return 0;
344 case ARPHRD_IPGRE:
345 return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
344 default: 346 default:
345 if (dir) { 347 if (dir) {
346 memcpy(buf, dev->broadcast, dev->addr_len); 348 memcpy(buf, dev->broadcast, dev->addr_len);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 152976ec0b74..d5bf91d04f63 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void)
1205 if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0) 1205 if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)
1206 continue; 1206 continue;
1207 sctp_assoc_hashtable = (struct sctp_hashbucket *) 1207 sctp_assoc_hashtable = (struct sctp_hashbucket *)
1208 __get_free_pages(GFP_ATOMIC, order); 1208 __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
1209 } while (!sctp_assoc_hashtable && --order > 0); 1209 } while (!sctp_assoc_hashtable && --order > 0);
1210 if (!sctp_assoc_hashtable) { 1210 if (!sctp_assoc_hashtable) {
1211 pr_err("Failed association hash alloc\n"); 1211 pr_err("Failed association hash alloc\n");
@@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void)
1238 if ((sctp_port_hashsize > (64 * 1024)) && order > 0) 1238 if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
1239 continue; 1239 continue;
1240 sctp_port_hashtable = (struct sctp_bind_hashbucket *) 1240 sctp_port_hashtable = (struct sctp_bind_hashbucket *)
1241 __get_free_pages(GFP_ATOMIC, order); 1241 __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
1242 } while (!sctp_port_hashtable && --order > 0); 1242 } while (!sctp_port_hashtable && --order > 0);
1243 if (!sctp_port_hashtable) { 1243 if (!sctp_port_hashtable) {
1244 pr_err("Failed bind hash alloc\n"); 1244 pr_err("Failed bind hash alloc\n");