Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Jan 2013 15:31:49 +0000 (07:31 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 8 Jan 2013 15:31:49 +0000 (07:31 -0800)
Pull networking fixes from David Miller:

 1) New sysctl ndisc_notify needs some documentation, from Hanns
    Frederic Sowa.

 2) Netfilter REJECT target doesn't set transport header of SKB
    correctly, from Mukund Jampala.

 3) Forcedeth driver needs to check for DMA mapping failures, from Larry
    Finger.

 4) brcmsmac driver can't use usleep_range while holding locks, use
    udelay instead.  From Niels Ole Salscheider.

 5) Fix unregister of netlink bridge multicast database handlers, from
    Vlad Yasevich and Rami Rosen.

 6) Fix checksum calculations in netfilter's ipv6 network prefix
    translation module.

 7) Fix high order page allocation failures in netfilter xt_recent, from
    Eric Dumazet.

 8) mac802154 needs to use netif_rx_ni() instead of netif_rx() because
    mac802154_process_data() can execute in process rather than
    interrupt context.  From Alexander Aring.

 9) Fix splice handling of MSG_SENDPAGE_NOTLAST, otherwise we elide one
    tcp_push() too many.  From Eric Dumazet and Willy Tarreau.

10) Fix skb->truesize tracking in XEN netfront driver, from Ian
    Campbell.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (46 commits)
  xen/netfront: improve truesize tracking
  ipv4: fix NULL checking in devinet_ioctl()
  tcp: fix MSG_SENDPAGE_NOTLAST logic
  net/ipv4/ipconfig: really display the BOOTP/DHCP server's address.
  ip-sysctl: fix spelling errors
  mac802154: fix NOHZ local_softirq_pending 08 warning
  ipv6: document ndisc_notify in networking/ip-sysctl.txt
  ath9k: Fix Kconfig for ATH9K_HTC
  netfilter: xt_recent: avoid high order page allocations
  netfilter: fix missing dependencies for the NOTRACK target
  netfilter: ip6t_NPT: fix IPv6 NTP checksum calculation
  bridge: add empty br_mdb_init() and br_mdb_uninit() definitions.
  vxlan: allow live mac address change
  bridge: Correctly unregister MDB rtnetlink handlers
  brcmfmac: fix parsing rsn ie for ap mode.
  brcmsmac: add copyright information for Canonical
  rtlwifi: rtl8723ae: Fix warning for unchecked pci_map_single() call
  rtlwifi: rtl8192se: Fix warning for unchecked pci_map_single() call
  rtlwifi: rtl8192de: Fix warning for unchecked pci_map_single() call
  rtlwifi: rtl8192ce: Fix warning for unchecked pci_map_single() call
  ...

44 files changed:
Documentation/networking/ip-sysctl.txt
drivers/bcma/Kconfig
drivers/bcma/driver_chipcommon_sflash.c
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/usb/qmi_wwan.c
drivers/net/vxlan.c
drivers/net/wireless/ath/ath9k/Kconfig
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/carl9170/fw.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmsmac/debug.h
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192de/trx.c
drivers/net/wireless/rtlwifi/rtl8192se/trx.c
drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
drivers/net/wireless/rtlwifi/usb.c
drivers/net/xen-netfront.c
drivers/ssb/Kconfig
fs/splice.c
include/net/netns/conntrack.h
include/net/netns/x_tables.h
net/bridge/br_multicast.c
net/bridge/br_netlink.c
net/bridge/br_private.h
net/ipv4/devinet.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/iptable_nat.c
net/ipv6/netfilter/ip6t_NPT.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/ip6table_nat.c
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/mac802154/wpan.c
net/netfilter/Kconfig
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nfnetlink_log.c
net/netfilter/xt_CT.c
net/netfilter/xt_hashlimit.c
net/netfilter/xt_recent.c

index dd52d51..dbca661 100644 (file)
@@ -36,7 +36,7 @@ neigh/default/unres_qlen_bytes - INTEGER
        The maximum number of bytes which may be used by packets
        queued for each unresolved address by other network layers.
        (added in linux 3.3)
-       Seting negative value is meaningless and will retrun error.
+       Setting negative value is meaningless and will return error.
        Default: 65536 Bytes(64KB)
 
 neigh/default/unres_qlen - INTEGER
@@ -215,7 +215,7 @@ tcp_ecn - INTEGER
        Possible values are:
                0 Disable ECN.  Neither initiate nor accept ECN.
                1 Always request ECN on outgoing connection attempts.
-               2 Enable ECN when requested by incomming connections
+               2 Enable ECN when requested by incoming connections
                  but do not request ECN on outgoing connections.
        Default: 2
 
@@ -503,7 +503,7 @@ tcp_fastopen - INTEGER
 tcp_syn_retries - INTEGER
        Number of times initial SYNs for an active TCP connection attempt
        will be retransmitted. Should not be higher than 255. Default value
-       is 6, which corresponds to 63seconds till the last restransmission
+       is 6, which corresponds to 63seconds till the last retransmission
        with the current initial RTO of 1second. With this the final timeout
        for an active TCP connection attempt will happen after 127seconds.
 
@@ -1331,6 +1331,12 @@ force_tllao - BOOLEAN
        race condition where the sender deletes the cached link-layer address
        prior to receiving a response to a previous solicitation."
 
+ndisc_notify - BOOLEAN
+       Define mode for notification of address and device changes.
+       0 - (default): do nothing
+       1 - Generate unsolicited neighbour advertisements when device is brought
+           up or hardware address changes.
+
 icmp/*:
 ratelimit - INTEGER
        Limit the maximal rates for sending ICMPv6 packets.
@@ -1530,7 +1536,7 @@ cookie_hmac_alg - STRING
        * sha1
        * none
        Ability to assign md5 or sha1 as the selected alg is predicated on the
-       configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and
+       configuration of those algorithms at build time (CONFIG_CRYPTO_MD5 and
        CONFIG_CRYPTO_SHA1).
 
        Default: Dependent on configuration.  MD5 if available, else SHA1 if
@@ -1548,7 +1554,7 @@ rcvbuf_policy - INTEGER
        blocking.
 
        1: rcvbuf space is per association
-       0: recbuf space is per socket
+       0: rcvbuf space is per socket
 
        Default: 0
 
index d7b56a8..8b4221c 100644 (file)
@@ -67,8 +67,7 @@ config BCMA_DRIVER_GMAC_CMN
 
 config BCMA_DRIVER_GPIO
        bool "BCMA GPIO driver"
-       depends on BCMA
-       select GPIOLIB
+       depends on BCMA && GPIOLIB
        help
          Driver to provide access to the GPIO pins of the bcma bus.
 
index 63e6883..1e694db 100644 (file)
@@ -35,7 +35,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
        { "M25P40", 0x12, 0x10000, 8, },
 
        { "M25P16", 0x14, 0x10000, 32, },
-       { "M25P32", 0x14, 0x10000, 64, },
+       { "M25P32", 0x15, 0x10000, 64, },
        { "M25P64", 0x16, 0x10000, 128, },
        { "M25FL128", 0x17, 0x10000, 256, },
        { 0 },
index 653487d..87fa591 100644 (file)
@@ -1821,6 +1821,11 @@ static int nv_alloc_rx(struct net_device *dev)
                                                             skb->data,
                                                             skb_tailroom(skb),
                                                             PCI_DMA_FROMDEVICE);
+                       if (pci_dma_mapping_error(np->pci_dev,
+                                                 np->put_rx_ctx->dma)) {
+                               kfree_skb(skb);
+                               goto packet_dropped;
+                       }
                        np->put_rx_ctx->dma_len = skb_tailroom(skb);
                        np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
                        wmb();
@@ -1830,6 +1835,7 @@ static int nv_alloc_rx(struct net_device *dev)
                        if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
                                np->put_rx_ctx = np->first_rx_ctx;
                } else {
+packet_dropped:
                        u64_stats_update_begin(&np->swstats_rx_syncp);
                        np->stat_rx_dropped++;
                        u64_stats_update_end(&np->swstats_rx_syncp);
@@ -1856,6 +1862,11 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
                                                             skb->data,
                                                             skb_tailroom(skb),
                                                             PCI_DMA_FROMDEVICE);
+                       if (pci_dma_mapping_error(np->pci_dev,
+                                                 np->put_rx_ctx->dma)) {
+                               kfree_skb(skb);
+                               goto packet_dropped;
+                       }
                        np->put_rx_ctx->dma_len = skb_tailroom(skb);
                        np->put_rx.ex->bufhigh = cpu_to_le32(dma_high(np->put_rx_ctx->dma));
                        np->put_rx.ex->buflow = cpu_to_le32(dma_low(np->put_rx_ctx->dma));
@@ -1866,6 +1877,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
                        if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
                                np->put_rx_ctx = np->first_rx_ctx;
                } else {
+packet_dropped:
                        u64_stats_update_begin(&np->swstats_rx_syncp);
                        np->stat_rx_dropped++;
                        u64_stats_update_end(&np->swstats_rx_syncp);
@@ -2217,6 +2229,15 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
                np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
                                                PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(np->pci_dev,
+                                         np->put_tx_ctx->dma)) {
+                       /* on DMA mapping error - drop the packet */
+                       kfree_skb(skb);
+                       u64_stats_update_begin(&np->swstats_tx_syncp);
+                       np->stat_tx_dropped++;
+                       u64_stats_update_end(&np->swstats_tx_syncp);
+                       return NETDEV_TX_OK;
+               }
                np->put_tx_ctx->dma_len = bcnt;
                np->put_tx_ctx->dma_single = 1;
                put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
@@ -2337,6 +2358,15 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
                np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
                                                PCI_DMA_TODEVICE);
+               if (pci_dma_mapping_error(np->pci_dev,
+                                         np->put_tx_ctx->dma)) {
+                       /* on DMA mapping error - drop the packet */
+                       kfree_skb(skb);
+                       u64_stats_update_begin(&np->swstats_tx_syncp);
+                       np->stat_tx_dropped++;
+                       u64_stats_update_end(&np->swstats_tx_syncp);
+                       return NETDEV_TX_OK;
+               }
                np->put_tx_ctx->dma_len = bcnt;
                np->put_tx_ctx->dma_single = 1;
                put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
@@ -5003,6 +5033,11 @@ static int nv_loopback_test(struct net_device *dev)
        test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data,
                                       skb_tailroom(tx_skb),
                                       PCI_DMA_FROMDEVICE);
+       if (pci_dma_mapping_error(np->pci_dev,
+                                 test_dma_addr)) {
+               dev_kfree_skb_any(tx_skb);
+               goto out;
+       }
        pkt_data = skb_put(tx_skb, pkt_len);
        for (i = 0; i < pkt_len; i++)
                pkt_data[i] = (u8)(i & 0xff);
index 91d7cb9..6a1ca50 100644 (file)
@@ -458,6 +458,7 @@ static const struct usb_device_id products[] = {
        {QMI_FIXED_INTF(0x1199, 0x68a2, 8)},    /* Sierra Wireless MC7710 in QMI mode */
        {QMI_FIXED_INTF(0x1199, 0x68a2, 19)},   /* Sierra Wireless MC7710 in QMI mode */
        {QMI_FIXED_INTF(0x1199, 0x901c, 8)},    /* Sierra Wireless EM7700 */
+       {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)},    /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */
 
        /* 4. Gobi 1000 devices */
        {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},    /* Acer Gobi Modem Device */
index 40f2cc1..656230e 100644 (file)
@@ -1191,6 +1191,7 @@ static void vxlan_setup(struct net_device *dev)
 
        dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
        dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
 
        spin_lock_init(&vxlan->hash_lock);
 
index 5fc15bf..7647ed6 100644 (file)
@@ -2,6 +2,7 @@ config ATH9K_HW
        tristate
 config ATH9K_COMMON
        tristate
+       select ATH_COMMON
 config ATH9K_DFS_DEBUGFS
        def_bool y
        depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT
 config ATH9K
        tristate "Atheros 802.11n wireless cards support"
        depends on MAC80211
-       select ATH_COMMON
        select ATH9K_HW
        select MAC80211_LEDS
        select LEDS_CLASS
@@ -56,7 +56,8 @@ config ATH9K_AHB
 
 config ATH9K_DEBUGFS
        bool "Atheros ath9k debugging"
-       depends on ATH9K && DEBUG_FS
+       depends on ATH9K
+       select MAC80211_DEBUGFS
        ---help---
          Say Y, if you need access to ath9k's statistics for
          interrupts, rate control, etc.
index 74fd397..59bf5f3 100644 (file)
@@ -544,7 +544,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
                                ar9340Common_rx_gain_table_1p0);
        else if (AR_SREV_9485_11(ah))
                INIT_INI_ARRAY(&ah->iniModesRxGain,
-                               ar9485Common_wo_xlna_rx_gain_1_1);
+                              ar9485_common_rx_gain_1_1);
        else if (AR_SREV_9550(ah)) {
                INIT_INI_ARRAY(&ah->iniModesRxGain,
                                ar955x_1p0_common_rx_gain_table);
index aaebecd..63fd9af 100644 (file)
@@ -336,8 +336,12 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
                if (SUPP(CARL9170FW_WLANTX_CAB)) {
                        if_comb_types |=
                                BIT(NL80211_IFTYPE_AP) |
-                               BIT(NL80211_IFTYPE_MESH_POINT) |
                                BIT(NL80211_IFTYPE_P2P_GO);
+
+#ifdef CONFIG_MAC80211_MESH
+                       if_comb_types |=
+                               BIT(NL80211_IFTYPE_MESH_POINT);
+#endif /* CONFIG_MAC80211_MESH */
                }
        }
 
index 1261a9b..75464ad 100644 (file)
@@ -3091,10 +3091,11 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
 
        len = wpa_ie->len + TLV_HDR_LEN;
        data = (u8 *)wpa_ie;
-       offset = 0;
+       offset = TLV_HDR_LEN;
        if (!is_rsn_ie)
                offset += VS_IE_FIXED_HDR_LEN;
-       offset += WPA_IE_VERSION_LEN;
+       else
+               offset += WPA_IE_VERSION_LEN;
 
        /* check for multicast cipher suite */
        if (offset + WPA_IE_MIN_OUI_LEN > len) {
index 796836b..822781c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012 Broadcom Corporation
+ * Copyright (c) 2012 Canonical Ltd.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
index 606b534..21a8242 100644 (file)
@@ -1343,13 +1343,13 @@ static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
 
        wlc_lcnphy_rx_gain_override_enable(pi, true);
        wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
-       usleep_range(500, 500);
+       udelay(500);
        write_radio_reg(pi, RADIO_2064_REG112, 0);
        if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
                return false;
 
        wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
-       usleep_range(500, 500);
+       udelay(500);
        write_radio_reg(pi, RADIO_2064_REG112, 0);
        if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
                return false;
index e71c702..800a165 100644 (file)
@@ -47,6 +47,7 @@ static struct usb_device_id p54u_table[] = {
        {USB_DEVICE(0x0411, 0x0050)},   /* Buffalo WLI2-USB2-G54 */
        {USB_DEVICE(0x045e, 0x00c2)},   /* Microsoft MN-710 */
        {USB_DEVICE(0x0506, 0x0a11)},   /* 3COM 3CRWE254G72 */
+       {USB_DEVICE(0x0675, 0x0530)},   /* DrayTek Vigor 530 */
        {USB_DEVICE(0x06b9, 0x0120)},   /* Thomson SpeedTouch 120g */
        {USB_DEVICE(0x0707, 0xee06)},   /* SMC 2862W-G */
        {USB_DEVICE(0x07aa, 0x001c)},   /* Corega CG-WLUSB2GT */
@@ -82,6 +83,8 @@ static struct usb_device_id p54u_table[] = {
        {USB_DEVICE(0x06a9, 0x000e)},   /* Westell 802.11g USB (A90-211WG-01) */
        {USB_DEVICE(0x06b9, 0x0121)},   /* Thomson SpeedTouch 121g */
        {USB_DEVICE(0x0707, 0xee13)},   /* SMC 2862W-G version 2 */
+       {USB_DEVICE(0x0803, 0x4310)},   /* Zoom 4410a */
+       {USB_DEVICE(0x083a, 0x4503)},   /* T-Com Sinus 154 data II */
        {USB_DEVICE(0x083a, 0x4521)},   /* Siemens Gigaset USB Adapter 54 version 2 */
        {USB_DEVICE(0x083a, 0xc501)},   /* Zoom Wireless-G 4410 */
        {USB_DEVICE(0x083a, 0xf503)},   /* Accton FD7050E ver 1010ec  */
@@ -101,6 +104,7 @@ static struct usb_device_id p54u_table[] = {
        {USB_DEVICE(0x13B1, 0x000C)},   /* Linksys WUSB54AG */
        {USB_DEVICE(0x1413, 0x5400)},   /* Telsey 802.11g USB2.0 Adapter */
        {USB_DEVICE(0x1435, 0x0427)},   /* Inventel UR054G */
+       /* {USB_DEVICE(0x15a9, 0x0002)}, * Also SparkLAN WL-682 with 3887 */
        {USB_DEVICE(0x1668, 0x1050)},   /* Actiontec 802UIG-1 */
        {USB_DEVICE(0x1740, 0x1000)},   /* Senao NUB-350 */
        {USB_DEVICE(0x2001, 0x3704)},   /* DLink DWL-G122 rev A2 */
index 3deacaf..4261e8e 100644 (file)
@@ -743,6 +743,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
 
 done:
                bufferaddress = (*((dma_addr_t *)skb->cb));
+               if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
+                       return;
                tmp_one = 1;
                rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
                                            HW_DESC_RXBUFF_ADDR,
@@ -1115,6 +1117,10 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
                                           PCI_DMA_FROMDEVICE);
 
                        bufferaddress = (*((dma_addr_t *)skb->cb));
+                       if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress)) {
+                               dev_kfree_skb_any(skb);
+                               return 1;
+                       }
                        rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
                                                    HW_DESC_RXBUFF_ADDR,
                                                    (u8 *)&bufferaddress);
