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

Pull networking fixes from David Miller:

 1) Don't halt the firmware in r8152 driver, from Hayes Wang.

 2) Handle full sized 802.1ad frames in bnx2 and tg3 drivers properly,
    from Vlad Yasevich.

 3) Don't sleep while holding tx_clean_lock in netxen driver, fix from
    Manish Chopra.

 4) Certain kinds of ipv6 routes can end up endlessly failing the route
    validation test, causing it to be re-looked up over and over again.
    This particularly kills input route caching in TCP sockets.  Fix
    from Hannes Frederic Sowa.

 5) netvsc_start_xmit() has a use-after-free access to skb->len, fix
    from K Y Srinivasan.

 6) Fix matching of inverted containers in ematch module, from Ignacy
    Gawędzki.

 7) Aggregation of GRO frames via SKB ->frag_list for linear skbs isn't
    handled properly, regression fix from Eric Dumazet.

 8) Don't test return value of ipv4_neigh_lookup(), which returns an
    error pointer, against NULL.  From WANG Cong.

 9) Fix an old regression where we mistakenly allow a double add of the
    same tunnel.  Fixes from Steffen Klassert.

10) macvtap device delete and open can run in parallel and corrupt lists
    etc., fix from Vlad Yasevich.

11) Fix build error with IPV6=m NETFILTER_XT_TARGET_TPROXY=y, from Pablo
    Neira Ayuso.

12) rhashtable_destroy() triggers lockdep splats, fix also from Pablo.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (32 commits)
  bna: Update Maintainer Email
  r8152: disable power cut for RTL8153
  r8152: remove clearing bp
  bnx2: Correctly receive full sized 802.1ad fragmes
  tg3: Allow for recieve of full-size 8021AD frames
  r8152: fix setting RTL8152_UNPLUG
  netxen: Fix bug in Tx completion path.
  netxen: Fix BUG "sleeping function called from invalid context"
  ipv6: remove rt6i_genid
  hyperv: Fix a bug in netvsc_start_xmit()
  net: stmmac: fix stmmac_pci_probe failed when CONFIG_HAVE_CLK is selected
  ematch: Fix matching of inverted containers.
  gro: fix aggregation for skb using frag_list
  neigh: check error pointer instead of NULL for ipv4_neigh_lookup()
  ip6_gre: Return an error when adding an existing tunnel.
  ip6_vti: Return an error when adding an existing tunnel.
  ip6_tunnel: Return an error when adding an existing tunnel.
  ip6gre: add a rtnl link alias for ip6gretap
  net/mlx4_core: Allow not to specify probe_vf in SRIOV IB mode
  r8152: fix the carrier off when autoresuming
  ...
This commit is contained in:
Linus Torvalds 2014-10-01 21:29:06 -07:00
commit 50dddff3cb
31 changed files with 217 additions and 134 deletions

View File

@ -2098,7 +2098,7 @@ S: Supported
F: drivers/scsi/bfa/
BROCADE BNA 10 GIGABIT ETHERNET DRIVER
M: Rasesh Mody <rmody@brocade.com>
M: Rasesh Mody <rasesh.mody@qlogic.com>
L: netdev@vger.kernel.org
S: Supported
F: drivers/net/ethernet/brocade/bna/

View File

