Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Nov 2013 17:57:35 +0000 (09:57 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Nov 2013 17:57:35 +0000 (09:57 -0800)
Pull networking fixes from David Miller:

 1) Fix memory leaks and other issues in mwifiex driver, from Amitkumar
    Karwar.

 2) skb_segment() can choke on packets using frag lists, fix from
    Herbert Xu with help from Eric Dumazet and others.

 3) IPv4 output cached route instantiation properly handles races
    involving two threads trying to install the same route, but we
    forgot to propagate this logic to input routes as well.  Fix from
    Alexei Starovoitov.

 4) Put protections in place to make sure that recvmsg() paths never
    accidently copy uninitialized memory back into userspace and also
    make sure that we never try to use more that sockaddr_storage for
    building the on-kernel-stack copy of a sockaddr.  Fixes from Hannes
    Frederic Sowa.

 5) R8152 driver transmit flow bug fixes from Hayes Wang.

 6) Fix some minor fallouts from genetlink changes, from Johannes Berg
    and Michael Opdenacker.

 7) AF_PACKET sendmsg path can race with netdevice unregister notifier,
    fix by using RCU to make sure the network device doesn't go away
    from under us.  Fix from Daniel Borkmann.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (43 commits)
  gso: handle new frag_list of frags GRO packets
  genetlink: fix genl_set_err() group ID
  genetlink: fix genlmsg_multicast() bug
  packet: fix use after free race in send path when dev is released
  xen-netback: stop the VIF thread before unbinding IRQs
  wimax: remove dead code
  net/phy: Add the autocross feature for forced links on VSC82x4
  net/phy: Add VSC8662 support
  net/phy: Add VSC8574 support
  net/phy: Add VSC8234 support
  net: add BUG_ON if kernel advertises msg_namelen > sizeof(struct sockaddr_storage)
  net: rework recvmsg handler msg_name and msg_namelen logic
  bridge: flush br's address entry in fdb when remove the
  net: core: Always propagate flag changes to interfaces
  ipv4: fix race in concurrent ip_route_input_slow()
  r8152: fix incorrect type in assignment
  r8152: support stopping/waking tx queue
  r8152: modify the tx flow
  r8152: fix tx/rx memory overflow
  netfilter: ebt_ip6: fix source and destination matching
  ...

72 files changed:
crypto/algif_hash.c
crypto/algif_skcipher.c
drivers/isdn/mISDN/socket.c
drivers/net/phy/phy_device.c
drivers/net/phy/vitesse.c
drivers/net/ppp/pppoe.c
drivers/net/usb/r8152.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
drivers/net/wireless/ath/regd.c
drivers/net/wireless/brcm80211/brcmfmac/p2p.c
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/sdio.c
drivers/net/wireless/mwifiex/usb.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/xen-netback/interface.c
include/linux/net.h
include/linux/phy.h
include/net/genetlink.h
net/appletalk/ddp.c
net/atm/common.c
net/ax25/af_ax25.c
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap_core.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/bluetooth/smp.c
net/bridge/br_if.c
net/bridge/netfilter/ebt_ip6.c
net/caif/caif_socket.c
net/compat.c
net/core/dev.c
net/core/iovec.c
net/core/skbuff.c
net/ipv4/netfilter/ipt_SYNPROXY.c
net/ipv4/route.c
net/ipv6/netfilter/ip6t_SYNPROXY.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/iucv/af_iucv.c
net/key/af_key.c
net/l2tp/l2tp_ppp.c
net/llc/af_llc.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_seqadj.c
net/netfilter/nf_synproxy_core.c
net/netfilter/nft_compat.c
net/netlink/af_netlink.c
net/netlink/genetlink.c
net/netrom/af_netrom.c
net/nfc/llcp_sock.c
net/nfc/rawsock.c
net/packet/af_packet.c
net/packet/internal.h
net/rds/recv.c
net/rose/af_rose.c
net/rxrpc/ar-recvmsg.c
net/socket.c
net/tipc/socket.c
net/unix/af_unix.c
net/vmw_vsock/af_vsock.c
net/vmw_vsock/vmci_transport.c
net/wimax/stack.c
net/x25/af_x25.c

index 0262210cad386bde9b75f45d823c730920a54756..ef5356cd280a54c086e4f8ff964245e38748a391 100644 (file)
@@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
        else if (len < ds)
                msg->msg_flags |= MSG_TRUNC;
 
-       msg->msg_namelen = 0;
-
        lock_sock(sk);
        if (ctx->more) {
                ctx->more = 0;
index a1c4f0a555832089129eb77be3680aea03856148..6a6dfc062d2a47f04449fbb0e1c3f3852be337dc 100644 (file)
@@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
        long copied = 0;
 
        lock_sock(sk);
-       msg->msg_namelen = 0;
        for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
             iovlen--, iov++) {
                unsigned long seglen = iov->iov_len;
index e47dcb9d1e91d0ea3e383cdf8b8b09dcde2fce0a..5cefb479c7072359c5c7289d68063925da39797c 100644 (file)
@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
        struct sk_buff          *skb;
        struct sock             *sk = sock->sk;
-       struct sockaddr_mISDN   *maddr;
 
        int             copied, err;
 
@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return err;
 
-       if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
-               msg->msg_namelen = sizeof(struct sockaddr_mISDN);
-               maddr = (struct sockaddr_mISDN *)msg->msg_name;
+       if (msg->msg_name) {
+               struct sockaddr_mISDN *maddr = msg->msg_name;
+
                maddr->family = AF_ISDN;
                maddr->dev = _pms(sk)->dev->id;
                if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                        maddr->sapi = _pms(sk)->ch.addr & 0xFF;
                        maddr->tei =  (_pms(sk)->ch.addr >> 8) & 0xFF;
                }
-       } else {
-               if (msg->msg_namelen)
-                       printk(KERN_WARNING "%s: too small namelen %d\n",
-                              __func__, msg->msg_namelen);
-               msg->msg_namelen = 0;
+               msg->msg_namelen = sizeof(*maddr);
        }
 
        copied = skb->len + MISDN_HEADER_LEN;
index 74630e94fa3bc323b9528b691514d7456b9abd6d..d6447b3f7409d2b19a5c5186f017780bb29080b8 100644 (file)
@@ -697,7 +697,7 @@ static int genphy_config_advert(struct phy_device *phydev)
  *   to the values in phydev. Assumes that the values are valid.
  *   Please see phy_sanitize_settings().
  */
-static int genphy_setup_forced(struct phy_device *phydev)
+int genphy_setup_forced(struct phy_device *phydev)
 {
        int err;
        int ctl = 0;
@@ -716,7 +716,7 @@ static int genphy_setup_forced(struct phy_device *phydev)
 
        return err;
 }
-
+EXPORT_SYMBOL(genphy_setup_forced);
 
 /**
  * genphy_restart_aneg - Enable and Restart Autonegotiation
index 69b482bce7d2449688fc67731cf923ce47ffcc32..508e4359338bc385dc2a0901e24a6351f735f780 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Author: Kriston Carson
  *
- * Copyright (c) 2005, 2009 Freescale Semiconductor, Inc.
+ * Copyright (c) 2005, 2009, 2011 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 
+/* Vitesse Extended Page Magic Register(s) */
+#define MII_VSC82X4_EXT_PAGE_16E       0x10
+#define MII_VSC82X4_EXT_PAGE_17E       0x11
+#define MII_VSC82X4_EXT_PAGE_18E       0x12
+
 /* Vitesse Extended Control Register 1 */
 #define MII_VSC8244_EXT_CON1           0x17
 #define MII_VSC8244_EXTCON1_INIT       0x0000
 #define MII_VSC8221_AUXCONSTAT_INIT    0x0004 /* need to set this bit? */
 #define MII_VSC8221_AUXCONSTAT_RESERVED        0x0004
 
+/* Vitesse Extended Page Access Register */
+#define MII_VSC82X4_EXT_PAGE_ACCESS    0x1f
+
+#define PHY_ID_VSC8234                 0x000fc620
 #define PHY_ID_VSC8244                 0x000fc6c0
+#define PHY_ID_VSC8574                 0x000704a0
+#define PHY_ID_VSC8662                 0x00070660
 #define PHY_ID_VSC8221                 0x000fc550
 #define PHY_ID_VSC8211                 0x000fc4b0
 
@@ -118,7 +129,9 @@ static int vsc82xx_config_intr(struct phy_device *phydev)
 
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
                err = phy_write(phydev, MII_VSC8244_IMASK,
-                       phydev->drv->phy_id == PHY_ID_VSC8244 ?
+                       (phydev->drv->phy_id == PHY_ID_VSC8234 ||
+                        phydev->drv->phy_id == PHY_ID_VSC8244 ||
+                        phydev->drv->phy_id == PHY_ID_VSC8574) ?
                                MII_VSC8244_IMASK_MASK :
                                MII_VSC8221_IMASK_MASK);
        else {
@@ -149,20 +162,113 @@ static int vsc8221_config_init(struct phy_device *phydev)
         */
 }
 