index 1734247..c31795e 100644 (file)
@@ -611,8 +611,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
        dma_addr_t mapping = pci_map_single(rtlpci->pdev,
                                            skb->data, skb->len,
                                            PCI_DMA_TODEVICE);
+
        u8 bw_40 = 0;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        rcu_read_lock();
        sta = get_sta(hw, mac->vif, mac->bssid);
        if (mac->opmode == NL80211_IFTYPE_STATION) {
@@ -774,6 +780,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
        __le16 fc = hdr->frame_control;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 
        if (firstseg)
index f9f3861..a0fbf28 100644 (file)
@@ -587,6 +587,11 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
        buf_len = skb->len;
        mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
                                 PCI_DMA_TODEVICE);
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
        if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
                firstseg = true;
@@ -740,6 +745,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
        __le16 fc = hdr->frame_control;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
        if (firstseg)
                SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
index 0e9f6eb..206561d 100644 (file)
@@ -611,6 +611,11 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
                    PCI_DMA_TODEVICE);
        u8 bw_40 = 0;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        if (mac->opmode == NL80211_IFTYPE_STATION) {
                bw_40 = mac->bw_40;
        } else if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -763,6 +768,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
 void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
        bool firstseg, bool lastseg, struct sk_buff *skb)
 {
+       struct rtl_priv *rtlpriv = rtl_priv(hw);
        struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
        struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
@@ -770,7 +776,12 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
        dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
                        PCI_DMA_TODEVICE);
 
-    /* Clear all status        */
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
+       /* Clear all status     */
        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
 
        /* This bit indicate this packet is used for FW download. */
index 87331d8..a313be8 100644 (file)
@@ -387,6 +387,11 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
                                            PCI_DMA_TODEVICE);
        u8 bw_40 = 0;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        if (mac->opmode == NL80211_IFTYPE_STATION) {
                bw_40 = mac->bw_40;
        } else if (mac->opmode == NL80211_IFTYPE_AP ||
@@ -542,6 +547,11 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
                                            PCI_DMA_TODEVICE);
        __le16 fc = hdr->frame_control;
 
+       if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+               RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+                        "DMA mapping error");
+               return;
+       }
        CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
 
        if (firstseg)
index 29f0969..f2ecdeb 100644 (file)
@@ -210,17 +210,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data,
        u16 index = REALTEK_USB_VENQT_CMD_IDX;
        int pipe = usb_sndctrlpipe(udev, 0); /* write_out */
        u8 *buffer;
-       dma_addr_t dma_addr;
 
-       wvalue = (u16)(addr&0x0000ffff);
-       buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr);
+       wvalue = (u16)(addr & 0x0000ffff);
+       buffer = kmalloc(len, GFP_ATOMIC);
        if (!buffer)
                return;
        memcpy(buffer, data, len);
        usb_control_msg(udev, pipe, request, reqtype, wvalue,
                        index, buffer, len, 50);
 
-       usb_free_coherent(udev, (size_t)len, buffer, dma_addr);
+       kfree(buffer);
 }
 
 static void _rtl_usb_io_handler_init(struct device *dev,
@@ -640,6 +639,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
                        RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
                                 "Failed to prep_rx_urb!!\n");
                        err = PTR_ERR(skb);
+                       usb_free_urb(urb);
                        goto err_out;
                }
 
index c26e28b..7ffa43b 100644 (file)
@@ -1015,29 +1015,10 @@ err:
                i = xennet_fill_frags(np, skb, &tmpq);
 
                /*
-                * Truesize approximates the size of true data plus
-                * any supervisor overheads. Adding hypervisor
-                * overheads has been shown to significantly reduce
-                * achievable bandwidth with the default receive
-                * buffer size. It is therefore not wise to account
-                * for it here.
-                *
-                * After alloc_skb(RX_COPY_THRESHOLD), truesize is set
-                * to RX_COPY_THRESHOLD + the supervisor
-                * overheads. Here, we add the size of the data pulled
-                * in xennet_fill_frags().
-                *
-                * We also adjust for any unused space in the main
-                * data area by subtracting (RX_COPY_THRESHOLD -
-                * len). This is especially important with drivers
-                * which split incoming packets into header and data,
-                * using only 66 bytes of the main data area (see the
-                * e1000 driver for example.)  On such systems,
-                * without this last adjustement, our achievable
-                * receive throughout using the standard receive
-                * buffer size was cut by 25%(!!!).
-                */
-               skb->truesize += skb->data_len - RX_COPY_THRESHOLD;
+                 * Truesize is the actual allocation size, even if the
+                 * allocation is only partially used.
+                 */
+               skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags;
                skb->len += skb->data_len;
 
                if (rx->flags & XEN_NETRXF_csum_blank)
index ff3c8a2..5d6f2ec 100644 (file)
@@ -162,8 +162,7 @@ config SSB_DRIVER_GIGE
 
 config SSB_DRIVER_GPIO
        bool "SSB GPIO driver"
-       depends on SSB
-       select GPIOLIB
+       depends on SSB && GPIOLIB
        help
          Driver to provide access to the GPIO pins on the bus.
 
index 8890604..6909d89 100644 (file)
@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
                return -EINVAL;
 
        more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0;
-       if (sd->len < sd->total_len)
+
+       if (sd->len < sd->total_len && pipe->nrbufs > 1)
                more |= MSG_SENDPAGE_NOTLAST;
+
        return file->f_op->sendpage(file, buf->page, buf->offset,
                                    sd->len, &pos, more);
 }
index a1d83cc..923cb20 100644 (file)
@@ -71,6 +71,7 @@ struct netns_ct {
        struct hlist_head       *expect_hash;
        struct hlist_nulls_head unconfirmed;
        struct hlist_nulls_head dying;
+       struct hlist_nulls_head tmpl;
        struct ip_conntrack_stat __percpu *stat;
        struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
        struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
index 591db7d..c24060e 100644 (file)
@@ -8,6 +8,7 @@ struct ebt_table;
 
 struct netns_xt {
        struct list_head tables[NFPROTO_NUMPROTO];
+       bool notrack_deprecated_warning;
 #if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
     defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
        struct ebt_table *broute_table;
index 5391ca4..6d6f265 100644 (file)
@@ -1608,7 +1608,6 @@ void br_multicast_init(struct net_bridge *br)
                    br_multicast_querier_expired, (unsigned long)br);
        setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
                    (unsigned long)br);
-       br_mdb_init();
 }
 
 void br_multicast_open(struct net_bridge *br)
@@ -1633,7 +1632,6 @@ void br_multicast_stop(struct net_bridge *br)
        del_timer_sync(&br->multicast_querier_timer);
        del_timer_sync(&br->multicast_query_timer);
 
-       br_mdb_uninit();
        spin_lock_bh(&br->multicast_lock);
        mdb = mlock_dereference(br->mdb, br);
        if (!mdb)
index 97ba018..5dc66ab 100644 (file)
@@ -299,10 +299,21 @@ struct rtnl_link_ops br_link_ops __read_mostly = {
 
 int __init br_netlink_init(void)
 {
-       return rtnl_link_register(&br_link_ops);
+       int err;
+
+       br_mdb_init();
+       err = rtnl_link_register(&br_link_ops);
+       if (err)
+               goto out;
+
+       return 0;
+out:
+       br_mdb_uninit();
+       return err;
 }
 
 void __exit br_netlink_fini(void)
 {
+       br_mdb_uninit();
        rtnl_link_unregister(&br_link_ops);
 }
index 8d83be5..711094a 100644 (file)
@@ -526,6 +526,12 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
 {
        return 0;
 }
+static inline void br_mdb_init(void)
+{
+}
+static inline void br_mdb_uninit(void)
+{
+}
 #endif
 
 /* br_netfilter.c */
index cc06a47..a8e4f26 100644 (file)
@@ -823,9 +823,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
                if (!ifa) {
                        ret = -ENOBUFS;
                        ifa = inet_alloc_ifa();
-                       INIT_HLIST_NODE(&ifa->hash);
                        if (!ifa)
                                break;
+                       INIT_HLIST_NODE(&ifa->hash);
                        if (colon)
                                memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
                        else
index d763701..a2e50ae 100644 (file)
@@ -136,6 +136,8 @@ __be32 ic_myaddr = NONE;            /* My IP address */
 static __be32 ic_netmask = NONE;       /* Netmask for local subnet */
 __be32 ic_gateway = NONE;      /* Gateway IP address */
 
+__be32 ic_addrservaddr = NONE; /* IP Address of the IP addresses'server */
+
 __be32 ic_servaddr = NONE;     /* Boot server IP address */
 
 __be32 root_server_addr = NONE;        /* Address of NFS server */
@@ -558,6 +560,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        if (ic_myaddr == NONE)
                ic_myaddr = tip;
        ic_servaddr = sip;
+       ic_addrservaddr = sip;
        ic_got_reply = IC_RARP;
 
 drop_unlock:
@@ -1068,7 +1071,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
                                ic_servaddr = server_id;
 #ifdef IPCONFIG_DEBUG
                                printk("DHCP: Offered address %pI4 by server %pI4\n",
-                                      &ic_myaddr, &ic_servaddr);
+                                      &ic_myaddr, &b->iph.saddr);
 #endif
                                /* The DHCP indicated server address takes
                                 * precedence over the bootp header one if
@@ -1113,6 +1116,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
        ic_dev = dev;
        ic_myaddr = b->your_ip;
        ic_servaddr = b->server_ip;
+       ic_addrservaddr = b->iph.saddr;
        if (ic_gateway == NONE && b->relay_ip)
                ic_gateway = b->relay_ip;
        if (ic_nameservers[0] == NONE)
@@ -1268,7 +1272,7 @@ static int __init ic_dynamic(void)
        printk("IP-Config: Got %s answer from %pI4, ",
                ((ic_got_reply & IC_RARP) ? "RARP"
                 : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
-              &ic_servaddr);
+              &ic_addrservaddr);
        pr_cont("my address is %pI4\n", &ic_myaddr);
 
        return 0;
index 51f13f8..04b18c1 100644 (file)
@@ -81,6 +81,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
        niph->saddr     = oiph->daddr;
        niph->daddr     = oiph->saddr;
 
+       skb_reset_transport_header(nskb);
        tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
        memset(tcph, 0, sizeof(*tcph));
        tcph->source    = oth->dest;
index da2c8a3..eeaff7e 100644 (file)
@@ -124,23 +124,28 @@ nf_nat_ipv4_fn(unsigned int hooknum,
                        ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
                        if (ret != NF_ACCEPT)
                                return ret;
-               } else
+               } else {
                        pr_debug("Already setup manip %s for ct %p\n",
                                 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
                                 ct);
+                       if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+                               goto oif_changed;
+               }
                break;
 
        default:
                /* ESTABLISHED */
                NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
                             ctinfo == IP_CT_ESTABLISHED_REPLY);
-               if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) {
-                       nf_ct_kill_acct(ct, ctinfo, skb);
-                       return NF_DROP;
-               }
+               if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+                       goto oif_changed;
        }
 
        return nf_nat_packet(ct, ctinfo, hooknum, skb);
+
+oif_changed:
+       nf_ct_kill_acct(ct, ctinfo, skb);
+       return NF_DROP;
 }
 
 static unsigned int
index e948691..7302b0b 100644 (file)
 #include <linux/netfilter_ipv6/ip6t_NPT.h>
 #include <linux/netfilter/x_tables.h>
 
-static __sum16 csum16_complement(__sum16 a)
-{
-       return (__force __sum16)(0xffff - (__force u16)a);
-}
-
-static __sum16 csum16_add(__sum16 a, __sum16 b)
-{
-       u16 sum;
-
-       sum = (__force u16)a + (__force u16)b;
-       sum += (__force u16)a < (__force u16)b;
-       return (__force __sum16)sum;
-}
-
-static __sum16 csum16_sub(__sum16 a, __sum16 b)
-{
-       return csum16_add(a, csum16_complement(b));
-}
-
 static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
 {
        struct ip6t_npt_tginfo *npt = par->targinfo;
-       __sum16 src_sum = 0, dst_sum = 0;
+       __wsum src_sum = 0, dst_sum = 0;
        unsigned int i;
 
        if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
                return -EINVAL;
 
        for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) {
-               src_sum = csum16_add(src_sum,
-                               (__force __sum16)npt->src_pfx.in6.s6_addr16[i]);
-               dst_sum = csum16_add(dst_sum,
-                               (__force __sum16)npt->dst_pfx.in6.s6_addr16[i]);
+               src_sum = csum_add(src_sum,
+                               (__force __wsum)npt->src_pfx.in6.s6_addr16[i]);
+               dst_sum = csum_add(dst_sum,
+                               (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]);
        }
 
-       npt->adjustment = csum16_sub(src_sum, dst_sum);
+       npt->adjustment = (__force __sum16) csum_sub(src_sum, dst_sum);
        return 0;
 }
 
@@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,
                        return false;
        }
 
-       sum = csum16_add((__force __sum16)addr->s6_addr16[idx],
+       sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx],
                         npt->adjustment);
        if (sum == CSUM_MANGLED_0)
                sum = 0;
index fd4fb34..029623d 100644 (file)
@@ -132,6 +132,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
        ip6h->saddr = oip6h->daddr;
        ip6h->daddr = oip6h->saddr;
 
+       skb_reset_transport_header(nskb);
        tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
        /* Truncate to length (no data) */
        tcph->doff = sizeof(struct tcphdr)/4;
index 6c8ae24..e0e788d 100644 (file)
@@ -127,23 +127,28 @@ nf_nat_ipv6_fn(unsigned int hooknum,
                        ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
                        if (ret != NF_ACCEPT)
                                return ret;
-               } else
+               } else {
                        pr_debug("Already setup manip %s for ct %p\n",
                                 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
                                 ct);
+                       if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+                               goto oif_changed;
+               }
                break;
 
        default:
                /* ESTABLISHED */
                NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
                             ctinfo == IP_CT_ESTABLISHED_REPLY);
-               if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) {
-                       nf_ct_kill_acct(ct, ctinfo, skb);
-                       return NF_DROP;
-               }
+               if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
+                       goto oif_changed;
        }
 
        return nf_nat_packet(ct, ctinfo, hooknum, skb);
+
+oif_changed:
+       nf_ct_kill_acct(ct, ctinfo, skb);
+       return NF_DROP;
 }
 
 static unsigned int
index 00ee17c..137e245 100644 (file)
@@ -81,8 +81,8 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
        }
        protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off);
        /*
-        * (protoff == skb->len) mean that the packet doesn't have no data
-        * except of IPv6 & ext headers. but it's tracked anyway. - YK
+        * (protoff == skb->len) means the packet has not data, just
+        * IPv6 and possibly extensions headers, but it is tracked anyway
         */
        if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
                pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
index 22c8ea9..3dacecc 100644 (file)
@@ -311,7 +311,10 @@ found:
        else
                fq->q.fragments = skb;
 
-       skb->dev = NULL;
+       if (skb->dev) {
+               fq->iif = skb->dev->ifindex;
+               skb->dev = NULL;
+       }
        fq->q.stamp = skb->tstamp;
        fq->q.meat += skb->len;
        if (payload_len > fq->q.max_size)
index 1191039..199b922 100644 (file)
@@ -389,7 +389,7 @@ void mac802154_wpan_setup(struct net_device *dev)
 
 static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
 {
-       return netif_rx(skb);
+       return netif_rx_ni(skb);
 }
 
 static int
index fefa514..49e96df 100644 (file)
@@ -680,6 +680,13 @@ config NETFILTER_XT_TARGET_NFQUEUE
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_TARGET_NOTRACK
+       tristate  '"NOTRACK" target support (DEPRECATED)'
+       depends on NF_CONNTRACK
+       depends on IP_NF_RAW || IP6_NF_RAW
+       depends on NETFILTER_ADVANCED
+       select NETFILTER_XT_TARGET_CT
+
 config NETFILTER_XT_TARGET_RATEEST
        tristate '"RATEEST" target support'
        depends on NETFILTER_ADVANCED
index 08cdc71..016d95e 100644 (file)
@@ -1526,6 +1526,7 @@ err_extend:
  */
 #define UNCONFIRMED_NULLS_VAL  ((1<<30)+0)
 #define DYING_NULLS_VAL                ((1<<30)+1)
+#define TEMPLATE_NULLS_VAL     ((1<<30)+2)
 
 static int nf_conntrack_init_net(struct net *net)
 {
@@ -1534,6 +1535,7 @@ static int nf_conntrack_init_net(struct net *net)
        atomic_set(&net->ct.count, 0);
        INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL);
        INIT_HLIST_NULLS_HEAD(&net->ct.dying, DYING_NULLS_VAL);
