diff options
Diffstat (limited to 'net')
34 files changed, 371 insertions, 135 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 916061f681b6..68ced4bf158c 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
| @@ -3,11 +3,20 @@ | |||
| 3 | #include <linux/if_vlan.h> | 3 | #include <linux/if_vlan.h> |
| 4 | #include "vlan.h" | 4 | #include "vlan.h" |
| 5 | 5 | ||
| 6 | struct vlan_hwaccel_cb { | ||
| 7 | struct net_device *dev; | ||
| 8 | }; | ||
| 9 | |||
| 10 | static inline struct vlan_hwaccel_cb *vlan_hwaccel_cb(struct sk_buff *skb) | ||
| 11 | { | ||
| 12 | return (struct vlan_hwaccel_cb *)skb->cb; | ||
| 13 | } | ||
| 14 | |||
| 6 | /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ | 15 | /* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ |
| 7 | int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | 16 | int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, |
| 8 | u16 vlan_tci, int polling) | 17 | u16 vlan_tci, int polling) |
| 9 | { | 18 | { |
| 10 | struct net_device_stats *stats; | 19 | struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb); |
| 11 | 20 | ||
| 12 | if (skb_bond_should_drop(skb)) { | 21 | if (skb_bond_should_drop(skb)) { |
| 13 | dev_kfree_skb_any(skb); | 22 | dev_kfree_skb_any(skb); |
| @@ -15,23 +24,35 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
| 15 | } | 24 | } |
| 16 | 25 | ||
| 17 | skb->vlan_tci = vlan_tci; | 26 | skb->vlan_tci = vlan_tci; |
| 27 | cb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); | ||
| 28 | |||
| 29 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); | ||
| 30 | } | ||
| 31 | EXPORT_SYMBOL(__vlan_hwaccel_rx); | ||
| 32 | |||
| 33 | int vlan_hwaccel_do_receive(struct sk_buff *skb) | ||
| 34 | { | ||
| 35 | struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb); | ||
| 36 | struct net_device *dev = cb->dev; | ||
| 37 | struct net_device_stats *stats; | ||
| 38 | |||
| 18 | netif_nit_deliver(skb); | 39 | netif_nit_deliver(skb); |
| 19 | 40 | ||
| 20 | skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); | 41 | if (dev == NULL) { |
| 21 | if (skb->dev == NULL) { | 42 | kfree_skb(skb); |
| 22 | dev_kfree_skb_any(skb); | 43 | return -1; |
| 23 | /* Not NET_RX_DROP, this is not being dropped | ||
| 24 | * due to congestion. */ | ||
| 25 | return NET_RX_SUCCESS; | ||
| 26 | } | 44 | } |
| 27 | skb->dev->last_rx = jiffies; | 45 | |
| 46 | skb->dev = dev; | ||
| 47 | skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci); | ||
| 28 | skb->vlan_tci = 0; | 48 | skb->vlan_tci = 0; |
| 29 | 49 | ||
| 30 | stats = &skb->dev->stats; | 50 | dev->last_rx = jiffies; |
| 51 | |||
| 52 | stats = &dev->stats; | ||
| 31 | stats->rx_packets++; | 53 | stats->rx_packets++; |
| 32 | stats->rx_bytes += skb->len; | 54 | stats->rx_bytes += skb->len; |
| 33 | 55 | ||
| 34 | skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci); | ||
| 35 | switch (skb->pkt_type) { | 56 | switch (skb->pkt_type) { |
| 36 | case PACKET_BROADCAST: | 57 | case PACKET_BROADCAST: |
| 37 | break; | 58 | break; |
| @@ -43,13 +64,12 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, | |||
| 43 | * This allows the VLAN to have a different MAC than the | 64 | * This allows the VLAN to have a different MAC than the |
| 44 | * underlying device, and still route correctly. */ | 65 | * underlying device, and still route correctly. */ |
| 45 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, | 66 | if (!compare_ether_addr(eth_hdr(skb)->h_dest, |
| 46 | skb->dev->dev_addr)) | 67 | dev->dev_addr)) |
| 47 | skb->pkt_type = PACKET_HOST; | 68 | skb->pkt_type = PACKET_HOST; |
| 48 | break; | 69 | break; |
| 49 | }; | 70 | }; |
| 50 | return (polling ? netif_receive_skb(skb) : netif_rx(skb)); | 71 | return 0; |
| 51 | } | 72 | } |
| 52 | EXPORT_SYMBOL(__vlan_hwaccel_rx); | ||
| 53 | 73 | ||
| 54 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) | 74 | struct net_device *vlan_dev_real_dev(const struct net_device *dev) |
| 55 | { | 75 | { |
diff --git a/net/9p/client.c b/net/9p/client.c index 67717f69412e..4b529454616d 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
| @@ -189,6 +189,9 @@ static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag) | |||
| 189 | printk(KERN_ERR "Couldn't grow tag array\n"); | 189 | printk(KERN_ERR "Couldn't grow tag array\n"); |
| 190 | kfree(req->tc); | 190 | kfree(req->tc); |
| 191 | kfree(req->rc); | 191 | kfree(req->rc); |
| 192 | kfree(req->wq); | ||
| 193 | req->tc = req->rc = NULL; | ||
| 194 | req->wq = NULL; | ||
| 192 | return ERR_PTR(-ENOMEM); | 195 | return ERR_PTR(-ENOMEM); |
| 193 | } | 196 | } |
| 194 | req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall); | 197 | req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall); |
| @@ -311,12 +314,6 @@ static void p9_free_req(struct p9_client *c, struct p9_req_t *r) | |||
| 311 | r->status = REQ_STATUS_IDLE; | 314 | r->status = REQ_STATUS_IDLE; |
| 312 | if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool)) | 315 | if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool)) |
| 313 | p9_idpool_put(tag, c->tagpool); | 316 | p9_idpool_put(tag, c->tagpool); |
| 314 | |||
| 315 | /* if this was a flush request we have to free response fcall */ | ||
| 316 | if (r->rc->id == P9_RFLUSH) { | ||
| 317 | kfree(r->tc); | ||
| 318 | kfree(r->rc); | ||
| 319 | } | ||
| 320 | } | 317 | } |
| 321 | 318 | ||
| 322 | /** | 319 | /** |
| @@ -611,19 +608,21 @@ reterr: | |||
| 611 | 608 | ||
| 612 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | 609 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) |
| 613 | { | 610 | { |
| 614 | int err; | 611 | int ret; |
| 615 | struct p9_fid *fid; | 612 | struct p9_fid *fid; |
| 613 | unsigned long flags; | ||
| 616 | 614 | ||
| 617 | P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt); | 615 | P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt); |
| 618 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); | 616 | fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL); |
| 619 | if (!fid) | 617 | if (!fid) |
| 620 | return ERR_PTR(-ENOMEM); | 618 | return ERR_PTR(-ENOMEM); |
| 621 | 619 | ||
| 622 | fid->fid = p9_idpool_get(clnt->fidpool); | 620 | ret = p9_idpool_get(clnt->fidpool); |
| 623 | if (fid->fid < 0) { | 621 | if (fid->fid < 0) { |
| 624 | err = -ENOSPC; | 622 | ret = -ENOSPC; |
| 625 | goto error; | 623 | goto error; |
| 626 | } | 624 | } |
| 625 | fid->fid = ret; | ||
| 627 | 626 | ||
| 628 | memset(&fid->qid, 0, sizeof(struct p9_qid)); | 627 | memset(&fid->qid, 0, sizeof(struct p9_qid)); |
| 629 | fid->mode = -1; | 628 | fid->mode = -1; |
| @@ -632,27 +631,28 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt) | |||
| 632 | fid->clnt = clnt; | 631 | fid->clnt = clnt; |
| 633 | fid->aux = NULL; | 632 | fid->aux = NULL; |
| 634 | 633 | ||
| 635 | spin_lock(&clnt->lock); | 634 | spin_lock_irqsave(&clnt->lock, flags); |
| 636 | list_add(&fid->flist, &clnt->fidlist); | 635 | list_add(&fid->flist, &clnt->fidlist); |
| 637 | spin_unlock(&clnt->lock); | 636 | spin_unlock_irqrestore(&clnt->lock, flags); |
| 638 | 637 | ||
| 639 | return fid; | 638 | return fid; |
| 640 | 639 | ||
| 641 | error: | 640 | error: |
| 642 | kfree(fid); | 641 | kfree(fid); |
| 643 | return ERR_PTR(err); | 642 | return ERR_PTR(ret); |
| 644 | } | 643 | } |
| 645 | 644 | ||
| 646 | static void p9_fid_destroy(struct p9_fid *fid) | 645 | static void p9_fid_destroy(struct p9_fid *fid) |
| 647 | { | 646 | { |
| 648 | struct p9_client *clnt; | 647 | struct p9_client *clnt; |
| 648 | unsigned long flags; | ||
| 649 | 649 | ||
| 650 | P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid); | 650 | P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid); |
| 651 | clnt = fid->clnt; | 651 | clnt = fid->clnt; |
| 652 | p9_idpool_put(fid->fid, clnt->fidpool); | 652 | p9_idpool_put(fid->fid, clnt->fidpool); |
| 653 | spin_lock(&clnt->lock); | 653 | spin_lock_irqsave(&clnt->lock, flags); |
| 654 | list_del(&fid->flist); | 654 | list_del(&fid->flist); |
| 655 | spin_unlock(&clnt->lock); | 655 | spin_unlock_irqrestore(&clnt->lock, flags); |
| 656 | kfree(fid); | 656 | kfree(fid); |
| 657 | } | 657 | } |
| 658 | 658 | ||
| @@ -818,7 +818,9 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, | |||
| 818 | } | 818 | } |
| 819 | 819 | ||
| 820 | P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n", | 820 | P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n", |
| 821 | qid.type, qid.path, qid.version); | 821 | qid.type, |
| 822 | (unsigned long long)qid.path, | ||
| 823 | qid.version); | ||
| 822 | 824 | ||
| 823 | memmove(&fid->qid, &qid, sizeof(struct p9_qid)); | 825 | memmove(&fid->qid, &qid, sizeof(struct p9_qid)); |
| 824 | 826 | ||
| @@ -865,7 +867,9 @@ p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname) | |||
| 865 | } | 867 | } |
| 866 | 868 | ||
| 867 | P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n", | 869 | P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n", |
| 868 | qid.type, qid.path, qid.version); | 870 | qid.type, |
| 871 | (unsigned long long)qid.path, | ||
| 872 | qid.version); | ||
| 869 | 873 | ||
| 870 | memmove(&afid->qid, &qid, sizeof(struct p9_qid)); | 874 | memmove(&afid->qid, &qid, sizeof(struct p9_qid)); |
| 871 | p9_free_req(clnt, req); | 875 | p9_free_req(clnt, req); |
| @@ -930,7 +934,8 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, | |||
| 930 | 934 | ||
| 931 | for (count = 0; count < nwqids; count++) | 935 | for (count = 0; count < nwqids; count++) |
| 932 | P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n", | 936 | P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n", |
| 933 | count, wqids[count].type, wqids[count].path, | 937 | count, wqids[count].type, |
| 938 | (unsigned long long)wqids[count].path, | ||
| 934 | wqids[count].version); | 939 | wqids[count].version); |
| 935 | 940 | ||
| 936 | if (nwname) | 941 | if (nwname) |
| @@ -980,7 +985,9 @@ int p9_client_open(struct p9_fid *fid, int mode) | |||
| 980 | } | 985 | } |
| 981 | 986 | ||
| 982 | P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n", | 987 | P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n", |
| 983 | qid.type, qid.path, qid.version, iounit); | 988 | qid.type, |
| 989 | (unsigned long long)qid.path, | ||
| 990 | qid.version, iounit); | ||
| 984 | 991 | ||
| 985 | fid->mode = mode; | 992 | fid->mode = mode; |
| 986 | fid->iounit = iounit; | 993 | fid->iounit = iounit; |
| @@ -1023,7 +1030,9 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode, | |||
| 1023 | } | 1030 | } |
| 1024 | 1031 | ||
| 1025 | P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n", | 1032 | P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n", |
| 1026 | qid.type, qid.path, qid.version, iounit); | 1033 | qid.type, |
| 1034 | (unsigned long long)qid.path, | ||
| 1035 | qid.version, iounit); | ||
| 1027 | 1036 | ||
| 1028 | fid->mode = mode; | 1037 | fid->mode = mode; |
| 1029 | fid->iounit = iounit; | 1038 | fid->iounit = iounit; |
| @@ -1230,9 +1239,9 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) | |||
| 1230 | "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n" | 1239 | "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n" |
| 1231 | "<<< uid=%d gid=%d n_muid=%d\n", | 1240 | "<<< uid=%d gid=%d n_muid=%d\n", |
| 1232 | ret->size, ret->type, ret->dev, ret->qid.type, | 1241 | ret->size, ret->type, ret->dev, ret->qid.type, |
| 1233 | ret->qid.path, ret->qid.version, ret->mode, | 1242 | (unsigned long long)ret->qid.path, ret->qid.version, ret->mode, |
| 1234 | ret->atime, ret->mtime, ret->length, ret->name, | 1243 | ret->atime, ret->mtime, (unsigned long long)ret->length, |
| 1235 | ret->uid, ret->gid, ret->muid, ret->extension, | 1244 | ret->name, ret->uid, ret->gid, ret->muid, ret->extension, |
| 1236 | ret->n_uid, ret->n_gid, ret->n_muid); | 1245 | ret->n_uid, ret->n_gid, ret->n_muid); |
| 1237 | 1246 | ||
| 1238 | free_and_error: | 1247 | free_and_error: |
| @@ -1255,9 +1264,9 @@ int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst) | |||
| 1255 | " name=%s uid=%s gid=%s muid=%s extension=(%s)\n" | 1264 | " name=%s uid=%s gid=%s muid=%s extension=(%s)\n" |
| 1256 | " uid=%d gid=%d n_muid=%d\n", | 1265 | " uid=%d gid=%d n_muid=%d\n", |
| 1257 | wst->size, wst->type, wst->dev, wst->qid.type, | 1266 | wst->size, wst->type, wst->dev, wst->qid.type, |
| 1258 | wst->qid.path, wst->qid.version, wst->mode, | 1267 | (unsigned long long)wst->qid.path, wst->qid.version, wst->mode, |
| 1259 | wst->atime, wst->mtime, wst->length, wst->name, | 1268 | wst->atime, wst->mtime, (unsigned long long)wst->length, |
| 1260 | wst->uid, wst->gid, wst->muid, wst->extension, | 1269 | wst->name, wst->uid, wst->gid, wst->muid, wst->extension, |
| 1261 | wst->n_uid, wst->n_gid, wst->n_muid); | 1270 | wst->n_uid, wst->n_gid, wst->n_muid); |
| 1262 | err = 0; | 1271 | err = 0; |
| 1263 | clnt = fid->clnt; | 1272 | clnt = fid->clnt; |
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 8d6cc4777aae..2f1fe5fc1228 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <net/9p/transport.h> | 45 | #include <net/9p/transport.h> |
| 46 | #include <rdma/ib_verbs.h> | 46 | #include <rdma/ib_verbs.h> |
| 47 | #include <rdma/rdma_cm.h> | 47 | #include <rdma/rdma_cm.h> |
| 48 | #include <rdma/ib_verbs.h> | ||
| 49 | 48 | ||
| 50 | #define P9_PORT 5640 | 49 | #define P9_PORT 5640 |
| 51 | #define P9_RDMA_SQ_DEPTH 32 | 50 | #define P9_RDMA_SQ_DEPTH 32 |
| @@ -589,6 +588,9 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args) | |||
| 589 | if (IS_ERR(rdma->cm_id)) | 588 | if (IS_ERR(rdma->cm_id)) |
| 590 | goto error; | 589 | goto error; |
| 591 | 590 | ||
| 591 | /* Associate the client with the transport */ | ||
| 592 | client->trans = rdma; | ||
| 593 | |||
| 592 | /* Resolve the server's address */ | 594 | /* Resolve the server's address */ |
| 593 | rdma->addr.sin_family = AF_INET; | 595 | rdma->addr.sin_family = AF_INET; |
| 594 | rdma->addr.sin_addr.s_addr = in_aton(addr); | 596 | rdma->addr.sin_addr.s_addr = in_aton(addr); |
| @@ -669,7 +671,6 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args) | |||
| 669 | if (err || (rdma->state != P9_RDMA_CONNECTED)) | 671 | if (err || (rdma->state != P9_RDMA_CONNECTED)) |
| 670 | goto error; | 672 | goto error; |
| 671 | 673 | ||
| 672 | client->trans = rdma; | ||
| 673 | client->status = Connected; | 674 | client->status = Connected; |
| 674 | 675 | ||
| 675 | return 0; | 676 | return 0; |
diff --git a/net/core/dev.c b/net/core/dev.c index d9038e328cc1..9174c77d3112 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2218,6 +2218,9 @@ int netif_receive_skb(struct sk_buff *skb) | |||
| 2218 | int ret = NET_RX_DROP; | 2218 | int ret = NET_RX_DROP; |
| 2219 | __be16 type; | 2219 | __be16 type; |
| 2220 | 2220 | ||
| 2221 | if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) | ||
| 2222 | return NET_RX_SUCCESS; | ||
| 2223 | |||
| 2221 | /* if we've gotten here through NAPI, check netpoll */ | 2224 | /* if we've gotten here through NAPI, check netpoll */ |
| 2222 | if (netpoll_receive_skb(skb)) | 2225 | if (netpoll_receive_skb(skb)) |
| 2223 | return NET_RX_DROP; | 2226 | return NET_RX_DROP; |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index f1d07b5c1e17..1895a4ca9c4f 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
| @@ -325,6 +325,38 @@ void unregister_pernet_subsys(struct pernet_operations *module) | |||
| 325 | } | 325 | } |
| 326 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); | 326 | EXPORT_SYMBOL_GPL(unregister_pernet_subsys); |
| 327 | 327 | ||
| 328 | int register_pernet_gen_subsys(int *id, struct pernet_operations *ops) | ||
| 329 | { | ||
| 330 | int rv; | ||
| 331 | |||
| 332 | mutex_lock(&net_mutex); | ||
| 333 | again: | ||
| 334 | rv = ida_get_new_above(&net_generic_ids, 1, id); | ||
| 335 | if (rv < 0) { | ||
| 336 | if (rv == -EAGAIN) { | ||
| 337 | ida_pre_get(&net_generic_ids, GFP_KERNEL); | ||
| 338 | goto again; | ||
| 339 | } | ||
| 340 | goto out; | ||
| 341 | } | ||
| 342 | rv = register_pernet_operations(first_device, ops); | ||
| 343 | if (rv < 0) | ||
| 344 | ida_remove(&net_generic_ids, *id); | ||
| 345 | mutex_unlock(&net_mutex); | ||
| 346 | out: | ||
| 347 | return rv; | ||
| 348 | } | ||
| 349 | EXPORT_SYMBOL_GPL(register_pernet_gen_subsys); | ||
| 350 | |||
| 351 | void unregister_pernet_gen_subsys(int id, struct pernet_operations *ops) | ||
| 352 | { | ||
| 353 | mutex_lock(&net_mutex); | ||
| 354 | unregister_pernet_operations(ops); | ||
| 355 | ida_remove(&net_generic_ids, id); | ||
| 356 | mutex_unlock(&net_mutex); | ||
| 357 | } | ||
| 358 | EXPORT_SYMBOL_GPL(unregister_pernet_gen_subsys); | ||
| 359 | |||
| 328 | /** | 360 | /** |
| 329 | * register_pernet_device - register a network namespace device | 361 | * register_pernet_device - register a network namespace device |
| 330 | * @ops: pernet operations structure for the subsystem | 362 | * @ops: pernet operations structure for the subsystem |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 99f656d35b4f..a47f5bad110d 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -1973,28 +1973,27 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
| 1973 | 1973 | ||
| 1974 | /* make sure that we don't pick a non-existing transmit queue */ | 1974 | /* make sure that we don't pick a non-existing transmit queue */ |
| 1975 | ntxq = pkt_dev->odev->real_num_tx_queues; | 1975 | ntxq = pkt_dev->odev->real_num_tx_queues; |
| 1976 | if (ntxq <= num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) { | 1976 | if (ntxq > num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) { |
| 1977 | printk(KERN_WARNING "pktgen: WARNING: QUEUE_MAP_CPU " | 1977 | printk(KERN_WARNING "pktgen: WARNING: QUEUE_MAP_CPU " |
| 1978 | "disabled because CPU count (%d) exceeds number ", | 1978 | "disabled because CPU count (%d) exceeds number " |
| 1979 | num_online_cpus()); | 1979 | "of tx queues (%d) on %s\n", num_online_cpus(), ntxq, |
| 1980 | printk(KERN_WARNING "pktgen: WARNING: of tx queues " | 1980 | pkt_dev->odev->name); |
| 1981 | "(%d) on %s \n", ntxq, pkt_dev->odev->name); | ||
| 1982 | pkt_dev->flags &= ~F_QUEUE_MAP_CPU; | 1981 | pkt_dev->flags &= ~F_QUEUE_MAP_CPU; |
| 1983 | } | 1982 | } |
| 1984 | if (ntxq <= pkt_dev->queue_map_min) { | 1983 | if (ntxq <= pkt_dev->queue_map_min) { |
| 1985 | printk(KERN_WARNING "pktgen: WARNING: Requested " | 1984 | printk(KERN_WARNING "pktgen: WARNING: Requested " |
| 1986 | "queue_map_min (%d) exceeds number of tx\n", | 1985 | "queue_map_min (zero-based) (%d) exceeds valid range " |
| 1987 | pkt_dev->queue_map_min); | 1986 | "[0 - %d] for (%d) queues on %s, resetting\n", |
| 1988 | printk(KERN_WARNING "pktgen: WARNING: queues (%d) on " | 1987 | pkt_dev->queue_map_min, (ntxq ?: 1)- 1, ntxq, |
| 1989 | "%s, resetting\n", ntxq, pkt_dev->odev->name); | 1988 | pkt_dev->odev->name); |
| 1990 | pkt_dev->queue_map_min = ntxq - 1; | 1989 | pkt_dev->queue_map_min = ntxq - 1; |
| 1991 | } | 1990 | } |
| 1992 | if (ntxq <= pkt_dev->queue_map_max) { | 1991 | if (pkt_dev->queue_map_max >= ntxq) { |
| 1993 | printk(KERN_WARNING "pktgen: WARNING: Requested " | 1992 | printk(KERN_WARNING "pktgen: WARNING: Requested " |
| 1994 | "queue_map_max (%d) exceeds number of tx\n", | 1993 | "queue_map_max (zero-based) (%d) exceeds valid range " |
| 1995 | pkt_dev->queue_map_max); | 1994 | "[0 - %d] for (%d) queues on %s, resetting\n", |
| 1996 | printk(KERN_WARNING "pktgen: WARNING: queues (%d) on " | 1995 | pkt_dev->queue_map_max, (ntxq ?: 1)- 1, ntxq, |
| 1997 | "%s, resetting\n", ntxq, pkt_dev->odev->name); | 1996 | pkt_dev->odev->name); |
| 1998 | pkt_dev->queue_map_max = ntxq - 1; | 1997 | pkt_dev->queue_map_max = ntxq - 1; |
| 1999 | } | 1998 | } |
| 2000 | 1999 | ||
diff --git a/net/core/scm.c b/net/core/scm.c index 10f5c65f6a47..ab242cc1acca 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
| @@ -75,6 +75,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) | |||
| 75 | if (!fpl) | 75 | if (!fpl) |
| 76 | return -ENOMEM; | 76 | return -ENOMEM; |
| 77 | *fplp = fpl; | 77 | *fplp = fpl; |
| 78 | INIT_LIST_HEAD(&fpl->list); | ||
| 78 | fpl->count = 0; | 79 | fpl->count = 0; |
| 79 | } | 80 | } |
| 80 | fpp = &fpl->fp[fpl->count]; | 81 | fpp = &fpl->fp[fpl->count]; |
| @@ -106,9 +107,25 @@ void __scm_destroy(struct scm_cookie *scm) | |||
| 106 | 107 | ||
| 107 | if (fpl) { | 108 | if (fpl) { |
| 108 | scm->fp = NULL; | 109 | scm->fp = NULL; |
| 109 | for (i=fpl->count-1; i>=0; i--) | 110 | if (current->scm_work_list) { |
| 110 | fput(fpl->fp[i]); | 111 | list_add_tail(&fpl->list, current->scm_work_list); |
| 111 | kfree(fpl); | 112 | } else { |
| 113 | LIST_HEAD(work_list); | ||
| 114 | |||
| 115 | current->scm_work_list = &work_list; | ||
| 116 | |||
| 117 | list_add(&fpl->list, &work_list); | ||
| 118 | while (!list_empty(&work_list)) { | ||
| 119 | fpl = list_first_entry(&work_list, struct scm_fp_list, list); | ||
| 120 | |||
| 121 | list_del(&fpl->list); | ||
| 122 | for (i=fpl->count-1; i>=0; i--) | ||
| 123 | fput(fpl->fp[i]); | ||
| 124 | kfree(fpl); | ||
| 125 | } | ||
| 126 | |||
| 127 | current->scm_work_list = NULL; | ||
| 128 | } | ||
| 112 | } | 129 | } |
| 113 | } | 130 | } |
| 114 | 131 | ||
| @@ -284,6 +301,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl) | |||
| 284 | 301 | ||
| 285 | new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); | 302 | new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); |
| 286 | if (new_fpl) { | 303 | if (new_fpl) { |
| 304 | INIT_LIST_HEAD(&new_fpl->list); | ||
| 287 | for (i=fpl->count-1; i>=0; i--) | 305 | for (i=fpl->count-1; i>=0; i--) |
| 288 | get_file(fpl->fp[i]); | 306 | get_file(fpl->fp[i]); |
| 289 | memcpy(new_fpl, fpl, sizeof(*fpl)); | 307 | memcpy(new_fpl, fpl, sizeof(*fpl)); |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4e22e3a35359..ebb6b94f8af2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -449,6 +449,18 @@ void kfree_skb(struct sk_buff *skb) | |||
| 449 | __kfree_skb(skb); | 449 | __kfree_skb(skb); |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | /** | ||
| 453 | * skb_recycle_check - check if skb can be reused for receive | ||
| 454 | * @skb: buffer | ||
| 455 | * @skb_size: minimum receive buffer size | ||
| 456 | * | ||
| 457 | * Checks that the skb passed in is not shared or cloned, and | ||
| 458 | * that it is linear and its head portion at least as large as | ||
| 459 | * skb_size so that it can be recycled as a receive buffer. | ||
| 460 | * If these conditions are met, this function does any necessary | ||
| 461 | * reference count dropping and cleans up the skbuff as if it | ||
| 462 | * just came from __alloc_skb(). | ||
| 463 | */ | ||
| 452 | int skb_recycle_check(struct sk_buff *skb, int skb_size) | 464 | int skb_recycle_check(struct sk_buff *skb, int skb_size) |
| 453 | { | 465 | { |
| 454 | struct skb_shared_info *shinfo; | 466 | struct skb_shared_info *shinfo; |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 490e035c6d90..2e78f6bd9775 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -2063,9 +2063,10 @@ int cipso_v4_skbuff_setattr(struct sk_buff *skb, | |||
| 2063 | u32 opt_len; | 2063 | u32 opt_len; |
| 2064 | int len_delta; | 2064 | int len_delta; |
| 2065 | 2065 | ||
| 2066 | buf_len = cipso_v4_genopt(buf, buf_len, doi_def, secattr); | 2066 | ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr); |
| 2067 | if (buf_len < 0) | 2067 | if (ret_val < 0) |
| 2068 | return buf_len; | 2068 | return ret_val; |
| 2069 | buf_len = ret_val; | ||
| 2069 | opt_len = (buf_len + 3) & ~3; | 2070 | opt_len = (buf_len + 3) & ~3; |
| 2070 | 2071 | ||
| 2071 | /* we overwrite any existing options to ensure that we have enough | 2072 | /* we overwrite any existing options to ensure that we have enough |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index eccb7165a80c..c5aca0bb116a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1374,8 +1374,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1374 | sk->sk_state == TCP_CLOSE || | 1374 | sk->sk_state == TCP_CLOSE || |
| 1375 | (sk->sk_shutdown & RCV_SHUTDOWN) || | 1375 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
| 1376 | !timeo || | 1376 | !timeo || |
| 1377 | signal_pending(current) || | 1377 | signal_pending(current)) |
| 1378 | (flags & MSG_PEEK)) | ||
| 1379 | break; | 1378 | break; |
| 1380 | } else { | 1379 | } else { |
| 1381 | if (sock_flag(sk, SOCK_DONE)) | 1380 | if (sock_flag(sk, SOCK_DONE)) |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e4c5ac9fe89b..ba85d8831893 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -2279,6 +2279,11 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2279 | } | 2279 | } |
| 2280 | 2280 | ||
| 2281 | memset(&opts, 0, sizeof(opts)); | 2281 | memset(&opts, 0, sizeof(opts)); |
| 2282 | #ifdef CONFIG_SYN_COOKIES | ||
| 2283 | if (unlikely(req->cookie_ts)) | ||
| 2284 | TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); | ||
| 2285 | else | ||
| 2286 | #endif | ||
| 2282 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2287 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
| 2283 | tcp_header_size = tcp_synack_options(sk, req, mss, | 2288 | tcp_header_size = tcp_synack_options(sk, req, mss, |
| 2284 | skb, &opts, &md5) + | 2289 | skb, &opts, &md5) + |
| @@ -2304,11 +2309,6 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
| 2304 | 2309 | ||
| 2305 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ | 2310 | /* RFC1323: The window in SYN & SYN/ACK segments is never scaled. */ |
| 2306 | th->window = htons(min(req->rcv_wnd, 65535U)); | 2311 | th->window = htons(min(req->rcv_wnd, 65535U)); |
| 2307 | #ifdef CONFIG_SYN_COOKIES | ||
| 2308 | if (unlikely(req->cookie_ts)) | ||
| 2309 | TCP_SKB_CB(skb)->when = cookie_init_timestamp(req); | ||
| 2310 | else | ||
| 2311 | #endif | ||
| 2312 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); | 2312 | tcp_options_write((__be32 *)(th + 1), tp, &opts, &md5_hash_location); |
| 2313 | th->doff = (tcp_header_size >> 2); | 2313 | th->doff = (tcp_header_size >> 2); |
| 2314 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); | 2314 | TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTSEGS); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2095abc3caba..cf02701ced48 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -284,7 +284,7 @@ struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, | |||
| 284 | } | 284 | } |
| 285 | EXPORT_SYMBOL_GPL(udp4_lib_lookup); | 285 | EXPORT_SYMBOL_GPL(udp4_lib_lookup); |
| 286 | 286 | ||
| 287 | static inline struct sock *udp_v4_mcast_next(struct sock *sk, | 287 | static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk, |
| 288 | __be16 loc_port, __be32 loc_addr, | 288 | __be16 loc_port, __be32 loc_addr, |
| 289 | __be16 rmt_port, __be32 rmt_addr, | 289 | __be16 rmt_port, __be32 rmt_addr, |
| 290 | int dif) | 290 | int dif) |
| @@ -296,7 +296,8 @@ static inline struct sock *udp_v4_mcast_next(struct sock *sk, | |||
| 296 | sk_for_each_from(s, node) { | 296 | sk_for_each_from(s, node) { |
| 297 | struct inet_sock *inet = inet_sk(s); | 297 | struct inet_sock *inet = inet_sk(s); |
| 298 | 298 | ||
| 299 | if (s->sk_hash != hnum || | 299 | if (!net_eq(sock_net(s), net) || |
| 300 | s->sk_hash != hnum || | ||
| 300 | (inet->daddr && inet->daddr != rmt_addr) || | 301 | (inet->daddr && inet->daddr != rmt_addr) || |
| 301 | (inet->dport != rmt_port && inet->dport) || | 302 | (inet->dport != rmt_port && inet->dport) || |
| 302 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || | 303 | (inet->rcv_saddr && inet->rcv_saddr != loc_addr) || |
| @@ -1079,15 +1080,16 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
| 1079 | read_lock(&udp_hash_lock); | 1080 | read_lock(&udp_hash_lock); |
| 1080 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); | 1081 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); |
| 1081 | dif = skb->dev->ifindex; | 1082 | dif = skb->dev->ifindex; |
| 1082 | sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 1083 | sk = udp_v4_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); |
| 1083 | if (sk) { | 1084 | if (sk) { |
| 1084 | struct sock *sknext = NULL; | 1085 | struct sock *sknext = NULL; |
| 1085 | 1086 | ||
| 1086 | do { | 1087 | do { |
| 1087 | struct sk_buff *skb1 = skb; | 1088 | struct sk_buff *skb1 = skb; |
| 1088 | 1089 | ||
| 1089 | sknext = udp_v4_mcast_next(sk_next(sk), uh->dest, daddr, | 1090 | sknext = udp_v4_mcast_next(net, sk_next(sk), uh->dest, |
| 1090 | uh->source, saddr, dif); | 1091 | daddr, uh->source, saddr, |
| 1092 | dif); | ||
| 1091 | if (sknext) | 1093 | if (sknext) |
| 1092 | skb1 = skb_clone(skb, GFP_ATOMIC); | 1094 | skb1 = skb_clone(skb, GFP_ATOMIC); |
| 1093 | 1095 | ||
diff --git a/net/ipv4/xfrm4_state.c b/net/ipv4/xfrm4_state.c index 07735ed280d7..55dc6beab9aa 100644 --- a/net/ipv4/xfrm4_state.c +++ b/net/ipv4/xfrm4_state.c | |||
| @@ -33,6 +33,7 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, | |||
| 33 | x->sel.dport_mask = htons(0xffff); | 33 | x->sel.dport_mask = htons(0xffff); |
| 34 | x->sel.sport = xfrm_flowi_sport(fl); | 34 | x->sel.sport = xfrm_flowi_sport(fl); |
| 35 | x->sel.sport_mask = htons(0xffff); | 35 | x->sel.sport_mask = htons(0xffff); |
| 36 | x->sel.family = AF_INET; | ||
| 36 | x->sel.prefixlen_d = 32; | 37 | x->sel.prefixlen_d = 32; |
| 37 | x->sel.prefixlen_s = 32; | 38 | x->sel.prefixlen_s = 32; |
| 38 | x->sel.proto = fl->proto; | 39 | x->sel.proto = fl->proto; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index eea9542728ca..d9da5eb9dcb2 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2483,8 +2483,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
| 2483 | if (!idev && dev->mtu >= IPV6_MIN_MTU) | 2483 | if (!idev && dev->mtu >= IPV6_MIN_MTU) |
| 2484 | idev = ipv6_add_dev(dev); | 2484 | idev = ipv6_add_dev(dev); |
| 2485 | 2485 | ||
| 2486 | if (idev) | 2486 | if (idev) { |
| 2487 | idev->if_flags |= IF_READY; | 2487 | idev->if_flags |= IF_READY; |
| 2488 | run_pending = 1; | ||
| 2489 | } | ||
| 2488 | } else { | 2490 | } else { |
| 2489 | if (!addrconf_qdisc_ok(dev)) { | 2491 | if (!addrconf_qdisc_ok(dev)) { |
| 2490 | /* device is still not ready. */ | 2492 | /* device is still not ready. */ |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e51da8c092fa..8b48512ebf6a 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -138,6 +138,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, | |||
| 138 | int peeked; | 138 | int peeked; |
| 139 | int err; | 139 | int err; |
| 140 | int is_udplite = IS_UDPLITE(sk); | 140 | int is_udplite = IS_UDPLITE(sk); |
| 141 | int is_udp4; | ||
| 141 | 142 | ||
| 142 | if (addr_len) | 143 | if (addr_len) |
| 143 | *addr_len=sizeof(struct sockaddr_in6); | 144 | *addr_len=sizeof(struct sockaddr_in6); |
| @@ -158,6 +159,8 @@ try_again: | |||
| 158 | else if (copied < ulen) | 159 | else if (copied < ulen) |
| 159 | msg->msg_flags |= MSG_TRUNC; | 160 | msg->msg_flags |= MSG_TRUNC; |
| 160 | 161 | ||
| 162 | is_udp4 = (skb->protocol == htons(ETH_P_IP)); | ||
| 163 | |||
| 161 | /* | 164 | /* |
| 162 | * If checksum is needed at all, try to do it while copying the | 165 | * If checksum is needed at all, try to do it while copying the |
| 163 | * data. If the data is truncated, or if we only want a partial | 166 | * data. If the data is truncated, or if we only want a partial |
| @@ -180,9 +183,14 @@ try_again: | |||
| 180 | if (err) | 183 | if (err) |
| 181 | goto out_free; | 184 | goto out_free; |
| 182 | 185 | ||
| 183 | if (!peeked) | 186 | if (!peeked) { |
| 184 | UDP6_INC_STATS_USER(sock_net(sk), | 187 | if (is_udp4) |
| 185 | UDP_MIB_INDATAGRAMS, is_udplite); | 188 | UDP_INC_STATS_USER(sock_net(sk), |
| 189 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
| 190 | else | ||
| 191 | UDP6_INC_STATS_USER(sock_net(sk), | ||
| 192 | UDP_MIB_INDATAGRAMS, is_udplite); | ||
| 193 | } | ||
| 186 | 194 | ||
| 187 | sock_recv_timestamp(msg, sk, skb); | 195 | sock_recv_timestamp(msg, sk, skb); |
| 188 | 196 | ||
| @@ -196,7 +204,7 @@ try_again: | |||
| 196 | sin6->sin6_flowinfo = 0; | 204 | sin6->sin6_flowinfo = 0; |
| 197 | sin6->sin6_scope_id = 0; | 205 | sin6->sin6_scope_id = 0; |
| 198 | 206 | ||
| 199 | if (skb->protocol == htons(ETH_P_IP)) | 207 | if (is_udp4) |
| 200 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, | 208 | ipv6_addr_set(&sin6->sin6_addr, 0, 0, |
| 201 | htonl(0xffff), ip_hdr(skb)->saddr); | 209 | htonl(0xffff), ip_hdr(skb)->saddr); |
| 202 | else { | 210 | else { |
| @@ -207,7 +215,7 @@ try_again: | |||
| 207 | } | 215 | } |
| 208 | 216 | ||
| 209 | } | 217 | } |
| 210 | if (skb->protocol == htons(ETH_P_IP)) { | 218 | if (is_udp4) { |
| 211 | if (inet->cmsg_flags) | 219 | if (inet->cmsg_flags) |
| 212 | ip_cmsg_recv(msg, skb); | 220 | ip_cmsg_recv(msg, skb); |
| 213 | } else { | 221 | } else { |
| @@ -228,8 +236,14 @@ out: | |||
| 228 | 236 | ||
| 229 | csum_copy_err: | 237 | csum_copy_err: |
| 230 | lock_sock(sk); | 238 | lock_sock(sk); |
| 231 | if (!skb_kill_datagram(sk, skb, flags)) | 239 | if (!skb_kill_datagram(sk, skb, flags)) { |
| 232 | UDP6_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 240 | if (is_udp4) |
| 241 | UDP_INC_STATS_USER(sock_net(sk), | ||
| 242 | UDP_MIB_INERRORS, is_udplite); | ||
| 243 | else | ||
| 244 | UDP6_INC_STATS_USER(sock_net(sk), | ||
| 245 | UDP_MIB_INERRORS, is_udplite); | ||
| 246 | } | ||
| 233 | release_sock(sk); | 247 | release_sock(sk); |
| 234 | 248 | ||
| 235 | if (flags & MSG_DONTWAIT) | 249 | if (flags & MSG_DONTWAIT) |
| @@ -328,7 +342,7 @@ drop: | |||
| 328 | return -1; | 342 | return -1; |
| 329 | } | 343 | } |
| 330 | 344 | ||
| 331 | static struct sock *udp_v6_mcast_next(struct sock *sk, | 345 | static struct sock *udp_v6_mcast_next(struct net *net, struct sock *sk, |
| 332 | __be16 loc_port, struct in6_addr *loc_addr, | 346 | __be16 loc_port, struct in6_addr *loc_addr, |
| 333 | __be16 rmt_port, struct in6_addr *rmt_addr, | 347 | __be16 rmt_port, struct in6_addr *rmt_addr, |
| 334 | int dif) | 348 | int dif) |
| @@ -340,7 +354,7 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, | |||
| 340 | sk_for_each_from(s, node) { | 354 | sk_for_each_from(s, node) { |
| 341 | struct inet_sock *inet = inet_sk(s); | 355 | struct inet_sock *inet = inet_sk(s); |
| 342 | 356 | ||
| 343 | if (sock_net(s) != sock_net(sk)) | 357 | if (!net_eq(sock_net(s), net)) |
| 344 | continue; | 358 | continue; |
| 345 | 359 | ||
| 346 | if (s->sk_hash == num && s->sk_family == PF_INET6) { | 360 | if (s->sk_hash == num && s->sk_family == PF_INET6) { |
| @@ -383,14 +397,14 @@ static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, | |||
| 383 | read_lock(&udp_hash_lock); | 397 | read_lock(&udp_hash_lock); |
| 384 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); | 398 | sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); |
| 385 | dif = inet6_iif(skb); | 399 | dif = inet6_iif(skb); |
| 386 | sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); | 400 | sk = udp_v6_mcast_next(net, sk, uh->dest, daddr, uh->source, saddr, dif); |
| 387 | if (!sk) { | 401 | if (!sk) { |
| 388 | kfree_skb(skb); | 402 | kfree_skb(skb); |
| 389 | goto out; | 403 | goto out; |
| 390 | } | 404 | } |
| 391 | 405 | ||
| 392 | sk2 = sk; | 406 | sk2 = sk; |
| 393 | while ((sk2 = udp_v6_mcast_next(sk_next(sk2), uh->dest, daddr, | 407 | while ((sk2 = udp_v6_mcast_next(net, sk_next(sk2), uh->dest, daddr, |
| 394 | uh->source, saddr, dif))) { | 408 | uh->source, saddr, dif))) { |
| 395 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); | 409 | struct sk_buff *buff = skb_clone(skb, GFP_ATOMIC); |
| 396 | if (buff) { | 410 | if (buff) { |
diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c index 89884a4f23aa..60c78cfc2737 100644 --- a/net/ipv6/xfrm6_state.c +++ b/net/ipv6/xfrm6_state.c | |||
| @@ -34,6 +34,7 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl, | |||
| 34 | x->sel.dport_mask = htons(0xffff); | 34 | x->sel.dport_mask = htons(0xffff); |
| 35 | x->sel.sport = xfrm_flowi_sport(fl); | 35 | x->sel.sport = xfrm_flowi_sport(fl); |
| 36 | x->sel.sport_mask = htons(0xffff); | 36 | x->sel.sport_mask = htons(0xffff); |
| 37 | x->sel.family = AF_INET6; | ||
| 37 | x->sel.prefixlen_d = 128; | 38 | x->sel.prefixlen_d = 128; |
| 38 | x->sel.prefixlen_s = 128; | 39 | x->sel.prefixlen_s = 128; |
| 39 | x->sel.proto = fl->proto; | 40 | x->sel.proto = fl->proto; |
diff --git a/net/key/af_key.c b/net/key/af_key.c index e55e0441e4d9..3440a4637f01 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -2075,7 +2075,6 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in | |||
| 2075 | req_size += socklen * 2; | 2075 | req_size += socklen * 2; |
| 2076 | } else { | 2076 | } else { |
| 2077 | size -= 2*socklen; | 2077 | size -= 2*socklen; |
| 2078 | socklen = 0; | ||
| 2079 | } | 2078 | } |
| 2080 | rq = (void*)skb_put(skb, req_size); | 2079 | rq = (void*)skb_put(skb, req_size); |
| 2081 | pol->sadb_x_policy_len += req_size/8; | 2080 | pol->sadb_x_policy_len += req_size/8; |
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index 0b024cd6b809..98f480708050 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c | |||
| @@ -94,8 +94,8 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
| 94 | prob / 10, prob % 10, | 94 | prob / 10, prob % 10, |
| 95 | mr->last_success, | 95 | mr->last_success, |
| 96 | mr->last_attempts, | 96 | mr->last_attempts, |
| 97 | mr->succ_hist, | 97 | (unsigned long long)mr->succ_hist, |
| 98 | mr->att_hist); | 98 | (unsigned long long)mr->att_hist); |
| 99 | } | 99 | } |
| 100 | p += sprintf(p, "\nTotal packet count:: ideal %d " | 100 | p += sprintf(p, "\nTotal packet count:: ideal %d " |
| 101 | "lookaround %d\n\n", | 101 | "lookaround %d\n\n", |
| @@ -106,7 +106,7 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
| 106 | return 0; | 106 | return 0; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static int | 109 | static ssize_t |
| 110 | minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) | 110 | minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o) |
| 111 | { | 111 | { |
| 112 | struct minstrel_stats_info *ms; | 112 | struct minstrel_stats_info *ms; |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 9c06b9f86ad4..c39b6a994133 100644 --- a/net/netfilter/nf_conntrack_helper.c +++ b/net/netfilter/nf_conntrack_helper.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
| 23 | #include <linux/rculist.h> | 23 | #include <linux/rculist.h> |
| 24 | #include <linux/rtnetlink.h> | ||
| 24 | 25 | ||
| 25 | #include <net/netfilter/nf_conntrack.h> | 26 | #include <net/netfilter/nf_conntrack.h> |
| 26 | #include <net/netfilter/nf_conntrack_l3proto.h> | 27 | #include <net/netfilter/nf_conntrack_l3proto.h> |
| @@ -167,10 +168,12 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) | |||
| 167 | */ | 168 | */ |
| 168 | synchronize_rcu(); | 169 | synchronize_rcu(); |
| 169 | 170 | ||
| 171 | rtnl_lock(); | ||
| 170 | spin_lock_bh(&nf_conntrack_lock); | 172 | spin_lock_bh(&nf_conntrack_lock); |
| 171 | for_each_net(net) | 173 | for_each_net(net) |
| 172 | __nf_conntrack_helper_unregister(me, net); | 174 | __nf_conntrack_helper_unregister(me, net); |
| 173 | spin_unlock_bh(&nf_conntrack_lock); | 175 | spin_unlock_bh(&nf_conntrack_lock); |
| 176 | rtnl_unlock(); | ||
| 174 | } | 177 | } |
| 175 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); | 178 | EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); |
| 176 | 179 | ||
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index a59a307e685d..592d73344d46 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/notifier.h> | 22 | #include <linux/notifier.h> |
| 23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 24 | #include <linux/netdevice.h> | 24 | #include <linux/netdevice.h> |
| 25 | #include <linux/rtnetlink.h> | ||
| 25 | 26 | ||
| 26 | #include <net/netfilter/nf_conntrack.h> | 27 | #include <net/netfilter/nf_conntrack.h> |
| 27 | #include <net/netfilter/nf_conntrack_l3proto.h> | 28 | #include <net/netfilter/nf_conntrack_l3proto.h> |
| @@ -221,8 +222,10 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) | |||
| 221 | synchronize_rcu(); | 222 | synchronize_rcu(); |
| 222 | 223 | ||
| 223 | /* Remove all contrack entries for this protocol */ | 224 | /* Remove all contrack entries for this protocol */ |
| 225 | rtnl_lock(); | ||
| 224 | for_each_net(net) | 226 | for_each_net(net) |
| 225 | nf_ct_iterate_cleanup(net, kill_l3proto, proto); | 227 | nf_ct_iterate_cleanup(net, kill_l3proto, proto); |
| 228 | rtnl_unlock(); | ||
| 226 | } | 229 | } |
| 227 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); | 230 | EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); |
| 228 | 231 | ||
| @@ -333,8 +336,10 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) | |||
| 333 | synchronize_rcu(); | 336 | synchronize_rcu(); |
| 334 | 337 | ||
| 335 | /* Remove all contrack entries for this protocol */ | 338 | /* Remove all contrack entries for this protocol */ |
| 339 | rtnl_lock(); | ||
| 336 | for_each_net(net) | 340 | for_each_net(net) |
| 337 | nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); | 341 | nf_ct_iterate_cleanup(net, kill_l4proto, l4proto); |
| 342 | rtnl_unlock(); | ||
| 338 | } | 343 | } |
| 339 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); | 344 | EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); |
| 340 | 345 | ||
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index a2cdbcbf64c4..4ab62ad85dd4 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c | |||
| @@ -335,7 +335,7 @@ static int __init nf_ct_proto_gre_init(void) | |||
| 335 | rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); | 335 | rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); |
| 336 | if (rv < 0) | 336 | if (rv < 0) |
| 337 | return rv; | 337 | return rv; |
| 338 | rv = register_pernet_gen_device(&proto_gre_net_id, &proto_gre_net_ops); | 338 | rv = register_pernet_gen_subsys(&proto_gre_net_id, &proto_gre_net_ops); |
| 339 | if (rv < 0) | 339 | if (rv < 0) |
| 340 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); | 340 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); |
| 341 | return rv; | 341 | return rv; |
| @@ -344,7 +344,7 @@ static int __init nf_ct_proto_gre_init(void) | |||
| 344 | static void nf_ct_proto_gre_fini(void) | 344 | static void nf_ct_proto_gre_fini(void) |
| 345 | { | 345 | { |
| 346 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); | 346 | nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); |
| 347 | unregister_pernet_gen_device(proto_gre_net_id, &proto_gre_net_ops); | 347 | unregister_pernet_gen_subsys(proto_gre_net_id, &proto_gre_net_ops); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | module_init(nf_ct_proto_gre_init); | 350 | module_init(nf_ct_proto_gre_init); |
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c index b0925a303353..249f6b92f153 100644 --- a/net/netlabel/netlabel_addrlist.c +++ b/net/netlabel/netlabel_addrlist.c | |||
| @@ -315,6 +315,7 @@ struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr, | |||
| 315 | * Audit Helper Functions | 315 | * Audit Helper Functions |
| 316 | */ | 316 | */ |
| 317 | 317 | ||
| 318 | #ifdef CONFIG_AUDIT | ||
| 318 | /** | 319 | /** |
| 319 | * netlbl_af4list_audit_addr - Audit an IPv4 address | 320 | * netlbl_af4list_audit_addr - Audit an IPv4 address |
| 320 | * @audit_buf: audit buffer | 321 | * @audit_buf: audit buffer |
| @@ -386,3 +387,4 @@ void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, | |||
| 386 | } | 387 | } |
| 387 | } | 388 | } |
| 388 | #endif /* IPv6 */ | 389 | #endif /* IPv6 */ |
| 390 | #endif /* CONFIG_AUDIT */ | ||
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 0242bead405f..07ae7fd82be1 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h | |||
| @@ -120,9 +120,19 @@ struct netlbl_af4list *netlbl_af4list_search(__be32 addr, | |||
| 120 | struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, | 120 | struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr, |
| 121 | __be32 mask, | 121 | __be32 mask, |
| 122 | struct list_head *head); | 122 | struct list_head *head); |
| 123 | |||
| 124 | #ifdef CONFIG_AUDIT | ||
| 123 | void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, | 125 | void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, |
| 124 | int src, const char *dev, | 126 | int src, const char *dev, |
| 125 | __be32 addr, __be32 mask); | 127 | __be32 addr, __be32 mask); |
| 128 | #else | ||
| 129 | static inline void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf, | ||
| 130 | int src, const char *dev, | ||
| 131 | __be32 addr, __be32 mask) | ||
| 132 | { | ||
| 133 | return; | ||
| 134 | } | ||
| 135 | #endif | ||
| 126 | 136 | ||
| 127 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | 137 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) |
| 128 | 138 | ||
| @@ -179,11 +189,23 @@ struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr, | |||
| 179 | struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, | 189 | struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr, |
| 180 | const struct in6_addr *mask, | 190 | const struct in6_addr *mask, |
| 181 | struct list_head *head); | 191 | struct list_head *head); |
| 192 | |||
| 193 | #ifdef CONFIG_AUDIT | ||
| 182 | void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, | 194 | void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, |
| 183 | int src, | 195 | int src, |
| 184 | const char *dev, | 196 | const char *dev, |
| 185 | const struct in6_addr *addr, | 197 | const struct in6_addr *addr, |
| 186 | const struct in6_addr *mask); | 198 | const struct in6_addr *mask); |
| 199 | #else | ||
| 200 | static inline void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf, | ||
| 201 | int src, | ||
| 202 | const char *dev, | ||
| 203 | const struct in6_addr *addr, | ||
| 204 | const struct in6_addr *mask) | ||
| 205 | { | ||
| 206 | return; | ||
| 207 | } | ||
| 208 | #endif | ||
| 187 | #endif /* IPV6 */ | 209 | #endif /* IPV6 */ |
| 188 | 210 | ||
| 189 | #endif | 211 | #endif |
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index ee769ecaa13c..0a0ef17b2a40 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
| @@ -265,7 +265,7 @@ add_failure: | |||
| 265 | static int netlbl_mgmt_listentry(struct sk_buff *skb, | 265 | static int netlbl_mgmt_listentry(struct sk_buff *skb, |
| 266 | struct netlbl_dom_map *entry) | 266 | struct netlbl_dom_map *entry) |
| 267 | { | 267 | { |
| 268 | int ret_val; | 268 | int ret_val = 0; |
| 269 | struct nlattr *nla_a; | 269 | struct nlattr *nla_a; |
| 270 | struct nlattr *nla_b; | 270 | struct nlattr *nla_b; |
| 271 | struct netlbl_af4list *iter4; | 271 | struct netlbl_af4list *iter4; |
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index b9d97effebe3..defeb7a0d502 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c | |||
| @@ -261,6 +261,8 @@ static inline int can_respond(struct sk_buff *skb) | |||
| 261 | return 0; /* we are not the destination */ | 261 | return 0; /* we are not the destination */ |
| 262 | if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5)) | 262 | if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5)) |
| 263 | return 0; | 263 | return 0; |
| 264 | if (ph->pn_res == PN_COMMGR) /* indications */ | ||
| 265 | return 0; | ||
| 264 | 266 | ||
| 265 | ph = pn_hdr(skb); /* re-acquires the pointer */ | 267 | ph = pn_hdr(skb); /* re-acquires the pointer */ |
| 266 | pm = pn_msg(skb); | 268 | pm = pn_msg(skb); |
| @@ -309,7 +311,8 @@ static int send_reset_indications(struct sk_buff *rskb) | |||
| 309 | 311 | ||
| 310 | return pn_raw_send(data, sizeof(data), rskb->dev, | 312 | return pn_raw_send(data, sizeof(data), rskb->dev, |
| 311 | pn_object(oph->pn_sdev, 0x00), | 313 | pn_object(oph->pn_sdev, 0x00), |
| 312 | pn_object(oph->pn_rdev, oph->pn_robj), 0x10); | 314 | pn_object(oph->pn_rdev, oph->pn_robj), |
| 315 | PN_COMMGR); | ||
| 313 | } | 316 | } |
| 314 | 317 | ||
| 315 | 318 | ||
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c index 21124ec0a73d..bfdade72e066 100644 --- a/net/rfkill/rfkill-input.c +++ b/net/rfkill/rfkill-input.c | |||
| @@ -256,6 +256,11 @@ static struct input_handler rfkill_handler = { | |||
| 256 | 256 | ||
| 257 | static int __init rfkill_handler_init(void) | 257 | static int __init rfkill_handler_init(void) |
| 258 | { | 258 | { |
| 259 | unsigned long last_run = jiffies - msecs_to_jiffies(500); | ||
| 260 | rfkill_wlan.last = last_run; | ||
| 261 | rfkill_bt.last = last_run; | ||
| 262 | rfkill_uwb.last = last_run; | ||
| 263 | rfkill_wimax.last = last_run; | ||
| 259 | return input_register_handler(&rfkill_handler); | 264 | return input_register_handler(&rfkill_handler); |
| 260 | } | 265 | } |
| 261 | 266 | ||
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index f949a482b007..25ba3bd57e66 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
| @@ -603,7 +603,7 @@ static int rfkill_check_duplicity(const struct rfkill *rfkill) | |||
| 603 | } | 603 | } |
| 604 | 604 | ||
| 605 | /* 0: first switch of its kind */ | 605 | /* 0: first switch of its kind */ |
| 606 | return test_bit(rfkill->type, seen); | 606 | return (test_bit(rfkill->type, seen)) ? 1 : 0; |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | static int rfkill_add_switch(struct rfkill *rfkill) | 609 | static int rfkill_add_switch(struct rfkill *rfkill) |
diff --git a/net/socket.c b/net/socket.c index 2b7a4b5c9b72..57550c3bcabe 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -990,7 +990,6 @@ static int sock_close(struct inode *inode, struct file *filp) | |||
| 990 | printk(KERN_DEBUG "sock_close: NULL inode\n"); | 990 | printk(KERN_DEBUG "sock_close: NULL inode\n"); |
| 991 | return 0; | 991 | return 0; |
| 992 | } | 992 | } |
| 993 | sock_fasync(-1, filp, 0); | ||
| 994 | sock_release(SOCKET_I(inode)); | 993 | sock_release(SOCKET_I(inode)); |
| 995 | return 0; | 994 | return 0; |
| 996 | } | 995 | } |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 436bf1b4b76c..cb216b2df666 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -228,19 +228,21 @@ static int | |||
| 228 | rpcauth_prune_expired(struct list_head *free, int nr_to_scan) | 228 | rpcauth_prune_expired(struct list_head *free, int nr_to_scan) |
| 229 | { | 229 | { |
| 230 | spinlock_t *cache_lock; | 230 | spinlock_t *cache_lock; |
| 231 | struct rpc_cred *cred; | 231 | struct rpc_cred *cred, *next; |
| 232 | unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; | 232 | unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; |
| 233 | 233 | ||
| 234 | while (!list_empty(&cred_unused)) { | 234 | list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { |
| 235 | cred = list_entry(cred_unused.next, struct rpc_cred, cr_lru); | 235 | |
| 236 | /* Enforce a 60 second garbage collection moratorium */ | ||
| 237 | if (time_in_range(cred->cr_expire, expired, jiffies) && | ||
| 238 | test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) | ||
| 239 | continue; | ||
| 240 | |||
| 236 | list_del_init(&cred->cr_lru); | 241 | list_del_init(&cred->cr_lru); |
| 237 | number_cred_unused--; | 242 | number_cred_unused--; |
| 238 | if (atomic_read(&cred->cr_count) != 0) | 243 | if (atomic_read(&cred->cr_count) != 0) |
| 239 | continue; | 244 | continue; |
| 240 | /* Enforce a 5 second garbage collection moratorium */ | 245 | |
| 241 | if (time_in_range(cred->cr_expire, expired, jiffies) && | ||
| 242 | test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) | ||
| 243 | continue; | ||
| 244 | cache_lock = &cred->cr_auth->au_credcache->lock; | 246 | cache_lock = &cred->cr_auth->au_credcache->lock; |
| 245 | spin_lock(cache_lock); | 247 | spin_lock(cache_lock); |
| 246 | if (atomic_read(&cred->cr_count) == 0) { | 248 | if (atomic_read(&cred->cr_count) == 0) { |
| @@ -453,7 +455,7 @@ need_lock: | |||
| 453 | } | 455 | } |
| 454 | if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) | 456 | if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) |
| 455 | rpcauth_unhash_cred(cred); | 457 | rpcauth_unhash_cred(cred); |
| 456 | else if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { | 458 | if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { |
| 457 | cred->cr_expire = jiffies; | 459 | cred->cr_expire = jiffies; |
| 458 | list_add_tail(&cred->cr_lru, &cred_unused); | 460 | list_add_tail(&cred->cr_lru, &cred_unused); |
| 459 | number_cred_unused++; | 461 | number_cred_unused++; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 9a288d5eea64..0a50361e3d83 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -249,6 +249,7 @@ struct sock_xprt { | |||
| 249 | void (*old_data_ready)(struct sock *, int); | 249 | void (*old_data_ready)(struct sock *, int); |
| 250 | void (*old_state_change)(struct sock *); | 250 | void (*old_state_change)(struct sock *); |
| 251 | void (*old_write_space)(struct sock *); | 251 | void (*old_write_space)(struct sock *); |
| 252 | void (*old_error_report)(struct sock *); | ||
| 252 | }; | 253 | }; |
| 253 | 254 | ||
| 254 | /* | 255 | /* |
| @@ -698,8 +699,9 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
| 698 | case -EAGAIN: | 699 | case -EAGAIN: |
| 699 | xs_nospace(task); | 700 | xs_nospace(task); |
| 700 | break; | 701 | break; |
| 701 | case -ECONNREFUSED: | ||
| 702 | case -ECONNRESET: | 702 | case -ECONNRESET: |
| 703 | xs_tcp_shutdown(xprt); | ||
| 704 | case -ECONNREFUSED: | ||
| 703 | case -ENOTCONN: | 705 | case -ENOTCONN: |
| 704 | case -EPIPE: | 706 | case -EPIPE: |
| 705 | status = -ENOTCONN; | 707 | status = -ENOTCONN; |
| @@ -742,6 +744,22 @@ out_release: | |||
| 742 | xprt_release_xprt(xprt, task); | 744 | xprt_release_xprt(xprt, task); |
| 743 | } | 745 | } |
| 744 | 746 | ||
| 747 | static void xs_save_old_callbacks(struct sock_xprt *transport, struct sock *sk) | ||
| 748 | { | ||
| 749 | transport->old_data_ready = sk->sk_data_ready; | ||
| 750 | transport->old_state_change = sk->sk_state_change; | ||
| 751 | transport->old_write_space = sk->sk_write_space; | ||
| 752 | transport->old_error_report = sk->sk_error_report; | ||
| 753 | } | ||
| 754 | |||
| 755 | static void xs_restore_old_callbacks(struct sock_xprt *transport, struct sock *sk) | ||
| 756 | { | ||
| 757 | sk->sk_data_ready = transport->old_data_ready; | ||
| 758 | sk->sk_state_change = transport->old_state_change; | ||
| 759 | sk->sk_write_space = transport->old_write_space; | ||
| 760 | sk->sk_error_report = transport->old_error_report; | ||
| 761 | } | ||
| 762 | |||
| 745 | /** | 763 | /** |
| 746 | * xs_close - close a socket | 764 | * xs_close - close a socket |
| 747 | * @xprt: transport | 765 | * @xprt: transport |
| @@ -765,9 +783,8 @@ static void xs_close(struct rpc_xprt *xprt) | |||
| 765 | transport->sock = NULL; | 783 | transport->sock = NULL; |
| 766 | 784 | ||
| 767 | sk->sk_user_data = NULL; | 785 | sk->sk_user_data = NULL; |
| 768 | sk->sk_data_ready = transport->old_data_ready; | 786 | |
| 769 | sk->sk_state_change = transport->old_state_change; | 787 | xs_restore_old_callbacks(transport, sk); |
| 770 | sk->sk_write_space = transport->old_write_space; | ||
| 771 | write_unlock_bh(&sk->sk_callback_lock); | 788 | write_unlock_bh(&sk->sk_callback_lock); |
| 772 | 789 | ||
| 773 | sk->sk_no_check = 0; | 790 | sk->sk_no_check = 0; |
| @@ -1180,6 +1197,28 @@ static void xs_tcp_state_change(struct sock *sk) | |||
| 1180 | } | 1197 | } |
| 1181 | 1198 | ||
| 1182 | /** | 1199 | /** |
| 1200 | * xs_tcp_error_report - callback mainly for catching RST events | ||
| 1201 | * @sk: socket | ||
| 1202 | */ | ||
| 1203 | static void xs_tcp_error_report(struct sock *sk) | ||
| 1204 | { | ||
| 1205 | struct rpc_xprt *xprt; | ||
| 1206 | |||
| 1207 | read_lock(&sk->sk_callback_lock); | ||
| 1208 | if (sk->sk_err != ECONNRESET || sk->sk_state != TCP_ESTABLISHED) | ||
| 1209 | goto out; | ||
| 1210 | if (!(xprt = xprt_from_sock(sk))) | ||
| 1211 | goto out; | ||
| 1212 | dprintk("RPC: %s client %p...\n" | ||
| 1213 | "RPC: error %d\n", | ||
| 1214 | __func__, xprt, sk->sk_err); | ||
| 1215 | |||
| 1216 | xprt_force_disconnect(xprt); | ||
| 1217 | out: | ||
| 1218 | read_unlock(&sk->sk_callback_lock); | ||
| 1219 | } | ||
| 1220 | |||
| 1221 | /** | ||
| 1183 | * xs_udp_write_space - callback invoked when socket buffer space | 1222 | * xs_udp_write_space - callback invoked when socket buffer space |
| 1184 | * becomes available | 1223 | * becomes available |
| 1185 | * @sk: socket whose state has changed | 1224 | * @sk: socket whose state has changed |
| @@ -1454,10 +1493,9 @@ static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
| 1454 | 1493 | ||
| 1455 | write_lock_bh(&sk->sk_callback_lock); | 1494 | write_lock_bh(&sk->sk_callback_lock); |
| 1456 | 1495 | ||
| 1496 | xs_save_old_callbacks(transport, sk); | ||
| 1497 | |||
| 1457 | sk->sk_user_data = xprt; | 1498 | sk->sk_user_data = xprt; |
| 1458 | transport->old_data_ready = sk->sk_data_ready; | ||
| 1459 | transport->old_state_change = sk->sk_state_change; | ||
| 1460 | transport->old_write_space = sk->sk_write_space; | ||
| 1461 | sk->sk_data_ready = xs_udp_data_ready; | 1499 | sk->sk_data_ready = xs_udp_data_ready; |
| 1462 | sk->sk_write_space = xs_udp_write_space; | 1500 | sk->sk_write_space = xs_udp_write_space; |
| 1463 | sk->sk_no_check = UDP_CSUM_NORCV; | 1501 | sk->sk_no_check = UDP_CSUM_NORCV; |
| @@ -1589,13 +1627,13 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
| 1589 | 1627 | ||
| 1590 | write_lock_bh(&sk->sk_callback_lock); | 1628 | write_lock_bh(&sk->sk_callback_lock); |
| 1591 | 1629 | ||
| 1630 | xs_save_old_callbacks(transport, sk); | ||
| 1631 | |||
| 1592 | sk->sk_user_data = xprt; | 1632 | sk->sk_user_data = xprt; |
| 1593 | transport->old_data_ready = sk->sk_data_ready; | ||
| 1594 | transport->old_state_change = sk->sk_state_change; | ||
| 1595 | transport->old_write_space = sk->sk_write_space; | ||
| 1596 | sk->sk_data_ready = xs_tcp_data_ready; | 1633 | sk->sk_data_ready = xs_tcp_data_ready; |
| 1597 | sk->sk_state_change = xs_tcp_state_change; | 1634 | sk->sk_state_change = xs_tcp_state_change; |
| 1598 | sk->sk_write_space = xs_tcp_write_space; | 1635 | sk->sk_write_space = xs_tcp_write_space; |
| 1636 | sk->sk_error_report = xs_tcp_error_report; | ||
| 1599 | sk->sk_allocation = GFP_ATOMIC; | 1637 | sk->sk_allocation = GFP_ATOMIC; |
| 1600 | 1638 | ||
| 1601 | /* socket options */ | 1639 | /* socket options */ |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index dc504d308ec0..eb90f77bb0e2 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
| @@ -1302,14 +1302,23 @@ static void unix_destruct_fds(struct sk_buff *skb) | |||
| 1302 | sock_wfree(skb); | 1302 | sock_wfree(skb); |
| 1303 | } | 1303 | } |
| 1304 | 1304 | ||
| 1305 | static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1305 | static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) |
| 1306 | { | 1306 | { |
| 1307 | int i; | 1307 | int i; |
| 1308 | |||
| 1309 | /* | ||
| 1310 | * Need to duplicate file references for the sake of garbage | ||
| 1311 | * collection. Otherwise a socket in the fps might become a | ||
| 1312 | * candidate for GC while the skb is not yet queued. | ||
| 1313 | */ | ||
| 1314 | UNIXCB(skb).fp = scm_fp_dup(scm->fp); | ||
| 1315 | if (!UNIXCB(skb).fp) | ||
| 1316 | return -ENOMEM; | ||
| 1317 | |||
| 1308 | for (i=scm->fp->count-1; i>=0; i--) | 1318 | for (i=scm->fp->count-1; i>=0; i--) |
| 1309 | unix_inflight(scm->fp->fp[i]); | 1319 | unix_inflight(scm->fp->fp[i]); |
| 1310 | UNIXCB(skb).fp = scm->fp; | ||
| 1311 | skb->destructor = unix_destruct_fds; | 1320 | skb->destructor = unix_destruct_fds; |
| 1312 | scm->fp = NULL; | 1321 | return 0; |
| 1313 | } | 1322 | } |
| 1314 | 1323 | ||
| 1315 | /* | 1324 | /* |
| @@ -1368,8 +1377,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1368 | goto out; | 1377 | goto out; |
| 1369 | 1378 | ||
| 1370 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1379 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
| 1371 | if (siocb->scm->fp) | 1380 | if (siocb->scm->fp) { |
| 1372 | unix_attach_fds(siocb->scm, skb); | 1381 | err = unix_attach_fds(siocb->scm, skb); |
| 1382 | if (err) | ||
| 1383 | goto out_free; | ||
| 1384 | } | ||
| 1373 | unix_get_secdata(siocb->scm, skb); | 1385 | unix_get_secdata(siocb->scm, skb); |
| 1374 | 1386 | ||
| 1375 | skb_reset_transport_header(skb); | 1387 | skb_reset_transport_header(skb); |
| @@ -1538,8 +1550,13 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
| 1538 | size = min_t(int, size, skb_tailroom(skb)); | 1550 | size = min_t(int, size, skb_tailroom(skb)); |
| 1539 | 1551 | ||
| 1540 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); | 1552 | memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); |
| 1541 | if (siocb->scm->fp) | 1553 | if (siocb->scm->fp) { |
| 1542 | unix_attach_fds(siocb->scm, skb); | 1554 | err = unix_attach_fds(siocb->scm, skb); |
| 1555 | if (err) { | ||
| 1556 | kfree_skb(skb); | ||
| 1557 | goto out_err; | ||
| 1558 | } | ||
| 1559 | } | ||
| 1543 | 1560 | ||
| 1544 | if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { | 1561 | if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { |
| 1545 | kfree_skb(skb); | 1562 | kfree_skb(skb); |
| @@ -2213,7 +2230,7 @@ static int unix_net_init(struct net *net) | |||
| 2213 | #endif | 2230 | #endif |
| 2214 | error = 0; | 2231 | error = 0; |
| 2215 | out: | 2232 | out: |
| 2216 | return 0; | 2233 | return error; |
| 2217 | } | 2234 | } |
| 2218 | 2235 | ||
| 2219 | static void unix_net_exit(struct net *net) | 2236 | static void unix_net_exit(struct net *net) |
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 2a27b84f740b..6d4a9a8de5ef 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
| @@ -186,8 +186,17 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), | |||
| 186 | */ | 186 | */ |
| 187 | struct sock *sk = unix_get_socket(*fp++); | 187 | struct sock *sk = unix_get_socket(*fp++); |
| 188 | if (sk) { | 188 | if (sk) { |
| 189 | hit = true; | 189 | struct unix_sock *u = unix_sk(sk); |
| 190 | func(unix_sk(sk)); | 190 | |
| 191 | /* | ||
| 192 | * Ignore non-candidates, they could | ||
| 193 | * have been added to the queues after | ||
| 194 | * starting the garbage collection | ||
| 195 | */ | ||
| 196 | if (u->gc_candidate) { | ||
| 197 | hit = true; | ||
| 198 | func(u); | ||
| 199 | } | ||
| 191 | } | 200 | } |
| 192 | } | 201 | } |
| 193 | if (hit && hitlist != NULL) { | 202 | if (hit && hitlist != NULL) { |
| @@ -249,11 +258,11 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
| 249 | { | 258 | { |
| 250 | atomic_long_inc(&u->inflight); | 259 | atomic_long_inc(&u->inflight); |
| 251 | /* | 260 | /* |
| 252 | * If this is still a candidate, move it to the end of the | 261 | * If this still might be part of a cycle, move it to the end |
| 253 | * list, so that it's checked even if it was already passed | 262 | * of the list, so that it's checked even if it was already |
| 254 | * over | 263 | * passed over |
| 255 | */ | 264 | */ |
| 256 | if (u->gc_candidate) | 265 | if (u->gc_maybe_cycle) |
| 257 | list_move_tail(&u->link, &gc_candidates); | 266 | list_move_tail(&u->link, &gc_candidates); |
| 258 | } | 267 | } |
| 259 | 268 | ||
| @@ -267,6 +276,7 @@ void unix_gc(void) | |||
| 267 | struct unix_sock *next; | 276 | struct unix_sock *next; |
| 268 | struct sk_buff_head hitlist; | 277 | struct sk_buff_head hitlist; |
| 269 | struct list_head cursor; | 278 | struct list_head cursor; |
| 279 | LIST_HEAD(not_cycle_list); | ||
| 270 | 280 | ||
| 271 | spin_lock(&unix_gc_lock); | 281 | spin_lock(&unix_gc_lock); |
| 272 | 282 | ||
| @@ -282,10 +292,14 @@ void unix_gc(void) | |||
| 282 | * | 292 | * |
| 283 | * Holding unix_gc_lock will protect these candidates from | 293 | * Holding unix_gc_lock will protect these candidates from |
| 284 | * being detached, and hence from gaining an external | 294 | * being detached, and hence from gaining an external |
| 285 | * reference. This also means, that since there are no | 295 | * reference. Since there are no possible receivers, all |
| 286 | * possible receivers, the receive queues of these sockets are | 296 | * buffers currently on the candidates' queues stay there |
| 287 | * static during the GC, even though the dequeue is done | 297 | * during the garbage collection. |
| 288 | * before the detach without atomicity guarantees. | 298 | * |
| 299 | * We also know that no new candidate can be added onto the | ||
| 300 | * receive queues. Other, non candidate sockets _can_ be | ||
| 301 | * added to queue, so we must make sure only to touch | ||
| 302 | * candidates. | ||
| 289 | */ | 303 | */ |
| 290 | list_for_each_entry_safe(u, next, &gc_inflight_list, link) { | 304 | list_for_each_entry_safe(u, next, &gc_inflight_list, link) { |
| 291 | long total_refs; | 305 | long total_refs; |
| @@ -299,6 +313,7 @@ void unix_gc(void) | |||
| 299 | if (total_refs == inflight_refs) { | 313 | if (total_refs == inflight_refs) { |
| 300 | list_move_tail(&u->link, &gc_candidates); | 314 | list_move_tail(&u->link, &gc_candidates); |
| 301 | u->gc_candidate = 1; | 315 | u->gc_candidate = 1; |
| 316 | u->gc_maybe_cycle = 1; | ||
| 302 | } | 317 | } |
| 303 | } | 318 | } |
| 304 | 319 | ||
| @@ -325,14 +340,24 @@ void unix_gc(void) | |||
| 325 | list_move(&cursor, &u->link); | 340 | list_move(&cursor, &u->link); |
| 326 | 341 | ||
| 327 | if (atomic_long_read(&u->inflight) > 0) { | 342 | if (atomic_long_read(&u->inflight) > 0) { |
| 328 | list_move_tail(&u->link, &gc_inflight_list); | 343 | list_move_tail(&u->link, ¬_cycle_list); |
| 329 | u->gc_candidate = 0; | 344 | u->gc_maybe_cycle = 0; |
| 330 | scan_children(&u->sk, inc_inflight_move_tail, NULL); | 345 | scan_children(&u->sk, inc_inflight_move_tail, NULL); |
| 331 | } | 346 | } |
| 332 | } | 347 | } |
| 333 | list_del(&cursor); | 348 | list_del(&cursor); |
| 334 | 349 | ||
| 335 | /* | 350 | /* |
| 351 | * not_cycle_list contains those sockets which do not make up a | ||
| 352 | * cycle. Restore these to the inflight list. | ||
| 353 | */ | ||
| 354 | while (!list_empty(¬_cycle_list)) { | ||
| 355 | u = list_entry(not_cycle_list.next, struct unix_sock, link); | ||
| 356 | u->gc_candidate = 0; | ||
| 357 | list_move_tail(&u->link, &gc_inflight_list); | ||
| 358 | } | ||
| 359 | |||
| 360 | /* | ||
| 336 | * Now gc_candidates contains only garbage. Restore original | 361 | * Now gc_candidates contains only garbage. Restore original |
| 337 | * inflight counters for these as well, and remove the skbuffs | 362 | * inflight counters for these as well, and remove the skbuffs |
| 338 | * which are creating the cycle(s). | 363 | * which are creating the cycle(s). |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 832b47c1de80..058f04f54b90 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -315,9 +315,9 @@ static void xfrm_policy_kill(struct xfrm_policy *policy) | |||
| 315 | return; | 315 | return; |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | spin_lock(&xfrm_policy_gc_lock); | 318 | spin_lock_bh(&xfrm_policy_gc_lock); |
| 319 | hlist_add_head(&policy->bydst, &xfrm_policy_gc_list); | 319 | hlist_add_head(&policy->bydst, &xfrm_policy_gc_list); |
| 320 | spin_unlock(&xfrm_policy_gc_lock); | 320 | spin_unlock_bh(&xfrm_policy_gc_lock); |
| 321 | 321 | ||
| 322 | schedule_work(&xfrm_policy_gc_work); | 322 | schedule_work(&xfrm_policy_gc_work); |
| 323 | } | 323 | } |
| @@ -1251,6 +1251,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl, | |||
| 1251 | -EINVAL : -EAGAIN); | 1251 | -EINVAL : -EAGAIN); |
| 1252 | xfrm_state_put(x); | 1252 | xfrm_state_put(x); |
| 1253 | } | 1253 | } |
| 1254 | else if (error == -ESRCH) | ||
| 1255 | error = -EAGAIN; | ||
| 1254 | 1256 | ||
| 1255 | if (!tmpl->optional) | 1257 | if (!tmpl->optional) |
| 1256 | goto fail; | 1258 | goto fail; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 4a8a1abb59ee..a278a6f3b991 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -1816,7 +1816,7 @@ static int copy_to_user_kmaddress(struct xfrm_kmaddress *k, struct sk_buff *skb) | |||
| 1816 | uk.family = k->family; | 1816 | uk.family = k->family; |
| 1817 | uk.reserved = k->reserved; | 1817 | uk.reserved = k->reserved; |
| 1818 | memcpy(&uk.local, &k->local, sizeof(uk.local)); | 1818 | memcpy(&uk.local, &k->local, sizeof(uk.local)); |
| 1819 | memcpy(&uk.remote, &k->local, sizeof(uk.remote)); | 1819 | memcpy(&uk.remote, &k->remote, sizeof(uk.remote)); |
| 1820 | 1820 | ||
| 1821 | return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk); | 1821 | return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk); |
| 1822 | } | 1822 | } |