@ -3236,8 +3236,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
skb->protocol = eth_type_trans(skb, bp->dev);
if ((len > (bp->dev->mtu + ETH_HLEN)) &&
(ntohs(skb->protocol) != 0x8100)) {
if (len > (bp->dev->mtu + ETH_HLEN) &&
skb->protocol != htons(0x8100) &&
skb->protocol != htons(ETH_P_8021AD)) {
dev_kfree_skb(skb);
goto next_rx;

View File

@ -6918,7 +6918,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
skb->protocol = eth_type_trans(skb, tp->dev);
if (len > (tp->dev->mtu + ETH_HLEN) &&
skb->protocol != htons(ETH_P_8021Q)) {
skb->protocol != htons(ETH_P_8021Q) &&
skb->protocol != htons(ETH_P_8021AD)) {
dev_kfree_skb_any(skb);
goto drop_it_no_recycle;
}

View File

@ -30,7 +30,6 @@
#include <linux/of_device.h>
#include <linux/of_mdio.h>
#include <linux/of_net.h>
#include <linux/pinctrl/consumer.h>
#include "macb.h"
@ -2071,7 +2070,6 @@ static int __init macb_probe(struct platform_device *pdev)
struct phy_device *phydev;
u32 config;
int err = -ENXIO;
struct pinctrl *pinctrl;
const char *mac;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -2080,15 +2078,6 @@ static int __init macb_probe(struct platform_device *pdev)
goto err_out;
}
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
err = PTR_ERR(pinctrl);
if (err == -EPROBE_DEFER)
goto err_out;
dev_warn(&pdev->dev, "No pinctrl provided\n");
}
err = -ENOMEM;
dev = alloc_etherdev(sizeof(*bp));
if (!dev)

View File

@ -78,13 +78,13 @@ MODULE_PARM_DESC(msi_x, "attempt to use MSI-X if nonzero");
#endif /* CONFIG_PCI_MSI */
static uint8_t num_vfs[3] = {0, 0, 0};
static int num_vfs_argc = 3;
static int num_vfs_argc;
module_param_array(num_vfs, byte , &num_vfs_argc, 0444);
MODULE_PARM_DESC(num_vfs, "enable #num_vfs functions if num_vfs > 0\n"
"num_vfs=port1,port2,port1+2");
static uint8_t probe_vf[3] = {0, 0, 0};
static int probe_vfs_argc = 3;
static int probe_vfs_argc;
module_param_array(probe_vf, byte, &probe_vfs_argc, 0444);
MODULE_PARM_DESC(probe_vf, "number of vfs to probe by pf driver (num_vfs > 0)\n"
"probe_vf=port1,port2,port1+2");

View File

@ -135,6 +135,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
int i, j;
struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
spin_lock(&adapter->tx_clean_lock);
cmd_buf = tx_ring->cmd_buf_arr;
for (i = 0; i < tx_ring->num_desc; i++) {
buffrag = cmd_buf->frag_array;
@ -158,6 +159,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
}
cmd_buf++;
}
spin_unlock(&adapter->tx_clean_lock);
}
void netxen_free_sw_resources(struct netxen_adapter *adapter)
@ -1792,9 +1794,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
break;
}
if (count && netif_running(netdev)) {
tx_ring->sw_consumer = sw_consumer;
tx_ring->sw_consumer = sw_consumer;
if (count && netif_running(netdev)) {
smp_mb();
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev))

View File

@ -1186,7 +1186,6 @@ __netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
return;
smp_mb();
spin_lock(&adapter->tx_clean_lock);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@ -1204,7 +1203,6 @@ __netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
netxen_napi_disable(adapter);
netxen_release_tx_buffers(adapter);
spin_unlock(&adapter->tx_clean_lock);
}
/* Usage: During suspend and firmware recovery module */

View File