-/* Vitesse 824x */
+/* vsc82x4_config_autocross_enable - Enable auto MDI/MDI-X for forced links
+ * @phydev: target phy_device struct
+ *
+ * Enable auto MDI/MDI-X when in 10/100 forced link speeds by writing
+ * special values in the VSC8234/VSC8244 extended reserved registers
+ */
+static int vsc82x4_config_autocross_enable(struct phy_device *phydev)
+{
+       int ret;
+
+       if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed > SPEED_100)
+               return 0;
+
+       /* map extended registers set 0x10 - 0x1e */
+       ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x52b5);
+       if (ret >= 0)
+               ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_18E, 0x0012);
+       if (ret >= 0)
+               ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_17E, 0x2803);
+       if (ret >= 0)
+               ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_16E, 0x87fa);
+       /* map standard registers set 0x10 - 0x1e */
+       if (ret >= 0)
+               ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
+       else
+               phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000);
+
+       return ret;
+}
+
+/* vsc82x4_config_aneg - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we write the BMCR and also start the auto
+ *   MDI/MDI-X feature
+ */
+static int vsc82x4_config_aneg(struct phy_device *phydev)
+{
+       int ret;
+
+       /* Enable auto MDI/MDI-X when in 10/100 forced link speeds by
+        * writing special values in the VSC8234 extended reserved registers
+        */
+       if (phydev->autoneg != AUTONEG_ENABLE && phydev->speed <= SPEED_100) {
+               ret = genphy_setup_forced(phydev);
+
+               if (ret < 0) /* error */
+                       return ret;
+
+               return vsc82x4_config_autocross_enable(phydev);
+       }
+
+       return genphy_config_aneg(phydev);
+}
+
+/* Vitesse 82xx */
 static struct phy_driver vsc82xx_driver[] = {
 {
+       .phy_id         = PHY_ID_VSC8234,
+       .name           = "Vitesse VSC8234",
+       .phy_id_mask    = 0x000ffff0,
+       .features       = PHY_GBIT_FEATURES,
+       .flags          = PHY_HAS_INTERRUPT,
+       .config_init    = &vsc824x_config_init,
+       .config_aneg    = &vsc82x4_config_aneg,
+       .read_status    = &genphy_read_status,
+       .ack_interrupt  = &vsc824x_ack_interrupt,
+       .config_intr    = &vsc82xx_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
+}, {
        .phy_id         = PHY_ID_VSC8244,
        .name           = "Vitesse VSC8244",
        .phy_id_mask    = 0x000fffc0,
        .features       = PHY_GBIT_FEATURES,
        .flags          = PHY_HAS_INTERRUPT,
        .config_init    = &vsc824x_config_init,
-       .config_aneg    = &genphy_config_aneg,
+       .config_aneg    = &vsc82x4_config_aneg,
        .read_status    = &genphy_read_status,
        .ack_interrupt  = &vsc824x_ack_interrupt,
        .config_intr    = &vsc82xx_config_intr,
        .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_VSC8574,
+       .name           = "Vitesse VSC8574",
+       .phy_id_mask    = 0x000ffff0,
+       .features       = PHY_GBIT_FEATURES,
+       .flags          = PHY_HAS_INTERRUPT,
+       .config_init    = &vsc824x_config_init,
+       .config_aneg    = &vsc82x4_config_aneg,
+       .read_status    = &genphy_read_status,
+       .ack_interrupt  = &vsc824x_ack_interrupt,
+       .config_intr    = &vsc82xx_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
+}, {
+       .phy_id         = PHY_ID_VSC8662,
+       .name           = "Vitesse VSC8662",
+       .phy_id_mask    = 0x000ffff0,
+       .features       = PHY_GBIT_FEATURES,
+       .flags          = PHY_HAS_INTERRUPT,
+       .config_init    = &vsc824x_config_init,
+       .config_aneg    = &vsc82x4_config_aneg,
+       .read_status    = &genphy_read_status,
+       .ack_interrupt  = &vsc824x_ack_interrupt,
+       .config_intr    = &vsc82xx_config_intr,
+       .driver         = { .owner = THIS_MODULE,},
 }, {
        /* Vitesse 8221 */
        .phy_id         = PHY_ID_VSC8221,
@@ -207,7 +313,10 @@ module_init(vsc82xx_init);
 module_exit(vsc82xx_exit);
 
 static struct mdio_device_id __maybe_unused vitesse_tbl[] = {
+       { PHY_ID_VSC8234, 0x000ffff0 },
        { PHY_ID_VSC8244, 0x000fffc0 },
+       { PHY_ID_VSC8574, 0x000ffff0 },
+       { PHY_ID_VSC8662, 0x000ffff0 },
        { PHY_ID_VSC8221, 0x000ffff0 },
        { PHY_ID_VSC8211, 0x000ffff0 },
        { }
index 5f66e30d98239651283ec200cbf3c842e60eb2ae..82ee6ed954cb84272aa41be0fa3ad12eb6c64e2c 100644 (file)
@@ -979,8 +979,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (error < 0)
                goto end;
 
-       m->msg_namelen = 0;
-
        if (skb) {
                total_len = min_t(size_t, total_len, skb->len);
                error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
index f3fce412c0c1a38bb7a5522ebf0d2dd2139bbff5..51073721e22400ef8a553ff153d240cf55789a68 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/ipv6.h>
 
 /* Version Information */
-#define DRIVER_VERSION "v1.01.0 (2013/08/12)"
+#define DRIVER_VERSION "v1.02.0 (2013/10/28)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -307,22 +307,22 @@ enum rtl8152_flags {
 #define MCU_TYPE_USB                   0x0000
 
 struct rx_desc {
-       u32 opts1;
+       __le32 opts1;
 #define RX_LEN_MASK                    0x7fff
-       u32 opts2;
-       u32 opts3;
-       u32 opts4;
-       u32 opts5;
-       u32 opts6;
+       __le32 opts2;
+       __le32 opts3;
+       __le32 opts4;
+       __le32 opts5;
+       __le32 opts6;
 };
 
 struct tx_desc {
-       u32 opts1;
+       __le32 opts1;
 #define TX_FS                  (1 << 31) /* First segment of a packet */
 #define TX_LS                  (1 << 30) /* Final segment of a packet */
 #define TX_LEN_MASK            0x3ffff
 
-       u32 opts2;
+       __le32 opts2;
 #define UDP_CS                 (1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS                 (1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS                        (1 << 29) /* Calculate IPv4 checksum */
@@ -365,6 +365,7 @@ struct r8152 {
        struct mii_if_info mii;
        int intr_interval;
        u32 msg_enable;
+       u32 tx_qlen;
        u16 ocp_base;
        u8 *intr_buff;
        u8 version;
@@ -876,7 +877,7 @@ static void write_bulk_callback(struct urb *urb)
 static void intr_callback(struct urb *urb)
 {
        struct r8152 *tp;
-       __u16 *d;
+       __le16 *d;
        int status = urb->status;
        int res;
 
@@ -1136,14 +1137,14 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 {
-       u32 remain;
+       int remain;
        u8 *tx_data;
 
        tx_data = agg->head;
        agg->skb_num = agg->skb_len = 0;
-       remain = rx_buf_sz - sizeof(struct tx_desc);
+       remain = rx_buf_sz;
 
-       while (remain >= ETH_ZLEN) {
+       while (remain >= ETH_ZLEN + sizeof(struct tx_desc)) {
                struct tx_desc *tx_desc;
                struct sk_buff *skb;
                unsigned int len;
@@ -1152,12 +1153,14 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
                if (!skb)
                        break;
 
+               remain -= sizeof(*tx_desc);
                len = skb->len;
                if (remain < len) {
                        skb_queue_head(&tp->tx_queue, skb);
                        break;
                }
 
+               tx_data = tx_agg_align(tx_data);
                tx_desc = (struct tx_desc *)tx_data;
                tx_data += sizeof(*tx_desc);
 
@@ -1167,11 +1170,18 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
                agg->skb_len += len;
                dev_kfree_skb_any(skb);
 
-               tx_data = tx_agg_align(tx_data + len);
-               remain = rx_buf_sz - sizeof(*tx_desc) -
-                        (u32)((void *)tx_data - agg->head);
+               tx_data += len;
+               remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
        }
 
+       netif_tx_lock(tp->netdev);
+
+       if (netif_queue_stopped(tp->netdev) &&
+           skb_queue_len(&tp->tx_queue) < tp->tx_qlen)
+               netif_wake_queue(tp->netdev);
+
+       netif_tx_unlock(tp->netdev);
+
        usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
                          agg->head, (int)(tx_data - (u8 *)agg->head),
                          (usb_complete_t)write_bulk_callback, agg);
@@ -1188,7 +1198,6 @@ static void rx_bottom(struct r8152 *tp)
        list_for_each_safe(cursor, next, &tp->rx_done) {
                struct rx_desc *rx_desc;
                struct rx_agg *agg;
-               unsigned pkt_len;
                int len_used = 0;
                struct urb *urb;
                u8 *rx_data;
@@ -1204,17 +1213,22 @@ static void rx_bottom(struct r8152 *tp)
 
                rx_desc = agg->head;
                rx_data = agg->head;
-               pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
-               len_used += sizeof(struct rx_desc) + pkt_len;
+               len_used += sizeof(struct rx_desc);
 
-               while (urb->actual_length >= len_used) {
+               while (urb->actual_length > len_used) {
                        struct net_device *netdev = tp->netdev;
                        struct net_device_stats *stats;
+                       unsigned int pkt_len;
                        struct sk_buff *skb;
 
+                       pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
                        if (pkt_len < ETH_ZLEN)
                                break;
 
+                       len_used += pkt_len;
+                       if (urb->actual_length < len_used)
+                               break;
+
                        stats = rtl8152_get_stats(netdev);
 
                        pkt_len -= 4; /* CRC */
@@ -1234,9 +1248,8 @@ static void rx_bottom(struct r8152 *tp)
 
                        rx_data = rx_agg_align(rx_data + pkt_len + 4);
                        rx_desc = (struct rx_desc *)rx_data;
-                       pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
                        len_used = (int)(rx_data - (u8 *)agg->head);
-                       len_used += sizeof(struct rx_desc) + pkt_len;
+                       len_used += sizeof(struct rx_desc);
                }
 
 submit:
@@ -1384,53 +1397,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
                                            struct net_device *netdev)
 {
        struct r8152 *tp = netdev_priv(netdev);
-       struct net_device_stats *stats = rtl8152_get_stats(netdev);
-       unsigned long flags;
-       struct tx_agg *agg = NULL;
-       struct tx_desc *tx_desc;
-       unsigned int len;
-       u8 *tx_data;
-       int res;
 
        skb_tx_timestamp(skb);
 
-       /* If tx_queue is not empty, it means at least one previous packt */
-       /* is waiting for sending. Don't send current one before it.      */
-       if (skb_queue_empty(&tp->tx_queue))
-               agg = r8152_get_tx_agg(tp);
-
-       if (!agg) {
-               skb_queue_tail(&tp->tx_queue, skb);
-               return NETDEV_TX_OK;
-       }
+       skb_queue_tail(&tp->tx_queue, skb);
 
-       tx_desc = (struct tx_desc *)agg->head;
-       tx_data = agg->head + sizeof(*tx_desc);
-       agg->skb_num = agg->skb_len = 0;
+       if (list_empty(&tp->tx_free) &&
+           skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
+               netif_stop_queue(netdev);
 
-       len = skb->len;
-       r8152_tx_csum(tp, tx_desc, skb);
-       memcpy(tx_data, skb->data, len);
-       dev_kfree_skb_any(skb);
-       agg->skb_num++;
-       agg->skb_len += len;
-       usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
-                         agg->head, len + sizeof(*tx_desc),
-                         (usb_complete_t)write_bulk_callback, agg);
-       res = usb_submit_urb(agg->urb, GFP_ATOMIC);
-       if (res) {
-               /* Can we get/handle EPIPE here? */
-               if (res == -ENODEV) {
-                       netif_device_detach(tp->netdev);
-               } else {
-                       netif_warn(tp, tx_err, netdev,
-                                  "failed tx_urb %d\n", res);
-                       stats->tx_dropped++;
-                       spin_lock_irqsave(&tp->tx_lock, flags);
-                       list_add_tail(&agg->list, &tp->tx_free);
-                       spin_unlock_irqrestore(&tp->tx_lock, flags);
-               }
-       }
+       if (!list_empty(&tp->tx_free))
+               tasklet_schedule(&tp->tl);
 
        return NETDEV_TX_OK;
 }
@@ -1459,6 +1436,14 @@ static void rtl8152_nic_reset(struct r8152 *tp)
        }
 }
 
+static void set_tx_qlen(struct r8152 *tp)
+{
+       struct net_device *netdev = tp->netdev;
+
+       tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN +
+                                  sizeof(struct tx_desc));
+}
+
 static inline u8 rtl8152_get_speed(struct r8152 *tp)
 {
        return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
@@ -1470,6 +1455,7 @@ static int rtl8152_enable(struct r8152 *tp)
        int i, ret;
        u8 speed;
 
+       set_tx_qlen(tp);
        speed = rtl8152_get_speed(tp);
        if (speed & _10bps) {
                ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
index 11f53589a3f34879b6ab3e8d9062e294fb6f7260..d39b79f5e841ada25c0e1bf435e7c7fd926c15ea 100644 (file)
@@ -701,6 +701,54 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
        return ret;
 }
 
+static void ar9003_doubler_fix(struct ath_hw *ah)
+{
+       if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
+               REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
+               REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
+               REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0);
+
+               udelay(200);
+
+               REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2,
+                           AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
+               REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2,
+                           AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
+               REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2,
+                           AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK);
+
+               udelay(1);
+
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2,
+                             AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2,
+                             AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2,
+                             AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1);
+
+               udelay(200);
+
+               REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12,
+                             AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf);
+
+               REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
+               REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
+               REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0,
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S |
+                       1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S);
+       }
+}
+
 static int ar9003_hw_process_ini(struct ath_hw *ah,
                                 struct ath9k_channel *chan)
 {
@@ -726,6 +774,8 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
                                           modesIndex);
        }
 
