mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix double SKB free in bluetooth 6lowpan layer, from Jukka Rissanen. 2) Fix receive checksum handling in enic driver, from Govindarajulu Varadarajan. 3) Fix NAPI poll list corruption in virtio_net and caif_virtio, from Herbert Xu. Also, add code to detect drivers that have this mistake in the future. 4) Fix doorbell endianness handling in mlx4 driver, from Amir Vadai. 5) Don't clobber IP6CB() before xfrm6_policy_check() is called in TCP input path,f rom Nicolas Dichtel. 6) Fix MPLS action validation in openvswitch, from Pravin B Shelar. 7) Fix double SKB free in vxlan driver, also from Pravin. 8) When we scrub a packet, which happens when we are switching the context of the packet (namespace, etc.), we should reset the secmark. From Thomas Graf. 9) ->ndo_gso_check() needs to do more than return true/false, it also has to allow the driver to clear netdev feature bits in order for the caller to be able to proceed properly. From Jesse Gross. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (62 commits) genetlink: A genl_bind() to an out-of-range multicast group should not WARN(). netlink/genetlink: pass network namespace to bind/unbind ne2k-pci: Add pci_disable_device in error handling bonding: change error message to debug message in __bond_release_one() genetlink: pass multicast bind/unbind to families netlink: call unbind when releasing socket netlink: update listeners directly when removing socket genetlink: pass only network namespace to genl_has_listeners() netlink: rename netlink_unbind() to netlink_undo_bind() net: Generalize ndo_gso_check to ndo_features_check net: incorrect use of init_completion fixup neigh: remove next ptr from struct neigh_table net: xilinx: Remove unnecessary temac_property in the driver net: phy: micrel: use generic config_init for KSZ8021/KSZ8031 net/core: Handle csum for CHECKSUM_COMPLETE VXLAN forwarding openvswitch: fix odd_ptr_err.cocci warnings Bluetooth: Fix accepting connections when not using mgmt Bluetooth: Fix controller configuration with HCI_QUIRK_INVALID_BDADDR brcmfmac: Do not crash if platform data is not populated ipw2200: select CFG80211_WEXT ...
This commit is contained in:
commit
2c90331cf5
@ -1648,7 +1648,7 @@ static int __bond_release_one(struct net_device *bond_dev,
|
||||
/* slave is not a slave or master is not master of this slave */
|
||||
if (!(slave_dev->flags & IFF_SLAVE) ||
|
||||
!netdev_has_upper_dev(slave_dev, bond_dev)) {
|
||||
netdev_err(bond_dev, "cannot release %s\n",
|
||||
netdev_dbg(bond_dev, "cannot release %s\n",
|
||||
slave_dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -257,7 +257,6 @@ static int cfv_rx_poll(struct napi_struct *napi, int quota)
|
||||
struct vringh_kiov *riov = &cfv->ctx.riov;
|
||||
unsigned int skb_len;
|
||||
|
||||
again:
|
||||
do {
|
||||
skb = NULL;
|
||||
|
||||
@ -322,7 +321,6 @@ exit:
|
||||
napi_schedule_prep(napi)) {
|
||||
vringh_notify_disable_kern(cfv->vr_rx);
|
||||
__napi_schedule(napi);
|
||||
goto again;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -246,13 +246,13 @@ static int ne2k_pci_init_one(struct pci_dev *pdev,
|
||||
|
||||
if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) {
|
||||
dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n");
|
||||
return -ENODEV;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) {
|
||||
dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n",
|
||||
NE_IO_EXTENT, ioaddr);
|
||||
return -EBUSY;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
reg0 = inb(ioaddr);
|
||||
@ -392,6 +392,8 @@ err_out_free_netdev:
|
||||
free_netdev (dev);
|
||||
err_out_free_res:
|
||||
release_region (ioaddr, NE_IO_EXTENT);
|
||||
err_out:
|
||||
pci_disable_device(pdev);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -156,18 +156,6 @@ source "drivers/net/ethernet/realtek/Kconfig"
|
||||
source "drivers/net/ethernet/renesas/Kconfig"
|
||||
source "drivers/net/ethernet/rdc/Kconfig"
|
||||
source "drivers/net/ethernet/rocker/Kconfig"
|
||||
|
||||
config S6GMAC
|
||||
tristate "S6105 GMAC ethernet support"
|
||||
depends on XTENSA_VARIANT_S6000
|
||||
select PHYLIB
|
||||
---help---
|
||||
This driver supports the on chip ethernet device on the
|
||||
S6105 xtensa processor.
|
||||
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called s6gmac.
|
||||
|
||||
source "drivers/net/ethernet/samsung/Kconfig"
|
||||
source "drivers/net/ethernet/seeq/Kconfig"
|
||||
source "drivers/net/ethernet/silan/Kconfig"
|
||||
|
@ -66,7 +66,6 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
|
||||
obj-$(CONFIG_SH_ETH) += renesas/
|
||||
obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
|
||||
obj-$(CONFIG_NET_VENDOR_ROCKER) += rocker/
|
||||
obj-$(CONFIG_S6GMAC) += s6gmac.o
|
||||
obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/
|
||||
obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
|
||||
obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
|
||||
|
@ -12553,9 +12553,11 @@ static int bnx2x_get_phys_port_id(struct net_device *netdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool bnx2x_gso_check(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_features_t bnx2x_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
return vxlan_gso_check(skb);
|
||||
return vxlan_features_check(skb, features);
|
||||
}
|
||||
|
||||
static const struct net_device_ops bnx2x_netdev_ops = {
|
||||
@ -12589,7 +12591,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
|
||||
#endif
|
||||
.ndo_get_phys_port_id = bnx2x_get_phys_port_id,
|
||||
.ndo_set_vf_link_state = bnx2x_set_vf_link_state,
|
||||
.ndo_gso_check = bnx2x_gso_check,
|
||||
.ndo_features_check = bnx2x_features_check,
|
||||
};
|
||||
|
||||
static int bnx2x_set_coherency_mask(struct bnx2x *bp)
|
||||
|
@ -17800,23 +17800,6 @@ static int tg3_init_one(struct pci_dev *pdev,
|
||||
goto err_out_apeunmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset chip in case UNDI or EFI driver did not shutdown
|
||||
* DMA self test will enable WDMAC and we'll see (spurious)
|
||||
* pending DMA on the PCI bus at that point.
|
||||
*/
|
||||
if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
|
||||
(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
|
||||
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
|
||||
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
|
||||
}
|
||||
|
||||
err = tg3_test_dma(tp);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
|
||||
goto err_out_apeunmap;
|
||||
}
|
||||
|
||||
intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
|
||||
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
|
||||
sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW;
|
||||
@ -17861,6 +17844,23 @@ static int tg3_init_one(struct pci_dev *pdev,
|
||||
sndmbx += 0xc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset chip in case UNDI or EFI driver did not shutdown
|
||||
* DMA self test will enable WDMAC and we'll see (spurious)
|
||||
* pending DMA on the PCI bus at that point.
|
||||
*/
|
||||
if ((tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE) ||
|
||||
(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
|
||||
tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
|
||||
tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
|
||||
}
|
||||
|
||||
err = tg3_test_dma(tp);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "DMA engine test failed, aborting\n");
|
||||
goto err_out_apeunmap;
|
||||
}
|
||||
|
||||
tg3_init_coal(tp);
|
||||
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
@ -172,7 +172,7 @@ bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len)
|
||||
|
||||
/* Retrieve flash partition info */
|
||||
fcomp.comp_status = 0;
|
||||
init_completion(&fcomp.comp);
|
||||
reinit_completion(&fcomp.comp);
|
||||
spin_lock_irqsave(&bnad->bna_lock, flags);
|
||||
ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr,
|
||||
bnad_cb_completion, &fcomp);
|
||||
|
@ -96,6 +96,9 @@ struct port_info {
|
||||
s16 xact_addr_filt; /* index of our MAC address filter */
|
||||
u16 rss_size; /* size of VI's RSS table slice */
|
||||
u8 pidx; /* index into adapter port[] */
|
||||
s8 mdio_addr;
|
||||
u8 port_type; /* firmware port type */
|
||||
u8 mod_type; /* firmware module type */
|
||||
u8 port_id; /* physical port ID */
|
||||
u8 nqsets; /* # of "Queue Sets" */
|
||||
u8 first_qset; /* index of first "Queue Set" */
|
||||
@ -522,6 +525,7 @@ static inline struct adapter *netdev2adap(const struct net_device *dev)
|
||||
* is "contracted" to provide for the common code.
|
||||
*/
|
||||
void t4vf_os_link_changed(struct adapter *, int, int);
|
||||
void t4vf_os_portmod_changed(struct adapter *, int);
|
||||
|
||||
/*
|
||||
* SGE function prototype declarations.
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mdio.h>
|
||||
|
||||
#include "t4vf_common.h"
|
||||
#include "t4vf_defs.h"
|
||||
@ -209,6 +210,38 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* THe port module type has changed on the indicated "port" (Virtual
|
||||
* Interface).
|
||||
*/
|
||||
void t4vf_os_portmod_changed(struct adapter *adapter, int pidx)
|
||||
{
|
||||
static const char * const mod_str[] = {
|
||||
NULL, "LR", "SR", "ER", "passive DA", "active DA", "LRM"
|
||||
};
|
||||
const struct net_device *dev = adapter->port[pidx];
|
||||
const struct port_info *pi = netdev_priv(dev);
|
||||
|
||||
if (pi->mod_type == FW_PORT_MOD_TYPE_NONE)
|
||||
dev_info(adapter->pdev_dev, "%s: port module unplugged\n",
|
||||
dev->name);
|
||||
else if (pi->mod_type < ARRAY_SIZE(mod_str))
|
||||
dev_info(adapter->pdev_dev, "%s: %s port module inserted\n",
|
||||
dev->name, mod_str[pi->mod_type]);
|
||||
else if (pi->mod_type == FW_PORT_MOD_TYPE_NOTSUPPORTED)
|
||||
dev_info(adapter->pdev_dev, "%s: unsupported optical port "
|
||||
"module inserted\n", dev->name);
|
||||
else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN)
|
||||
dev_info(adapter->pdev_dev, "%s: unknown port module inserted,"
|
||||
"forcing TWINAX\n", dev->name);
|
||||
else if (pi->mod_type == FW_PORT_MOD_TYPE_ERROR)
|
||||
dev_info(adapter->pdev_dev, "%s: transceiver module error\n",
|
||||
dev->name);
|
||||
else
|
||||
dev_info(adapter->pdev_dev, "%s: unknown module type %d "
|
||||
"inserted\n", dev->name, pi->mod_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Net device operations.
|
||||
* ======================
|
||||
@ -1193,24 +1226,103 @@ static void cxgb4vf_poll_controller(struct net_device *dev)
|
||||
* state of the port to which we're linked.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return current port link settings.
|
||||
*/
|
||||
static int cxgb4vf_get_settings(struct net_device *dev,
|
||||
struct ethtool_cmd *cmd)
|
||||
static unsigned int t4vf_from_fw_linkcaps(enum fw_port_type type,
|
||||
unsigned int caps)
|
||||
{
|
||||
const struct port_info *pi = netdev_priv(dev);
|
||||
unsigned int v = 0;
|
||||
|
||||
cmd->supported = pi->link_cfg.supported;
|
||||
cmd->advertising = pi->link_cfg.advertising;
|
||||
if (type == FW_PORT_TYPE_BT_SGMII || type == FW_PORT_TYPE_BT_XFI ||
|
||||
type == FW_PORT_TYPE_BT_XAUI) {
|
||||
v |= SUPPORTED_TP;
|
||||
if (caps & FW_PORT_CAP_SPEED_100M)
|
||||
v |= SUPPORTED_100baseT_Full;
|
||||
if (caps & FW_PORT_CAP_SPEED_1G)
|
||||
v |= SUPPORTED_1000baseT_Full;
|
||||
if (caps & FW_PORT_CAP_SPEED_10G)
|
||||
v |= SUPPORTED_10000baseT_Full;
|
||||
} else if (type == FW_PORT_TYPE_KX4 || type == FW_PORT_TYPE_KX) {
|
||||
v |= SUPPORTED_Backplane;
|
||||
if (caps & FW_PORT_CAP_SPEED_1G)
|
||||
v |= SUPPORTED_1000baseKX_Full;
|
||||
if (caps & FW_PORT_CAP_SPEED_10G)
|
||||
v |= SUPPORTED_10000baseKX4_Full;
|
||||
} else if (type == FW_PORT_TYPE_KR)
|
||||
v |= SUPPORTED_Backplane | SUPPORTED_10000baseKR_Full;
|
||||
else if (type == FW_PORT_TYPE_BP_AP)
|
||||
v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC |
|
||||
SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full;
|
||||
else if (type == FW_PORT_TYPE_BP4_AP)
|
||||
v |= SUPPORTED_Backplane | SUPPORTED_10000baseR_FEC |
|
||||
SUPPORTED_10000baseKR_Full | SUPPORTED_1000baseKX_Full |
|
||||
SUPPORTED_10000baseKX4_Full;
|
||||
else if (type == FW_PORT_TYPE_FIBER_XFI ||
|
||||
type == FW_PORT_TYPE_FIBER_XAUI ||
|
||||
type == FW_PORT_TYPE_SFP ||
|
||||
type == FW_PORT_TYPE_QSFP_10G ||
|
||||
type == FW_PORT_TYPE_QSA) {
|
||||
v |= SUPPORTED_FIBRE;
|
||||
if (caps & FW_PORT_CAP_SPEED_1G)
|
||||
v |= SUPPORTED_1000baseT_Full;
|
||||
if (caps & FW_PORT_CAP_SPEED_10G)
|
||||
v |= SUPPORTED_10000baseT_Full;
|
||||
} else if (type == FW_PORT_TYPE_BP40_BA ||
|
||||
type == FW_PORT_TYPE_QSFP) {
|
||||
v |= SUPPORTED_40000baseSR4_Full;
|
||||
v |= SUPPORTED_FIBRE;
|
||||
}
|
||||
|
||||
if (caps & FW_PORT_CAP_ANEG)
|
||||
v |= SUPPORTED_Autoneg;
|
||||
return v;
|
||||
}
|
||||
|
||||
static int cxgb4vf_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
const struct port_info *p = netdev_priv(dev);
|
||||
|
||||
if (p->port_type == FW_PORT_TYPE_BT_SGMII ||
|
||||
p->port_type == FW_PORT_TYPE_BT_XFI ||
|
||||
p->port_type == FW_PORT_TYPE_BT_XAUI)
|
||||
cmd->port = PORT_TP;
|
||||
else if (p->port_type == FW_PORT_TYPE_FIBER_XFI ||
|
||||
p->port_type == FW_PORT_TYPE_FIBER_XAUI)
|
||||
cmd->port = PORT_FIBRE;
|
||||
else if (p->port_type == FW_PORT_TYPE_SFP ||
|
||||
p->port_type == FW_PORT_TYPE_QSFP_10G ||
|
||||
p->port_type == FW_PORT_TYPE_QSA ||
|
||||
p->port_type == FW_PORT_TYPE_QSFP) {
|
||||
if (p->mod_type == FW_PORT_MOD_TYPE_LR ||
|
||||
p->mod_type == FW_PORT_MOD_TYPE_SR ||
|
||||
p->mod_type == FW_PORT_MOD_TYPE_ER ||
|
||||
p->mod_type == FW_PORT_MOD_TYPE_LRM)
|
||||
cmd->port = PORT_FIBRE;
|
||||
else if (p->mod_type == FW_PORT_MOD_TYPE_TWINAX_PASSIVE ||
|
||||
p->mod_type == FW_PORT_MOD_TYPE_TWINAX_ACTIVE)
|
||||
cmd->port = PORT_DA;
|
||||
else
|
||||
cmd->port = PORT_OTHER;
|
||||
} else
|
||||
cmd->port = PORT_OTHER;
|
||||
|
||||
if (p->mdio_addr >= 0) {
|
||||
cmd->phy_address = p->mdio_addr;
|
||||
cmd->transceiver = XCVR_EXTERNAL;
|
||||
cmd->mdio_support = p->port_type == FW_PORT_TYPE_BT_SGMII ?
|
||||
MDIO_SUPPORTS_C22 : MDIO_SUPPORTS_C45;
|
||||
} else {
|
||||
cmd->phy_address = 0; /* not really, but no better option */
|
||||
cmd->transceiver = XCVR_INTERNAL;
|
||||
cmd->mdio_support = 0;
|
||||
}
|
||||
|
||||
cmd->supported = t4vf_from_fw_linkcaps(p->port_type,
|
||||
p->link_cfg.supported);
|
||||
cmd->advertising = t4vf_from_fw_linkcaps(p->port_type,
|
||||
p->link_cfg.advertising);
|
||||
ethtool_cmd_speed_set(cmd,
|
||||
netif_carrier_ok(dev) ? pi->link_cfg.speed : -1);
|
||||
netif_carrier_ok(dev) ? p->link_cfg.speed : 0);
|
||||
cmd->duplex = DUPLEX_FULL;
|
||||
|
||||
cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
|
||||
cmd->phy_address = pi->port_id;
|
||||
cmd->transceiver = XCVR_EXTERNAL;
|
||||
cmd->autoneg = pi->link_cfg.autoneg;
|
||||
cmd->autoneg = p->link_cfg.autoneg;
|
||||
cmd->maxtxpkt = 0;
|
||||
cmd->maxrxpkt = 0;
|
||||
return 0;
|
||||
|
@ -230,7 +230,7 @@ struct adapter_params {
|
||||
|
||||
static inline bool is_10g_port(const struct link_config *lc)
|
||||
{
|
||||
return (lc->supported & SUPPORTED_10000baseT_Full) != 0;
|
||||
return (lc->supported & FW_PORT_CAP_SPEED_10G) != 0;
|
||||
}
|
||||
|
||||
static inline bool is_x_10g_port(const struct link_config *lc)
|
||||
|
@ -245,6 +245,10 @@ static int hash_mac_addr(const u8 *addr)
|
||||
return a & 0x3f;
|
||||
}
|
||||
|
||||
#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
|
||||
FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \
|
||||
FW_PORT_CAP_SPEED_100G | FW_PORT_CAP_ANEG)
|
||||
|
||||
/**
|
||||
* init_link_config - initialize a link's SW state
|
||||
* @lc: structure holding the link state
|
||||
@ -259,8 +263,8 @@ static void init_link_config(struct link_config *lc, unsigned int caps)
|
||||
lc->requested_speed = 0;
|
||||
lc->speed = 0;
|
||||
lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
|
||||
if (lc->supported & SUPPORTED_Autoneg) {
|
||||
lc->advertising = lc->supported;
|
||||
if (lc->supported & FW_PORT_CAP_ANEG) {
|
||||
lc->advertising = lc->supported & ADVERT_MASK;
|
||||
lc->autoneg = AUTONEG_ENABLE;
|
||||
lc->requested_fc |= PAUSE_AUTONEG;
|
||||
} else {
|
||||
@ -280,7 +284,6 @@ int t4vf_port_init(struct adapter *adapter, int pidx)
|
||||
struct fw_vi_cmd vi_cmd, vi_rpl;
|
||||
struct fw_port_cmd port_cmd, port_rpl;
|
||||
int v;
|
||||
u32 word;
|
||||
|
||||
/*
|
||||
* Execute a VI Read command to get our Virtual Interface information
|
||||
@ -319,19 +322,11 @@ int t4vf_port_init(struct adapter *adapter, int pidx)
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
v = 0;
|
||||
word = be16_to_cpu(port_rpl.u.info.pcap);
|
||||
if (word & FW_PORT_CAP_SPEED_100M)
|
||||
v |= SUPPORTED_100baseT_Full;
|
||||
if (word & FW_PORT_CAP_SPEED_1G)
|
||||
v |= SUPPORTED_1000baseT_Full;
|
||||
if (word & FW_PORT_CAP_SPEED_10G)
|
||||
v |= SUPPORTED_10000baseT_Full;
|
||||
if (word & FW_PORT_CAP_SPEED_40G)
|
||||
v |= SUPPORTED_40000baseSR4_Full;
|
||||
if (word & FW_PORT_CAP_ANEG)
|
||||
v |= SUPPORTED_Autoneg;
|
||||
init_link_config(&pi->link_cfg, v);
|
||||
v = be32_to_cpu(port_rpl.u.info.lstatus_to_modtype);
|
||||
pi->port_type = FW_PORT_CMD_PTYPE_G(v);
|
||||
pi->mod_type = FW_PORT_MOD_TYPE_NA;
|
||||
|
||||
init_link_config(&pi->link_cfg, be16_to_cpu(port_rpl.u.info.pcap));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1491,7 +1486,7 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
|
||||
*/
|
||||
const struct fw_port_cmd *port_cmd =
|
||||
(const struct fw_port_cmd *)rpl;
|
||||
u32 word;
|
||||
u32 stat, mod;
|
||||
int action, port_id, link_ok, speed, fc, pidx;
|
||||
|
||||
/*
|
||||
@ -1509,21 +1504,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
|
||||
port_id = FW_PORT_CMD_PORTID_G(
|
||||
be32_to_cpu(port_cmd->op_to_portid));
|
||||
|
||||
word = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype);
|
||||
link_ok = (word & FW_PORT_CMD_LSTATUS_F) != 0;
|
||||
stat = be32_to_cpu(port_cmd->u.info.lstatus_to_modtype);
|
||||
link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
|
||||
speed = 0;
|
||||
fc = 0;
|
||||
if (word & FW_PORT_CMD_RXPAUSE_F)
|
||||
if (stat & FW_PORT_CMD_RXPAUSE_F)
|
||||
fc |= PAUSE_RX;
|
||||
if (word & FW_PORT_CMD_TXPAUSE_F)
|
||||
if (stat & FW_PORT_CMD_TXPAUSE_F)
|
||||
fc |= PAUSE_TX;
|
||||
if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
||||
if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
|
||||
speed = 100;
|
||||
else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
||||
else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
|
||||
speed = 1000;
|
||||
else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
||||
else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
|
||||
speed = 10000;
|
||||
else if (word & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
||||
else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
|
||||
speed = 40000;
|
||||
|
||||
/*
|
||||
@ -1540,12 +1535,21 @@ int t4vf_handle_fw_rpl(struct adapter *adapter, const __be64 *rpl)
|
||||
continue;
|
||||
|
||||
lc = &pi->link_cfg;
|
||||
|
||||
mod = FW_PORT_CMD_MODTYPE_G(stat);
|
||||
if (mod != pi->mod_type) {
|
||||
pi->mod_type = mod;
|
||||
t4vf_os_portmod_changed(adapter, pidx);
|
||||
}
|
||||
|
||||
if (link_ok != lc->link_ok || speed != lc->speed ||
|
||||
fc != lc->fc) {
|
||||
/* something changed */
|
||||
lc->link_ok = link_ok;
|
||||
lc->speed = speed;
|
||||
lc->fc = fc;
|
||||
lc->supported =
|
||||
be16_to_cpu(port_cmd->u.info.pcap);
|
||||
t4vf_os_link_changed(adapter, pidx, link_ok);
|
||||
}
|
||||
}
|
||||
|
@ -1060,10 +1060,14 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
|
||||
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
|
||||
}
|
||||
|
||||
if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
|
||||
skb->csum = htons(checksum);
|
||||
skb->ip_summed = CHECKSUM_COMPLETE;
|
||||
}
|
||||
/* Hardware does not provide whole packet checksum. It only
|
||||
* provides pseudo checksum. Since hw validates the packet
|
||||
* checksum but not provide us the checksum value. use
|
||||
* CHECSUM_UNNECESSARY.
|
||||
*/
|
||||
if ((netdev->features & NETIF_F_RXCSUM) && tcp_udp_csum_ok &&
|
||||
ipv4_csum_ok)
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
|
||||
if (vlan_stripped)
|
||||
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci);
|
||||
|
@ -4459,9 +4459,11 @@ done:
|
||||
adapter->vxlan_port_count--;
|
||||
}
|
||||
|
||||
static bool be_gso_check(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_features_t be_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
return vxlan_gso_check(skb);
|
||||
return vxlan_features_check(skb, features);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4492,7 +4494,7 @@ static const struct net_device_ops be_netdev_ops = {
|
||||
#ifdef CONFIG_BE2NET_VXLAN
|
||||
.ndo_add_vxlan_port = be_add_vxlan_port,
|
||||
.ndo_del_vxlan_port = be_del_vxlan_port,
|
||||
.ndo_gso_check = be_gso_check,
|
||||
.ndo_features_check = be_features_check,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2365,9 +2365,11 @@ static void mlx4_en_del_vxlan_port(struct net_device *dev,
|
||||
queue_work(priv->mdev->workqueue, &priv->vxlan_del_task);
|
||||
}
|
||||
|
||||
static bool mlx4_en_gso_check(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
return vxlan_gso_check(skb);
|
||||
return vxlan_features_check(skb, features);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2400,7 +2402,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
|
||||
#ifdef CONFIG_MLX4_EN_VXLAN
|
||||
.ndo_add_vxlan_port = mlx4_en_add_vxlan_port,
|
||||
.ndo_del_vxlan_port = mlx4_en_del_vxlan_port,
|
||||
.ndo_gso_check = mlx4_en_gso_check,
|
||||
.ndo_features_check = mlx4_en_features_check,
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -2434,7 +2436,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
|
||||
#ifdef CONFIG_MLX4_EN_VXLAN
|
||||
.ndo_add_vxlan_port = mlx4_en_add_vxlan_port,
|
||||
.ndo_del_vxlan_port = mlx4_en_del_vxlan_port,
|
||||
.ndo_gso_check = mlx4_en_gso_check,
|
||||
.ndo_features_check = mlx4_en_features_check,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -962,7 +962,17 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
tx_desc->ctrl.owner_opcode = op_own;
|
||||
if (send_doorbell) {
|
||||
wmb();
|
||||
iowrite32(ring->doorbell_qpn,
|
||||
/* Since there is no iowrite*_native() that writes the
|
||||
* value as is, without byteswapping - using the one
|
||||
* the doesn't do byteswapping in the relevant arch
|
||||
* endianness.
|
||||
*/
|
||||
#if defined(__LITTLE_ENDIAN)
|
||||
iowrite32(
|
||||
#else
|
||||
iowrite32be(
|
||||
#endif
|
||||
ring->doorbell_qpn,
|
||||
ring->bf.uar->map + MLX4_SEND_DOORBELL);
|
||||
} else {
|
||||
ring->xmit_more++;
|
||||
|
@ -2303,12 +2303,6 @@ static inline int port_chk_force_flow_ctrl(struct ksz_hw *hw, int p)
|
||||
|
||||
/* Spanning Tree */
|
||||
|
||||
static inline void port_cfg_dis_learn(struct ksz_hw *hw, int p, int set)
|
||||
{
|
||||
port_cfg(hw, p,
|
||||
KS8842_PORT_CTRL_2_OFFSET, PORT_LEARN_DISABLE, set);
|
||||
}
|
||||
|
||||
static inline void port_cfg_rx(struct ksz_hw *hw, int p, int set)
|
||||
{
|
||||
port_cfg(hw, p,
|
||||
|
@ -505,9 +505,11 @@ static void qlcnic_del_vxlan_port(struct net_device *netdev,
|
||||
adapter->flags |= QLCNIC_DEL_VXLAN_PORT;
|
||||
}
|
||||
|
||||
static bool qlcnic_gso_check(struct sk_buff *skb, struct net_device *dev)
|
||||
static netdev_features_t qlcnic_features_check(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features)
|
||||
{
|
||||
return vxlan_gso_check(skb);
|
||||
return vxlan_features_check(skb, features);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -532,7 +534,7 @@ static const struct net_device_ops qlcnic_netdev_ops = {
|
||||
#ifdef CONFIG_QLCNIC_VXLAN
|
||||
.ndo_add_vxlan_port = qlcnic_add_vxlan_port,
|
||||
.ndo_del_vxlan_port = qlcnic_del_vxlan_port,
|
||||
.ndo_gso_check = qlcnic_gso_check,
|
||||
.ndo_features_check = qlcnic_features_check,
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
.ndo_poll_controller = qlcnic_poll_controller,
|
||||
|
@ -787,10 +787,10 @@ static struct net_device *rtl8139_init_board(struct pci_dev *pdev)
|
||||
if (rc)
|
||||
goto err_out;
|
||||
|
||||
disable_dev_on_err = 1;
|
||||
rc = pci_request_regions (pdev, DRV_NAME);
|
||||
if (rc)
|
||||
goto err_out;
|
||||
disable_dev_on_err = 1;
|
||||
|
||||
pci_set_master (pdev);
|
||||
|
||||
@ -1110,6 +1110,7 @@ static int rtl8139_init_one(struct pci_dev *pdev,
|
||||
return 0;
|
||||
|
||||
err_out:
|
||||
netif_napi_del(&tp->napi);
|
||||
__rtl8139_cleanup_dev (dev);
|
||||
pci_disable_device (pdev);
|
||||
return i;
|
||||
@ -1124,6 +1125,7 @@ static void rtl8139_remove_one(struct pci_dev *pdev)
|
||||
assert (dev != NULL);
|
||||
|
||||
cancel_delayed_work_sync(&tp->thread);
|
||||
netif_napi_del(&tp->napi);
|
||||
|
||||
unregister_netdev (dev);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1671,7 +1671,7 @@ static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
|
||||
* 0 on success and an appropriate (-)ve integer as defined in errno.h
|
||||
* file on failure.
|
||||
*/
|
||||
static int stmmac_hw_setup(struct net_device *dev)
|
||||
static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
|
||||
{
|
||||
struct stmmac_priv *priv = netdev_priv(dev);
|
||||
int ret;
|
||||
@ -1708,9 +1708,11 @@ static int stmmac_hw_setup(struct net_device *dev)
|
||||
|
||||
stmmac_mmc_setup(priv);
|
||||
|
||||
ret = stmmac_init_ptp(priv);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
pr_warn("%s: failed PTP initialisation\n", __func__);
|
||||
if (init_ptp) {
|
||||
ret = stmmac_init_ptp(priv);
|
||||
if (ret && ret != -EOPNOTSUPP)
|
||||
pr_warn("%s: failed PTP initialisation\n", __func__);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ret = stmmac_init_fs(dev);
|
||||
@ -1787,7 +1789,7 @@ static int stmmac_open(struct net_device *dev)
|
||||
goto init_error;
|
||||
}
|
||||
|
||||
ret = stmmac_hw_setup(dev);
|
||||
ret = stmmac_hw_setup(dev, true);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: Hw setup failed\n", __func__);
|
||||
goto init_error;
|
||||
@ -3036,7 +3038,7 @@ int stmmac_resume(struct net_device *ndev)
|
||||
netif_device_attach(ndev);
|
||||
|
||||
init_dma_desc_rings(ndev, GFP_ATOMIC);
|
||||
stmmac_hw_setup(ndev);
|
||||
stmmac_hw_setup(ndev, false);
|
||||
stmmac_init_tx_coalesce(priv);
|
||||
|
||||
napi_enable(&priv->napi);
|
||||
|
@ -430,7 +430,6 @@ static struct platform_driver stmmac_pltfr_driver = {
|
||||
.remove = stmmac_pltfr_remove,
|
||||
.driver = {
|
||||
.name = STMMAC_RESOURCE_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.pm = &stmmac_pltfr_pm_ops,
|
||||
.of_match_table = of_match_ptr(stmmac_dt_ids),
|
||||
},
|
||||
|
@ -1201,6 +1201,7 @@ static int vnet_handle_offloads(struct vnet_port *port, struct sk_buff *skb)
|
||||
segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO);
|
||||
if (IS_ERR(segs)) {
|
||||
dev->stats.tx_dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -388,7 +388,6 @@ struct axidma_bd {
|
||||
* @dma_err_tasklet: Tasklet structure to process Axi DMA errors
|
||||
* @tx_irq: Axidma TX IRQ number
|
||||
* @rx_irq: Axidma RX IRQ number
|
||||
* @temac_type: axienet type to identify between soft and hard temac
|
||||
* @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X
|
||||
* @options: AxiEthernet option word
|
||||
* @last_link: Phy link state in which the PHY was negotiated earlier
|
||||
@ -431,7 +430,6 @@ struct axienet_local {
|
||||
|
||||
int tx_irq;
|
||||
int rx_irq;
|
||||
u32 temac_type;
|
||||
u32 phy_type;
|
||||
|
||||
u32 options; /* Current options word */
|
||||
|
@ -1555,10 +1555,6 @@ static int axienet_of_probe(struct platform_device *op)
|
||||
if ((be32_to_cpup(p)) >= 0x4000)
|
||||
lp->jumbo_support = 1;
|
||||
}
|
||||
p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type",
|
||||
NULL);
|
||||
if (p)
|
||||
lp->temac_type = be32_to_cpup(p);
|
||||
p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL);
|
||||
if (p)
|
||||
lp->phy_type = be32_to_cpup(p);
|
||||
|
@ -590,6 +590,7 @@ struct nvsp_message {
|
||||
|
||||
|
||||
#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
|
||||
#define NETVSC_SEND_BUFFER_ID 0
|
||||
|
||||
#define NETVSC_PACKET_SIZE 4096
|
||||
|
||||
|
@ -161,8 +161,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device)
|
||||
|
||||
/* Deal with the send buffer we may have setup.
|
||||
* If we got a send section size, it means we received a
|
||||
* SendsendBufferComplete msg (ie sent
|
||||
* NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
|
||||
* NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE msg (ie sent
|
||||
* NVSP_MSG1_TYPE_SEND_SEND_BUF msg) therefore, we need
|
||||
* to send a revoke msg here
|
||||
*/
|
||||
if (net_device->send_section_size) {
|
||||
@ -172,7 +172,8 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device)
|
||||
|
||||
revoke_packet->hdr.msg_type =
|
||||
NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
|
||||
revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0;
|
||||
revoke_packet->msg.v1_msg.revoke_send_buf.id =
|
||||
NETVSC_SEND_BUFFER_ID;
|
||||
|
||||
ret = vmbus_sendpacket(net_device->dev->channel,
|
||||
revoke_packet,
|
||||
@ -204,7 +205,7 @@ static int netvsc_destroy_buf(struct netvsc_device *net_device)
|
||||
net_device->send_buf_gpadl_handle = 0;
|
||||
}
|
||||
if (net_device->send_buf) {
|
||||
/* Free up the receive buffer */
|
||||
/* Free up the send buffer */
|
||||
vfree(net_device->send_buf);
|
||||
net_device->send_buf = NULL;
|
||||
}
|
||||
@ -339,9 +340,9 @@ static int netvsc_init_buf(struct hv_device *device)
|
||||
init_packet = &net_device->channel_init_pkt;
|
||||
memset(init_packet, 0, sizeof(struct nvsp_message));
|
||||
init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF;
|
||||
init_packet->msg.v1_msg.send_recv_buf.gpadl_handle =
|
||||
init_packet->msg.v1_msg.send_send_buf.gpadl_handle =
|
||||
net_device->send_buf_gpadl_handle;
|
||||
init_packet->msg.v1_msg.send_recv_buf.id = 0;
|
||||
init_packet->msg.v1_msg.send_send_buf.id = NETVSC_SEND_BUFFER_ID;
|
||||
|
||||
/* Send the gpadl notification request */
|
||||
ret = vmbus_sendpacket(device->channel, init_packet,
|
||||
@ -364,7 +365,7 @@ static int netvsc_init_buf(struct hv_device *device)
|
||||
netdev_err(ndev, "Unable to complete send buffer "
|
||||
"initialization with NetVsp - status %d\n",
|
||||
init_packet->msg.v1_msg.
|
||||
send_recv_buf_complete.status);
|
||||
send_send_buf_complete.status);
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ struct kszphy_priv {
|
||||
|
||||
static const struct kszphy_type ksz8021_type = {
|
||||
.led_mode_reg = MII_KSZPHY_CTRL_2,
|
||||
.has_broadcast_disable = true,
|
||||
.has_rmii_ref_clk_sel = true,
|
||||
};
|
||||
|
||||
@ -258,19 +259,6 @@ static int kszphy_config_init(struct phy_device *phydev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz8021_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = kszphy_config_init(phydev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = kszphy_broadcast_disable(phydev);
|
||||
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
static int ksz9021_load_values_from_of(struct phy_device *phydev,
|
||||
struct device_node *of_node, u16 reg,
|
||||
char *field1, char *field2,
|
||||
@ -584,7 +572,7 @@ static struct phy_driver ksphy_driver[] = {
|
||||
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
|
||||
.driver_data = &ksz8021_type,
|
||||
.probe = kszphy_probe,
|
||||
.config_init = ksz8021_config_init,
|
||||
.config_init = kszphy_config_init,
|
||||
.config_aneg = genphy_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = kszphy_ack_interrupt,
|
||||
@ -601,7 +589,7 @@ static struct phy_driver ksphy_driver[] = {
|
||||
.flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
|
||||
.driver_data = &ksz8021_type,
|
||||
.probe = kszphy_probe,
|
||||
.config_init = ksz8021_config_init,
|
||||
.config_init = kszphy_config_init,
|
||||
.config_aneg = genphy_config_aneg,
|
||||
.read_status = genphy_read_status,
|
||||
.ack_interrupt = kszphy_ack_interrupt,
|
||||
|
@ -760,7 +760,6 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
|
||||
container_of(napi, struct receive_queue, napi);
|
||||
unsigned int r, received = 0;
|
||||
|
||||
again:
|
||||
received += virtnet_receive(rq, budget - received);
|
||||
|
||||
/* Out of packets? */
|
||||
@ -771,7 +770,6 @@ again:
|
||||
napi_schedule_prep(napi)) {
|
||||
virtqueue_disable_cb(rq->vq);
|
||||
__napi_schedule(napi);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1579,8 +1579,10 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
|
||||
bool udp_sum = !udp_get_no_check6_tx(vs->sock->sk);
|
||||
|
||||
skb = udp_tunnel_handle_offloads(skb, udp_sum);
|
||||
if (IS_ERR(skb))
|
||||
return -EINVAL;
|
||||
if (IS_ERR(skb)) {
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
skb_scrub_packet(skb, xnet);
|
||||
|
||||
@ -1590,12 +1592,16 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
|
||||
|
||||
/* Need space for new headers (invalidates iph ptr) */
|
||||
err = skb_cow_head(skb, min_headroom);
|
||||
if (unlikely(err))
|
||||
return err;
|
||||
if (unlikely(err)) {
|
||||
kfree_skb(skb);
|
||||
goto err;
|
||||
}
|
||||
|
||||
skb = vlan_hwaccel_push_inside(skb);
|
||||
if (WARN_ON(!skb))
|
||||
return -ENOMEM;
|
||||
if (WARN_ON(!skb)) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
|
||||
vxh->vx_flags = htonl(VXLAN_FLAGS);
|
||||
@ -1606,6 +1612,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
|
||||
udp_tunnel6_xmit_skb(vs->sock, dst, skb, dev, saddr, daddr, prio,
|
||||
ttl, src_port, dst_port);
|
||||
return 0;
|
||||
err:
|
||||
dst_release(dst);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1621,7 +1630,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
|
||||
|
||||
skb = udp_tunnel_handle_offloads(skb, udp_sum);
|
||||
if (IS_ERR(skb))
|
||||
return -EINVAL;
|
||||
return PTR_ERR(skb);
|
||||
|
||||
min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
|
||||
+ VXLAN_HLEN + sizeof(struct iphdr)
|
||||
@ -1629,8 +1638,10 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
|
||||
|
||||
/* Need space for new headers (invalidates iph ptr) */
|
||||
err = skb_cow_head(skb, min_headroom);
|
||||
if (unlikely(err))
|
||||
if (unlikely(err)) {
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
skb = vlan_hwaccel_push_inside(skb);
|
||||
if (WARN_ON(!skb))
|
||||
@ -1776,9 +1787,12 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
|
||||
tos, ttl, df, src_port, dst_port,
|
||||
htonl(vni << 8),
|
||||
!net_eq(vxlan->net, dev_net(vxlan->dev)));
|
||||
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
/* skb is already freed. */
|
||||
skb = NULL;
|
||||
goto rt_tx_error;
|
||||
}
|
||||
|
||||
iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
} else {
|
||||
|
@ -1070,7 +1070,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
*/
|
||||
if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
|
||||
((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
|
||||
(sdiodev->pdata->oob_irq_supported)))
|
||||
(sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
|
||||
bus_if->wowl_supported = true;
|
||||
#endif
|
||||
|
||||
@ -1167,7 +1167,7 @@ static int brcmf_ops_sdio_resume(struct device *dev)
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
if (sdiodev->pdata->oob_irq_supported)
|
||||
if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)
|
||||
disable_irq_wake(sdiodev->pdata->oob_irq_nr);
|
||||
brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
|
||||
atomic_set(&sdiodev->suspend, false);
|
||||
|
@ -65,7 +65,8 @@ config IPW2100_DEBUG
|
||||
|
||||
config IPW2200
|
||||
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
|
||||
depends on PCI && CFG80211 && CFG80211_WEXT
|
||||
depends on PCI && CFG80211
|
||||
select CFG80211_WEXT
|
||||
select WIRELESS_EXT
|
||||
select WEXT_SPY
|
||||
select WEXT_PRIV
|
||||
|
@ -1323,10 +1323,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
|
||||
try_again:
|
||||
/* try next, if any */
|
||||
kfree(pieces);
|
||||
release_firmware(ucode_raw);
|
||||
if (iwl_request_firmware(drv, false))
|
||||
goto out_unbind;
|
||||
kfree(pieces);
|
||||
return;
|
||||
|
||||
out_free_fw:
|
||||
|
@ -310,6 +310,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
|
||||
#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
|
||||
|
||||
#define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28
|
||||
#define FH_MEM_TB_MAX_LENGTH (0x00020000)
|
||||
|
||||
/* TFDB Area - TFDs buffer table */
|
||||
#define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK (0xFFFFFFFF)
|
||||
|
@ -1004,8 +1004,13 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
|
||||
{
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* disallow low power states when the FW is down */
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
/*
|
||||
* Disallow low power states when the FW is down by taking
|
||||
* the UCODE_DOWN ref. in case of ongoing hw restart the
|
||||
* ref is already taken, so don't take it again.
|
||||
*/
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
/* async_handlers_wk is now blocked */
|
||||
|
||||
@ -1023,6 +1028,12 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
|
||||
/* the fw is stopped, the aux sta is dead: clean up driver state */
|
||||
iwl_mvm_del_aux_sta(mvm);
|
||||
|
||||
/*
|
||||
* Clear IN_HW_RESTART flag when stopping the hw (as restart_complete()
|
||||
* won't be called in this case).
|
||||
*/
|
||||
clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
|
||||
mvm->ucode_loaded = false;
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
|
||||
|
||||
/* 3165 Series */
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)},
|
||||
{IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)},
|
||||
|
||||
/* 7265 Series */
|
||||
{IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
|
||||
|
@ -614,7 +614,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
|
||||
{
|
||||
u8 *v_addr;
|
||||
dma_addr_t p_addr;
|
||||
u32 offset, chunk_sz = section->len;
|
||||
u32 offset, chunk_sz = min_t(u32, FH_MEM_TB_MAX_LENGTH, section->len);
|
||||
int ret = 0;
|
||||
|
||||
IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
|
||||
@ -1012,16 +1012,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_pcie_apm_stop(trans);
|
||||
|
||||
/* Upon stop, the APM issues an interrupt if HW RF kill is set.
|
||||
* Clean again the interrupt here
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
||||
udelay(20);
|
||||
|
||||
/*
|
||||
* Upon stop, the APM issues an interrupt if HW RF kill is set.
|
||||
* This is a bug in certain verions of the hardware.
|
||||
* Certain devices also keep sending HW RF kill interrupt all
|
||||
* the time, unless the interrupt is ACKed even if the interrupt
|
||||
* should be masked. Re-ACK all the interrupts here.
|
||||
*/
|
||||
spin_lock(&trans_pcie->irq_lock);
|
||||
iwl_disable_interrupts(trans);
|
||||
spin_unlock(&trans_pcie->irq_lock);
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
|
||||
udelay(20);
|
||||
|
||||
/* clear all status bits */
|
||||
clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
|
||||
|
@ -1012,12 +1012,15 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
|
||||
* Callback to use for xmit over the accelerated station. This
|
||||
* is used in place of ndo_start_xmit on accelerated net
|
||||
* devices.
|
||||
* bool (*ndo_gso_check) (struct sk_buff *skb,
|
||||
* struct net_device *dev);
|
||||
* netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
|
||||
* struct net_device *dev
|
||||
* netdev_features_t features);
|
||||
* Called by core transmit path to determine if device is capable of
|
||||
* performing GSO on a packet. The device returns true if it is
|
||||
* able to GSO the packet, false otherwise. If the return value is
|
||||
* false the stack will do software GSO.
|
||||
* performing offload operations on a given packet. This is to give
|
||||
* the device an opportunity to implement any restrictions that cannot
|
||||
* be otherwise expressed by feature flags. The check is called with
|
||||
* the set of features that the stack has calculated and it returns
|
||||
* those the driver believes to be appropriate.
|
||||
*
|
||||
* int (*ndo_switch_parent_id_get)(struct net_device *dev,
|
||||
* struct netdev_phys_item_id *psid);
|
||||
@ -1178,8 +1181,9 @@ struct net_device_ops {
|
||||
struct net_device *dev,
|
||||
void *priv);
|
||||
int (*ndo_get_lock_subclass)(struct net_device *dev);
|
||||
bool (*ndo_gso_check) (struct sk_buff *skb,
|
||||
struct net_device *dev);
|
||||
netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
netdev_features_t features);
|
||||
#ifdef CONFIG_NET_SWITCHDEV
|
||||
int (*ndo_switch_parent_id_get)(struct net_device *dev,
|
||||
struct netdev_phys_item_id *psid);
|
||||
@ -3611,8 +3615,6 @@ static inline bool netif_needs_gso(struct net_device *dev, struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
{
|
||||
return skb_is_gso(skb) && (!skb_gso_ok(skb, features) ||
|
||||
(dev->netdev_ops->ndo_gso_check &&
|
||||
!dev->netdev_ops->ndo_gso_check(skb, dev)) ||
|
||||
unlikely((skb->ip_summed != CHECKSUM_PARTIAL) &&
|
||||
(skb->ip_summed != CHECKSUM_UNNECESSARY)));
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ struct netlink_kernel_cfg {
|
||||
unsigned int flags;
|
||||
void (*input)(struct sk_buff *skb);
|
||||
struct mutex *cb_mutex;
|
||||
int (*bind)(int group);
|
||||
void (*unbind)(int group);
|
||||
int (*bind)(struct net *net, int group);
|
||||
void (*unbind)(struct net *net, int group);
|
||||
bool (*compare)(struct net *net, struct sock *sk);
|
||||
};
|
||||
|
||||
|
@ -31,6 +31,9 @@ struct genl_info;
|
||||
* do additional, common, filtering and return an error
|
||||
* @post_doit: called after an operation's doit callback, it may
|
||||
* undo operations done by pre_doit, for example release locks
|
||||
* @mcast_bind: a socket bound to the given multicast group (which
|
||||
* is given as the offset into the groups array)
|
||||
* @mcast_unbind: a socket was unbound from the given multicast group
|
||||
* @attrbuf: buffer to store parsed attributes
|
||||
* @family_list: family list
|
||||
* @mcgrps: multicast groups used by this family (private)
|
||||
@ -53,6 +56,8 @@ struct genl_family {
|
||||
void (*post_doit)(const struct genl_ops *ops,
|
||||
struct sk_buff *skb,
|
||||
struct genl_info *info);
|
||||
int (*mcast_bind)(struct net *net, int group);
|
||||
void (*mcast_unbind)(struct net *net, int group);
|
||||
struct nlattr ** attrbuf; /* private */
|
||||
const struct genl_ops * ops; /* private */
|
||||
const struct genl_multicast_group *mcgrps; /* private */
|
||||
@ -395,11 +400,11 @@ static inline int genl_set_err(struct genl_family *family, struct net *net,
|
||||
}
|
||||
|
||||
static inline int genl_has_listeners(struct genl_family *family,
|
||||
struct sock *sk, unsigned int group)
|
||||
struct net *net, unsigned int group)
|
||||
{
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return netlink_has_listeners(sk, group);
|
||||
return netlink_has_listeners(net->genl_sock, group);
|
||||
}
|
||||
#endif /* __NET_GENERIC_NETLINK_H */
|
||||
|
@ -190,7 +190,6 @@ struct neigh_hash_table {
|
||||
|
||||
|
||||
struct neigh_table {
|
||||
struct neigh_table *next;
|
||||
int family;
|
||||
int entry_size;
|
||||
int key_len;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#ifndef __NET_VXLAN_H
|
||||
#define __NET_VXLAN_H 1
|
||||
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/udp.h>
|
||||
@ -51,16 +54,33 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
|
||||
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
|
||||
__be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
|
||||
|
||||
static inline bool vxlan_gso_check(struct sk_buff *skb)
|
||||
static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
|
||||
netdev_features_t features)
|
||||
{
|
||||
if ((skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) &&
|
||||
u8 l4_hdr = 0;
|
||||
|
||||
if (!skb->encapsulation)
|
||||
return features;
|
||||
|
||||
switch (vlan_get_protocol(skb)) {
|
||||
case htons(ETH_P_IP):
|
||||
l4_hdr = ip_hdr(skb)->protocol;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
l4_hdr = ipv6_hdr(skb)->nexthdr;
|
||||
break;
|
||||
default:
|
||||
return features;;
|
||||
}
|
||||
|
||||
if ((l4_hdr == IPPROTO_UDP) &&
|
||||
(skb->inner_protocol_type != ENCAP_TYPE_ETHER ||
|
||||
skb->inner_protocol != htons(ETH_P_TEB) ||
|
||||
(skb_inner_mac_header(skb) - skb_transport_header(skb) !=
|
||||
sizeof(struct udphdr) + sizeof(struct vxlanhdr))))
|
||||
return false;
|
||||
return features & ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK);
|
||||
|
||||
return true;
|
||||
return features;
|
||||
}
|
||||
|
||||
/* IP header + UDP + VXLAN + Ethernet header */
|
||||
|
@ -149,7 +149,7 @@ struct in6_flowlabel_req {
|
||||
/*
|
||||
* IPV6 socket options
|
||||
*/
|
||||
|
||||
#if __UAPI_DEF_IPV6_OPTIONS
|
||||
#define IPV6_ADDRFORM 1
|
||||
#define IPV6_2292PKTINFO 2
|
||||
#define IPV6_2292HOPOPTS 3
|
||||
@ -196,6 +196,7 @@ struct in6_flowlabel_req {
|
||||
|
||||
#define IPV6_IPSEC_POLICY 34
|
||||
#define IPV6_XFRM_POLICY 35
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Multicast:
|
||||
|
@ -69,6 +69,7 @@
|
||||
#define __UAPI_DEF_SOCKADDR_IN6 0
|
||||
#define __UAPI_DEF_IPV6_MREQ 0
|
||||
#define __UAPI_DEF_IPPROTO_V6 0
|
||||
#define __UAPI_DEF_IPV6_OPTIONS 0
|
||||
|
||||
#else
|
||||
|
||||
@ -82,6 +83,7 @@
|
||||
#define __UAPI_DEF_SOCKADDR_IN6 1
|
||||
#define __UAPI_DEF_IPV6_MREQ 1
|
||||
#define __UAPI_DEF_IPPROTO_V6 1
|
||||
#define __UAPI_DEF_IPV6_OPTIONS 1
|
||||
|
||||
#endif /* _NETINET_IN_H */
|
||||
|
||||
@ -103,6 +105,7 @@
|
||||
#define __UAPI_DEF_SOCKADDR_IN6 1
|
||||
#define __UAPI_DEF_IPV6_MREQ 1
|
||||
#define __UAPI_DEF_IPPROTO_V6 1
|
||||
#define __UAPI_DEF_IPV6_OPTIONS 1
|
||||
|
||||
/* Definitions for xattr.h */
|
||||
#define __UAPI_DEF_XATTR 1
|
||||
|
@ -1100,7 +1100,7 @@ static void audit_receive(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* Run custom bind function on netlink socket group connect or bind requests. */
|
||||
static int audit_bind(int group)
|
||||
static int audit_bind(struct net *net, int group)
|
||||
{
|
||||
if (!capable(CAP_AUDIT_READ))
|
||||
return -EPERM;
|
||||
|
@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb)
|
||||
kfree(entry);
|
||||
|
||||
/* Make room for the rest of the fragments. */
|
||||
if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) {
|
||||
if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {
|
||||
kfree_skb(skb_out);
|
||||
skb_out = NULL;
|
||||
goto free;
|
||||
@ -434,7 +434,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
|
||||
* fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
|
||||
*/
|
||||
mtu = min_t(unsigned, mtu, BATADV_FRAG_MAX_FRAG_SIZE);
|
||||
max_fragment_size = (mtu - header_size - ETH_HLEN);
|
||||
max_fragment_size = mtu - header_size;
|
||||
max_packet_size = max_fragment_size * BATADV_FRAG_MAX_FRAGMENTS;
|
||||
|
||||
/* Don't even try to fragment, if we need more than 16 fragments */
|
||||
|
@ -810,7 +810,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
|
||||
goto out;
|
||||
|
||||
gw_node = batadv_gw_node_get(bat_priv, orig_dst_node);
|
||||
if (!gw_node->bandwidth_down == 0)
|
||||
if (!gw_node)
|
||||
goto out;
|
||||
|
||||
switch (atomic_read(&bat_priv->gw_mode)) {
|
||||
|
@ -390,7 +390,6 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
|
||||
|
||||
drop:
|
||||
dev->stats.rx_dropped++;
|
||||
kfree_skb(skb);
|
||||
return NET_RX_DROP;
|
||||
}
|
||||
|
||||
|
@ -533,6 +533,9 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
if (!l2cap_is_socket(sock))
|
||||
return -EBADFD;
|
||||
|
||||
baswap((void *) dst, &l2cap_pi(sock->sk)->chan->dst);
|
||||
baswap((void *) src, &l2cap_pi(sock->sk)->chan->src);
|
||||
|
||||
|
@ -334,6 +334,9 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
|
||||
|
||||
BT_DBG("");
|
||||
|
||||
if (!l2cap_is_socket(sock))
|
||||
return -EBADFD;
|
||||
|
||||
session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL);
|
||||
if (!session)
|
||||
return -ENOMEM;
|
||||
|
@ -242,7 +242,8 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
if (rp->status)
|
||||
return;
|
||||
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags))
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
|
||||
test_bit(HCI_CONFIG, &hdev->dev_flags))
|
||||
memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
|
||||
}
|
||||
|
||||
@ -509,7 +510,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
if (rp->status)
|
||||
return;
|
||||
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
|
||||
test_bit(HCI_CONFIG, &hdev->dev_flags)) {
|
||||
hdev->hci_ver = rp->hci_ver;
|
||||
hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
|
||||
hdev->lmp_ver = rp->lmp_ver;
|
||||
@ -528,7 +530,8 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
|
||||
if (rp->status)
|
||||
return;
|
||||
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags))
|
||||
if (test_bit(HCI_SETUP, &hdev->dev_flags) ||
|
||||
test_bit(HCI_CONFIG, &hdev->dev_flags))
|
||||
memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
|
||||
}
|
||||
|
||||
@ -2194,7 +2197,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
|
||||
/* Require HCI_CONNECTABLE or a whitelist entry to accept the
|
||||
* connection. These features are only touched through mgmt so
|
||||
* only do the checks if HCI_MGMT is set.
|
||||
*/
|
||||
if (test_bit(HCI_MGMT, &hdev->dev_flags) &&
|
||||
!test_bit(HCI_CONNECTABLE, &hdev->dev_flags) &&
|
||||
!hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
|
||||
BDADDR_BREDR)) {
|
||||
hci_reject_conn(hdev, &ev->bdaddr);
|
||||
|
@ -1314,13 +1314,14 @@ int hidp_connection_add(struct hidp_connadd_req *req,
|
||||
{
|
||||
struct hidp_session *session;
|
||||
struct l2cap_conn *conn;
|
||||
struct l2cap_chan *chan = l2cap_pi(ctrl_sock->sk)->chan;
|
||||
struct l2cap_chan *chan;
|
||||
int ret;
|
||||
|
||||
ret = hidp_verify_sockets(ctrl_sock, intr_sock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
chan = l2cap_pi(ctrl_sock->sk)->chan;
|
||||
conn = NULL;
|
||||
l2cap_chan_lock(chan);
|
||||
if (chan->conn)
|
||||
|
175
net/core/dev.c
175
net/core/dev.c
@ -1694,6 +1694,7 @@ int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
|
||||
|
||||
skb_scrub_packet(skb, true);
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2522,7 +2523,7 @@ static int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
|
||||
/* If MPLS offload request, verify we are testing hardware MPLS features
|
||||
* instead of standard features for the netdev.
|
||||
*/
|
||||
#ifdef CONFIG_NET_MPLS_GSO
|
||||
#if IS_ENABLED(CONFIG_NET_MPLS_GSO)
|
||||
static netdev_features_t net_mpls_features(struct sk_buff *skb,
|
||||
netdev_features_t features,
|
||||
__be16 type)
|
||||
@ -2562,7 +2563,7 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
|
||||
|
||||
netdev_features_t netif_skb_features(struct sk_buff *skb)
|
||||
{
|
||||
const struct net_device *dev = skb->dev;
|
||||
struct net_device *dev = skb->dev;
|
||||
netdev_features_t features = dev->features;
|
||||
u16 gso_segs = skb_shinfo(skb)->gso_segs;
|
||||
__be16 protocol = skb->protocol;
|
||||
@ -2570,11 +2571,21 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
|
||||
if (gso_segs > dev->gso_max_segs || gso_segs < dev->gso_min_segs)
|
||||
features &= ~NETIF_F_GSO_MASK;
|
||||
|
||||
if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) {
|
||||
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
|
||||
protocol = veh->h_vlan_encapsulated_proto;
|
||||
} else if (!vlan_tx_tag_present(skb)) {
|
||||
return harmonize_features(skb, features);
|
||||
/* If encapsulation offload request, verify we are testing
|
||||
* hardware encapsulation features instead of standard
|
||||
* features for the netdev
|
||||
*/
|
||||
if (skb->encapsulation)
|
||||
features &= dev->hw_enc_features;
|
||||
|
||||
if (!vlan_tx_tag_present(skb)) {
|
||||
if (unlikely(protocol == htons(ETH_P_8021Q) ||
|
||||
protocol == htons(ETH_P_8021AD))) {
|
||||
struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data;
|
||||
protocol = veh->h_vlan_encapsulated_proto;
|
||||
} else {
|
||||
goto finalize;
|
||||
}
|
||||
}
|
||||
|
||||
features = netdev_intersect_features(features,
|
||||
@ -2591,6 +2602,11 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
|
||||
NETIF_F_HW_VLAN_CTAG_TX |
|
||||
NETIF_F_HW_VLAN_STAG_TX);
|
||||
|
||||
finalize:
|
||||
if (dev->netdev_ops->ndo_features_check)
|
||||
features &= dev->netdev_ops->ndo_features_check(skb, dev,
|
||||
features);
|
||||
|
||||
return harmonize_features(skb, features);
|
||||
}
|
||||
EXPORT_SYMBOL(netif_skb_features);
|
||||
@ -2661,19 +2677,12 @@ static struct sk_buff *validate_xmit_skb(struct sk_buff *skb, struct net_device
|
||||
if (unlikely(!skb))
|
||||
goto out_null;
|
||||
|
||||
/* If encapsulation offload request, verify we are testing
|
||||
* hardware encapsulation features instead of standard
|
||||
* features for the netdev
|
||||
*/
|
||||
if (skb->encapsulation)
|
||||
features &= dev->hw_enc_features;
|
||||
|
||||
if (netif_needs_gso(dev, skb, features)) {
|
||||
struct sk_buff *segs;
|
||||
|
||||
segs = skb_gso_segment(skb, features);
|
||||
if (IS_ERR(segs)) {
|
||||
segs = NULL;
|
||||
goto out_kfree_skb;
|
||||
} else if (segs) {
|
||||
consume_skb(skb);
|
||||
skb = segs;
|
||||
@ -4557,6 +4566,68 @@ void netif_napi_del(struct napi_struct *napi)
|
||||
}
|
||||
EXPORT_SYMBOL(netif_napi_del);
|
||||
|
||||
static int napi_poll(struct napi_struct *n, struct list_head *repoll)
|
||||
{
|
||||
void *have;
|
||||
int work, weight;
|
||||
|
||||
list_del_init(&n->poll_list);
|
||||
|
||||
have = netpoll_poll_lock(n);
|
||||
|
||||
weight = n->weight;
|
||||
|
||||
/* This NAPI_STATE_SCHED test is for avoiding a race
|
||||
* with netpoll's poll_napi(). Only the entity which
|
||||
* obtains the lock and sees NAPI_STATE_SCHED set will
|
||||
* actually make the ->poll() call. Therefore we avoid
|
||||
* accidentally calling ->poll() when NAPI is not scheduled.
|
||||
*/
|
||||
work = 0;
|
||||
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
|
||||
work = n->poll(n, weight);
|
||||
trace_napi_poll(n);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(work > weight);
|
||||
|
||||
if (likely(work < weight))
|
||||
goto out_unlock;
|
||||
|
||||
/* Drivers must not modify the NAPI state if they
|
||||
* consume the entire weight. In such cases this code
|
||||
* still "owns" the NAPI instance and therefore can
|
||||
* move the instance around on the list at-will.
|
||||
*/
|
||||
if (unlikely(napi_disable_pending(n))) {
|
||||
napi_complete(n);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (n->gro_list) {
|
||||
/* flush too old packets
|
||||
* If HZ < 1000, flush all packets.
|
||||
*/
|
||||
napi_gro_flush(n, HZ >= 1000);
|
||||
}
|
||||
|
||||
/* Some drivers may have called napi_schedule
|
||||
* prior to exhausting their budget.
|
||||
*/
|
||||
if (unlikely(!list_empty(&n->poll_list))) {
|
||||
pr_warn_once("%s: Budget exhausted after napi rescheduled\n",
|
||||
n->dev ? n->dev->name : "backlog");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
list_add_tail(&n->poll_list, repoll);
|
||||
|
||||
out_unlock:
|
||||
netpoll_poll_unlock(have);
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
static void net_rx_action(struct softirq_action *h)
|
||||
{
|
||||
struct softnet_data *sd = this_cpu_ptr(&softnet_data);
|
||||
@ -4564,74 +4635,34 @@ static void net_rx_action(struct softirq_action *h)
|
||||
int budget = netdev_budget;
|
||||
LIST_HEAD(list);
|
||||
LIST_HEAD(repoll);
|
||||
void *have;
|
||||
|
||||
local_irq_disable();
|
||||
list_splice_init(&sd->poll_list, &list);
|
||||
local_irq_enable();
|
||||
|
||||
while (!list_empty(&list)) {
|
||||
for (;;) {
|
||||
struct napi_struct *n;
|
||||
int work, weight;
|
||||
|
||||
if (list_empty(&list)) {
|
||||
if (!sd_has_rps_ipi_waiting(sd) && list_empty(&repoll))
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
n = list_first_entry(&list, struct napi_struct, poll_list);
|
||||
budget -= napi_poll(n, &repoll);
|
||||
|
||||
/* If softirq window is exhausted then punt.
|
||||
* Allow this to run for 2 jiffies since which will allow
|
||||
* an average latency of 1.5/HZ.
|
||||
*/
|
||||
if (unlikely(budget <= 0 || time_after_eq(jiffies, time_limit)))
|
||||
goto softnet_break;
|
||||
|
||||
|
||||
n = list_first_entry(&list, struct napi_struct, poll_list);
|
||||
list_del_init(&n->poll_list);
|
||||
|
||||
have = netpoll_poll_lock(n);
|
||||
|
||||
weight = n->weight;
|
||||
|
||||
/* This NAPI_STATE_SCHED test is for avoiding a race
|
||||
* with netpoll's poll_napi(). Only the entity which
|
||||
* obtains the lock and sees NAPI_STATE_SCHED set will
|
||||
* actually make the ->poll() call. Therefore we avoid
|
||||
* accidentally calling ->poll() when NAPI is not scheduled.
|
||||
*/
|
||||
work = 0;
|
||||
if (test_bit(NAPI_STATE_SCHED, &n->state)) {
|
||||
work = n->poll(n, weight);
|
||||
trace_napi_poll(n);
|
||||
if (unlikely(budget <= 0 ||
|
||||
time_after_eq(jiffies, time_limit))) {
|
||||
sd->time_squeeze++;
|
||||
break;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(work > weight);
|
||||
|
||||
budget -= work;
|
||||
|
||||
/* Drivers must not modify the NAPI state if they
|
||||
* consume the entire weight. In such cases this code
|
||||
* still "owns" the NAPI instance and therefore can
|
||||
* move the instance around on the list at-will.
|
||||
*/
|
||||
if (unlikely(work == weight)) {
|
||||
if (unlikely(napi_disable_pending(n))) {
|
||||
napi_complete(n);
|
||||
} else {
|
||||
if (n->gro_list) {
|
||||
/* flush too old packets
|
||||
* If HZ < 1000, flush all packets.
|
||||
*/
|
||||
napi_gro_flush(n, HZ >= 1000);
|
||||
}
|
||||
list_add_tail(&n->poll_list, &repoll);
|
||||
}
|
||||
}
|
||||
|
||||
netpoll_poll_unlock(have);
|
||||
}
|
||||
|
||||
if (!sd_has_rps_ipi_waiting(sd) &&
|
||||
list_empty(&list) &&
|
||||
list_empty(&repoll))
|
||||
return;
|
||||
out:
|
||||
local_irq_disable();
|
||||
|
||||
list_splice_tail_init(&sd->poll_list, &list);
|
||||
@ -4641,12 +4672,6 @@ out:
|
||||
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
|
||||
|
||||
net_rps_action_and_irq_enable(sd);
|
||||
|
||||
return;
|
||||
|
||||
softnet_break:
|
||||
sd->time_squeeze++;
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct netdev_adjacent {
|
||||
|
@ -4148,6 +4148,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet)
|
||||
skb->ignore_df = 0;
|
||||
skb_dst_drop(skb);
|
||||
skb->mark = 0;
|
||||
skb_init_secmark(skb);
|
||||
secpath_reset(skb);
|
||||
nf_reset(skb);
|
||||
nf_reset_trace(skb);
|
||||
|
@ -122,14 +122,18 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt,
|
||||
int err;
|
||||
|
||||
skb = udp_tunnel_handle_offloads(skb, !gs->sock->sk->sk_no_check_tx);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
|
||||
+ GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr)
|
||||
+ (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
|
||||
|
||||
err = skb_cow_head(skb, min_headroom);
|
||||
if (unlikely(err))
|
||||
if (unlikely(err)) {
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
skb = vlan_hwaccel_push_inside(skb);
|
||||
if (unlikely(!skb))
|
||||
|
@ -1387,6 +1387,28 @@ ipv6_pktoptions:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
|
||||
const struct tcphdr *th)
|
||||
{
|
||||
/* This is tricky: we move IP6CB at its correct location into
|
||||
* TCP_SKB_CB(). It must be done after xfrm6_policy_check(), because
|
||||
* _decode_session6() uses IP6CB().
|
||||
* barrier() makes sure compiler won't play aliasing games.
|
||||
*/
|
||||
memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
|
||||
sizeof(struct inet6_skb_parm));
|
||||
barrier();
|
||||
|
||||
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
|
||||
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
|
||||
skb->len - th->doff*4);
|
||||
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
|
||||
TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
|
||||
TCP_SKB_CB(skb)->tcp_tw_isn = 0;
|
||||
TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
|
||||
TCP_SKB_CB(skb)->sacked = 0;
|
||||
}
|
||||
|
||||
static int tcp_v6_rcv(struct sk_buff *skb)
|
||||
{
|
||||
const struct tcphdr *th;
|
||||
@ -1418,24 +1440,9 @@ static int tcp_v6_rcv(struct sk_buff *skb)
|
||||
|
||||
th = tcp_hdr(skb);
|
||||
hdr = ipv6_hdr(skb);
|
||||
/* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
|
||||
* barrier() makes sure compiler wont play fool^Waliasing games.
|
||||
*/
|
||||
memmove(&TCP_SKB_CB(skb)->header.h6, IP6CB(skb),
|
||||
sizeof(struct inet6_skb_parm));
|
||||
barrier();
|
||||
|
||||
TCP_SKB_CB(skb)->seq = ntohl(th->seq);
|
||||
TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
|
||||
skb->len - th->doff*4);
|
||||
TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
|
||||
TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
|
||||
TCP_SKB_CB(skb)->tcp_tw_isn = 0;
|
||||
TCP_SKB_CB(skb)->ip_dsfield = ipv6_get_dsfield(hdr);
|
||||
TCP_SKB_CB(skb)->sacked = 0;
|
||||
|
||||
sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest,
|
||||
tcp_v6_iif(skb));
|
||||
inet6_iif(skb));
|
||||
if (!sk)
|
||||
goto no_tcp_socket;
|
||||
|
||||
@ -1451,6 +1458,8 @@ process:
|
||||
if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
|
||||
goto discard_and_relse;
|
||||
|
||||
tcp_v6_fill_cb(skb, hdr, th);
|
||||
|
||||
#ifdef CONFIG_TCP_MD5SIG
|
||||
if (tcp_v6_inbound_md5_hash(sk, skb))
|
||||
goto discard_and_relse;
|
||||
@ -1482,6 +1491,8 @@ no_tcp_socket:
|
||||
if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
|
||||
goto discard_it;
|
||||
|
||||
tcp_v6_fill_cb(skb, hdr, th);
|
||||
|
||||
if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
|
||||
csum_error:
|
||||
TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
|
||||
@ -1505,6 +1516,8 @@ do_time_wait:
|
||||
goto discard_it;
|
||||
}
|
||||
|
||||
tcp_v6_fill_cb(skb, hdr, th);
|
||||
|
||||
if (skb->len < (th->doff<<2)) {
|
||||
inet_twsk_put(inet_twsk(sk));
|
||||
goto bad_packet;
|
||||
|
@ -31,10 +31,7 @@ static struct sk_buff *mpls_gso_segment(struct sk_buff *skb,
|
||||
SKB_GSO_TCPV6 |
|
||||
SKB_GSO_UDP |
|
||||
SKB_GSO_DODGY |
|
||||
SKB_GSO_TCP_ECN |
|
||||
SKB_GSO_GRE |
|
||||
SKB_GSO_GRE_CSUM |
|
||||
SKB_GSO_IPIP)))
|
||||
SKB_GSO_TCP_ECN)))
|
||||
goto out;
|
||||
|
||||
/* Setup inner SKB. */
|
||||
|
@ -463,7 +463,7 @@ static void nfnetlink_rcv(struct sk_buff *skb)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
static int nfnetlink_bind(int group)
|
||||
static int nfnetlink_bind(struct net *net, int group)
|
||||
{
|
||||
const struct nfnetlink_subsystem *ss;
|
||||
int type;
|
||||
|
@ -1091,8 +1091,10 @@ static void netlink_remove(struct sock *sk)
|
||||
mutex_unlock(&nl_sk_hash_lock);
|
||||
|
||||
netlink_table_grab();
|
||||
if (nlk_sk(sk)->subscriptions)
|
||||
if (nlk_sk(sk)->subscriptions) {
|
||||
__sk_del_bind_node(sk);
|
||||
netlink_update_listeners(sk);
|
||||
}
|
||||
netlink_table_ungrab();
|
||||
}
|
||||
|
||||
@ -1139,8 +1141,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
|
||||
struct module *module = NULL;
|
||||
struct mutex *cb_mutex;
|
||||
struct netlink_sock *nlk;
|
||||
int (*bind)(int group);
|
||||
void (*unbind)(int group);
|
||||
int (*bind)(struct net *net, int group);
|
||||
void (*unbind)(struct net *net, int group);
|
||||
int err = 0;
|
||||
|
||||
sock->state = SS_UNCONNECTED;
|
||||
@ -1226,8 +1228,8 @@ static int netlink_release(struct socket *sock)
|
||||
|
||||
module_put(nlk->module);
|
||||
|
||||
netlink_table_grab();
|
||||
if (netlink_is_kernel(sk)) {
|
||||
netlink_table_grab();
|
||||
BUG_ON(nl_table[sk->sk_protocol].registered == 0);
|
||||
if (--nl_table[sk->sk_protocol].registered == 0) {
|
||||
struct listeners *old;
|
||||
@ -1241,11 +1243,16 @@ static int netlink_release(struct socket *sock)
|
||||
nl_table[sk->sk_protocol].flags = 0;
|
||||
nl_table[sk->sk_protocol].registered = 0;
|
||||
}
|
||||
} else if (nlk->subscriptions) {
|
||||
netlink_update_listeners(sk);
|
||||
netlink_table_ungrab();
|
||||
}
|
||||
netlink_table_ungrab();
|
||||
|
||||
if (nlk->netlink_unbind) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nlk->ngroups; i++)
|
||||
if (test_bit(i, nlk->groups))
|
||||
nlk->netlink_unbind(sock_net(sk), i + 1);
|
||||
}
|
||||
kfree(nlk->groups);
|
||||
nlk->groups = NULL;
|
||||
|
||||
@ -1410,9 +1417,10 @@ static int netlink_realloc_groups(struct sock *sk)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void netlink_unbind(int group, long unsigned int groups,
|
||||
struct netlink_sock *nlk)
|
||||
static void netlink_undo_bind(int group, long unsigned int groups,
|
||||
struct sock *sk)
|
||||
{
|
||||
struct netlink_sock *nlk = nlk_sk(sk);
|
||||
int undo;
|
||||
|
||||
if (!nlk->netlink_unbind)
|
||||
@ -1420,7 +1428,7 @@ static void netlink_unbind(int group, long unsigned int groups,
|
||||
|
||||
for (undo = 0; undo < group; undo++)
|
||||
if (test_bit(undo, &groups))
|
||||
nlk->netlink_unbind(undo);
|
||||
nlk->netlink_unbind(sock_net(sk), undo);
|
||||
}
|
||||
|
||||
static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
||||
@ -1458,10 +1466,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
||||
for (group = 0; group < nlk->ngroups; group++) {
|
||||
if (!test_bit(group, &groups))
|
||||
continue;
|
||||
err = nlk->netlink_bind(group);
|
||||
err = nlk->netlink_bind(net, group);
|
||||
if (!err)
|
||||
continue;
|
||||
netlink_unbind(group, groups, nlk);
|
||||
netlink_undo_bind(group, groups, sk);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -1471,7 +1479,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
||||
netlink_insert(sk, net, nladdr->nl_pid) :
|
||||
netlink_autobind(sock);
|
||||
if (err) {
|
||||
netlink_unbind(nlk->ngroups, groups, nlk);
|
||||
netlink_undo_bind(nlk->ngroups, groups, sk);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -2122,7 +2130,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
||||
if (!val || val - 1 >= nlk->ngroups)
|
||||
return -EINVAL;
|
||||
if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
|
||||
err = nlk->netlink_bind(val);
|
||||
err = nlk->netlink_bind(sock_net(sk), val);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@ -2131,7 +2139,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
|
||||
optname == NETLINK_ADD_MEMBERSHIP);
|
||||
netlink_table_ungrab();
|
||||
if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
|
||||
nlk->netlink_unbind(val);
|
||||
nlk->netlink_unbind(sock_net(sk), val);
|
||||
|
||||
err = 0;
|
||||
break;
|
||||
|
@ -39,8 +39,8 @@ struct netlink_sock {
|
||||
struct mutex *cb_mutex;
|
||||
struct mutex cb_def_mutex;
|
||||
void (*netlink_rcv)(struct sk_buff *skb);
|
||||
int (*netlink_bind)(int group);
|
||||
void (*netlink_unbind)(int group);
|
||||
int (*netlink_bind)(struct net *net, int group);
|
||||
void (*netlink_unbind)(struct net *net, int group);
|
||||
struct module *module;
|
||||
#ifdef CONFIG_NETLINK_MMAP
|
||||
struct mutex pg_vec_lock;
|
||||
@ -65,8 +65,8 @@ struct netlink_table {
|
||||
unsigned int groups;
|
||||
struct mutex *cb_mutex;
|
||||
struct module *module;
|
||||
int (*bind)(int group);
|
||||
void (*unbind)(int group);
|
||||
int (*bind)(struct net *net, int group);
|
||||
void (*unbind)(struct net *net, int group);
|
||||
bool (*compare)(struct net *net, struct sock *sock);
|
||||
int registered;
|
||||
};
|
||||
|
@ -983,11 +983,67 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
|
||||
{ .name = "notify", },
|
||||
};
|
||||
|
||||
static int genl_bind(struct net *net, int group)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
down_read(&cb_lock);
|
||||
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
|
||||
struct genl_family *f;
|
||||
|
||||
list_for_each_entry(f, genl_family_chain(i), family_list) {
|
||||
if (group >= f->mcgrp_offset &&
|
||||
group < f->mcgrp_offset + f->n_mcgrps) {
|
||||
int fam_grp = group - f->mcgrp_offset;
|
||||
|
||||
if (!f->netnsok && net != &init_net)
|
||||
err = -ENOENT;
|
||||
else if (f->mcast_bind)
|
||||
err = f->mcast_bind(net, fam_grp);
|
||||
else
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
up_read(&cb_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void genl_unbind(struct net *net, int group)
|
||||
{
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
down_read(&cb_lock);
|
||||
for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
|
||||
struct genl_family *f;
|
||||
|
||||
list_for_each_entry(f, genl_family_chain(i), family_list) {
|
||||
if (group >= f->mcgrp_offset &&
|
||||
group < f->mcgrp_offset + f->n_mcgrps) {
|
||||
int fam_grp = group - f->mcgrp_offset;
|
||||
|
||||
if (f->mcast_unbind)
|
||||
f->mcast_unbind(net, fam_grp);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
up_read(&cb_lock);
|
||||
|
||||
WARN_ON(!found);
|
||||
}
|
||||
|
||||
static int __net_init genl_pernet_init(struct net *net)
|
||||
{
|
||||
struct netlink_kernel_cfg cfg = {
|
||||
.input = genl_rcv,
|
||||
.flags = NL_CFG_F_NONROOT_RECV,
|
||||
.bind = genl_bind,
|
||||
.unbind = genl_unbind,
|
||||
};
|
||||
|
||||
/* we'll bump the group number right afterwards */
|
||||
|
@ -147,7 +147,8 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
|
||||
hdr = eth_hdr(skb);
|
||||
hdr->h_proto = mpls->mpls_ethertype;
|
||||
|
||||
skb_set_inner_protocol(skb, skb->protocol);
|
||||
if (!skb->inner_protocol)
|
||||
skb_set_inner_protocol(skb, skb->protocol);
|
||||
skb->protocol = mpls->mpls_ethertype;
|
||||
|
||||
invalidate_flow_key(key);
|
||||
|
@ -83,8 +83,7 @@ static bool ovs_must_notify(struct genl_family *family, struct genl_info *info,
|
||||
unsigned int group)
|
||||
{
|
||||
return info->nlhdr->nlmsg_flags & NLM_F_ECHO ||
|
||||
genl_has_listeners(family, genl_info_net(info)->genl_sock,
|
||||
group);
|
||||
genl_has_listeners(family, genl_info_net(info), group);
|
||||
}
|
||||
|
||||
static void ovs_notify(struct genl_family *family,
|
||||
|
@ -1753,7 +1753,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
||||
__be16 eth_type, __be16 vlan_tci, bool log)
|
||||
{
|
||||
const struct nlattr *a;
|
||||
bool out_tnl_port = false;
|
||||
int rem, err;
|
||||
|
||||
if (depth >= SAMPLE_ACTION_DEPTH)
|
||||
@ -1796,8 +1795,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
||||
case OVS_ACTION_ATTR_OUTPUT:
|
||||
if (nla_get_u32(a) >= DP_MAX_PORTS)
|
||||
return -EINVAL;
|
||||
out_tnl_port = false;
|
||||
|
||||
break;
|
||||
|
||||
case OVS_ACTION_ATTR_HASH: {
|
||||
@ -1832,12 +1829,6 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
||||
case OVS_ACTION_ATTR_PUSH_MPLS: {
|
||||
const struct ovs_action_push_mpls *mpls = nla_data(a);
|
||||
|
||||
/* Networking stack do not allow simultaneous Tunnel
|
||||
* and MPLS GSO.
|
||||
*/
|
||||
if (out_tnl_port)
|
||||
return -EINVAL;
|
||||
|
||||
if (!eth_p_mpls(mpls->mpls_ethertype))
|
||||
return -EINVAL;
|
||||
/* Prohibit push MPLS other than to a white list
|
||||
@ -1873,11 +1864,9 @@ static int __ovs_nla_copy_actions(const struct nlattr *attr,
|
||||
|
||||
case OVS_ACTION_ATTR_SET:
|
||||
err = validate_set(a, key, sfa,
|
||||
&out_tnl_port, eth_type, log);
|
||||
&skip_copy, eth_type, log);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
skip_copy = out_tnl_port;
|
||||
break;
|
||||
|
||||
case OVS_ACTION_ATTR_SAMPLE:
|
||||
|
@ -219,7 +219,10 @@ static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
false);
|
||||
if (err < 0)
|
||||
ip_rt_put(rt);
|
||||
return err;
|
||||
|
||||
error:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ static struct sk_buff *__build_header(struct sk_buff *skb,
|
||||
|
||||
skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM));
|
||||
if (IS_ERR(skb))
|
||||
return NULL;
|
||||
return skb;
|
||||
|
||||
tpi.flags = filter_tnl_flags(tun_key->tun_flags);
|
||||
tpi.proto = htons(ETH_P_TEB);
|
||||
@ -144,7 +144,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
|
||||
if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
goto err_free_skb;
|
||||
}
|
||||
|
||||
tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
|
||||
@ -157,8 +157,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
fl.flowi4_proto = IPPROTO_GRE;
|
||||
|
||||
rt = ip_route_output_key(net, &fl);
|
||||
if (IS_ERR(rt))
|
||||
return PTR_ERR(rt);
|
||||
if (IS_ERR(rt)) {
|
||||
err = PTR_ERR(rt);
|
||||
goto err_free_skb;
|
||||
}
|
||||
|
||||
tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags);
|
||||
|
||||
@ -183,8 +185,9 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
|
||||
/* Push Tunnel header. */
|
||||
skb = __build_header(skb, tunnel_hlen);
|
||||
if (unlikely(!skb)) {
|
||||
err = 0;
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
skb = NULL;
|
||||
goto err_free_rt;
|
||||
}
|
||||
|
||||
@ -198,7 +201,8 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false);
|
||||
err_free_rt:
|
||||
ip_rt_put(rt);
|
||||
error:
|
||||
err_free_skb:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,9 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
|
||||
false);
|
||||
if (err < 0)
|
||||
ip_rt_put(rt);
|
||||
return err;
|
||||
error:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -519,10 +519,9 @@ int ovs_vport_send(struct vport *vport, struct sk_buff *skb)
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
} else if (sent < 0) {
|
||||
ovs_vport_record_error(vport, VPORT_E_TX_ERROR);
|
||||
kfree_skb(skb);
|
||||
} else
|
||||
} else {
|
||||
ovs_vport_record_error(vport, VPORT_E_TX_DROPPED);
|
||||
|
||||
}
|
||||
return sent;
|
||||
}
|
||||
|
||||
|
@ -785,6 +785,7 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
|
||||
|
||||
struct tpacket3_hdr *last_pkt;
|
||||
struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;
|
||||
struct sock *sk = &po->sk;
|
||||
|
||||
if (po->stats.stats3.tp_drops)
|
||||
status |= TP_STATUS_LOSING;
|
||||
@ -809,6 +810,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
|
||||
/* Flush the block */
|
||||
prb_flush_block(pkc1, pbd1, status);
|
||||
|
||||
sk->sk_data_ready(sk);
|
||||
|
||||
pkc1->kactive_blk_num = GET_NEXT_PRB_BLK_NUM(pkc1);
|
||||
}
|
||||
|
||||
@ -2052,12 +2055,12 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
smp_wmb();
|
||||
#endif
|
||||
|
||||
if (po->tp_version <= TPACKET_V2)
|
||||
if (po->tp_version <= TPACKET_V2) {
|
||||
__packet_set_status(po, h.raw, status);
|
||||
else
|
||||
sk->sk_data_ready(sk);
|
||||
} else {
|
||||
prb_clear_blk_fill_status(&po->rx_ring);
|
||||
|
||||
sk->sk_data_ready(sk);
|
||||
}
|
||||
|
||||
drop_n_restore:
|
||||
if (skb_head != skb->data && skb_shared(skb)) {
|
||||
|
Loading…
Reference in New Issue
Block a user