@ -1177,9 +1177,8 @@ static void qlcnic_83xx_setup_idc_parameters(struct qlcnic_adapter *adapter)
{
u32 idc_params, val;
if (qlcnic_83xx_lockless_flash_read32(adapter,
QLC_83XX_IDC_FLASH_PARAM_ADDR,
(u8 *)&idc_params, 1)) {
if (qlcnic_83xx_flash_read32(adapter, QLC_83XX_IDC_FLASH_PARAM_ADDR,
(u8 *)&idc_params, 1)) {
dev_info(&adapter->pdev->dev,
"%s:failed to get IDC params from flash\n", __func__);
adapter->dev_init_timeo = QLC_83XX_IDC_INIT_TIMEOUT_SECS;

View File

@ -1333,21 +1333,21 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev,
struct qlcnic_host_tx_ring *tx_ring;
struct qlcnic_esw_statistics port_stats;
struct qlcnic_mac_statistics mac_stats;
int index, ret, length, size, tx_size, ring;
int index, ret, length, size, ring;
char *p;
tx_size = adapter->drv_tx_rings * QLCNIC_TX_STATS_LEN;
memset(data, 0, stats->n_stats * sizeof(u64));
memset(data, 0, tx_size * sizeof(u64));
for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
if (adapter->is_up == QLCNIC_ADAPTER_UP_MAGIC) {
tx_ring = &adapter->tx_ring[ring];
data = qlcnic_fill_tx_queue_stats(data, tx_ring);
qlcnic_update_stats(adapter);
} else {
data += QLCNIC_TX_STATS_LEN;
}
}
memset(data, 0, stats->n_stats * sizeof(u64));
length = QLCNIC_STATS_LEN;
for (index = 0; index < length; index++) {
p = (char *)adapter + qlcnic_gstrings_stats[index].stat_offset;

View File

@ -2786,8 +2786,15 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device,
if (IS_ERR(priv->stmmac_clk)) {
dev_warn(priv->device, "%s: warning: cannot get CSR clock\n",
__func__);
ret = PTR_ERR(priv->stmmac_clk);
goto error_clk_get;
/* If failed to obtain stmmac_clk and specific clk_csr value
* is NOT passed from the platform, probe fail.
*/
if (!priv->plat->clk_csr) {
ret = PTR_ERR(priv->stmmac_clk);
goto error_clk_get;
} else {
priv->stmmac_clk = NULL;
}
}
clk_prepare_enable(priv->stmmac_clk);

View File

@ -387,6 +387,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
int hdr_offset;
u32 net_trans_info;
u32 hash;
u32 skb_length = skb->len;
/* We will atmost need two pages to describe the rndis
@ -562,7 +563,7 @@ do_send:
drop:
if (ret == 0) {
net->stats.tx_bytes += skb->len;
net->stats.tx_bytes += skb_length;
net->stats.tx_packets++;
} else {
kfree(packet);

View File

@ -112,17 +112,15 @@ out:
return err;
}
/* Requires RTNL */
static int macvtap_set_queue(struct net_device *dev, struct file *file,
struct macvtap_queue *q)
{
struct macvlan_dev *vlan = netdev_priv(dev);
int err = -EBUSY;
rtnl_lock();
if (vlan->numqueues == MAX_MACVTAP_QUEUES)
goto out;
return -EBUSY;
err = 0;
rcu_assign_pointer(q->vlan, vlan);
rcu_assign_pointer(vlan->taps[vlan->numvtaps], q);
sock_hold(&q->sk);
@ -136,9 +134,7 @@ static int macvtap_set_queue(struct net_device *dev, struct file *file,
vlan->numvtaps++;
vlan->numqueues++;
out:
rtnl_unlock();
return err;
return 0;
}
static int macvtap_disable_queue(struct macvtap_queue *q)
@ -454,11 +450,12 @@ static void macvtap_sock_destruct(struct sock *sk)
static int macvtap_open(struct inode *inode, struct file *file)
{
struct net *net = current->nsproxy->net_ns;
struct net_device *dev = dev_get_by_macvtap_minor(iminor(inode));
struct net_device *dev;
struct macvtap_queue *q;
int err;
int err = -ENODEV;
err = -ENODEV;
rtnl_lock();
dev = dev_get_by_macvtap_minor(iminor(inode));
if (!dev)
goto out;
@ -498,6 +495,7 @@ out:
if (dev)
dev_put(dev);
rtnl_unlock();
return err;
}

View File

@ -24,7 +24,7 @@
#include <net/ip6_checksum.h>
/* Version Information */
#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
#define DRIVER_VERSION "v1.06.1 (2014/10/01)"
#define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
#define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
#define MODULENAME "r8152"
@ -1949,10 +1949,34 @@ static void rxdy_gated_en(struct r8152 *tp, bool enable)
ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
}
static int rtl_start_rx(struct r8152 *tp)
{
int i, ret = 0;
INIT_LIST_HEAD(&tp->rx_done);
for (i = 0; i < RTL8152_MAX_RX; i++) {
INIT_LIST_HEAD(&tp->rx_info[i].list);
ret = r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL);
if (ret)
break;
}
return ret;
}
static int rtl_stop_rx(struct r8152 *tp)
{
int i;
for (i = 0; i < RTL8152_MAX_RX; i++)
usb_kill_urb(tp->rx_info[i].urb);
return 0;
}
static int rtl_enable(struct r8152 *tp)
{
u32 ocp_data;
int i, ret;
r8152b_reset_packet_filter(tp);
@ -1962,14 +1986,7 @@ static int rtl_enable(struct r8152 *tp)
rxdy_gated_en(tp, false);
INIT_LIST_HEAD(&tp->rx_done);
ret = 0;
for (i = 0; i < RTL8152_MAX_RX; i++) {
INIT_LIST_HEAD(&tp->rx_info[i].list);
ret |= r8152_submit_rx(tp, &tp->rx_info[i], GFP_KERNEL);
}
return ret;
return rtl_start_rx(tp);
}
static int rtl8152_enable(struct r8152 *tp)
@ -2053,8 +2070,7 @@ static void rtl_disable(struct r8152 *tp)
mdelay(1);
}
for (i = 0; i < RTL8152_MAX_RX; i++)
usb_kill_urb(tp->rx_info[i].urb);
rtl_stop_rx(tp);
rtl8152_nic_reset(tp);
}
@ -2185,28 +2201,6 @@ static void rtl_phy_reset(struct r8152 *tp)
}
}
static void rtl_clear_bp(struct r8152 *tp)
{
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
mdelay(3);
ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
}
static void r8153_clear_bp(struct r8152 *tp)
{
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
rtl_clear_bp(tp);
}
static void r8153_teredo_off(struct r8152 *tp)
{
u32 ocp_data;
@ -2249,8 +2243,6 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
r8152_mdio_write(tp, MII_BMCR, data);
}
rtl_clear_bp(tp);
set_bit(PHY_RESET, &tp->flags);
}
@ -2401,8 +2393,6 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
r8152_mdio_write(tp, MII_BMCR, data);
}
r8153_clear_bp(tp);
if (tp->version == RTL_VER_03) {
data = ocp_reg_read(tp, OCP_EEE_CFG);
data &= ~CTAP_SHORT_EN;
@ -3083,13 +3073,14 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
tasklet_disable(&tp->tl);
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
rtl_stop_rx(tp);
rtl_runtime_suspend_enable(tp, true);
} else {
tasklet_disable(&tp->tl);
tp->rtl_ops.down(tp);
tasklet_enable(&tp->tl);
}
tasklet_enable(&tp->tl);
}
return 0;
@ -3108,17 +3099,18 @@ static int rtl8152_resume(struct usb_interface *intf)
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
rtl_runtime_suspend_enable(tp, false);
clear_bit(SELECTIVE_SUSPEND, &tp->flags);
set_bit(WORK_ENABLE, &tp->flags);
if (tp->speed & LINK_STATUS)
tp->rtl_ops.disable(tp);
rtl_start_rx(tp);
} else {
tp->rtl_ops.up(tp);
rtl8152_set_speed(tp, AUTONEG_ENABLE,
tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
DUPLEX_FULL);
tp->speed = 0;
netif_carrier_off(tp->netdev);
set_bit(WORK_ENABLE, &tp->flags);
}
tp->speed = 0;
netif_carrier_off(tp->netdev);
set_bit(WORK_ENABLE, &tp->flags);
usb_submit_urb(tp->intr_urb, GFP_KERNEL);
}
@ -3405,7 +3397,7 @@ static void rtl8153_unload(struct r8152 *tp)
if (test_bit(RTL8152_UNPLUG, &tp->flags))
return;
r8153_power_cut_en(tp, true);
r8153_power_cut_en(tp, false);
}
static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
@ -3558,7 +3550,11 @@ static void rtl8152_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
if (tp) {
set_bit(RTL8152_UNPLUG, &tp->flags);
struct usb_device *udev = tp->udev;
if (udev->state == USB_STATE_NOTATTACHED)
set_bit(RTL8152_UNPLUG, &tp->flags);
tasklet_kill(&tp->tl);
unregister_netdev(tp->netdev);
tp->rtl_ops.unload(tp);

View File

@ -114,16 +114,13 @@ struct rt6_info {
u32 rt6i_flags;
struct rt6key rt6i_src;
struct rt6key rt6i_prefsrc;
u32 rt6i_metric;
struct inet6_dev *rt6i_idev;
unsigned long _rt6i_peer;
u32 rt6i_genid;
u32 rt6i_metric;
/* more non-fragment space at head required */
unsigned short rt6i_nfheader_len;
u8 rt6i_protocol;
};

View File

@ -352,26 +352,12 @@ static inline void rt_genid_bump_ipv4(struct net *net)
atomic_inc(&net->ipv4.rt_genid);
}
#if IS_ENABLED(CONFIG_IPV6)
static inline int rt_genid_ipv6(struct net *net)
{
return atomic_read(&net->ipv6.rt_genid);
}
extern void (*__fib6_flush_trees)(struct net *net);
static inline void rt_genid_bump_ipv6(struct net *net)
{
atomic_inc(&net->ipv6.rt_genid);
if (__fib6_flush_trees)
__fib6_flush_trees(net);
}
#else
static inline int rt_genid_ipv6(struct net *net)
{
return 0;
}
static inline void rt_genid_bump_ipv6(struct net *net)
{
}
#endif
#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
static inline struct netns_ieee802154_lowpan *

View File

@ -588,13 +588,13 @@ EXPORT_SYMBOL_GPL(rhashtable_init);
* rhashtable_destroy - destroy hash table
* @ht: the hash table to destroy
*
* Frees the bucket array.
* Frees the bucket array. This function is not rcu safe, therefore the caller
* has to make sure that no resizing may happen by unpublishing the hashtable
* and waiting for the quiescent cycle before releasing the bucket array.
*/
void rhashtable_destroy(const struct rhashtable *ht)
{
const struct bucket_table *tbl = rht_dereference(ht->tbl, ht);
bucket_table_free(tbl);
bucket_table_free(ht->tbl);
}
EXPORT_SYMBOL_GPL(rhashtable_destroy);

View File

@ -3152,6 +3152,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD;
goto done;
}
/* switch back to head shinfo */
pinfo = skb_shinfo(p);
if (pinfo->frag_list)
goto merge;
if (skb_gro_len(p) != pinfo->gso_size)

View File

@ -764,9 +764,14 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
if (!t && (cmd == SIOCADDTUNNEL)) {
t = ip_tunnel_create(net, itn, p);
err = PTR_ERR_OR_ZERO(t);
if (cmd == SIOCADDTUNNEL) {
if (!t) {
t = ip_tunnel_create(net, itn, p);
err = PTR_ERR_OR_ZERO(t);
break;
}
err = -EEXIST;
break;
}
if (dev != itn->fb_tunnel_dev && cmd == SIOCCHGTUNNEL) {

View File

@ -746,7 +746,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
}
n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw);
if (n) {
if (!IS_ERR(n)) {
if (!(n->nud_state & NUD_VALID)) {
neigh_event_send(n, NULL);
} else {

View File

@ -4780,10 +4780,11 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
if (ip6_del_rt(ifp->rt))
dst_free(&ifp->rt->dst);
rt_genid_bump_ipv6(net);
break;
}
atomic_inc(&net->ipv6.dev_addr_genid);
rt_genid_bump_ipv6(net);
}
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)