+       ar9003_doubler_fix(ah);
+
        /*
         * RXGAIN initvals.
         */
index fca624322dc8886f991632d7a2d5e78b0bdfa114..2af667beb2738ea498c87ed171d8e4aed5e31bd5 100644 (file)
 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT   ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00000001 : 0x00000002)
 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0 : 1)
 #define AR_PHY_65NM_CH0_SYNTH7      0x16098
+#define AR_PHY_65NM_CH0_SYNTH12     0x160ac
 #define AR_PHY_65NM_CH0_BIAS1       0x160c0
 #define AR_PHY_65NM_CH0_BIAS2       0x160c4
 #define AR_PHY_65NM_CH0_BIAS4       0x160cc
+#define AR_PHY_65NM_CH0_RXTX2       0x16104
+#define AR_PHY_65NM_CH1_RXTX2       0x16504
+#define AR_PHY_65NM_CH2_RXTX2       0x16904
 #define AR_PHY_65NM_CH0_RXTX4       0x1610c
 #define AR_PHY_65NM_CH1_RXTX4       0x1650c
 #define AR_PHY_65NM_CH2_RXTX4       0x1690c
 
+#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3           0x00780000
+#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S         19
+#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK         0x00000004
+#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S       2
+#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK        0x00000008
+#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S      3
+
 #define AR_CH0_TOP     (AR_SREV_9300(ah) ? 0x16288 : \
                         (((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280)))
 #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300)