+       INIT_HLIST_NULLS_HEAD(&net->ct.tmpl, TEMPLATE_NULLS_VAL);
        net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
        if (!net->ct.stat) {
                ret = -ENOMEM;
index 4e078cd..627b0e5 100644 (file)
@@ -2624,7 +2624,7 @@ ctnetlink_create_expect(struct net *net, u16 zone,
        if (!help) {
                if (!cda[CTA_EXPECT_TIMEOUT]) {
                        err = -EINVAL;
-                       goto out;
+                       goto err_out;
                }
                exp->timeout.expires =
                  jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
index 9f199f2..92fd8ec 100644 (file)
@@ -13,6 +13,7 @@
  */
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/if_arp.h>
 #include <linux/init.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
@@ -384,6 +385,7 @@ __build_packet_message(struct nfulnl_instance *inst,
        struct nfgenmsg *nfmsg;
        sk_buff_data_t old_tail = inst->skb->tail;
        struct sock *sk;
+       const unsigned char *hwhdrp;
 
        nlh = nlmsg_put(inst->skb, 0, 0,
                        NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
@@ -485,9 +487,17 @@ __build_packet_message(struct nfulnl_instance *inst,
        if (indev && skb_mac_header_was_set(skb)) {
                if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
                    nla_put_be16(inst->skb, NFULA_HWLEN,
-                                htons(skb->dev->hard_header_len)) ||
-                   nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len,
-                           skb_mac_header(skb)))
+                                htons(skb->dev->hard_header_len)))
+                       goto nla_put_failure;
+
+               hwhdrp = skb_mac_header(skb);
+
+               if (skb->dev->type == ARPHRD_SIT)
+                       hwhdrp -= ETH_HLEN;
+
+               if (hwhdrp >= skb->head &&
+                   nla_put(inst->skb, NFULA_HWHEADER,
+                           skb->dev->hard_header_len, hwhdrp))
                        goto nla_put_failure;
        }
 
index ae7f5da..2a08430 100644 (file)
@@ -149,6 +149,10 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par)
 
        __set_bit(IPS_TEMPLATE_BIT, &ct->status);
        __set_bit(IPS_CONFIRMED_BIT, &ct->status);
+
+       /* Overload tuple linked list to put us in template list. */
+       hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
+                                &par->net->ct.tmpl);
 out:
        info->ct = ct;
        return 0;
@@ -289,6 +293,10 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par)
 
        __set_bit(IPS_TEMPLATE_BIT, &ct->status);
        __set_bit(IPS_CONFIRMED_BIT, &ct->status);
+
+       /* Overload tuple linked list to put us in template list. */
+       hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
+                                &par->net->ct.tmpl);
 out:
        info->ct = ct;
        return 0;
@@ -377,14 +385,60 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = {
        },
 };
 
+static unsigned int
+notrack_tg(struct sk_buff *skb, const struct xt_action_param *par)
+{
+       /* Previously seen (loopback)? Ignore. */
+       if (skb->nfct != NULL)
+               return XT_CONTINUE;
+
+       skb->nfct = &nf_ct_untracked_get()->ct_general;
+       skb->nfctinfo = IP_CT_NEW;
+       nf_conntrack_get(skb->nfct);
+
+       return XT_CONTINUE;
+}
+
+static int notrack_chk(const struct xt_tgchk_param *par)
+{
+       if (!par->net->xt.notrack_deprecated_warning) {
+               pr_info("netfilter: NOTRACK target is deprecated, "
+                       "use CT instead or upgrade iptables\n");
+               par->net->xt.notrack_deprecated_warning = true;
+       }
+       return 0;
+}
+
+static struct xt_target notrack_tg_reg __read_mostly = {
+       .name           = "NOTRACK",
+       .revision       = 0,
+       .family         = NFPROTO_UNSPEC,
+       .checkentry     = notrack_chk,
+       .target         = notrack_tg,
+       .table          = "raw",
+       .me             = THIS_MODULE,
+};
+
 static int __init xt_ct_tg_init(void)
 {
-       return xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
+       int ret;
+
+       ret = xt_register_target(&notrack_tg_reg);
+       if (ret < 0)
+               return ret;
+
+       ret = xt_register_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
+       if (ret < 0) {
+               xt_unregister_target(&notrack_tg_reg);
+               return ret;
+       }
+       return 0;
 }
 
 static void __exit xt_ct_tg_exit(void)
 {
        xt_unregister_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg));
+       xt_unregister_target(&notrack_tg_reg);
 }
 
 module_init(xt_ct_tg_init);
@@ -394,3 +448,5 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Xtables: connection tracking target");
 MODULE_ALIAS("ipt_CT");
 MODULE_ALIAS("ip6t_CT");
