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

Pull networking fixes from David Miller:

 1) nft_compat accidently truncates ethernet protocol to 8-bits, from
    Arturo Borrero.

 2) Memory leak in ip_vs_proc_conn(), from Julian Anastasov.

 3) Don't allow the space required for nftables rules to exceed the
    maximum value representable in the dlen field.  From Patrick
    McHardy.

 4) bcm63xx_enet can accidently leave interrupts permanently disabled
    due to errors in the NAPI polling exit logic.  Fix from Nicolas
    Schichan.

 5) Fix OOPSes triggerable by the ping protocol module, due to missing
    address family validations etc.  From Lorenzo Colitti.

 6) Don't use RCU locking in sleepable context in team driver, from Jiri
    Pirko.

 7) xen-netback miscalculates statistic offset pointers when reporting
    the stats to userspace.  From David Vrabel.

 8) Fix a leak of up to 256 pages per VIF destroy in xen-netaback, also
    from David Vrabel.

 9) ip_check_defrag() cannot assume that skb_network_offset(),
    particularly when it is used by the AF_PACKET fanout defrag code.
    From Alexander Drozdov.

10) gianfar driver doesn't query OF node names properly when trying to
    determine the number of hw queues available.  Fix it to explicitly
    check for OF nodes named queue-group.  From Tobias Waldekranz.

11) MID field in macb driver should be 12 bits, not 16.  From Punnaiah
    Choudary Kalluri.

12) Fix unintentional regression in traceroute due to timestamp socket
    option changes.  Empty ICMP payloads should be allowed in
    non-timestamp cases.  From Willem de Bruijn.

13) When devices are unregistered, we have to get rid of AF_PACKET
    multicast list entries that point to it via ifindex.  Fix from
    Francesco Ruggeri.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (38 commits)
  tipc: fix bug in link failover handling
  net: delete stale packet_mclist entries
  net: macb: constify macb configuration data
  MAINTAINERS: add Marc Kleine-Budde as co maintainer for CAN networking layer
  MAINTAINERS: linux-can moved to github
  can: kvaser_usb: Read all messages in a bulk-in URB buffer
  can: kvaser_usb: Avoid double free on URB submission failures
  can: peak_usb: fix missing ctrlmode_ init for every dev
  can: add missing initialisations in CAN related skbuffs
  ip: fix error queue empty skb handling
  bgmac: Clean warning messages
  tcp: align tcp_xmit_size_goal() on tcp_tso_autosize()
  net: fec: fix unbalanced clk disable on driver unbind
  net: macb: Correct the MID field length value
  net: gianfar: correctly determine the number of queue groups
  ipv4: ip_check_defrag should not assume that skb_network_offset is zero
  net: bcmgenet: properly disable password matching
  net: eth: xgene: fix booting with devicetree
  bnx2x: Force fundamental reset for EEH recovery
  xen-netback: refactor xenvif_handle_frag_list()
  ...
This commit is contained in:
Linus Torvalds 2015-03-09 18:17:21 -07:00
commit 36bef88380
39 changed files with 311 additions and 177 deletions

View File

@ -4,7 +4,10 @@ Ethernet nodes are defined to describe on-chip ethernet interfaces in
APM X-Gene SoC.
Required properties for all the ethernet interfaces:
- compatible: Should be "apm,xgene-enet"
- compatible: Should state binding information from the following list,
- "apm,xgene-enet": RGMII based 1G interface
- "apm,xgene1-sgenet": SGMII based 1G interface
- "apm,xgene1-xgenet": XFI based 10G interface
- reg: Address and length of the register set for the device. It contains the
information of registers in the same order as described by reg-names
- reg-names: Should contain the register set names

View File

@ -2369,8 +2369,9 @@ F: arch/x86/include/asm/tce.h
CAN NETWORK LAYER
M: Oliver Hartkopp <socketcan@hartkopp.net>
M: Marc Kleine-Budde <mkl@pengutronix.de>
L: linux-can@vger.kernel.org
W: http://gitorious.org/linux-can
W: https://github.com/linux-can
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
S: Maintained
@ -2386,7 +2387,7 @@ CAN NETWORK DRIVERS
M: Wolfgang Grandegger <wg@grandegger.com>
M: Marc Kleine-Budde <mkl@pengutronix.de>
L: linux-can@vger.kernel.org
W: http://gitorious.org/linux-can
W: https://github.com/linux-can
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git
S: Maintained

View File

@ -36,6 +36,7 @@
#include <linux/platform_data/video-pxafb.h>
#include <mach/bitfield.h>
#include <linux/platform_data/mmc-pxamci.h>
#include <linux/smc91x.h>
#include "generic.h"
#include "devices.h"

View File

@ -195,7 +195,7 @@ static struct resource smc91x_resources[] = {
};
struct smc91x_platdata smc91x_platdata = {
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT;
.flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
static struct platform_device smc91x_device = {

View File

@ -268,8 +268,8 @@ static int neponset_probe(struct platform_device *dev)
.id = 0,
.res = smc91x_resources,
.num_res = ARRAY_SIZE(smc91x_resources),
.data = &smc91c_platdata,
.size_data = sizeof(smc91c_platdata),
.data = &smc91x_platdata,
.size_data = sizeof(smc91x_platdata),
};
int ret, irq;

View File

@ -54,7 +54,7 @@ static struct platform_device smc91x_device = {
.num_resources = ARRAY_SIZE(smc91x_resources),
.resource = smc91x_resources,
.dev = {
.platform_data = &smc91c_platdata,
.platform_data = &smc91x_platdata,
},
};

View File

@ -622,7 +622,7 @@
};
sgenet0: ethernet@1f210000 {
compatible = "apm,xgene-enet";
compatible = "apm,xgene1-sgenet";
status = "disabled";
reg = <0x0 0x1f210000 0x0 0xd100>,
<0x0 0x1f200000 0x0 0Xc300>,
@ -636,7 +636,7 @@
};
xgenet: ethernet@1f610000 {
compatible = "apm,xgene-enet";
compatible = "apm,xgene1-xgenet";
status = "disabled";
reg = <0x0 0x1f610000 0x0 0xd100>,
<0x0 0x1f600000 0x0 0Xc300>,

View File

@ -579,6 +579,10 @@ struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
@ -603,6 +607,10 @@ struct sk_buff *alloc_canfd_skb(struct net_device *dev,
skb->pkt_type = PACKET_BROADCAST;
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;

View File

@ -14,6 +14,7 @@
* Copyright (C) 2015 Valeo S.A.
*/
#include <linux/kernel.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@ -584,8 +585,15 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
while (pos <= actual_len - MSG_HEADER_LEN) {
tmp = buf + pos;
if (!tmp->len)
break;
/* Handle messages crossing the USB endpoint max packet
* size boundary. Check kvaser_usb_read_bulk_callback()
* for further details.
*/
if (tmp->len == 0) {
pos = round_up(pos,
dev->bulk_in->wMaxPacketSize);
continue;
}
if (pos + tmp->len > actual_len) {
dev_err(dev->udev->dev.parent,
@ -787,7 +795,6 @@ static int kvaser_usb_simple_msg_async(struct kvaser_usb_net_priv *priv,
netdev_err(netdev, "Error transmitting URB\n");
usb_unanchor_urb(urb);
usb_free_urb(urb);
kfree(buf);
return err;
}
@ -1317,8 +1324,19 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
while (pos <= urb->actual_length - MSG_HEADER_LEN) {
msg = urb->transfer_buffer + pos;
if (!msg->len)
break;
/* The Kvaser firmware can only read and write messages that
* does not cross the USB's endpoint wMaxPacketSize boundary.
* If a follow-up command crosses such boundary, firmware puts
* a placeholder zero-length command in its place then aligns
* the real command to the next max packet size.
*
* Handle such cases or we're going to miss a significant
* number of events in case of a heavy rx load on the bus.
*/
if (msg->len == 0) {
pos = round_up(pos, dev->bulk_in->wMaxPacketSize);
continue;
}
if (pos + msg->len > urb->actual_length) {
dev_err(dev->udev->dev.parent, "Format error\n");
@ -1326,7 +1344,6 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb)
}
kvaser_usb_handle_message(dev, msg);
pos += msg->len;
}
@ -1615,8 +1632,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
struct urb *urb;
void *buf;
struct kvaser_msg *msg;
int i, err;
int ret = NETDEV_TX_OK;
int i, err, ret = NETDEV_TX_OK;
u8 *msg_tx_can_flags = NULL; /* GCC */
if (can_dropped_invalid_skb(netdev, skb))
@ -1634,7 +1650,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (!buf) {
stats->tx_dropped++;
dev_kfree_skb(skb);
goto nobufmem;
goto freeurb;
}
msg = buf;
@ -1681,8 +1697,10 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
/* This should never happen; it implies a flow control bug */
if (!context) {
netdev_warn(netdev, "cannot find free context\n");
kfree(buf);
ret = NETDEV_TX_BUSY;
goto releasebuf;
goto freeurb;
}
context->priv = priv;
@ -1719,16 +1737,12 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
else
netdev_warn(netdev, "Failed tx_urb %d\n", err);
goto releasebuf;
goto freeurb;
}
usb_free_urb(urb);
ret = NETDEV_TX_OK;
return NETDEV_TX_OK;
releasebuf:
kfree(buf);
nobufmem:
freeurb:
usb_free_urb(urb);
return ret;
}

View File

@ -879,6 +879,10 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
pdev->usb_if = ppdev->usb_if;
pdev->cmd_buffer_addr = ppdev->cmd_buffer_addr;
/* do a copy of the ctrlmode[_supported] too */
dev->can.ctrlmode = ppdev->dev.can.ctrlmode;
dev->can.ctrlmode_supported = ppdev->dev.can.ctrlmode_supported;
}
pdev->usb_if->dev[dev->ctrl_idx] = dev;

View File

@ -593,7 +593,7 @@ static int xgene_enet_reset(struct xgene_enet_pdata *pdata)
if (!xgene_ring_mgr_init(pdata))
return -ENODEV;
if (!efi_enabled(EFI_BOOT)) {
if (pdata->clk) {
clk_prepare_enable(pdata->clk);
clk_disable_unprepare(pdata->clk);
clk_prepare_enable(pdata->clk);

View File

@ -1025,6 +1025,8 @@ static int xgene_enet_remove(struct platform_device *pdev)
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgene_enet_acpi_match[] = {
{ "APMC0D05", },
{ "APMC0D30", },
{ "APMC0D31", },
{ }
};
MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
@ -1033,6 +1035,8 @@ MODULE_DEVICE_TABLE(acpi, xgene_enet_acpi_match);
#ifdef CONFIG_OF
static struct of_device_id xgene_enet_of_match[] = {
{.compatible = "apm,xgene-enet",},
{.compatible = "apm,xgene1-sgenet",},
{.compatible = "apm,xgene1-xgenet",},
{},
};

View File

@ -486,7 +486,7 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
{
struct bcm_enet_priv *priv;
struct net_device *dev;
int tx_work_done, rx_work_done;
int rx_work_done;
priv = container_of(napi, struct bcm_enet_priv, napi);
dev = priv->net_dev;
@ -498,14 +498,14 @@ static int bcm_enet_poll(struct napi_struct *napi, int budget)
ENETDMAC_IR, priv->tx_chan);
/* reclaim sent skb */
tx_work_done = bcm_enet_tx_reclaim(dev, 0);
bcm_enet_tx_reclaim(dev, 0);
spin_lock(&priv->rx_lock);
rx_work_done = bcm_enet_receive_queue(dev, budget);
spin_unlock(&priv->rx_lock);
if (rx_work_done >= budget || tx_work_done > 0) {
/* rx/tx queue is not yet empty/clean */
if (rx_work_done >= budget) {
/* rx queue is not yet empty/clean */
return rx_work_done;
}

View File

@ -302,9 +302,6 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac,
slot->skb = skb;
slot->dma_addr = dma_addr;
if (slot->dma_addr & 0xC0000000)
bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
return 0;
}
@ -505,8 +502,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac)
ring->mmio_base);
goto err_dma_free;
}
if (ring->dma_base & 0xC0000000)
bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
BGMAC_DMA_RING_TX);
@ -536,8 +531,6 @@ static int bgmac_dma_alloc(struct bgmac *bgmac)
err = -ENOMEM;
goto err_dma_free;
}
if (ring->dma_base & 0xC0000000)
bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n");
ring->unaligned = bgmac_dma_unaligned(bgmac, ring,
BGMAC_DMA_RING_RX);