index 4dbc294df7e39eb9ccedf3abe1a6613a45060612..57fc5f459d0aa6a40719407b8c287ac7f3786d00 100644 (file)
@@ -361,7 +361,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
        {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
        {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
-       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+       {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5},
        {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
        {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
        {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
@@ -400,7 +400,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
        {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
        {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
        {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
-       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa},
        {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
 };
 
@@ -472,7 +472,7 @@ static const u32 ar9462_2p1_radio_postamble[][5] = {
 
 static const u32 ar9462_2p1_soc_preamble[][2] = {
        /* Addr      allmodes  */
-       {0x000040a4, 0x00a0c1c9},
+       {0x000040a4, 0x00a0c9c9},
        {0x00007020, 0x00000000},
        {0x00007034, 0x00000002},
        {0x00007038, 0x000004c2},
index c00687e05688e6498b70131ba11c1105d0b933b1..1217c52ab28e6b07847217890bb6f1d9840a84b1 100644 (file)
@@ -362,7 +362,8 @@ static int __ath_reg_dyn_country(struct wiphy *wiphy,
 {
        u16 country_code;
 
-       if (!ath_is_world_regd(reg))
+       if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
+           !ath_is_world_regd(reg))
                return -EINVAL;
 
        country_code = ath_regd_find_country_by_name(request->alpha2);
index 5b5b952d47b194950c881eea53176df6ffe70af6..4a2293041821ff708c6cefef86ed21406f18266c 100644 (file)
@@ -823,6 +823,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
                }
                err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state,
                                      action, P2PAPI_BSSCFG_DEVICE);
+               kfree(chanspecs);
        }
 exit:
        if (err)
index fbad00a5abc83502c3a16a7762f05bf6dcccf36a..aeaea0e3b4c414ae925b79a3eb4962f7bb36ad4b 100644 (file)
@@ -2210,8 +2210,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                priv->bss_started = 0;
                priv->bss_num = 0;
 
-               if (mwifiex_cfg80211_init_p2p_client(priv))
-                       return ERR_PTR(-EFAULT);
+               if (mwifiex_cfg80211_init_p2p_client(priv)) {
+                       wdev = ERR_PTR(-EFAULT);
+                       goto done;
+               }
 
                break;
        default:
@@ -2224,7 +2226,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
        if (!dev) {
                wiphy_err(wiphy, "no memory available for netdevice\n");
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-               return ERR_PTR(-ENOMEM);
+               wdev = ERR_PTR(-ENOMEM);
+               goto done;
        }
 
        mwifiex_init_priv_params(priv, dev);
@@ -2264,7 +2267,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
                wiphy_err(wiphy, "cannot register virtual network device\n");
                free_netdev(dev);
                priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
-               return ERR_PTR(-EFAULT);
+               priv->netdev = NULL;
+               wdev = ERR_PTR(-EFAULT);
+               goto done;
        }
 
        sema_init(&priv->async_sem, 1);
@@ -2274,6 +2279,13 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
 #ifdef CONFIG_DEBUG_FS
        mwifiex_dev_debugfs_init(priv);
 #endif
+
+done:
+       if (IS_ERR(wdev)) {
+               kfree(priv->wdev);
+               priv->wdev = NULL;
+       }
+
        return wdev;
 }
 EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
@@ -2298,7 +2310,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
                unregister_netdevice(wdev->netdev);
 
        /* Clear the priv in adapter */
+       priv->netdev->ieee80211_ptr = NULL;
        priv->netdev = NULL;
+       kfree(wdev);
+       priv->wdev = NULL;
 
        priv->media_connected = false;
 
index 9d7c9d354d34aeb9e0b3e4bf854fc6a999671958..78e8a6666cc6edad81bd87c98dcf0353af371866 100644 (file)
@@ -411,13 +411,14 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
  */
 static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
 {
-       int ret, i;
+       int ret;
        char fmt[64];
        struct mwifiex_private *priv;
        struct mwifiex_adapter *adapter = context;
        struct mwifiex_fw_image fw;
        struct semaphore *sem = adapter->card_sem;
        bool init_failed = false;
+       struct wireless_dev *wdev;
 
        if (!firmware) {
                dev_err(adapter->dev,
@@ -469,14 +470,16 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
        priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
        if (mwifiex_register_cfg80211(adapter)) {
                dev_err(adapter->dev, "cannot register with cfg80211\n");
-               goto err_register_cfg80211;
+               goto err_init_fw;
        }
 
        rtnl_lock();
        /* Create station interface by default */
-       if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
-                                     NL80211_IFTYPE_STATION, NULL, NULL)) {
+       wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
+                                       NL80211_IFTYPE_STATION, NULL, NULL);
+       if (IS_ERR(wdev)) {
                dev_err(adapter->dev, "cannot create default STA interface\n");
+               rtnl_unlock();
                goto err_add_intf;
        }
        rtnl_unlock();
@@ -486,17 +489,6 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
        goto done;
 
 err_add_intf:
-       for (i = 0; i < adapter->priv_num; i++) {
-               priv = adapter->priv[i];
-
-               if (!priv)
-                       continue;
-
-               if (priv->wdev && priv->netdev)
-                       mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
-       }
-       rtnl_unlock();
-err_register_cfg80211:
        wiphy_unregister(adapter->wiphy);
        wiphy_free(adapter->wiphy);
 err_init_fw:
@@ -1006,12 +998,6 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
        wiphy_unregister(priv->wdev->wiphy);
        wiphy_free(priv->wdev->wiphy);
 
-       for (i = 0; i < adapter->priv_num; i++) {
-               priv = adapter->priv[i];
-               if (priv)
-                       kfree(priv->wdev);
-       }
-
        mwifiex_terminate_workqueue(adapter);
 
        /* Unregister device */
index 33fa9432b241b353c3ae381ab57c48d5d71f763b..03688aa14e8adb8575163e3a40aeda4a70a32c19 100644 (file)
@@ -232,7 +232,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
        }
 
        mwifiex_remove_card(card->adapter, &add_remove_card_sem);
-       kfree(card);
 }
 
 static void mwifiex_pcie_shutdown(struct pci_dev *pdev)
@@ -2313,6 +2312,7 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter)
                pci_release_region(pdev, 0);
                pci_set_drvdata(pdev, NULL);
        }
+       kfree(card);
 }
 
 /*
index 9bf8898743ab3d8a31aaad7641ecad09204e0265..b44a31523461e2c5ba7d768c941fc0934abaacb6 100644 (file)
@@ -196,7 +196,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
        }
 
        mwifiex_remove_card(card->adapter, &add_remove_card_sem);
-       kfree(card);
 }
 
 /*
@@ -1745,7 +1744,6 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
                sdio_claim_host(card->func);
                sdio_disable_func(card->func);
                sdio_release_host(card->func);
-               sdio_set_drvdata(card->func, NULL);
        }
 }
 
@@ -1773,7 +1771,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
                return ret;
        }
 
-       sdio_set_drvdata(func, card);
 
        adapter->dev = &func->dev;
 
@@ -1801,6 +1798,8 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
        int ret;
        u8 sdio_ireg;
 
+       sdio_set_drvdata(card->func, card);
+
        /*
         * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
         * from the bootloader. If we don't do this we get a interrupt
@@ -1883,6 +1882,8 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
        kfree(card->mpa_rx.len_arr);
        kfree(card->mpa_tx.buf);
        kfree(card->mpa_rx.buf);
+       sdio_set_drvdata(card->func, NULL);
+       kfree(card);
 }
 
 /*
index 1c70b8d092270ba3a456664aaf6ec3e9da4b3b59..edf5b7a24900ec1edf8d1fbb1e426b5268d2d3e2 100644 (file)
@@ -350,7 +350,6 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
 
        card->udev = udev;
        card->intf = intf;
-       usb_card = card;
 
        pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
                 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
@@ -525,25 +524,28 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
 static void mwifiex_usb_disconnect(struct usb_interface *intf)
 {
        struct usb_card_rec *card = usb_get_intfdata(intf);
-       struct mwifiex_adapter *adapter;
 
-       if (!card || !card->adapter) {
-               pr_err("%s: card or card->adapter is NULL\n", __func__);
+       if (!card) {
+               pr_err("%s: card is NULL\n", __func__);
                return;
        }
 
-       adapter = card->adapter;
-       if (!adapter->priv_num)
-               return;
-
        mwifiex_usb_free(card);
 
-       dev_dbg(adapter->dev, "%s: removing card\n", __func__);
-       mwifiex_remove_card(adapter, &add_remove_card_sem);
+       if (card->adapter) {
+               struct mwifiex_adapter *adapter = card->adapter;
+
+               if (!adapter->priv_num)
+                       return;
+
+               dev_dbg(adapter->dev, "%s: removing card\n", __func__);
+               mwifiex_remove_card(adapter, &add_remove_card_sem);
+       }
 
        usb_set_intfdata(intf, NULL);
        usb_put_dev(interface_to_usbdev(intf));
        kfree(card);
+       usb_card = NULL;
 
        return;
 }
@@ -754,6 +756,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
        card->adapter = adapter;
        adapter->dev = &card->udev->dev;
        strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
+       usb_card = card;
 
        return 0;
 }
@@ -762,7 +765,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
 {
        struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
 
-       usb_set_intfdata(card->intf, NULL);
+       card->adapter = NULL;
 }
 
 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
@@ -1004,7 +1007,7 @@ static void mwifiex_usb_cleanup_module(void)
        if (!down_interruptible(&add_remove_card_sem))
                up(&add_remove_card_sem);
 
-       if (usb_card) {
+       if (usb_card && usb_card->adapter) {
                struct mwifiex_adapter *adapter = usb_card->adapter;
                int i;
 
index 080b1fcae5fa8f3f2b376d5b77bffab2519ddf57..9dd92a700442a4c7e3aa8b2bacc97830b4a95148 100644 (file)
@@ -181,6 +181,7 @@ static void rt2x00lib_autowakeup(struct work_struct *work)
 static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
                                     struct ieee80211_vif *vif)
 {
+       struct ieee80211_tx_control control = {};
        struct rt2x00_dev *rt2x00dev = data;
        struct sk_buff *skb;
 
@@ -195,7 +196,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac,
         */
        skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
        while (skb) {
-               rt2x00mac_tx(rt2x00dev->hw, NULL, skb);
+               rt2x00mac_tx(rt2x00dev->hw, &control, skb);
                skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
        }
 }
index 393685390f3ee41f78a903d198eb51484654a55f..e26312fb4356720b06e3f844423a96ca07dd79e4 100644 (file)
@@ -769,7 +769,7 @@ static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw,
 
 static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
                                      struct rtl_stats *pstats,
-                                     struct rx_desc_92c *pdesc,
+                                     struct rx_desc_92c *p_desc,
                                      struct rx_fwinfo_92c *p_drvinfo,
                                      bool packet_match_bssid,
                                      bool packet_toself,
@@ -784,11 +784,11 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
        u32 rssi, total_rssi = 0;
        bool in_powersavemode = false;
        bool is_cck_rate;
+       u8 *pdesc = (u8 *)p_desc;
 
-       is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
+       is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc);
        pstats->packet_matchbssid = packet_match_bssid;
        pstats->packet_toself = packet_toself;
-       pstats->is_cck = is_cck_rate;
        pstats->packet_beacon = packet_beacon;
        pstats->is_cck = is_cck_rate;
        pstats->RX_SIGQ[0] = -1;
index b0c346a9e4b8ca8adf9df562ac444d478a3ece57..1bc21ccfa71b85f671afebb8d2826e43be45f9e9 100644 (file)
@@ -303,10 +303,10 @@ out:
 bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
                           struct rtl_stats *stats,
                           struct ieee80211_rx_status *rx_status,
-                          u8 *p_desc, struct sk_buff *skb)
+                          u8 *pdesc, struct sk_buff *skb)
 {
        struct rx_fwinfo_92c *p_drvinfo;
-       struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
+       struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc;
        u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc);
 
        stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
@@ -345,7 +345,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
        if (phystatus) {
                p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
                                                     stats->rx_bufshift);
-               rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc,
+               rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc,
                                                 p_drvinfo);
        }
        /*rx_status->qual = stats->signal; */
index b78ee10a956a199e8d5e1a1615d5a6e1cbe94acd..2329cccf1fa6dd15f65c4dc30c54c62cce0551a7 100644 (file)
@@ -461,6 +461,9 @@ void xenvif_disconnect(struct xenvif *vif)
        if (netif_carrier_ok(vif->dev))
                xenvif_carrier_off(vif);
 
+       if (vif->task)
+               kthread_stop(vif->task);
+
        if (vif->tx_irq) {
                if (vif->tx_irq == vif->rx_irq)
                        unbind_from_irqhandler(vif->tx_irq, vif);
@@ -471,9 +474,6 @@ void xenvif_disconnect(struct xenvif *vif)
                vif->tx_irq = 0;
        }
 
-       if (vif->task)
-               kthread_stop(vif->task);
-
        xenvif_unmap_frontend_rings(vif);
 }
 
index b292a04355717a503b093e2d2c424cf92951415f..4bcee94cef9314c44dfaa94fb17d3c905fefee08 100644 (file)
@@ -164,6 +164,14 @@ struct proto_ops {
 #endif
        int             (*sendmsg)   (struct kiocb *iocb, struct socket *sock,
                                      struct msghdr *m, size_t total_len);
+       /* Notes for implementing recvmsg:
+        * ===============================
+        * msg->msg_namelen should get updated by the recvmsg handlers
+        * iff msg_name != NULL. It is by default 0 to prevent
+        * returning uninitialized memory to user space.  The recvfrom
+        * handlers can assume that msg.msg_name is either NULL or has
+        * a minimum size of sizeof(struct sockaddr_storage).
+        */
        int             (*recvmsg)   (struct kiocb *iocb, struct socket *sock,
                                      struct msghdr *m, size_t total_len,
                                      int flags);
index 64ab823f7b7451f77aa4b58df22b4a3a54c30db1..48a4dc3cb8cf26b91af2bd2cb147bf6879956695 100644 (file)
@@ -559,6 +559,7 @@ static inline int phy_read_status(struct phy_device *phydev) {
        return phydev->drv->read_status(phydev);
 }
 
+int genphy_setup_forced(struct phy_device *phydev);
 int genphy_restart_aneg(struct phy_device *phydev);
 int genphy_config_aneg(struct phy_device *phydev);
 int genphy_update_link(struct phy_device *phydev);
index ace4abf118d7d4b0501fa3c6829001da905e728b..1b177ed803b7aa99045fec46e6449b29b76ac323 100644 (file)
@@ -265,7 +265,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
                                          struct net *net, struct sk_buff *skb,
                                          u32 portid, unsigned int group, gfp_t flags)
 {
-       if (group >= family->n_mcgrps)
+       if (WARN_ON_ONCE(group >= family->n_mcgrps))
                return -EINVAL;
        group = family->mcgrp_offset + group;
        return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
@@ -283,9 +283,6 @@ static inline int genlmsg_multicast(struct genl_family *family,
                                    struct sk_buff *skb, u32 portid,
                                    unsigned int group, gfp_t flags)
 {
-       if (group >= family->n_mcgrps)
-               return -EINVAL;
-       group = family->mcgrp_offset + group;
        return genlmsg_multicast_netns(family, &init_net, skb,
                                       portid, group, flags);
 }
@@ -387,6 +384,9 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
 static inline int genl_set_err(struct genl_family *family, struct net *net,
                               u32 portid, u32 group, int code)
 {
+       if (WARN_ON_ONCE(group >= family->n_mcgrps))
+               return -EINVAL;
+       group = family->mcgrp_offset + group;
        return netlink_set_err(net->genl_sock, portid, group, code);
 }
 
index 7fee50d637f956240a6146b342e7723a131ce4bd..7d424ac6e760bbb5d11ad3c164052374fd0491d1 100644 (file)
@@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                         size_t size, int flags)
 {
        struct sock *sk = sock->sk;
-       struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
        struct ddpehdr *ddp;
        int copied = 0;
        int offset = 0;
@@ -1764,14 +1763,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        }
        err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
 
