summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/atm/solos-pci.c4
-rw-r--r--drivers/bluetooth/btusb.c4
-rw-r--r--drivers/net/can/sja1000/sja1000.c13
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/ethernet/broadcom/b44.c2
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c6
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_enet_desc.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.c2
-rw-r--r--drivers/net/ethernet/jme.c10
-rw-r--r--drivers/net/ethernet/jme.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c2
-rw-r--r--drivers/net/ethernet/sfc/rx.c4
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c6
-rw-r--r--drivers/net/phy/icplus.c55
-rw-r--r--drivers/net/ppp/ppp_generic.c23
-rw-r--r--drivers/net/usb/cdc_ether.c7
-rw-r--r--drivers/net/usb/hso.c2
-rw-r--r--drivers/net/usb/zaurus.c12
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c8
-rw-r--r--include/linux/if_link.h1
-rw-r--r--include/linux/netfilter_bridge/ebtables.h4
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/skbuff.h10
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/bluetooth/hci_core.h6
-rw-r--r--include/net/bluetooth/l2cap.h12
-rw-r--r--include/net/netfilter/nf_conntrack.h2
-rw-r--r--include/net/rtnetlink.h2
-rw-r--r--net/atm/clip.c10
-rw-r--r--net/bluetooth/af_bluetooth.c12
-rw-r--r--net/bluetooth/hci_conn.c4
-rw-r--r--net/bluetooth/hci_core.c3
-rw-r--r--net/bluetooth/l2cap_core.c24
-rw-r--r--net/bluetooth/l2cap_sock.c4
-rw-r--r--net/bluetooth/rfcomm/core.c18
-rw-r--r--net/bluetooth/rfcomm/sock.c2
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/rtnetlink.c78
-rw-r--r--net/ipv4/ip_gre.c10
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/xfrm4_mode_beet.c5
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c6
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ndisc.c5
-rw-r--r--net/ipv6/xfrm6_mode_beet.c6
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c6
-rw-r--r--net/mac80211/debugfs_sta.c4
-rw-r--r--net/mac80211/rate.c2
-rw-r--r--net/mac80211/rate.h3
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c38
-rw-r--r--net/netfilter/nf_conntrack_netlink.c46
-rw-r--r--net/netfilter/nf_queue.c40
-rw-r--r--net/netfilter/xt_TEE.c5
-rw-r--r--net/sched/sch_netem.c6
61 files changed, 380 insertions, 204 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 5d1d076..e8cd652 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1206,9 +1206,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
out_unmap_both:
pci_set_drvdata(dev, NULL);
- pci_iounmap(dev, card->config_regs);
- out_unmap_config:
pci_iounmap(dev, card->buffers);
+ out_unmap_config:
+ pci_iounmap(dev, card->config_regs);
out_release_regions:
pci_release_regions(dev);
out:
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f00f596..789c9b5 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0a5c, 0x21e3) },
+ { USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
{ } /* Terminating entry */
@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb)
usb_fill_bulk_urb(urb, data->udev, pipe,
skb->data, skb->len, btusb_tx_complete, skb);
- if (skb->priority >= HCI_PRIO_MAX - 1)
- urb->transfer_flags = URB_ISO_ASAP;
-
hdev->stat.acl_tx++;
break;
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 04a3f1b..192b0d1 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
}
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+ return (priv->read_reg(priv, REG_MOD) == 0xFF);
+}
+
static int sja1000_probe_chip(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
- if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+ if (priv->reg_base && sja1000_is_absent(priv)) {
printk(KERN_INFO "%s: probing @0x%lX failed\n",
DRV_NAME, dev->base_addr);
return 0;
@@ -493,6 +498,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
n++;
status = priv->read_reg(priv, REG_SR);
+ /* check for absent controller due to hw unplug */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ return IRQ_NONE;
if (isrc & IRQ_WUI)
dev_warn(dev->dev.parent, "wakeup interrupt\n");
@@ -509,6 +517,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
while (status & SR_RBS) {
sja1000_rx(dev);
status = priv->read_reg(priv, REG_SR);
+ /* check for absent controller */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ return IRQ_NONE;
}
}
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index b859124..1ff3c6d 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2244,10 +2244,6 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
dev_info(&adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
- if (skb->mark == 0x01)
- type = atl1c_trans_high;
- else
- type = atl1c_trans_normal;
if (atl1c_tpd_avail(adapter, type) < tpd_req) {
/* no enough descriptor, just stop queue */
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 3fb66d0..cab8745 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2339,7 +2339,7 @@ static inline int __init b44_pci_init(void)
return err;
}
-static inline void __exit b44_pci_exit(void)
+static inline void b44_pci_exit(void)
{
#ifdef CONFIG_B44_PCI
ssb_pcihost_unregister(&b44_pci_driver);
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index dd3a0a2..818a573 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -3584,7 +3584,11 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr,
fl6.flowi6_oif = dst_addr->sin6_scope_id;
*dst = ip6_route_output(&init_net, NULL, &fl6);
- if (*dst)
+ if ((*dst)->error) {
+ dst_release(*dst);
+ *dst = NULL;
+ return -ENETUNREACH;
+ } else
return 0;
#endif
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
index c2c0680..ac37cac 100644
--- a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
+++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
@@ -157,7 +157,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0;
*fcoe_enc_error = (desc->flags &
CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0;
- *fcoe_eof = (u8)((desc->checksum_fcoe >>
+ *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >>
CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) &
CQ_ENET_RQ_DESC_FCOE_EOF_MASK);
*checksum = 0;
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index 22bf03a..c347b62 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -72,7 +72,7 @@ static int enic_set_port_profile(struct enic *enic, int vf)
struct enic_port_profile *pp;
struct vic_provinfo *vp;
const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
- const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
+ const __be16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
char uuid_str[38];
char client_mac_str[18];
u8 *client_mac;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 27d651a..55cbf65 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2328,19 +2328,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
((new_mtu) < IPV6_MIN_MTU))
return -EINVAL;
- if (new_mtu > 4000) {
- jme->reg_rxcs &= ~RXCS_FIFOTHNP;
- jme->reg_rxcs |= RXCS_FIFOTHNP_64QW;
- jme_restart_rx_engine(jme);
- } else {
- jme->reg_rxcs &= ~RXCS_FIFOTHNP;
- jme->reg_rxcs |= RXCS_FIFOTHNP_128QW;
- jme_restart_rx_engine(jme);
- }
netdev->mtu = new_mtu;
netdev_update_features(netdev);
+ jme_restart_rx_engine(jme);
jme_reset_link(jme);
return 0;
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 4304072..3efc897 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -730,7 +730,7 @@ enum jme_rxcs_values {
RXCS_RETRYCNT_60 = 0x00000F00,
RXCS_DEFAULT = RXCS_FIFOTHTP_128T |
- RXCS_FIFOTHNP_128QW |
+ RXCS_FIFOTHNP_16QW |
RXCS_DMAREQSZ_128B |
RXCS_RETRYGAP_256ns |
RXCS_RETRYCNT_32,
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 8fa41f3..9129ace0 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1036,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
struct mlx4_priv *priv = mlx4_priv(dev);
int vec = 0, err = 0, i;
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
if (~priv->msix_ctl.pool_bm & 1ULL << i) {
priv->msix_ctl.pool_bm |= 1ULL << i;
@@ -1058,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
eq_set_ci(&priv->eq_table.eq[vec], 1);
}
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
if (vec) {
*vector = vec;
@@ -1079,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
if (likely(i >= 0)) {
/*sanity check , making sure were not trying to free irq's
Belonging to a legacy EQ*/
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
if (priv->msix_ctl.pool_bm & 1ULL << i) {
free_irq(priv->eq_table.eq[vec].irq,
&priv->eq_table.eq[vec]);
priv->msix_ctl.pool_bm &= ~(1ULL << i);
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 678558b..d498f04 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
for (port = 0; port < dev->caps.num_ports; port++) {
/* Change the port type only if the new type is different
* from the current, and not set to Auto */
- if (port_types[port] != dev->caps.port_type[port + 1]) {
+ if (port_types[port] != dev->caps.port_type[port + 1])
change = 1;
- dev->caps.port_type[port + 1] = port_types[port];
- }
}
if (change) {
mlx4_unregister_device(dev);
for (port = 1; port <= dev->caps.num_ports; port++) {
mlx4_CLOSE_PORT(dev, port);
+ dev->caps.port_type[port] = port_types[port - 1];
err = mlx4_SET_PORT(dev, port);
if (err) {
mlx4_err(dev, "Failed to set port %d, "
@@ -986,6 +985,9 @@ static int map_bf_area(struct mlx4_dev *dev)
resource_size_t bf_len;
int err = 0;
+ if (!dev->caps.bf_reg_size)
+ return -ENXIO;
+
bf_start = pci_resource_start(dev->pdev, 2) +
(dev->caps.num_uars << PAGE_SHIFT);
bf_len = pci_resource_len(dev->pdev, 2) -
@@ -1825,7 +1827,7 @@ slave_start:
goto err_master_mfunc;
priv->msix_ctl.pool_bm = 0;
- spin_lock_init(&priv->msix_ctl.pool_lock);
+ mutex_init(&priv->msix_ctl.pool_lock);
mlx4_enable_msi_x(dev);
if ((mlx4_is_mfunc(dev)) &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index c92269f..28f8251 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -697,7 +697,7 @@ struct mlx4_sense {
struct mlx4_msix_ctl {
u64 pool_bm;
- spinlock_t pool_lock;
+ struct mutex pool_lock;
};
struct mlx4_steer {
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 231176f..2784bc7 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1545,7 +1545,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
netdev->irq = platform_get_irq(pdev, 0);
- if (netdev->irq < 0) {
+ if ((int)netdev->irq < 0) {
err = netdev->irq;
goto err_get_irq;
}
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index aca3498..fc52fca 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -156,11 +156,10 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
if (unlikely(!skb))
return -ENOMEM;
- /* Adjust the SKB for padding and checksum */
+ /* Adjust the SKB for padding */
skb_reserve(skb, NET_IP_ALIGN);
rx_buf->len = skb_len - NET_IP_ALIGN;
rx_buf->is_page = false;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
rx_buf->dma_addr = pci_map_single(efx->pci_dev,
skb->data, rx_buf->len,
@@ -496,6 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
EFX_BUG_ON_PARANOID(!checksummed);
rx_buf->u.skb = NULL;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
gro_result = napi_gro_receive(napi, skb);
}
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 4fa0bcb..4b2f545 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1009,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status)
int ret;
/* free and bail if we are shutting down */
- if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) {
+ if (unlikely(!netif_running(ndev))) {
dev_kfree_skb_any(skb);
return;
}
@@ -1038,7 +1038,9 @@ static void emac_rx_handler(void *token, int len, int status)
recycle:
ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
skb_tailroom(skb), GFP_KERNEL);
- if (WARN_ON(ret < 0))
+
+ WARN_ON(ret == -ENOMEM);
+ if (unlikely(ret < 0))
dev_kfree_skb_any(skb);
}
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c81f136..0856e1b 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,16 +30,16 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers");
+MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
MODULE_AUTHOR("Michael Barkowski");
MODULE_LICENSE("GPL");
-/* IP101A/IP1001 */
-#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
-#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
-#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
-#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
-#define IP101A_APS_ON 2 /* IP101A APS Mode bit */
+/* IP101A/G - IP1001 */
+#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
+#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
+#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
+#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
+#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */
static int ip175c_config_init(struct phy_device *phydev)
{
@@ -98,20 +98,24 @@ static int ip175c_config_init(struct phy_device *phydev)
static int ip1xx_reset(struct phy_device *phydev)
{
- int err, bmcr;
+ int bmcr;
/* Software Reset PHY */
bmcr = phy_read(phydev, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
bmcr |= BMCR_RESET;
- err = phy_write(phydev, MII_BMCR, bmcr);
- if (err < 0)
- return err;
+ bmcr = phy_write(phydev, MII_BMCR, bmcr);
+ if (bmcr < 0)
+ return bmcr;
do {
bmcr = phy_read(phydev, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
} while (bmcr & BMCR_RESET);
- return err;
+ return 0;
}
static int ip1001_config_init(struct phy_device *phydev)
@@ -124,7 +128,10 @@ static int ip1001_config_init(struct phy_device *phydev)
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
+ if (c < 0)
+ return c;
c |= IP1001_APS_ON;
+ c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c);
if (c < 0)
return c;
@@ -132,14 +139,19 @@ static int ip1001_config_init(struct phy_device *phydev)
/* Additional delay (2ns) used to adjust RX clock phase
* at RGMII interface */
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
+ if (c < 0)
+ return c;
+
c |= IP1001_PHASE_SEL_MASK;
c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
+ if (c < 0)
+ return c;
}
- return c;
+ return 0;
}
-static int ip101a_config_init(struct phy_device *phydev)
+static int ip101a_g_config_init(struct phy_device *phydev)
{
int c;
@@ -149,7 +161,7 @@ static int ip101a_config_init(struct phy_device *phydev)
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
- c |= IP101A_APS_ON;
+ c |= IP101A_G_APS_ON;
return c;
}
@@ -191,6 +203,7 @@ static struct phy_driver ip1001_driver = {
.phy_id_mask = 0x0ffffff0,
.features = PHY_GBIT_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
+ .flags = PHY_HAS_INTERRUPT,
.config_init = &ip1001_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
@@ -199,13 +212,14 @@ static struct phy_driver ip1001_driver = {
.driver = { .owner = THIS_MODULE,},
};
-static struct phy_driver ip101a_driver = {
+static struct phy_driver ip101a_g_driver = {
.phy_id = 0x02430c54,
- .name = "ICPlus IP101A",
+ .name = "ICPlus IP101A/G",
.phy_id_mask = 0x0ffffff0,
.features = PHY_BASIC_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
- .config_init = &ip101a_config_init,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &ip101a_g_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.suspend = genphy_suspend,
@@ -221,7 +235,7 @@ static int __init icplus_init(void)
if (ret < 0)
return -ENODEV;
- ret = phy_driver_register(&ip101a_driver);
+ ret = phy_driver_register(&ip101a_g_driver);
if (ret < 0)
return -ENODEV;
@@ -231,7 +245,7 @@ static int __init icplus_init(void)
static void __exit icplus_exit(void)
{
phy_driver_unregister(&ip1001_driver);
- phy_driver_unregister(&ip101a_driver);
+ phy_driver_unregister(&ip101a_g_driver);
phy_driver_unregister(&ip175c_driver);
}
@@ -241,6 +255,7 @@ module_exit(icplus_exit);
static struct mdio_device_id __maybe_unused icplus_tbl[] = {
{ 0x02430d80, 0x0ffffff0 },
{ 0x02430d90, 0x0ffffff0 },
+ { 0x02430c54, 0x0ffffff0 },
{ }
};
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index edfa15d..486b404 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2024,14 +2024,22 @@ ppp_mp_reconstruct(struct ppp *ppp)
continue;
}
if (PPP_MP_CB(p)->sequence != seq) {
+ u32 oldseq;
/* Fragment `seq' is missing. If it is after
minseq, it might arrive later, so stop here. */
if (seq_after(seq, minseq))
break;
/* Fragment `seq' is lost, keep going. */
lost = 1;
+ oldseq = seq;
seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
minseq + 1: PPP_MP_CB(p)->sequence;
+
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "lost frag %u..%u\n",
+ oldseq, seq-1);
+
goto again;
}
@@ -2076,6 +2084,10 @@ ppp_mp_reconstruct(struct ppp *ppp)
struct sk_buff *tmp2;
skb_queue_reverse_walk_from_safe(list, p, tmp2) {
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "discarding frag %u\n",
+ PPP_MP_CB(p)->sequence);
__skb_unlink(p, list);
kfree_skb(p);
}
@@ -2091,6 +2103,17 @@ ppp_mp_reconstruct(struct ppp *ppp)
/* If we have discarded any fragments,
signal a receive error. */
if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
+ skb_queue_walk_safe(list, p, tmp) {
+ if (p == head)
+ break;
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "discarding frag %u\n",
+ PPP_MP_CB(p)->sequence);
+ __skb_unlink(p, list);
+ kfree_skb(p);
+ }
+
if (ppp->debug & 1)
netdev_printk(KERN_DEBUG, ppp->dev,
" missed pkts %u..%u\n",
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 41a61ef..90a3002 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -573,6 +573,13 @@ static const struct usb_device_id products [] = {
.driver_info = 0,
},
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = 0,
+},
+
/*
* WHITELIST!!!
*
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 304fe78..e1324b4 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1632,7 +1632,7 @@ static int hso_get_count(struct tty_struct *tty,
struct hso_serial *serial = get_serial_by_tty(tty);
struct hso_tiocmget *tiocmget = serial->tiocmget;
- memset(&icount, 0, sizeof(struct serial_icounter_struct));
+ memset(icount, 0, sizeof(struct serial_icounter_struct));
if (!tiocmget)
return -ENOENT;
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index f701d41..c3197ce 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -316,6 +316,11 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO,
}, {
+ /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
+ USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
@@ -349,6 +354,13 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = OLYMPUS_MXL_INFO,
},
+
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
+},
{ }, // END
};
MODULE_DEVICE_TABLE(usb, products);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index de7fc34..3dcd385 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -843,8 +843,8 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
/* for simplicity, don't copy L4 headers */
ctx->l4_hdr_size = 0;
}
- ctx->copy_size = ctx->eth_ip_hdr_size +
- ctx->l4_hdr_size;
+ ctx->copy_size = min(ctx->eth_ip_hdr_size +
+ ctx->l4_hdr_size, skb->len);
} else {
ctx->eth_ip_hdr_size = 0;
ctx->l4_hdr_size = 0;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 635b592..a427a16 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
fc = hdr->frame_control;
for (i = 0; i < sc->hw->max_rates; i++) {
struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
- if (!rate->count)
+ if (rate->idx < 0 || !rate->count)
break;
final_ts_idx = i;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c3b6c46..5b2972b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -841,7 +841,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
ret = mwifiex_set_rf_channel(priv, channel,
priv->adapter->channel_type);
- ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */
+ /* As this is new association, clear locally stored
+ * keys and security related flags */
+ priv->sec_info.wpa_enabled = false;
+ priv->sec_info.wpa2_enabled = false;
+ priv->wep_key_curr_index = 0;
+ ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
if (mode == NL80211_IFTYPE_ADHOC) {
/* "privacy" is set only for ad-hoc mode */
@@ -886,6 +891,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
dev_dbg(priv->adapter->dev,
"info: setting wep encryption"
" with key len %d\n", sme->key_len);
+ priv->wep_key_curr_index = sme->key_idx;
ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
sme->key_idx, 0);
}
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index c52d4b5..4b24ff4 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -137,6 +137,7 @@ enum {
IFLA_AF_SPEC,
IFLA_GROUP, /* Group the device belongs to */
IFLA_NET_NS_FD,
+ IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
__IFLA_MAX
};
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 8797ed1..4dd5bd6 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -285,8 +285,8 @@ struct ebt_table {
struct module *me;
};
-#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
- ~(__alignof__(struct ebt_replace)-1))
+#define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \
+ ~(__alignof__(struct _xt_align)-1))
extern struct ebt_table *ebt_register_table(struct net *net,
const struct ebt_table *table);
extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 8e872ea..577592e 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -602,6 +602,9 @@ struct tcamsg {
#define TCA_ACT_TAB 1 /* attr type must be >=1 */
#define TCAA_MAX 1
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF (1 << 0)
+
/* End of information exported to user level */
#ifdef __KERNEL__
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 50db9b0..ae86ade 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1465,6 +1465,16 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset)
}
#endif /* NET_SKBUFF_DATA_USES_OFFSET */
+static inline void skb_mac_header_rebuild(struct sk_buff *skb)
+{
+ if (skb_mac_header_was_set(skb)) {
+ const unsigned char *old_mac = skb_mac_header(skb);
+
+ skb_set_mac_header(skb, -skb->mac_len);
+ memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+ }
+}
+
static inline int skb_checksum_start_offset(const struct sk_buff *skb)
{
return skb->csum_start - skb_headroom(skb);
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index abaad6e..4a82ca0 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -256,4 +256,6 @@ void l2cap_exit(void);
int sco_init(void);
void sco_exit(void);
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
#endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea9231f..453893b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn);
static inline void hci_conn_hold(struct hci_conn *conn)
{
atomic_inc(&conn->refcnt);
- cancel_delayed_work_sync(&conn->disc_work);
+ cancel_delayed_work(&conn->disc_work);
}
static inline void hci_conn_put(struct hci_conn *conn)
@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
} else {
timeo = msecs_to_jiffies(10);
}
- cancel_delayed_work_sync(&conn->disc_work);
+ cancel_delayed_work(&conn->disc_work);
queue_delayed_work(conn->hdev->workqueue,
- &conn->disc_work, jiffies + timeo);
+ &conn->disc_work, timeo);
}
}
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 68f5891..b1664ed 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
- if (!__cancel_delayed_work(work))
+ if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
static inline void l2cap_clear_timer(struct l2cap_chan *chan,
struct delayed_work *work)
{
- if (__cancel_delayed_work(work))
+ if (cancel_delayed_work(work))
l2cap_chan_put(chan);
}
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
- L2CAP_DEFAULT_RETRANS_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
- L2CAP_DEFAULT_MONITOR_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
- L2CAP_DEFAULT_ACK_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
u32 priority);
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 8a2b0ae..ab86036 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -209,7 +209,7 @@ extern struct nf_conntrack_tuple_hash *
__nf_conntrack_find(struct net *net, u16 zone,
const struct nf_conntrack_tuple *tuple);
-extern void nf_conntrack_hash_insert(struct nf_conn *ct);
+extern int nf_conntrack_hash_check_insert(struct nf_conn *ct);
extern void nf_ct_delete_from_lists(struct nf_conn *ct);
extern void nf_ct_insert_dying_list(struct nf_conn *ct);
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 678f1ff..3702939 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -6,7 +6,7 @@
typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *);
typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
-typedef u16 (*rtnl_calcit_func)(struct sk_buff *);
+typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *);
extern int __rtnl_register(int protocol, int msgtype,
rtnl_doit_func, rtnl_dumpit_func,
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c258..127fe70 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -46,8 +46,8 @@
static struct net_device *clip_devs;
static struct atm_vcc *atmarpd;
-static struct neigh_table clip_tbl;
static struct timer_list idle_timer;
+static const struct neigh_ops clip_neigh_ops;
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
{
@@ -123,6 +123,8 @@ static int neigh_check_cb(struct neighbour *n)
struct atmarp_entry *entry = neighbour_priv(n);
struct clip_vcc *cv;
+ if (n->ops != &clip_neigh_ops)
+ return 0;
for (cv = entry->vccs; cv; cv = cv->next) {
unsigned long exp = cv->last_use + cv->idle_timeout;
@@ -154,10 +156,10 @@ static int neigh_check_cb(struct neighbour *n)
static void idle_timer_check(unsigned long dummy)
{
- write_lock(&clip_tbl.lock);
- __neigh_for_each_release(&clip_tbl, neigh_check_cb);
+ write_lock(&arp_tbl.lock);
+ __neigh_for_each_release(&arp_tbl, neigh_check_cb);
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
- write_unlock(&clip_tbl.lock);
+ write_unlock(&arp_tbl.lock);
}
static int clip_arp_rcv(struct sk_buff *skb)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ef92864..72eb187 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
};
-static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+void bt_sock_reclassify_lock(struct sock *sk, int proto)
{
- struct sock *sk = sock->sk;
-
- if (!sk)
- return;
-
+ BUG_ON(!sk);
BUG_ON(sock_owned_by_user(sk));
sock_lock_init_class_and_name(sk,
bt_slock_key_strings[proto], &bt_slock_key[proto],
bt_key_strings[proto], &bt_lock_key[proto]);
}
+EXPORT_SYMBOL(bt_sock_reclassify_lock);
int bt_sock_register(int proto, const struct net_proto_family *ops)
{
@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto,
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(net, sock, proto, kern);
- bt_sock_reclassify_lock(sock, proto);
+ if (!err)
+ bt_sock_reclassify_lock(sock->sk, proto);
module_put(bt_proto[proto]->owner);
}
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3db4324..07bc69e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
+
+ /* encrypt must be pending if auth is also pending */
+ set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9de9371..5aeb624 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
- if (!test_bit(HCI_RAW, &hdev->flags)) {
+ if (!test_bit(HCI_RAW, &hdev->flags) &&
+ test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(250));
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index faf0b11..32d338c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work_sync(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
return c1;
}
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
{
struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src;
@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) {
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default:
sk->sk_err = ECONNRESET;
- __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0;
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
if (encrypt == 0x00) {
if (chan->sec_level == BT_SECURITY_MEDIUM) {
__clear_chan_timer(chan);
- __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
} else if (chan->sec_level == BT_SECURITY_HIGH)
l2cap_chan_close(chan, ECONNREFUSED);
} else {
@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0);
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();
@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
L2CAP_CONN_REQ, sizeof(req), &req);
} else {
__clear_chan_timer(chan);
- __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
}
} else if (chan->state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
}
} else {
l2cap_state_change(chan, BT_DISCONN);
- __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c61d967..401d942 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
if (!sk)
return NULL;
+ bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
l2cap_sock_init(sk, parent);
return l2cap_pi(sk)->chan;
@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
- sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+ sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sock_reset_flag(sk, SOCK_ZAPPED);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 501649b..8a60238 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
break;
case BT_DISCONN:
- /* When socket is closed and we are not RFCOMM
- * initiator rfcomm_process_rx already calls
- * rfcomm_session_put() */
- if (s->sock->sk->sk_state != BT_CLOSED)
- if (list_empty(&s->dlcs))
- rfcomm_session_put(s);
+ /* rfcomm_session_put is called later so don't do
+ * anything here otherwise we will mess up the session
+ * reference counter:
+ *
+ * (a) when we are the initiator dlc_unlink will drive
+ * the reference counter to 0 (there is no initial put
+ * after session_add)
+ *
+ * (b) when we are not the initiator rfcomm_rx_process
+ * will explicitly call put to balance the initial hold
+ * done after session add.
+ */
break;
}
}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index f066678..22169c3 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if (!sk)
goto done;
+ bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
+
rfcomm_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, &src);
bacpy(&bt_sk(sk)->dst, &dst);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e287346..2a83914 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -826,6 +826,8 @@ next_elt:
write_unlock_bh(&tbl->lock);
cond_resched();
write_lock_bh(&tbl->lock);
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
}
/* Cycle through all hash buckets every base_reachable_time/2 ticks.
* ARP entry timeouts range from 1/2 base_reachable_time to 3/2
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 65aebd4..606a6e8 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -60,7 +60,6 @@ struct rtnl_link {
};
static DEFINE_MUTEX(rtnl_mutex);
-static u16 min_ifinfo_dump_size;
void rtnl_lock(void)
{
@@ -724,10 +723,11 @@ static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
}
/* All VF info */
-static inline int rtnl_vfinfo_size(const struct net_device *dev)
+static inline int rtnl_vfinfo_size(const struct net_device *dev,
+ u32 ext_filter_mask)
{
- if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
-
+ if (dev->dev.parent && dev_is_pci(dev->dev.parent) &&
+ (ext_filter_mask & RTEXT_FILTER_VF)) {
int num_vfs = dev_num_vf(dev->dev.parent);
size_t size = nla_total_size(sizeof(struct nlattr));
size += nla_total_size(num_vfs * sizeof(struct nlattr));
@@ -766,7 +766,8 @@ static size_t rtnl_port_size(const struct net_device *dev)
return port_self_size;
}
-static noinline size_t if_nlmsg_size(const struct net_device *dev)
+static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ u32 ext_filter_mask)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -784,8 +785,9 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev)
+ nla_total_size(4) /* IFLA_MASTER */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
- + nla_total_size(4) /* IFLA_NUM_VF */
- + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
+ + nla_total_size(ext_filter_mask
+ & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
+ + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
+ rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
@@ -868,7 +870,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
- unsigned int flags)
+ unsigned int flags, u32 ext_filter_mask)
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
@@ -941,10 +943,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
copy_rtnl_link_stats64(nla_data(attr), stats);
- if (dev->dev.parent)
+ if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF))
NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
- if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
+ if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent
+ && (ext_filter_mask & RTEXT_FILTER_VF)) {
int i;
struct nlattr *vfinfo, *vf;
@@ -1048,6 +1051,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
struct hlist_head *head;
struct hlist_node *node;
+ struct nlattr *tb[IFLA_MAX+1];
+ u32 ext_filter_mask = 0;
s_h = cb->args[0];
s_idx = cb->args[1];
@@ -1055,6 +1060,12 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
rcu_read_lock();
cb->seq = net->dev_base_seq;
+ nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+ ifla_policy);
+
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
@@ -1064,7 +1075,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, 0,
- NLM_F_MULTI) <= 0)
+ NLM_F_MULTI,
+ ext_filter_mask) <= 0)
goto out;
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -1100,6 +1112,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_VF_PORTS] = { .type = NLA_NESTED },
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
+ [IFLA_EXT_MASK] = { .type = NLA_U32 },
};
EXPORT_SYMBOL(ifla_policy);
@@ -1509,8 +1522,6 @@ errout:
if (send_addr_notify)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
- min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev),
- min_ifinfo_dump_size);
return err;
}
@@ -1842,6 +1853,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
struct net_device *dev = NULL;
struct sk_buff *nskb;
int err;
+ u32 ext_filter_mask = 0;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err < 0)
@@ -1850,6 +1862,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (tb[IFLA_IFNAME])
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
@@ -1861,12 +1876,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (dev == NULL)
return -ENODEV;
- nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
+ nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL);
if (nskb == NULL)
return -ENOBUFS;
err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
- nlh->nlmsg_seq, 0, 0);
+ nlh->nlmsg_seq, 0, 0, ext_filter_mask);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE);
@@ -1877,8 +1892,31 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
return err;
}
-static u16 rtnl_calcit(struct sk_buff *skb)
+static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ struct nlattr *tb[IFLA_MAX+1];
+ u32 ext_filter_mask = 0;
+ u16 min_ifinfo_dump_size = 0;
+
+ nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy);
+
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
+ if (!ext_filter_mask)
+ return NLMSG_GOODSIZE;
+ /*
+ * traverse the list of net devices and compute the minimum
+ * buffer size based upon the filter mask.
+ */
+ list_for_each_entry(dev, &net->dev_base_head, dev_list) {
+ min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
+ if_nlmsg_size(dev,
+ ext_filter_mask));
+ }
+
return min_ifinfo_dump_size;
}
@@ -1913,13 +1951,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
int err = -ENOBUFS;
size_t if_info_size;
- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL);
+ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL);
if (skb == NULL)
goto errout;
- min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size);
-
- err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
+ err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
@@ -1977,7 +2013,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EOPNOTSUPP;
calcit = rtnl_get_calcit(family, type);
if (calcit)
- min_dump_alloc = calcit(skb);
+ min_dump_alloc = calcit(skb, nlh);
__rtnl_unlock();
rtnl = net->rtnl;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6b3ca5b..38673d2 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -65,7 +65,7 @@
it is infeasible task. The most general solutions would be
to keep skb->encapsulation counter (sort of local ttl),
and silently drop packet when it expires. It is a good
- solution, but it supposes maintaing new variable in ALL
+ solution, but it supposes maintaining new variable in ALL
skb, even if no tunneling is used.
Current solution: xmit_recursion breaks dead loops. This is a percpu
@@ -91,14 +91,14 @@
One of them is to parse packet trying to detect inner encapsulation
made by our node. It is difficult or even impossible, especially,
- taking into account fragmentation. TO be short, tt is not solution at all.
+ taking into account fragmentation. TO be short, ttl is not solution at all.
Current solution: The solution was UNEXPECTEDLY SIMPLE.
We force DF flag on tunnels with preconfigured hop limit,
that is ALL. :-) Well, it does not remove the problem completely,
but exponential growth of network traffic is changed to linear
(branches, that exceed pmtu are pruned) and tunnel mtu
- fastly degrades to value <68, where looping stops.
+ rapidly degrades to value <68, where looping stops.
Yes, it is not good if there exists a router in the loop,
which does not force DF, even when encapsulating packets have DF set.
But it is not our problem! Nobody could accuse us, we made
@@ -457,8 +457,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
GRE tunnels with enabled checksum. Tell them "thank you".
Well, I wonder, rfc1812 was written by Cisco employee,
- what the hell these idiots break standrads established
- by themself???
+ what the hell these idiots break standards established
+ by themselves???
*/
const struct iphdr *iph = (const struct iphdr *)skb->data;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index aea5a19..b072386 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -630,6 +630,7 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
+ err = -EOPNOTSUPP;
if (flags & MSG_OOB)
goto out;
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 6341818..e3db3f9 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -110,10 +110,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
skb_push(skb, sizeof(*iph));
skb_reset_network_header(skb);
-
- memmove(skb->data - skb->mac_len, skb_mac_header(skb),
- skb->mac_len);
- skb_set_mac_header(skb, -skb->mac_len);
+ skb_mac_header_rebuild(skb);
xfrm4_beet_make_header(skb);
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 534972e..ed4bf11 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -66,7 +66,6 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
- const unsigned char *old_mac;
int err = -EINVAL;
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
@@ -84,10 +83,9 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip_ecn_decapsulate(skb);
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
skb_reset_network_header(skb);
+ skb_mac_header_rebuild(skb);
+
err = 0;
out:
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index c7e95c8..5aa3981 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1926,8 +1926,10 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
};
dst = ip6_route_output(net, NULL, &fl6);
- if (!dst)
+ if (dst->error) {
+ dst_release(dst);
goto out_free;
+ }
skb_dst_drop(skb);
skb_dst_set(skb, dst);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d8f02ef..c964958 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1545,9 +1545,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
dst = ip6_route_output(net, NULL, &fl6);
- if (dst == NULL)
+ if (dst->error) {
+ dst_release(dst);
return;
-
+ }
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst))
return;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index a81ce94..9949a35 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -80,7 +80,6 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
{
struct ipv6hdr *ip6h;
- const unsigned char *old_mac;
int size = sizeof(struct ipv6hdr);
int err;
@@ -90,10 +89,7 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
__skb_push(skb, size);
skb_reset_network_header(skb);
-
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+ skb_mac_header_rebuild(skb);
xfrm6_beet_make_header(skb);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 261e6e6..9f2095b 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -63,7 +63,6 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
int err = -EINVAL;
- const unsigned char *old_mac;
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
goto out;
@@ -80,10 +79,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip6_ecn_decapsulate(skb);
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
skb_reset_network_header(skb);
+ skb_mac_header_rebuild(skb);
+
err = 0;
out:
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2406b3e..d86217d 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,14 +63,14 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
int res = scnprintf(buf, sizeof(buf),
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
TEST(PS_DRIVER), TEST(AUTHORIZED),
TEST(SHORT_PREAMBLE),
TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
- TEST(TDLS_PEER_AUTH));
+ TEST(TDLS_PEER_AUTH), TEST(RATE_CONTROL));
#undef TEST
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 5a5a776..ad64f4d 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -336,7 +336,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
int i;
u32 mask;
- if (sta) {
+ if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
ista = &sta->sta;
priv_sta = sta->rate_ctrl_priv;
}
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 168427b..80cfc00 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -41,7 +41,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv;
- if (!ref)
+ if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
return;
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
@@ -62,6 +62,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
+ set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
}
static inline void rate_control_rate_update(struct ieee80211_local *local,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12..bfed851 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
* @WLAN_STA_SP: Station is in a service period, so don't try to
* reply to other uAPSD trigger frames or PS-Poll.
* @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH,
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_UAPSD,
WLAN_STA_SP,
WLAN_STA_4ADDR_EVENT,
+ WLAN_STA_RATE_CONTROL,
};
enum ieee80211_sta_state {
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 611c335..2555816 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -232,6 +232,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
__be16 dport = 0; /* destination port to forward */
unsigned int flags;
struct ip_vs_conn_param param;
+ const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
union nf_inet_addr snet; /* source network of the client,
after masking */
@@ -267,7 +268,6 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
{
int protocol = iph.protocol;
const union nf_inet_addr *vaddr = &iph.daddr;
- const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
__be16 vport = 0;
if (dst_port == svc->port) {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 76613f5..ed86a3b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -404,19 +404,49 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
&net->ct.hash[repl_hash]);
}
-void nf_conntrack_hash_insert(struct nf_conn *ct)
+int
+nf_conntrack_hash_check_insert(struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
unsigned int hash, repl_hash;
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
u16 zone;
zone = nf_ct_zone(ct);
- hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
- repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ hash = hash_conntrack(net, zone,
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ repl_hash = hash_conntrack(net, zone,
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+ spin_lock_bh(&nf_conntrack_lock);
+ /* See if there's one in the list already, including reverse */
+ hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode)
+ if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ &h->tuple) &&
+ zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+ goto out;
+ hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode)
+ if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
+ &h->tuple) &&
+ zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+ goto out;
+
+ add_timer(&ct->timeout);
+ nf_conntrack_get(&ct->ct_general);
__nf_conntrack_hash_insert(ct, hash, repl_hash);
+ NF_CT_STAT_INC(net, insert);
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ return 0;
+
+out:
+ NF_CT_STAT_INC(net, insert_failed);
+ spin_unlock_bh(&nf_conntrack_lock);
+ return -EEXIST;
}
-EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
+EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
/* Confirm a connection given skb; places it in hash table */
int
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9307b03..30c9d4c 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1367,15 +1367,12 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
nf_ct_protonum(ct));
if (helper == NULL) {
rcu_read_unlock();
- spin_unlock_bh(&nf_conntrack_lock);
#ifdef CONFIG_MODULES
if (request_module("nfct-helper-%s", helpname) < 0) {
- spin_lock_bh(&nf_conntrack_lock);
err = -EOPNOTSUPP;
goto err1;
}
- spin_lock_bh(&nf_conntrack_lock);
rcu_read_lock();
helper = __nf_conntrack_helper_find(helpname,
nf_ct_l3num(ct),
@@ -1468,8 +1465,10 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
if (tstamp)
tstamp->start = ktime_to_ns(ktime_get_real());
- add_timer(&ct->timeout);
- nf_conntrack_hash_insert(ct);
+ err = nf_conntrack_hash_check_insert(ct);
+ if (err < 0)
+ goto err2;
+
rcu_read_unlock();
return ct;
@@ -1490,6 +1489,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct nf_conntrack_tuple otuple, rtuple;
struct nf_conntrack_tuple_hash *h = NULL;
struct nfgenmsg *nfmsg = nlmsg_data(nlh);
+ struct nf_conn *ct;
u_int8_t u3 = nfmsg->nfgen_family;
u16 zone;
int err;
@@ -1510,27 +1510,22 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
}
- spin_lock_bh(&nf_conntrack_lock);
if (cda[CTA_TUPLE_ORIG])
- h = __nf_conntrack_find(net, zone, &otuple);
+ h = nf_conntrack_find_get(net, zone, &otuple);
else if (cda[CTA_TUPLE_REPLY])
- h = __nf_conntrack_find(net, zone, &rtuple);
+ h = nf_conntrack_find_get(net, zone, &rtuple);
if (h == NULL) {
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE) {
- struct nf_conn *ct;
enum ip_conntrack_events events;
ct = ctnetlink_create_conntrack(net, zone, cda, &otuple,
&rtuple, u3);
- if (IS_ERR(ct)) {
- err = PTR_ERR(ct);
- goto out_unlock;
- }
+ if (IS_ERR(ct))
+ return PTR_ERR(ct);
+
err = 0;
- nf_conntrack_get(&ct->ct_general);
- spin_unlock_bh(&nf_conntrack_lock);
if (test_bit(IPS_EXPECTED_BIT, &ct->status))
events = IPCT_RELATED;
else
@@ -1545,23 +1540,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct, NETLINK_CB(skb).pid,
nlmsg_report(nlh));
nf_ct_put(ct);
- } else
- spin_unlock_bh(&nf_conntrack_lock);
+ }
return err;
}
/* implicit 'else' */
- /* We manipulate the conntrack inside the global conntrack table lock,
- * so there's no need to increase the refcount */
err = -EEXIST;
+ ct = nf_ct_tuplehash_to_ctrack(h);
if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
- struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
-
+ spin_lock_bh(&nf_conntrack_lock);
err = ctnetlink_change_conntrack(ct, cda);
+ spin_unlock_bh(&nf_conntrack_lock);
if (err == 0) {
- nf_conntrack_get(&ct->ct_general);
- spin_unlock_bh(&nf_conntrack_lock);
nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
(1 << IPCT_ASSURED) |
(1 << IPCT_HELPER) |
@@ -1570,15 +1561,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
(1 << IPCT_MARK),
ct, NETLINK_CB(skb).pid,
nlmsg_report(nlh));
- nf_ct_put(ct);
- } else
- spin_unlock_bh(&nf_conntrack_lock);
-
- return err;
+ }
}
-out_unlock:
- spin_unlock_bh(&nf_conntrack_lock);
+ nf_ct_put(ct);
return err;
}
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index b3a7db6..ce60cf0 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -203,6 +203,27 @@ err:
return status;
}
+#ifdef CONFIG_BRIDGE_NETFILTER
+/* When called from bridge netfilter, skb->data must point to MAC header
+ * before calling skb_gso_segment(). Else, original MAC header is lost
+ * and segmented skbs will be sent to wrong destination.
+ */
+static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
+{
+ if (skb->nf_bridge)
+ __skb_push(skb, skb->network_header - skb->mac_header);
+}
+
+static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
+{
+ if (skb->nf_bridge)
+ __skb_pull(skb, skb->network_header - skb->mac_header);
+}
+#else
+#define nf_bridge_adjust_skb_data(s) do {} while (0)
+#define nf_bridge_adjust_segmented_data(s) do {} while (0)
+#endif
+
int nf_queue(struct sk_buff *skb,
struct list_head *elem,
u_int8_t pf, unsigned int hook,
@@ -212,7 +233,7 @@ int nf_queue(struct sk_buff *skb,
unsigned int queuenum)
{
struct sk_buff *segs;
- int err;
+ int err = -EINVAL;
unsigned int queued;
if (!skb_is_gso(skb))
@@ -228,23 +249,25 @@ int nf_queue(struct sk_buff *skb,
break;
}
+ nf_bridge_adjust_skb_data(skb);
segs = skb_gso_segment(skb, 0);
/* Does not use PTR_ERR to limit the number of error codes that can be
* returned by nf_queue. For instance, callers rely on -ECANCELED to mean
* 'ignore this hook'.
*/
if (IS_ERR(segs))
- return -EINVAL;
-
+ goto out_err;
queued = 0;
err = 0;
do {
struct sk_buff *nskb = segs->next;
segs->next = NULL;
- if (err == 0)
+ if (err == 0) {
+ nf_bridge_adjust_segmented_data(segs);
err = __nf_queue(segs, elem, pf, hook, indev,
outdev, okfn, queuenum);
+ }
if (err == 0)
queued++;
else
@@ -252,11 +275,12 @@ int nf_queue(struct sk_buff *skb,
segs = nskb;
} while (segs);
- /* also free orig skb if only some segments were queued */
- if (unlikely(err && queued))
- err = 0;
- if (err == 0)
+ if (queued) {
kfree_skb(skb);
+ return 0;
+ }
+ out_err:
+ nf_bridge_adjust_segmented_data(skb);
return err;
}
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 3aae66f..4d50579 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -152,9 +152,10 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
(iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
dst = ip6_route_output(net, NULL, &fl6);
- if (dst == NULL)
+ if (dst->error) {
+ dst_release(dst);
return false;
-
+ }
skb_dst_drop(skb);
skb_dst_set(skb, dst);
skb->dev = dst->dev;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index e83d61c..5da548f 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -501,9 +501,8 @@ tfifo_dequeue:
/* if more time remaining? */
if (cb->time_to_send <= psched_get_time()) {
- skb = qdisc_dequeue_tail(sch);
- if (unlikely(!skb))
- goto qdisc_dequeue;
+ __skb_unlink(skb, &sch->q);
+ sch->qstats.backlog -= qdisc_pkt_len(skb);
#ifdef CONFIG_NET_CLS_ACT
/*
@@ -539,7 +538,6 @@ deliver:
qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
}
-qdisc_dequeue:
if (q->qdisc) {
skb = q->qdisc->ops->dequeue(q->qdisc);
if (skb)