+MODULE_ALIAS("ipt_NOTRACK");
+MODULE_ALIAS("ip6t_NOTRACK");
index 26a668a..a9d7af9 100644 (file)
@@ -157,11 +157,22 @@ dsthash_find(const struct xt_hashlimit_htable *ht,
 /* allocate dsthash_ent, initialize dst, put in htable and lock it */
 static struct dsthash_ent *
 dsthash_alloc_init(struct xt_hashlimit_htable *ht,
-                  const struct dsthash_dst *dst)
+                  const struct dsthash_dst *dst, bool *race)
 {
        struct dsthash_ent *ent;
 
        spin_lock(&ht->lock);
+
+       /* Two or more packets may race to create the same entry in the
+        * hashtable, double check if this packet lost race.
+        */
+       ent = dsthash_find(ht, dst);
+       if (ent != NULL) {
+               spin_unlock(&ht->lock);
+               *race = true;
+               return ent;
+       }
+
        /* initialize hash with random val at the time we allocate
         * the first hashtable entry */
        if (unlikely(!ht->rnd_initialized)) {
@@ -318,7 +329,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
                parent = hashlimit_net->ipt_hashlimit;
        else
                parent = hashlimit_net->ip6t_hashlimit;
-       remove_proc_entry(hinfo->pde->name, parent);
+
+       if(parent != NULL)
+               remove_proc_entry(hinfo->pde->name, parent);
+
        htable_selective_cleanup(hinfo, select_all);
        vfree(hinfo);
 }
@@ -585,6 +599,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
        unsigned long now = jiffies;
        struct dsthash_ent *dh;
        struct dsthash_dst dst;
+       bool race = false;
        u32 cost;
 
        if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
@@ -593,13 +608,18 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
        rcu_read_lock_bh();
        dh = dsthash_find(hinfo, &dst);
        if (dh == NULL) {
-               dh = dsthash_alloc_init(hinfo, &dst);
+               dh = dsthash_alloc_init(hinfo, &dst, &race);
                if (dh == NULL) {
                        rcu_read_unlock_bh();
                        goto hotdrop;
+               } else if (race) {
+                       /* Already got an entry, update expiration timeout */
+                       dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
+                       rateinfo_recalc(dh, now, hinfo->cfg.mode);
+               } else {
+                       dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
+                       rateinfo_init(dh, hinfo);
                }
-               dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
-               rateinfo_init(dh, hinfo);
        } else {
                /* update expiration timeout */
                dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
@@ -856,6 +876,27 @@ static int __net_init hashlimit_proc_net_init(struct net *net)
 
 static void __net_exit hashlimit_proc_net_exit(struct net *net)
 {
+       struct xt_hashlimit_htable *hinfo;
+       struct hlist_node *pos;
+       struct proc_dir_entry *pde;
+       struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);
+
+       /* recent_net_exit() is called before recent_mt_destroy(). Make sure
+        * that the parent xt_recent proc entry is is empty before trying to
+        * remove it.
+        */
+       mutex_lock(&hashlimit_mutex);
+       pde = hashlimit_net->ipt_hashlimit;
+       if (pde == NULL)
+               pde = hashlimit_net->ip6t_hashlimit;
+
+       hlist_for_each_entry(hinfo, pos, &hashlimit_net->htables, node)
+               remove_proc_entry(hinfo->pde->name, pde);
+
+       hashlimit_net->ipt_hashlimit = NULL;
+       hashlimit_net->ip6t_hashlimit = NULL;
+       mutex_unlock(&hashlimit_mutex);
+
        proc_net_remove(net, "ipt_hashlimit");
 #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
        proc_net_remove(net, "ip6t_hashlimit");
@@ -872,9 +913,6 @@ static int __net_init hashlimit_net_init(struct net *net)
 
 static void __net_exit hashlimit_net_exit(struct net *net)
 {
-       struct hashlimit_net *hashlimit_net = hashlimit_pernet(net);
-
-       BUG_ON(!hlist_empty(&hashlimit_net->htables));
        hashlimit_proc_net_exit(net);
 }
 
index 4635c9b..978efc9 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/skbuff.h>
 #include <linux/inet.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -310,6 +311,14 @@ out:
        return ret;
 }
 
+static void recent_table_free(void *addr)
+{
+       if (is_vmalloc_addr(addr))
+               vfree(addr);
+       else
+               kfree(addr);
+}
+
 static int recent_mt_check(const struct xt_mtchk_param *par,
                           const struct xt_recent_mtinfo_v1 *info)
 {
@@ -322,6 +331,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
 #endif
        unsigned int i;
        int ret = -EINVAL;
+       size_t sz;
 
        if (unlikely(!hash_rnd_inited)) {
                get_random_bytes(&hash_rnd, sizeof(hash_rnd));
@@ -360,8 +370,11 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
                goto out;
        }
 
-       t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size,
-                   GFP_KERNEL);
+       sz = sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size;
+       if (sz <= PAGE_SIZE)
+               t = kzalloc(sz, GFP_KERNEL);
+       else
+               t = vzalloc(sz);
        if (t == NULL) {
                ret = -ENOMEM;
                goto out;
@@ -377,14 +390,14 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
        uid = make_kuid(&init_user_ns, ip_list_uid);
        gid = make_kgid(&init_user_ns, ip_list_gid);
        if (!uid_valid(uid) || !gid_valid(gid)) {
-               kfree(t);
+               recent_table_free(t);
                ret = -EINVAL;
                goto out;
        }
        pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent,
                  &recent_mt_fops, t);
        if (pde == NULL) {
-               kfree(t);
+               recent_table_free(t);
                ret = -ENOMEM;
                goto out;
        }
@@ -431,10 +444,11 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par)
                list_del(&t->list);
                spin_unlock_bh(&recent_lock);
 #ifdef CONFIG_PROC_FS
-               remove_proc_entry(t->name, recent_net->xt_recent);
+               if (recent_net->xt_recent != NULL)
+                       remove_proc_entry(t->name, recent_net->xt_recent);
 #endif
                recent_table_flush(t);
-               kfree(t);
+               recent_table_free(t);
        }
        mutex_unlock(&recent_mutex);
 }
@@ -615,6 +629,20 @@ static int __net_init recent_proc_net_init(struct net *net)
 
 static void __net_exit recent_proc_net_exit(struct net *net)
 {
+       struct recent_net *recent_net = recent_pernet(net);
+       struct recent_table *t;
+
+       /* recent_net_exit() is called before recent_mt_destroy(). Make sure
+        * that the parent xt_recent proc entry is is empty before trying to
+        * remove it.
+        */
+       spin_lock_bh(&recent_lock);
+       list_for_each_entry(t, &recent_net->tables, list)
+               remove_proc_entry(t->name, recent_net->xt_recent);
+
+       recent_net->xt_recent = NULL;
+       spin_unlock_bh(&recent_lock);
+
        proc_net_remove(net, "xt_recent");
 }
 #else
@@ -638,9 +666,6 @@ static int __net_init recent_net_init(struct net *net)
 
 static void __net_exit recent_net_exit(struct net *net)
 {
-       struct recent_net *recent_net = recent_pernet(net);
-
-       BUG_ON(!list_empty(&recent_net->tables));
        recent_proc_net_exit(net);
 }