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
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
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.
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.
* 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
blocking.
1: rcvbuf space is per association
- 0: recbuf space is per socket
+ 0: rcvbuf space is per socket
Default: 0
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.
{ "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 },
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();
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);
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));
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);
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);
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));
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);
{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 */
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);
tristate
config ATH9K_COMMON
tristate
+ select ATH_COMMON
config ATH9K_DFS_DEBUGFS
def_bool y
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
config ATH9K
tristate "Atheros 802.11n wireless cards support"
depends on MAC80211
- select ATH_COMMON
select ATH9K_HW
select MAC80211_LEDS
select LEDS_CLASS
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.
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);
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 */
}
}
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) {
/*
* 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
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;
{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 */
{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 */
{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 */
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,
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);
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) {
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)
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;
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);
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 ||
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);
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. */
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 ||
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)
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,
RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG,
"Failed to prep_rx_urb!!\n");
err = PTR_ERR(skb);
+ usb_free_urb(urb);
goto err_out;
}
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)
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.
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);
}
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;
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;
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)
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)
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);
}
{
return 0;
}
+static inline void br_mdb_init(void)
+{
+}
+static inline void br_mdb_uninit(void)
+{
+}
#endif
/* br_netfilter.c */
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
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 */
if (ic_myaddr == NONE)
ic_myaddr = tip;
ic_servaddr = sip;
+ ic_addrservaddr = sip;
ic_got_reply = IC_RARP;
drop_unlock:
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
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)
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;
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;
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
#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;
}
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;
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;
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
}
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");
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)
static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb)
{
- return netif_rx(skb);
+ return netif_rx_ni(skb);
}
static int
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
*/
#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)
{
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;
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;
*/
#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>
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,
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;
}
__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;
__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;
},
};
+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(¬rack_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(¬rack_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(¬rack_tg_reg);
}
module_init(xt_ct_tg_init);
MODULE_DESCRIPTION("Xtables: connection tracking target");
MODULE_ALIAS("ipt_CT");
MODULE_ALIAS("ip6t_CT");
+MODULE_ALIAS("ipt_NOTRACK");
+MODULE_ALIAS("ip6t_NOTRACK");
/* 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)) {
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);
}
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)
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);
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");
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);
}
#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>
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)
{
#endif
unsigned int i;
int ret = -EINVAL;
+ size_t sz;
if (unlikely(!hash_rnd_inited)) {
get_random_bytes(&hash_rnd, sizeof(hash_rnd));
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;
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;
}
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);
}
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
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);
}