View File

@ -8,6 +8,13 @@
#include <net/addrconf.h>
#include <net/ip.h>
/* if ipv6 module registers this function is used by xfrm to force all
* sockets to relookup their nodes - this is fairly expensive, be
* careful
*/
void (*__fib6_flush_trees)(struct net *);
EXPORT_SYMBOL(__fib6_flush_trees);
#define IPV6_ADDR_SCOPE_TYPE(scope) ((scope) << 16)
static inline unsigned int ipv6_addr_scope2type(unsigned int scope)

View File

@ -1605,6 +1605,24 @@ static void fib6_prune_clones(struct net *net, struct fib6_node *fn)
fib6_clean_tree(net, fn, fib6_prune_clone, 1, NULL);
}
static int fib6_update_sernum(struct rt6_info *rt, void *arg)
{
__u32 sernum = *(__u32 *)arg;
if (rt->rt6i_node &&
rt->rt6i_node->fn_sernum != sernum)
rt->rt6i_node->fn_sernum = sernum;
return 0;
}
static void fib6_flush_trees(struct net *net)
{
__u32 new_sernum = fib6_new_sernum();
fib6_clean_all(net, fib6_update_sernum, &new_sernum);
}
/*
* Garbage collection
*/
@ -1788,6 +1806,8 @@ int __init fib6_init(void)
NULL);
if (ret)
goto out_unregister_subsys;
__fib6_flush_trees = fib6_flush_trees;
out:
return ret;