View File

@ -12722,6 +12722,9 @@ static int bnx2x_init_dev(struct bnx2x *bp, struct pci_dev *pdev,
pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS,
PCICFG_VENDOR_ID_OFFSET);
/* Set PCIe reset type to fundamental for EEH recovery */
pdev->needs_freset = 1;
/* AER (Advanced Error reporting) configuration */
rc = pci_enable_pcie_error_reporting(pdev);
if (!rc)

View File

@ -73,15 +73,17 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~(WAKE_MAGIC | WAKE_MAGICSECURE))
return -EINVAL;
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
if (wol->wolopts & WAKE_MAGICSECURE) {
bcmgenet_umac_writel(priv, get_unaligned_be16(&wol->sopass[0]),
UMAC_MPD_PW_MS);
bcmgenet_umac_writel(priv, get_unaligned_be32(&wol->sopass[2]),
UMAC_MPD_PW_LS);
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
reg |= MPD_PW_EN;
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
} else {
reg &= ~MPD_PW_EN;
}
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
/* Flag the device and relevant IRQ as wakeup capable */
if (wol->wolopts) {

View File

@ -2113,17 +2113,17 @@ static const struct net_device_ops macb_netdev_ops = {
};
#if defined(CONFIG_OF)
static struct macb_config pc302gem_config = {
static const struct macb_config pc302gem_config = {
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
.dma_burst_length = 16,
};
static struct macb_config sama5d3_config = {
static const struct macb_config sama5d3_config = {
.caps = MACB_CAPS_SG_DISABLED | MACB_CAPS_GIGABIT_MODE_AVAILABLE,
.dma_burst_length = 16,
};
static struct macb_config sama5d4_config = {
static const struct macb_config sama5d4_config = {
.caps = 0,
.dma_burst_length = 4,
};
@ -2154,7 +2154,7 @@ static void macb_configure_caps(struct macb *bp)
if (bp->pdev->dev.of_node) {
match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node);
if (match && match->data) {
config = (const struct macb_config *)match->data;
config = match->data;
bp->caps = config->caps;
/*

View File

@ -351,7 +351,7 @@
/* Bitfields in MID */
#define MACB_IDNUM_OFFSET 16
#define MACB_IDNUM_SIZE 16
#define MACB_IDNUM_SIZE 12
#define MACB_REV_OFFSET 0
#define MACB_REV_SIZE 16

View File

@ -1597,7 +1597,7 @@ fec_enet_interrupt(int irq, void *dev_id)
writel(int_events, fep->hwp + FEC_IEVENT);
fec_enet_collect_events(fep, int_events);
if (fep->work_tx || fep->work_rx) {
if ((fep->work_tx || fep->work_rx) && fep->link) {
ret = IRQ_HANDLED;
if (napi_schedule_prep(&fep->napi)) {
@ -3383,7 +3383,6 @@ fec_drv_remove(struct platform_device *pdev)
regulator_disable(fep->reg_phy);
if (fep->ptp_clock)
ptp_clock_unregister(fep->ptp_clock);
fec_enet_clk_enable(ndev, false);
of_node_put(fep->phy_node);
free_netdev(ndev);

View File

@ -747,6 +747,18 @@ static int gfar_parse_group(struct device_node *np,
return 0;
}
static int gfar_of_group_count(struct device_node *np)
{
struct device_node *child;
int num = 0;
for_each_available_child_of_node(np, child)
if (!of_node_cmp(child->name, "queue-group"))
num++;
return num;
}
static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
{
const char *model;
@ -784,7 +796,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
num_rx_qs = 1;
} else { /* MQ_MG_MODE */
/* get the actual number of supported groups */
unsigned int num_grps = of_get_available_child_count(np);
unsigned int num_grps = gfar_of_group_count(np);
if (num_grps == 0 || num_grps > MAXGROUPS) {
dev_err(&ofdev->dev, "Invalid # of int groups(%d)\n",
@ -851,7 +863,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
/* Parse and initialize group specific information */
if (priv->mode == MQ_MG_MODE) {
for_each_child_of_node(np, child) {
for_each_available_child_of_node(np, child) {
if (of_node_cmp(child->name, "queue-group"))
continue;
err = gfar_parse_group(child, priv, model);
if (err)
goto err_grp_init;

View File

@ -92,6 +92,7 @@ static const char version[] =
#include "smc91x.h"
#if defined(CONFIG_ASSABET_NEPONSET)
#include <mach/assabet.h>
#include <mach/neponset.h>
#endif

View File

@ -272,6 +272,37 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
struct stmmac_priv *priv = NULL;
struct plat_stmmacenet_data *plat_dat = NULL;
const char *mac = NULL;
int irq, wol_irq, lpi_irq;
/* Get IRQ information early to have an ability to ask for deferred
* probe if needed before we went too far with resource allocation.
*/
irq = platform_get_irq_byname(pdev, "macirq");
if (irq < 0) {
if (irq != -EPROBE_DEFER) {
dev_err(dev,
"MAC IRQ configuration information not found\n");
}
return irq;
}
/* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
* The external wake up irq can be passed through the platform code
* named as "eth_wake_irq"
*
* In case the wake up interrupt is not passed from the platform
* so the driver will continue to use the mac irq (ndev->irq)
*/
wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
if (wol_irq < 0) {
if (wol_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
wol_irq = irq;
}
lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
if (lpi_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
addr = devm_ioremap_resource(dev, res);
@ -323,39 +354,15 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
return PTR_ERR(priv);
}
/* Copy IRQ values to priv structure which is now avaialble */
priv->dev->irq = irq;
priv->wol_irq = wol_irq;
priv->lpi_irq = lpi_irq;
/* Get MAC address if available (DT) */
if (mac)
memcpy(priv->dev->dev_addr, mac, ETH_ALEN);
/* Get the MAC information */
priv->dev->irq = platform_get_irq_byname(pdev, "macirq");
if (priv->dev->irq < 0) {
if (priv->dev->irq != -EPROBE_DEFER) {
netdev_err(priv->dev,
"MAC IRQ configuration information not found\n");
}
return priv->dev->irq;
}
/*
* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
* The external wake up irq can be passed through the platform code
* named as "eth_wake_irq"
*
* In case the wake up interrupt is not passed from the platform
* so the driver will continue to use the mac irq (ndev->irq)
*/
priv->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
if (priv->wol_irq < 0) {
if (priv->wol_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
priv->wol_irq = priv->dev->irq;
}
priv->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
if (priv->lpi_irq == -EPROBE_DEFER)
return -EPROBE_DEFER;
platform_set_drvdata(pdev, priv->dev);
pr_debug("STMMAC platform driver registration completed");

View File

@ -1730,11 +1730,11 @@ static int team_set_mac_address(struct net_device *dev, void *p)
if (dev->type == ARPHRD_ETHER && !is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
rcu_read_lock();
list_for_each_entry_rcu(port, &team->port_list, list)
mutex_lock(&team->lock);
list_for_each_entry(port, &team->port_list, list)
if (team->ops.port_change_dev_addr)
team->ops.port_change_dev_addr(team, port);
rcu_read_unlock();
mutex_unlock(&team->lock);
return 0;
}

View File

@ -340,12 +340,11 @@ static void xenvif_get_ethtool_stats(struct net_device *dev,
unsigned int num_queues = vif->num_queues;
int i;
unsigned int queue_index;
struct xenvif_stats *vif_stats;
for (i = 0; i < ARRAY_SIZE(xenvif_stats); i++) {
unsigned long accum = 0;
for (queue_index = 0; queue_index < num_queues; ++queue_index) {
vif_stats = &vif->queues[queue_index].stats;
void *vif_stats = &vif->queues[queue_index].stats;
accum += *(unsigned long *)(vif_stats + xenvif_stats[i].offset);
}
data[i] = accum;

View File

@ -1349,7 +1349,7 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
{
unsigned int offset = skb_headlen(skb);
skb_frag_t frags[MAX_SKB_FRAGS];
int i;
int i, f;
struct ubuf_info *uarg;
struct sk_buff *nskb = skb_shinfo(skb)->frag_list;
@ -1389,23 +1389,25 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s
frags[i].page_offset = 0;
skb_frag_size_set(&frags[i], len);
}
/* swap out with old one */
memcpy(skb_shinfo(skb)->frags,
frags,
i * sizeof(skb_frag_t));
skb_shinfo(skb)->nr_frags = i;
skb->truesize += i * PAGE_SIZE;
/* remove traces of mapped pages and frag_list */
/* Copied all the bits from the frag list -- free it. */
skb_frag_list_init(skb);
xenvif_skb_zerocopy_prepare(queue, nskb);
kfree_skb(nskb);
/* Release all the original (foreign) frags. */
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
skb_frag_unref(skb, f);
uarg = skb_shinfo(skb)->destructor_arg;
/* increase inflight counter to offset decrement in callback */
atomic_inc(&queue->inflight_packets);
uarg->callback(uarg, true);
skb_shinfo(skb)->destructor_arg = NULL;
xenvif_skb_zerocopy_prepare(queue, nskb);
kfree_skb(nskb);
/* Fill the skb with the new (local) frags. */
memcpy(skb_shinfo(skb)->frags, frags, i * sizeof(skb_frag_t));
skb_shinfo(skb)->nr_frags = i;
skb->truesize += i * PAGE_SIZE;
return 0;
}

View File

@ -119,6 +119,22 @@ int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
const struct nft_data *data,
enum nft_data_types type);
/**
* struct nft_userdata - user defined data associated with an object
*
* @len: length of the data
* @data: content
*
* The presence of user data is indicated in an object specific fashion,
* so a length of zero can't occur and the value "len" indicates data
* of length len + 1.
*/
struct nft_userdata {
u8 len;
unsigned char data[0];
};
/**
* struct nft_set_elem - generic representation of set elements
*
@ -380,7 +396,7 @@ static inline void *nft_expr_priv(const struct nft_expr *expr)
* @handle: rule handle
* @genmask: generation mask
* @dlen: length of expression data
* @ulen: length of user data (used for comments)
* @udata: user data is appended to the rule
* @data: expression data
*/
struct nft_rule {
@ -388,7 +404,7 @@ struct nft_rule {
u64 handle:42,
genmask:2,
dlen:12,
ulen:8;
udata:1;
unsigned char data[]
__attribute__((aligned(__alignof__(struct nft_expr))));
};
@ -476,7 +492,7 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
return (struct nft_expr *)&rule->data[rule->dlen];
}
static inline void *nft_userdata(const struct nft_rule *rule)
static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
{
return (void *)&rule->data[rule->dlen];
}

View File

@ -259,6 +259,9 @@ int can_send(struct sk_buff *skb, int loop)
goto inval_skb;
}
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
skb_reset_transport_header(skb);

View File

@ -659,27 +659,30 @@ EXPORT_SYMBOL(ip_defrag);
struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
{
struct iphdr iph;
int netoff;
u32 len;
if (skb->protocol != htons(ETH_P_IP))
return skb;
if (skb_copy_bits(skb, 0, &iph, sizeof(iph)) < 0)
netoff = skb_network_offset(skb);
if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0)
return skb;
if (iph.ihl < 5 || iph.version != 4)
return skb;
len = ntohs(iph.tot_len);
if (skb->len < len || len < (iph.ihl * 4))
if (skb->len < netoff + len || len < (iph.ihl * 4))
return skb;
if (ip_is_fragment(&iph)) {
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb) {
if (!pskb_may_pull(skb, iph.ihl*4))
if (!pskb_may_pull(skb, netoff + iph.ihl * 4))
return skb;
if (pskb_trim_rcsum(skb, len))
if (pskb_trim_rcsum(skb, netoff + len))
return skb;
memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
if (ip_defrag(skb, user))

View File

@ -432,17 +432,32 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
kfree_skb(skb);
}
static bool ipv4_pktinfo_prepare_errqueue(const struct sock *sk,
const struct sk_buff *skb,
int ee_origin)
/* IPv4 supports cmsg on all imcp errors and some timestamps
*
* Timestamp code paths do not initialize the fields expected by cmsg:
* the PKTINFO fields in skb->cb[]. Fill those in here.
*/
static bool ipv4_datagram_support_cmsg(const struct sock *sk,
struct sk_buff *skb,
int ee_origin)
{
struct in_pktinfo *info = PKTINFO_SKB_CB(skb);
struct in_pktinfo *info;
if ((ee_origin != SO_EE_ORIGIN_TIMESTAMPING) ||
(!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) ||
if (ee_origin == SO_EE_ORIGIN_ICMP)
return true;
if (ee_origin == SO_EE_ORIGIN_LOCAL)
return false;
/* Support IP_PKTINFO on tstamp packets if requested, to correlate
* timestamp with egress dev. Not possible for packets without dev
* or without payload (SOF_TIMESTAMPING_OPT_TSONLY).
*/
if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) ||
(!skb->dev))
return false;
info = PKTINFO_SKB_CB(skb);
info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr;
info->ipi_ifindex = skb->dev->ifindex;
return true;
@ -483,7 +498,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
serr = SKB_EXT_ERR(skb);
if (sin && skb->len) {
if (sin && serr->port) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
serr->addr_offset);
@ -496,9 +511,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
sin = &errhdr.offender;
memset(sin, 0, sizeof(*sin));
if (skb->len &&
(serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin))) {
if (ipv4_datagram_support_cmsg(sk, skb, serr->ee.ee_origin)) {
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
if (inet_sk(sk)->cmsg_flags)

View File

@ -259,6 +259,9 @@ int ping_init_sock(struct sock *sk)
kgid_t low, high;
int ret = 0;
if (sk->sk_family == AF_INET6)
sk->sk_ipv6only = 1;
inet_get_ping_group_range_net(net, &low, &high);
if (gid_lte(low, group) && gid_lte(group, high))
return 0;
@ -305,6 +308,11 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
if (addr_len < sizeof(*addr))
return -EINVAL;
if (addr->sin_family != AF_INET &&
!(addr->sin_family == AF_UNSPEC &&
addr->sin_addr.s_addr == htonl(INADDR_ANY)))
return -EAFNOSUPPORT;
pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n",
sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port));
@ -330,7 +338,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
return -EINVAL;
if (addr->sin6_family != AF_INET6)
return -EINVAL;
return -EAFNOSUPPORT;
pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
@ -716,7 +724,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
if (msg->msg_namelen < sizeof(*usin))
return -EINVAL;
if (usin->sin_family != AF_INET)
return -EINVAL;
return -EAFNOSUPPORT;
daddr = usin->sin_addr.s_addr;
/* no remote port */
} else {

View File

@ -835,17 +835,13 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
int large_allowed)
{
struct tcp_sock *tp = tcp_sk(sk);
u32 new_size_goal, size_goal, hlen;
u32 new_size_goal, size_goal;
if (!large_allowed || !sk_can_gso(sk))
return mss_now;
/* Maybe we should/could use sk->sk_prot->max_header here ? */
hlen = inet_csk(sk)->icsk_af_ops->net_header_len +
inet_csk(sk)->icsk_ext_hdr_len +
tp->tcp_header_len;
new_size_goal = sk->sk_gso_max_size - 1 - hlen;
/* Note : tcp_tso_autosize() will eventually split this later */
new_size_goal = sk->sk_gso_max_size - 1 - MAX_TCP_HEADER;
new_size_goal = tcp_bound_to_half_wnd(tp, new_size_goal);
/* We try hard to avoid divides here */

View File

@ -325,14 +325,34 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu)
kfree_skb(skb);
}
static void ip6_datagram_prepare_pktinfo_errqueue(struct sk_buff *skb)
/* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL.
*
* At one point, excluding local errors was a quick test to identify icmp/icmp6
* errors. This is no longer true, but the test remained, so the v6 stack,
* unlike v4, also honors cmsg requests on all wifi and timestamp errors.
*
* Timestamp code paths do not initialize the fields expected by cmsg:
* the PKTINFO fields in skb->cb[]. Fill those in here.
*/
static bool ip6_datagram_support_cmsg(struct sk_buff *skb,
struct sock_exterr_skb *serr)
{
int ifindex = skb->dev ? skb->dev->ifindex : -1;
if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6)
return true;
if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL)
return false;
if (!skb->dev)
return false;
if (skb->protocol == htons(ETH_P_IPV6))
IP6CB(skb)->iif = ifindex;
IP6CB(skb)->iif = skb->dev->ifindex;
else
PKTINFO_SKB_CB(skb)->ipi_ifindex = ifindex;
PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex;
return true;
}
/*
@ -369,7 +389,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
serr = SKB_EXT_ERR(skb);
if (sin && skb->len) {
if (sin && serr->port) {
const unsigned char *nh = skb_network_header(skb);
sin->sin6_family = AF_INET6;
sin->sin6_flowinfo = 0;
@ -394,14 +414,11 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
sin = &errhdr.offender;
memset(sin, 0, sizeof(*sin));
if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL && skb->len) {
if (ip6_datagram_support_cmsg(skb, serr)) {
sin->sin6_family = AF_INET6;
if (np->rxopt.all) {
if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP &&
serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6)
ip6_datagram_prepare_pktinfo_errqueue(skb);
if (np->rxopt.all)
ip6_datagram_recv_common_ctl(sk, msg, skb);
}
if (skb->protocol == htons(ETH_P_IPV6)) {
sin->sin6_addr = ipv6_hdr(skb)->saddr;
if (np->rxopt.all)

View File

@ -102,9 +102,10 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (msg->msg_name) {
DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name);
if (msg->msg_namelen < sizeof(struct sockaddr_in6) ||
u->sin6_family != AF_INET6) {
if (msg->msg_namelen < sizeof(*u))
return -EINVAL;
if (u->sin6_family != AF_INET6) {
return -EAFNOSUPPORT;
}
if (sk->sk_bound_dev_if &&
sk->sk_bound_dev_if != u->sin6_scope_id) {

View File

@ -896,6 +896,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
return;
}
if (!(flags & IP_VS_CONN_F_TEMPLATE))
kfree(param->pe_data);
}
if (opt)
@ -1169,6 +1171,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end)
(opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL)
);
#endif
ip_vs_pe_put(param.pe);
return 0;
/* Error exit */
out:

View File

@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
{
rule->genmask = 0;
rule->genmask &= ~(1 << gencursor_next(net));
}
static int
@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
}
nla_nest_end(skb, list);
if (rule->ulen &&
nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule)))
goto nla_put_failure;
if (rule->udata) {
struct nft_userdata *udata = nft_userdata(rule);
if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
udata->data) < 0)
goto nla_put_failure;
}
nlmsg_end(skb, nlh);
return 0;
@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
struct nft_table *table;
struct nft_chain *chain;
struct nft_rule *rule, *old_rule = NULL;
struct nft_userdata *udata;
struct nft_trans *trans = NULL;
struct nft_expr *expr;
struct nft_ctx ctx;
struct nlattr *tmp;
unsigned int size, i, n, ulen = 0;
unsigned int size, i, n, ulen = 0, usize = 0;
int err, rem;
bool create;
u64 handle, pos_handle;
@ -1968,12 +1972,19 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
n++;
}
}
/* Check for overflow of dlen field */
err = -EFBIG;
if (size >= 1 << 12)
goto err1;
if (nla[NFTA_RULE_USERDATA])
if (nla[NFTA_RULE_USERDATA]) {
ulen = nla_len(nla[NFTA_RULE_USERDATA]);
if (ulen > 0)
usize = sizeof(struct nft_userdata) + ulen;
}
err = -ENOMEM;
rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL);
rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
if (rule == NULL)
goto err1;
@ -1981,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
rule->handle = handle;
rule->dlen = size;
rule->ulen = ulen;
rule->udata = ulen ? 1 : 0;
if (ulen)
nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen);
if (ulen) {
udata = nft_userdata(rule);
udata->len = ulen - 1;
nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
}
expr = nft_expr_first(rule);
for (i = 0; i < n; i++) {
@ -2031,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
err3:
list_del_rcu(&rule->list);
if (trans) {
list_del_rcu(&nft_trans_rule(trans)->list);
nft_rule_clear(net, nft_trans_rule(trans));
nft_trans_destroy(trans);
chain->use++;
}
err2:
nf_tables_rule_destroy(&ctx, rule);
err1:
@ -3612,12 +3620,11 @@ static int nf_tables_commit(struct sk_buff *skb)
&te->elem,
NFT_MSG_DELSETELEM, 0);
te->set->ops->get(te->set, &te->elem);
te->set->ops->remove(te->set, &te->elem);
nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
if (te->elem.flags & NFT_SET_MAP) {
nft_data_uninit(&te->elem.data,
te->set->dtype);
}
if (te->set->flags & NFT_SET_MAP &&
!(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
nft_data_uninit(&te->elem.data, te->set->dtype);
te->set->ops->remove(te->set, &te->elem);
nft_trans_destroy(trans);
break;
}
@ -3658,7 +3665,7 @@ static int nf_tables_abort(struct sk_buff *skb)
{
struct net *net = sock_net(skb->sk);
struct nft_trans *trans, *next;
struct nft_set *set;
struct nft_trans_elem *te;
list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
switch (trans->msg_type) {
@ -3719,9 +3726,13 @@ static int nf_tables_abort(struct sk_buff *skb)
break;
case NFT_MSG_NEWSETELEM:
nft_trans_elem_set(trans)->nelems--;
set = nft_trans_elem_set(trans);
set->ops->get(set, &nft_trans_elem(trans));
set->ops->remove(set, &nft_trans_elem(trans));
te = (struct nft_trans_elem *)trans->data;
te->set->ops->get(te->set, &te->elem);
nft_data_uninit(&te->elem.key, NFT_DATA_VALUE);
if (te->set->flags & NFT_SET_MAP &&
!(te->elem.flags & NFT_SET_ELEM_INTERVAL_END))
nft_data_uninit(&te->elem.data, te->set->dtype);
te->set->ops->remove(te->set, &te->elem);
nft_trans_destroy(trans);
break;
case NFT_MSG_DELSETELEM:

View File

@ -123,7 +123,7 @@ static void
nft_target_set_tgchk_param(struct xt_tgchk_param *par,
const struct nft_ctx *ctx,
struct xt_target *target, void *info,
union nft_entry *entry, u8 proto, bool inv)
union nft_entry *entry, u16 proto, bool inv)
{
par->net = ctx->net;
par->table = ctx->table->name;
@ -137,7 +137,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
case NFPROTO_BRIDGE:
entry->ebt.ethproto = proto;
entry->ebt.ethproto = (__force __be16)proto;
entry->ebt.invflags = inv ? EBT_IPROTO : 0;
break;
}
@ -171,7 +171,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1]
[NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 },
};
static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv)
static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
{
struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1];
u32 flags;
@ -203,7 +203,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct xt_target *target = expr->ops->data;
struct xt_tgchk_param par;
size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO]));
u8 proto = 0;
u16 proto = 0;
bool inv = false;
union nft_entry e = {};
int ret;
@ -334,7 +334,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = {
static void
nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
struct xt_match *match, void *info,
union nft_entry *entry, u8 proto, bool inv)
union nft_entry *entry, u16 proto, bool inv)
{
par->net = ctx->net;
par->table = ctx->table->name;
@ -348,7 +348,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0;
break;
case NFPROTO_BRIDGE:
entry->ebt.ethproto = proto;
entry->ebt.ethproto = (__force __be16)proto;
entry->ebt.invflags = inv ? EBT_IPROTO : 0;
break;
}
@ -385,7 +385,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
struct xt_match *match = expr->ops->data;
struct xt_mtchk_param par;
size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO]));
u8 proto = 0;
u16 proto = 0;
bool inv = false;
union nft_entry e = {};
int ret;

View File

@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
return 0;
}
static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what)
static void packet_dev_mclist_delete(struct net_device *dev,
struct packet_mclist **mlp)
{
for ( ; i; i = i->next) {
if (i->ifindex == dev->ifindex)
packet_dev_mc(dev, i, what);
struct packet_mclist *ml;
while ((ml = *mlp) != NULL) {
if (ml->ifindex == dev->ifindex) {
packet_dev_mc(dev, ml, -1);
*mlp = ml->next;
kfree(ml);
} else
mlp = &ml->next;
}
}
@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
packet_dev_mc(dev, ml, -1);
kfree(ml);
}
rtnl_unlock();
return 0;
break;
}
}
rtnl_unlock();
return -EADDRNOTAVAIL;
return 0;
}
static void packet_flush_mclist(struct sock *sk)
@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this,
switch (msg) {
case NETDEV_UNREGISTER:
if (po->mclist)
packet_dev_mclist(dev, po->mclist, -1);
packet_dev_mclist_delete(dev, &po->mclist);
/* fallthrough */
case NETDEV_DOWN:

View File

@ -42,7 +42,8 @@ void rxrpc_UDP_error_report(struct sock *sk)
_leave("UDP socket errqueue empty");
return;
}
if (!skb->len) {
serr = SKB_EXT_ERR(skb);
if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) {
_leave("UDP empty message");
kfree_skb(skb);
return;
@ -50,7 +51,6 @@ void rxrpc_UDP_error_report(struct sock *sk)
rxrpc_new_skb(skb);
serr = SKB_EXT_ERR(skb);
addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset);
port = serr->port;

View File

@ -464,10 +464,11 @@ void tipc_link_reset(struct tipc_link *l_ptr)
/* Clean up all queues, except inputq: */
__skb_queue_purge(&l_ptr->outqueue);
__skb_queue_purge(&l_ptr->deferred_queue);
skb_queue_splice_init(&l_ptr->wakeupq, &l_ptr->inputq);
if (!skb_queue_empty(&l_ptr->inputq))
if (!owner->inputq)
owner->inputq = &l_ptr->inputq;
skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq);
if (!skb_queue_empty(owner->inputq))
owner->action_flags |= TIPC_MSG_EVT;
owner->inputq = &l_ptr->inputq;
l_ptr->next_out = NULL;
l_ptr->unacked_window = 0;
l_ptr->checkpoint = 1;