-       if (!err) {
-               if (sat) {
-                       sat->sat_family      = AF_APPLETALK;
-                       sat->sat_port        = ddp->deh_sport;
-                       sat->sat_addr.s_node = ddp->deh_snode;
-                       sat->sat_addr.s_net  = ddp->deh_snet;
-               }
-               msg->msg_namelen = sizeof(*sat);
+       if (!err && msg->msg_name) {
+               struct sockaddr_at *sat = msg->msg_name;
+               sat->sat_family      = AF_APPLETALK;
+               sat->sat_port        = ddp->deh_sport;
+               sat->sat_addr.s_node = ddp->deh_snode;
+               sat->sat_addr.s_net  = ddp->deh_snet;
+               msg->msg_namelen     = sizeof(*sat);
        }
 
        skb_free_datagram(sk, skb);     /* Free the datagram. */
index 737bef59ce899adc0a3e0ba67ea3d56536e5b7e5..7b491006eaf4000424282979b0c4709325102152 100644 (file)
@@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        struct sk_buff *skb;
        int copied, error = -EINVAL;
 
-       msg->msg_namelen = 0;
-
        if (sock->state != SS_CONNECTED)
                return -ENOTCONN;
 
index a00123ebb0ae0705c8e45e8433a07e96a2a06fe5..7bb1605bdfd999d134507b2a925b747bd1e5a07b 100644 (file)
@@ -1636,11 +1636,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-       if (msg->msg_namelen != 0) {
-               struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
+       if (msg->msg_name) {
                ax25_digi digi;
                ax25_address src;
                const unsigned char *mac = skb_mac_header(skb);
+               struct sockaddr_ax25 *sax = msg->msg_name;
 
                memset(sax, 0, sizeof(struct full_sockaddr_ax25));
                ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
index f6a1671ea2ff793bfca0efdd1541765803fb4d03..56ca494621c66e76465aaada6be27d5f6820e33e 100644 (file)
@@ -224,10 +224,9 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb = skb_recv_datagram(sk, flags, noblock, &err);
        if (!skb) {
-               if (sk->sk_shutdown & RCV_SHUTDOWN) {
-                       msg->msg_namelen = 0;
+               if (sk->sk_shutdown & RCV_SHUTDOWN)
                        return 0;
-               }
+
                return err;
        }
 
@@ -245,8 +244,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                if (bt_sk(sk)->skb_msg_name)
                        bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
                                                &msg->msg_namelen);
-               else
-                       msg->msg_namelen = 0;
        }
 
        skb_free_datagram(sk, skb);
@@ -295,8 +292,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags & MSG_OOB)
                return -EOPNOTSUPP;
 
-       msg->msg_namelen = 0;
-
        BT_DBG("sk %p size %zu", sk, size);
 
        lock_sock(sk);
index 71f0be1730801a615191a9badc2bd2f588bd4fbb..6a6c8bb4fd72d4f2d4294b9f7fed772d81e57b93 100644 (file)
@@ -856,8 +856,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return err;
 
-       msg->msg_namelen = 0;
-
        copied = skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index 0cef677078381315c7ce3e58abb6573136bc227b..4af3821df880f70dd17cd36161eff766c3e49334 100644 (file)
@@ -2439,6 +2439,9 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
        int err;
        struct sk_buff_head seg_queue;
 
+       if (!chan->conn)
+               return -ENOTCONN;
+
        /* Connectionless channel */
        if (chan->chan_type == L2CAP_CHAN_CONN_LESS) {
                skb = l2cap_create_connless_pdu(chan, msg, len, priority);
index 94d06cbfbc184a6e827aa5c3cbd15d4693eca49a..facd8a79c0383eb8898fca8dc905c87ed623202a 100644 (file)
@@ -694,6 +694,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_psm    = 0;
        addr.l2_cid    = 0;
+       addr.l2_bdaddr_type = BDADDR_BREDR;
        *err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
        if (*err < 0)
                goto failed;
@@ -719,6 +720,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_psm    = __constant_cpu_to_le16(RFCOMM_PSM);
        addr.l2_cid    = 0;
+       addr.l2_bdaddr_type = BDADDR_BREDR;
        *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
        if (*err == 0 || *err == -EINPROGRESS)
                return s;
@@ -1983,6 +1985,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
        addr.l2_family = AF_BLUETOOTH;
        addr.l2_psm    = __constant_cpu_to_le16(RFCOMM_PSM);
        addr.l2_cid    = 0;
+       addr.l2_bdaddr_type = BDADDR_BREDR;
        err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
        if (err < 0) {
                BT_ERR("Bind failed %d", err);
index c4d3d423f89b84d41b9ff0e6919e9f37786f4960..3c2d3e4aa2f58a271bea6632451edd21b92668a9 100644 (file)
@@ -615,7 +615,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
                rfcomm_dlc_accept(d);
-               msg->msg_namelen = 0;
                return 0;
        }
 
@@ -739,8 +738,9 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
 static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
 {
        struct sock *sk = sock->sk;
+       struct sock *l2cap_sk;
+       struct l2cap_conn *conn;
        struct rfcomm_conninfo cinfo;
-       struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
        int len, err = 0;
        u32 opt;
 
@@ -783,6 +783,9 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
                        break;
                }
 
+               l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
+               conn = l2cap_pi(l2cap_sk)->chan->conn;
+
                memset(&cinfo, 0, sizeof(cinfo));
                cinfo.hci_handle = conn->hcon->handle;
                memcpy(cinfo.dev_class, conn->hcon->dev_class, 3);
index 12a0e51e21e13631beeec14d97e64aa137fd0e99..24fa3964b3c84da299287d6c913771c579d6a9a5 100644 (file)
@@ -711,7 +711,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
            test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
                sco_conn_defer_accept(pi->conn->hcon, pi->setting);
                sk->sk_state = BT_CONFIG;
-               msg->msg_namelen = 0;
 
                release_sock(sk);
                return 0;
index 85a2796cac61bcc423ef724f1911f2a794667aff..4b07acb8293c3df3542e2a1661a6ae07bcfa6596 100644 (file)
@@ -742,6 +742,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
        BT_DBG("conn %p", conn);
 
+       if (!(conn->hcon->link_mode & HCI_LM_MASTER))
+               return SMP_CMD_NOTSUPP;
+
        hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req);
 
        if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
index 6e6194fcd88e1c3427c24a9c914956cc1bd1e66d..4bf02adb5dc2433709ce06d6f4b4fdc48e171dd0 100644 (file)
@@ -172,6 +172,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
                del_nbp(p);
        }
 
+       br_fdb_delete_by_port(br, NULL, 1);
+
        br_vlan_flush(br);
        del_timer_sync(&br->gc_timer);
 
index 99c85668f5518ab9ee8d05a7b085139734893fdd..17fd5f2cb4b89cbf4e00b62b09bab7685b9f3965 100644 (file)
@@ -48,10 +48,12 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par)
        if (info->bitmask & EBT_IP6_TCLASS &&
           FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
                return false;
-       if (FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
-                                      &info->saddr), EBT_IP6_SOURCE) ||
+       if ((info->bitmask & EBT_IP6_SOURCE &&
+           FWINV(ipv6_masked_addr_cmp(&ih6->saddr, &info->smsk,
+                                      &info->saddr), EBT_IP6_SOURCE)) ||
+           (info->bitmask & EBT_IP6_DEST &&
            FWINV(ipv6_masked_addr_cmp(&ih6->daddr, &info->dmsk,
-                                      &info->daddr), EBT_IP6_DEST))
+                                      &info->daddr), EBT_IP6_DEST)))
                return false;
        if (info->bitmask & EBT_IP6_PROTO) {
                uint8_t nexthdr = ih6->nexthdr;
index 05a41c7ec304e4256dca41b6b111bc1a267598b5..d6be3edb7a43493a18766c6824b0a1c9ac430d05 100644 (file)
@@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (m->msg_flags&MSG_OOB)
                goto read_error;
 
-       m->msg_namelen = 0;
-
        skb = skb_recv_datagram(sk, flags, 0 , &ret);
        if (!skb)
                goto read_error;
@@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags&MSG_OOB)
                goto out;
 
