Commit 5c33d9b2 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net

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
  ...
parents 2a893f91 d9a58a78
...@@ -36,7 +36,7 @@ neigh/default/unres_qlen_bytes - INTEGER ...@@ -36,7 +36,7 @@ neigh/default/unres_qlen_bytes - INTEGER
The maximum number of bytes which may be used by packets The maximum number of bytes which may be used by packets
queued for each unresolved address by other network layers. queued for each unresolved address by other network layers.
(added in linux 3.3) (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) Default: 65536 Bytes(64KB)
neigh/default/unres_qlen - INTEGER neigh/default/unres_qlen - INTEGER
...@@ -215,7 +215,7 @@ tcp_ecn - INTEGER ...@@ -215,7 +215,7 @@ tcp_ecn - INTEGER
Possible values are: Possible values are:
0 Disable ECN. Neither initiate nor accept ECN. 0 Disable ECN. Neither initiate nor accept ECN.
1 Always request ECN on outgoing connection attempts. 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. but do not request ECN on outgoing connections.
Default: 2 Default: 2
...@@ -503,7 +503,7 @@ tcp_fastopen - INTEGER ...@@ -503,7 +503,7 @@ tcp_fastopen - INTEGER
tcp_syn_retries - INTEGER tcp_syn_retries - INTEGER
Number of times initial SYNs for an active TCP connection attempt Number of times initial SYNs for an active TCP connection attempt
will be retransmitted. Should not be higher than 255. Default value 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 with the current initial RTO of 1second. With this the final timeout
for an active TCP connection attempt will happen after 127seconds. for an active TCP connection attempt will happen after 127seconds.
...@@ -1331,6 +1331,12 @@ force_tllao - BOOLEAN ...@@ -1331,6 +1331,12 @@ force_tllao - BOOLEAN
race condition where the sender deletes the cached link-layer address race condition where the sender deletes the cached link-layer address
prior to receiving a response to a previous solicitation." 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/*: icmp/*:
ratelimit - INTEGER ratelimit - INTEGER
Limit the maximal rates for sending ICMPv6 packets. Limit the maximal rates for sending ICMPv6 packets.
...@@ -1530,7 +1536,7 @@ cookie_hmac_alg - STRING ...@@ -1530,7 +1536,7 @@ cookie_hmac_alg - STRING
* sha1 * sha1
* none * none
Ability to assign md5 or sha1 as the selected alg is predicated on the 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). CONFIG_CRYPTO_SHA1).
Default: Dependent on configuration. MD5 if available, else SHA1 if Default: Dependent on configuration. MD5 if available, else SHA1 if
...@@ -1548,7 +1554,7 @@ rcvbuf_policy - INTEGER ...@@ -1548,7 +1554,7 @@ rcvbuf_policy - INTEGER
blocking. blocking.
1: rcvbuf space is per association 1: rcvbuf space is per association
0: recbuf space is per socket 0: rcvbuf space is per socket
Default: 0 Default: 0
......
...@@ -67,8 +67,7 @@ config BCMA_DRIVER_GMAC_CMN ...@@ -67,8 +67,7 @@ config BCMA_DRIVER_GMAC_CMN
config BCMA_DRIVER_GPIO config BCMA_DRIVER_GPIO
bool "BCMA GPIO driver" bool "BCMA GPIO driver"
depends on BCMA depends on BCMA && GPIOLIB
select GPIOLIB
help help
Driver to provide access to the GPIO pins of the bcma bus. Driver to provide access to the GPIO pins of the bcma bus.
......
...@@ -35,7 +35,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = { ...@@ -35,7 +35,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
{ "M25P40", 0x12, 0x10000, 8, }, { "M25P40", 0x12, 0x10000, 8, },
{ "M25P16", 0x14, 0x10000, 32, }, { "M25P16", 0x14, 0x10000, 32, },
{ "M25P32", 0x14, 0x10000, 64, }, { "M25P32", 0x15, 0x10000, 64, },
{ "M25P64", 0x16, 0x10000, 128, }, { "M25P64", 0x16, 0x10000, 128, },
{ "M25FL128", 0x17, 0x10000, 256, }, { "M25FL128", 0x17, 0x10000, 256, },
{ 0 }, { 0 },
......
...@@ -1821,6 +1821,11 @@ static int nv_alloc_rx(struct net_device *dev) ...@@ -1821,6 +1821,11 @@ static int nv_alloc_rx(struct net_device *dev)
skb->data, skb->data,
skb_tailroom(skb), skb_tailroom(skb),
PCI_DMA_FROMDEVICE); 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_ctx->dma_len = skb_tailroom(skb);
np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma); np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
wmb(); wmb();
...@@ -1830,6 +1835,7 @@ static int nv_alloc_rx(struct net_device *dev) ...@@ -1830,6 +1835,7 @@ static int nv_alloc_rx(struct net_device *dev)
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx; np->put_rx_ctx = np->first_rx_ctx;
} else { } else {
packet_dropped:
u64_stats_update_begin(&np->swstats_rx_syncp); u64_stats_update_begin(&np->swstats_rx_syncp);
np->stat_rx_dropped++; np->stat_rx_dropped++;
u64_stats_update_end(&np->swstats_rx_syncp); u64_stats_update_end(&np->swstats_rx_syncp);
...@@ -1856,6 +1862,11 @@ static int nv_alloc_rx_optimized(struct net_device *dev) ...@@ -1856,6 +1862,11 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
skb->data, skb->data,
skb_tailroom(skb), skb_tailroom(skb),
PCI_DMA_FROMDEVICE); 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_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->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)); 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) ...@@ -1866,6 +1877,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx)) if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx; np->put_rx_ctx = np->first_rx_ctx;
} else { } else {
packet_dropped:
u64_stats_update_begin(&np->swstats_rx_syncp); u64_stats_update_begin(&np->swstats_rx_syncp);
np->stat_rx_dropped++; np->stat_rx_dropped++;
u64_stats_update_end(&np->swstats_rx_syncp); 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) ...@@ -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; 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, np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
PCI_DMA_TODEVICE); 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_len = bcnt;
np->put_tx_ctx->dma_single = 1; np->put_tx_ctx->dma_single = 1;
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma); 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, ...@@ -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; 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, np->put_tx_ctx->dma = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
PCI_DMA_TODEVICE); 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_len = bcnt;
np->put_tx_ctx->dma_single = 1; np->put_tx_ctx->dma_single = 1;
put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma)); 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) ...@@ -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, test_dma_addr = pci_map_single(np->pci_dev, tx_skb->data,
skb_tailroom(tx_skb), skb_tailroom(tx_skb),
PCI_DMA_FROMDEVICE); 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); pkt_data = skb_put(tx_skb, pkt_len);
for (i = 0; i < pkt_len; i++) for (i = 0; i < pkt_len; i++)
pkt_data[i] = (u8)(i & 0xff); pkt_data[i] = (u8)(i & 0xff);
......
...@@ -458,6 +458,7 @@ static const struct usb_device_id products[] = { ...@@ -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, 8)}, /* Sierra Wireless MC7710 in QMI mode */
{QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* 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(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 */ /* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
......
...@@ -1191,6 +1191,7 @@ static void vxlan_setup(struct net_device *dev) ...@@ -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->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
spin_lock_init(&vxlan->hash_lock); spin_lock_init(&vxlan->hash_lock);
......
...@@ -2,6 +2,7 @@ config ATH9K_HW ...@@ -2,6 +2,7 @@ config ATH9K_HW
tristate tristate
config ATH9K_COMMON config ATH9K_COMMON
tristate tristate
select ATH_COMMON
config ATH9K_DFS_DEBUGFS config ATH9K_DFS_DEBUGFS
def_bool y def_bool y
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
...@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT ...@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT
config ATH9K config ATH9K
tristate "Atheros 802.11n wireless cards support" tristate "Atheros 802.11n wireless cards support"
depends on MAC80211 depends on MAC80211
select ATH_COMMON
select ATH9K_HW select ATH9K_HW
select MAC80211_LEDS select MAC80211_LEDS
select LEDS_CLASS select LEDS_CLASS
...@@ -56,7 +56,8 @@ config ATH9K_AHB ...@@ -56,7 +56,8 @@ config ATH9K_AHB
config ATH9K_DEBUGFS config ATH9K_DEBUGFS
bool "Atheros ath9k debugging" bool "Atheros ath9k debugging"
depends on ATH9K && DEBUG_FS depends on ATH9K
select MAC80211_DEBUGFS
---help--- ---help---
Say Y, if you need access to ath9k's statistics for Say Y, if you need access to ath9k's statistics for
interrupts, rate control, etc. interrupts, rate control, etc.
......
...@@ -544,7 +544,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) ...@@ -544,7 +544,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
ar9340Common_rx_gain_table_1p0); ar9340Common_rx_gain_table_1p0);
else if (AR_SREV_9485_11(ah)) else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1); ar9485_common_rx_gain_1_1);
else if (AR_SREV_9550(ah)) { else if (AR_SREV_9550(ah)) {
INIT_INI_ARRAY(&ah->iniModesRxGain, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar955x_1p0_common_rx_gain_table); ar955x_1p0_common_rx_gain_table);
......
...@@ -336,8 +336,12 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ...@@ -336,8 +336,12 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
if (SUPP(CARL9170FW_WLANTX_CAB)) { if (SUPP(CARL9170FW_WLANTX_CAB)) {
if_comb_types |= if_comb_types |=
BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT) |
BIT(NL80211_IFTYPE_P2P_GO); BIT(NL80211_IFTYPE_P2P_GO);
#ifdef CONFIG_MAC80211_MESH
if_comb_types |=
BIT(NL80211_IFTYPE_MESH_POINT);
#endif /* CONFIG_MAC80211_MESH */
} }
} }
......
...@@ -3091,10 +3091,11 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, ...@@ -3091,10 +3091,11 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
len = wpa_ie->len + TLV_HDR_LEN; len = wpa_ie->len + TLV_HDR_LEN;
data = (u8 *)wpa_ie; data = (u8 *)wpa_ie;
offset = 0; offset = TLV_HDR_LEN;
if (!is_rsn_ie) if (!is_rsn_ie)
offset += VS_IE_FIXED_HDR_LEN; offset += VS_IE_FIXED_HDR_LEN;
offset += WPA_IE_VERSION_LEN; else
offset += WPA_IE_VERSION_LEN;
/* check for multicast cipher suite */ /* check for multicast cipher suite */
if (offset + WPA_IE_MIN_OUI_LEN > len) { if (offset + WPA_IE_MIN_OUI_LEN > len) {
......
/* /*
* Copyright (c) 2012 Broadcom Corporation * Copyright (c) 2012 Broadcom Corporation
* Copyright (c) 2012 Canonical Ltd.
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
......
...@@ -1343,13 +1343,13 @@ static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, ...@@ -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_rx_gain_override_enable(pi, true);
wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0); wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
usleep_range(500, 500); udelay(500);
write_radio_reg(pi, RADIO_2064_REG112, 0); write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l)) if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
return false; return false;
wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0); wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
usleep_range(500, 500); udelay(500);
write_radio_reg(pi, RADIO_2064_REG112, 0); write_radio_reg(pi, RADIO_2064_REG112, 0);
if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h)) if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
return false; return false;
......
...@@ -47,6 +47,7 @@ static struct usb_device_id p54u_table[] = { ...@@ -47,6 +47,7 @@ static struct usb_device_id p54u_table[] = {
{USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
{USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
{USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
{USB_DEVICE(0x0675, 0x0530)}, /* DrayTek Vigor 530 */
{USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
{USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
{USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */ {USB_DEVICE(0x07aa, 0x001c)}, /* Corega CG-WLUSB2GT */
...@@ -82,6 +83,8 @@ static struct usb_device_id p54u_table[] = { ...@@ -82,6 +83,8 @@ static struct usb_device_id p54u_table[] = {
{USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
{USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
{USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {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, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
{USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
{USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
...@@ -101,6 +104,7 @@ static struct usb_device_id p54u_table[] = { ...@@ -101,6 +104,7 @@ static struct usb_device_id p54u_table[] = {
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {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(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
{USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */ {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */
{USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
......
...@@ -743,6 +743,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) ...@@ -743,6 +743,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
done: done:
bufferaddress = (*((dma_addr_t *)skb->cb)); bufferaddress = (*((dma_addr_t *)skb->cb));
if (pci_dma_mapping_error(rtlpci->pdev, bufferaddress))
return;
tmp_one = 1; tmp_one = 1;
rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
HW_DESC_RXBUFF_ADDR, HW_DESC_RXBUFF_ADDR,
...@@ -1115,6 +1117,10 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) ...@@ -1115,6 +1117,10 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
bufferaddress = (*((dma_addr_t *)skb->cb)); 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, rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
HW_DESC_RXBUFF_ADDR, HW_DESC_RXBUFF_ADDR,
(u8 *)&bufferaddress); (u8 *)&bufferaddress);
......
...@@ -611,8 +611,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, ...@@ -611,8 +611,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
dma_addr_t mapping = pci_map_single(rtlpci->pdev, dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len, skb->data, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
u8 bw_40 = 0; 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(); rcu_read_lock();
sta = get_sta(hw, mac->vif, mac->bssid); sta = get_sta(hw, mac->vif, mac->bssid);
if (mac->opmode == NL80211_IFTYPE_STATION) { if (mac->opmode == NL80211_IFTYPE_STATION) {
...@@ -774,6 +780,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, ...@@ -774,6 +780,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control; __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); CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (firstseg) if (firstseg)
......
...@@ -587,6 +587,11 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, ...@@ -587,6 +587,11 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
buf_len = skb->len; buf_len = skb->len;
mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE); 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)); CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92d));
if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
firstseg = true; firstseg = true;
...@@ -740,6 +745,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, ...@@ -740,6 +745,11 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
__le16 fc = hdr->frame_control; __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); CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (firstseg) if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
......
...@@ -611,6 +611,11 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, ...@@ -611,6 +611,11 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
u8 bw_40 = 0; 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) { if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40; bw_40 = mac->bw_40;
} else if (mac->opmode == NL80211_IFTYPE_AP || } else if (mac->opmode == NL80211_IFTYPE_AP ||
...@@ -763,6 +768,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, ...@@ -763,6 +768,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
bool firstseg, bool lastseg, struct sk_buff *skb) 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_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb); 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, ...@@ -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, dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE); 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); CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
/* This bit indicate this packet is used for FW download. */ /* This bit indicate this packet is used for FW download. */
......
...@@ -387,6 +387,11 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, ...@@ -387,6 +387,11 @@ void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
u8 bw_40 = 0; 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) { if (mac->opmode == NL80211_IFTYPE_STATION) {
bw_40 = mac->bw_40; bw_40 = mac->bw_40;
} else if (mac->opmode == NL80211_IFTYPE_AP || } else if (mac->opmode == NL80211_IFTYPE_AP ||
...@@ -542,6 +547,11 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, ...@@ -542,6 +547,11 @@ void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
__le16 fc = hdr->frame_control; __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); CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
if (firstseg) if (firstseg)
......
...@@ -210,17 +210,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data, ...@@ -210,17 +210,16 @@ static void _usb_writeN_sync(struct rtl_priv *rtlpriv, u32 addr, void *data,
u16 index = REALTEK_USB_VENQT_CMD_IDX; u16 index = REALTEK_USB_VENQT_CMD_IDX;
int pipe = usb_sndctrlpipe(udev, 0); /* write_out */ int pipe = usb_sndctrlpipe(udev, 0); /* write_out */
u8 *buffer; u8 *buffer;
dma_addr_t dma_addr;
wvalue = (u16)(addr&0x0000ffff); wvalue = (u16)(addr & 0x0000ffff);
buffer = usb_alloc_coherent(udev, (size_t)len, GFP_ATOMIC, &dma_addr); buffer = kmalloc(len, GFP_ATOMIC);
if (!buffer) if (!buffer)
return; return;
memcpy(buffer, data, len); memcpy(buffer, data, len);
usb_control_msg(udev, pipe, request, reqtype, wvalue, usb_control_msg(udev, pipe, request, reqtype, wvalue,
index, buffer, len, 50); 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, static void _rtl_usb_io_handler_init(struct device *dev,
...@@ -640,6 +639,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) ...@@ -640,6 +639,7 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw)
RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
"Failed to prep_rx_urb!!\n"); "Failed to prep_rx_urb!!\n");
err = PTR_ERR(skb); err = PTR_ERR(skb);
usb_free_urb(urb);
goto err_out; goto err_out;
} }
......
...@@ -1015,29 +1015,10 @@ static int xennet_poll(struct napi_struct *napi, int budget) ...@@ -1015,29 +1015,10 @@ static int xennet_poll(struct napi_struct *napi, int budget)
i = xennet_fill_frags(np, skb, &tmpq); i = xennet_fill_frags(np, skb, &tmpq);
/* /*
* Truesize approximates the size of true data plus * Truesize is the actual allocation size, even if the
* any supervisor overheads. Adding hypervisor * allocation is only partially used.
* overheads has been shown to significantly reduce */
* achievable bandwidth with the default receive skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags;
* 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;
skb->len += skb->data_len; skb->len += skb->data_len;
if (rx->flags & XEN_NETRXF_csum_blank) if (rx->flags & XEN_NETRXF_csum_blank)
......
...@@ -162,8 +162,7 @@ config SSB_DRIVER_GIGE ...@@ -162,8 +162,7 @@ config SSB_DRIVER_GIGE
config SSB_DRIVER_GPIO config SSB_DRIVER_GPIO
bool "SSB GPIO driver" bool "SSB GPIO driver"
depends on SSB depends on SSB && GPIOLIB
select GPIOLIB
help help
Driver to provide access to the GPIO pins on the bus. Driver to provide access to the GPIO pins on the bus.
......
...@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, ...@@ -696,8 +696,10 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
return -EINVAL; return -EINVAL;
more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; 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; more |= MSG_SENDPAGE_NOTLAST;
return file->f_op->sendpage(file, buf->page, buf->offset, return file->f_op->sendpage(file, buf->page, buf->offset,
sd->len, &pos, more); sd->len, &pos, more);
} }
......
...@@ -71,6 +71,7 @@ struct netns_ct { ...@@ -71,6 +71,7 @@ struct netns_ct {
struct hlist_head *expect_hash; struct hlist_head *expect_hash;
struct hlist_nulls_head unconfirmed; struct hlist_nulls_head unconfirmed;
struct hlist_nulls_head dying; struct hlist_nulls_head dying;
struct hlist_nulls_head tmpl;
struct ip_conntrack_stat __percpu *stat; struct ip_conntrack_stat __percpu *stat;
struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb; struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
struct nf_exp_event_notifier __rcu *nf_expect_event_cb; struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
......
...@@ -8,6 +8,7 @@ struct ebt_table; ...@@ -8,6 +8,7 @@ struct ebt_table;
struct netns_xt { struct netns_xt {
struct list_head tables[NFPROTO_NUMPROTO]; struct list_head tables[NFPROTO_NUMPROTO];
bool notrack_deprecated_warning;
#if defined(CONFIG_BRIDGE_NF_EBTABLES) || \ #if defined(CONFIG_BRIDGE_NF_EBTABLES) || \
defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE) defined(CONFIG_BRIDGE_NF_EBTABLES_MODULE)
struct ebt_table *broute_table; struct ebt_table *broute_table;
......
...@@ -1608,7 +1608,6 @@ void br_multicast_init(struct net_bridge *br) ...@@ -1608,7 +1608,6 @@ void br_multicast_init(struct net_bridge *br)
br_multicast_querier_expired, (unsigned long)br); br_multicast_querier_expired, (unsigned long)br);
setup_timer(&br->multicast_query_timer, br_multicast_query_expired, setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
(unsigned long)br); (unsigned long)br);
br_mdb_init();
} }
void br_multicast_open(struct net_bridge *br) void br_multicast_open(struct net_bridge *br)
...@@ -1633,7 +1632,6 @@ void br_multicast_stop(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_querier_timer);
del_timer_sync(&br->multicast_query_timer); del_timer_sync(&br->multicast_query_timer);
br_mdb_uninit();
spin_lock_bh(&br->multicast_lock); spin_lock_bh(&br->multicast_lock);
mdb = mlock_dereference(br->mdb, br); mdb = mlock_dereference(br->mdb, br);
if (!mdb) if (!mdb)
......
...@@ -299,10 +299,21 @@ struct rtnl_link_ops br_link_ops __read_mostly = { ...@@ -299,10 +299,21 @@ struct rtnl_link_ops br_link_ops __read_mostly = {
int __init br_netlink_init(void) 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) void __exit br_netlink_fini(void)
{ {
br_mdb_uninit();
rtnl_link_unregister(&br_link_ops); rtnl_link_unregister(&br_link_ops);
} }
...@@ -526,6 +526,12 @@ static inline bool br_multicast_is_router(struct net_bridge *br) ...@@ -526,6 +526,12 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
{ {
return 0; return 0;
} }
static inline void br_mdb_init(void)
{
}
static inline void br_mdb_uninit(void)
{
}
#endif #endif
/* br_netfilter.c */ /* br_netfilter.c */
......
...@@ -823,9 +823,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg) ...@@ -823,9 +823,9 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (!ifa) { if (!ifa) {
ret = -ENOBUFS; ret = -ENOBUFS;
ifa = inet_alloc_ifa(); ifa = inet_alloc_ifa();
INIT_HLIST_NODE(&ifa->hash);
if (!ifa) if (!ifa)
break; break;
INIT_HLIST_NODE(&ifa->hash);
if (colon) if (colon)
memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ); memcpy(ifa->ifa_label, ifr.ifr_name, IFNAMSIZ);
else else
......
...@@ -136,6 +136,8 @@ __be32 ic_myaddr = NONE; /* My IP address */ ...@@ -136,6 +136,8 @@ __be32 ic_myaddr = NONE; /* My IP address */
static __be32 ic_netmask = NONE; /* Netmask for local subnet */ static __be32 ic_netmask = NONE; /* Netmask for local subnet */
__be32 ic_gateway = NONE; /* Gateway IP address */ __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 ic_servaddr = NONE; /* Boot server IP address */
__be32 root_server_addr = NONE; /* Address of NFS server */ __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 ...@@ -558,6 +560,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
if (ic_myaddr == NONE) if (ic_myaddr == NONE)
ic_myaddr = tip; ic_myaddr = tip;
ic_servaddr = sip; ic_servaddr = sip;
ic_addrservaddr = sip;
ic_got_reply = IC_RARP; ic_got_reply = IC_RARP;
drop_unlock: drop_unlock:
...@@ -1068,7 +1071,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str ...@@ -1068,7 +1071,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_servaddr = server_id; ic_servaddr = server_id;
#ifdef IPCONFIG_DEBUG #ifdef IPCONFIG_DEBUG
printk("DHCP: Offered address %pI4 by server %pI4\n", printk("DHCP: Offered address %pI4 by server %pI4\n",
&ic_myaddr, &ic_servaddr); &ic_myaddr, &b->iph.saddr);
#endif #endif
/* The DHCP indicated server address takes /* The DHCP indicated server address takes
* precedence over the bootp header one if * 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 ...@@ -1113,6 +1116,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ic_dev = dev; ic_dev = dev;
ic_myaddr = b->your_ip; ic_myaddr = b->your_ip;
ic_servaddr = b->server_ip; ic_servaddr = b->server_ip;
ic_addrservaddr = b->iph.saddr;
if (ic_gateway == NONE && b->relay_ip) if (ic_gateway == NONE && b->relay_ip)
ic_gateway = b->relay_ip; ic_gateway = b->relay_ip;
if (ic_nameservers[0] == NONE) if (ic_nameservers[0] == NONE)
...@@ -1268,7 +1272,7 @@ static int __init ic_dynamic(void) ...@@ -1268,7 +1272,7 @@ static int __init ic_dynamic(void)
printk("IP-Config: Got %s answer from %pI4, ", printk("IP-Config: Got %s answer from %pI4, ",
((ic_got_reply & IC_RARP) ? "RARP" ((ic_got_reply & IC_RARP) ? "RARP"
: (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"), : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
&ic_servaddr); &ic_addrservaddr);
pr_cont("my address is %pI4\n", &ic_myaddr); pr_cont("my address is %pI4\n", &ic_myaddr);
return 0; return 0;
......
...@@ -81,6 +81,7 @@ static void send_reset(struct sk_buff *oldskb, int hook) ...@@ -81,6 +81,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
niph->saddr = oiph->daddr; niph->saddr = oiph->daddr;
niph->daddr = oiph->saddr; niph->daddr = oiph->saddr;
skb_reset_transport_header(nskb);
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
memset(tcph, 0, sizeof(*tcph)); memset(tcph, 0, sizeof(*tcph));
tcph->source = oth->dest; tcph->source = oth->dest;
......
...@@ -124,23 +124,28 @@ nf_nat_ipv4_fn(unsigned int hooknum, ...@@ -124,23 +124,28 @@ nf_nat_ipv4_fn(unsigned int hooknum,
ret = nf_nat_rule_find(skb, hooknum, in, out, ct); ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
if (ret != NF_ACCEPT) if (ret != NF_ACCEPT)
return ret; return ret;
} else } else {
pr_debug("Already setup manip %s for ct %p\n", pr_debug("Already setup manip %s for ct %p\n",
maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
ct); ct);
if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
goto oif_changed;
}
break; break;
default: default:
/* ESTABLISHED */ /* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY); ctinfo == IP_CT_ESTABLISHED_REPLY);
if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) { if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
nf_ct_kill_acct(ct, ctinfo, skb); goto oif_changed;
return NF_DROP;
}
} }
return nf_nat_packet(ct, ctinfo, hooknum, skb); return nf_nat_packet(ct, ctinfo, hooknum, skb);
oif_changed:
nf_ct_kill_acct(ct, ctinfo, skb);
return NF_DROP;
} }
static unsigned int static unsigned int
......
...@@ -14,42 +14,23 @@ ...@@ -14,42 +14,23 @@
#include <linux/netfilter_ipv6/ip6t_NPT.h> #include <linux/netfilter_ipv6/ip6t_NPT.h>
#include <linux/netfilter/x_tables.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) static int ip6t_npt_checkentry(const struct xt_tgchk_param *par)
{ {
struct ip6t_npt_tginfo *npt = par->targinfo; struct ip6t_npt_tginfo *npt = par->targinfo;
__sum16 src_sum = 0, dst_sum = 0; __wsum src_sum = 0, dst_sum = 0;
unsigned int i; unsigned int i;
if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64)
return -EINVAL; return -EINVAL;
for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) {
src_sum = csum16_add(src_sum, src_sum = csum_add(src_sum,
(__force __sum16)npt->src_pfx.in6.s6_addr16[i]); (__force __wsum)npt->src_pfx.in6.s6_addr16[i]);
dst_sum = csum16_add(dst_sum, dst_sum = csum_add(dst_sum,
(__force __sum16)npt->dst_pfx.in6.s6_addr16[i]); (__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; return 0;
} }
...@@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, ...@@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt,
return false; return false;
} }
sum = csum16_add((__force __sum16)addr->s6_addr16[idx], sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx],
npt->adjustment); npt->adjustment);
if (sum == CSUM_MANGLED_0) if (sum == CSUM_MANGLED_0)
sum = 0; sum = 0;
......
...@@ -132,6 +132,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb) ...@@ -132,6 +132,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
ip6h->saddr = oip6h->daddr; ip6h->saddr = oip6h->daddr;
ip6h->daddr = oip6h->saddr; ip6h->daddr = oip6h->saddr;
skb_reset_transport_header(nskb);
tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr)); tcph = (struct tcphdr *)skb_put(nskb, sizeof(struct tcphdr));
/* Truncate to length (no data) */ /* Truncate to length (no data) */
tcph->doff = sizeof(struct tcphdr)/4; tcph->doff = sizeof(struct tcphdr)/4;
......
...@@ -127,23 +127,28 @@ nf_nat_ipv6_fn(unsigned int hooknum, ...@@ -127,23 +127,28 @@ nf_nat_ipv6_fn(unsigned int hooknum,
ret = nf_nat_rule_find(skb, hooknum, in, out, ct); ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
if (ret != NF_ACCEPT) if (ret != NF_ACCEPT)
return ret; return ret;
} else } else {
pr_debug("Already setup manip %s for ct %p\n", pr_debug("Already setup manip %s for ct %p\n",
maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST", maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
ct); ct);
if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
goto oif_changed;
}
break; break;
default: default:
/* ESTABLISHED */ /* ESTABLISHED */
NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED || NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
ctinfo == IP_CT_ESTABLISHED_REPLY); ctinfo == IP_CT_ESTABLISHED_REPLY);
if (nf_nat_oif_changed(hooknum, ctinfo, nat, out)) { if (nf_nat_oif_changed(hooknum, ctinfo, nat, out))
nf_ct_kill_acct(ct, ctinfo, skb); goto oif_changed;
return NF_DROP;
}
} }
return nf_nat_packet(ct, ctinfo, hooknum, skb); return nf_nat_packet(ct, ctinfo, hooknum, skb);
oif_changed:
nf_ct_kill_acct(ct, ctinfo, skb);
return NF_DROP;
} }
static unsigned int static unsigned int
......
...@@ -81,8 +81,8 @@ static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, ...@@ -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 = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off);
/* /*
* (protoff == skb->len) mean that the packet doesn't have no data * (protoff == skb->len) means the packet has not data, just
* except of IPv6 & ext headers. but it's tracked anyway. - YK * IPv6 and possibly extensions headers, but it is tracked anyway
*/ */
if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
pr_debug("ip6_conntrack_core: can't find proto in pkt\n"); pr_debug("ip6_conntrack_core: can't find proto in pkt\n");
......
...@@ -311,7 +311,10 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb, ...@@ -311,7 +311,10 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
else else
fq->q.fragments = skb; 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.stamp = skb->tstamp;
fq->q.meat += skb->len; fq->q.meat += skb->len;
if (payload_len > fq->q.max_size) if (payload_len > fq->q.max_size)
......
...@@ -389,7 +389,7 @@ void mac802154_wpan_setup(struct net_device *dev) ...@@ -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) static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
{ {
return netif_rx(skb); return netif_rx_ni(skb);
} }
static int static int
......
...@@ -680,6 +680,13 @@ config NETFILTER_XT_TARGET_NFQUEUE ...@@ -680,6 +680,13 @@ config NETFILTER_XT_TARGET_NFQUEUE
To compile it as a module, choose M here. If unsure, say N. 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 config NETFILTER_XT_TARGET_RATEEST
tristate '"RATEEST" target support' tristate '"RATEEST" target support'
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
......
...@@ -1526,6 +1526,7 @@ static int nf_conntrack_init_init_net(void) ...@@ -1526,6 +1526,7 @@ static int nf_conntrack_init_init_net(void)
*/ */
#define UNCONFIRMED_NULLS_VAL ((1<<30)+0) #define UNCONFIRMED_NULLS_VAL ((1<<30)+0)
#define DYING_NULLS_VAL ((1<<30)+1) #define DYING_NULLS_VAL ((1<<30)+1)
#define TEMPLATE_NULLS_VAL ((1<<30)+2)
static int nf_conntrack_init_net(struct net *net) static int nf_conntrack_init_net(struct net *net)
{ {
...@@ -1534,6 +1535,7 @@ 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); atomic_set(&net->ct.count, 0);
INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, UNCONFIRMED_NULLS_VAL); 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.dying, DYING_NULLS_VAL);
INIT_HLIST_NULLS_HEAD(&net->ct.tmpl, TEMPLATE_NULLS_VAL);
net->ct.stat = alloc_percpu(struct ip_conntrack_stat); net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
if (!net->ct.stat) { if (!net->ct.stat) {
ret = -ENOMEM; ret = -ENOMEM;
......
...@@ -2624,7 +2624,7 @@ ctnetlink_create_expect(struct net *net, u16 zone, ...@@ -2624,7 +2624,7 @@ ctnetlink_create_expect(struct net *net, u16 zone,
if (!help) { if (!help) {
if (!cda[CTA_EXPECT_TIMEOUT]) { if (!cda[CTA_EXPECT_TIMEOUT]) {
err = -EINVAL; err = -EINVAL;
goto out; goto err_out;
} }
exp->timeout.expires = exp->timeout.expires =
jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ; jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/ipv6.h> #include <linux/ipv6.h>
...@@ -384,6 +385,7 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -384,6 +385,7 @@ __build_packet_message(struct nfulnl_instance *inst,
struct nfgenmsg *nfmsg; struct nfgenmsg *nfmsg;
sk_buff_data_t old_tail = inst->skb->tail; sk_buff_data_t old_tail = inst->skb->tail;
struct sock *sk; struct sock *sk;
const unsigned char *hwhdrp;
nlh = nlmsg_put(inst->skb, 0, 0, nlh = nlmsg_put(inst->skb, 0, 0,
NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET, NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET,
...@@ -485,9 +487,17 @@ __build_packet_message(struct nfulnl_instance *inst, ...@@ -485,9 +487,17 @@ __build_packet_message(struct nfulnl_instance *inst,
if (indev && skb_mac_header_was_set(skb)) { if (indev && skb_mac_header_was_set(skb)) {
if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || if (nla_put_be16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) ||
nla_put_be16(inst->skb, NFULA_HWLEN, nla_put_be16(inst->skb, NFULA_HWLEN,
htons(skb->dev->hard_header_len)) || htons(skb->dev->hard_header_len)))
nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, goto nla_put_failure;
skb_mac_header(skb)))
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; goto nla_put_failure;
} }
......
...@@ -149,6 +149,10 @@ static int xt_ct_tg_check_v0(const struct xt_tgchk_param *par) ...@@ -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_TEMPLATE_BIT, &ct->status);
__set_bit(IPS_CONFIRMED_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: out:
info->ct = ct; info->ct = ct;
return 0; return 0;
...@@ -289,6 +293,10 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) ...@@ -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_TEMPLATE_BIT, &ct->status);
__set_bit(IPS_CONFIRMED_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: out:
info->ct = ct; info->ct = ct;
return 0; return 0;
...@@ -377,14 +385,60 @@ static struct xt_target xt_ct_tg_reg[] __read_mostly = { ...@@ -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) 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) static void __exit xt_ct_tg_exit(void)
{ {
xt_unregister_targets(xt_ct_tg_reg, ARRAY_SIZE(xt_ct_tg_reg)); 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); module_init(xt_ct_tg_init);
...@@ -394,3 +448,5 @@ MODULE_LICENSE("GPL"); ...@@ -394,3 +448,5 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Xtables: connection tracking target"); MODULE_DESCRIPTION("Xtables: connection tracking target");
MODULE_ALIAS("ipt_CT"); MODULE_ALIAS("ipt_CT");
MODULE_ALIAS("ip6t_CT"); MODULE_ALIAS("ip6t_CT");
MODULE_ALIAS("ipt_NOTRACK");
MODULE_ALIAS("ip6t_NOTRACK");
...@@ -157,11 +157,22 @@ dsthash_find(const struct xt_hashlimit_htable *ht, ...@@ -157,11 +157,22 @@ dsthash_find(const struct xt_hashlimit_htable *ht,
/* allocate dsthash_ent, initialize dst, put in htable and lock it */ /* allocate dsthash_ent, initialize dst, put in htable and lock it */
static struct dsthash_ent * static struct dsthash_ent *
dsthash_alloc_init(struct xt_hashlimit_htable *ht, dsthash_alloc_init(struct xt_hashlimit_htable *ht,
const struct dsthash_dst *dst) const struct dsthash_dst *dst, bool *race)
{ {
struct dsthash_ent *ent; struct dsthash_ent *ent;
spin_lock(&ht->lock); 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 /* initialize hash with random val at the time we allocate
* the first hashtable entry */ * the first hashtable entry */
if (unlikely(!ht->rnd_initialized)) { if (unlikely(!ht->rnd_initialized)) {
...@@ -318,7 +329,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo) ...@@ -318,7 +329,10 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
parent = hashlimit_net->ipt_hashlimit; parent = hashlimit_net->ipt_hashlimit;
else else
parent = hashlimit_net->ip6t_hashlimit; 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); htable_selective_cleanup(hinfo, select_all);
vfree(hinfo); vfree(hinfo);
} }
...@@ -585,6 +599,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -585,6 +599,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
unsigned long now = jiffies; unsigned long now = jiffies;
struct dsthash_ent *dh; struct dsthash_ent *dh;
struct dsthash_dst dst; struct dsthash_dst dst;
bool race = false;
u32 cost; u32 cost;
if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0) 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) ...@@ -593,13 +608,18 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
rcu_read_lock_bh(); rcu_read_lock_bh();
dh = dsthash_find(hinfo, &dst); dh = dsthash_find(hinfo, &dst);
if (dh == NULL) { if (dh == NULL) {
dh = dsthash_alloc_init(hinfo, &dst); dh = dsthash_alloc_init(hinfo, &dst, &race);
if (dh == NULL) { if (dh == NULL) {
rcu_read_unlock_bh(); rcu_read_unlock_bh();
goto hotdrop; 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 { } else {
/* update expiration timeout */ /* update expiration timeout */
dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire);
...@@ -856,6 +876,27 @@ static int __net_init hashlimit_proc_net_init(struct net *net) ...@@ -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) 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"); proc_net_remove(net, "ipt_hashlimit");
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
proc_net_remove(net, "ip6t_hashlimit"); proc_net_remove(net, "ip6t_hashlimit");
...@@ -872,9 +913,6 @@ static int __net_init hashlimit_net_init(struct net *net) ...@@ -872,9 +913,6 @@ static int __net_init hashlimit_net_init(struct net *net)
static void __net_exit hashlimit_net_exit(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); hashlimit_proc_net_exit(net);
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/inet.h> #include <linux/inet.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/netns/generic.h> #include <net/netns/generic.h>
...@@ -310,6 +311,14 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par) ...@@ -310,6 +311,14 @@ recent_mt(const struct sk_buff *skb, struct xt_action_param *par)
return ret; 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, static int recent_mt_check(const struct xt_mtchk_param *par,
const struct xt_recent_mtinfo_v1 *info) const struct xt_recent_mtinfo_v1 *info)
{ {
...@@ -322,6 +331,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -322,6 +331,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
#endif #endif
unsigned int i; unsigned int i;
int ret = -EINVAL; int ret = -EINVAL;
size_t sz;
if (unlikely(!hash_rnd_inited)) { if (unlikely(!hash_rnd_inited)) {
get_random_bytes(&hash_rnd, sizeof(hash_rnd)); get_random_bytes(&hash_rnd, sizeof(hash_rnd));
...@@ -360,8 +370,11 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -360,8 +370,11 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
goto out; goto out;
} }
t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, sz = sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size;
GFP_KERNEL); if (sz <= PAGE_SIZE)
t = kzalloc(sz, GFP_KERNEL);
else
t = vzalloc(sz);
if (t == NULL) { if (t == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -377,14 +390,14 @@ static int recent_mt_check(const struct xt_mtchk_param *par, ...@@ -377,14 +390,14 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
uid = make_kuid(&init_user_ns, ip_list_uid); uid = make_kuid(&init_user_ns, ip_list_uid);
gid = make_kgid(&init_user_ns, ip_list_gid); gid = make_kgid(&init_user_ns, ip_list_gid);
if (!uid_valid(uid) || !gid_valid(gid)) { if (!uid_valid(uid) || !gid_valid(gid)) {
kfree(t); recent_table_free(t);
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent,
&recent_mt_fops, t); &recent_mt_fops, t);
if (pde == NULL) { if (pde == NULL) {
kfree(t); recent_table_free(t);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
...@@ -431,10 +444,11 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par) ...@@ -431,10 +444,11 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par)
list_del(&t->list); list_del(&t->list);
spin_unlock_bh(&recent_lock); spin_unlock_bh(&recent_lock);
#ifdef CONFIG_PROC_FS #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 #endif
recent_table_flush(t); recent_table_flush(t);
kfree(t); recent_table_free(t);
} }
mutex_unlock(&recent_mutex); mutex_unlock(&recent_mutex);
} }
...@@ -615,6 +629,20 @@ static int __net_init recent_proc_net_init(struct net *net) ...@@ -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) 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"); proc_net_remove(net, "xt_recent");
} }
#else #else
...@@ -638,9 +666,6 @@ static int __net_init recent_net_init(struct net *net) ...@@ -638,9 +666,6 @@ static int __net_init recent_net_init(struct net *net)
static void __net_exit recent_net_exit(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); recent_proc_net_exit(net);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment