diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-02-15 02:26:41 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-02-15 02:26:41 -0500 |
commit | d60cf53a30956e47919788b2ef49287786a959c9 (patch) | |
tree | cb518d7cc4813f4b54a3fd5fcaad43e6d82be6a3 /net | |
parent | 0ce08870b8a4895044b6cf2bbdc774a6faaa3656 (diff) | |
parent | 13c12a4e8ecdf3998cd2d89ade69f6f194819c95 (diff) |
Merge branch 'sh/st-integration' into sh/urgent
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/unicast.c | 15 | ||||
-rw-r--r-- | net/batman-adv/vis.c | 14 | ||||
-rw-r--r-- | net/bridge/br_fdb.c | 4 | ||||
-rw-r--r-- | net/caif/chnl_net.c | 4 | ||||
-rw-r--r-- | net/core/dev.c | 32 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 6 | ||||
-rw-r--r-- | net/core/skbuff.c | 1 | ||||
-rw-r--r-- | net/econet/af_econet.c | 4 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 16 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 76 | ||||
-rw-r--r-- | net/ipv4/netfilter/arpt_mangle.c | 6 | ||||
-rw-r--r-- | net/ipv4/raw.c | 19 | ||||
-rw-r--r-- | net/ipv4/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 75 | ||||
-rw-r--r-- | net/ipv6/raw.c | 19 | ||||
-rw-r--r-- | net/ipv6/route.c | 10 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 9 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/status.c | 7 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 11 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_ecache.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 1 | ||||
-rw-r--r-- | net/netfilter/xt_iprange.c | 16 | ||||
-rw-r--r-- | net/x25/x25_facilities.c | 28 | ||||
-rw-r--r-- | net/x25/x25_in.c | 14 | ||||
-rw-r--r-- | net/x25/x25_link.c | 5 |
28 files changed, 341 insertions, 66 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index ee41fef04b21..d1a611322549 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
@@ -50,12 +50,12 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, | |||
50 | skb = tfp->skb; | 50 | skb = tfp->skb; |
51 | } | 51 | } |
52 | 52 | ||
53 | if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0) | ||
54 | goto err; | ||
55 | |||
53 | skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); | 56 | skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); |
54 | if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) { | 57 | if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) |
55 | /* free buffered skb, skb will be freed later */ | 58 | goto err; |
56 | kfree_skb(tfp->skb); | ||
57 | return NULL; | ||
58 | } | ||
59 | 59 | ||
60 | /* move free entry to end */ | 60 | /* move free entry to end */ |
61 | tfp->skb = NULL; | 61 | tfp->skb = NULL; |
@@ -70,6 +70,11 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, | |||
70 | unicast_packet->packet_type = BAT_UNICAST; | 70 | unicast_packet->packet_type = BAT_UNICAST; |
71 | 71 | ||
72 | return skb; | 72 | return skb; |
73 | |||
74 | err: | ||
75 | /* free buffered skb, skb will be freed later */ | ||
76 | kfree_skb(tfp->skb); | ||
77 | return NULL; | ||
73 | } | 78 | } |
74 | 79 | ||
75 | static void frag_create_entry(struct list_head *head, struct sk_buff *skb) | 80 | static void frag_create_entry(struct list_head *head, struct sk_buff *skb) |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index cd4c4231fa48..de1022cacaf7 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -64,6 +64,7 @@ static void free_info(struct kref *ref) | |||
64 | 64 | ||
65 | spin_unlock_bh(&bat_priv->vis_list_lock); | 65 | spin_unlock_bh(&bat_priv->vis_list_lock); |
66 | kfree_skb(info->skb_packet); | 66 | kfree_skb(info->skb_packet); |
67 | kfree(info); | ||
67 | } | 68 | } |
68 | 69 | ||
69 | /* Compare two vis packets, used by the hashing algorithm */ | 70 | /* Compare two vis packets, used by the hashing algorithm */ |
@@ -268,10 +269,10 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) | |||
268 | buff_pos += sprintf(buff + buff_pos, "%pM,", | 269 | buff_pos += sprintf(buff + buff_pos, "%pM,", |
269 | entry->addr); | 270 | entry->addr); |
270 | 271 | ||
271 | for (i = 0; i < packet->entries; i++) | 272 | for (j = 0; j < packet->entries; j++) |
272 | buff_pos += vis_data_read_entry( | 273 | buff_pos += vis_data_read_entry( |
273 | buff + buff_pos, | 274 | buff + buff_pos, |
274 | &entries[i], | 275 | &entries[j], |
275 | entry->addr, | 276 | entry->addr, |
276 | entry->primary); | 277 | entry->primary); |
277 | 278 | ||
@@ -444,7 +445,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, | |||
444 | info); | 445 | info); |
445 | if (hash_added < 0) { | 446 | if (hash_added < 0) { |
446 | /* did not work (for some reason) */ | 447 | /* did not work (for some reason) */ |
447 | kref_put(&old_info->refcount, free_info); | 448 | kref_put(&info->refcount, free_info); |
448 | info = NULL; | 449 | info = NULL; |
449 | } | 450 | } |
450 | 451 | ||
@@ -815,7 +816,7 @@ static void send_vis_packets(struct work_struct *work) | |||
815 | container_of(work, struct delayed_work, work); | 816 | container_of(work, struct delayed_work, work); |
816 | struct bat_priv *bat_priv = | 817 | struct bat_priv *bat_priv = |
817 | container_of(delayed_work, struct bat_priv, vis_work); | 818 | container_of(delayed_work, struct bat_priv, vis_work); |
818 | struct vis_info *info, *temp; | 819 | struct vis_info *info; |
819 | 820 | ||
820 | spin_lock_bh(&bat_priv->vis_hash_lock); | 821 | spin_lock_bh(&bat_priv->vis_hash_lock); |
821 | purge_vis_packets(bat_priv); | 822 | purge_vis_packets(bat_priv); |
@@ -825,8 +826,9 @@ static void send_vis_packets(struct work_struct *work) | |||
825 | send_list_add(bat_priv, bat_priv->my_vis_info); | 826 | send_list_add(bat_priv, bat_priv->my_vis_info); |
826 | } | 827 | } |
827 | 828 | ||
828 | list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, | 829 | while (!list_empty(&bat_priv->vis_send_list)) { |
829 | send_list) { | 830 | info = list_first_entry(&bat_priv->vis_send_list, |
831 | typeof(*info), send_list); | ||
830 | 832 | ||
831 | kref_get(&info->refcount); | 833 | kref_get(&info->refcount); |
832 | spin_unlock_bh(&bat_priv->vis_hash_lock); | 834 | spin_unlock_bh(&bat_priv->vis_hash_lock); |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 2872393b2939..88485cc74dc3 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -328,12 +328,12 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, | |||
328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); | 328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); |
329 | if (fdb) { | 329 | if (fdb) { |
330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); | 330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); |
331 | hlist_add_head_rcu(&fdb->hlist, head); | ||
332 | |||
333 | fdb->dst = source; | 331 | fdb->dst = source; |
334 | fdb->is_local = is_local; | 332 | fdb->is_local = is_local; |
335 | fdb->is_static = is_local; | 333 | fdb->is_static = is_local; |
336 | fdb->ageing_timer = jiffies; | 334 | fdb->ageing_timer = jiffies; |
335 | |||
336 | hlist_add_head_rcu(&fdb->hlist, head); | ||
337 | } | 337 | } |
338 | return fdb; | 338 | return fdb; |
339 | } | 339 | } |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index fa9dab372b68..6008d6dc18a0 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -394,9 +394,7 @@ static void ipcaif_net_setup(struct net_device *dev) | |||
394 | priv->conn_req.sockaddr.u.dgm.connection_id = -1; | 394 | priv->conn_req.sockaddr.u.dgm.connection_id = -1; |
395 | priv->flowenabled = false; | 395 | priv->flowenabled = false; |
396 | 396 | ||
397 | ASSERT_RTNL(); | ||
398 | init_waitqueue_head(&priv->netmgmt_wq); | 397 | init_waitqueue_head(&priv->netmgmt_wq); |
399 | list_add(&priv->list_field, &chnl_net_list); | ||
400 | } | 398 | } |
401 | 399 | ||
402 | 400 | ||
@@ -453,6 +451,8 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, | |||
453 | ret = register_netdevice(dev); | 451 | ret = register_netdevice(dev); |
454 | if (ret) | 452 | if (ret) |
455 | pr_warn("device rtml registration failed\n"); | 453 | pr_warn("device rtml registration failed\n"); |
454 | else | ||
455 | list_add(&caifdev->list_field, &chnl_net_list); | ||
456 | return ret; | 456 | return ret; |
457 | } | 457 | } |
458 | 458 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 24ea2d71e7ea..8e726cb47ed7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2563,7 +2563,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2563 | 2563 | ||
2564 | map = rcu_dereference(rxqueue->rps_map); | 2564 | map = rcu_dereference(rxqueue->rps_map); |
2565 | if (map) { | 2565 | if (map) { |
2566 | if (map->len == 1) { | 2566 | if (map->len == 1 && |
2567 | !rcu_dereference_raw(rxqueue->rps_flow_table)) { | ||
2567 | tcpu = map->cpus[0]; | 2568 | tcpu = map->cpus[0]; |
2568 | if (cpu_online(tcpu)) | 2569 | if (cpu_online(tcpu)) |
2569 | cpu = tcpu; | 2570 | cpu = tcpu; |
@@ -3424,6 +3425,8 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
3424 | __skb_pull(skb, skb_headlen(skb)); | 3425 | __skb_pull(skb, skb_headlen(skb)); |
3425 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 3426 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
3426 | skb->vlan_tci = 0; | 3427 | skb->vlan_tci = 0; |
3428 | skb->dev = napi->dev; | ||
3429 | skb->skb_iif = 0; | ||
3427 | 3430 | ||
3428 | napi->skb = skb; | 3431 | napi->skb = skb; |
3429 | } | 3432 | } |
@@ -5657,30 +5660,35 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
5657 | 5660 | ||
5658 | dev_net_set(dev, &init_net); | 5661 | dev_net_set(dev, &init_net); |
5659 | 5662 | ||
5663 | dev->gso_max_size = GSO_MAX_SIZE; | ||
5664 | |||
5665 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
5666 | dev->ethtool_ntuple_list.count = 0; | ||
5667 | INIT_LIST_HEAD(&dev->napi_list); | ||
5668 | INIT_LIST_HEAD(&dev->unreg_list); | ||
5669 | INIT_LIST_HEAD(&dev->link_watch_list); | ||
5670 | dev->priv_flags = IFF_XMIT_DST_RELEASE; | ||
5671 | setup(dev); | ||
5672 | |||
5660 | dev->num_tx_queues = txqs; | 5673 | dev->num_tx_queues = txqs; |
5661 | dev->real_num_tx_queues = txqs; | 5674 | dev->real_num_tx_queues = txqs; |
5662 | if (netif_alloc_netdev_queues(dev)) | 5675 | if (netif_alloc_netdev_queues(dev)) |
5663 | goto free_pcpu; | 5676 | goto free_all; |
5664 | 5677 | ||
5665 | #ifdef CONFIG_RPS | 5678 | #ifdef CONFIG_RPS |
5666 | dev->num_rx_queues = rxqs; | 5679 | dev->num_rx_queues = rxqs; |
5667 | dev->real_num_rx_queues = rxqs; | 5680 | dev->real_num_rx_queues = rxqs; |
5668 | if (netif_alloc_rx_queues(dev)) | 5681 | if (netif_alloc_rx_queues(dev)) |
5669 | goto free_pcpu; | 5682 | goto free_all; |
5670 | #endif | 5683 | #endif |
5671 | 5684 | ||
5672 | dev->gso_max_size = GSO_MAX_SIZE; | ||
5673 | |||
5674 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
5675 | dev->ethtool_ntuple_list.count = 0; | ||
5676 | INIT_LIST_HEAD(&dev->napi_list); | ||
5677 | INIT_LIST_HEAD(&dev->unreg_list); | ||
5678 | INIT_LIST_HEAD(&dev->link_watch_list); | ||
5679 | dev->priv_flags = IFF_XMIT_DST_RELEASE; | ||
5680 | setup(dev); | ||
5681 | strcpy(dev->name, name); | 5685 | strcpy(dev->name, name); |
5682 | return dev; | 5686 | return dev; |
5683 | 5687 | ||
5688 | free_all: | ||
5689 | free_netdev(dev); | ||
5690 | return NULL; | ||
5691 | |||
5684 | free_pcpu: | 5692 | free_pcpu: |
5685 | free_percpu(dev->pcpu_refcnt); | 5693 | free_percpu(dev->pcpu_refcnt); |
5686 | kfree(dev->_tx); | 5694 | kfree(dev->_tx); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 750db57f3bb3..2d65c6bb24c1 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1121,8 +1121,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) | |||
1121 | return -EOPNOTSUPP; | 1121 | return -EOPNOTSUPP; |
1122 | 1122 | ||
1123 | if (af_ops->validate_link_af) { | 1123 | if (af_ops->validate_link_af) { |
1124 | err = af_ops->validate_link_af(dev, | 1124 | err = af_ops->validate_link_af(dev, af); |
1125 | tb[IFLA_AF_SPEC]); | ||
1126 | if (err < 0) | 1125 | if (err < 0) |
1127 | return err; | 1126 | return err; |
1128 | } | 1127 | } |
@@ -1672,6 +1671,9 @@ replay: | |||
1672 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); | 1671 | snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); |
1673 | 1672 | ||
1674 | dest_net = rtnl_link_get_net(net, tb); | 1673 | dest_net = rtnl_link_get_net(net, tb); |
1674 | if (IS_ERR(dest_net)) | ||
1675 | return PTR_ERR(dest_net); | ||
1676 | |||
1675 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); | 1677 | dev = rtnl_create_link(net, dest_net, ifname, ops, tb); |
1676 | 1678 | ||
1677 | if (IS_ERR(dev)) | 1679 | if (IS_ERR(dev)) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 7cd1bc86d591..d883dcc78b6b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -210,6 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, | |||
210 | shinfo = skb_shinfo(skb); | 210 | shinfo = skb_shinfo(skb); |
211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | 211 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); |
212 | atomic_set(&shinfo->dataref, 1); | 212 | atomic_set(&shinfo->dataref, 1); |
213 | kmemcheck_annotate_variable(shinfo->destructor_arg); | ||
213 | 214 | ||
214 | if (fclone) { | 215 | if (fclone) { |
215 | struct sk_buff *child = skb + 1; | 216 | struct sk_buff *child = skb + 1; |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 15dcc1a586b4..0c2826337919 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -265,13 +265,13 @@ static void ec_tx_done(struct sk_buff *skb, int result) | |||
265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | 265 | static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, |
266 | struct msghdr *msg, size_t len) | 266 | struct msghdr *msg, size_t len) |
267 | { | 267 | { |
268 | struct sock *sk = sock->sk; | ||
269 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; | 268 | struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name; |
270 | struct net_device *dev; | 269 | struct net_device *dev; |
271 | struct ec_addr addr; | 270 | struct ec_addr addr; |
272 | int err; | 271 | int err; |
273 | unsigned char port, cb; | 272 | unsigned char port, cb; |
274 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) | 273 | #if defined(CONFIG_ECONET_AUNUDP) || defined(CONFIG_ECONET_NATIVE) |
274 | struct sock *sk = sock->sk; | ||
275 | struct sk_buff *skb; | 275 | struct sk_buff *skb; |
276 | struct ec_cb *eb; | 276 | struct ec_cb *eb; |
277 | #endif | 277 | #endif |
@@ -488,10 +488,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
488 | 488 | ||
489 | error_free_buf: | 489 | error_free_buf: |
490 | vfree(userbuf); | 490 | vfree(userbuf); |
491 | error: | ||
491 | #else | 492 | #else |
492 | err = -EPROTOTYPE; | 493 | err = -EPROTOTYPE; |
493 | #endif | 494 | #endif |
494 | error: | ||
495 | mutex_unlock(&econet_mutex); | 495 | mutex_unlock(&econet_mutex); |
496 | 496 | ||
497 | return err; | 497 | return err; |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f2b61107df6c..45b89d7bda5a 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -880,6 +880,19 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
880 | } | 880 | } |
881 | EXPORT_SYMBOL(inet_ioctl); | 881 | EXPORT_SYMBOL(inet_ioctl); |
882 | 882 | ||
883 | #ifdef CONFIG_COMPAT | ||
884 | int inet_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
885 | { | ||
886 | struct sock *sk = sock->sk; | ||
887 | int err = -ENOIOCTLCMD; | ||
888 | |||
889 | if (sk->sk_prot->compat_ioctl) | ||
890 | err = sk->sk_prot->compat_ioctl(sk, cmd, arg); | ||
891 | |||
892 | return err; | ||
893 | } | ||
894 | #endif | ||
895 | |||
883 | const struct proto_ops inet_stream_ops = { | 896 | const struct proto_ops inet_stream_ops = { |
884 | .family = PF_INET, | 897 | .family = PF_INET, |
885 | .owner = THIS_MODULE, | 898 | .owner = THIS_MODULE, |
@@ -903,6 +916,7 @@ const struct proto_ops inet_stream_ops = { | |||
903 | #ifdef CONFIG_COMPAT | 916 | #ifdef CONFIG_COMPAT |
904 | .compat_setsockopt = compat_sock_common_setsockopt, | 917 | .compat_setsockopt = compat_sock_common_setsockopt, |
905 | .compat_getsockopt = compat_sock_common_getsockopt, | 918 | .compat_getsockopt = compat_sock_common_getsockopt, |
919 | .compat_ioctl = inet_compat_ioctl, | ||
906 | #endif | 920 | #endif |
907 | }; | 921 | }; |
908 | EXPORT_SYMBOL(inet_stream_ops); | 922 | EXPORT_SYMBOL(inet_stream_ops); |
@@ -929,6 +943,7 @@ const struct proto_ops inet_dgram_ops = { | |||
929 | #ifdef CONFIG_COMPAT | 943 | #ifdef CONFIG_COMPAT |
930 | .compat_setsockopt = compat_sock_common_setsockopt, | 944 | .compat_setsockopt = compat_sock_common_setsockopt, |
931 | .compat_getsockopt = compat_sock_common_getsockopt, | 945 | .compat_getsockopt = compat_sock_common_getsockopt, |
946 | .compat_ioctl = inet_compat_ioctl, | ||
932 | #endif | 947 | #endif |
933 | }; | 948 | }; |
934 | EXPORT_SYMBOL(inet_dgram_ops); | 949 | EXPORT_SYMBOL(inet_dgram_ops); |
@@ -959,6 +974,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
959 | #ifdef CONFIG_COMPAT | 974 | #ifdef CONFIG_COMPAT |
960 | .compat_setsockopt = compat_sock_common_setsockopt, | 975 | .compat_setsockopt = compat_sock_common_setsockopt, |
961 | .compat_getsockopt = compat_sock_common_getsockopt, | 976 | .compat_getsockopt = compat_sock_common_getsockopt, |
977 | .compat_ioctl = inet_compat_ioctl, | ||
962 | #endif | 978 | #endif |
963 | }; | 979 | }; |
964 | 980 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3f3a9afd73e0..8b65a12654e7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
61 | #include <linux/if_arp.h> | 61 | #include <linux/if_arp.h> |
62 | #include <linux/netfilter_ipv4.h> | 62 | #include <linux/netfilter_ipv4.h> |
63 | #include <linux/compat.h> | ||
63 | #include <net/ipip.h> | 64 | #include <net/ipip.h> |
64 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
65 | #include <net/netlink.h> | 66 | #include <net/netlink.h> |
@@ -1434,6 +1435,81 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1434 | } | 1435 | } |
1435 | } | 1436 | } |
1436 | 1437 | ||
1438 | #ifdef CONFIG_COMPAT | ||
1439 | struct compat_sioc_sg_req { | ||
1440 | struct in_addr src; | ||
1441 | struct in_addr grp; | ||
1442 | compat_ulong_t pktcnt; | ||
1443 | compat_ulong_t bytecnt; | ||
1444 | compat_ulong_t wrong_if; | ||
1445 | }; | ||
1446 | |||
1447 | struct compat_sioc_vif_req { | ||
1448 | vifi_t vifi; /* Which iface */ | ||
1449 | compat_ulong_t icount; | ||
1450 | compat_ulong_t ocount; | ||
1451 | compat_ulong_t ibytes; | ||
1452 | compat_ulong_t obytes; | ||
1453 | }; | ||
1454 | |||
1455 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
1456 | { | ||
1457 | struct compat_sioc_sg_req sr; | ||
1458 | struct compat_sioc_vif_req vr; | ||
1459 | struct vif_device *vif; | ||
1460 | struct mfc_cache *c; | ||
1461 | struct net *net = sock_net(sk); | ||
1462 | struct mr_table *mrt; | ||
1463 | |||
1464 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
1465 | if (mrt == NULL) | ||
1466 | return -ENOENT; | ||
1467 | |||
1468 | switch (cmd) { | ||
1469 | case SIOCGETVIFCNT: | ||
1470 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
1471 | return -EFAULT; | ||
1472 | if (vr.vifi >= mrt->maxvif) | ||
1473 | return -EINVAL; | ||
1474 | read_lock(&mrt_lock); | ||
1475 | vif = &mrt->vif_table[vr.vifi]; | ||
1476 | if (VIF_EXISTS(mrt, vr.vifi)) { | ||
1477 | vr.icount = vif->pkt_in; | ||
1478 | vr.ocount = vif->pkt_out; | ||
1479 | vr.ibytes = vif->bytes_in; | ||
1480 | vr.obytes = vif->bytes_out; | ||
1481 | read_unlock(&mrt_lock); | ||
1482 | |||
1483 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
1484 | return -EFAULT; | ||
1485 | return 0; | ||
1486 | } | ||
1487 | read_unlock(&mrt_lock); | ||
1488 | return -EADDRNOTAVAIL; | ||
1489 | case SIOCGETSGCNT: | ||
1490 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
1491 | return -EFAULT; | ||
1492 | |||
1493 | rcu_read_lock(); | ||
1494 | c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); | ||
1495 | if (c) { | ||
1496 | sr.pktcnt = c->mfc_un.res.pkt; | ||
1497 | sr.bytecnt = c->mfc_un.res.bytes; | ||
1498 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
1499 | rcu_read_unlock(); | ||
1500 | |||
1501 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
1502 | return -EFAULT; | ||
1503 | return 0; | ||
1504 | } | ||
1505 | rcu_read_unlock(); | ||
1506 | return -EADDRNOTAVAIL; | ||
1507 | default: | ||
1508 | return -ENOIOCTLCMD; | ||
1509 | } | ||
1510 | } | ||
1511 | #endif | ||
1512 | |||
1437 | 1513 | ||
1438 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) | 1514 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) |
1439 | { | 1515 | { |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index b8ddcc480ed9..a5e52a9f0a12 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -60,12 +60,12 @@ static int checkentry(const struct xt_tgchk_param *par) | |||
60 | 60 | ||
61 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
62 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
63 | return false; | 63 | return -EINVAL; |
64 | 64 | ||
65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && | 65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && |
66 | mangle->target != XT_CONTINUE) | 66 | mangle->target != XT_CONTINUE) |
67 | return false; | 67 | return -EINVAL; |
68 | return true; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct xt_target arpt_mangle_reg __read_mostly = { | 71 | static struct xt_target arpt_mangle_reg __read_mostly = { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a3d5ab786e81..6390ba299b3d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -76,6 +76,7 @@ | |||
76 | #include <linux/seq_file.h> | 76 | #include <linux/seq_file.h> |
77 | #include <linux/netfilter.h> | 77 | #include <linux/netfilter.h> |
78 | #include <linux/netfilter_ipv4.h> | 78 | #include <linux/netfilter_ipv4.h> |
79 | #include <linux/compat.h> | ||
79 | 80 | ||
80 | static struct raw_hashinfo raw_v4_hashinfo = { | 81 | static struct raw_hashinfo raw_v4_hashinfo = { |
81 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), | 82 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), |
@@ -838,6 +839,23 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
838 | } | 839 | } |
839 | } | 840 | } |
840 | 841 | ||
842 | #ifdef CONFIG_COMPAT | ||
843 | static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
844 | { | ||
845 | switch (cmd) { | ||
846 | case SIOCOUTQ: | ||
847 | case SIOCINQ: | ||
848 | return -ENOIOCTLCMD; | ||
849 | default: | ||
850 | #ifdef CONFIG_IP_MROUTE | ||
851 | return ipmr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
852 | #else | ||
853 | return -ENOIOCTLCMD; | ||
854 | #endif | ||
855 | } | ||
856 | } | ||
857 | #endif | ||
858 | |||
841 | struct proto raw_prot = { | 859 | struct proto raw_prot = { |
842 | .name = "RAW", | 860 | .name = "RAW", |
843 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
@@ -860,6 +878,7 @@ struct proto raw_prot = { | |||
860 | #ifdef CONFIG_COMPAT | 878 | #ifdef CONFIG_COMPAT |
861 | .compat_setsockopt = compat_raw_setsockopt, | 879 | .compat_setsockopt = compat_raw_setsockopt, |
862 | .compat_getsockopt = compat_raw_getsockopt, | 880 | .compat_getsockopt = compat_raw_getsockopt, |
881 | .compat_ioctl = compat_raw_ioctl, | ||
863 | #endif | 882 | #endif |
864 | }; | 883 | }; |
865 | 884 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 351dc4e85242..788a3e74834e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2707,6 +2707,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo | |||
2707 | return NULL; | 2707 | return NULL; |
2708 | } | 2708 | } |
2709 | 2709 | ||
2710 | static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst) | ||
2711 | { | ||
2712 | return 0; | ||
2713 | } | ||
2714 | |||
2710 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2715 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2711 | { | 2716 | { |
2712 | } | 2717 | } |
@@ -2716,6 +2721,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2716 | .protocol = cpu_to_be16(ETH_P_IP), | 2721 | .protocol = cpu_to_be16(ETH_P_IP), |
2717 | .destroy = ipv4_dst_destroy, | 2722 | .destroy = ipv4_dst_destroy, |
2718 | .check = ipv4_blackhole_dst_check, | 2723 | .check = ipv4_blackhole_dst_check, |
2724 | .default_mtu = ipv4_blackhole_default_mtu, | ||
2719 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2725 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2720 | }; | 2726 | }; |
2721 | 2727 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 9fab274019c0..0e1d53bcf1e0 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/compat.h> | ||
37 | #include <net/protocol.h> | 38 | #include <net/protocol.h> |
38 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
39 | #include <net/sock.h> | 40 | #include <net/sock.h> |
@@ -1804,6 +1805,80 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1804 | } | 1805 | } |
1805 | } | 1806 | } |
1806 | 1807 | ||
1808 | #ifdef CONFIG_COMPAT | ||
1809 | struct compat_sioc_sg_req6 { | ||
1810 | struct sockaddr_in6 src; | ||
1811 | struct sockaddr_in6 grp; | ||
1812 | compat_ulong_t pktcnt; | ||
1813 | compat_ulong_t bytecnt; | ||
1814 | compat_ulong_t wrong_if; | ||
1815 | }; | ||
1816 | |||
1817 | struct compat_sioc_mif_req6 { | ||
1818 | mifi_t mifi; | ||
1819 | compat_ulong_t icount; | ||
1820 | compat_ulong_t ocount; | ||
1821 | compat_ulong_t ibytes; | ||
1822 | compat_ulong_t obytes; | ||
1823 | }; | ||
1824 | |||
1825 | int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
1826 | { | ||
1827 | struct compat_sioc_sg_req6 sr; | ||
1828 | struct compat_sioc_mif_req6 vr; | ||
1829 | struct mif_device *vif; | ||
1830 | struct mfc6_cache *c; | ||
1831 | struct net *net = sock_net(sk); | ||
1832 | struct mr6_table *mrt; | ||
1833 | |||
1834 | mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT); | ||
1835 | if (mrt == NULL) | ||
1836 | return -ENOENT; | ||
1837 | |||
1838 | switch (cmd) { | ||
1839 | case SIOCGETMIFCNT_IN6: | ||
1840 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
1841 | return -EFAULT; | ||
1842 | if (vr.mifi >= mrt->maxvif) | ||
1843 | return -EINVAL; | ||
1844 | read_lock(&mrt_lock); | ||
1845 | vif = &mrt->vif6_table[vr.mifi]; | ||
1846 | if (MIF_EXISTS(mrt, vr.mifi)) { | ||
1847 | vr.icount = vif->pkt_in; | ||
1848 | vr.ocount = vif->pkt_out; | ||
1849 | vr.ibytes = vif->bytes_in; | ||
1850 | vr.obytes = vif->bytes_out; | ||
1851 | read_unlock(&mrt_lock); | ||
1852 | |||
1853 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
1854 | return -EFAULT; | ||
1855 | return 0; | ||
1856 | } | ||
1857 | read_unlock(&mrt_lock); | ||
1858 | return -EADDRNOTAVAIL; | ||
1859 | case SIOCGETSGCNT_IN6: | ||
1860 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
1861 | return -EFAULT; | ||
1862 | |||
1863 | read_lock(&mrt_lock); | ||
1864 | c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); | ||
1865 | if (c) { | ||
1866 | sr.pktcnt = c->mfc_un.res.pkt; | ||
1867 | sr.bytecnt = c->mfc_un.res.bytes; | ||
1868 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
1869 | read_unlock(&mrt_lock); | ||
1870 | |||
1871 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
1872 | return -EFAULT; | ||
1873 | return 0; | ||
1874 | } | ||
1875 | read_unlock(&mrt_lock); | ||
1876 | return -EADDRNOTAVAIL; | ||
1877 | default: | ||
1878 | return -ENOIOCTLCMD; | ||
1879 | } | ||
1880 | } | ||
1881 | #endif | ||
1807 | 1882 | ||
1808 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) | 1883 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) |
1809 | { | 1884 | { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 86c39526ba5e..c5b0915d106b 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/netfilter.h> | 31 | #include <linux/netfilter.h> |
32 | #include <linux/netfilter_ipv6.h> | 32 | #include <linux/netfilter_ipv6.h> |
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <linux/compat.h> | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | #include <asm/ioctls.h> | 36 | #include <asm/ioctls.h> |
36 | 37 | ||
@@ -1157,6 +1158,23 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1157 | } | 1158 | } |
1158 | } | 1159 | } |
1159 | 1160 | ||
1161 | #ifdef CONFIG_COMPAT | ||
1162 | static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
1163 | { | ||
1164 | switch (cmd) { | ||
1165 | case SIOCOUTQ: | ||
1166 | case SIOCINQ: | ||
1167 | return -ENOIOCTLCMD; | ||
1168 | default: | ||
1169 | #ifdef CONFIG_IPV6_MROUTE | ||
1170 | return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
1171 | #else | ||
1172 | return -ENOIOCTLCMD; | ||
1173 | #endif | ||
1174 | } | ||
1175 | } | ||
1176 | #endif | ||
1177 | |||
1160 | static void rawv6_close(struct sock *sk, long timeout) | 1178 | static void rawv6_close(struct sock *sk, long timeout) |
1161 | { | 1179 | { |
1162 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) | 1180 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) |
@@ -1215,6 +1233,7 @@ struct proto rawv6_prot = { | |||
1215 | #ifdef CONFIG_COMPAT | 1233 | #ifdef CONFIG_COMPAT |
1216 | .compat_setsockopt = compat_rawv6_setsockopt, | 1234 | .compat_setsockopt = compat_rawv6_setsockopt, |
1217 | .compat_getsockopt = compat_rawv6_getsockopt, | 1235 | .compat_getsockopt = compat_rawv6_getsockopt, |
1236 | .compat_ioctl = compat_rawv6_ioctl, | ||
1218 | #endif | 1237 | #endif |
1219 | }; | 1238 | }; |
1220 | 1239 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1534508f6c68..1c29f95695de 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -113,6 +113,11 @@ static struct dst_ops ip6_dst_ops_template = { | |||
113 | .local_out = __ip6_local_out, | 113 | .local_out = __ip6_local_out, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | ||
117 | { | ||
118 | return 0; | ||
119 | } | ||
120 | |||
116 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 121 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
117 | { | 122 | { |
118 | } | 123 | } |
@@ -122,6 +127,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
122 | .protocol = cpu_to_be16(ETH_P_IPV6), | 127 | .protocol = cpu_to_be16(ETH_P_IPV6), |
123 | .destroy = ip6_dst_destroy, | 128 | .destroy = ip6_dst_destroy, |
124 | .check = ip6_dst_check, | 129 | .check = ip6_dst_check, |
130 | .default_mtu = ip6_blackhole_default_mtu, | ||
125 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 131 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
126 | }; | 132 | }; |
127 | 133 | ||
@@ -194,7 +200,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
194 | in6_dev_put(idev); | 200 | in6_dev_put(idev); |
195 | } | 201 | } |
196 | if (peer) { | 202 | if (peer) { |
197 | BUG_ON(!(rt->rt6i_flags & RTF_CACHE)); | ||
198 | rt->rt6i_peer = NULL; | 203 | rt->rt6i_peer = NULL; |
199 | inet_putpeer(peer); | 204 | inet_putpeer(peer); |
200 | } | 205 | } |
@@ -204,9 +209,6 @@ void rt6_bind_peer(struct rt6_info *rt, int create) | |||
204 | { | 209 | { |
205 | struct inet_peer *peer; | 210 | struct inet_peer *peer; |
206 | 211 | ||
207 | if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE))) | ||
208 | return; | ||
209 | |||
210 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); | 212 | peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create); |
211 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) | 213 | if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL) |
212 | inet_putpeer(peer); | 214 | inet_putpeer(peer); |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index fa1d8f4e0051..7cb65ef79f9c 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <net/addrconf.h> | 15 | #include <net/addrconf.h> |
16 | #include <net/inet_frag.h> | 16 | #include <net/inet_frag.h> |
17 | 17 | ||
18 | static struct ctl_table empty[1]; | ||
19 | |||
18 | static ctl_table ipv6_table_template[] = { | 20 | static ctl_table ipv6_table_template[] = { |
19 | { | 21 | { |
20 | .procname = "route", | 22 | .procname = "route", |
@@ -35,6 +37,12 @@ static ctl_table ipv6_table_template[] = { | |||
35 | .mode = 0644, | 37 | .mode = 0644, |
36 | .proc_handler = proc_dointvec | 38 | .proc_handler = proc_dointvec |
37 | }, | 39 | }, |
40 | { | ||
41 | .procname = "neigh", | ||
42 | .maxlen = 0, | ||
43 | .mode = 0555, | ||
44 | .child = empty, | ||
45 | }, | ||
38 | { } | 46 | { } |
39 | }; | 47 | }; |
40 | 48 | ||
@@ -152,7 +160,6 @@ static struct ctl_table_header *ip6_base; | |||
152 | 160 | ||
153 | int ipv6_static_sysctl_register(void) | 161 | int ipv6_static_sysctl_register(void) |
154 | { | 162 | { |
155 | static struct ctl_table empty[1]; | ||
156 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); | 163 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
157 | if (ip6_base == NULL) | 164 | if (ip6_base == NULL) |
158 | return -ENOMEM; | 165 | return -ENOMEM; |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4bc8a9250cfd..9cd73b11506e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1822,6 +1822,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1822 | *cookie ^= 2; | 1822 | *cookie ^= 2; |
1823 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | 1823 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; |
1824 | local->hw_roc_skb = skb; | 1824 | local->hw_roc_skb = skb; |
1825 | local->hw_roc_skb_for_status = skb; | ||
1825 | mutex_unlock(&local->mtx); | 1826 | mutex_unlock(&local->mtx); |
1826 | 1827 | ||
1827 | return 0; | 1828 | return 0; |
@@ -1875,6 +1876,7 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | |||
1875 | if (ret == 0) { | 1876 | if (ret == 0) { |
1876 | kfree_skb(local->hw_roc_skb); | 1877 | kfree_skb(local->hw_roc_skb); |
1877 | local->hw_roc_skb = NULL; | 1878 | local->hw_roc_skb = NULL; |
1879 | local->hw_roc_skb_for_status = NULL; | ||
1878 | } | 1880 | } |
1879 | 1881 | ||
1880 | mutex_unlock(&local->mtx); | 1882 | mutex_unlock(&local->mtx); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c47d7c0e48a4..533fd32f49ff 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -953,7 +953,7 @@ struct ieee80211_local { | |||
953 | 953 | ||
954 | struct ieee80211_channel *hw_roc_channel; | 954 | struct ieee80211_channel *hw_roc_channel; |
955 | struct net_device *hw_roc_dev; | 955 | struct net_device *hw_roc_dev; |
956 | struct sk_buff *hw_roc_skb; | 956 | struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status; |
957 | struct work_struct hw_roc_start, hw_roc_done; | 957 | struct work_struct hw_roc_start, hw_roc_done; |
958 | enum nl80211_channel_type hw_roc_channel_type; | 958 | enum nl80211_channel_type hw_roc_channel_type; |
959 | unsigned int hw_roc_duration; | 959 | unsigned int hw_roc_duration; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 38a797217a91..071ac95c4aa0 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -323,6 +323,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
323 | 323 | ||
324 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 324 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
325 | struct ieee80211_work *wk; | 325 | struct ieee80211_work *wk; |
326 | u64 cookie = (unsigned long)skb; | ||
326 | 327 | ||
327 | rcu_read_lock(); | 328 | rcu_read_lock(); |
328 | list_for_each_entry_rcu(wk, &local->work_list, list) { | 329 | list_for_each_entry_rcu(wk, &local->work_list, list) { |
@@ -334,8 +335,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
334 | break; | 335 | break; |
335 | } | 336 | } |
336 | rcu_read_unlock(); | 337 | rcu_read_unlock(); |
338 | if (local->hw_roc_skb_for_status == skb) { | ||
339 | cookie = local->hw_roc_cookie ^ 2; | ||
340 | local->hw_roc_skb_for_status = NULL; | ||
341 | } | ||
337 | cfg80211_mgmt_tx_status( | 342 | cfg80211_mgmt_tx_status( |
338 | skb->dev, (unsigned long) skb, skb->data, skb->len, | 343 | skb->dev, cookie, skb->data, skb->len, |
339 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); | 344 | !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); |
340 | } | 345 | } |
341 | 346 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index b64b42bc774b..b0beaa58246b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1547,7 +1547,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1547 | skb_orphan(skb); | 1547 | skb_orphan(skb); |
1548 | } | 1548 | } |
1549 | 1549 | ||
1550 | if (skb_header_cloned(skb)) | 1550 | if (skb_cloned(skb)) |
1551 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | 1551 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); |
1552 | else if (head_need || tail_need) | 1552 | else if (head_need || tail_need) |
1553 | I802_DEBUG_INC(local->tx_expand_skb_head); | 1553 | I802_DEBUG_INC(local->tx_expand_skb_head); |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e61511929c66..84f4fcc5884b 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -942,8 +942,15 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, | |||
942 | if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) | 942 | if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) |
943 | nf_conntrack_event_cache(IPCT_REPLY, ct); | 943 | nf_conntrack_event_cache(IPCT_REPLY, ct); |
944 | out: | 944 | out: |
945 | if (tmpl) | 945 | if (tmpl) { |
946 | nf_ct_put(tmpl); | 946 | /* Special case: we have to repeat this hook, assign the |
947 | * template again to this packet. We assume that this packet | ||
948 | * has no conntrack assigned. This is used by nf_ct_tcp. */ | ||
949 | if (ret == NF_REPEAT) | ||
950 | skb->nfct = (struct nf_conntrack *)tmpl; | ||
951 | else | ||
952 | nf_ct_put(tmpl); | ||
953 | } | ||
947 | 954 | ||
948 | return ret; | 955 | return ret; |
949 | } | 956 | } |
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index 5702de35e2bb..63a1b915a7e4 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c | |||
@@ -63,6 +63,9 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct) | |||
63 | * this does not harm and it happens very rarely. */ | 63 | * this does not harm and it happens very rarely. */ |
64 | unsigned long missed = e->missed; | 64 | unsigned long missed = e->missed; |
65 | 65 | ||
66 | if (!((events | missed) & e->ctmask)) | ||
67 | goto out_unlock; | ||
68 | |||
66 | ret = notify->fcn(events | missed, &item); | 69 | ret = notify->fcn(events | missed, &item); |
67 | if (unlikely(ret < 0 || missed)) { | 70 | if (unlikely(ret < 0 || missed)) { |
68 | spin_lock_bh(&ct->lock); | 71 | spin_lock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 93297aaceb2b..eead9db6f899 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -667,6 +667,7 @@ restart: | |||
667 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, | 667 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, |
668 | cb->nlh->nlmsg_seq, | 668 | cb->nlh->nlmsg_seq, |
669 | IPCTNL_MSG_CT_NEW, ct) < 0) { | 669 | IPCTNL_MSG_CT_NEW, ct) < 0) { |
670 | nf_conntrack_get(&ct->ct_general); | ||
670 | cb->args[1] = (unsigned long)ct; | 671 | cb->args[1] = (unsigned long)ct; |
671 | goto out; | 672 | goto out; |
672 | } | 673 | } |
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index 88f7c3511c72..73c33a42f87f 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c | |||
@@ -53,15 +53,13 @@ iprange_mt4(const struct sk_buff *skb, struct xt_action_param *par) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | static inline int | 55 | static inline int |
56 | iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b) | 56 | iprange_ipv6_lt(const struct in6_addr *a, const struct in6_addr *b) |
57 | { | 57 | { |
58 | unsigned int i; | 58 | unsigned int i; |
59 | int r; | ||
60 | 59 | ||
61 | for (i = 0; i < 4; ++i) { | 60 | for (i = 0; i < 4; ++i) { |
62 | r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]); | 61 | if (a->s6_addr32[i] != b->s6_addr32[i]) |
63 | if (r != 0) | 62 | return ntohl(a->s6_addr32[i]) < ntohl(b->s6_addr32[i]); |
64 | return r; | ||
65 | } | 63 | } |
66 | 64 | ||
67 | return 0; | 65 | return 0; |
@@ -75,15 +73,15 @@ iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par) | |||
75 | bool m; | 73 | bool m; |
76 | 74 | ||
77 | if (info->flags & IPRANGE_SRC) { | 75 | if (info->flags & IPRANGE_SRC) { |
78 | m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0; | 76 | m = iprange_ipv6_lt(&iph->saddr, &info->src_min.in6); |
79 | m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0; | 77 | m |= iprange_ipv6_lt(&info->src_max.in6, &iph->saddr); |
80 | m ^= !!(info->flags & IPRANGE_SRC_INV); | 78 | m ^= !!(info->flags & IPRANGE_SRC_INV); |
81 | if (m) | 79 | if (m) |
82 | return false; | 80 | return false; |
83 | } | 81 | } |
84 | if (info->flags & IPRANGE_DST) { | 82 | if (info->flags & IPRANGE_DST) { |
85 | m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0; | 83 | m = iprange_ipv6_lt(&iph->daddr, &info->dst_min.in6); |
86 | m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0; | 84 | m |= iprange_ipv6_lt(&info->dst_max.in6, &iph->daddr); |
87 | m ^= !!(info->flags & IPRANGE_DST_INV); | 85 | m ^= !!(info->flags & IPRANGE_DST_INV); |
88 | if (m) | 86 | if (m) |
89 | return false; | 87 | return false; |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 55187c8f6420..406207515b5e 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
@@ -27,9 +27,19 @@ | |||
27 | #include <net/sock.h> | 27 | #include <net/sock.h> |
28 | #include <net/x25.h> | 28 | #include <net/x25.h> |
29 | 29 | ||
30 | /* | 30 | /** |
31 | * Parse a set of facilities into the facilities structures. Unrecognised | 31 | * x25_parse_facilities - Parse facilities from skb into the facilities structs |
32 | * facilities are written to the debug log file. | 32 | * |
33 | * @skb: sk_buff to parse | ||
34 | * @facilities: Regular facilites, updated as facilities are found | ||
35 | * @dte_facs: ITU DTE facilities, updated as DTE facilities are found | ||
36 | * @vc_fac_mask: mask is updated with all facilities found | ||
37 | * | ||
38 | * Return codes: | ||
39 | * -1 - Parsing error, caller should drop call and clean up | ||
40 | * 0 - Parse OK, this skb has no facilities | ||
41 | * >0 - Parse OK, returns the length of the facilities header | ||
42 | * | ||
33 | */ | 43 | */ |
34 | int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | 44 | int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, |
35 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) | 45 | struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask) |
@@ -62,7 +72,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
62 | switch (*p & X25_FAC_CLASS_MASK) { | 72 | switch (*p & X25_FAC_CLASS_MASK) { |
63 | case X25_FAC_CLASS_A: | 73 | case X25_FAC_CLASS_A: |
64 | if (len < 2) | 74 | if (len < 2) |
65 | return 0; | 75 | return -1; |
66 | switch (*p) { | 76 | switch (*p) { |
67 | case X25_FAC_REVERSE: | 77 | case X25_FAC_REVERSE: |
68 | if((p[1] & 0x81) == 0x81) { | 78 | if((p[1] & 0x81) == 0x81) { |
@@ -107,7 +117,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
107 | break; | 117 | break; |
108 | case X25_FAC_CLASS_B: | 118 | case X25_FAC_CLASS_B: |
109 | if (len < 3) | 119 | if (len < 3) |
110 | return 0; | 120 | return -1; |
111 | switch (*p) { | 121 | switch (*p) { |
112 | case X25_FAC_PACKET_SIZE: | 122 | case X25_FAC_PACKET_SIZE: |
113 | facilities->pacsize_in = p[1]; | 123 | facilities->pacsize_in = p[1]; |
@@ -130,7 +140,7 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
130 | break; | 140 | break; |
131 | case X25_FAC_CLASS_C: | 141 | case X25_FAC_CLASS_C: |
132 | if (len < 4) | 142 | if (len < 4) |
133 | return 0; | 143 | return -1; |
134 | printk(KERN_DEBUG "X.25: unknown facility %02X, " | 144 | printk(KERN_DEBUG "X.25: unknown facility %02X, " |
135 | "values %02X, %02X, %02X\n", | 145 | "values %02X, %02X, %02X\n", |
136 | p[0], p[1], p[2], p[3]); | 146 | p[0], p[1], p[2], p[3]); |
@@ -139,18 +149,18 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
139 | break; | 149 | break; |
140 | case X25_FAC_CLASS_D: | 150 | case X25_FAC_CLASS_D: |
141 | if (len < p[1] + 2) | 151 | if (len < p[1] + 2) |
142 | return 0; | 152 | return -1; |
143 | switch (*p) { | 153 | switch (*p) { |
144 | case X25_FAC_CALLING_AE: | 154 | case X25_FAC_CALLING_AE: |
145 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) | 155 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
146 | return 0; | 156 | return -1; |
147 | dte_facs->calling_len = p[2]; | 157 | dte_facs->calling_len = p[2]; |
148 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | 158 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); |
149 | *vc_fac_mask |= X25_MASK_CALLING_AE; | 159 | *vc_fac_mask |= X25_MASK_CALLING_AE; |
150 | break; | 160 | break; |
151 | case X25_FAC_CALLED_AE: | 161 | case X25_FAC_CALLED_AE: |
152 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) | 162 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
153 | return 0; | 163 | return -1; |
154 | dte_facs->called_len = p[2]; | 164 | dte_facs->called_len = p[2]; |
155 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | 165 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); |
156 | *vc_fac_mask |= X25_MASK_CALLED_AE; | 166 | *vc_fac_mask |= X25_MASK_CALLED_AE; |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index f729f022be69..15de65f04719 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
@@ -91,10 +91,10 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
91 | { | 91 | { |
92 | struct x25_address source_addr, dest_addr; | 92 | struct x25_address source_addr, dest_addr; |
93 | int len; | 93 | int len; |
94 | struct x25_sock *x25 = x25_sk(sk); | ||
94 | 95 | ||
95 | switch (frametype) { | 96 | switch (frametype) { |
96 | case X25_CALL_ACCEPTED: { | 97 | case X25_CALL_ACCEPTED: { |
97 | struct x25_sock *x25 = x25_sk(sk); | ||
98 | 98 | ||
99 | x25_stop_timer(sk); | 99 | x25_stop_timer(sk); |
100 | x25->condition = 0x00; | 100 | x25->condition = 0x00; |
@@ -113,14 +113,16 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
113 | &dest_addr); | 113 | &dest_addr); |
114 | if (len > 0) | 114 | if (len > 0) |
115 | skb_pull(skb, len); | 115 | skb_pull(skb, len); |
116 | else if (len < 0) | ||
117 | goto out_clear; | ||
116 | 118 | ||
117 | len = x25_parse_facilities(skb, &x25->facilities, | 119 | len = x25_parse_facilities(skb, &x25->facilities, |
118 | &x25->dte_facilities, | 120 | &x25->dte_facilities, |
119 | &x25->vc_facil_mask); | 121 | &x25->vc_facil_mask); |
120 | if (len > 0) | 122 | if (len > 0) |
121 | skb_pull(skb, len); | 123 | skb_pull(skb, len); |
122 | else | 124 | else if (len < 0) |
123 | return -1; | 125 | goto out_clear; |
124 | /* | 126 | /* |
125 | * Copy any Call User Data. | 127 | * Copy any Call User Data. |
126 | */ | 128 | */ |
@@ -144,6 +146,12 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
144 | } | 146 | } |
145 | 147 | ||
146 | return 0; | 148 | return 0; |
149 | |||
150 | out_clear: | ||
151 | x25_write_internal(sk, X25_CLEAR_REQUEST); | ||
152 | x25->state = X25_STATE_2; | ||
153 | x25_start_t23timer(sk); | ||
154 | return 0; | ||
147 | } | 155 | } |
148 | 156 | ||
149 | /* | 157 | /* |
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 4cbc942f762a..21306928d47f 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
@@ -396,9 +396,12 @@ void __exit x25_link_free(void) | |||
396 | write_lock_bh(&x25_neigh_list_lock); | 396 | write_lock_bh(&x25_neigh_list_lock); |
397 | 397 | ||
398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 398 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
399 | struct net_device *dev; | ||
400 | |||
399 | nb = list_entry(entry, struct x25_neigh, node); | 401 | nb = list_entry(entry, struct x25_neigh, node); |
402 | dev = nb->dev; | ||
400 | __x25_remove_neigh(nb); | 403 | __x25_remove_neigh(nb); |
401 | dev_put(nb->dev); | 404 | dev_put(dev); |
402 | } | 405 | } |
403 | write_unlock_bh(&x25_neigh_list_lock); | 406 | write_unlock_bh(&x25_neigh_list_lock); |
404 | } | 407 | } |