-       msg->msg_namelen = 0;
-
        /*
         * Lock the socket to prevent queue disordering
         * while sleeps in memcpy_tomsg
index 89032580bd1d8aa5ef29d1395661bdd0bcfe95f1..618c6a8a911b65c9a406ba5d7d0e221cb124960e 100644 (file)
@@ -93,7 +93,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
                        if (err < 0)
                                return err;
                }
-               kern_msg->msg_name = kern_address;
+               if (kern_msg->msg_name)
+                       kern_msg->msg_name = kern_address;
        } else
                kern_msg->msg_name = NULL;
 
index 7e00a7342ee6aa4e9d7ab408423694fecb2966db..ba3b7ea5ebb3139cca38e82ac6f5f5e346f4a4e0 100644 (file)
@@ -4996,7 +4996,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
 
-       if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
+       if (ops->ndo_change_rx_flags)
                ops->ndo_change_rx_flags(dev, flags);
 }
 
index 4cdb7c48dad6cb7ade5b1b9c76b32bff08c51d25..b61869429f4ced5a2ed08b178c20fc998bbfdaf2 100644 (file)
@@ -48,7 +48,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr_storage *a
                        if (err < 0)
                                return err;
                }
-               m->msg_name = address;
+               if (m->msg_name)
+                       m->msg_name = address;
        } else {
                m->msg_name = NULL;
        }
index 8cec1e6b844df666b563429f538adf7695a527b6..2718fed53d8cf5b81a06c82f8cdf8ed96632185a 100644 (file)
@@ -2796,6 +2796,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
        struct sk_buff *segs = NULL;
        struct sk_buff *tail = NULL;
        struct sk_buff *fskb = skb_shinfo(skb)->frag_list;
+       skb_frag_t *skb_frag = skb_shinfo(skb)->frags;
        unsigned int mss = skb_shinfo(skb)->gso_size;
        unsigned int doffset = skb->data - skb_mac_header(skb);
        unsigned int offset = doffset;
@@ -2835,16 +2836,38 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                if (hsize > len || !sg)
                        hsize = len;
 
-               if (!hsize && i >= nfrags) {
-                       BUG_ON(fskb->len != len);
+               if (!hsize && i >= nfrags && skb_headlen(fskb) &&
+                   (skb_headlen(fskb) == len || sg)) {
+                       BUG_ON(skb_headlen(fskb) > len);
+
+                       i = 0;
+                       nfrags = skb_shinfo(fskb)->nr_frags;
+                       skb_frag = skb_shinfo(fskb)->frags;
+                       pos += skb_headlen(fskb);
+
+                       while (pos < offset + len) {
+                               BUG_ON(i >= nfrags);
+
+                               size = skb_frag_size(skb_frag);
+                               if (pos + size > offset + len)
+                                       break;
+
+                               i++;
+                               pos += size;
+                               skb_frag++;
+                       }
 
-                       pos += len;
                        nskb = skb_clone(fskb, GFP_ATOMIC);
                        fskb = fskb->next;
 
                        if (unlikely(!nskb))
                                goto err;
 
+                       if (unlikely(pskb_trim(nskb, len))) {
+                               kfree_skb(nskb);
+                               goto err;
+                       }
+
                        hsize = skb_end_offset(nskb);
                        if (skb_cow_head(nskb, doffset + headroom)) {
                                kfree_skb(nskb);
@@ -2881,7 +2904,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                                                 nskb->data - tnl_hlen,
                                                 doffset + tnl_hlen);
 
-               if (fskb != skb_shinfo(skb)->frag_list)
+               if (nskb->len == len + doffset)
                        goto perform_csum_check;
 
                if (!sg) {
@@ -2899,8 +2922,28 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
 
                skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG;
 
-               while (pos < offset + len && i < nfrags) {
-                       *frag = skb_shinfo(skb)->frags[i];
+               while (pos < offset + len) {
+                       if (i >= nfrags) {
+                               BUG_ON(skb_headlen(fskb));
+
+                               i = 0;
+                               nfrags = skb_shinfo(fskb)->nr_frags;
+                               skb_frag = skb_shinfo(fskb)->frags;
+
+                               BUG_ON(!nfrags);
+
+                               fskb = fskb->next;
+                       }
+
+                       if (unlikely(skb_shinfo(nskb)->nr_frags >=
+                                    MAX_SKB_FRAGS)) {
+                               net_warn_ratelimited(
+                                       "skb_segment: too many frags: %u %u\n",
+                                       pos, mss);
+                               goto err;
+                       }
+
+                       *frag = *skb_frag;
                        __skb_frag_ref(frag);
                        size = skb_frag_size(frag);
 
@@ -2913,6 +2956,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
 
                        if (pos + size <= offset + len) {
                                i++;
+                               skb_frag++;
                                pos += size;
                        } else {
                                skb_frag_size_sub(frag, pos + size - (offset + len));
@@ -2922,25 +2966,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features)
                        frag++;
                }
 
-               if (pos < offset + len) {
-                       struct sk_buff *fskb2 = fskb;
-
-                       BUG_ON(pos + fskb->len != offset + len);
-
-                       pos += fskb->len;
-                       fskb = fskb->next;
-
-                       if (fskb2->next) {
-                               fskb2 = skb_clone(fskb2, GFP_ATOMIC);
-                               if (!fskb2)
-                                       goto err;
-                       } else
-                               skb_get(fskb2);
-
-                       SKB_FRAG_ASSERT(nskb);
-                       skb_shinfo(nskb)->frag_list = fskb2;
-               }
-
 skip_fraglist:
                nskb->data_len = len - hsize;
                nskb->len += nskb->data_len;
index 01cffeaa0085ede5bb802999fc1f29c9e6ec4b7f..f13bd91d9a56774f58dcf14de892b2bedd855cc5 100644 (file)
@@ -244,6 +244,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet,
 
        this_cpu_inc(snet->stats->cookie_valid);
        opts->mss = mss;
+       opts->options |= XT_SYNPROXY_OPT_MSS;
 
        if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP)
                synproxy_check_timestamp_cookie(opts);
index f428935c50dba64b7cf7babd955978ed238fd928..f8da28278014ee2c99b2e530a694151d329bc5c2 100644 (file)
@@ -1776,8 +1776,12 @@ local_input:
                rth->dst.error= -err;
                rth->rt_flags   &= ~RTCF_LOCAL;
        }
-       if (do_cache)
-               rt_cache_route(&FIB_RES_NH(res), rth);
+       if (do_cache) {
+               if (unlikely(!rt_cache_route(&FIB_RES_NH(res), rth))) {
+                       rth->dst.flags |= DST_NOCACHE;
+                       rt_add_uncached_list(rth);
+               }
+       }
        skb_dst_set(skb, &rth->dst);
        err = 0;
        goto out;
index bf9f612c1bc24eb9eb0b26fbf7d0a62f74932735..f78f41aca8e90967a026a145f938746ce317cf10 100644 (file)
@@ -259,6 +259,7 @@ synproxy_recv_client_ack(const struct synproxy_net *snet,
 
        this_cpu_inc(snet->stats->cookie_valid);
        opts->mss = mss;
+       opts->options |= XT_SYNPROXY_OPT_MSS;
 
        if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP)
                synproxy_check_timestamp_cookie(opts);
index 7a1e0fc1bd4dd2ca8f31d8a376d94a30406cb1e1..e096025b477f39c43ce65ddb8584193491bd62c1 100644 (file)
@@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (skb->tstamp.tv64)
                sk->sk_stamp = skb->tstamp;
 
-       msg->msg_namelen = sizeof(*sipx);
-
        if (sipx) {
                sipx->sipx_family       = AF_IPX;
                sipx->sipx_port         = ipx->ipx_source.sock;
@@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
                sipx->sipx_network      = IPX_SKB_CB(skb)->ipx_source_net;
                sipx->sipx_type         = ipx->ipx_type;
                sipx->sipx_zero         = 0;
+               msg->msg_namelen        = sizeof(*sipx);
        }
        rc = copied;
 
index 0f676908d15b6108225817108d1cdddf0e31dc16..de7db23049f141be0b6f319db136e7d1a3c5a1f1 100644 (file)
@@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
 
        IRDA_DEBUG(4, "%s()\n", __func__);
 
-       msg->msg_namelen = 0;
-
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
@@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
        timeo = sock_rcvtimeo(sk, noblock);
 
-       msg->msg_namelen = 0;
-
        do {
                int chunk;
                struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
index 168aff5e60de528194a1f4b8ea836cf394ea6613..c4b7218058b648856066bb24dacf38d54d16defc 100644 (file)
@@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        int err = 0;
        u32 offset;
 
-       msg->msg_namelen = 0;
-
        if ((sk->sk_state == IUCV_DISCONN) &&
            skb_queue_empty(&iucv->backlog_skb_q) &&
            skb_queue_empty(&sk->sk_receive_queue) &&
index 911ef03bf8fbf1716672fb503f39de7fe13746d9..545f047868ad86c416f68f468a31d7cc5bd07eb4 100644 (file)
@@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
        if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
                goto out;
 
-       msg->msg_namelen = 0;
        skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
        if (skb == NULL)
                goto out;
index ffda81ef1a709df605ef128ebc866cb00c75fe32..be5fadf3473946a3b7ef886eeadcb2d219e867aa 100644 (file)
@@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sk->sk_state & PPPOX_BOUND)
                goto end;
 
-       msg->msg_namelen = 0;
-
        err = 0;
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
index 6cba486353e8a33dcba394e89664f3886da205c2..7b01b9f5846c845bcf4f04b21cfbcb5786c19421 100644 (file)
@@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
        int target;     /* Read at least this many bytes */
        long timeo;
 
-       msg->msg_namelen = 0;
-
        lock_sock(sk);
        copied = -ENOTCONN;
        if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
index 48acec17e27a1524ced30bd86ad865f147ef3a3e..c3398cd99b94ed4c68da3927c1612da815f1a06d 100644 (file)
@@ -909,7 +909,7 @@ config NETFILTER_XT_MATCH_CONNLABEL
          connection simultaneously.
 
 config NETFILTER_XT_MATCH_CONNLIMIT