View File

@ -314,6 +314,8 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
t = ip6gre_tunnel_find(net, parms, ARPHRD_IP6GRE);
if (t && create)
return NULL;
if (t || !create)
return t;
@ -1724,4 +1726,5 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)");
MODULE_DESCRIPTION("GRE over IPv6 tunneling device");
MODULE_ALIAS_RTNL_LINK("ip6gre");
MODULE_ALIAS_RTNL_LINK("ip6gretap");
MODULE_ALIAS_NETDEV("ip6gre0");

View File

@ -364,8 +364,12 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net,
(t = rtnl_dereference(*tp)) != NULL;
tp = &t->next) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
ipv6_addr_equal(remote, &t->parms.raddr))
ipv6_addr_equal(remote, &t->parms.raddr)) {
if (create)
return NULL;
return t;
}
}
if (!create)
return NULL;

View File

@ -253,8 +253,12 @@ static struct ip6_tnl *vti6_locate(struct net *net, struct __ip6_tnl_parm *p,
(t = rtnl_dereference(*tp)) != NULL;
tp = &t->next) {
if (ipv6_addr_equal(local, &t->parms.laddr) &&
ipv6_addr_equal(remote, &t->parms.raddr))
ipv6_addr_equal(remote, &t->parms.raddr)) {
if (create)
return NULL;
return t;
}
}
if (!create)
return NULL;

View File

@ -314,7 +314,6 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
rt->rt6i_genid = rt_genid_ipv6(net);
INIT_LIST_HEAD(&rt->rt6i_siblings);
}
return rt;
@ -1098,9 +1097,6 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
* DST_OBSOLETE_FORCE_CHK which forces validation calls down
* into this function always.
*/
if (rt->rt6i_genid != rt_genid_ipv6(dev_net(rt->dst.dev)))
return NULL;
if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie))
return NULL;

View File

@ -847,6 +847,7 @@ config NETFILTER_XT_TARGET_TPROXY
tristate '"TPROXY" target transparent proxying support'
depends on NETFILTER_XTABLES
depends on NETFILTER_ADVANCED
depends on (IPV6 || IPV6=n)
depends on IP_NF_MANGLE
select NF_DEFRAG_IPV4
select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES

View File

