diff options
Diffstat (limited to 'net')
63 files changed, 830 insertions, 384 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 453512266ea1..db783d7af5a3 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -378,6 +378,8 @@ static void vlan_transfer_features(struct net_device *dev, | |||
378 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | 378 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) |
379 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; | 379 | vlandev->fcoe_ddp_xid = dev->fcoe_ddp_xid; |
380 | #endif | 380 | #endif |
381 | vlandev->real_num_tx_queues = dev->real_num_tx_queues; | ||
382 | BUG_ON(vlandev->real_num_tx_queues > vlandev->num_tx_queues); | ||
381 | 383 | ||
382 | if (old_features != vlandev->features) | 384 | if (old_features != vlandev->features) |
383 | netdev_features_change(vlandev); | 385 | netdev_features_change(vlandev); |
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index c0316e0ca6e8..c584a0af77d3 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -11,7 +11,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
11 | if (netpoll_rx(skb)) | 11 | if (netpoll_rx(skb)) |
12 | return NET_RX_DROP; | 12 | return NET_RX_DROP; |
13 | 13 | ||
14 | if (skb_bond_should_drop(skb)) | 14 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
15 | goto drop; | 15 | goto drop; |
16 | 16 | ||
17 | skb->skb_iif = skb->dev->ifindex; | 17 | skb->skb_iif = skb->dev->ifindex; |
@@ -83,7 +83,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, | |||
83 | { | 83 | { |
84 | struct sk_buff *p; | 84 | struct sk_buff *p; |
85 | 85 | ||
86 | if (skb_bond_should_drop(skb)) | 86 | if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) |
87 | goto drop; | 87 | goto drop; |
88 | 88 | ||
89 | skb->skb_iif = skb->dev->ifindex; | 89 | skb->skb_iif = skb->dev->ifindex; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9e83272fc5b0..2fd057c81bbf 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -361,6 +361,14 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, | |||
361 | return ret; | 361 | return ret; |
362 | } | 362 | } |
363 | 363 | ||
364 | static u16 vlan_dev_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
365 | { | ||
366 | struct net_device *rdev = vlan_dev_info(dev)->real_dev; | ||
367 | const struct net_device_ops *ops = rdev->netdev_ops; | ||
368 | |||
369 | return ops->ndo_select_queue(rdev, skb); | ||
370 | } | ||
371 | |||
364 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) | 372 | static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu) |
365 | { | 373 | { |
366 | /* TODO: gotta make sure the underlying layer can handle it, | 374 | /* TODO: gotta make sure the underlying layer can handle it, |
@@ -688,7 +696,8 @@ static const struct header_ops vlan_header_ops = { | |||
688 | .parse = eth_header_parse, | 696 | .parse = eth_header_parse, |
689 | }; | 697 | }; |
690 | 698 | ||
691 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops; | 699 | static const struct net_device_ops vlan_netdev_ops, vlan_netdev_accel_ops, |
700 | vlan_netdev_ops_sq, vlan_netdev_accel_ops_sq; | ||
692 | 701 | ||
693 | static int vlan_dev_init(struct net_device *dev) | 702 | static int vlan_dev_init(struct net_device *dev) |
694 | { | 703 | { |
@@ -722,11 +731,17 @@ static int vlan_dev_init(struct net_device *dev) | |||
722 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { | 731 | if (real_dev->features & NETIF_F_HW_VLAN_TX) { |
723 | dev->header_ops = real_dev->header_ops; | 732 | dev->header_ops = real_dev->header_ops; |
724 | dev->hard_header_len = real_dev->hard_header_len; | 733 | dev->hard_header_len = real_dev->hard_header_len; |
725 | dev->netdev_ops = &vlan_netdev_accel_ops; | 734 | if (real_dev->netdev_ops->ndo_select_queue) |
735 | dev->netdev_ops = &vlan_netdev_accel_ops_sq; | ||
736 | else | ||
737 | dev->netdev_ops = &vlan_netdev_accel_ops; | ||
726 | } else { | 738 | } else { |
727 | dev->header_ops = &vlan_header_ops; | 739 | dev->header_ops = &vlan_header_ops; |
728 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; | 740 | dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN; |
729 | dev->netdev_ops = &vlan_netdev_ops; | 741 | if (real_dev->netdev_ops->ndo_select_queue) |
742 | dev->netdev_ops = &vlan_netdev_ops_sq; | ||
743 | else | ||
744 | dev->netdev_ops = &vlan_netdev_ops; | ||
730 | } | 745 | } |
731 | 746 | ||
732 | if (is_vlan_dev(real_dev)) | 747 | if (is_vlan_dev(real_dev)) |
@@ -865,6 +880,56 @@ static const struct net_device_ops vlan_netdev_accel_ops = { | |||
865 | #endif | 880 | #endif |
866 | }; | 881 | }; |
867 | 882 | ||
883 | static const struct net_device_ops vlan_netdev_ops_sq = { | ||
884 | .ndo_select_queue = vlan_dev_select_queue, | ||
885 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
886 | .ndo_init = vlan_dev_init, | ||
887 | .ndo_uninit = vlan_dev_uninit, | ||
888 | .ndo_open = vlan_dev_open, | ||
889 | .ndo_stop = vlan_dev_stop, | ||
890 | .ndo_start_xmit = vlan_dev_hard_start_xmit, | ||
891 | .ndo_validate_addr = eth_validate_addr, | ||
892 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
893 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
894 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
895 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
896 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
897 | .ndo_neigh_setup = vlan_dev_neigh_setup, | ||
898 | .ndo_get_stats = vlan_dev_get_stats, | ||
899 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
900 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
901 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
902 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
903 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
904 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | ||
905 | #endif | ||
906 | }; | ||
907 | |||
908 | static const struct net_device_ops vlan_netdev_accel_ops_sq = { | ||
909 | .ndo_select_queue = vlan_dev_select_queue, | ||
910 | .ndo_change_mtu = vlan_dev_change_mtu, | ||
911 | .ndo_init = vlan_dev_init, | ||
912 | .ndo_uninit = vlan_dev_uninit, | ||
913 | .ndo_open = vlan_dev_open, | ||
914 | .ndo_stop = vlan_dev_stop, | ||
915 | .ndo_start_xmit = vlan_dev_hwaccel_hard_start_xmit, | ||
916 | .ndo_validate_addr = eth_validate_addr, | ||
917 | .ndo_set_mac_address = vlan_dev_set_mac_address, | ||
918 | .ndo_set_rx_mode = vlan_dev_set_rx_mode, | ||
919 | .ndo_set_multicast_list = vlan_dev_set_rx_mode, | ||
920 | .ndo_change_rx_flags = vlan_dev_change_rx_flags, | ||
921 | .ndo_do_ioctl = vlan_dev_ioctl, | ||
922 | .ndo_neigh_setup = vlan_dev_neigh_setup, | ||
923 | .ndo_get_stats = vlan_dev_get_stats, | ||
924 | #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) | ||
925 | .ndo_fcoe_ddp_setup = vlan_dev_fcoe_ddp_setup, | ||
926 | .ndo_fcoe_ddp_done = vlan_dev_fcoe_ddp_done, | ||
927 | .ndo_fcoe_enable = vlan_dev_fcoe_enable, | ||
928 | .ndo_fcoe_disable = vlan_dev_fcoe_disable, | ||
929 | .ndo_fcoe_get_wwn = vlan_dev_fcoe_get_wwn, | ||
930 | #endif | ||
931 | }; | ||
932 | |||
868 | void vlan_setup(struct net_device *dev) | 933 | void vlan_setup(struct net_device *dev) |
869 | { | 934 | { |
870 | ether_setup(dev); | 935 | ether_setup(dev); |
diff --git a/net/9p/client.c b/net/9p/client.c index 09d4f1e2e4a8..e3e5bf4469ce 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -46,6 +46,7 @@ enum { | |||
46 | Opt_msize, | 46 | Opt_msize, |
47 | Opt_trans, | 47 | Opt_trans, |
48 | Opt_legacy, | 48 | Opt_legacy, |
49 | Opt_version, | ||
49 | Opt_err, | 50 | Opt_err, |
50 | }; | 51 | }; |
51 | 52 | ||
@@ -53,9 +54,42 @@ static const match_table_t tokens = { | |||
53 | {Opt_msize, "msize=%u"}, | 54 | {Opt_msize, "msize=%u"}, |
54 | {Opt_legacy, "noextend"}, | 55 | {Opt_legacy, "noextend"}, |
55 | {Opt_trans, "trans=%s"}, | 56 | {Opt_trans, "trans=%s"}, |
57 | {Opt_version, "version=%s"}, | ||
56 | {Opt_err, NULL}, | 58 | {Opt_err, NULL}, |
57 | }; | 59 | }; |
58 | 60 | ||
61 | inline int p9_is_proto_dotl(struct p9_client *clnt) | ||
62 | { | ||
63 | return (clnt->proto_version == p9_proto_2000L); | ||
64 | } | ||
65 | EXPORT_SYMBOL(p9_is_proto_dotl); | ||
66 | |||
67 | inline int p9_is_proto_dotu(struct p9_client *clnt) | ||
68 | { | ||
69 | return (clnt->proto_version == p9_proto_2000u); | ||
70 | } | ||
71 | EXPORT_SYMBOL(p9_is_proto_dotu); | ||
72 | |||
73 | /* Interpret mount option for protocol version */ | ||
74 | static unsigned char get_protocol_version(const substring_t *name) | ||
75 | { | ||
76 | unsigned char version = -EINVAL; | ||
77 | if (!strncmp("9p2000", name->from, name->to-name->from)) { | ||
78 | version = p9_proto_legacy; | ||
79 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: Legacy\n"); | ||
80 | } else if (!strncmp("9p2000.u", name->from, name->to-name->from)) { | ||
81 | version = p9_proto_2000u; | ||
82 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.u\n"); | ||
83 | } else if (!strncmp("9p2000.L", name->from, name->to-name->from)) { | ||
84 | version = p9_proto_2000L; | ||
85 | P9_DPRINTK(P9_DEBUG_9P, "Protocol version: 9P2000.L\n"); | ||
86 | } else { | ||
87 | P9_DPRINTK(P9_DEBUG_ERROR, "Unknown protocol version %s. ", | ||
88 | name->from); | ||
89 | } | ||
90 | return version; | ||
91 | } | ||
92 | |||
59 | static struct p9_req_t * | 93 | static struct p9_req_t * |
60 | p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); | 94 | p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...); |
61 | 95 | ||
@@ -75,7 +109,7 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
75 | int option; | 109 | int option; |
76 | int ret = 0; | 110 | int ret = 0; |
77 | 111 | ||
78 | clnt->dotu = 1; | 112 | clnt->proto_version = p9_proto_2000u; |
79 | clnt->msize = 8192; | 113 | clnt->msize = 8192; |
80 | 114 | ||
81 | if (!opts) | 115 | if (!opts) |
@@ -118,7 +152,13 @@ static int parse_opts(char *opts, struct p9_client *clnt) | |||
118 | } | 152 | } |
119 | break; | 153 | break; |
120 | case Opt_legacy: | 154 | case Opt_legacy: |
121 | clnt->dotu = 0; | 155 | clnt->proto_version = p9_proto_legacy; |
156 | break; | ||
157 | case Opt_version: | ||
158 | ret = get_protocol_version(&args[0]); | ||
159 | if (ret == -EINVAL) | ||
160 | goto free_and_return; | ||
161 | clnt->proto_version = ret; | ||
122 | break; | 162 | break; |
123 | default: | 163 | default: |
124 | continue; | 164 | continue; |
@@ -410,14 +450,15 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req) | |||
410 | int ecode; | 450 | int ecode; |
411 | char *ename; | 451 | char *ename; |
412 | 452 | ||
413 | err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode); | 453 | err = p9pdu_readf(req->rc, c->proto_version, "s?d", |
454 | &ename, &ecode); | ||
414 | if (err) { | 455 | if (err) { |
415 | P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", | 456 | P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n", |
416 | err); | 457 | err); |
417 | return err; | 458 | return err; |
418 | } | 459 | } |
419 | 460 | ||
420 | if (c->dotu) | 461 | if (p9_is_proto_dotu(c)) |
421 | err = -ecode; | 462 | err = -ecode; |
422 | 463 | ||
423 | if (!err || !IS_ERR_VALUE(err)) | 464 | if (!err || !IS_ERR_VALUE(err)) |
@@ -515,7 +556,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) | |||
515 | /* marshall the data */ | 556 | /* marshall the data */ |
516 | p9pdu_prepare(req->tc, tag, type); | 557 | p9pdu_prepare(req->tc, tag, type); |
517 | va_start(ap, fmt); | 558 | va_start(ap, fmt); |
518 | err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap); | 559 | err = p9pdu_vwritef(req->tc, c->proto_version, fmt, ap); |
519 | va_end(ap); | 560 | va_end(ap); |
520 | p9pdu_finalize(req->tc); | 561 | p9pdu_finalize(req->tc); |
521 | 562 | ||
@@ -627,14 +668,31 @@ int p9_client_version(struct p9_client *c) | |||
627 | char *version; | 668 | char *version; |
628 | int msize; | 669 | int msize; |
629 | 670 | ||
630 | P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n", | 671 | P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n", |
631 | c->msize, c->dotu); | 672 | c->msize, c->proto_version); |
632 | req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize, | 673 | |
633 | c->dotu ? "9P2000.u" : "9P2000"); | 674 | switch (c->proto_version) { |
675 | case p9_proto_2000L: | ||
676 | req = p9_client_rpc(c, P9_TVERSION, "ds", | ||
677 | c->msize, "9P2000.L"); | ||
678 | break; | ||
679 | case p9_proto_2000u: | ||
680 | req = p9_client_rpc(c, P9_TVERSION, "ds", | ||
681 | c->msize, "9P2000.u"); | ||
682 | break; | ||
683 | case p9_proto_legacy: | ||
684 | req = p9_client_rpc(c, P9_TVERSION, "ds", | ||
685 | c->msize, "9P2000"); | ||
686 | break; | ||
687 | default: | ||
688 | return -EINVAL; | ||
689 | break; | ||
690 | } | ||
691 | |||
634 | if (IS_ERR(req)) | 692 | if (IS_ERR(req)) |
635 | return PTR_ERR(req); | 693 | return PTR_ERR(req); |
636 | 694 | ||
637 | err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version); | 695 | err = p9pdu_readf(req->rc, c->proto_version, "ds", &msize, &version); |
638 | if (err) { | 696 | if (err) { |
639 | P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); | 697 | P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err); |
640 | p9pdu_dump(1, req->rc); | 698 | p9pdu_dump(1, req->rc); |
@@ -642,10 +700,12 @@ int p9_client_version(struct p9_client *c) | |||
642 | } | 700 | } |
643 | 701 | ||
644 | P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); | 702 | P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version); |
645 | if (!memcmp(version, "9P2000.u", 8)) | 703 | if (!strncmp(version, "9P2000.L", 8)) |
646 | c->dotu = 1; | 704 | c->proto_version = p9_proto_2000L; |
647 | else if (!memcmp(version, "9P2000", 6)) | 705 | else if (!strncmp(version, "9P2000.u", 8)) |
648 | c->dotu = 0; | 706 | c->proto_version = p9_proto_2000u; |
707 | else if (!strncmp(version, "9P2000", 6)) | ||
708 | c->proto_version = p9_proto_legacy; | ||
649 | else { | 709 | else { |
650 | err = -EREMOTEIO; | 710 | err = -EREMOTEIO; |
651 | goto error; | 711 | goto error; |
@@ -700,8 +760,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options) | |||
700 | goto put_trans; | 760 | goto put_trans; |
701 | } | 761 | } |
702 | 762 | ||
703 | P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n", | 763 | P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n", |
704 | clnt, clnt->trans_mod, clnt->msize, clnt->dotu); | 764 | clnt, clnt->trans_mod, clnt->msize, clnt->proto_version); |
705 | 765 | ||
706 | err = clnt->trans_mod->create(clnt, dev_name, options); | 766 | err = clnt->trans_mod->create(clnt, dev_name, options); |
707 | if (err) | 767 | if (err) |
@@ -784,7 +844,7 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | |||
784 | goto error; | 844 | goto error; |
785 | } | 845 | } |
786 | 846 | ||
787 | err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid); | 847 | err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); |
788 | if (err) { | 848 | if (err) { |
789 | p9pdu_dump(1, req->rc); | 849 | p9pdu_dump(1, req->rc); |
790 | p9_free_req(clnt, req); | 850 | p9_free_req(clnt, req); |
@@ -833,7 +893,7 @@ p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname) | |||
833 | goto error; | 893 | goto error; |
834 | } | 894 | } |
835 | 895 | ||
836 | err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid); | 896 | err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); |
837 | if (err) { | 897 | if (err) { |
838 | p9pdu_dump(1, req->rc); | 898 | p9pdu_dump(1, req->rc); |
839 | p9_free_req(clnt, req); | 899 | p9_free_req(clnt, req); |
@@ -891,7 +951,7 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
891 | goto error; | 951 | goto error; |
892 | } | 952 | } |
893 | 953 | ||
894 | err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids); | 954 | err = p9pdu_readf(req->rc, clnt->proto_version, "R", &nwqids, &wqids); |
895 | if (err) { | 955 | if (err) { |
896 | p9pdu_dump(1, req->rc); | 956 | p9pdu_dump(1, req->rc); |
897 | p9_free_req(clnt, req); | 957 | p9_free_req(clnt, req); |
@@ -952,7 +1012,7 @@ int p9_client_open(struct p9_fid *fid, int mode) | |||
952 | goto error; | 1012 | goto error; |
953 | } | 1013 | } |
954 | 1014 | ||
955 | err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit); | 1015 | err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); |
956 | if (err) { | 1016 | if (err) { |
957 | p9pdu_dump(1, req->rc); | 1017 | p9pdu_dump(1, req->rc); |
958 | goto free_and_error; | 1018 | goto free_and_error; |
@@ -997,7 +1057,7 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | |||
997 | goto error; | 1057 | goto error; |
998 | } | 1058 | } |
999 | 1059 | ||
1000 | err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit); | 1060 | err = p9pdu_readf(req->rc, clnt->proto_version, "Qd", &qid, &iounit); |
1001 | if (err) { | 1061 | if (err) { |
1002 | p9pdu_dump(1, req->rc); | 1062 | p9pdu_dump(1, req->rc); |
1003 | goto free_and_error; | 1063 | goto free_and_error; |
@@ -1098,7 +1158,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset, | |||
1098 | goto error; | 1158 | goto error; |
1099 | } | 1159 | } |
1100 | 1160 | ||
1101 | err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr); | 1161 | err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr); |
1102 | if (err) { | 1162 | if (err) { |
1103 | p9pdu_dump(1, req->rc); | 1163 | p9pdu_dump(1, req->rc); |
1104 | goto free_and_error; | 1164 | goto free_and_error; |
@@ -1159,7 +1219,7 @@ p9_client_write(struct p9_fid *fid, char *data, const char __user *udata, | |||
1159 | goto error; | 1219 | goto error; |
1160 | } | 1220 | } |
1161 | 1221 | ||
1162 | err = p9pdu_readf(req->rc, clnt->dotu, "d", &count); | 1222 | err = p9pdu_readf(req->rc, clnt->proto_version, "d", &count); |
1163 | if (err) { | 1223 | if (err) { |
1164 | p9pdu_dump(1, req->rc); | 1224 | p9pdu_dump(1, req->rc); |
1165 | goto free_and_error; | 1225 | goto free_and_error; |
@@ -1199,7 +1259,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
1199 | goto error; | 1259 | goto error; |
1200 | } | 1260 | } |
1201 | 1261 | ||
1202 | err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret); | 1262 | err = p9pdu_readf(req->rc, clnt->proto_version, "wS", &ignored, ret); |
1203 | if (err) { | 1263 | if (err) { |
1204 | p9pdu_dump(1, req->rc); | 1264 | p9pdu_dump(1, req->rc); |
1205 | p9_free_req(clnt, req); | 1265 | p9_free_req(clnt, req); |
@@ -1226,7 +1286,7 @@ error: | |||
1226 | } | 1286 | } |
1227 | EXPORT_SYMBOL(p9_client_stat); | 1287 | EXPORT_SYMBOL(p9_client_stat); |
1228 | 1288 | ||
1229 | static int p9_client_statsize(struct p9_wstat *wst, int optional) | 1289 | static int p9_client_statsize(struct p9_wstat *wst, int proto_version) |
1230 | { | 1290 | { |
1231 | int ret; | 1291 | int ret; |
1232 | 1292 | ||
@@ -1245,7 +1305,7 @@ static int p9_client_statsize(struct p9_wstat *wst, int optional) | |||
1245 | if (wst->muid) | 1305 | if (wst->muid) |
1246 | ret += strlen(wst->muid); | 1306 | ret += strlen(wst->muid); |
1247 | 1307 | ||
1248 | if (optional) { | 1308 | if (proto_version == p9_proto_2000u) { |
1249 | ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */ | 1309 | ret += 2+4+4+4; /* extension[s] n_uid[4] n_gid[4] n_muid[4] */ |
1250 | if (wst->extension) | 1310 | if (wst->extension) |
1251 | ret += strlen(wst->extension); | 1311 | ret += strlen(wst->extension); |
@@ -1262,7 +1322,7 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | |||
1262 | 1322 | ||
1263 | err = 0; | 1323 | err = 0; |
1264 | clnt = fid->clnt; | 1324 | clnt = fid->clnt; |
1265 | wst->size = p9_client_statsize(wst, clnt->dotu); | 1325 | wst->size = p9_client_statsize(wst, clnt->proto_version); |
1266 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid); | 1326 | P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid); |
1267 | P9_DPRINTK(P9_DEBUG_9P, | 1327 | P9_DPRINTK(P9_DEBUG_9P, |
1268 | " sz=%x type=%x dev=%x qid=%x.%llx.%x\n" | 1328 | " sz=%x type=%x dev=%x qid=%x.%llx.%x\n" |
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index fc70147c771e..94f5a8f65e9c 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -52,7 +52,7 @@ | |||
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | static int | 54 | static int |
55 | p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...); | 55 | p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); |
56 | 56 | ||
57 | #ifdef CONFIG_NET_9P_DEBUG | 57 | #ifdef CONFIG_NET_9P_DEBUG |
58 | void | 58 | void |
@@ -144,7 +144,8 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size) | |||
144 | */ | 144 | */ |
145 | 145 | ||
146 | static int | 146 | static int |
147 | p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | 147 | p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, |
148 | va_list ap) | ||
148 | { | 149 | { |
149 | const char *ptr; | 150 | const char *ptr; |
150 | int errcode = 0; | 151 | int errcode = 0; |
@@ -194,7 +195,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
194 | int16_t len; | 195 | int16_t len; |
195 | int size; | 196 | int size; |
196 | 197 | ||
197 | errcode = p9pdu_readf(pdu, optional, "w", &len); | 198 | errcode = p9pdu_readf(pdu, proto_version, |
199 | "w", &len); | ||
198 | if (errcode) | 200 | if (errcode) |
199 | break; | 201 | break; |
200 | 202 | ||
@@ -217,7 +219,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
217 | struct p9_qid *qid = | 219 | struct p9_qid *qid = |
218 | va_arg(ap, struct p9_qid *); | 220 | va_arg(ap, struct p9_qid *); |
219 | 221 | ||
220 | errcode = p9pdu_readf(pdu, optional, "bdq", | 222 | errcode = p9pdu_readf(pdu, proto_version, "bdq", |
221 | &qid->type, &qid->version, | 223 | &qid->type, &qid->version, |
222 | &qid->path); | 224 | &qid->path); |
223 | } | 225 | } |
@@ -230,7 +232,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
230 | stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = | 232 | stbuf->n_uid = stbuf->n_gid = stbuf->n_muid = |
231 | -1; | 233 | -1; |
232 | errcode = | 234 | errcode = |
233 | p9pdu_readf(pdu, optional, | 235 | p9pdu_readf(pdu, proto_version, |
234 | "wwdQdddqssss?sddd", | 236 | "wwdQdddqssss?sddd", |
235 | &stbuf->size, &stbuf->type, | 237 | &stbuf->size, &stbuf->type, |
236 | &stbuf->dev, &stbuf->qid, | 238 | &stbuf->dev, &stbuf->qid, |
@@ -250,7 +252,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
250 | void **data = va_arg(ap, void **); | 252 | void **data = va_arg(ap, void **); |
251 | 253 | ||
252 | errcode = | 254 | errcode = |
253 | p9pdu_readf(pdu, optional, "d", count); | 255 | p9pdu_readf(pdu, proto_version, "d", count); |
254 | if (!errcode) { | 256 | if (!errcode) { |
255 | *count = | 257 | *count = |
256 | MIN(*count, | 258 | MIN(*count, |
@@ -263,8 +265,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
263 | int16_t *nwname = va_arg(ap, int16_t *); | 265 | int16_t *nwname = va_arg(ap, int16_t *); |
264 | char ***wnames = va_arg(ap, char ***); | 266 | char ***wnames = va_arg(ap, char ***); |
265 | 267 | ||
266 | errcode = | 268 | errcode = p9pdu_readf(pdu, proto_version, |
267 | p9pdu_readf(pdu, optional, "w", nwname); | 269 | "w", nwname); |
268 | if (!errcode) { | 270 | if (!errcode) { |
269 | *wnames = | 271 | *wnames = |
270 | kmalloc(sizeof(char *) * *nwname, | 272 | kmalloc(sizeof(char *) * *nwname, |
@@ -278,7 +280,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
278 | 280 | ||
279 | for (i = 0; i < *nwname; i++) { | 281 | for (i = 0; i < *nwname; i++) { |
280 | errcode = | 282 | errcode = |
281 | p9pdu_readf(pdu, optional, | 283 | p9pdu_readf(pdu, |
284 | proto_version, | ||
282 | "s", | 285 | "s", |
283 | &(*wnames)[i]); | 286 | &(*wnames)[i]); |
284 | if (errcode) | 287 | if (errcode) |
@@ -306,7 +309,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
306 | *wqids = NULL; | 309 | *wqids = NULL; |
307 | 310 | ||
308 | errcode = | 311 | errcode = |
309 | p9pdu_readf(pdu, optional, "w", nwqid); | 312 | p9pdu_readf(pdu, proto_version, "w", nwqid); |
310 | if (!errcode) { | 313 | if (!errcode) { |
311 | *wqids = | 314 | *wqids = |
312 | kmalloc(*nwqid * | 315 | kmalloc(*nwqid * |
@@ -321,7 +324,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
321 | 324 | ||
322 | for (i = 0; i < *nwqid; i++) { | 325 | for (i = 0; i < *nwqid; i++) { |
323 | errcode = | 326 | errcode = |
324 | p9pdu_readf(pdu, optional, | 327 | p9pdu_readf(pdu, |
328 | proto_version, | ||
325 | "Q", | 329 | "Q", |
326 | &(*wqids)[i]); | 330 | &(*wqids)[i]); |
327 | if (errcode) | 331 | if (errcode) |
@@ -336,7 +340,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
336 | } | 340 | } |
337 | break; | 341 | break; |
338 | case '?': | 342 | case '?': |
339 | if (!optional) | 343 | if (proto_version != p9_proto_2000u) |
340 | return 0; | 344 | return 0; |
341 | break; | 345 | break; |
342 | default: | 346 | default: |
@@ -352,7 +356,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
352 | } | 356 | } |
353 | 357 | ||
354 | int | 358 | int |
355 | p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | 359 | p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, |
360 | va_list ap) | ||
356 | { | 361 | { |
357 | const char *ptr; | 362 | const char *ptr; |
358 | int errcode = 0; | 363 | int errcode = 0; |
@@ -389,7 +394,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
389 | if (sptr) | 394 | if (sptr) |
390 | len = MIN(strlen(sptr), USHORT_MAX); | 395 | len = MIN(strlen(sptr), USHORT_MAX); |
391 | 396 | ||
392 | errcode = p9pdu_writef(pdu, optional, "w", len); | 397 | errcode = p9pdu_writef(pdu, proto_version, |
398 | "w", len); | ||
393 | if (!errcode && pdu_write(pdu, sptr, len)) | 399 | if (!errcode && pdu_write(pdu, sptr, len)) |
394 | errcode = -EFAULT; | 400 | errcode = -EFAULT; |
395 | } | 401 | } |
@@ -398,7 +404,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
398 | const struct p9_qid *qid = | 404 | const struct p9_qid *qid = |
399 | va_arg(ap, const struct p9_qid *); | 405 | va_arg(ap, const struct p9_qid *); |
400 | errcode = | 406 | errcode = |
401 | p9pdu_writef(pdu, optional, "bdq", | 407 | p9pdu_writef(pdu, proto_version, "bdq", |
402 | qid->type, qid->version, | 408 | qid->type, qid->version, |
403 | qid->path); | 409 | qid->path); |
404 | } break; | 410 | } break; |
@@ -406,7 +412,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
406 | const struct p9_wstat *stbuf = | 412 | const struct p9_wstat *stbuf = |
407 | va_arg(ap, const struct p9_wstat *); | 413 | va_arg(ap, const struct p9_wstat *); |
408 | errcode = | 414 | errcode = |
409 | p9pdu_writef(pdu, optional, | 415 | p9pdu_writef(pdu, proto_version, |
410 | "wwdQdddqssss?sddd", | 416 | "wwdQdddqssss?sddd", |
411 | stbuf->size, stbuf->type, | 417 | stbuf->size, stbuf->type, |
412 | stbuf->dev, &stbuf->qid, | 418 | stbuf->dev, &stbuf->qid, |
@@ -421,8 +427,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
421 | int32_t count = va_arg(ap, int32_t); | 427 | int32_t count = va_arg(ap, int32_t); |
422 | const void *data = va_arg(ap, const void *); | 428 | const void *data = va_arg(ap, const void *); |
423 | 429 | ||
424 | errcode = | 430 | errcode = p9pdu_writef(pdu, proto_version, "d", |
425 | p9pdu_writef(pdu, optional, "d", count); | 431 | count); |
426 | if (!errcode && pdu_write(pdu, data, count)) | 432 | if (!errcode && pdu_write(pdu, data, count)) |
427 | errcode = -EFAULT; | 433 | errcode = -EFAULT; |
428 | } | 434 | } |
@@ -431,8 +437,8 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
431 | int32_t count = va_arg(ap, int32_t); | 437 | int32_t count = va_arg(ap, int32_t); |
432 | const char __user *udata = | 438 | const char __user *udata = |
433 | va_arg(ap, const void __user *); | 439 | va_arg(ap, const void __user *); |
434 | errcode = | 440 | errcode = p9pdu_writef(pdu, proto_version, "d", |
435 | p9pdu_writef(pdu, optional, "d", count); | 441 | count); |
436 | if (!errcode && pdu_write_u(pdu, udata, count)) | 442 | if (!errcode && pdu_write_u(pdu, udata, count)) |
437 | errcode = -EFAULT; | 443 | errcode = -EFAULT; |
438 | } | 444 | } |
@@ -441,14 +447,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
441 | int16_t nwname = va_arg(ap, int); | 447 | int16_t nwname = va_arg(ap, int); |
442 | const char **wnames = va_arg(ap, const char **); | 448 | const char **wnames = va_arg(ap, const char **); |
443 | 449 | ||
444 | errcode = | 450 | errcode = p9pdu_writef(pdu, proto_version, "w", |
445 | p9pdu_writef(pdu, optional, "w", nwname); | 451 | nwname); |
446 | if (!errcode) { | 452 | if (!errcode) { |
447 | int i; | 453 | int i; |
448 | 454 | ||
449 | for (i = 0; i < nwname; i++) { | 455 | for (i = 0; i < nwname; i++) { |
450 | errcode = | 456 | errcode = |
451 | p9pdu_writef(pdu, optional, | 457 | p9pdu_writef(pdu, |
458 | proto_version, | ||
452 | "s", | 459 | "s", |
453 | wnames[i]); | 460 | wnames[i]); |
454 | if (errcode) | 461 | if (errcode) |
@@ -462,14 +469,15 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
462 | struct p9_qid *wqids = | 469 | struct p9_qid *wqids = |
463 | va_arg(ap, struct p9_qid *); | 470 | va_arg(ap, struct p9_qid *); |
464 | 471 | ||
465 | errcode = | 472 | errcode = p9pdu_writef(pdu, proto_version, "w", |
466 | p9pdu_writef(pdu, optional, "w", nwqid); | 473 | nwqid); |
467 | if (!errcode) { | 474 | if (!errcode) { |
468 | int i; | 475 | int i; |
469 | 476 | ||
470 | for (i = 0; i < nwqid; i++) { | 477 | for (i = 0; i < nwqid; i++) { |
471 | errcode = | 478 | errcode = |
472 | p9pdu_writef(pdu, optional, | 479 | p9pdu_writef(pdu, |
480 | proto_version, | ||
473 | "Q", | 481 | "Q", |
474 | &wqids[i]); | 482 | &wqids[i]); |
475 | if (errcode) | 483 | if (errcode) |
@@ -479,7 +487,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
479 | } | 487 | } |
480 | break; | 488 | break; |
481 | case '?': | 489 | case '?': |
482 | if (!optional) | 490 | if (proto_version != p9_proto_2000u) |
483 | return 0; | 491 | return 0; |
484 | break; | 492 | break; |
485 | default: | 493 | default: |
@@ -494,32 +502,32 @@ p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap) | |||
494 | return errcode; | 502 | return errcode; |
495 | } | 503 | } |
496 | 504 | ||
497 | int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...) | 505 | int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...) |
498 | { | 506 | { |
499 | va_list ap; | 507 | va_list ap; |
500 | int ret; | 508 | int ret; |
501 | 509 | ||
502 | va_start(ap, fmt); | 510 | va_start(ap, fmt); |
503 | ret = p9pdu_vreadf(pdu, optional, fmt, ap); | 511 | ret = p9pdu_vreadf(pdu, proto_version, fmt, ap); |
504 | va_end(ap); | 512 | va_end(ap); |
505 | 513 | ||
506 | return ret; | 514 | return ret; |
507 | } | 515 | } |
508 | 516 | ||
509 | static int | 517 | static int |
510 | p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...) | 518 | p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...) |
511 | { | 519 | { |
512 | va_list ap; | 520 | va_list ap; |
513 | int ret; | 521 | int ret; |
514 | 522 | ||
515 | va_start(ap, fmt); | 523 | va_start(ap, fmt); |
516 | ret = p9pdu_vwritef(pdu, optional, fmt, ap); | 524 | ret = p9pdu_vwritef(pdu, proto_version, fmt, ap); |
517 | va_end(ap); | 525 | va_end(ap); |
518 | 526 | ||
519 | return ret; | 527 | return ret; |
520 | } | 528 | } |
521 | 529 | ||
522 | int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu) | 530 | int p9stat_read(char *buf, int len, struct p9_wstat *st, int proto_version) |
523 | { | 531 | { |
524 | struct p9_fcall fake_pdu; | 532 | struct p9_fcall fake_pdu; |
525 | int ret; | 533 | int ret; |
@@ -529,7 +537,7 @@ int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu) | |||
529 | fake_pdu.sdata = buf; | 537 | fake_pdu.sdata = buf; |
530 | fake_pdu.offset = 0; | 538 | fake_pdu.offset = 0; |
531 | 539 | ||
532 | ret = p9pdu_readf(&fake_pdu, dotu, "S", st); | 540 | ret = p9pdu_readf(&fake_pdu, proto_version, "S", st); |
533 | if (ret) { | 541 | if (ret) { |
534 | P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); | 542 | P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret); |
535 | p9pdu_dump(1, &fake_pdu); | 543 | p9pdu_dump(1, &fake_pdu); |
diff --git a/net/9p/protocol.h b/net/9p/protocol.h index ccde462e7ac5..2431c0f38d56 100644 --- a/net/9p/protocol.h +++ b/net/9p/protocol.h | |||
@@ -25,9 +25,9 @@ | |||
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | 27 | ||
28 | int | 28 | int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, |
29 | p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap); | 29 | va_list ap); |
30 | int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...); | 30 | int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...); |
31 | int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type); | 31 | int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type); |
32 | int p9pdu_finalize(struct p9_fcall *pdu); | 32 | int p9pdu_finalize(struct p9_fcall *pdu); |
33 | void p9pdu_dump(int, struct p9_fcall *); | 33 | void p9pdu_dump(int, struct p9_fcall *); |
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index cb50f4ae5eef..afde1a89fbb3 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
@@ -49,8 +49,6 @@ | |||
49 | 49 | ||
50 | /* a single mutex to manage channel initialization and attachment */ | 50 | /* a single mutex to manage channel initialization and attachment */ |
51 | static DEFINE_MUTEX(virtio_9p_lock); | 51 | static DEFINE_MUTEX(virtio_9p_lock); |
52 | /* global which tracks highest initialized channel */ | ||
53 | static int chan_index; | ||
54 | 52 | ||
55 | /** | 53 | /** |
56 | * struct virtio_chan - per-instance transport information | 54 | * struct virtio_chan - per-instance transport information |
@@ -68,8 +66,7 @@ static int chan_index; | |||
68 | * | 66 | * |
69 | */ | 67 | */ |
70 | 68 | ||
71 | static struct virtio_chan { | 69 | struct virtio_chan { |
72 | bool initialized; | ||
73 | bool inuse; | 70 | bool inuse; |
74 | 71 | ||
75 | spinlock_t lock; | 72 | spinlock_t lock; |
@@ -80,7 +77,17 @@ static struct virtio_chan { | |||
80 | 77 | ||
81 | /* Scatterlist: can be too big for stack. */ | 78 | /* Scatterlist: can be too big for stack. */ |
82 | struct scatterlist sg[VIRTQUEUE_NUM]; | 79 | struct scatterlist sg[VIRTQUEUE_NUM]; |
83 | } channels[MAX_9P_CHAN]; | 80 | |
81 | int tag_len; | ||
82 | /* | ||
83 | * tag name to identify a mount Non-null terminated | ||
84 | */ | ||
85 | char *tag; | ||
86 | |||
87 | struct list_head chan_list; | ||
88 | }; | ||
89 | |||
90 | static struct list_head virtio_chan_list; | ||
84 | 91 | ||
85 | /* How many bytes left in this page. */ | 92 | /* How many bytes left in this page. */ |
86 | static unsigned int rest_of_page(void *data) | 93 | static unsigned int rest_of_page(void *data) |
@@ -213,30 +220,38 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) | |||
213 | return 0; | 220 | return 0; |
214 | } | 221 | } |
215 | 222 | ||
223 | static ssize_t p9_mount_tag_show(struct device *dev, | ||
224 | struct device_attribute *attr, char *buf) | ||
225 | { | ||
226 | struct virtio_chan *chan; | ||
227 | struct virtio_device *vdev; | ||
228 | |||
229 | vdev = dev_to_virtio(dev); | ||
230 | chan = vdev->priv; | ||
231 | |||
232 | return snprintf(buf, chan->tag_len + 1, "%s", chan->tag); | ||
233 | } | ||
234 | |||
235 | static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL); | ||
236 | |||
216 | /** | 237 | /** |
217 | * p9_virtio_probe - probe for existence of 9P virtio channels | 238 | * p9_virtio_probe - probe for existence of 9P virtio channels |
218 | * @vdev: virtio device to probe | 239 | * @vdev: virtio device to probe |
219 | * | 240 | * |
220 | * This probes for existing virtio channels. At present only | 241 | * This probes for existing virtio channels. |
221 | * a single channel is in use, so in the future more work may need | ||
222 | * to be done here. | ||
223 | * | 242 | * |
224 | */ | 243 | */ |
225 | 244 | ||
226 | static int p9_virtio_probe(struct virtio_device *vdev) | 245 | static int p9_virtio_probe(struct virtio_device *vdev) |
227 | { | 246 | { |
247 | __u16 tag_len; | ||
248 | char *tag; | ||
228 | int err; | 249 | int err; |
229 | struct virtio_chan *chan; | 250 | struct virtio_chan *chan; |
230 | int index; | ||
231 | 251 | ||
232 | mutex_lock(&virtio_9p_lock); | 252 | chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL); |
233 | index = chan_index++; | 253 | if (!chan) { |
234 | chan = &channels[index]; | 254 | printk(KERN_ERR "9p: Failed to allocate virtio 9P channel\n"); |
235 | mutex_unlock(&virtio_9p_lock); | ||
236 | |||
237 | if (chan_index > MAX_9P_CHAN) { | ||
238 | printk(KERN_ERR "9p: virtio: Maximum channels exceeded\n"); | ||
239 | BUG(); | ||
240 | err = -ENOMEM; | 255 | err = -ENOMEM; |
241 | goto fail; | 256 | goto fail; |
242 | } | 257 | } |
@@ -255,15 +270,37 @@ static int p9_virtio_probe(struct virtio_device *vdev) | |||
255 | sg_init_table(chan->sg, VIRTQUEUE_NUM); | 270 | sg_init_table(chan->sg, VIRTQUEUE_NUM); |
256 | 271 | ||
257 | chan->inuse = false; | 272 | chan->inuse = false; |
258 | chan->initialized = true; | 273 | if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) { |
274 | vdev->config->get(vdev, | ||
275 | offsetof(struct virtio_9p_config, tag_len), | ||
276 | &tag_len, sizeof(tag_len)); | ||
277 | } else { | ||
278 | err = -EINVAL; | ||
279 | goto out_free_vq; | ||
280 | } | ||
281 | tag = kmalloc(tag_len, GFP_KERNEL); | ||
282 | if (!tag) { | ||
283 | err = -ENOMEM; | ||
284 | goto out_free_vq; | ||
285 | } | ||
286 | vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag), | ||
287 | tag, tag_len); | ||
288 | chan->tag = tag; | ||
289 | chan->tag_len = tag_len; | ||
290 | err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | ||
291 | if (err) { | ||
292 | kfree(tag); | ||
293 | goto out_free_vq; | ||
294 | } | ||
295 | mutex_lock(&virtio_9p_lock); | ||
296 | list_add_tail(&chan->chan_list, &virtio_chan_list); | ||
297 | mutex_unlock(&virtio_9p_lock); | ||
259 | return 0; | 298 | return 0; |
260 | 299 | ||
261 | out_free_vq: | 300 | out_free_vq: |
262 | vdev->config->del_vqs(vdev); | 301 | vdev->config->del_vqs(vdev); |
302 | kfree(chan); | ||
263 | fail: | 303 | fail: |
264 | mutex_lock(&virtio_9p_lock); | ||
265 | chan_index--; | ||
266 | mutex_unlock(&virtio_9p_lock); | ||
267 | return err; | 304 | return err; |
268 | } | 305 | } |
269 | 306 | ||
@@ -280,35 +317,31 @@ fail: | |||
280 | * We use a simple reference count mechanism to ensure that only a single | 317 | * We use a simple reference count mechanism to ensure that only a single |
281 | * mount has a channel open at a time. | 318 | * mount has a channel open at a time. |
282 | * | 319 | * |
283 | * Bugs: doesn't allow identification of a specific channel | ||
284 | * to allocate, channels are allocated sequentially. This was | ||
285 | * a pragmatic decision to get things rolling, but ideally some | ||
286 | * way of identifying the channel to attach to would be nice | ||
287 | * if we are going to support multiple channels. | ||
288 | * | ||
289 | */ | 320 | */ |
290 | 321 | ||
291 | static int | 322 | static int |
292 | p9_virtio_create(struct p9_client *client, const char *devname, char *args) | 323 | p9_virtio_create(struct p9_client *client, const char *devname, char *args) |
293 | { | 324 | { |
294 | struct virtio_chan *chan = channels; | 325 | struct virtio_chan *chan; |
295 | int index = 0; | 326 | int ret = -ENOENT; |
327 | int found = 0; | ||
296 | 328 | ||
297 | mutex_lock(&virtio_9p_lock); | 329 | mutex_lock(&virtio_9p_lock); |
298 | while (index < MAX_9P_CHAN) { | 330 | list_for_each_entry(chan, &virtio_chan_list, chan_list) { |
299 | if (chan->initialized && !chan->inuse) { | 331 | if (!strncmp(devname, chan->tag, chan->tag_len)) { |
300 | chan->inuse = true; | 332 | if (!chan->inuse) { |
301 | break; | 333 | chan->inuse = true; |
302 | } else { | 334 | found = 1; |
303 | index++; | 335 | break; |
304 | chan = &channels[index]; | 336 | } |
337 | ret = -EBUSY; | ||
305 | } | 338 | } |
306 | } | 339 | } |
307 | mutex_unlock(&virtio_9p_lock); | 340 | mutex_unlock(&virtio_9p_lock); |
308 | 341 | ||
309 | if (index >= MAX_9P_CHAN) { | 342 | if (!found) { |
310 | printk(KERN_ERR "9p: no channels available\n"); | 343 | printk(KERN_ERR "9p: no channels available\n"); |
311 | return -ENODEV; | 344 | return ret; |
312 | } | 345 | } |
313 | 346 | ||
314 | client->trans = (void *)chan; | 347 | client->trans = (void *)chan; |
@@ -329,11 +362,15 @@ static void p9_virtio_remove(struct virtio_device *vdev) | |||
329 | struct virtio_chan *chan = vdev->priv; | 362 | struct virtio_chan *chan = vdev->priv; |
330 | 363 | ||
331 | BUG_ON(chan->inuse); | 364 | BUG_ON(chan->inuse); |
365 | vdev->config->del_vqs(vdev); | ||
366 | |||
367 | mutex_lock(&virtio_9p_lock); | ||
368 | list_del(&chan->chan_list); | ||
369 | mutex_unlock(&virtio_9p_lock); | ||
370 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | ||
371 | kfree(chan->tag); | ||
372 | kfree(chan); | ||
332 | 373 | ||
333 | if (chan->initialized) { | ||
334 | vdev->config->del_vqs(vdev); | ||
335 | chan->initialized = false; | ||
336 | } | ||
337 | } | 374 | } |
338 | 375 | ||
339 | static struct virtio_device_id id_table[] = { | 376 | static struct virtio_device_id id_table[] = { |
@@ -341,13 +378,19 @@ static struct virtio_device_id id_table[] = { | |||
341 | { 0 }, | 378 | { 0 }, |
342 | }; | 379 | }; |
343 | 380 | ||
381 | static unsigned int features[] = { | ||
382 | VIRTIO_9P_MOUNT_TAG, | ||
383 | }; | ||
384 | |||
344 | /* The standard "struct lguest_driver": */ | 385 | /* The standard "struct lguest_driver": */ |
345 | static struct virtio_driver p9_virtio_drv = { | 386 | static struct virtio_driver p9_virtio_drv = { |
346 | .driver.name = KBUILD_MODNAME, | 387 | .feature_table = features, |
347 | .driver.owner = THIS_MODULE, | 388 | .feature_table_size = ARRAY_SIZE(features), |
348 | .id_table = id_table, | 389 | .driver.name = KBUILD_MODNAME, |
349 | .probe = p9_virtio_probe, | 390 | .driver.owner = THIS_MODULE, |
350 | .remove = p9_virtio_remove, | 391 | .id_table = id_table, |
392 | .probe = p9_virtio_probe, | ||
393 | .remove = p9_virtio_remove, | ||
351 | }; | 394 | }; |
352 | 395 | ||
353 | static struct p9_trans_module p9_virtio_trans = { | 396 | static struct p9_trans_module p9_virtio_trans = { |
@@ -364,10 +407,7 @@ static struct p9_trans_module p9_virtio_trans = { | |||
364 | /* The standard init function */ | 407 | /* The standard init function */ |
365 | static int __init p9_virtio_init(void) | 408 | static int __init p9_virtio_init(void) |
366 | { | 409 | { |
367 | int count; | 410 | INIT_LIST_HEAD(&virtio_chan_list); |
368 | |||
369 | for (count = 0; count < MAX_9P_CHAN; count++) | ||
370 | channels[count].initialized = false; | ||
371 | 411 | ||
372 | v9fs_register_trans(&p9_virtio_trans); | 412 | v9fs_register_trans(&p9_virtio_trans); |
373 | return register_virtio_driver(&p9_virtio_drv); | 413 | return register_virtio_driver(&p9_virtio_drv); |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index cafb55b0cea5..05fd125f74fe 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -8,8 +8,7 @@ | |||
8 | #include <net/bluetooth/bluetooth.h> | 8 | #include <net/bluetooth/bluetooth.h> |
9 | #include <net/bluetooth/hci_core.h> | 9 | #include <net/bluetooth/hci_core.h> |
10 | 10 | ||
11 | struct class *bt_class = NULL; | 11 | static struct class *bt_class; |
12 | EXPORT_SYMBOL_GPL(bt_class); | ||
13 | 12 | ||
14 | struct dentry *bt_debugfs = NULL; | 13 | struct dentry *bt_debugfs = NULL; |
15 | EXPORT_SYMBOL_GPL(bt_debugfs); | 14 | EXPORT_SYMBOL_GPL(bt_debugfs); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 400efa26ddba..7794a2e2adce 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/debugfs.h> | ||
44 | #include <linux/seq_file.h> | ||
43 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
44 | #include <linux/crc16.h> | 46 | #include <linux/crc16.h> |
45 | #include <net/sock.h> | 47 | #include <net/sock.h> |
@@ -2830,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2830 | int len = cmd->len - sizeof(*rsp); | 2832 | int len = cmd->len - sizeof(*rsp); |
2831 | char req[64]; | 2833 | char req[64]; |
2832 | 2834 | ||
2835 | if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { | ||
2836 | l2cap_send_disconn_req(conn, sk); | ||
2837 | goto done; | ||
2838 | } | ||
2839 | |||
2833 | /* throw out any old stored conf requests */ | 2840 | /* throw out any old stored conf requests */ |
2834 | result = L2CAP_CONF_SUCCESS; | 2841 | result = L2CAP_CONF_SUCCESS; |
2835 | len = l2cap_parse_conf_rsp(sk, rsp->data, | 2842 | len = l2cap_parse_conf_rsp(sk, rsp->data, |
@@ -3937,29 +3944,42 @@ drop: | |||
3937 | return 0; | 3944 | return 0; |
3938 | } | 3945 | } |
3939 | 3946 | ||
3940 | static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) | 3947 | static int l2cap_debugfs_show(struct seq_file *f, void *p) |
3941 | { | 3948 | { |
3942 | struct sock *sk; | 3949 | struct sock *sk; |
3943 | struct hlist_node *node; | 3950 | struct hlist_node *node; |
3944 | char *str = buf; | ||
3945 | 3951 | ||
3946 | read_lock_bh(&l2cap_sk_list.lock); | 3952 | read_lock_bh(&l2cap_sk_list.lock); |
3947 | 3953 | ||
3948 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 3954 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
3949 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3955 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
3950 | 3956 | ||
3951 | str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", | 3957 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", |
3952 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 3958 | batostr(&bt_sk(sk)->src), |
3953 | sk->sk_state, __le16_to_cpu(pi->psm), pi->scid, | 3959 | batostr(&bt_sk(sk)->dst), |
3954 | pi->dcid, pi->imtu, pi->omtu, pi->sec_level); | 3960 | sk->sk_state, __le16_to_cpu(pi->psm), |
3961 | pi->scid, pi->dcid, | ||
3962 | pi->imtu, pi->omtu, pi->sec_level); | ||
3955 | } | 3963 | } |
3956 | 3964 | ||
3957 | read_unlock_bh(&l2cap_sk_list.lock); | 3965 | read_unlock_bh(&l2cap_sk_list.lock); |
3958 | 3966 | ||
3959 | return str - buf; | 3967 | return 0; |
3960 | } | 3968 | } |
3961 | 3969 | ||
3962 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); | 3970 | static int l2cap_debugfs_open(struct inode *inode, struct file *file) |
3971 | { | ||
3972 | return single_open(file, l2cap_debugfs_show, inode->i_private); | ||
3973 | } | ||
3974 | |||
3975 | static const struct file_operations l2cap_debugfs_fops = { | ||
3976 | .open = l2cap_debugfs_open, | ||
3977 | .read = seq_read, | ||
3978 | .llseek = seq_lseek, | ||
3979 | .release = single_release, | ||
3980 | }; | ||
3981 | |||
3982 | static struct dentry *l2cap_debugfs; | ||
3963 | 3983 | ||
3964 | static const struct proto_ops l2cap_sock_ops = { | 3984 | static const struct proto_ops l2cap_sock_ops = { |
3965 | .family = PF_BLUETOOTH, | 3985 | .family = PF_BLUETOOTH, |
@@ -4019,8 +4039,12 @@ static int __init l2cap_init(void) | |||
4019 | goto error; | 4039 | goto error; |
4020 | } | 4040 | } |
4021 | 4041 | ||
4022 | if (class_create_file(bt_class, &class_attr_l2cap) < 0) | 4042 | if (bt_debugfs) { |
4023 | BT_ERR("Failed to create L2CAP info file"); | 4043 | l2cap_debugfs = debugfs_create_file("l2cap", 0444, |
4044 | bt_debugfs, NULL, &l2cap_debugfs_fops); | ||
4045 | if (!l2cap_debugfs) | ||
4046 | BT_ERR("Failed to create L2CAP debug file"); | ||
4047 | } | ||
4024 | 4048 | ||
4025 | BT_INFO("L2CAP ver %s", VERSION); | 4049 | BT_INFO("L2CAP ver %s", VERSION); |
4026 | BT_INFO("L2CAP socket layer initialized"); | 4050 | BT_INFO("L2CAP socket layer initialized"); |
@@ -4034,7 +4058,7 @@ error: | |||
4034 | 4058 | ||
4035 | static void __exit l2cap_exit(void) | 4059 | static void __exit l2cap_exit(void) |
4036 | { | 4060 | { |
4037 | class_remove_file(bt_class, &class_attr_l2cap); | 4061 | debugfs_remove(l2cap_debugfs); |
4038 | 4062 | ||
4039 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | 4063 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) |
4040 | BT_ERR("L2CAP socket unregistration failed"); | 4064 | BT_ERR("L2CAP socket unregistration failed"); |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 89f4a59eb82b..13f114e8b0f9 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
35 | #include <linux/device.h> | 35 | #include <linux/device.h> |
36 | #include <linux/debugfs.h> | ||
37 | #include <linux/seq_file.h> | ||
36 | #include <linux/net.h> | 38 | #include <linux/net.h> |
37 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
38 | #include <linux/kthread.h> | 40 | #include <linux/kthread.h> |
@@ -2098,11 +2100,10 @@ static struct hci_cb rfcomm_cb = { | |||
2098 | .security_cfm = rfcomm_security_cfm | 2100 | .security_cfm = rfcomm_security_cfm |
2099 | }; | 2101 | }; |
2100 | 2102 | ||
2101 | static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) | 2103 | static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x) |
2102 | { | 2104 | { |
2103 | struct rfcomm_session *s; | 2105 | struct rfcomm_session *s; |
2104 | struct list_head *pp, *p; | 2106 | struct list_head *pp, *p; |
2105 | char *str = buf; | ||
2106 | 2107 | ||
2107 | rfcomm_lock(); | 2108 | rfcomm_lock(); |
2108 | 2109 | ||
@@ -2112,18 +2113,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) | |||
2112 | struct sock *sk = s->sock->sk; | 2113 | struct sock *sk = s->sock->sk; |
2113 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); | 2114 | struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list); |
2114 | 2115 | ||
2115 | str += sprintf(str, "%s %s %ld %d %d %d %d\n", | 2116 | seq_printf(f, "%s %s %ld %d %d %d %d\n", |
2116 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 2117 | batostr(&bt_sk(sk)->src), |
2117 | d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); | 2118 | batostr(&bt_sk(sk)->dst), |
2119 | d->state, d->dlci, d->mtu, | ||
2120 | d->rx_credits, d->tx_credits); | ||
2118 | } | 2121 | } |
2119 | } | 2122 | } |
2120 | 2123 | ||
2121 | rfcomm_unlock(); | 2124 | rfcomm_unlock(); |
2122 | 2125 | ||
2123 | return (str - buf); | 2126 | return 0; |
2124 | } | 2127 | } |
2125 | 2128 | ||
2126 | static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL); | 2129 | static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file) |
2130 | { | ||
2131 | return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private); | ||
2132 | } | ||
2133 | |||
2134 | static const struct file_operations rfcomm_dlc_debugfs_fops = { | ||
2135 | .open = rfcomm_dlc_debugfs_open, | ||
2136 | .read = seq_read, | ||
2137 | .llseek = seq_lseek, | ||
2138 | .release = single_release, | ||
2139 | }; | ||
2140 | |||
2141 | static struct dentry *rfcomm_dlc_debugfs; | ||
2127 | 2142 | ||
2128 | /* ---- Initialization ---- */ | 2143 | /* ---- Initialization ---- */ |
2129 | static int __init rfcomm_init(void) | 2144 | static int __init rfcomm_init(void) |
@@ -2140,8 +2155,12 @@ static int __init rfcomm_init(void) | |||
2140 | goto unregister; | 2155 | goto unregister; |
2141 | } | 2156 | } |
2142 | 2157 | ||
2143 | if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0) | 2158 | if (bt_debugfs) { |
2144 | BT_ERR("Failed to create RFCOMM info file"); | 2159 | rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444, |
2160 | bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops); | ||
2161 | if (!rfcomm_dlc_debugfs) | ||
2162 | BT_ERR("Failed to create RFCOMM debug file"); | ||
2163 | } | ||
2145 | 2164 | ||
2146 | err = rfcomm_init_ttys(); | 2165 | err = rfcomm_init_ttys(); |
2147 | if (err < 0) | 2166 | if (err < 0) |
@@ -2169,7 +2188,7 @@ unregister: | |||
2169 | 2188 | ||
2170 | static void __exit rfcomm_exit(void) | 2189 | static void __exit rfcomm_exit(void) |
2171 | { | 2190 | { |
2172 | class_remove_file(bt_class, &class_attr_rfcomm_dlc); | 2191 | debugfs_remove(rfcomm_dlc_debugfs); |
2173 | 2192 | ||
2174 | hci_unregister_cb(&rfcomm_cb); | 2193 | hci_unregister_cb(&rfcomm_cb); |
2175 | 2194 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 4b5968dda673..7f439765403d 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/debugfs.h> | ||
44 | #include <linux/seq_file.h> | ||
43 | #include <net/sock.h> | 45 | #include <net/sock.h> |
44 | 46 | ||
45 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -1061,26 +1063,38 @@ done: | |||
1061 | return result; | 1063 | return result; |
1062 | } | 1064 | } |
1063 | 1065 | ||
1064 | static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf) | 1066 | static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p) |
1065 | { | 1067 | { |
1066 | struct sock *sk; | 1068 | struct sock *sk; |
1067 | struct hlist_node *node; | 1069 | struct hlist_node *node; |
1068 | char *str = buf; | ||
1069 | 1070 | ||
1070 | read_lock_bh(&rfcomm_sk_list.lock); | 1071 | read_lock_bh(&rfcomm_sk_list.lock); |
1071 | 1072 | ||
1072 | sk_for_each(sk, node, &rfcomm_sk_list.head) { | 1073 | sk_for_each(sk, node, &rfcomm_sk_list.head) { |
1073 | str += sprintf(str, "%s %s %d %d\n", | 1074 | seq_printf(f, "%s %s %d %d\n", |
1074 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 1075 | batostr(&bt_sk(sk)->src), |
1076 | batostr(&bt_sk(sk)->dst), | ||
1075 | sk->sk_state, rfcomm_pi(sk)->channel); | 1077 | sk->sk_state, rfcomm_pi(sk)->channel); |
1076 | } | 1078 | } |
1077 | 1079 | ||
1078 | read_unlock_bh(&rfcomm_sk_list.lock); | 1080 | read_unlock_bh(&rfcomm_sk_list.lock); |
1079 | 1081 | ||
1080 | return (str - buf); | 1082 | return 0; |
1081 | } | 1083 | } |
1082 | 1084 | ||
1083 | static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL); | 1085 | static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file) |
1086 | { | ||
1087 | return single_open(file, rfcomm_sock_debugfs_show, inode->i_private); | ||
1088 | } | ||
1089 | |||
1090 | static const struct file_operations rfcomm_sock_debugfs_fops = { | ||
1091 | .open = rfcomm_sock_debugfs_open, | ||
1092 | .read = seq_read, | ||
1093 | .llseek = seq_lseek, | ||
1094 | .release = single_release, | ||
1095 | }; | ||
1096 | |||
1097 | static struct dentry *rfcomm_sock_debugfs; | ||
1084 | 1098 | ||
1085 | static const struct proto_ops rfcomm_sock_ops = { | 1099 | static const struct proto_ops rfcomm_sock_ops = { |
1086 | .family = PF_BLUETOOTH, | 1100 | .family = PF_BLUETOOTH, |
@@ -1120,8 +1134,12 @@ int __init rfcomm_init_sockets(void) | |||
1120 | if (err < 0) | 1134 | if (err < 0) |
1121 | goto error; | 1135 | goto error; |
1122 | 1136 | ||
1123 | if (class_create_file(bt_class, &class_attr_rfcomm) < 0) | 1137 | if (bt_debugfs) { |
1124 | BT_ERR("Failed to create RFCOMM info file"); | 1138 | rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444, |
1139 | bt_debugfs, NULL, &rfcomm_sock_debugfs_fops); | ||
1140 | if (!rfcomm_sock_debugfs) | ||
1141 | BT_ERR("Failed to create RFCOMM debug file"); | ||
1142 | } | ||
1125 | 1143 | ||
1126 | BT_INFO("RFCOMM socket layer initialized"); | 1144 | BT_INFO("RFCOMM socket layer initialized"); |
1127 | 1145 | ||
@@ -1135,7 +1153,7 @@ error: | |||
1135 | 1153 | ||
1136 | void rfcomm_cleanup_sockets(void) | 1154 | void rfcomm_cleanup_sockets(void) |
1137 | { | 1155 | { |
1138 | class_remove_file(bt_class, &class_attr_rfcomm); | 1156 | debugfs_remove(rfcomm_sock_debugfs); |
1139 | 1157 | ||
1140 | if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) | 1158 | if (bt_sock_unregister(BTPROTO_RFCOMM) < 0) |
1141 | BT_ERR("RFCOMM socket layer unregistration failed"); | 1159 | BT_ERR("RFCOMM socket layer unregistration failed"); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index dd8f6ec57dce..e5b16b76b22e 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/socket.h> | 38 | #include <linux/socket.h> |
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/debugfs.h> | ||
42 | #include <linux/seq_file.h> | ||
41 | #include <linux/list.h> | 43 | #include <linux/list.h> |
42 | #include <net/sock.h> | 44 | #include <net/sock.h> |
43 | 45 | ||
@@ -953,26 +955,36 @@ drop: | |||
953 | return 0; | 955 | return 0; |
954 | } | 956 | } |
955 | 957 | ||
956 | static ssize_t sco_sysfs_show(struct class *dev, char *buf) | 958 | static int sco_debugfs_show(struct seq_file *f, void *p) |
957 | { | 959 | { |
958 | struct sock *sk; | 960 | struct sock *sk; |
959 | struct hlist_node *node; | 961 | struct hlist_node *node; |
960 | char *str = buf; | ||
961 | 962 | ||
962 | read_lock_bh(&sco_sk_list.lock); | 963 | read_lock_bh(&sco_sk_list.lock); |
963 | 964 | ||
964 | sk_for_each(sk, node, &sco_sk_list.head) { | 965 | sk_for_each(sk, node, &sco_sk_list.head) { |
965 | str += sprintf(str, "%s %s %d\n", | 966 | seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), |
966 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 967 | batostr(&bt_sk(sk)->dst), sk->sk_state); |
967 | sk->sk_state); | ||
968 | } | 968 | } |
969 | 969 | ||
970 | read_unlock_bh(&sco_sk_list.lock); | 970 | read_unlock_bh(&sco_sk_list.lock); |
971 | 971 | ||
972 | return (str - buf); | 972 | return 0; |
973 | } | 973 | } |
974 | 974 | ||
975 | static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); | 975 | static int sco_debugfs_open(struct inode *inode, struct file *file) |
976 | { | ||
977 | return single_open(file, sco_debugfs_show, inode->i_private); | ||
978 | } | ||
979 | |||
980 | static const struct file_operations sco_debugfs_fops = { | ||
981 | .open = sco_debugfs_open, | ||
982 | .read = seq_read, | ||
983 | .llseek = seq_lseek, | ||
984 | .release = single_release, | ||
985 | }; | ||
986 | |||
987 | static struct dentry *sco_debugfs; | ||
976 | 988 | ||
977 | static const struct proto_ops sco_sock_ops = { | 989 | static const struct proto_ops sco_sock_ops = { |
978 | .family = PF_BLUETOOTH, | 990 | .family = PF_BLUETOOTH, |
@@ -1030,8 +1042,12 @@ static int __init sco_init(void) | |||
1030 | goto error; | 1042 | goto error; |
1031 | } | 1043 | } |
1032 | 1044 | ||
1033 | if (class_create_file(bt_class, &class_attr_sco) < 0) | 1045 | if (bt_debugfs) { |
1034 | BT_ERR("Failed to create SCO info file"); | 1046 | sco_debugfs = debugfs_create_file("sco", 0444, |
1047 | bt_debugfs, NULL, &sco_debugfs_fops); | ||
1048 | if (!sco_debugfs) | ||
1049 | BT_ERR("Failed to create SCO debug file"); | ||
1050 | } | ||
1035 | 1051 | ||
1036 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | 1052 | BT_INFO("SCO (Voice Link) ver %s", VERSION); |
1037 | BT_INFO("SCO socket layer initialized"); | 1053 | BT_INFO("SCO socket layer initialized"); |
@@ -1045,7 +1061,7 @@ error: | |||
1045 | 1061 | ||
1046 | static void __exit sco_exit(void) | 1062 | static void __exit sco_exit(void) |
1047 | { | 1063 | { |
1048 | class_remove_file(bt_class, &class_attr_sco); | 1064 | debugfs_remove(sco_debugfs); |
1049 | 1065 | ||
1050 | if (bt_sock_unregister(BTPROTO_SCO) < 0) | 1066 | if (bt_sock_unregister(BTPROTO_SCO) < 0) |
1051 | BT_ERR("SCO socket unregistration failed"); | 1067 | BT_ERR("SCO socket unregistration failed"); |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index eb7062d2e9e5..90a9024e5c1e 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -40,7 +40,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
40 | goto out; | 40 | goto out; |
41 | 41 | ||
42 | mdst = br_mdb_get(br, skb); | 42 | mdst = br_mdb_get(br, skb); |
43 | if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) | 43 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) |
44 | br_multicast_deliver(mdst, skb); | 44 | br_multicast_deliver(mdst, skb); |
45 | else | 45 | else |
46 | br_flood_deliver(br, skb); | 46 | br_flood_deliver(br, skb); |
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index d61e6f741125..8dbec83e50ca 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -19,6 +19,11 @@ | |||
19 | #include <linux/netfilter_bridge.h> | 19 | #include <linux/netfilter_bridge.h> |
20 | #include "br_private.h" | 20 | #include "br_private.h" |
21 | 21 | ||
22 | static int deliver_clone(const struct net_bridge_port *prev, | ||
23 | struct sk_buff *skb, | ||
24 | void (*__packet_hook)(const struct net_bridge_port *p, | ||
25 | struct sk_buff *skb)); | ||
26 | |||
22 | /* Don't forward packets to originating port or forwarding diasabled */ | 27 | /* Don't forward packets to originating port or forwarding diasabled */ |
23 | static inline int should_deliver(const struct net_bridge_port *p, | 28 | static inline int should_deliver(const struct net_bridge_port *p, |
24 | const struct sk_buff *skb) | 29 | const struct sk_buff *skb) |
@@ -94,17 +99,22 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) | |||
94 | } | 99 | } |
95 | 100 | ||
96 | /* called with rcu_read_lock */ | 101 | /* called with rcu_read_lock */ |
97 | void br_forward(const struct net_bridge_port *to, struct sk_buff *skb) | 102 | void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0) |
98 | { | 103 | { |
99 | if (should_deliver(to, skb)) { | 104 | if (should_deliver(to, skb)) { |
100 | __br_forward(to, skb); | 105 | if (skb0) |
106 | deliver_clone(to, skb, __br_forward); | ||
107 | else | ||
108 | __br_forward(to, skb); | ||
101 | return; | 109 | return; |
102 | } | 110 | } |
103 | 111 | ||
104 | kfree_skb(skb); | 112 | if (!skb0) |
113 | kfree_skb(skb); | ||
105 | } | 114 | } |
106 | 115 | ||
107 | static int deliver_clone(struct net_bridge_port *prev, struct sk_buff *skb, | 116 | static int deliver_clone(const struct net_bridge_port *prev, |
117 | struct sk_buff *skb, | ||
108 | void (*__packet_hook)(const struct net_bridge_port *p, | 118 | void (*__packet_hook)(const struct net_bridge_port *p, |
109 | struct sk_buff *skb)) | 119 | struct sk_buff *skb)) |
110 | { | 120 | { |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 53b39851d87d..d74d570fc848 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -70,7 +70,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
70 | 70 | ||
71 | if (is_multicast_ether_addr(dest)) { | 71 | if (is_multicast_ether_addr(dest)) { |
72 | mdst = br_mdb_get(br, skb); | 72 | mdst = br_mdb_get(br, skb); |
73 | if (mdst || BR_INPUT_SKB_CB(skb)->mrouters_only) { | 73 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { |
74 | if ((mdst && !hlist_unhashed(&mdst->mglist)) || | 74 | if ((mdst && !hlist_unhashed(&mdst->mglist)) || |
75 | br_multicast_is_router(br)) | 75 | br_multicast_is_router(br)) |
76 | skb2 = skb; | 76 | skb2 = skb; |
@@ -90,7 +90,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
90 | 90 | ||
91 | if (skb) { | 91 | if (skb) { |
92 | if (dst) | 92 | if (dst) |
93 | br_forward(dst->dst, skb); | 93 | br_forward(dst->dst, skb, skb2); |
94 | else | 94 | else |
95 | br_flood_forward(br, skb, skb2); | 95 | br_flood_forward(br, skb, skb2); |
96 | } | 96 | } |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 12ce1eaa4f3e..6980625537ca 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( | |||
49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( | 49 | static struct net_bridge_mdb_entry *br_mdb_ip_get( |
50 | struct net_bridge_mdb_htable *mdb, __be32 dst) | 50 | struct net_bridge_mdb_htable *mdb, __be32 dst) |
51 | { | 51 | { |
52 | if (!mdb) | ||
53 | return NULL; | ||
54 | |||
52 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); | 55 | return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst)); |
53 | } | 56 | } |
54 | 57 | ||
55 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, | 58 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
56 | struct sk_buff *skb) | 59 | struct sk_buff *skb) |
57 | { | 60 | { |
58 | struct net_bridge_mdb_htable *mdb = br->mdb; | 61 | if (br->multicast_disabled) |
59 | |||
60 | if (!mdb || br->multicast_disabled) | ||
61 | return NULL; | 62 | return NULL; |
62 | 63 | ||
63 | switch (skb->protocol) { | 64 | switch (skb->protocol) { |
64 | case htons(ETH_P_IP): | 65 | case htons(ETH_P_IP): |
65 | if (BR_INPUT_SKB_CB(skb)->igmp) | 66 | if (BR_INPUT_SKB_CB(skb)->igmp) |
66 | break; | 67 | break; |
67 | return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr); | 68 | return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr); |
68 | } | 69 | } |
69 | 70 | ||
70 | return NULL; | 71 | return NULL; |
@@ -823,6 +824,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
823 | unsigned long max_delay; | 824 | unsigned long max_delay; |
824 | unsigned long now = jiffies; | 825 | unsigned long now = jiffies; |
825 | __be32 group; | 826 | __be32 group; |
827 | int err = 0; | ||
826 | 828 | ||
827 | spin_lock(&br->multicast_lock); | 829 | spin_lock(&br->multicast_lock); |
828 | if (!netif_running(br->dev) || | 830 | if (!netif_running(br->dev) || |
@@ -841,15 +843,17 @@ static int br_multicast_query(struct net_bridge *br, | |||
841 | group = 0; | 843 | group = 0; |
842 | } | 844 | } |
843 | } else { | 845 | } else { |
844 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) | 846 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) { |
845 | return -EINVAL; | 847 | err = -EINVAL; |
848 | goto out; | ||
849 | } | ||
846 | 850 | ||
847 | ih3 = igmpv3_query_hdr(skb); | 851 | ih3 = igmpv3_query_hdr(skb); |
848 | if (ih3->nsrcs) | 852 | if (ih3->nsrcs) |
849 | return 0; | 853 | goto out; |
850 | 854 | ||
851 | max_delay = ih3->code ? 1 : | 855 | max_delay = ih3->code ? |
852 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); | 856 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1; |
853 | } | 857 | } |
854 | 858 | ||
855 | if (!group) | 859 | if (!group) |
@@ -876,7 +880,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
876 | 880 | ||
877 | out: | 881 | out: |
878 | spin_unlock(&br->multicast_lock); | 882 | spin_unlock(&br->multicast_lock); |
879 | return 0; | 883 | return err; |
880 | } | 884 | } |
881 | 885 | ||
882 | static void br_multicast_leave_group(struct net_bridge *br, | 886 | static void br_multicast_leave_group(struct net_bridge *br, |
@@ -987,7 +991,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
987 | 991 | ||
988 | err = pskb_trim_rcsum(skb2, len); | 992 | err = pskb_trim_rcsum(skb2, len); |
989 | if (err) | 993 | if (err) |
990 | return err; | 994 | goto err_out; |
991 | } | 995 | } |
992 | 996 | ||
993 | len -= ip_hdrlen(skb2); | 997 | len -= ip_hdrlen(skb2); |
@@ -1009,7 +1013,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1009 | case CHECKSUM_NONE: | 1013 | case CHECKSUM_NONE: |
1010 | skb2->csum = 0; | 1014 | skb2->csum = 0; |
1011 | if (skb_checksum_complete(skb2)) | 1015 | if (skb_checksum_complete(skb2)) |
1012 | return -EINVAL; | 1016 | goto out; |
1013 | } | 1017 | } |
1014 | 1018 | ||
1015 | err = 0; | 1019 | err = 0; |
@@ -1036,6 +1040,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br, | |||
1036 | 1040 | ||
1037 | out: | 1041 | out: |
1038 | __skb_push(skb2, offset); | 1042 | __skb_push(skb2, offset); |
1043 | err_out: | ||
1039 | if (skb2 != skb) | 1044 | if (skb2 != skb) |
1040 | kfree_skb(skb2); | 1045 | kfree_skb(skb2); |
1041 | return err; | 1046 | return err; |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1cf2cef78584..846d7d1e2075 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -206,12 +206,20 @@ struct net_bridge | |||
206 | 206 | ||
207 | struct br_input_skb_cb { | 207 | struct br_input_skb_cb { |
208 | struct net_device *brdev; | 208 | struct net_device *brdev; |
209 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | ||
209 | int igmp; | 210 | int igmp; |
210 | int mrouters_only; | 211 | int mrouters_only; |
212 | #endif | ||
211 | }; | 213 | }; |
212 | 214 | ||
213 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) | 215 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) |
214 | 216 | ||
217 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | ||
218 | # define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only) | ||
219 | #else | ||
220 | # define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0) | ||
221 | #endif | ||
222 | |||
215 | extern struct notifier_block br_device_notifier; | 223 | extern struct notifier_block br_device_notifier; |
216 | extern const u8 br_group_address[ETH_ALEN]; | 224 | extern const u8 br_group_address[ETH_ALEN]; |
217 | 225 | ||
@@ -252,7 +260,7 @@ extern void br_deliver(const struct net_bridge_port *to, | |||
252 | struct sk_buff *skb); | 260 | struct sk_buff *skb); |
253 | extern int br_dev_queue_push_xmit(struct sk_buff *skb); | 261 | extern int br_dev_queue_push_xmit(struct sk_buff *skb); |
254 | extern void br_forward(const struct net_bridge_port *to, | 262 | extern void br_forward(const struct net_bridge_port *to, |
255 | struct sk_buff *skb); | 263 | struct sk_buff *skb, struct sk_buff *skb0); |
256 | extern int br_forward_finish(struct sk_buff *skb); | 264 | extern int br_forward_finish(struct sk_buff *skb); |
257 | extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); | 265 | extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb); |
258 | extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, | 266 | extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb, |
@@ -423,7 +431,7 @@ extern void br_ifinfo_notify(int event, struct net_bridge_port *port); | |||
423 | 431 | ||
424 | #ifdef CONFIG_SYSFS | 432 | #ifdef CONFIG_SYSFS |
425 | /* br_sysfs_if.c */ | 433 | /* br_sysfs_if.c */ |
426 | extern struct sysfs_ops brport_sysfs_ops; | 434 | extern const struct sysfs_ops brport_sysfs_ops; |
427 | extern int br_sysfs_addif(struct net_bridge_port *p); | 435 | extern int br_sysfs_addif(struct net_bridge_port *p); |
428 | 436 | ||
429 | /* br_sysfs_br.c */ | 437 | /* br_sysfs_br.c */ |
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 696596cd3384..0b9916489d6b 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c | |||
@@ -238,7 +238,7 @@ static ssize_t brport_store(struct kobject * kobj, | |||
238 | return ret; | 238 | return ret; |
239 | } | 239 | } |
240 | 240 | ||
241 | struct sysfs_ops brport_sysfs_ops = { | 241 | const struct sysfs_ops brport_sysfs_ops = { |
242 | .show = brport_show, | 242 | .show = brport_show, |
243 | .store = brport_store, | 243 | .store = brport_store, |
244 | }; | 244 | }; |
diff --git a/net/core/dev.c b/net/core/dev.c index bcc490cc9452..59d4394d2ce8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2483,6 +2483,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2483 | { | 2483 | { |
2484 | struct packet_type *ptype, *pt_prev; | 2484 | struct packet_type *ptype, *pt_prev; |
2485 | struct net_device *orig_dev; | 2485 | struct net_device *orig_dev; |
2486 | struct net_device *master; | ||
2486 | struct net_device *null_or_orig; | 2487 | struct net_device *null_or_orig; |
2487 | struct net_device *null_or_bond; | 2488 | struct net_device *null_or_bond; |
2488 | int ret = NET_RX_DROP; | 2489 | int ret = NET_RX_DROP; |
@@ -2503,11 +2504,12 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2503 | 2504 | ||
2504 | null_or_orig = NULL; | 2505 | null_or_orig = NULL; |
2505 | orig_dev = skb->dev; | 2506 | orig_dev = skb->dev; |
2506 | if (orig_dev->master) { | 2507 | master = ACCESS_ONCE(orig_dev->master); |
2507 | if (skb_bond_should_drop(skb)) | 2508 | if (master) { |
2509 | if (skb_bond_should_drop(skb, master)) | ||
2508 | null_or_orig = orig_dev; /* deliver only exact match */ | 2510 | null_or_orig = orig_dev; /* deliver only exact match */ |
2509 | else | 2511 | else |
2510 | skb->dev = orig_dev->master; | 2512 | skb->dev = master; |
2511 | } | 2513 | } |
2512 | 2514 | ||
2513 | __get_cpu_var(netdev_rx_stat).total++; | 2515 | __get_cpu_var(netdev_rx_stat).total++; |
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index fd91569e2394..3dc295beb483 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c | |||
@@ -97,8 +97,9 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) | |||
97 | 97 | ||
98 | netif_addr_lock_bh(dev); | 98 | netif_addr_lock_bh(dev); |
99 | if (alen != dev->addr_len) | 99 | if (alen != dev->addr_len) |
100 | return -EINVAL; | 100 | err = -EINVAL; |
101 | err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); | 101 | else |
102 | err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); | ||
102 | if (!err) | 103 | if (!err) |
103 | __dev_set_rx_mode(dev); | 104 | __dev_set_rx_mode(dev); |
104 | netif_addr_unlock_bh(dev); | 105 | netif_addr_unlock_bh(dev); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d102f6d9abdc..6cee6434da67 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -771,6 +771,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n) | |||
771 | } | 771 | } |
772 | 772 | ||
773 | static void neigh_invalidate(struct neighbour *neigh) | 773 | static void neigh_invalidate(struct neighbour *neigh) |
774 | __releases(neigh->lock) | ||
775 | __acquires(neigh->lock) | ||
774 | { | 776 | { |
775 | struct sk_buff *skb; | 777 | struct sk_buff *skb; |
776 | 778 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 7aa697253765..6f9206b36dc2 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -614,7 +614,7 @@ void netpoll_print_options(struct netpoll *np) | |||
614 | np->name, np->local_port); | 614 | np->name, np->local_port); |
615 | printk(KERN_INFO "%s: local IP %pI4\n", | 615 | printk(KERN_INFO "%s: local IP %pI4\n", |
616 | np->name, &np->local_ip); | 616 | np->name, &np->local_ip); |
617 | printk(KERN_INFO "%s: interface %s\n", | 617 | printk(KERN_INFO "%s: interface '%s'\n", |
618 | np->name, np->dev_name); | 618 | np->name, np->dev_name); |
619 | printk(KERN_INFO "%s: remote port %d\n", | 619 | printk(KERN_INFO "%s: remote port %d\n", |
620 | np->name, np->remote_port); | 620 | np->name, np->remote_port); |
@@ -661,6 +661,9 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
661 | if ((delim = strchr(cur, '@')) == NULL) | 661 | if ((delim = strchr(cur, '@')) == NULL) |
662 | goto parse_failed; | 662 | goto parse_failed; |
663 | *delim = 0; | 663 | *delim = 0; |
664 | if (*cur == ' ' || *cur == '\t') | ||
665 | printk(KERN_INFO "%s: warning: whitespace" | ||
666 | "is not allowed\n", np->name); | ||
664 | np->remote_port = simple_strtol(cur, NULL, 10); | 667 | np->remote_port = simple_strtol(cur, NULL, 10); |
665 | cur = delim; | 668 | cur = delim; |
666 | } | 669 | } |
@@ -708,7 +711,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
708 | return 0; | 711 | return 0; |
709 | 712 | ||
710 | parse_failed: | 713 | parse_failed: |
711 | printk(KERN_INFO "%s: couldn't parse config at %s!\n", | 714 | printk(KERN_INFO "%s: couldn't parse config at '%s'!\n", |
712 | np->name, cur); | 715 | np->name, cur); |
713 | return -1; | 716 | return -1; |
714 | } | 717 | } |
@@ -735,7 +738,7 @@ int netpoll_setup(struct netpoll *np) | |||
735 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); | 738 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); |
736 | if (!npinfo) { | 739 | if (!npinfo) { |
737 | err = -ENOMEM; | 740 | err = -ENOMEM; |
738 | goto release; | 741 | goto put; |
739 | } | 742 | } |
740 | 743 | ||
741 | npinfo->rx_flags = 0; | 744 | npinfo->rx_flags = 0; |
@@ -845,7 +848,7 @@ int netpoll_setup(struct netpoll *np) | |||
845 | 848 | ||
846 | kfree(npinfo); | 849 | kfree(npinfo); |
847 | } | 850 | } |
848 | 851 | put: | |
849 | dev_put(ndev); | 852 | dev_put(ndev); |
850 | return err; | 853 | return err; |
851 | } | 854 | } |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index b195c4feaa0a..4071eaf2b361 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -998,11 +998,11 @@ static struct inet_protosw dccp_v4_protosw = { | |||
998 | 998 | ||
999 | static int __net_init dccp_v4_init_net(struct net *net) | 999 | static int __net_init dccp_v4_init_net(struct net *net) |
1000 | { | 1000 | { |
1001 | int err; | 1001 | if (dccp_hashinfo.bhash == NULL) |
1002 | return -ESOCKTNOSUPPORT; | ||
1002 | 1003 | ||
1003 | err = inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, | 1004 | return inet_ctl_sock_create(&net->dccp.v4_ctl_sk, PF_INET, |
1004 | SOCK_DCCP, IPPROTO_DCCP, net); | 1005 | SOCK_DCCP, IPPROTO_DCCP, net); |
1005 | return err; | ||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static void __net_exit dccp_v4_exit_net(struct net *net) | 1008 | static void __net_exit dccp_v4_exit_net(struct net *net) |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 1aec6349e858..af3394df63b7 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -1191,11 +1191,11 @@ static struct inet_protosw dccp_v6_protosw = { | |||
1191 | 1191 | ||
1192 | static int __net_init dccp_v6_init_net(struct net *net) | 1192 | static int __net_init dccp_v6_init_net(struct net *net) |
1193 | { | 1193 | { |
1194 | int err; | 1194 | if (dccp_hashinfo.bhash == NULL) |
1195 | return -ESOCKTNOSUPPORT; | ||
1195 | 1196 | ||
1196 | err = inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, | 1197 | return inet_ctl_sock_create(&net->dccp.v6_ctl_sk, PF_INET6, |
1197 | SOCK_DCCP, IPPROTO_DCCP, net); | 1198 | SOCK_DCCP, IPPROTO_DCCP, net); |
1198 | return err; | ||
1199 | } | 1199 | } |
1200 | 1200 | ||
1201 | static void __net_exit dccp_v6_exit_net(struct net *net) | 1201 | static void __net_exit dccp_v6_exit_net(struct net *net) |
diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 0ef7061920c0..aa4cef374fd0 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c | |||
@@ -1036,7 +1036,7 @@ static int __init dccp_init(void) | |||
1036 | FIELD_SIZEOF(struct sk_buff, cb)); | 1036 | FIELD_SIZEOF(struct sk_buff, cb)); |
1037 | rc = percpu_counter_init(&dccp_orphan_count, 0); | 1037 | rc = percpu_counter_init(&dccp_orphan_count, 0); |
1038 | if (rc) | 1038 | if (rc) |
1039 | goto out; | 1039 | goto out_fail; |
1040 | rc = -ENOBUFS; | 1040 | rc = -ENOBUFS; |
1041 | inet_hashinfo_init(&dccp_hashinfo); | 1041 | inet_hashinfo_init(&dccp_hashinfo); |
1042 | dccp_hashinfo.bind_bucket_cachep = | 1042 | dccp_hashinfo.bind_bucket_cachep = |
@@ -1125,8 +1125,9 @@ static int __init dccp_init(void) | |||
1125 | goto out_sysctl_exit; | 1125 | goto out_sysctl_exit; |
1126 | 1126 | ||
1127 | dccp_timestamping_init(); | 1127 | dccp_timestamping_init(); |
1128 | out: | 1128 | |
1129 | return rc; | 1129 | return 0; |
1130 | |||
1130 | out_sysctl_exit: | 1131 | out_sysctl_exit: |
1131 | dccp_sysctl_exit(); | 1132 | dccp_sysctl_exit(); |
1132 | out_ackvec_exit: | 1133 | out_ackvec_exit: |
@@ -1135,18 +1136,19 @@ out_free_dccp_mib: | |||
1135 | dccp_mib_exit(); | 1136 | dccp_mib_exit(); |
1136 | out_free_dccp_bhash: | 1137 | out_free_dccp_bhash: |
1137 | free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); | 1138 | free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); |
1138 | dccp_hashinfo.bhash = NULL; | ||
1139 | out_free_dccp_locks: | 1139 | out_free_dccp_locks: |
1140 | inet_ehash_locks_free(&dccp_hashinfo); | 1140 | inet_ehash_locks_free(&dccp_hashinfo); |
1141 | out_free_dccp_ehash: | 1141 | out_free_dccp_ehash: |
1142 | free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); | 1142 | free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); |
1143 | dccp_hashinfo.ehash = NULL; | ||
1144 | out_free_bind_bucket_cachep: | 1143 | out_free_bind_bucket_cachep: |
1145 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); | 1144 | kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); |
1146 | dccp_hashinfo.bind_bucket_cachep = NULL; | ||
1147 | out_free_percpu: | 1145 | out_free_percpu: |
1148 | percpu_counter_destroy(&dccp_orphan_count); | 1146 | percpu_counter_destroy(&dccp_orphan_count); |
1149 | goto out; | 1147 | out_fail: |
1148 | dccp_hashinfo.bhash = NULL; | ||
1149 | dccp_hashinfo.ehash = NULL; | ||
1150 | dccp_hashinfo.bind_bucket_cachep = NULL; | ||
1151 | return rc; | ||
1150 | } | 1152 | } |
1151 | 1153 | ||
1152 | static void __exit dccp_fini(void) | 1154 | static void __exit dccp_fini(void) |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 51ca946e3392..3feb2b390308 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1194,7 +1194,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) | |||
1194 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 1194 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
1195 | if (idx < s_idx) | 1195 | if (idx < s_idx) |
1196 | goto cont; | 1196 | goto cont; |
1197 | if (idx > s_idx) | 1197 | if (h > s_h || idx > s_idx) |
1198 | s_ip_idx = 0; | 1198 | s_ip_idx = 0; |
1199 | in_dev = __in_dev_get_rcu(dev); | 1199 | in_dev = __in_dev_get_rcu(dev); |
1200 | if (!in_dev) | 1200 | if (!in_dev) |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index af5d89792860..01ef8ba9025c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -961,7 +961,9 @@ fib_find_node(struct trie *t, u32 key) | |||
961 | struct node *n; | 961 | struct node *n; |
962 | 962 | ||
963 | pos = 0; | 963 | pos = 0; |
964 | n = rcu_dereference(t->trie); | 964 | n = rcu_dereference_check(t->trie, |
965 | rcu_read_lock_held() || | ||
966 | lockdep_rtnl_is_held()); | ||
965 | 967 | ||
966 | while (n != NULL && NODE_TYPE(n) == T_TNODE) { | 968 | while (n != NULL && NODE_TYPE(n) == T_TNODE) { |
967 | tn = (struct tnode *) n; | 969 | tn = (struct tnode *) n; |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index f47c9f76754b..f78402d097b3 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -810,11 +810,13 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev | |||
810 | tunnel->err_count = 0; | 810 | tunnel->err_count = 0; |
811 | } | 811 | } |
812 | 812 | ||
813 | max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen; | 813 | max_headroom = LL_RESERVED_SPACE(tdev) + gre_hlen + rt->u.dst.header_len; |
814 | 814 | ||
815 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| | 815 | if (skb_headroom(skb) < max_headroom || skb_shared(skb)|| |
816 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { | 816 | (skb_cloned(skb) && !skb_clone_writable(skb, 0))) { |
817 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); | 817 | struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); |
818 | if (max_headroom > dev->needed_headroom) | ||
819 | dev->needed_headroom = max_headroom; | ||
818 | if (!new_skb) { | 820 | if (!new_skb) { |
819 | ip_rt_put(rt); | 821 | ip_rt_put(rt); |
820 | txq->tx_dropped++; | 822 | txq->tx_dropped++; |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 10a6a604bf32..678909281648 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -187,6 +187,16 @@ struct ic_device { | |||
187 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ | 187 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ |
188 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ | 188 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ |
189 | 189 | ||
190 | static bool __init ic_device_match(struct net_device *dev) | ||
191 | { | ||
192 | if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : | ||
193 | (!(dev->flags & IFF_LOOPBACK) && | ||
194 | (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && | ||
195 | strncmp(dev->name, "dummy", 5))) | ||
196 | return true; | ||
197 | return false; | ||
198 | } | ||
199 | |||
190 | static int __init ic_open_devs(void) | 200 | static int __init ic_open_devs(void) |
191 | { | 201 | { |
192 | struct ic_device *d, **last; | 202 | struct ic_device *d, **last; |
@@ -207,10 +217,7 @@ static int __init ic_open_devs(void) | |||
207 | for_each_netdev(&init_net, dev) { | 217 | for_each_netdev(&init_net, dev) { |
208 | if (dev->flags & IFF_LOOPBACK) | 218 | if (dev->flags & IFF_LOOPBACK) |
209 | continue; | 219 | continue; |
210 | if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : | 220 | if (ic_device_match(dev)) { |
211 | (!(dev->flags & IFF_LOOPBACK) && | ||
212 | (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) && | ||
213 | strncmp(dev->name, "dummy", 5))) { | ||
214 | int able = 0; | 221 | int able = 0; |
215 | if (dev->mtu >= 364) | 222 | if (dev->mtu >= 364) |
216 | able |= IC_BOOTP; | 223 | able |= IC_BOOTP; |
@@ -228,7 +235,7 @@ static int __init ic_open_devs(void) | |||
228 | } | 235 | } |
229 | if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { | 236 | if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { |
230 | rtnl_unlock(); | 237 | rtnl_unlock(); |
231 | return -1; | 238 | return -ENOMEM; |
232 | } | 239 | } |
233 | d->dev = dev; | 240 | d->dev = dev; |
234 | *last = d; | 241 | *last = d; |
@@ -253,7 +260,7 @@ static int __init ic_open_devs(void) | |||
253 | printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name); | 260 | printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name); |
254 | else | 261 | else |
255 | printk(KERN_ERR "IP-Config: No network devices available.\n"); | 262 | printk(KERN_ERR "IP-Config: No network devices available.\n"); |
256 | return -1; | 263 | return -ENODEV; |
257 | } | 264 | } |
258 | return 0; | 265 | return 0; |
259 | } | 266 | } |
@@ -1303,6 +1310,32 @@ __be32 __init root_nfs_parse_addr(char *name) | |||
1303 | return addr; | 1310 | return addr; |
1304 | } | 1311 | } |
1305 | 1312 | ||
1313 | #define DEVICE_WAIT_MAX 12 /* 12 seconds */ | ||
1314 | |||
1315 | static int __init wait_for_devices(void) | ||
1316 | { | ||
1317 | int i; | ||
1318 | |||
1319 | msleep(CONF_PRE_OPEN); | ||
1320 | for (i = 0; i < DEVICE_WAIT_MAX; i++) { | ||
1321 | struct net_device *dev; | ||
1322 | int found = 0; | ||
1323 | |||
1324 | rtnl_lock(); | ||
1325 | for_each_netdev(&init_net, dev) { | ||
1326 | if (ic_device_match(dev)) { | ||
1327 | found = 1; | ||
1328 | break; | ||
1329 | } | ||
1330 | } | ||
1331 | rtnl_unlock(); | ||
1332 | if (found) | ||
1333 | return 0; | ||
1334 | ssleep(1); | ||
1335 | } | ||
1336 | return -ENODEV; | ||
1337 | } | ||
1338 | |||
1306 | /* | 1339 | /* |
1307 | * IP Autoconfig dispatcher. | 1340 | * IP Autoconfig dispatcher. |
1308 | */ | 1341 | */ |
@@ -1313,6 +1346,7 @@ static int __init ip_auto_config(void) | |||
1313 | #ifdef IPCONFIG_DYNAMIC | 1346 | #ifdef IPCONFIG_DYNAMIC |
1314 | int retries = CONF_OPEN_RETRIES; | 1347 | int retries = CONF_OPEN_RETRIES; |
1315 | #endif | 1348 | #endif |
1349 | int err; | ||
1316 | 1350 | ||
1317 | #ifdef CONFIG_PROC_FS | 1351 | #ifdef CONFIG_PROC_FS |
1318 | proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); | 1352 | proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); |
@@ -1325,12 +1359,15 @@ static int __init ip_auto_config(void) | |||
1325 | #ifdef IPCONFIG_DYNAMIC | 1359 | #ifdef IPCONFIG_DYNAMIC |
1326 | try_try_again: | 1360 | try_try_again: |
1327 | #endif | 1361 | #endif |
1328 | /* Give hardware a chance to settle */ | 1362 | /* Wait for devices to appear */ |
1329 | msleep(CONF_PRE_OPEN); | 1363 | err = wait_for_devices(); |
1364 | if (err) | ||
1365 | return err; | ||
1330 | 1366 | ||
1331 | /* Setup all network devices */ | 1367 | /* Setup all network devices */ |
1332 | if (ic_open_devs() < 0) | 1368 | err = ic_open_devs(); |
1333 | return -1; | 1369 | if (err) |
1370 | return err; | ||
1334 | 1371 | ||
1335 | /* Give drivers a chance to settle */ | 1372 | /* Give drivers a chance to settle */ |
1336 | ssleep(CONF_POST_OPEN); | 1373 | ssleep(CONF_POST_OPEN); |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8582e12e4a62..d0a6092a67be 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -802,6 +802,9 @@ static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) | |||
802 | int line; | 802 | int line; |
803 | struct mfc_cache *uc, *c, **cp; | 803 | struct mfc_cache *uc, *c, **cp; |
804 | 804 | ||
805 | if (mfc->mfcc_parent >= MAXVIFS) | ||
806 | return -ENFILE; | ||
807 | |||
805 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); | 808 | line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); |
806 | 809 | ||
807 | for (cp = &net->ipv4.mfc_cache_array[line]; | 810 | for (cp = &net->ipv4.mfc_cache_array[line]; |
@@ -1613,17 +1616,20 @@ ipmr_fill_mroute(struct sk_buff *skb, struct mfc_cache *c, struct rtmsg *rtm) | |||
1613 | int ct; | 1616 | int ct; |
1614 | struct rtnexthop *nhp; | 1617 | struct rtnexthop *nhp; |
1615 | struct net *net = mfc_net(c); | 1618 | struct net *net = mfc_net(c); |
1616 | struct net_device *dev = net->ipv4.vif_table[c->mfc_parent].dev; | ||
1617 | u8 *b = skb_tail_pointer(skb); | 1619 | u8 *b = skb_tail_pointer(skb); |
1618 | struct rtattr *mp_head; | 1620 | struct rtattr *mp_head; |
1619 | 1621 | ||
1620 | if (dev) | 1622 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1621 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1623 | if (c->mfc_parent > MAXVIFS) |
1624 | return -ENOENT; | ||
1625 | |||
1626 | if (VIF_EXISTS(net, c->mfc_parent)) | ||
1627 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv4.vif_table[c->mfc_parent].dev->ifindex); | ||
1622 | 1628 | ||
1623 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1629 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1624 | 1630 | ||
1625 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1631 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1626 | if (c->mfc_un.res.ttls[ct] < 255) { | 1632 | if (VIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1627 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1633 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1628 | goto rtattr_failure; | 1634 | goto rtattr_failure; |
1629 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1635 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d9b40248b97f..d413b57be9b3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -932,10 +932,8 @@ static void rt_secret_rebuild_oneshot(struct net *net) | |||
932 | { | 932 | { |
933 | del_timer_sync(&net->ipv4.rt_secret_timer); | 933 | del_timer_sync(&net->ipv4.rt_secret_timer); |
934 | rt_cache_invalidate(net); | 934 | rt_cache_invalidate(net); |
935 | if (ip_rt_secret_interval) { | 935 | if (ip_rt_secret_interval) |
936 | net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; | 936 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval); |
937 | add_timer(&net->ipv4.rt_secret_timer); | ||
938 | } | ||
939 | } | 937 | } |
940 | 938 | ||
941 | static void rt_emergency_hash_rebuild(struct net *net) | 939 | static void rt_emergency_hash_rebuild(struct net *net) |
@@ -1099,7 +1097,7 @@ static int slow_chain_length(const struct rtable *head) | |||
1099 | } | 1097 | } |
1100 | 1098 | ||
1101 | static int rt_intern_hash(unsigned hash, struct rtable *rt, | 1099 | static int rt_intern_hash(unsigned hash, struct rtable *rt, |
1102 | struct rtable **rp, struct sk_buff *skb) | 1100 | struct rtable **rp, struct sk_buff *skb, int ifindex) |
1103 | { | 1101 | { |
1104 | struct rtable *rth, **rthp; | 1102 | struct rtable *rth, **rthp; |
1105 | unsigned long now; | 1103 | unsigned long now; |
@@ -1214,11 +1212,16 @@ restart: | |||
1214 | slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { | 1212 | slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { |
1215 | struct net *net = dev_net(rt->u.dst.dev); | 1213 | struct net *net = dev_net(rt->u.dst.dev); |
1216 | int num = ++net->ipv4.current_rt_cache_rebuild_count; | 1214 | int num = ++net->ipv4.current_rt_cache_rebuild_count; |
1217 | if (!rt_caching(dev_net(rt->u.dst.dev))) { | 1215 | if (!rt_caching(net)) { |
1218 | printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", | 1216 | printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", |
1219 | rt->u.dst.dev->name, num); | 1217 | rt->u.dst.dev->name, num); |
1220 | } | 1218 | } |
1221 | rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev)); | 1219 | rt_emergency_hash_rebuild(net); |
1220 | spin_unlock_bh(rt_hash_lock_addr(hash)); | ||
1221 | |||
1222 | hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, | ||
1223 | ifindex, rt_genid(net)); | ||
1224 | goto restart; | ||
1222 | } | 1225 | } |
1223 | } | 1226 | } |
1224 | 1227 | ||
@@ -1443,7 +1446,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1443 | dev_hold(rt->u.dst.dev); | 1446 | dev_hold(rt->u.dst.dev); |
1444 | if (rt->idev) | 1447 | if (rt->idev) |
1445 | in_dev_hold(rt->idev); | 1448 | in_dev_hold(rt->idev); |
1446 | rt->u.dst.obsolete = 0; | 1449 | rt->u.dst.obsolete = -1; |
1447 | rt->u.dst.lastuse = jiffies; | 1450 | rt->u.dst.lastuse = jiffies; |
1448 | rt->u.dst.path = &rt->u.dst; | 1451 | rt->u.dst.path = &rt->u.dst; |
1449 | rt->u.dst.neighbour = NULL; | 1452 | rt->u.dst.neighbour = NULL; |
@@ -1479,7 +1482,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1479 | &netevent); | 1482 | &netevent); |
1480 | 1483 | ||
1481 | rt_del(hash, rth); | 1484 | rt_del(hash, rth); |
1482 | if (!rt_intern_hash(hash, rt, &rt, NULL)) | 1485 | if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif)) |
1483 | ip_rt_put(rt); | 1486 | ip_rt_put(rt); |
1484 | goto do_next; | 1487 | goto do_next; |
1485 | } | 1488 | } |
@@ -1508,11 +1511,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1508 | struct dst_entry *ret = dst; | 1511 | struct dst_entry *ret = dst; |
1509 | 1512 | ||
1510 | if (rt) { | 1513 | if (rt) { |
1511 | if (dst->obsolete) { | 1514 | if (dst->obsolete > 0) { |
1512 | ip_rt_put(rt); | 1515 | ip_rt_put(rt); |
1513 | ret = NULL; | 1516 | ret = NULL; |
1514 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || | 1517 | } else if ((rt->rt_flags & RTCF_REDIRECTED) || |
1515 | rt->u.dst.expires) { | 1518 | (rt->u.dst.expires && |
1519 | time_after_eq(jiffies, rt->u.dst.expires))) { | ||
1516 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, | 1520 | unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, |
1517 | rt->fl.oif, | 1521 | rt->fl.oif, |
1518 | rt_genid(dev_net(dst->dev))); | 1522 | rt_genid(dev_net(dst->dev))); |
@@ -1728,7 +1732,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) | |||
1728 | 1732 | ||
1729 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | 1733 | static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) |
1730 | { | 1734 | { |
1731 | return NULL; | 1735 | if (rt_is_expired((struct rtable *)dst)) |
1736 | return NULL; | ||
1737 | return dst; | ||
1732 | } | 1738 | } |
1733 | 1739 | ||
1734 | static void ipv4_dst_destroy(struct dst_entry *dst) | 1740 | static void ipv4_dst_destroy(struct dst_entry *dst) |
@@ -1890,7 +1896,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1890 | if (!rth) | 1896 | if (!rth) |
1891 | goto e_nobufs; | 1897 | goto e_nobufs; |
1892 | 1898 | ||
1893 | rth->u.dst.output= ip_rt_bug; | 1899 | rth->u.dst.output = ip_rt_bug; |
1900 | rth->u.dst.obsolete = -1; | ||
1894 | 1901 | ||
1895 | atomic_set(&rth->u.dst.__refcnt, 1); | 1902 | atomic_set(&rth->u.dst.__refcnt, 1); |
1896 | rth->u.dst.flags= DST_HOST; | 1903 | rth->u.dst.flags= DST_HOST; |
@@ -1929,7 +1936,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1929 | 1936 | ||
1930 | in_dev_put(in_dev); | 1937 | in_dev_put(in_dev); |
1931 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1938 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
1932 | return rt_intern_hash(hash, rth, NULL, skb); | 1939 | return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex); |
1933 | 1940 | ||
1934 | e_nobufs: | 1941 | e_nobufs: |
1935 | in_dev_put(in_dev); | 1942 | in_dev_put(in_dev); |
@@ -2056,6 +2063,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
2056 | rth->fl.oif = 0; | 2063 | rth->fl.oif = 0; |
2057 | rth->rt_spec_dst= spec_dst; | 2064 | rth->rt_spec_dst= spec_dst; |
2058 | 2065 | ||
2066 | rth->u.dst.obsolete = -1; | ||
2059 | rth->u.dst.input = ip_forward; | 2067 | rth->u.dst.input = ip_forward; |
2060 | rth->u.dst.output = ip_output; | 2068 | rth->u.dst.output = ip_output; |
2061 | rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); | 2069 | rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); |
@@ -2095,7 +2103,7 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
2095 | /* put it into the cache */ | 2103 | /* put it into the cache */ |
2096 | hash = rt_hash(daddr, saddr, fl->iif, | 2104 | hash = rt_hash(daddr, saddr, fl->iif, |
2097 | rt_genid(dev_net(rth->u.dst.dev))); | 2105 | rt_genid(dev_net(rth->u.dst.dev))); |
2098 | return rt_intern_hash(hash, rth, NULL, skb); | 2106 | return rt_intern_hash(hash, rth, NULL, skb, fl->iif); |
2099 | } | 2107 | } |
2100 | 2108 | ||
2101 | /* | 2109 | /* |
@@ -2220,6 +2228,7 @@ local_input: | |||
2220 | goto e_nobufs; | 2228 | goto e_nobufs; |
2221 | 2229 | ||
2222 | rth->u.dst.output= ip_rt_bug; | 2230 | rth->u.dst.output= ip_rt_bug; |
2231 | rth->u.dst.obsolete = -1; | ||
2223 | rth->rt_genid = rt_genid(net); | 2232 | rth->rt_genid = rt_genid(net); |
2224 | 2233 | ||
2225 | atomic_set(&rth->u.dst.__refcnt, 1); | 2234 | atomic_set(&rth->u.dst.__refcnt, 1); |
@@ -2251,7 +2260,7 @@ local_input: | |||
2251 | } | 2260 | } |
2252 | rth->rt_type = res.type; | 2261 | rth->rt_type = res.type; |
2253 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); | 2262 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
2254 | err = rt_intern_hash(hash, rth, NULL, skb); | 2263 | err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); |
2255 | goto done; | 2264 | goto done; |
2256 | 2265 | ||
2257 | no_route: | 2266 | no_route: |
@@ -2446,6 +2455,7 @@ static int __mkroute_output(struct rtable **result, | |||
2446 | rth->rt_spec_dst= fl->fl4_src; | 2455 | rth->rt_spec_dst= fl->fl4_src; |
2447 | 2456 | ||
2448 | rth->u.dst.output=ip_output; | 2457 | rth->u.dst.output=ip_output; |
2458 | rth->u.dst.obsolete = -1; | ||
2449 | rth->rt_genid = rt_genid(dev_net(dev_out)); | 2459 | rth->rt_genid = rt_genid(dev_net(dev_out)); |
2450 | 2460 | ||
2451 | RT_CACHE_STAT_INC(out_slow_tot); | 2461 | RT_CACHE_STAT_INC(out_slow_tot); |
@@ -2497,7 +2507,7 @@ static int ip_mkroute_output(struct rtable **rp, | |||
2497 | if (err == 0) { | 2507 | if (err == 0) { |
2498 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, | 2508 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
2499 | rt_genid(dev_net(dev_out))); | 2509 | rt_genid(dev_net(dev_out))); |
2500 | err = rt_intern_hash(hash, rth, rp, NULL); | 2510 | err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif); |
2501 | } | 2511 | } |
2502 | 2512 | ||
2503 | return err; | 2513 | return err; |
@@ -3103,22 +3113,20 @@ static void rt_secret_reschedule(int old) | |||
3103 | rtnl_lock(); | 3113 | rtnl_lock(); |
3104 | for_each_net(net) { | 3114 | for_each_net(net) { |
3105 | int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); | 3115 | int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); |
3116 | long time; | ||
3106 | 3117 | ||
3107 | if (!new) | 3118 | if (!new) |
3108 | continue; | 3119 | continue; |
3109 | 3120 | ||
3110 | if (deleted) { | 3121 | if (deleted) { |
3111 | long time = net->ipv4.rt_secret_timer.expires - jiffies; | 3122 | time = net->ipv4.rt_secret_timer.expires - jiffies; |
3112 | 3123 | ||
3113 | if (time <= 0 || (time += diff) <= 0) | 3124 | if (time <= 0 || (time += diff) <= 0) |
3114 | time = 0; | 3125 | time = 0; |
3115 | |||
3116 | net->ipv4.rt_secret_timer.expires = time; | ||
3117 | } else | 3126 | } else |
3118 | net->ipv4.rt_secret_timer.expires = new; | 3127 | time = new; |
3119 | 3128 | ||
3120 | net->ipv4.rt_secret_timer.expires += jiffies; | 3129 | mod_timer(&net->ipv4.rt_secret_timer, jiffies + time); |
3121 | add_timer(&net->ipv4.rt_secret_timer); | ||
3122 | } | 3130 | } |
3123 | rtnl_unlock(); | 3131 | rtnl_unlock(); |
3124 | } | 3132 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5901010fad55..2c75f891914e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -429,7 +429,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
429 | if (tp->urg_seq == tp->copied_seq && | 429 | if (tp->urg_seq == tp->copied_seq && |
430 | !sock_flag(sk, SOCK_URGINLINE) && | 430 | !sock_flag(sk, SOCK_URGINLINE) && |
431 | tp->urg_data) | 431 | tp->urg_data) |
432 | target--; | 432 | target++; |
433 | 433 | ||
434 | /* Potential race condition. If read of tp below will | 434 | /* Potential race condition. If read of tp below will |
435 | * escape above sk->sk_state, we can be illegally awaken | 435 | * escape above sk->sk_state, we can be illegally awaken |
@@ -1254,6 +1254,39 @@ static void tcp_prequeue_process(struct sock *sk) | |||
1254 | tp->ucopy.memory = 0; | 1254 | tp->ucopy.memory = 0; |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | #ifdef CONFIG_NET_DMA | ||
1258 | static void tcp_service_net_dma(struct sock *sk, bool wait) | ||
1259 | { | ||
1260 | dma_cookie_t done, used; | ||
1261 | dma_cookie_t last_issued; | ||
1262 | struct tcp_sock *tp = tcp_sk(sk); | ||
1263 | |||
1264 | if (!tp->ucopy.dma_chan) | ||
1265 | return; | ||
1266 | |||
1267 | last_issued = tp->ucopy.dma_cookie; | ||
1268 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1269 | |||
1270 | do { | ||
1271 | if (dma_async_memcpy_complete(tp->ucopy.dma_chan, | ||
1272 | last_issued, &done, | ||
1273 | &used) == DMA_SUCCESS) { | ||
1274 | /* Safe to free early-copied skbs now */ | ||
1275 | __skb_queue_purge(&sk->sk_async_wait_queue); | ||
1276 | break; | ||
1277 | } else { | ||
1278 | struct sk_buff *skb; | ||
1279 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | ||
1280 | (dma_async_is_complete(skb->dma_cookie, done, | ||
1281 | used) == DMA_SUCCESS)) { | ||
1282 | __skb_dequeue(&sk->sk_async_wait_queue); | ||
1283 | kfree_skb(skb); | ||
1284 | } | ||
1285 | } | ||
1286 | } while (wait); | ||
1287 | } | ||
1288 | #endif | ||
1289 | |||
1257 | static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) | 1290 | static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off) |
1258 | { | 1291 | { |
1259 | struct sk_buff *skb; | 1292 | struct sk_buff *skb; |
@@ -1335,6 +1368,7 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc, | |||
1335 | sk_eat_skb(sk, skb, 0); | 1368 | sk_eat_skb(sk, skb, 0); |
1336 | if (!desc->count) | 1369 | if (!desc->count) |
1337 | break; | 1370 | break; |
1371 | tp->copied_seq = seq; | ||
1338 | } | 1372 | } |
1339 | tp->copied_seq = seq; | 1373 | tp->copied_seq = seq; |
1340 | 1374 | ||
@@ -1546,6 +1580,10 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1546 | /* __ Set realtime policy in scheduler __ */ | 1580 | /* __ Set realtime policy in scheduler __ */ |
1547 | } | 1581 | } |
1548 | 1582 | ||
1583 | #ifdef CONFIG_NET_DMA | ||
1584 | if (tp->ucopy.dma_chan) | ||
1585 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1586 | #endif | ||
1549 | if (copied >= target) { | 1587 | if (copied >= target) { |
1550 | /* Do not sleep, just process backlog. */ | 1588 | /* Do not sleep, just process backlog. */ |
1551 | release_sock(sk); | 1589 | release_sock(sk); |
@@ -1554,6 +1592,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1554 | sk_wait_data(sk, &timeo); | 1592 | sk_wait_data(sk, &timeo); |
1555 | 1593 | ||
1556 | #ifdef CONFIG_NET_DMA | 1594 | #ifdef CONFIG_NET_DMA |
1595 | tcp_service_net_dma(sk, false); /* Don't block */ | ||
1557 | tp->ucopy.wakeup = 0; | 1596 | tp->ucopy.wakeup = 0; |
1558 | #endif | 1597 | #endif |
1559 | 1598 | ||
@@ -1633,6 +1672,9 @@ do_prequeue: | |||
1633 | copied = -EFAULT; | 1672 | copied = -EFAULT; |
1634 | break; | 1673 | break; |
1635 | } | 1674 | } |
1675 | |||
1676 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1677 | |||
1636 | if ((offset + used) == skb->len) | 1678 | if ((offset + used) == skb->len) |
1637 | copied_early = 1; | 1679 | copied_early = 1; |
1638 | 1680 | ||
@@ -1702,27 +1744,9 @@ skip_copy: | |||
1702 | } | 1744 | } |
1703 | 1745 | ||
1704 | #ifdef CONFIG_NET_DMA | 1746 | #ifdef CONFIG_NET_DMA |
1705 | if (tp->ucopy.dma_chan) { | 1747 | tcp_service_net_dma(sk, true); /* Wait for queue to drain */ |
1706 | dma_cookie_t done, used; | 1748 | tp->ucopy.dma_chan = NULL; |
1707 | |||
1708 | dma_async_memcpy_issue_pending(tp->ucopy.dma_chan); | ||
1709 | |||
1710 | while (dma_async_memcpy_complete(tp->ucopy.dma_chan, | ||
1711 | tp->ucopy.dma_cookie, &done, | ||
1712 | &used) == DMA_IN_PROGRESS) { | ||
1713 | /* do partial cleanup of sk_async_wait_queue */ | ||
1714 | while ((skb = skb_peek(&sk->sk_async_wait_queue)) && | ||
1715 | (dma_async_is_complete(skb->dma_cookie, done, | ||
1716 | used) == DMA_SUCCESS)) { | ||
1717 | __skb_dequeue(&sk->sk_async_wait_queue); | ||
1718 | kfree_skb(skb); | ||
1719 | } | ||
1720 | } | ||
1721 | 1749 | ||
1722 | /* Safe to free early-copied skbs now */ | ||
1723 | __skb_queue_purge(&sk->sk_async_wait_queue); | ||
1724 | tp->ucopy.dma_chan = NULL; | ||
1725 | } | ||
1726 | if (tp->ucopy.pinned_list) { | 1750 | if (tp->ucopy.pinned_list) { |
1727 | dma_unpin_iovec_pages(tp->ucopy.pinned_list); | 1751 | dma_unpin_iovec_pages(tp->ucopy.pinned_list); |
1728 | tp->ucopy.pinned_list = NULL; | 1752 | tp->ucopy.pinned_list = NULL; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 788851ca8c5d..c096a4218b8f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2511,6 +2511,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) | |||
2511 | int err; | 2511 | int err; |
2512 | unsigned int mss; | 2512 | unsigned int mss; |
2513 | 2513 | ||
2514 | if (packets == 0) | ||
2515 | return; | ||
2516 | |||
2514 | WARN_ON(packets > tp->packets_out); | 2517 | WARN_ON(packets > tp->packets_out); |
2515 | if (tp->lost_skb_hint) { | 2518 | if (tp->lost_skb_hint) { |
2516 | skb = tp->lost_skb_hint; | 2519 | skb = tp->lost_skb_hint; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 8d51d39ad1bb..f4df5f931f36 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -370,6 +370,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
370 | if (sk->sk_state == TCP_CLOSE) | 370 | if (sk->sk_state == TCP_CLOSE) |
371 | goto out; | 371 | goto out; |
372 | 372 | ||
373 | if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { | ||
374 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); | ||
375 | goto out; | ||
376 | } | ||
377 | |||
373 | icsk = inet_csk(sk); | 378 | icsk = inet_csk(sk); |
374 | tp = tcp_sk(sk); | 379 | tp = tcp_sk(sk); |
375 | seq = ntohl(th->seq); | 380 | seq = ntohl(th->seq); |
@@ -1651,15 +1656,15 @@ int tcp_v4_rcv(struct sk_buff *skb) | |||
1651 | if (!sk) | 1656 | if (!sk) |
1652 | goto no_tcp_socket; | 1657 | goto no_tcp_socket; |
1653 | 1658 | ||
1659 | process: | ||
1660 | if (sk->sk_state == TCP_TIME_WAIT) | ||
1661 | goto do_time_wait; | ||
1662 | |||
1654 | if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { | 1663 | if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { |
1655 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); | 1664 | NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); |
1656 | goto discard_and_relse; | 1665 | goto discard_and_relse; |
1657 | } | 1666 | } |
1658 | 1667 | ||
1659 | process: | ||
1660 | if (sk->sk_state == TCP_TIME_WAIT) | ||
1661 | goto do_time_wait; | ||
1662 | |||
1663 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) | 1668 | if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) |
1664 | goto discard_and_relse; | 1669 | goto discard_and_relse; |
1665 | nf_reset(skb); | 1670 | nf_reset(skb); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index a17629b8912e..b2e6bbccaee1 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -134,7 +134,7 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | /* This function calculates a "timeout" which is equivalent to the timeout of a | 136 | /* This function calculates a "timeout" which is equivalent to the timeout of a |
137 | * TCP connection after "boundary" unsucessful, exponentially backed-off | 137 | * TCP connection after "boundary" unsuccessful, exponentially backed-off |
138 | * retransmissions with an initial RTO of TCP_RTO_MIN. | 138 | * retransmissions with an initial RTO of TCP_RTO_MIN. |
139 | */ | 139 | */ |
140 | static bool retransmits_timed_out(struct sock *sk, | 140 | static bool retransmits_timed_out(struct sock *sk, |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6cf3ee14ace3..7e567ae5eaab 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1380,6 +1380,8 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed) | |||
1380 | if (dad_failed) | 1380 | if (dad_failed) |
1381 | ifp->flags |= IFA_F_DADFAILED; | 1381 | ifp->flags |= IFA_F_DADFAILED; |
1382 | spin_unlock_bh(&ifp->lock); | 1382 | spin_unlock_bh(&ifp->lock); |
1383 | if (dad_failed) | ||
1384 | ipv6_ifa_notify(0, ifp); | ||
1383 | in6_ifa_put(ifp); | 1385 | in6_ifa_put(ifp); |
1384 | #ifdef CONFIG_IPV6_PRIVACY | 1386 | #ifdef CONFIG_IPV6_PRIVACY |
1385 | } else if (ifp->flags&IFA_F_TEMPORARY) { | 1387 | } else if (ifp->flags&IFA_F_TEMPORARY) { |
@@ -3608,7 +3610,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3608 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 3610 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
3609 | if (idx < s_idx) | 3611 | if (idx < s_idx) |
3610 | goto cont; | 3612 | goto cont; |
3611 | if (idx > s_idx) | 3613 | if (h > s_h || idx > s_idx) |
3612 | s_ip_idx = 0; | 3614 | s_ip_idx = 0; |
3613 | ip_idx = 0; | 3615 | ip_idx = 0; |
3614 | if ((idev = __in6_dev_get(dev)) == NULL) | 3616 | if ((idev = __in6_dev_get(dev)) == NULL) |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 52e0f74fdfe0..27acfb58650a 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1113,6 +1113,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) | |||
1113 | unsigned char ttls[MAXMIFS]; | 1113 | unsigned char ttls[MAXMIFS]; |
1114 | int i; | 1114 | int i; |
1115 | 1115 | ||
1116 | if (mfc->mf6cc_parent >= MAXMIFS) | ||
1117 | return -ENFILE; | ||
1118 | |||
1116 | memset(ttls, 255, MAXMIFS); | 1119 | memset(ttls, 255, MAXMIFS); |
1117 | for (i = 0; i < MAXMIFS; i++) { | 1120 | for (i = 0; i < MAXMIFS; i++) { |
1118 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) | 1121 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) |
@@ -1692,17 +1695,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1692 | int ct; | 1695 | int ct; |
1693 | struct rtnexthop *nhp; | 1696 | struct rtnexthop *nhp; |
1694 | struct net *net = mfc6_net(c); | 1697 | struct net *net = mfc6_net(c); |
1695 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1696 | u8 *b = skb_tail_pointer(skb); | 1698 | u8 *b = skb_tail_pointer(skb); |
1697 | struct rtattr *mp_head; | 1699 | struct rtattr *mp_head; |
1698 | 1700 | ||
1699 | if (dev) | 1701 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1700 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1702 | if (c->mf6c_parent > MAXMIFS) |
1703 | return -ENOENT; | ||
1704 | |||
1705 | if (MIF_EXISTS(net, c->mf6c_parent)) | ||
1706 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex); | ||
1701 | 1707 | ||
1702 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1708 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1703 | 1709 | ||
1704 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1710 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1705 | if (c->mfc_un.res.ttls[ct] < 255) { | 1711 | if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1706 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1712 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1707 | goto rtattr_failure; | 1713 | goto rtattr_failure; |
1708 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1714 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index aef31a29de9e..b9cf7cd61923 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -13,7 +13,7 @@ static const struct xt_table packet_raw = { | |||
13 | .valid_hooks = RAW_VALID_HOOKS, | 13 | .valid_hooks = RAW_VALID_HOOKS, |
14 | .me = THIS_MODULE, | 14 | .me = THIS_MODULE, |
15 | .af = NFPROTO_IPV6, | 15 | .af = NFPROTO_IPV6, |
16 | .priority = NF_IP6_PRI_FIRST, | 16 | .priority = NF_IP6_PRI_RAW, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | /* The work comes in here from netfilter.c. */ | 19 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 52cd3eff31dc..0d7713c5c206 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -879,7 +879,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
879 | 879 | ||
880 | rt = (struct rt6_info *) dst; | 880 | rt = (struct rt6_info *) dst; |
881 | 881 | ||
882 | if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) | 882 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
883 | return dst; | 883 | return dst; |
884 | 884 | ||
885 | return NULL; | 885 | return NULL; |
@@ -890,12 +890,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
890 | struct rt6_info *rt = (struct rt6_info *) dst; | 890 | struct rt6_info *rt = (struct rt6_info *) dst; |
891 | 891 | ||
892 | if (rt) { | 892 | if (rt) { |
893 | if (rt->rt6i_flags & RTF_CACHE) | 893 | if (rt->rt6i_flags & RTF_CACHE) { |
894 | ip6_del_rt(rt); | 894 | if (rt6_check_expired(rt)) { |
895 | else | 895 | ip6_del_rt(rt); |
896 | dst = NULL; | ||
897 | } | ||
898 | } else { | ||
896 | dst_release(dst); | 899 | dst_release(dst); |
900 | dst = NULL; | ||
901 | } | ||
897 | } | 902 | } |
898 | return NULL; | 903 | return dst; |
899 | } | 904 | } |
900 | 905 | ||
901 | static void ip6_link_failure(struct sk_buff *skb) | 906 | static void ip6_link_failure(struct sk_buff *skb) |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 368707882647..344145f23c34 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2129,10 +2129,9 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c | |||
2129 | int err; | 2129 | int err; |
2130 | 2130 | ||
2131 | out_skb = pfkey_xfrm_policy2msg_prep(xp); | 2131 | out_skb = pfkey_xfrm_policy2msg_prep(xp); |
2132 | if (IS_ERR(out_skb)) { | 2132 | if (IS_ERR(out_skb)) |
2133 | err = PTR_ERR(out_skb); | 2133 | return PTR_ERR(out_skb); |
2134 | goto out; | 2134 | |
2135 | } | ||
2136 | err = pfkey_xfrm_policy2msg(out_skb, xp, dir); | 2135 | err = pfkey_xfrm_policy2msg(out_skb, xp, dir); |
2137 | if (err < 0) | 2136 | if (err < 0) |
2138 | return err; | 2137 | return err; |
@@ -2148,7 +2147,6 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *c | |||
2148 | out_hdr->sadb_msg_seq = c->seq; | 2147 | out_hdr->sadb_msg_seq = c->seq; |
2149 | out_hdr->sadb_msg_pid = c->pid; | 2148 | out_hdr->sadb_msg_pid = c->pid; |
2150 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); | 2149 | pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp)); |
2151 | out: | ||
2152 | return 0; | 2150 | return 0; |
2153 | 2151 | ||
2154 | } | 2152 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index bc4e20e57ff5..1a29c4a8139e 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -744,7 +744,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
744 | break; | 744 | break; |
745 | default: | 745 | default: |
746 | /* should not get here, PLINK_BLOCKED is dealt with at the | 746 | /* should not get here, PLINK_BLOCKED is dealt with at the |
747 | * beggining of the function | 747 | * beginning of the function |
748 | */ | 748 | */ |
749 | spin_unlock_bh(&sta->lock); | 749 | spin_unlock_bh(&sta->lock); |
750 | break; | 750 | break; |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2b2af631d2b8..569410a85953 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -582,7 +582,9 @@ nla_put_failure: | |||
582 | nlmsg_failure: | 582 | nlmsg_failure: |
583 | kfree_skb(skb); | 583 | kfree_skb(skb); |
584 | errout: | 584 | errout: |
585 | nfnetlink_set_err(net, 0, group, -ENOBUFS); | 585 | if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0) |
586 | return -ENOBUFS; | ||
587 | |||
586 | return 0; | 588 | return 0; |
587 | } | 589 | } |
588 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ | 590 | #endif /* CONFIG_NF_CONNTRACK_EVENTS */ |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 8dd75d90efc0..c6cd1b84eddd 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -284,7 +284,7 @@ EXPORT_SYMBOL_GPL(ct_sip_parse_request); | |||
284 | * tabs, spaces and continuation lines, which are treated as a single whitespace | 284 | * tabs, spaces and continuation lines, which are treated as a single whitespace |
285 | * character. | 285 | * character. |
286 | * | 286 | * |
287 | * Some headers may appear multiple times. A comma seperated list of values is | 287 | * Some headers may appear multiple times. A comma separated list of values is |
288 | * equivalent to multiple headers. | 288 | * equivalent to multiple headers. |
289 | */ | 289 | */ |
290 | static const struct sip_header ct_sip_hdrs[] = { | 290 | static const struct sip_header ct_sip_hdrs[] = { |
@@ -421,7 +421,7 @@ int ct_sip_get_header(const struct nf_conn *ct, const char *dptr, | |||
421 | } | 421 | } |
422 | EXPORT_SYMBOL_GPL(ct_sip_get_header); | 422 | EXPORT_SYMBOL_GPL(ct_sip_get_header); |
423 | 423 | ||
424 | /* Get next header field in a list of comma seperated values */ | 424 | /* Get next header field in a list of comma separated values */ |
425 | static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr, | 425 | static int ct_sip_next_header(const struct nf_conn *ct, const char *dptr, |
426 | unsigned int dataoff, unsigned int datalen, | 426 | unsigned int dataoff, unsigned int datalen, |
427 | enum sip_header_types type, | 427 | enum sip_header_types type, |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 8eb0cc23ada3..6afa3d52ea5f 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -113,9 +113,9 @@ int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, | |||
113 | } | 113 | } |
114 | EXPORT_SYMBOL_GPL(nfnetlink_send); | 114 | EXPORT_SYMBOL_GPL(nfnetlink_send); |
115 | 115 | ||
116 | void nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) | 116 | int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error) |
117 | { | 117 | { |
118 | netlink_set_err(net->nfnl, pid, group, error); | 118 | return netlink_set_err(net->nfnl, pid, group, error); |
119 | } | 119 | } |
120 | EXPORT_SYMBOL_GPL(nfnetlink_set_err); | 120 | EXPORT_SYMBOL_GPL(nfnetlink_set_err); |
121 | 121 | ||
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index d952806b6469..215a64835de8 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * xt_hashlimit - Netfilter module to limit the number of packets per time | 2 | * xt_hashlimit - Netfilter module to limit the number of packets per time |
3 | * seperately for each hashbucket (sourceip/sourceport/dstip/dstport) | 3 | * separately for each hashbucket (sourceip/sourceport/dstip/dstport) |
4 | * | 4 | * |
5 | * (C) 2003-2004 by Harald Welte <laforge@netfilter.org> | 5 | * (C) 2003-2004 by Harald Welte <laforge@netfilter.org> |
6 | * Copyright © CC Computer Consultants GmbH, 2007 - 2008 | 6 | * Copyright © CC Computer Consultants GmbH, 2007 - 2008 |
@@ -493,6 +493,7 @@ static void hashlimit_ipv6_mask(__be32 *i, unsigned int p) | |||
493 | case 64 ... 95: | 493 | case 64 ... 95: |
494 | i[2] = maskl(i[2], p - 64); | 494 | i[2] = maskl(i[2], p - 64); |
495 | i[3] = 0; | 495 | i[3] = 0; |
496 | break; | ||
496 | case 96 ... 127: | 497 | case 96 ... 127: |
497 | i[3] = maskl(i[3], p - 96); | 498 | i[3] = maskl(i[3], p - 96); |
498 | break; | 499 | break; |
@@ -879,7 +880,8 @@ static void dl_seq_stop(struct seq_file *s, void *v) | |||
879 | struct xt_hashlimit_htable *htable = s->private; | 880 | struct xt_hashlimit_htable *htable = s->private; |
880 | unsigned int *bucket = (unsigned int *)v; | 881 | unsigned int *bucket = (unsigned int *)v; |
881 | 882 | ||
882 | kfree(bucket); | 883 | if (!IS_ERR(bucket)) |
884 | kfree(bucket); | ||
883 | spin_unlock_bh(&htable->lock); | 885 | spin_unlock_bh(&htable->lock); |
884 | } | 886 | } |
885 | 887 | ||
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 7073dbb8100c..971d172afece 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -267,7 +267,7 @@ recent_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
267 | for (i = 0; i < e->nstamps; i++) { | 267 | for (i = 0; i < e->nstamps; i++) { |
268 | if (info->seconds && time_after(time, e->stamps[i])) | 268 | if (info->seconds && time_after(time, e->stamps[i])) |
269 | continue; | 269 | continue; |
270 | if (info->hit_count && ++hits >= info->hit_count) { | 270 | if (!info->hit_count || ++hits >= info->hit_count) { |
271 | ret = !ret; | 271 | ret = !ret; |
272 | break; | 272 | break; |
273 | } | 273 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 320d0423a240..acbbae1e89b5 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1093,6 +1093,7 @@ static inline int do_one_set_err(struct sock *sk, | |||
1093 | struct netlink_set_err_data *p) | 1093 | struct netlink_set_err_data *p) |
1094 | { | 1094 | { |
1095 | struct netlink_sock *nlk = nlk_sk(sk); | 1095 | struct netlink_sock *nlk = nlk_sk(sk); |
1096 | int ret = 0; | ||
1096 | 1097 | ||
1097 | if (sk == p->exclude_sk) | 1098 | if (sk == p->exclude_sk) |
1098 | goto out; | 1099 | goto out; |
@@ -1104,10 +1105,15 @@ static inline int do_one_set_err(struct sock *sk, | |||
1104 | !test_bit(p->group - 1, nlk->groups)) | 1105 | !test_bit(p->group - 1, nlk->groups)) |
1105 | goto out; | 1106 | goto out; |
1106 | 1107 | ||
1108 | if (p->code == ENOBUFS && nlk->flags & NETLINK_RECV_NO_ENOBUFS) { | ||
1109 | ret = 1; | ||
1110 | goto out; | ||
1111 | } | ||
1112 | |||
1107 | sk->sk_err = p->code; | 1113 | sk->sk_err = p->code; |
1108 | sk->sk_error_report(sk); | 1114 | sk->sk_error_report(sk); |
1109 | out: | 1115 | out: |
1110 | return 0; | 1116 | return ret; |
1111 | } | 1117 | } |
1112 | 1118 | ||
1113 | /** | 1119 | /** |
@@ -1116,12 +1122,16 @@ out: | |||
1116 | * @pid: the PID of a process that we want to skip (if any) | 1122 | * @pid: the PID of a process that we want to skip (if any) |
1117 | * @groups: the broadcast group that will notice the error | 1123 | * @groups: the broadcast group that will notice the error |
1118 | * @code: error code, must be negative (as usual in kernelspace) | 1124 | * @code: error code, must be negative (as usual in kernelspace) |
1125 | * | ||
1126 | * This function returns the number of broadcast listeners that have set the | ||
1127 | * NETLINK_RECV_NO_ENOBUFS socket option. | ||
1119 | */ | 1128 | */ |
1120 | void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) | 1129 | int netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) |
1121 | { | 1130 | { |
1122 | struct netlink_set_err_data info; | 1131 | struct netlink_set_err_data info; |
1123 | struct hlist_node *node; | 1132 | struct hlist_node *node; |
1124 | struct sock *sk; | 1133 | struct sock *sk; |
1134 | int ret = 0; | ||
1125 | 1135 | ||
1126 | info.exclude_sk = ssk; | 1136 | info.exclude_sk = ssk; |
1127 | info.pid = pid; | 1137 | info.pid = pid; |
@@ -1132,9 +1142,10 @@ void netlink_set_err(struct sock *ssk, u32 pid, u32 group, int code) | |||
1132 | read_lock(&nl_table_lock); | 1142 | read_lock(&nl_table_lock); |
1133 | 1143 | ||
1134 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) | 1144 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) |
1135 | do_one_set_err(sk, &info); | 1145 | ret += do_one_set_err(sk, &info); |
1136 | 1146 | ||
1137 | read_unlock(&nl_table_lock); | 1147 | read_unlock(&nl_table_lock); |
1148 | return ret; | ||
1138 | } | 1149 | } |
1139 | EXPORT_SYMBOL(netlink_set_err); | 1150 | EXPORT_SYMBOL(netlink_set_err); |
1140 | 1151 | ||
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index c597cc53a6fb..5c6ae0c701c0 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c | |||
@@ -107,8 +107,7 @@ static void phonet_device_destroy(struct net_device *dev) | |||
107 | if (pnd) { | 107 | if (pnd) { |
108 | u8 addr; | 108 | u8 addr; |
109 | 109 | ||
110 | for (addr = find_first_bit(pnd->addrs, 64); addr < 64; | 110 | for_each_set_bit(addr, pnd->addrs, 64) |
111 | addr = find_next_bit(pnd->addrs, 64, 1+addr)) | ||
112 | phonet_address_notify(RTM_DELADDR, dev, addr); | 111 | phonet_address_notify(RTM_DELADDR, dev, addr); |
113 | kfree(pnd); | 112 | kfree(pnd); |
114 | } | 113 | } |
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index 2e6c7eb8e76a..fe2e7088ee07 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -141,8 +141,7 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb) | |||
141 | continue; | 141 | continue; |
142 | 142 | ||
143 | addr_idx = 0; | 143 | addr_idx = 0; |
144 | for (addr = find_first_bit(pnd->addrs, 64); addr < 64; | 144 | for_each_set_bit(addr, pnd->addrs, 64) { |
145 | addr = find_next_bit(pnd->addrs, 64, 1+addr)) { | ||
146 | if (addr_idx++ < addr_start_idx) | 145 | if (addr_idx++ < addr_start_idx) |
147 | continue; | 146 | continue; |
148 | 147 | ||
diff --git a/net/rxrpc/ar-accept.c b/net/rxrpc/ar-accept.c index 77228f28fa36..2d744f22a9a1 100644 --- a/net/rxrpc/ar-accept.c +++ b/net/rxrpc/ar-accept.c | |||
@@ -88,6 +88,11 @@ static int rxrpc_accept_incoming_call(struct rxrpc_local *local, | |||
88 | 88 | ||
89 | /* get a notification message to send to the server app */ | 89 | /* get a notification message to send to the server app */ |
90 | notification = alloc_skb(0, GFP_NOFS); | 90 | notification = alloc_skb(0, GFP_NOFS); |
91 | if (!notification) { | ||
92 | _debug("no memory"); | ||
93 | ret = -ENOMEM; | ||
94 | goto error_nofree; | ||
95 | } | ||
91 | rxrpc_new_skb(notification); | 96 | rxrpc_new_skb(notification); |
92 | notification->mark = RXRPC_SKB_MARK_NEW_CALL; | 97 | notification->mark = RXRPC_SKB_MARK_NEW_CALL; |
93 | 98 | ||
@@ -189,6 +194,7 @@ invalid_service: | |||
189 | ret = -ECONNREFUSED; | 194 | ret = -ECONNREFUSED; |
190 | error: | 195 | error: |
191 | rxrpc_free_skb(notification); | 196 | rxrpc_free_skb(notification); |
197 | error_nofree: | ||
192 | _leave(" = %d", ret); | 198 | _leave(" = %d", ret); |
193 | return ret; | 199 | return ret; |
194 | } | 200 | } |
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 21f9c7678aa3..2f691fb180d1 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -328,13 +328,16 @@ config NET_CLS_FLOW | |||
328 | module will be called cls_flow. | 328 | module will be called cls_flow. |
329 | 329 | ||
330 | config NET_CLS_CGROUP | 330 | config NET_CLS_CGROUP |
331 | bool "Control Group Classifier" | 331 | tristate "Control Group Classifier" |
332 | select NET_CLS | 332 | select NET_CLS |
333 | depends on CGROUPS | 333 | depends on CGROUPS |
334 | ---help--- | 334 | ---help--- |
335 | Say Y here if you want to classify packets based on the control | 335 | Say Y here if you want to classify packets based on the control |
336 | cgroup of their process. | 336 | cgroup of their process. |
337 | 337 | ||
338 | To compile this code as a module, choose M here: the | ||
339 | module will be called cls_cgroup. | ||
340 | |||
338 | config NET_EMATCH | 341 | config NET_EMATCH |
339 | bool "Extended Matches" | 342 | bool "Extended Matches" |
340 | select NET_CLS | 343 | select NET_CLS |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index e4877ca6727c..7f27d2c15e08 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -24,6 +24,25 @@ struct cgroup_cls_state | |||
24 | u32 classid; | 24 | u32 classid; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss, | ||
28 | struct cgroup *cgrp); | ||
29 | static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
30 | static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
31 | |||
32 | struct cgroup_subsys net_cls_subsys = { | ||
33 | .name = "net_cls", | ||
34 | .create = cgrp_create, | ||
35 | .destroy = cgrp_destroy, | ||
36 | .populate = cgrp_populate, | ||
37 | #ifdef CONFIG_NET_CLS_CGROUP | ||
38 | .subsys_id = net_cls_subsys_id, | ||
39 | #else | ||
40 | #define net_cls_subsys_id net_cls_subsys.subsys_id | ||
41 | #endif | ||
42 | .module = THIS_MODULE, | ||
43 | }; | ||
44 | |||
45 | |||
27 | static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) | 46 | static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) |
28 | { | 47 | { |
29 | return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), | 48 | return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), |
@@ -79,14 +98,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) | |||
79 | return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); | 98 | return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); |
80 | } | 99 | } |
81 | 100 | ||
82 | struct cgroup_subsys net_cls_subsys = { | ||
83 | .name = "net_cls", | ||
84 | .create = cgrp_create, | ||
85 | .destroy = cgrp_destroy, | ||
86 | .populate = cgrp_populate, | ||
87 | .subsys_id = net_cls_subsys_id, | ||
88 | }; | ||
89 | |||
90 | struct cls_cgroup_head | 101 | struct cls_cgroup_head |
91 | { | 102 | { |
92 | u32 handle; | 103 | u32 handle; |
@@ -277,12 +288,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = { | |||
277 | 288 | ||
278 | static int __init init_cgroup_cls(void) | 289 | static int __init init_cgroup_cls(void) |
279 | { | 290 | { |
280 | return register_tcf_proto_ops(&cls_cgroup_ops); | 291 | int ret = register_tcf_proto_ops(&cls_cgroup_ops); |
292 | if (ret) | ||
293 | return ret; | ||
294 | ret = cgroup_load_subsys(&net_cls_subsys); | ||
295 | if (ret) | ||
296 | unregister_tcf_proto_ops(&cls_cgroup_ops); | ||
297 | return ret; | ||
281 | } | 298 | } |
282 | 299 | ||
283 | static void __exit exit_cgroup_cls(void) | 300 | static void __exit exit_cgroup_cls(void) |
284 | { | 301 | { |
285 | unregister_tcf_proto_ops(&cls_cgroup_ops); | 302 | unregister_tcf_proto_ops(&cls_cgroup_ops); |
303 | cgroup_unload_subsys(&net_cls_subsys); | ||
286 | } | 304 | } |
287 | 305 | ||
288 | module_init(init_cgroup_cls); | 306 | module_init(init_cgroup_cls); |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 4e4ca65cd320..500886bda9b4 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -475,7 +475,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
475 | * used to provide an upper bound to this doubling operation. | 475 | * used to provide an upper bound to this doubling operation. |
476 | * | 476 | * |
477 | * Special Case: the first HB doesn't trigger exponential backoff. | 477 | * Special Case: the first HB doesn't trigger exponential backoff. |
478 | * The first unacknowleged HB triggers it. We do this with a flag | 478 | * The first unacknowledged HB triggers it. We do this with a flag |
479 | * that indicates that we have an outstanding HB. | 479 | * that indicates that we have an outstanding HB. |
480 | */ | 480 | */ |
481 | if (!is_hb || transport->hb_sent) { | 481 | if (!is_hb || transport->hb_sent) { |
diff --git a/net/socket.c b/net/socket.c index 769c386bd428..f55ffe9f8c87 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2135,6 +2135,10 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2135 | break; | 2135 | break; |
2136 | ++datagrams; | 2136 | ++datagrams; |
2137 | 2137 | ||
2138 | /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ | ||
2139 | if (flags & MSG_WAITFORONE) | ||
2140 | flags |= MSG_DONTWAIT; | ||
2141 | |||
2138 | if (timeout) { | 2142 | if (timeout) { |
2139 | ktime_get_ts(timeout); | 2143 | ktime_get_ts(timeout); |
2140 | *timeout = timespec_sub(end_time, *timeout); | 2144 | *timeout = timespec_sub(end_time, *timeout); |
diff --git a/net/sunrpc/addr.c b/net/sunrpc/addr.c index 6dcdd2517819..f845d9d72f73 100644 --- a/net/sunrpc/addr.c +++ b/net/sunrpc/addr.c | |||
@@ -71,8 +71,9 @@ static size_t rpc_ntop6(const struct sockaddr *sap, | |||
71 | if (unlikely(len == 0)) | 71 | if (unlikely(len == 0)) |
72 | return len; | 72 | return len; |
73 | 73 | ||
74 | if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && | 74 | if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) |
75 | !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL)) | 75 | return len; |
76 | if (sin6->sin6_scope_id == 0) | ||
76 | return len; | 77 | return len; |
77 | 78 | ||
78 | rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u", | 79 | rc = snprintf(scopebuf, sizeof(scopebuf), "%c%u", |
@@ -165,8 +166,7 @@ static int rpc_parse_scope_id(const char *buf, const size_t buflen, | |||
165 | if (*delim != IPV6_SCOPE_DELIMITER) | 166 | if (*delim != IPV6_SCOPE_DELIMITER) |
166 | return 0; | 167 | return 0; |
167 | 168 | ||
168 | if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL) && | 169 | if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL)) |
169 | !(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_SITELOCAL)) | ||
170 | return 0; | 170 | return 0; |
171 | 171 | ||
172 | len = (buf + buflen) - delim - 1; | 172 | len = (buf + buflen) - delim - 1; |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index f7a7f8380e38..0cfccc2a0297 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -206,8 +206,14 @@ gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct | |||
206 | ctx->gc_win = window_size; | 206 | ctx->gc_win = window_size; |
207 | /* gssd signals an error by passing ctx->gc_win = 0: */ | 207 | /* gssd signals an error by passing ctx->gc_win = 0: */ |
208 | if (ctx->gc_win == 0) { | 208 | if (ctx->gc_win == 0) { |
209 | /* in which case, p points to an error code which we ignore */ | 209 | /* |
210 | p = ERR_PTR(-EACCES); | 210 | * in which case, p points to an error code. Anything other |
211 | * than -EKEYEXPIRED gets converted to -EACCES. | ||
212 | */ | ||
213 | p = simple_get_bytes(p, end, &ret, sizeof(ret)); | ||
214 | if (!IS_ERR(p)) | ||
215 | p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) : | ||
216 | ERR_PTR(-EACCES); | ||
211 | goto err; | 217 | goto err; |
212 | } | 218 | } |
213 | /* copy the opaque wire context */ | 219 | /* copy the opaque wire context */ |
@@ -646,6 +652,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
646 | err = PTR_ERR(p); | 652 | err = PTR_ERR(p); |
647 | switch (err) { | 653 | switch (err) { |
648 | case -EACCES: | 654 | case -EACCES: |
655 | case -EKEYEXPIRED: | ||
649 | gss_msg->msg.errno = err; | 656 | gss_msg->msg.errno = err; |
650 | err = mlen; | 657 | err = mlen; |
651 | break; | 658 | break; |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 9ea45383480e..8d63f8fd29b7 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -999,19 +999,14 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) | |||
999 | inode = rpc_get_inode(sb, S_IFDIR | 0755); | 999 | inode = rpc_get_inode(sb, S_IFDIR | 0755); |
1000 | if (!inode) | 1000 | if (!inode) |
1001 | return -ENOMEM; | 1001 | return -ENOMEM; |
1002 | root = d_alloc_root(inode); | 1002 | sb->s_root = root = d_alloc_root(inode); |
1003 | if (!root) { | 1003 | if (!root) { |
1004 | iput(inode); | 1004 | iput(inode); |
1005 | return -ENOMEM; | 1005 | return -ENOMEM; |
1006 | } | 1006 | } |
1007 | if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL)) | 1007 | if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL)) |
1008 | goto out; | 1008 | return -ENOMEM; |
1009 | sb->s_root = root; | ||
1010 | return 0; | 1009 | return 0; |
1011 | out: | ||
1012 | d_genocide(root); | ||
1013 | dput(root); | ||
1014 | return -ENOMEM; | ||
1015 | } | 1010 | } |
1016 | 1011 | ||
1017 | static int | 1012 | static int |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 538ca433a56c..8420a4205b76 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -133,7 +133,7 @@ svc_pool_map_choose_mode(void) | |||
133 | return SVC_POOL_PERNODE; | 133 | return SVC_POOL_PERNODE; |
134 | } | 134 | } |
135 | 135 | ||
136 | node = any_online_node(node_online_map); | 136 | node = first_online_node; |
137 | if (nr_cpus_node(node) > 2) { | 137 | if (nr_cpus_node(node) > 2) { |
138 | /* | 138 | /* |
139 | * Non-trivial SMP, or CONFIG_NUMA on | 139 | * Non-trivial SMP, or CONFIG_NUMA on |
@@ -506,6 +506,10 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) | |||
506 | { | 506 | { |
507 | unsigned int pages, arghi; | 507 | unsigned int pages, arghi; |
508 | 508 | ||
509 | /* bc_xprt uses fore channel allocated buffers */ | ||
510 | if (svc_is_backchannel(rqstp)) | ||
511 | return 1; | ||
512 | |||
509 | pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply. | 513 | pages = size / PAGE_SIZE + 1; /* extra page as we hold both request and reply. |
510 | * We assume one is at most one page | 514 | * We assume one is at most one page |
511 | */ | 515 | */ |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 7d1f9e928f69..8f0f1fb3dc52 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -173,11 +173,13 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
173 | .sin_addr.s_addr = htonl(INADDR_ANY), | 173 | .sin_addr.s_addr = htonl(INADDR_ANY), |
174 | .sin_port = htons(port), | 174 | .sin_port = htons(port), |
175 | }; | 175 | }; |
176 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
176 | struct sockaddr_in6 sin6 = { | 177 | struct sockaddr_in6 sin6 = { |
177 | .sin6_family = AF_INET6, | 178 | .sin6_family = AF_INET6, |
178 | .sin6_addr = IN6ADDR_ANY_INIT, | 179 | .sin6_addr = IN6ADDR_ANY_INIT, |
179 | .sin6_port = htons(port), | 180 | .sin6_port = htons(port), |
180 | }; | 181 | }; |
182 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
181 | struct sockaddr *sap; | 183 | struct sockaddr *sap; |
182 | size_t len; | 184 | size_t len; |
183 | 185 | ||
@@ -186,10 +188,12 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl, | |||
186 | sap = (struct sockaddr *)&sin; | 188 | sap = (struct sockaddr *)&sin; |
187 | len = sizeof(sin); | 189 | len = sizeof(sin); |
188 | break; | 190 | break; |
191 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
189 | case PF_INET6: | 192 | case PF_INET6: |
190 | sap = (struct sockaddr *)&sin6; | 193 | sap = (struct sockaddr *)&sin6; |
191 | len = sizeof(sin6); | 194 | len = sizeof(sin6); |
192 | break; | 195 | break; |
196 | #endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ | ||
193 | default: | 197 | default: |
194 | return ERR_PTR(-EAFNOSUPPORT); | 198 | return ERR_PTR(-EAFNOSUPPORT); |
195 | } | 199 | } |
@@ -231,7 +235,10 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
231 | err: | 235 | err: |
232 | spin_unlock(&svc_xprt_class_lock); | 236 | spin_unlock(&svc_xprt_class_lock); |
233 | dprintk("svc: transport %s not found\n", xprt_name); | 237 | dprintk("svc: transport %s not found\n", xprt_name); |
234 | return -ENOENT; | 238 | |
239 | /* This errno is exposed to user space. Provide a reasonable | ||
240 | * perror msg for a bad transport. */ | ||
241 | return -EPROTONOSUPPORT; | ||
235 | } | 242 | } |
236 | EXPORT_SYMBOL_GPL(svc_create_xprt); | 243 | EXPORT_SYMBOL_GPL(svc_create_xprt); |
237 | 244 | ||
@@ -699,8 +706,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
699 | spin_unlock_bh(&pool->sp_lock); | 706 | spin_unlock_bh(&pool->sp_lock); |
700 | 707 | ||
701 | len = 0; | 708 | len = 0; |
702 | if (test_bit(XPT_LISTENER, &xprt->xpt_flags) && | 709 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { |
703 | !test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 710 | dprintk("svc_recv: found XPT_CLOSE\n"); |
711 | svc_delete_xprt(xprt); | ||
712 | } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { | ||
704 | struct svc_xprt *newxpt; | 713 | struct svc_xprt *newxpt; |
705 | newxpt = xprt->xpt_ops->xpo_accept(xprt); | 714 | newxpt = xprt->xpt_ops->xpo_accept(xprt); |
706 | if (newxpt) { | 715 | if (newxpt) { |
@@ -726,7 +735,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
726 | svc_xprt_received(newxpt); | 735 | svc_xprt_received(newxpt); |
727 | } | 736 | } |
728 | svc_xprt_received(xprt); | 737 | svc_xprt_received(xprt); |
729 | } else if (!test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | 738 | } else { |
730 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", | 739 | dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", |
731 | rqstp, pool->sp_id, xprt, | 740 | rqstp, pool->sp_id, xprt, |
732 | atomic_read(&xprt->xpt_ref.refcount)); | 741 | atomic_read(&xprt->xpt_ref.refcount)); |
@@ -739,11 +748,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
739 | dprintk("svc: got len=%d\n", len); | 748 | dprintk("svc: got len=%d\n", len); |
740 | } | 749 | } |
741 | 750 | ||
742 | if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { | ||
743 | dprintk("svc_recv: found XPT_CLOSE\n"); | ||
744 | svc_delete_xprt(xprt); | ||
745 | } | ||
746 | |||
747 | /* No data, incomplete (TCP) read, or accept() */ | 751 | /* No data, incomplete (TCP) read, or accept() */ |
748 | if (len == 0 || len == -EAGAIN) { | 752 | if (len == 0 || len == -EAGAIN) { |
749 | rqstp->rq_res.len = 0; | 753 | rqstp->rq_res.len = 0; |
@@ -889,11 +893,8 @@ void svc_delete_xprt(struct svc_xprt *xprt) | |||
889 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | 893 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
890 | serv->sv_tmpcnt--; | 894 | serv->sv_tmpcnt--; |
891 | 895 | ||
892 | for (dr = svc_deferred_dequeue(xprt); dr; | 896 | while ((dr = svc_deferred_dequeue(xprt)) != NULL) |
893 | dr = svc_deferred_dequeue(xprt)) { | ||
894 | svc_xprt_put(xprt); | ||
895 | kfree(dr); | 897 | kfree(dr); |
896 | } | ||
897 | 898 | ||
898 | svc_xprt_put(xprt); | 899 | svc_xprt_put(xprt); |
899 | spin_unlock_bh(&serv->sv_lock); | 900 | spin_unlock_bh(&serv->sv_lock); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index d8c041114497..afdcb0459a83 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #define RPCDBG_FACILITY RPCDBG_AUTH | 16 | #define RPCDBG_FACILITY RPCDBG_AUTH |
17 | 17 | ||
18 | #include <linux/sunrpc/clnt.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * AUTHUNIX and AUTHNULL credentials are both handled here. | 21 | * AUTHUNIX and AUTHNULL credentials are both handled here. |
@@ -187,10 +188,13 @@ static int ip_map_parse(struct cache_detail *cd, | |||
187 | * for scratch: */ | 188 | * for scratch: */ |
188 | char *buf = mesg; | 189 | char *buf = mesg; |
189 | int len; | 190 | int len; |
190 | int b1, b2, b3, b4, b5, b6, b7, b8; | ||
191 | char c; | ||
192 | char class[8]; | 191 | char class[8]; |
193 | struct in6_addr addr; | 192 | union { |
193 | struct sockaddr sa; | ||
194 | struct sockaddr_in s4; | ||
195 | struct sockaddr_in6 s6; | ||
196 | } address; | ||
197 | struct sockaddr_in6 sin6; | ||
194 | int err; | 198 | int err; |
195 | 199 | ||
196 | struct ip_map *ipmp; | 200 | struct ip_map *ipmp; |
@@ -209,24 +213,24 @@ static int ip_map_parse(struct cache_detail *cd, | |||
209 | len = qword_get(&mesg, buf, mlen); | 213 | len = qword_get(&mesg, buf, mlen); |
210 | if (len <= 0) return -EINVAL; | 214 | if (len <= 0) return -EINVAL; |
211 | 215 | ||
212 | if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) { | 216 | if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) |
213 | addr.s6_addr32[0] = 0; | ||
214 | addr.s6_addr32[1] = 0; | ||
215 | addr.s6_addr32[2] = htonl(0xffff); | ||
216 | addr.s6_addr32[3] = | ||
217 | htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); | ||
218 | } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c", | ||
219 | &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) { | ||
220 | addr.s6_addr16[0] = htons(b1); | ||
221 | addr.s6_addr16[1] = htons(b2); | ||
222 | addr.s6_addr16[2] = htons(b3); | ||
223 | addr.s6_addr16[3] = htons(b4); | ||
224 | addr.s6_addr16[4] = htons(b5); | ||
225 | addr.s6_addr16[5] = htons(b6); | ||
226 | addr.s6_addr16[6] = htons(b7); | ||
227 | addr.s6_addr16[7] = htons(b8); | ||
228 | } else | ||
229 | return -EINVAL; | 217 | return -EINVAL; |
218 | switch (address.sa.sa_family) { | ||
219 | case AF_INET: | ||
220 | /* Form a mapped IPv4 address in sin6 */ | ||
221 | memset(&sin6, 0, sizeof(sin6)); | ||
222 | sin6.sin6_family = AF_INET6; | ||
223 | sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | ||
224 | sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr; | ||
225 | break; | ||
226 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
227 | case AF_INET6: | ||
228 | memcpy(&sin6, &address.s6, sizeof(sin6)); | ||
229 | break; | ||
230 | #endif | ||
231 | default: | ||
232 | return -EINVAL; | ||
233 | } | ||
230 | 234 | ||
231 | expiry = get_expiry(&mesg); | 235 | expiry = get_expiry(&mesg); |
232 | if (expiry ==0) | 236 | if (expiry ==0) |
@@ -243,7 +247,8 @@ static int ip_map_parse(struct cache_detail *cd, | |||
243 | } else | 247 | } else |
244 | dom = NULL; | 248 | dom = NULL; |
245 | 249 | ||
246 | ipmp = ip_map_lookup(class, &addr); | 250 | /* IPv6 scope IDs are ignored for now */ |
251 | ipmp = ip_map_lookup(class, &sin6.sin6_addr); | ||
247 | if (ipmp) { | 252 | if (ipmp) { |
248 | err = ip_map_update(ipmp, | 253 | err = ip_map_update(ipmp, |
249 | container_of(dom, struct unix_domain, h), | 254 | container_of(dom, struct unix_domain, h), |
@@ -619,7 +624,7 @@ static int unix_gid_show(struct seq_file *m, | |||
619 | else | 624 | else |
620 | glen = 0; | 625 | glen = 0; |
621 | 626 | ||
622 | seq_printf(m, "%d %d:", ug->uid, glen); | 627 | seq_printf(m, "%u %d:", ug->uid, glen); |
623 | for (i = 0; i < glen; i++) | 628 | for (i = 0; i < glen; i++) |
624 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); | 629 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); |
625 | seq_printf(m, "\n"); | 630 | seq_printf(m, "\n"); |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 870929e08e5d..a29f259204e6 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -968,6 +968,7 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) | |||
968 | return len; | 968 | return len; |
969 | err_delete: | 969 | err_delete: |
970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); | 970 | set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); |
971 | svc_xprt_received(&svsk->sk_xprt); | ||
971 | err_again: | 972 | err_again: |
972 | return -EAGAIN; | 973 | return -EAGAIN; |
973 | } | 974 | } |
@@ -1357,7 +1358,7 @@ int svc_addsock(struct svc_serv *serv, const int fd, char *name_return, | |||
1357 | 1358 | ||
1358 | if (!so) | 1359 | if (!so) |
1359 | return err; | 1360 | return err; |
1360 | if (so->sk->sk_family != AF_INET) | 1361 | if ((so->sk->sk_family != PF_INET) && (so->sk->sk_family != PF_INET6)) |
1361 | err = -EAFNOSUPPORT; | 1362 | err = -EAFNOSUPPORT; |
1362 | else if (so->sk->sk_protocol != IPPROTO_TCP && | 1363 | else if (so->sk->sk_protocol != IPPROTO_TCP && |
1363 | so->sk->sk_protocol != IPPROTO_UDP) | 1364 | so->sk->sk_protocol != IPPROTO_UDP) |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 4f55ab7ec1b1..e4839c07c913 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -548,8 +548,6 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
548 | /* Still some bytes left; set up for a retry later. */ | 548 | /* Still some bytes left; set up for a retry later. */ |
549 | status = -EAGAIN; | 549 | status = -EAGAIN; |
550 | } | 550 | } |
551 | if (!transport->sock) | ||
552 | goto out; | ||
553 | 551 | ||
554 | switch (status) { | 552 | switch (status) { |
555 | case -ENOTSOCK: | 553 | case -ENOTSOCK: |
@@ -569,7 +567,7 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
569 | * prompts ECONNREFUSED. */ | 567 | * prompts ECONNREFUSED. */ |
570 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 568 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); |
571 | } | 569 | } |
572 | out: | 570 | |
573 | return status; | 571 | return status; |
574 | } | 572 | } |
575 | 573 | ||
@@ -651,8 +649,6 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
651 | status = -EAGAIN; | 649 | status = -EAGAIN; |
652 | break; | 650 | break; |
653 | } | 651 | } |
654 | if (!transport->sock) | ||
655 | goto out; | ||
656 | 652 | ||
657 | switch (status) { | 653 | switch (status) { |
658 | case -ENOTSOCK: | 654 | case -ENOTSOCK: |
@@ -672,7 +668,7 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
672 | case -ENOTCONN: | 668 | case -ENOTCONN: |
673 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); | 669 | clear_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags); |
674 | } | 670 | } |
675 | out: | 671 | |
676 | return status; | 672 | return status; |
677 | } | 673 | } |
678 | 674 | ||
@@ -1911,6 +1907,11 @@ static void xs_tcp_setup_socket(struct rpc_xprt *xprt, | |||
1911 | case -EALREADY: | 1907 | case -EALREADY: |
1912 | xprt_clear_connecting(xprt); | 1908 | xprt_clear_connecting(xprt); |
1913 | return; | 1909 | return; |
1910 | case -EINVAL: | ||
1911 | /* Happens, for instance, if the user specified a link | ||
1912 | * local IPv6 address without a scope-id. | ||
1913 | */ | ||
1914 | goto out; | ||
1914 | } | 1915 | } |
1915 | out_eagain: | 1916 | out_eagain: |
1916 | status = -EAGAIN; | 1917 | status = -EAGAIN; |
@@ -2099,7 +2100,7 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
2099 | * we allocate pages instead doing a kmalloc like rpc_malloc is because we want | 2100 | * we allocate pages instead doing a kmalloc like rpc_malloc is because we want |
2100 | * to use the server side send routines. | 2101 | * to use the server side send routines. |
2101 | */ | 2102 | */ |
2102 | void *bc_malloc(struct rpc_task *task, size_t size) | 2103 | static void *bc_malloc(struct rpc_task *task, size_t size) |
2103 | { | 2104 | { |
2104 | struct page *page; | 2105 | struct page *page; |
2105 | struct rpc_buffer *buf; | 2106 | struct rpc_buffer *buf; |
@@ -2119,7 +2120,7 @@ void *bc_malloc(struct rpc_task *task, size_t size) | |||
2119 | /* | 2120 | /* |
2120 | * Free the space allocated in the bc_alloc routine | 2121 | * Free the space allocated in the bc_alloc routine |
2121 | */ | 2122 | */ |
2122 | void bc_free(void *buffer) | 2123 | static void bc_free(void *buffer) |
2123 | { | 2124 | { |
2124 | struct rpc_buffer *buf; | 2125 | struct rpc_buffer *buf; |
2125 | 2126 | ||
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 414fc34b8bea..8dea66500cf5 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
@@ -153,11 +153,11 @@ void tipc_ref_table_stop(void) | |||
153 | 153 | ||
154 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) | 154 | u32 tipc_ref_acquire(void *object, spinlock_t **lock) |
155 | { | 155 | { |
156 | struct reference *entry; | ||
157 | u32 index; | 156 | u32 index; |
158 | u32 index_mask; | 157 | u32 index_mask; |
159 | u32 next_plus_upper; | 158 | u32 next_plus_upper; |
160 | u32 ref; | 159 | u32 ref; |
160 | struct reference *entry = NULL; | ||
161 | 161 | ||
162 | if (!object) { | 162 | if (!object) { |
163 | err("Attempt to acquire reference to non-existent object\n"); | 163 | err("Attempt to acquire reference to non-existent object\n"); |
@@ -175,30 +175,36 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock) | |||
175 | index = tipc_ref_table.first_free; | 175 | index = tipc_ref_table.first_free; |
176 | entry = &(tipc_ref_table.entries[index]); | 176 | entry = &(tipc_ref_table.entries[index]); |
177 | index_mask = tipc_ref_table.index_mask; | 177 | index_mask = tipc_ref_table.index_mask; |
178 | /* take lock in case a previous user of entry still holds it */ | ||
179 | spin_lock_bh(&entry->lock); | ||
180 | next_plus_upper = entry->ref; | 178 | next_plus_upper = entry->ref; |
181 | tipc_ref_table.first_free = next_plus_upper & index_mask; | 179 | tipc_ref_table.first_free = next_plus_upper & index_mask; |
182 | ref = (next_plus_upper & ~index_mask) + index; | 180 | ref = (next_plus_upper & ~index_mask) + index; |
183 | entry->ref = ref; | ||
184 | entry->object = object; | ||
185 | *lock = &entry->lock; | ||
186 | } | 181 | } |
187 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { | 182 | else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { |
188 | index = tipc_ref_table.init_point++; | 183 | index = tipc_ref_table.init_point++; |
189 | entry = &(tipc_ref_table.entries[index]); | 184 | entry = &(tipc_ref_table.entries[index]); |
190 | spin_lock_init(&entry->lock); | 185 | spin_lock_init(&entry->lock); |
191 | spin_lock_bh(&entry->lock); | ||
192 | ref = tipc_ref_table.start_mask + index; | 186 | ref = tipc_ref_table.start_mask + index; |
193 | entry->ref = ref; | ||
194 | entry->object = object; | ||
195 | *lock = &entry->lock; | ||
196 | } | 187 | } |
197 | else { | 188 | else { |
198 | ref = 0; | 189 | ref = 0; |
199 | } | 190 | } |
200 | write_unlock_bh(&ref_table_lock); | 191 | write_unlock_bh(&ref_table_lock); |
201 | 192 | ||
193 | /* | ||
194 | * Grab the lock so no one else can modify this entry | ||
195 | * While we assign its ref value & object pointer | ||
196 | */ | ||
197 | if (entry) { | ||
198 | spin_lock_bh(&entry->lock); | ||
199 | entry->ref = ref; | ||
200 | entry->object = object; | ||
201 | *lock = &entry->lock; | ||
202 | /* | ||
203 | * keep it locked, the caller is responsible | ||
204 | * for unlocking this when they're done with it | ||
205 | */ | ||
206 | } | ||
207 | |||
202 | return ref; | 208 | return ref; |
203 | } | 209 | } |
204 | 210 | ||