-       tristate '"connlimit" match support"'
+       tristate '"connlimit" match support'
        depends on NF_CONNTRACK
        depends on NETFILTER_ADVANCED
        ---help---
index e22d950c60b3c2a6e4ce7112ce13b9cb54e14d7a..43549eb7a7bec4312a1bbf768de2c125a79a526b 100644 (file)
@@ -764,9 +764,10 @@ void nf_conntrack_free(struct nf_conn *ct)
        struct net *net = nf_ct_net(ct);
 
        nf_ct_ext_destroy(ct);
-       atomic_dec(&net->ct.count);
        nf_ct_ext_free(ct);
        kmem_cache_free(net->ct.nf_conntrack_cachep, ct);
+       smp_mb__before_atomic_dec();
+       atomic_dec(&net->ct.count);
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_free);
 
index 5f9bfd060deac302955f91dce75a3a86962a14d5..17c1bcb182c6b58a782744e23bfe671de160bf92 100644 (file)
@@ -41,8 +41,8 @@ int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
        spin_lock_bh(&ct->lock);
        this_way = &seqadj->seq[dir];
        if (this_way->offset_before == this_way->offset_after ||
-           before(this_way->correction_pos, seq)) {
-               this_way->correction_pos = seq;
+           before(this_way->correction_pos, ntohl(seq))) {
+               this_way->correction_pos = ntohl(seq);
                this_way->offset_before  = this_way->offset_after;
                this_way->offset_after  += off;
        }
index cdf4567ba9b330929aec53eb1c75d57a7047106e..9858e3e51a3a049ce796b3ed625e3d3ad8bbe5cc 100644 (file)
@@ -151,9 +151,10 @@ void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info,
        opts->tsecr = opts->tsval;
        opts->tsval = tcp_time_stamp & ~0x3f;
 
-       if (opts->options & XT_SYNPROXY_OPT_WSCALE)
-               opts->tsval |= info->wscale;
-       else
+       if (opts->options & XT_SYNPROXY_OPT_WSCALE) {
+               opts->tsval |= opts->wscale;
+               opts->wscale = info->wscale;
+       } else
                opts->tsval |= 0xf;
 
        if (opts->options & XT_SYNPROXY_OPT_SACK_PERM)
index a82667c64729a3964e8fbd44f0ddd69d1cefa5c3..da0c1f4ada128d79c41d0425d4072641b7b34fe3 100644 (file)
@@ -128,7 +128,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1]
        [NFTA_RULE_COMPAT_FLAGS]        = { .type = NLA_U32 },
 };
 
-static u8 nft_parse_compat(const struct nlattr *attr, bool *inv)
+static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv)
 {
        struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
        u32 flags;
@@ -148,7 +148,8 @@ static u8 nft_parse_compat(const struct nlattr *attr, bool *inv)
        if (flags & NFT_RULE_COMPAT_F_INV)
                *inv = true;
 
-       return ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
+       *proto = ntohl(nla_get_be32(tb[NFTA_RULE_COMPAT_PROTO]));
+       return 0;
 }
 
 static int
@@ -166,8 +167,11 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
        target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
 
-       if (ctx->nla[NFTA_RULE_COMPAT])
-               proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv);
+       if (ctx->nla[NFTA_RULE_COMPAT]) {
+               ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
+               if (ret < 0)
+                       goto err;
+       }
 
        nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
 
@@ -356,8 +360,11 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
        match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
 
-       if (ctx->nla[NFTA_RULE_COMPAT])
-               proto = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &inv);
+       if (ctx->nla[NFTA_RULE_COMPAT]) {
+               ret = nft_parse_compat(ctx->nla[NFTA_RULE_COMPAT], &proto, &inv);
+               if (ret < 0)
+                       goto err;
+       }
 
        nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
 
index f0176e1a5a81a01e59cfdbb59c51d54decf2c0e6..bca50b95c182300cbd89f8cfc21b17e9d6e31fe2 100644 (file)
@@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
        }
 #endif
 
-       msg->msg_namelen = 0;
-
        copied = data_skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index 7dbc4f732c75a1ae7b18a59f07acbab5743c9e7f..4518a57aa5febb14db1c1d750f217102dd8fd2a9 100644 (file)
@@ -1045,7 +1045,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
 int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
                            u32 portid, unsigned int group, gfp_t flags)
 {
-       if (group >= family->n_mcgrps)
+       if (WARN_ON_ONCE(group >= family->n_mcgrps))
                return -EINVAL;
        group = family->mcgrp_offset + group;
        return genlmsg_mcast(skb, portid, group, flags);
@@ -1062,7 +1062,7 @@ void genl_notify(struct genl_family *family,
        if (nlh)
                report = nlmsg_report(nlh);
 
-       if (group >= family->n_mcgrps)
+       if (WARN_ON_ONCE(group >= family->n_mcgrps))
                return;
        group = family->mcgrp_offset + group;
        nlmsg_notify(sk, skb, portid, group, report, flags);
index 698814bfa7adfd4a58e9ec13f24eeb341ea86e08..53c19a35fc6dccd2e29318f123b537401c005314 100644 (file)
@@ -1179,10 +1179,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
                sax->sax25_family = AF_NETROM;
                skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
                              AX25_ADDR_LEN);
+               msg->msg_namelen = sizeof(*sax);
        }
 
-       msg->msg_namelen = sizeof(*sax);
-
        skb_free_datagram(sk, skb);
 
        release_sock(sk);
index d308402b67d80c192c948aa6db05c15089cfdbe8..824c6056bf823b0852b116af45698da916cdc772 100644 (file)
@@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        pr_debug("%p %zu\n", sk, len);
 
