diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan_core.c | 46 | ||||
-rw-r--r-- | net/8021q/vlanproc.c | 2 | ||||
-rw-r--r-- | net/9p/client.c | 59 | ||||
-rw-r--r-- | net/9p/trans_rdma.c | 5 | ||||
-rw-r--r-- | net/core/dev.c | 3 | ||||
-rw-r--r-- | net/core/scm.c | 24 | ||||
-rw-r--r-- | net/core/skbuff.c | 2 | ||||
-rw-r--r-- | net/dsa/slave.c | 72 | ||||
-rw-r--r-- | net/dsa/tag_dsa.c | 1 | ||||
-rw-r--r-- | net/dsa/tag_edsa.c | 1 | ||||
-rw-r--r-- | net/dsa/tag_trailer.c | 1 | ||||
-rw-r--r-- | net/ipv4/proc.c | 58 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 3 | ||||
-rw-r--r-- | net/ipv4/xfrm4_state.c | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 9 | ||||
-rw-r--r-- | net/ipv6/xfrm6_state.c | 1 | ||||
-rw-r--r-- | net/key/af_key.c | 1 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 2 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_xmit.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_helper.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto.c | 5 | ||||
-rw-r--r-- | net/rfkill/rfkill.c | 2 | ||||
-rw-r--r-- | net/unix/af_unix.c | 31 | ||||
-rw-r--r-- | net/unix/garbage.c | 49 |
25 files changed, 284 insertions, 104 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/8021q/vlanproc.c b/net/8021q/vlanproc.c index 0feefa4e1a4b..3628e0a81b40 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 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/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 ebb6b94f8af2..d49ef8301b5b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -486,8 +486,8 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
486 | shinfo->frag_list = NULL; | 486 | shinfo->frag_list = NULL; |
487 | 487 | ||
488 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 488 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
489 | skb_reset_tail_pointer(skb); | ||
490 | skb->data = skb->head + NET_SKB_PAD; | 489 | skb->data = skb->head + NET_SKB_PAD; |
490 | skb_reset_tail_pointer(skb); | ||
491 | 491 | ||
492 | return 1; | 492 | return 1; |
493 | } | 493 | } |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 37616884b8a9..1af5a79309e9 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 bdc0510b53b7..31866543332e 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 f985ea993843..9f4ce55eae59 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 d3117764b2c2..efd26697e716 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/proc.c b/net/ipv4/proc.c index 8f5a403f6f6b..a631a1f110ca 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 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/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/ip6mr.c b/net/ipv6/ip6mr.c index 182f8a177e7f..52a7eb0e2c2c 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/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 3440a4637f01..5b22e011653b 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -3188,6 +3188,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
3188 | return xp; | 3188 | return xp; |
3189 | 3189 | ||
3190 | out: | 3190 | out: |
3191 | xp->walk.dead = 1; | ||
3191 | xfrm_policy_destroy(xp); | 3192 | xfrm_policy_destroy(xp); |
3192 | return NULL; | 3193 | return NULL; |
3193 | } | 3194 | } |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 189d0bafa91a..b85c4f27b361 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 02ddc2b3ce2e..e90d52f199bc 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 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/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/unix/af_unix.c b/net/unix/af_unix.c index 4d3c6071b9a4..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); |
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). |