diff options
Diffstat (limited to 'net')
36 files changed, 397 insertions, 132 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 916061f681b..68ced4bf158 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/8021q/vlanproc.c b/net/8021q/vlanproc.c index 0feefa4e1a4..3628e0a81b4 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c | |||
| @@ -314,7 +314,7 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset) | |||
| 314 | dev_info->ingress_priority_map[6], | 314 | dev_info->ingress_priority_map[6], |
| 315 | dev_info->ingress_priority_map[7]); | 315 | dev_info->ingress_priority_map[7]); |
| 316 | 316 | ||
| 317 | seq_printf(seq, "EGRESSS priority Mappings: "); | 317 | seq_printf(seq, " EGRESS priority mappings: "); |
| 318 | for (i = 0; i < 16; i++) { | 318 | for (i = 0; i < 16; i++) { |
| 319 | const struct vlan_priority_tci_mapping *mp | 319 | const struct vlan_priority_tci_mapping *mp |
| 320 | = dev_info->egress_priority_map[i]; | 320 | = dev_info->egress_priority_map[i]; |
diff --git a/net/9p/client.c b/net/9p/client.c index 67717f69412..4b529454616 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 8d6cc4777aa..2f1fe5fc122 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 d9038e328cc..9174c77d311 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 f1d07b5c1e1..1895a4ca9c4 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/scm.c b/net/core/scm.c index 10f5c65f6a4..ab242cc1acc 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 4e22e3a3535..d49ef8301b5 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; |
| @@ -474,8 +486,8 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
| 474 | shinfo->frag_list = NULL; | 486 | shinfo->frag_list = NULL; |
| 475 | 487 | ||
| 476 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 488 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
| 477 | skb_reset_tail_pointer(skb); | ||
| 478 | skb->data = skb->head + NET_SKB_PAD; | 489 | skb->data = skb->head + NET_SKB_PAD; |
| 490 | skb_reset_tail_pointer(skb); | ||
| 479 | 491 | ||
| 480 | return 1; | 492 | return 1; |
| 481 | } | 493 | } |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 37616884b8a..1af5a79309e 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
| 12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
| 13 | #include <linux/etherdevice.h> | ||
| 13 | #include <linux/phy.h> | 14 | #include <linux/phy.h> |
| 14 | #include "dsa_priv.h" | 15 | #include "dsa_priv.h" |
| 15 | 16 | ||
| @@ -49,11 +50,57 @@ void dsa_slave_mii_bus_init(struct dsa_switch *ds) | |||
| 49 | /* slave device handling ****************************************************/ | 50 | /* slave device handling ****************************************************/ |
| 50 | static int dsa_slave_open(struct net_device *dev) | 51 | static int dsa_slave_open(struct net_device *dev) |
| 51 | { | 52 | { |
| 53 | struct dsa_slave_priv *p = netdev_priv(dev); | ||
| 54 | struct net_device *master = p->parent->master_netdev; | ||
| 55 | int err; | ||
| 56 | |||
| 57 | if (!(master->flags & IFF_UP)) | ||
| 58 | return -ENETDOWN; | ||
| 59 | |||
| 60 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { | ||
| 61 | err = dev_unicast_add(master, dev->dev_addr, ETH_ALEN); | ||
| 62 | if (err < 0) | ||
| 63 | goto out; | ||
| 64 | } | ||
| 65 | |||
| 66 | if (dev->flags & IFF_ALLMULTI) { | ||
| 67 | err = dev_set_allmulti(master, 1); | ||
| 68 | if (err < 0) | ||
| 69 | goto del_unicast; | ||
| 70 | } | ||
| 71 | if (dev->flags & IFF_PROMISC) { | ||
| 72 | err = dev_set_promiscuity(master, 1); | ||
| 73 | if (err < 0) | ||
| 74 | goto clear_allmulti; | ||
| 75 | } | ||
| 76 | |||
| 52 | return 0; | 77 | return 0; |
| 78 | |||
| 79 | clear_allmulti: | ||
| 80 | if (dev->flags & IFF_ALLMULTI) | ||
| 81 | dev_set_allmulti(master, -1); | ||
| 82 | del_unicast: | ||
| 83 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | ||
| 84 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | ||
| 85 | out: | ||
| 86 | return err; | ||
| 53 | } | 87 | } |
| 54 | 88 | ||
| 55 | static int dsa_slave_close(struct net_device *dev) | 89 | static int dsa_slave_close(struct net_device *dev) |
| 56 | { | 90 | { |
| 91 | struct dsa_slave_priv *p = netdev_priv(dev); | ||
| 92 | struct net_device *master = p->parent->master_netdev; | ||
| 93 | |||
| 94 | dev_mc_unsync(master, dev); | ||
| 95 | dev_unicast_unsync(master, dev); | ||
| 96 | if (dev->flags & IFF_ALLMULTI) | ||
| 97 | dev_set_allmulti(master, -1); | ||
| 98 | if (dev->flags & IFF_PROMISC) | ||
| 99 | dev_set_promiscuity(master, -1); | ||
| 100 | |||
| 101 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | ||
| 102 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | ||
| 103 | |||
| 57 | return 0; | 104 | return 0; |
| 58 | } | 105 | } |
| 59 | 106 | ||
| @@ -77,9 +124,30 @@ static void dsa_slave_set_rx_mode(struct net_device *dev) | |||
| 77 | dev_unicast_sync(master, dev); | 124 | dev_unicast_sync(master, dev); |
| 78 | } | 125 | } |
| 79 | 126 | ||
| 80 | static int dsa_slave_set_mac_address(struct net_device *dev, void *addr) | 127 | static int dsa_slave_set_mac_address(struct net_device *dev, void *a) |
| 81 | { | 128 | { |
| 82 | memcpy(dev->dev_addr, addr + 2, 6); | 129 | struct dsa_slave_priv *p = netdev_priv(dev); |
| 130 | struct net_device *master = p->parent->master_netdev; | ||
| 131 | struct sockaddr *addr = a; | ||
| 132 | int err; | ||
| 133 | |||
| 134 | if (!is_valid_ether_addr(addr->sa_data)) | ||
| 135 | return -EADDRNOTAVAIL; | ||
| 136 | |||
| 137 | if (!(dev->flags & IFF_UP)) | ||
| 138 | goto out; | ||
| 139 | |||
| 140 | if (compare_ether_addr(addr->sa_data, master->dev_addr)) { | ||
| 141 | err = dev_unicast_add(master, addr->sa_data, ETH_ALEN); | ||
| 142 | if (err < 0) | ||
| 143 | return err; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | ||
| 147 | dev_unicast_delete(master, dev->dev_addr, ETH_ALEN); | ||
| 148 | |||
| 149 | out: | ||
| 150 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | ||
| 83 | 151 | ||
| 84 | return 0; | 152 | return 0; |
| 85 | } | 153 | } |
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index bdc0510b53b..31866543332 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c | |||
| @@ -159,6 +159,7 @@ static int dsa_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 159 | 159 | ||
| 160 | skb->dev = ds->ports[source_port]; | 160 | skb->dev = ds->ports[source_port]; |
| 161 | skb_push(skb, ETH_HLEN); | 161 | skb_push(skb, ETH_HLEN); |
| 162 | skb->pkt_type = PACKET_HOST; | ||
| 162 | skb->protocol = eth_type_trans(skb, skb->dev); | 163 | skb->protocol = eth_type_trans(skb, skb->dev); |
| 163 | 164 | ||
| 164 | skb->dev->last_rx = jiffies; | 165 | skb->dev->last_rx = jiffies; |
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c index f985ea99384..9f4ce55eae5 100644 --- a/net/dsa/tag_edsa.c +++ b/net/dsa/tag_edsa.c | |||
| @@ -178,6 +178,7 @@ static int edsa_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 178 | 178 | ||
| 179 | skb->dev = ds->ports[source_port]; | 179 | skb->dev = ds->ports[source_port]; |
| 180 | skb_push(skb, ETH_HLEN); | 180 | skb_push(skb, ETH_HLEN); |
| 181 | skb->pkt_type = PACKET_HOST; | ||
| 181 | skb->protocol = eth_type_trans(skb, skb->dev); | 182 | skb->protocol = eth_type_trans(skb, skb->dev); |
| 182 | 183 | ||
| 183 | skb->dev->last_rx = jiffies; | 184 | skb->dev->last_rx = jiffies; |
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c index d3117764b2c..efd26697e71 100644 --- a/net/dsa/tag_trailer.c +++ b/net/dsa/tag_trailer.c | |||
| @@ -95,6 +95,7 @@ static int trailer_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 95 | 95 | ||
| 96 | skb->dev = ds->ports[source_port]; | 96 | skb->dev = ds->ports[source_port]; |
| 97 | skb_push(skb, ETH_HLEN); | 97 | skb_push(skb, ETH_HLEN); |
| 98 | skb->pkt_type = PACKET_HOST; | ||
| 98 | skb->protocol = eth_type_trans(skb, skb->dev); | 99 | skb->protocol = eth_type_trans(skb, skb->dev); |
| 99 | 100 | ||
| 100 | skb->dev->last_rx = jiffies; | 101 | skb->dev->last_rx = jiffies; |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 490e035c6d9..2e78f6bd977 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/proc.c b/net/ipv4/proc.c index 8f5a403f6f6..a631a1f110c 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -237,43 +237,45 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
| 237 | SNMP_MIB_SENTINEL | 237 | SNMP_MIB_SENTINEL |
| 238 | }; | 238 | }; |
| 239 | 239 | ||
| 240 | static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals, | ||
| 241 | unsigned short *type, int count) | ||
| 242 | { | ||
| 243 | int j; | ||
| 244 | |||
| 245 | if (count) { | ||
| 246 | seq_printf(seq, "\nIcmpMsg:"); | ||
| 247 | for (j = 0; j < count; ++j) | ||
| 248 | seq_printf(seq, " %sType%u", | ||
| 249 | type[j] & 0x100 ? "Out" : "In", | ||
| 250 | type[j] & 0xff); | ||
| 251 | seq_printf(seq, "\nIcmpMsg:"); | ||
| 252 | for (j = 0; j < count; ++j) | ||
| 253 | seq_printf(seq, " %lu", vals[j]); | ||
| 254 | } | ||
| 255 | } | ||
| 256 | |||
| 240 | static void icmpmsg_put(struct seq_file *seq) | 257 | static void icmpmsg_put(struct seq_file *seq) |
| 241 | { | 258 | { |
| 242 | #define PERLINE 16 | 259 | #define PERLINE 16 |
| 243 | 260 | ||
| 244 | int j, i, count; | 261 | int i, count; |
| 245 | static int out[PERLINE]; | 262 | unsigned short type[PERLINE]; |
| 263 | unsigned long vals[PERLINE], val; | ||
| 246 | struct net *net = seq->private; | 264 | struct net *net = seq->private; |
| 247 | 265 | ||
| 248 | count = 0; | 266 | count = 0; |
| 249 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { | 267 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
| 250 | 268 | val = snmp_fold_field((void **) net->mib.icmpmsg_statistics, i); | |
| 251 | if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i)) | 269 | if (val) { |
| 252 | out[count++] = i; | 270 | type[count] = i; |
| 253 | if (count < PERLINE) | 271 | vals[count++] = val; |
| 254 | continue; | 272 | } |
| 255 | 273 | if (count == PERLINE) { | |
| 256 | seq_printf(seq, "\nIcmpMsg:"); | 274 | icmpmsg_put_line(seq, vals, type, count); |
| 257 | for (j = 0; j < PERLINE; ++j) | 275 | count = 0; |
| 258 | seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In", | 276 | } |
| 259 | i & 0xff); | ||
| 260 | seq_printf(seq, "\nIcmpMsg: "); | ||
| 261 | for (j = 0; j < PERLINE; ++j) | ||
| 262 | seq_printf(seq, " %lu", | ||
| 263 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, | ||
| 264 | out[j])); | ||
| 265 | seq_putc(seq, '\n'); | ||
| 266 | } | ||
| 267 | if (count) { | ||
| 268 | seq_printf(seq, "\nIcmpMsg:"); | ||
| 269 | for (j = 0; j < count; ++j) | ||
| 270 | seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" : | ||
| 271 | "In", out[j] & 0xff); | ||
| 272 | seq_printf(seq, "\nIcmpMsg:"); | ||
| 273 | for (j = 0; j < count; ++j) | ||
| 274 | seq_printf(seq, " %lu", snmp_fold_field((void **) | ||
| 275 | net->mib.icmpmsg_statistics, out[j])); | ||
| 276 | } | 277 | } |
| 278 | icmpmsg_put_line(seq, vals, type, count); | ||
| 277 | 279 | ||
| 278 | #undef PERLINE | 280 | #undef PERLINE |
| 279 | } | 281 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index eccb7165a80..c5aca0bb116 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/udp.c b/net/ipv4/udp.c index 2095abc3cab..cf02701ced4 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 07735ed280d..55dc6beab9a 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 eea9542728c..d9da5eb9dcb 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/ip6mr.c b/net/ipv6/ip6mr.c index 182f8a177e7..52a7eb0e2c2 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
| @@ -981,14 +981,15 @@ int __init ip6_mr_init(void) | |||
| 981 | goto proc_cache_fail; | 981 | goto proc_cache_fail; |
| 982 | #endif | 982 | #endif |
| 983 | return 0; | 983 | return 0; |
| 984 | reg_notif_fail: | ||
| 985 | kmem_cache_destroy(mrt_cachep); | ||
| 986 | #ifdef CONFIG_PROC_FS | 984 | #ifdef CONFIG_PROC_FS |
| 987 | proc_vif_fail: | ||
| 988 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
| 989 | proc_cache_fail: | 985 | proc_cache_fail: |
| 990 | proc_net_remove(&init_net, "ip6_mr_vif"); | 986 | proc_net_remove(&init_net, "ip6_mr_vif"); |
| 987 | proc_vif_fail: | ||
| 988 | unregister_netdevice_notifier(&ip6_mr_notifier); | ||
| 991 | #endif | 989 | #endif |
| 990 | reg_notif_fail: | ||
| 991 | del_timer(&ipmr_expire_timer); | ||
| 992 | kmem_cache_destroy(mrt_cachep); | ||
| 992 | return err; | 993 | return err; |
| 993 | } | 994 | } |
| 994 | 995 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index e51da8c092f..8b48512ebf6 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 89884a4f23a..60c78cfc273 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 e55e0441e4d..5b22e011653 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; |
| @@ -3189,6 +3188,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
| 3189 | return xp; | 3188 | return xp; |
| 3190 | 3189 | ||
| 3191 | out: | 3190 | out: |
| 3191 | xp->walk.dead = 1; | ||
| 3192 | xfrm_policy_destroy(xp); | 3192 | xfrm_policy_destroy(xp); |
| 3193 | return NULL; | 3193 | return NULL; |
| 3194 | } | 3194 | } |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 189d0bafa91..b85c4f27b36 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
| @@ -199,7 +199,7 @@ static ssize_t sta_agg_status_write(struct file *file, | |||
| 199 | /* toggle Rx aggregation command */ | 199 | /* toggle Rx aggregation command */ |
| 200 | tid_num = tid_num - 100; | 200 | tid_num = tid_num - 100; |
| 201 | if (tid_static_rx[tid_num] == 1) { | 201 | if (tid_static_rx[tid_num] == 1) { |
| 202 | strcpy(state, "off "); | 202 | strcpy(state, "off"); |
| 203 | ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0, | 203 | ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0, |
| 204 | WLAN_REASON_QSTA_REQUIRE_SETUP); | 204 | WLAN_REASON_QSTA_REQUIRE_SETUP); |
| 205 | sta->ampdu_mlme.tid_state_rx[tid_num] |= | 205 | sta->ampdu_mlme.tid_state_rx[tid_num] |= |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 02ddc2b3ce2..e90d52f199b 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
| @@ -713,7 +713,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
| 713 | iph = ipv6_hdr(skb); | 713 | iph = ipv6_hdr(skb); |
| 714 | iph->version = 6; | 714 | iph->version = 6; |
| 715 | iph->nexthdr = IPPROTO_IPV6; | 715 | iph->nexthdr = IPPROTO_IPV6; |
| 716 | iph->payload_len = old_iph->payload_len + sizeof(old_iph); | 716 | iph->payload_len = old_iph->payload_len; |
| 717 | be16_add_cpu(&iph->payload_len, sizeof(*old_iph)); | ||
| 717 | iph->priority = old_iph->priority; | 718 | iph->priority = old_iph->priority; |
| 718 | memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); | 719 | memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); |
| 719 | iph->daddr = rt->rt6i_dst.addr; | 720 | iph->daddr = rt->rt6i_dst.addr; |
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c index 9c06b9f86ad..c39b6a99413 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 a59a307e685..592d73344d4 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 a2cdbcbf64c..4ab62ad85dd 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 b0925a30335..249f6b92f15 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 0242bead405..07ae7fd82be 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 ee769ecaa13..0a0ef17b2a4 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/rfkill/rfkill.c b/net/rfkill/rfkill.c index f949a482b00..25ba3bd57e6 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 2b7a4b5c9b7..57550c3bcab 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/unix/af_unix.c b/net/unix/af_unix.c index dc504d308ec..eb90f77bb0e 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 2a27b84f740..6d4a9a8de5e 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 832b47c1de8..058f04f54b9 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 4a8a1abb59e..a278a6f3b99 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 | } |