-       msg->msg_namelen = 0;
-
        lock_sock(sk);
 
        if (sk->sk_state == LLCP_CLOSED &&
index cd958b381f9615911b1acfc6da6aceb39d373401..66bcd2eb577374bebb032dd32053a2e0835aed74 100644 (file)
@@ -244,8 +244,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return rc;
 
-       msg->msg_namelen = 0;
-
        copied = skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index 2e8286b47c28e5bef7cb80162e12ddb8ca4b358e..ac27c86ef6d11e00c2ecb1512b09bbda73c3eefc 100644 (file)
@@ -244,11 +244,15 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
 static void register_prot_hook(struct sock *sk)
 {
        struct packet_sock *po = pkt_sk(sk);
+
        if (!po->running) {
-               if (po->fanout)
+               if (po->fanout) {
                        __fanout_link(sk, po);
-               else
+               } else {
                        dev_add_pack(&po->prot_hook);
+                       rcu_assign_pointer(po->cached_dev, po->prot_hook.dev);
+               }
+
                sock_hold(sk);
                po->running = 1;
        }
@@ -266,10 +270,13 @@ static void __unregister_prot_hook(struct sock *sk, bool sync)
        struct packet_sock *po = pkt_sk(sk);
 
        po->running = 0;
-       if (po->fanout)
+       if (po->fanout) {
                __fanout_unlink(sk, po);
-       else
+       } else {
                __dev_remove_pack(&po->prot_hook);
+               RCU_INIT_POINTER(po->cached_dev, NULL);
+       }
+
        __sock_put(sk);
 
        if (sync) {
@@ -2052,12 +2059,24 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
        return tp_len;
 }
 
+static struct net_device *packet_cached_dev_get(struct packet_sock *po)
+{
+       struct net_device *dev;
+
+       rcu_read_lock();
+       dev = rcu_dereference(po->cached_dev);
+       if (dev)
+               dev_hold(dev);
+       rcu_read_unlock();
+
+       return dev;
+}
+
 static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 {
        struct sk_buff *skb;
        struct net_device *dev;
        __be16 proto;
-       bool need_rls_dev = false;
        int err, reserve = 0;
        void *ph;
        struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
@@ -2070,7 +2089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
        mutex_lock(&po->pg_vec_lock);
 
        if (saddr == NULL) {
-               dev = po->prot_hook.dev;
+               dev     = packet_cached_dev_get(po);
                proto   = po->num;
                addr    = NULL;
        } else {
@@ -2084,19 +2103,17 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
                proto   = saddr->sll_protocol;
                addr    = saddr->sll_addr;
                dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
-               need_rls_dev = true;
        }
 
        err = -ENXIO;
        if (unlikely(dev == NULL))
                goto out;
-
-       reserve = dev->hard_header_len;
-
        err = -ENETDOWN;
        if (unlikely(!(dev->flags & IFF_UP)))
                goto out_put;
 
+       reserve = dev->hard_header_len;
+
        size_max = po->tx_ring.frame_size
                - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
 
@@ -2173,8 +2190,7 @@ out_status:
        __packet_set_status(po, ph, status);
        kfree_skb(skb);
 out_put:
-       if (need_rls_dev)
-               dev_put(dev);
+       dev_put(dev);
 out:
        mutex_unlock(&po->pg_vec_lock);
        return err;
@@ -2212,7 +2228,6 @@ static int packet_snd(struct socket *sock,
        struct sk_buff *skb;
        struct net_device *dev;
        __be16 proto;
-       bool need_rls_dev = false;
        unsigned char *addr;
        int err, reserve = 0;
        struct virtio_net_hdr vnet_hdr = { 0 };
@@ -2228,7 +2243,7 @@ static int packet_snd(struct socket *sock,
         */
 
        if (saddr == NULL) {
-               dev = po->prot_hook.dev;
+               dev     = packet_cached_dev_get(po);
                proto   = po->num;
                addr    = NULL;
        } else {
@@ -2240,19 +2255,17 @@ static int packet_snd(struct socket *sock,
                proto   = saddr->sll_protocol;
                addr    = saddr->sll_addr;
                dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
-               need_rls_dev = true;
        }
 
        err = -ENXIO;
-       if (dev == NULL)
+       if (unlikely(dev == NULL))
                goto out_unlock;
-       if (sock->type == SOCK_RAW)
-               reserve = dev->hard_header_len;
-
        err = -ENETDOWN;
-       if (!(dev->flags & IFF_UP))
+       if (unlikely(!(dev->flags & IFF_UP)))
                goto out_unlock;
 
+       if (sock->type == SOCK_RAW)
+               reserve = dev->hard_header_len;
        if (po->has_vnet_hdr) {
                vnet_hdr_len = sizeof(vnet_hdr);
 
@@ -2386,15 +2399,14 @@ static int packet_snd(struct socket *sock,
        if (err > 0 && (err = net_xmit_errno(err)) != 0)
                goto out_unlock;
 
-       if (need_rls_dev)
-               dev_put(dev);
+       dev_put(dev);
 
        return len;
 
 out_free:
        kfree_skb(skb);
 out_unlock:
-       if (dev && need_rls_dev)
+       if (dev)
                dev_put(dev);
 out:
        return err;
@@ -2614,6 +2626,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
        po = pkt_sk(sk);
        sk->sk_family = PF_PACKET;
        po->num = proto;
+       RCU_INIT_POINTER(po->cached_dev, NULL);
 
        sk->sk_destruct = packet_sock_destruct;
        sk_refcnt_debug_inc(sk);
@@ -2660,7 +2673,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct sk_buff *skb;
        int copied, err;
-       struct sockaddr_ll *sll;
        int vnet_hdr_len = 0;
 
        err = -EINVAL;
@@ -2744,22 +2756,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
                        goto out_free;
        }
 
-       /*
-        *      If the address length field is there to be filled in, we fill
-        *      it in now.
+       /* You lose any data beyond the buffer you gave. If it worries
+        * a user program they can ask the device for its MTU
+        * anyway.
         */
-
-       sll = &PACKET_SKB_CB(skb)->sa.ll;
-       if (sock->type == SOCK_PACKET)
-               msg->msg_namelen = sizeof(struct sockaddr_pkt);
-       else
-               msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
-
-       /*
-        *      You lose any data beyond the buffer you gave. If it worries a
-        *      user program they can ask the device for its MTU anyway.
-        */
-
        copied = skb->len;
        if (copied > len) {
                copied = len;
@@ -2772,9 +2772,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        sock_recv_ts_and_drops(msg, sk, skb);
 
-       if (msg->msg_name)
+       if (msg->msg_name) {
+               /* If the address length field is there to be filled
+                * in, we fill it in now.
+                */
+               if (sock->type == SOCK_PACKET) {
+                       msg->msg_namelen = sizeof(struct sockaddr_pkt);
+               } else {
+                       struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
+                       msg->msg_namelen = sll->sll_halen +
+                               offsetof(struct sockaddr_ll, sll_addr);
+               }
                memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
                       msg->msg_namelen);
+       }
 
        if (pkt_sk(sk)->auxdata) {
                struct tpacket_auxdata aux;
index c4e4b4561207354c49c9797dd5ea405867de0bcd..1035fa2d909c7f18c100266c85ec07bce4a73a97 100644 (file)
@@ -113,6 +113,7 @@ struct packet_sock {
        unsigned int            tp_loss:1;
        unsigned int            tp_tx_has_off:1;
        unsigned int            tp_tstamp;
+       struct net_device __rcu *cached_dev;
        struct packet_type      prot_hook ____cacheline_aligned_in_smp;
 };
 
index 9f0f17cf6bf9b16e95c7a89d1bc452a0e4c0aada..de339b24ca140f5322a4c6d167450449f3f81bdc 100644 (file)
@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 
        rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
 
-       msg->msg_namelen = 0;
-
        if (msg_flags & MSG_OOB)
                goto out;
 
index e98fcfbe6007919d6c114708cde848a649bb2e4e..33af77246bfeb90c6b31bfe6163dc2c9cfbda787 100644 (file)
@@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
        struct sock *sk = sock->sk;
        struct rose_sock *rose = rose_sk(sk);
-       struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
        size_t copied;
        unsigned char *asmptr;
        struct sk_buff *skb;
@@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-       if (srose != NULL) {
-               memset(srose, 0, msg->msg_namelen);
+       if (msg->msg_name) {
+               struct sockaddr_rose *srose;
+
+               memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
+               srose = msg->msg_name;
                srose->srose_family = AF_ROSE;
                srose->srose_addr   = rose->dest_addr;
                srose->srose_call   = rose->dest_call;
index 4b48687c3890fc64c186b797181062a4cc9ac4fa..898492a8d61be8fde5bcdf66084d525bee23b5f0 100644 (file)
@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                /* copy the peer address and timestamp */
                if (!continue_call) {
-                       if (msg->msg_name && msg->msg_namelen > 0)
+                       if (msg->msg_name) {
+                               size_t len =
+                                       sizeof(call->conn->trans->peer->srx);
                                memcpy(msg->msg_name,
-                                      &call->conn->trans->peer->srx,
-                                      sizeof(call->conn->trans->peer->srx));
+                                      &call->conn->trans->peer->srx, len);
+                               msg->msg_namelen = len;
+                       }
                        sock_recv_ts_and_drops(msg, &rx->sk, skb);
                }
 
index c226aceee65b8b8c59d93d6a133a04c86177ceef..0b18693f2be6deb2f6f6b6bbf99aa131c767e830 100644 (file)
@@ -221,12 +221,13 @@ static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen,
        int err;
        int len;
 
+       BUG_ON(klen > sizeof(struct sockaddr_storage));
        err = get_user(len, ulen);
        if (err)
                return err;
        if (len > klen)
                len = klen;
-       if (len < 0 || len > sizeof(struct sockaddr_storage))
+       if (len < 0)
                return -EINVAL;
        if (len) {
                if (audit_sockaddr(klen, kaddr))
@@ -1840,8 +1841,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        msg.msg_iov = &iov;
        iov.iov_len = size;
        iov.iov_base = ubuf;
-       msg.msg_name = (struct sockaddr *)&address;
-       msg.msg_namelen = sizeof(address);
+       /* Save some cycles and don't copy the address if not needed */
+       msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg.msg_namelen = 0;
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = sock_recvmsg(sock, &msg, size, flags);
@@ -2221,16 +2224,14 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
                        goto out;
        }
 
-       /*
-        *      Save the user-mode address (verify_iovec will change the
-        *      kernel msghdr to use the kernel address space)
+       /* Save the user-mode address (verify_iovec will change the
+        * kernel msghdr to use the kernel address space)
         */
-
        uaddr = (__force void __user *)msg_sys->msg_name;
        uaddr_len = COMPAT_NAMELEN(msg);
-       if (MSG_CMSG_COMPAT & flags) {
+       if (MSG_CMSG_COMPAT & flags)
                err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
-       else
+       else
                err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE);
        if (err < 0)
                goto out_freeiov;
@@ -2239,6 +2240,9 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
        cmsg_ptr = (unsigned long)msg_sys->msg_control;
        msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
 
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg_sys->msg_namelen = 0;
+
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
index 3906527259d19f2d18d06d3641eda0b755d34968..3b61851bb9276ec733f7ab8c9d2179a5dd7fef4d 100644 (file)
@@ -980,9 +980,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
-       /* will be updated in set_orig_addr() if needed */
-       m->msg_namelen = 0;
-
        timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 restart:
 
@@ -1091,9 +1088,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
-       /* will be updated in set_orig_addr() if needed */
-       m->msg_namelen = 0;
-
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
        timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
 
index c1f403bed683ee8653356870f35457fe6e7f18eb..01625ccc3ae64ac3b5b1c664feec7f0136973e04 100644 (file)
@@ -1754,7 +1754,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
 {
        struct unix_sock *u = unix_sk(sk);
 
-       msg->msg_namelen = 0;
        if (u->addr) {
                msg->msg_namelen = u->addr->len;
                memcpy(msg->msg_name, u->addr->name, u->addr->len);
@@ -1778,8 +1777,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags&MSG_OOB)
                goto out;
 
-       msg->msg_namelen = 0;
-
        err = mutex_lock_interruptible(&u->readlock);
        if (err) {
                err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
@@ -1924,8 +1921,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
        timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
 
-       msg->msg_namelen = 0;
-
        /* Lock the socket to prevent queue disordering
         * while sleeps in memcpy_tomsg
         */
index 545c08b8a1d482ac0c155ab755f6623c62ffcbe5..5adfd94c5b85d3d48a6d48d3a4c7c2fa98526d8b 100644 (file)
@@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
        vsk = vsock_sk(sk);
        err = 0;
 
-       msg->msg_namelen = 0;
-
        lock_sock(sk);
 
        if (sk->sk_state != SS_CONNECTED) {
index 9d6986634e0bfaf1a4431cc8f6fc015f212e7042..687360da62d9f5e9a0075ba1a532da33ba973f98 100644 (file)
@@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
        if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
                return -EOPNOTSUPP;
 
-       msg->msg_namelen = 0;
-
        /* Retrieve the head sk_buff from the socket's receive queue. */
        err = 0;
        skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
index ef2191b969a7aa6967f2a3f7855e5b20cfef5cfc..ec8b577db1354a6e6c33e631a3223f1fb5af7ccf 100644 (file)
@@ -610,7 +610,6 @@ int __init wimax_subsys_init(void)
        d_fnend(4, NULL, "() = 0\n");
        return 0;
 
-       genl_unregister_family(&wimax_gnl_family);
 error_register_family:
        d_fnend(4, NULL, "() = %d\n", result);
        return result;
index 45a3ab5612c13c8a583ecd0e866c4113a898a896..7622789d37501f10d29af54a2c778daa85d960bc 100644 (file)
@@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sx25) {
                sx25->sx25_family = AF_X25;
                sx25->sx25_addr   = x25->dest_addr;
+               msg->msg_namelen = sizeof(*sx25);
        }
 
-       msg->msg_namelen = sizeof(struct sockaddr_x25);
-
        x25_check_rbuf(sk);
        rc = copied;
 out_free_dgram: