diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_if.c | 1 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 2 | ||||
-rw-r--r-- | net/bridge/br_private.h | 1 | ||||
-rw-r--r-- | net/core/ethtool.c | 1 | ||||
-rw-r--r-- | net/core/netpoll.c | 11 | ||||
-rw-r--r-- | net/core/skbuff.c | 3 | ||||
-rw-r--r-- | net/core/sock.c | 7 | ||||
-rw-r--r-- | net/ipv6/route.c | 41 | ||||
-rw-r--r-- | net/l2tp/l2tp_eth.c | 2 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip.c | 9 | ||||
-rw-r--r-- | net/mac80211/rx.c | 5 | ||||
-rw-r--r-- | net/nfc/nci/ntf.c | 4 | ||||
-rw-r--r-- | net/nfc/rawsock.c | 5 |
13 files changed, 66 insertions, 26 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f603e5b0b930..f3f75ad93c89 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -240,6 +240,7 @@ int br_add_bridge(struct net *net, const char *name) return -ENOMEM; dev_net_set(dev, net); + dev->rtnl_link_ops = &br_link_ops; res = register_netdev(dev); if (res) diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index a1daf8227ed1..cbf9ccd45784 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -211,7 +211,7 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } -static struct rtnl_link_ops br_link_ops __read_mostly = { +struct rtnl_link_ops br_link_ops __read_mostly = { .kind = "bridge", .priv_size = sizeof(struct net_bridge), .setup = br_dev_setup, diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 93264dfd1da3..b9bba8fb478a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -536,6 +536,7 @@ extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr) #endif /* br_netlink.c */ +extern struct rtnl_link_ops br_link_ops; extern int br_netlink_init(void); extern void br_netlink_fini(void); extern void br_ifinfo_notify(int event, struct net_bridge_port *port); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 2b587ec07140..236724669855 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -1672,6 +1672,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: case ETHTOOL_GSG: + case ETHTOOL_GSSET_INFO: case ETHTOOL_GSTRINGS: case ETHTOOL_GTSO: case ETHTOOL_GPERMADDR: diff --git a/net/core/netpoll.c b/net/core/netpoll.c index ab0633f15d84..db4bb7a9ca78 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -351,22 +351,23 @@ EXPORT_SYMBOL(netpoll_send_skb_on_dev); void netpoll_send_udp(struct netpoll *np, const char *msg, int len) { - int total_len, eth_len, ip_len, udp_len; + int total_len, ip_len, udp_len; struct sk_buff *skb; struct udphdr *udph; struct iphdr *iph; struct ethhdr *eth; udp_len = len + sizeof(*udph); - ip_len = eth_len = udp_len + sizeof(*iph); - total_len = eth_len + ETH_HLEN + NET_IP_ALIGN; + ip_len = udp_len + sizeof(*iph); + total_len = ip_len + LL_RESERVED_SPACE(np->dev); - skb = find_skb(np, total_len, total_len - len); + skb = find_skb(np, total_len + np->dev->needed_tailroom, + total_len - len); if (!skb) return; skb_copy_to_linear_data(skb, msg, len); - skb->len += len; + skb_put(skb, len); skb_push(skb, sizeof(*udph)); skb_reset_transport_header(skb); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2ec200de08b3..af9c3c6832f6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -1663,6 +1663,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset, struct splice_pipe_desc spd = { .pages = pages, .partial = partial, + .nr_pages_max = MAX_SKB_FRAGS, .flags = flags, .ops = &sock_pipe_buf_ops, .spd_release = sock_spd_release, @@ -1709,7 +1710,7 @@ done: lock_sock(sk); } - splice_shrink_spd(pipe, &spd); + splice_shrink_spd(&spd); return ret; } diff --git a/net/core/sock.c b/net/core/sock.c index a87eb16faabf..718314bfc23b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1497,6 +1497,11 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, gfp_t gfp_mask; long timeo; int err; + int npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + + err = -EMSGSIZE; + if (npages > MAX_SKB_FRAGS) + goto failure; gfp_mask = sk->sk_allocation; if (gfp_mask & __GFP_WAIT) @@ -1515,14 +1520,12 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, if (atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) { skb = alloc_skb(header_len, gfp_mask); if (skb) { - int npages; int i; /* No pages, we're done... */ if (!data_len) break; - npages = (data_len + (PAGE_SIZE - 1)) >> PAGE_SHIFT; skb->truesize += data_len; skb_shinfo(skb)->nr_frags = npages; for (i = 0; i < npages; i++) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 059b9d990ab1..2e21751f94c5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2881,10 +2881,6 @@ static int __net_init ip6_route_net_init(struct net *net) net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ; net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40; -#ifdef CONFIG_PROC_FS - proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); - proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); -#endif net->ipv6.ip6_rt_gc_expire = 30*HZ; ret = 0; @@ -2905,10 +2901,6 @@ out_ip6_dst_ops: static void __net_exit ip6_route_net_exit(struct net *net) { -#ifdef CONFIG_PROC_FS - proc_net_remove(net, "ipv6_route"); - proc_net_remove(net, "rt6_stats"); -#endif kfree(net->ipv6.ip6_null_entry); #ifdef CONFIG_IPV6_MULTIPLE_TABLES kfree(net->ipv6.ip6_prohibit_entry); @@ -2917,11 +2909,33 @@ static void __net_exit ip6_route_net_exit(struct net *net) dst_entries_destroy(&net->ipv6.ip6_dst_ops); } +static int __net_init ip6_route_net_init_late(struct net *net) +{ +#ifdef CONFIG_PROC_FS + proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); + proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); +#endif + return 0; +} + +static void __net_exit ip6_route_net_exit_late(struct net *net) +{ +#ifdef CONFIG_PROC_FS + proc_net_remove(net, "ipv6_route"); + proc_net_remove(net, "rt6_stats"); +#endif +} + static struct pernet_operations ip6_route_net_ops = { .init = ip6_route_net_init, .exit = ip6_route_net_exit, }; +static struct pernet_operations ip6_route_net_late_ops = { + .init = ip6_route_net_init_late, + .exit = ip6_route_net_exit_late, +}; + static struct notifier_block ip6_route_dev_notifier = { .notifier_call = ip6_route_dev_notify, .priority = 0, @@ -2971,19 +2985,25 @@ int __init ip6_route_init(void) if (ret) goto xfrm6_init; + ret = register_pernet_subsys(&ip6_route_net_late_ops); + if (ret) + goto fib6_rules_init; + ret = -ENOBUFS; if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, NULL) || __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, NULL)) - goto fib6_rules_init; + goto out_register_late_subsys; ret = register_netdevice_notifier(&ip6_route_dev_notifier); if (ret) - goto fib6_rules_init; + goto out_register_late_subsys; out: return ret; +out_register_late_subsys: + unregister_pernet_subsys(&ip6_route_net_late_ops); fib6_rules_init: fib6_rules_cleanup(); xfrm6_init: @@ -3002,6 +3022,7 @@ out_kmem_cache: void ip6_route_cleanup(void) { unregister_netdevice_notifier(&ip6_route_dev_notifier); + unregister_pernet_subsys(&ip6_route_net_late_ops); fib6_rules_cleanup(); xfrm6_fini(); fib6_gc_cleanup(); diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index d2726a74597d..3c55f633928e 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -167,6 +167,7 @@ static void l2tp_eth_delete(struct l2tp_session *session) if (dev) { unregister_netdev(dev); spriv->dev = NULL; + module_put(THIS_MODULE); } } } @@ -254,6 +255,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p if (rc < 0) goto out_del_dev; + __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 2fbbe1ffd481..6c7e6095bab1 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -515,10 +515,12 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m sk->sk_bound_dev_if); if (IS_ERR(rt)) goto no_route; - if (connected) + if (connected) { sk_setup_caps(sk, &rt->dst); - else - dst_release(&rt->dst); /* safe since we hold rcu_read_lock */ + } else { + skb_dst_set(skb, &rt->dst); + goto xmit; + } } /* We dont need to clone dst here, it is guaranteed to not disappear. @@ -526,6 +528,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m */ skb_dst_set_noref(skb, &rt->dst); +xmit: /* Queue the packet to IP for output */ rc = ip_queue_xmit(skb, &inet->cork.fl); rcu_read_unlock(); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 642d96c23c9d..6791b22953e6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2389,7 +2389,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * frames that we didn't handle, including returning unknown * ones. For all other modes we will return them to the sender, * setting the 0x80 bit in the action category, as required by - * 802.11-2007 7.3.1.11. + * 802.11-2012 9.24.4. * Newer versions of hostapd shall also use the management frame * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. @@ -2399,6 +2399,9 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; + if (is_multicast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) return RX_DROP_UNUSABLE; diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 96633f5cda4f..12b6a80a5c71 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -86,7 +86,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); data += 2; - nfca_poll->nfcid1_len = *data++; + nfca_poll->nfcid1_len = min_t(__u8, *data++, sizeof(nfca_poll->nfcid1)); nfc_dbg("sens_res 0x%x, nfcid1_len %d", nfca_poll->sens_res, @@ -111,7 +111,7 @@ static int nci_rf_activate_nfca_passive_poll(struct nci_dev *ndev, switch (ntf->rf_interface_type) { case NCI_RF_INTERFACE_ISO_DEP: - nfca_poll_iso_dep->rats_res_len = *data++; + nfca_poll_iso_dep->rats_res_len = min_t(__u8, *data++, 20); if (nfca_poll_iso_dep->rats_res_len > 0) { memcpy(nfca_poll_iso_dep->rats_res, data, diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index ee7b2b365ef2..7a167fce319c 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -52,7 +52,10 @@ static int rawsock_release(struct socket *sock) { struct sock *sk = sock->sk; - nfc_dbg("sock=%p", sock); + nfc_dbg("sock=%p sk=%p", sock, sk); + + if (!sk) + return 0; sock_orphan(sk); sock_put(sk); |