@ -222,6 +222,51 @@ replay:
}
}
struct nfnl_err {
struct list_head head;
struct nlmsghdr *nlh;
int err;
};
static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err)
{
struct nfnl_err *nfnl_err;
nfnl_err = kmalloc(sizeof(struct nfnl_err), GFP_KERNEL);
if (nfnl_err == NULL)
return -ENOMEM;
nfnl_err->nlh = nlh;
nfnl_err->err = err;
list_add_tail(&nfnl_err->head, list);
return 0;
}
static void nfnl_err_del(struct nfnl_err *nfnl_err)
{
list_del(&nfnl_err->head);
kfree(nfnl_err);
}
static void nfnl_err_reset(struct list_head *err_list)
{
struct nfnl_err *nfnl_err, *next;
list_for_each_entry_safe(nfnl_err, next, err_list, head)
nfnl_err_del(nfnl_err);
}
static void nfnl_err_deliver(struct list_head *err_list, struct sk_buff *skb)
{
struct nfnl_err *nfnl_err, *next;
list_for_each_entry_safe(nfnl_err, next, err_list, head) {
netlink_ack(skb, nfnl_err->nlh, nfnl_err->err);
nfnl_err_del(nfnl_err);
}
}
static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
u_int16_t subsys_id)
{
@ -230,6 +275,7 @@ static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
const struct nfnetlink_subsystem *ss;
const struct nfnl_callback *nc;
bool success = true, done = false;
static LIST_HEAD(err_list);
int err;
if (subsys_id >= NFNL_SUBSYS_COUNT)
@ -287,6 +333,7 @@ replay:
type = nlh->nlmsg_type;
if (type == NFNL_MSG_BATCH_BEGIN) {
/* Malformed: Batch begin twice */
nfnl_err_reset(&err_list);
success = false;
goto done;
} else if (type == NFNL_MSG_BATCH_END) {
@ -333,6 +380,7 @@ replay:
* original skb.
*/
if (err == -EAGAIN) {
nfnl_err_reset(&err_list);
ss->abort(skb);
nfnl_unlock(subsys_id);
kfree_skb(nskb);
@ -341,11 +389,24 @@ replay:
}
ack:
if (nlh->nlmsg_flags & NLM_F_ACK || err) {
/* Errors are delivered once the full batch has been
* processed, this avoids that the same error is
* reported several times when replaying the batch.
*/
if (nfnl_err_add(&err_list, nlh, err) < 0) {
/* We failed to enqueue an error, reset the
* list of errors and send OOM to userspace
* pointing to the batch header.
*/
nfnl_err_reset(&err_list);
netlink_ack(skb, nlmsg_hdr(oskb), -ENOMEM);
success = false;
goto done;
}
/* We don't stop processing the batch on errors, thus,
* userspace gets all the errors that the batch
* triggers.
*/
netlink_ack(skb, nlh, err);
if (err)
success = false;
}
@ -361,6 +422,7 @@ done:
else
ss->abort(skb);
nfnl_err_deliver(&err_list, oskb);
nfnl_unlock(subsys_id);
kfree_skb(nskb);
}

View File

@ -180,15 +180,17 @@ static int nft_hash_init(const struct nft_set *set,
static void nft_hash_destroy(const struct nft_set *set)
{
const struct rhashtable *priv = nft_set_priv(set);
const struct bucket_table *tbl;
const struct bucket_table *tbl = priv->tbl;
struct nft_hash_elem *he, *next;
unsigned int i;
tbl = rht_dereference(priv->tbl, priv);
for (i = 0; i < tbl->size; i++)
rht_for_each_entry_safe(he, next, tbl->buckets[i], priv, node)
for (i = 0; i < tbl->size; i++) {
for (he = rht_entry(tbl->buckets[i], struct nft_hash_elem, node);
he != NULL; he = next) {
next = rht_entry(he->node.next, struct nft_hash_elem, node);
nft_hash_elem_destroy(set, he);
}
}
rhashtable_destroy(priv);
}

View File

@ -234,13 +234,11 @@ static void nft_rbtree_destroy(const struct nft_set *set)
struct nft_rbtree_elem *rbe;
struct rb_node *node;
spin_lock_bh(&nft_rbtree_lock);
while ((node = priv->root.rb_node) != NULL) {
rb_erase(node, &priv->root);
rbe = rb_entry(node, struct nft_rbtree_elem, node);
nft_rbtree_elem_destroy(set, rbe);
}
spin_unlock_bh(&nft_rbtree_lock);
}
static bool nft_rbtree_estimate(const struct nft_set_desc *desc, u32 features,

View File

@ -526,9 +526,11 @@ pop_stack:
match_idx = stack[--stackp];
cur_match = tcf_em_get_match(tree, match_idx);
if (tcf_em_early_end(cur_match, res))
if (tcf_em_early_end(cur_match, res)) {
if (tcf_em_is_inverted(cur_match))
res = !res;
goto pop_stack;
else {
} else {
match_idx++;
goto proceed;
}