mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix null deref in xt_TEE netfilter module, from Eric Dumazet. 2) Several spots need to get to the original listner for SYN-ACK packets, most spots got this ok but some were not. Whilst covering the remaining cases, create a helper to do this. From Eric Dumazet. 3) Missiing check of return value from alloc_netdev() in CAIF SPI code, from Rasmus Villemoes. 4) Don't sleep while != TASK_RUNNING in macvtap, from Vlad Yasevich. 5) Use after free in mvneta driver, from Justin Maggard. 6) Fix race on dst->flags access in dst_release(), from Eric Dumazet. 7) Add missing ZLIB_INFLATE dependency for new qed driver. From Arnd Bergmann. 8) Fix multicast getsockopt deadlock, from WANG Cong. 9) Fix deadlock in btusb, from Kuba Pawlak. 10) Some ipv6_add_dev() failure paths were not cleaning up the SNMP6 counter state. From Sabrina Dubroca. 11) Fix packet_bind() race, which can cause lost notifications, from Francesco Ruggeri. 12) Fix MAC restoration in qlcnic driver during bonding mode changes, from Jarod Wilson. 13) Revert bridging forward delay change which broke libvirt and other userspace things, from Vlad Yasevich. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (65 commits) Revert "bridge: Allow forward delay to be cfgd when STP enabled" bpf_trace: Make dependent on PERF_EVENTS qed: select ZLIB_INFLATE net: fix a race in dst_release() net: mvneta: Fix memory use after free. net: Documentation: Fix default value tcp_limit_output_bytes macvtap: Resolve possible __might_sleep warning in macvtap_do_read() mvneta: add FIXED_PHY dependency net: caif: check return value of alloc_netdev net: hisilicon: NET_VENDOR_HISILICON should depend on HAS_DMA drivers: net: xgene: fix RGMII 10/100Mb mode netfilter: nft_meta: use skb_to_full_sk() helper net_sched: em_meta: use skb_to_full_sk() helper sched: cls_flow: use skb_to_full_sk() helper netfilter: xt_owner: use skb_to_full_sk() helper smack: use skb_to_full_sk() helper net: add skb_to_full_sk() helper and use it in selinux_netlbl_skbuff_setsid() bpf: doc: correct arch list for supported eBPF JIT dwc_eth_qos: Delete an unnecessary check before the function call "of_node_put" bonding: fix panic on non-ARPHRD_ETHER enslave failure ...
This commit is contained in:
commit
2df4ee78d0
@ -48,6 +48,11 @@ Optional properties:
|
||||
- mac-address : See ethernet.txt file in the same directory
|
||||
- phy-handle : See ethernet.txt file in the same directory
|
||||
|
||||
Slave sub-nodes:
|
||||
- fixed-link : See fixed-link.txt file in the same directory
|
||||
Either the properties phy_id and phy-mode,
|
||||
or the sub-node fixed-link can be specified
|
||||
|
||||
Note: "ti,hwmods" field is used to fetch the base address and irq
|
||||
resources from TI, omap hwmod data base during device registration.
|
||||
Future plan is to migrate hwmod data base contents into device tree
|
||||
|
@ -596,9 +596,9 @@ skb pointer). All constraints and restrictions from bpf_check_classic() apply
|
||||
before a conversion to the new layout is being done behind the scenes!
|
||||
|
||||
Currently, the classic BPF format is being used for JITing on most of the
|
||||
architectures. Only x86-64 performs JIT compilation from eBPF instruction set,
|
||||
however, future work will migrate other JIT compilers as well, so that they
|
||||
will profit from the very same benefits.
|
||||
architectures. x86-64, aarch64 and s390x perform JIT compilation from eBPF
|
||||
instruction set, however, future work will migrate other JIT compilers as well,
|
||||
so that they will profit from the very same benefits.
|
||||
|
||||
Some core changes of the new internal format:
|
||||
|
||||
|
@ -709,7 +709,7 @@ tcp_limit_output_bytes - INTEGER
|
||||
typical pfifo_fast qdiscs.
|
||||
tcp_limit_output_bytes limits the number of bytes on qdisc
|
||||
or device to reduce artificial RTT/cwnd and reduce bufferbloat.
|
||||
Default: 131072
|
||||
Default: 262144
|
||||
|
||||
tcp_challenge_ack_limit - INTEGER
|
||||
Limits number of Challenge ACK sent per second, as recommended
|
||||
|
@ -1372,6 +1372,8 @@ static void btusb_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (data->isoc_altsetting != new_alts) {
|
||||
unsigned long flags;
|
||||
|
||||
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
|
||||
usb_kill_anchored_urbs(&data->isoc_anchor);
|
||||
|
||||
@ -1384,10 +1386,10 @@ static void btusb_work(struct work_struct *work)
|
||||
* Clear outstanding fragment when selecting a new
|
||||
* alternate setting.
|
||||
*/
|
||||
spin_lock(&data->rxlock);
|
||||
spin_lock_irqsave(&data->rxlock, flags);
|
||||
kfree_skb(data->sco_skb);
|
||||
data->sco_skb = NULL;
|
||||
spin_unlock(&data->rxlock);
|
||||
spin_unlock_irqrestore(&data->rxlock, flags);
|
||||
|
||||
if (__set_isoc_interface(hdev, new_alts) < 0)
|
||||
return;
|
||||
|
@ -1749,6 +1749,7 @@ err_undo_flags:
|
||||
slave_dev->dev_addr))
|
||||
eth_hw_addr_random(bond_dev);
|
||||
if (bond_dev->type != ARPHRD_ETHER) {
|
||||
dev_close(bond_dev);
|
||||
ether_setup(bond_dev);
|
||||
bond_dev->flags |= IFF_MASTER;
|
||||
bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
|
@ -730,11 +730,14 @@ int cfspi_spi_probe(struct platform_device *pdev)
|
||||
int res;
|
||||
dev = (struct cfspi_dev *)pdev->dev.platform_data;
|
||||
|
||||
ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d",
|
||||
NET_NAME_UNKNOWN, cfspi_setup);
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
ndev = alloc_netdev(sizeof(struct cfspi), "cfspi%d",
|
||||
NET_NAME_UNKNOWN, cfspi_setup);
|
||||
if (!ndev)
|
||||
return -ENOMEM;
|
||||
|
||||
cfspi = netdev_priv(ndev);
|
||||
netif_stop_queue(ndev);
|
||||
cfspi->ndev = ndev;
|
||||
|
@ -103,6 +103,8 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
|
||||
#endif
|
||||
.get_regs_len = mv88e6xxx_get_regs_len,
|
||||
.get_regs = mv88e6xxx_get_regs,
|
||||
.port_join_bridge = mv88e6xxx_port_bridge_join,
|
||||
.port_leave_bridge = mv88e6xxx_port_bridge_leave,
|
||||
.port_stp_update = mv88e6xxx_port_stp_update,
|
||||
.port_pvid_get = mv88e6xxx_port_pvid_get,
|
||||
.port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
|
||||
|
@ -323,6 +323,8 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
|
||||
.set_eeprom = mv88e6352_set_eeprom,
|
||||
.get_regs_len = mv88e6xxx_get_regs_len,
|
||||
.get_regs = mv88e6xxx_get_regs,
|
||||
.port_join_bridge = mv88e6xxx_port_bridge_join,
|
||||
.port_leave_bridge = mv88e6xxx_port_bridge_leave,
|
||||
.port_stp_update = mv88e6xxx_port_stp_update,
|
||||
.port_pvid_get = mv88e6xxx_port_pvid_get,
|
||||
.port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
|
||||
|
@ -1462,6 +1462,10 @@ int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
|
||||
const struct switchdev_obj_port_vlan *vlan,
|
||||
struct switchdev_trans *trans)
|
||||
{
|
||||
/* We reserve a few VLANs to isolate unbridged ports */
|
||||
if (vlan->vid_end >= 4000)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* We don't need any dynamic resource from the kernel (yet),
|
||||
* so skip the prepare phase.
|
||||
*/
|
||||
@ -1870,6 +1874,36 @@ unlock:
|
||||
return err;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
|
||||
int err;
|
||||
|
||||
/* The port joined a bridge, so leave its reserved VLAN */
|
||||
mutex_lock(&ps->smi_mutex);
|
||||
err = _mv88e6xxx_port_vlan_del(ds, port, pvid);
|
||||
if (!err)
|
||||
err = _mv88e6xxx_port_pvid_set(ds, port, 0);
|
||||
mutex_unlock(&ps->smi_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
const u16 pvid = 4000 + ds->index * DSA_MAX_PORTS + port;
|
||||
int err;
|
||||
|
||||
/* The port left the bridge, so join its reserved VLAN */
|
||||
mutex_lock(&ps->smi_mutex);
|
||||
err = _mv88e6xxx_port_vlan_add(ds, port, pvid, true);
|
||||
if (!err)
|
||||
err = _mv88e6xxx_port_pvid_set(ds, port, pvid);
|
||||
mutex_unlock(&ps->smi_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void mv88e6xxx_bridge_work(struct work_struct *work)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps;
|
||||
@ -2140,6 +2174,14 @@ int mv88e6xxx_setup_ports(struct dsa_switch *ds)
|
||||
ret = mv88e6xxx_setup_port(ds, i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
|
||||
continue;
|
||||
|
||||
/* setup the unbridged state */
|
||||
ret = mv88e6xxx_port_bridge_leave(ds, i, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -468,6 +468,8 @@ int mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int addr, int regnum,
|
||||
int mv88e6xxx_get_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
|
||||
int mv88e6xxx_set_eee(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phydev, struct ethtool_eee *e);
|
||||
int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, u32 members);
|
||||
int mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, u32 members);
|
||||
int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state);
|
||||
int mv88e6xxx_port_vlan_prepare(struct dsa_switch *ds, int port,
|
||||
const struct switchdev_obj_port_vlan *vlan,
|
||||
|
@ -459,6 +459,45 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
|
||||
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
|
||||
}
|
||||
|
||||
static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct device *dev = &pdata->pdev->dev;
|
||||
|
||||
if (dev->of_node) {
|
||||
struct clk *parent = clk_get_parent(pdata->clk);
|
||||
|
||||
switch (pdata->phy_speed) {
|
||||
case SPEED_10:
|
||||
clk_set_rate(parent, 2500000);
|
||||
break;
|
||||
case SPEED_100:
|
||||
clk_set_rate(parent, 25000000);
|
||||
break;
|
||||
default:
|
||||
clk_set_rate(parent, 125000000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_ACPI
|
||||
else {
|
||||
switch (pdata->phy_speed) {
|
||||
case SPEED_10:
|
||||
acpi_evaluate_object(ACPI_HANDLE(dev),
|
||||
"S10", NULL, NULL);
|
||||
break;
|
||||
case SPEED_100:
|
||||
acpi_evaluate_object(ACPI_HANDLE(dev),
|
||||
"S100", NULL, NULL);
|
||||
break;
|
||||
default:
|
||||
acpi_evaluate_object(ACPI_HANDLE(dev),
|
||||
"S1G", NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
|
||||
{
|
||||
struct device *dev = &pdata->pdev->dev;
|
||||
@ -477,12 +516,14 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
|
||||
switch (pdata->phy_speed) {
|
||||
case SPEED_10:
|
||||
ENET_INTERFACE_MODE2_SET(&mc2, 1);
|
||||
intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE);
|
||||
CFG_MACMODE_SET(&icm0, 0);
|
||||
CFG_WAITASYNCRD_SET(&icm2, 500);
|
||||
rgmii &= ~CFG_SPEED_1250;
|
||||
break;
|
||||
case SPEED_100:
|
||||
ENET_INTERFACE_MODE2_SET(&mc2, 1);
|
||||
intf_ctl &= ~ENET_GHD_MODE;
|
||||
intf_ctl |= ENET_LHD_MODE;
|
||||
CFG_MACMODE_SET(&icm0, 1);
|
||||
CFG_WAITASYNCRD_SET(&icm2, 80);
|
||||
@ -490,12 +531,15 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
|
||||
break;
|
||||
default:
|
||||
ENET_INTERFACE_MODE2_SET(&mc2, 2);
|
||||
intf_ctl &= ~ENET_LHD_MODE;
|
||||
intf_ctl |= ENET_GHD_MODE;
|
||||
|
||||
CFG_MACMODE_SET(&icm0, 2);
|
||||
CFG_WAITASYNCRD_SET(&icm2, 0);
|
||||
if (dev->of_node) {
|
||||
CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);
|
||||
CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);
|
||||
}
|
||||
rgmii |= CFG_SPEED_1250;
|
||||
|
||||
xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);
|
||||
value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
|
||||
@ -503,7 +547,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
|
||||
break;
|
||||
}
|
||||
|
||||
mc2 |= FULL_DUPLEX2;
|
||||
mc2 |= FULL_DUPLEX2 | PAD_CRC;
|
||||
xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
|
||||
xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
|
||||
|
||||
@ -522,6 +566,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
|
||||
/* Rtype should be copied from FP */
|
||||
xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);
|
||||
xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
|
||||
xgene_enet_configure_clock(pdata);
|
||||
|
||||
/* Rx-Tx traffic resume */
|
||||
xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
|
||||
|
@ -181,6 +181,7 @@ enum xgene_enet_rm {
|
||||
#define ENET_LHD_MODE BIT(25)
|
||||
#define ENET_GHD_MODE BIT(26)
|
||||
#define FULL_DUPLEX2 BIT(0)
|
||||
#define PAD_CRC BIT(2)
|
||||
#define SCAN_AUTO_INCR BIT(5)
|
||||
#define TBYT_ADDR 0x38
|
||||
#define TPKT_ADDR 0x39
|
||||
|
@ -698,7 +698,6 @@ static int xgene_enet_open(struct net_device *ndev)
|
||||
else
|
||||
schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
|
||||
|
||||
netif_carrier_off(ndev);
|
||||
netif_start_queue(ndev);
|
||||
|
||||
return ret;
|
||||
|
@ -173,6 +173,7 @@ config SYSTEMPORT
|
||||
config BNXT
|
||||
tristate "Broadcom NetXtreme-C/E support"
|
||||
depends on PCI
|
||||
depends on VXLAN || VXLAN=n
|
||||
select FW_LOADER
|
||||
select LIBCRC32C
|
||||
---help---
|
||||
|
@ -1292,8 +1292,6 @@ static inline int bnxt_has_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
|
||||
return TX_CMP_VALID(txcmp, raw_cons);
|
||||
}
|
||||
|
||||
#define CAG_LEGACY_INT_STATUS 0x2014
|
||||
|
||||
static irqreturn_t bnxt_inta(int irq, void *dev_instance)
|
||||
{
|
||||
struct bnxt_napi *bnapi = dev_instance;
|
||||
@ -1305,7 +1303,7 @@ static irqreturn_t bnxt_inta(int irq, void *dev_instance)
|
||||
prefetch(&cpr->cp_desc_ring[CP_RING(cons)][CP_IDX(cons)]);
|
||||
|
||||
if (!bnxt_has_work(bp, cpr)) {
|
||||
int_status = readl(bp->bar0 + CAG_LEGACY_INT_STATUS);
|
||||
int_status = readl(bp->bar0 + BNXT_CAG_REG_LEGACY_INT_STATUS);
|
||||
/* return if erroneous interrupt */
|
||||
if (!(int_status & (0x10000 << cpr->cp_ring_struct.fw_ring_id)))
|
||||
return IRQ_NONE;
|
||||
@ -4527,10 +4525,25 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Common routine to pre-map certain register block to different GRC window.
|
||||
* A PF has 16 4K windows and a VF has 4 4K windows. However, only 15 windows
|
||||
* in PF and 3 windows in VF that can be customized to map in different
|
||||
* register blocks.
|
||||
*/
|
||||
static void bnxt_preset_reg_win(struct bnxt *bp)
|
||||
{
|
||||
if (BNXT_PF(bp)) {
|
||||
/* CAG registers map to GRC window #4 */
|
||||
writel(BNXT_CAG_REG_BASE,
|
||||
bp->bar0 + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 12);
|
||||
}
|
||||
}
|
||||
|
||||
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
bnxt_preset_reg_win(bp);
|
||||
netif_carrier_off(bp->dev);
|
||||
if (irq_re_init) {
|
||||
rc = bnxt_setup_int_mode(bp);
|
||||
@ -5294,7 +5307,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
|
||||
struct bnxt_ntuple_filter *fltr, *new_fltr;
|
||||
struct flow_keys *fkeys;
|
||||
struct ethhdr *eth = (struct ethhdr *)skb_mac_header(skb);
|
||||
int rc = 0, idx;
|
||||
int rc = 0, idx, bit_id;
|
||||
struct hlist_head *head;
|
||||
|
||||
if (skb->encapsulation)
|
||||
@ -5332,14 +5345,15 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
|
||||
rcu_read_unlock();
|
||||
|
||||
spin_lock_bh(&bp->ntp_fltr_lock);
|
||||
new_fltr->sw_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
|
||||
BNXT_NTP_FLTR_MAX_FLTR, 0);
|
||||
if (new_fltr->sw_id < 0) {
|
||||
bit_id = bitmap_find_free_region(bp->ntp_fltr_bmap,
|
||||
BNXT_NTP_FLTR_MAX_FLTR, 0);
|
||||
if (bit_id < 0) {
|
||||
spin_unlock_bh(&bp->ntp_fltr_lock);
|
||||
rc = -ENOMEM;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
new_fltr->sw_id = (u16)bit_id;
|
||||
new_fltr->flow_id = flow_id;
|
||||
new_fltr->rxq = rxq_index;
|
||||
hlist_add_head_rcu(&new_fltr->hash, head);
|
||||
|
@ -166,9 +166,11 @@ struct rx_cmp {
|
||||
#define RX_CMP_HASH_VALID(rxcmp) \
|
||||
((rxcmp)->rx_cmp_len_flags_type & cpu_to_le32(RX_CMP_FLAGS_RSS_VALID))
|
||||
|
||||
#define RSS_PROFILE_ID_MASK 0x1f
|
||||
|
||||
#define RX_CMP_HASH_TYPE(rxcmp) \
|
||||
((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
|
||||
RX_CMP_RSS_HASH_TYPE_SHIFT)
|
||||
(((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
|
||||
RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
|
||||
|
||||
struct rx_cmp_ext {
|
||||
__le32 rx_cmp_flags2;
|
||||
@ -282,9 +284,9 @@ struct rx_tpa_start_cmp {
|
||||
cpu_to_le32(RX_TPA_START_CMP_FLAGS_RSS_VALID))
|
||||
|
||||
#define TPA_START_HASH_TYPE(rx_tpa_start) \
|
||||
((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \
|
||||
RX_TPA_START_CMP_RSS_HASH_TYPE) >> \
|
||||
RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT)
|
||||
(((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \
|
||||
RX_TPA_START_CMP_RSS_HASH_TYPE) >> \
|
||||
RX_TPA_START_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
|
||||
|
||||
#define TPA_START_AGG_ID(rx_tpa_start) \
|
||||
((le32_to_cpu((rx_tpa_start)->rx_tpa_start_cmp_misc_v1) & \
|
||||
@ -839,6 +841,10 @@ struct bnxt_queue_info {
|
||||
u8 queue_profile;
|
||||
};
|
||||
|
||||
#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
|
||||
#define BNXT_CAG_REG_LEGACY_INT_STATUS 0x4014
|
||||
#define BNXT_CAG_REG_BASE 0x300000
|
||||
|
||||
struct bnxt {
|
||||
void __iomem *bar0;
|
||||
void __iomem *bar1;
|
||||
@ -959,11 +965,11 @@ struct bnxt {
|
||||
#define BNXT_RX_MASK_SP_EVENT 0
|
||||
#define BNXT_RX_NTP_FLTR_SP_EVENT 1
|
||||
#define BNXT_LINK_CHNG_SP_EVENT 2
|
||||
#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 4
|
||||
#define BNXT_VXLAN_ADD_PORT_SP_EVENT 8
|
||||
#define BNXT_VXLAN_DEL_PORT_SP_EVENT 16
|
||||
#define BNXT_RESET_TASK_SP_EVENT 32
|
||||
#define BNXT_RST_RING_SP_EVENT 64
|
||||
#define BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT 3
|
||||
#define BNXT_VXLAN_ADD_PORT_SP_EVENT 4
|
||||
#define BNXT_VXLAN_DEL_PORT_SP_EVENT 5
|
||||
#define BNXT_RESET_TASK_SP_EVENT 6
|
||||
#define BNXT_RST_RING_SP_EVENT 7
|
||||
|
||||
struct bnxt_pf_info pf;
|
||||
#ifdef CONFIG_BNXT_SRIOV
|
||||
|
@ -258,7 +258,7 @@ static int bnxt_set_vf_attr(struct bnxt *bp, int num_vfs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp)
|
||||
static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp, int num_vfs)
|
||||
{
|
||||
int i, rc = 0;
|
||||
struct bnxt_pf_info *pf = &bp->pf;
|
||||
@ -267,7 +267,7 @@ static int bnxt_hwrm_func_vf_resource_free(struct bnxt *bp)
|
||||
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_VF_RESC_FREE, -1, -1);
|
||||
|
||||
mutex_lock(&bp->hwrm_cmd_lock);
|
||||
for (i = pf->first_vf_id; i < pf->first_vf_id + pf->active_vfs; i++) {
|
||||
for (i = pf->first_vf_id; i < pf->first_vf_id + num_vfs; i++) {
|
||||
req.vf_id = cpu_to_le16(i);
|
||||
rc = _hwrm_send_message(bp, &req, sizeof(req),
|
||||
HWRM_CMD_TIMEOUT);
|
||||
@ -509,7 +509,7 @@ static int bnxt_sriov_enable(struct bnxt *bp, int *num_vfs)
|
||||
|
||||
err_out2:
|
||||
/* Free the resources reserved for various VF's */
|
||||
bnxt_hwrm_func_vf_resource_free(bp);
|
||||
bnxt_hwrm_func_vf_resource_free(bp, *num_vfs);
|
||||
|
||||
err_out1:
|
||||
bnxt_free_vf_resources(bp);
|
||||
@ -519,13 +519,19 @@ err_out1:
|
||||
|
||||
void bnxt_sriov_disable(struct bnxt *bp)
|
||||
{
|
||||
if (!bp->pf.active_vfs)
|
||||
u16 num_vfs = pci_num_vf(bp->pdev);
|
||||
|
||||
if (!num_vfs)
|
||||
return;
|
||||
|
||||
pci_disable_sriov(bp->pdev);
|
||||
|
||||
/* Free the resources reserved for various VF's */
|
||||
bnxt_hwrm_func_vf_resource_free(bp);
|
||||
if (pci_vfs_assigned(bp->pdev)) {
|
||||
netdev_warn(bp->dev, "Unable to free %d VFs because some are assigned to VMs.\n",
|
||||
num_vfs);
|
||||
} else {
|
||||
pci_disable_sriov(bp->pdev);
|
||||
/* Free the HW resources reserved for various VF's */
|
||||
bnxt_hwrm_func_vf_resource_free(bp, num_vfs);
|
||||
}
|
||||
|
||||
bnxt_free_vf_resources(bp);
|
||||
|
||||
@ -552,17 +558,25 @@ int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs)
|
||||
}
|
||||
bp->sriov_cfg = true;
|
||||
rtnl_unlock();
|
||||
if (!num_vfs) {
|
||||
bnxt_sriov_disable(bp);
|
||||
return 0;
|
||||
|
||||
if (pci_vfs_assigned(bp->pdev)) {
|
||||
netdev_warn(dev, "Unable to configure SRIOV since some VFs are assigned to VMs.\n");
|
||||
num_vfs = 0;
|
||||
goto sriov_cfg_exit;
|
||||
}
|
||||
|
||||
/* Check if enabled VFs is same as requested */
|
||||
if (num_vfs == bp->pf.active_vfs)
|
||||
return 0;
|
||||
if (num_vfs && num_vfs == bp->pf.active_vfs)
|
||||
goto sriov_cfg_exit;
|
||||
|
||||
/* if there are previous existing VFs, clean them up */
|
||||
bnxt_sriov_disable(bp);
|
||||
if (!num_vfs)
|
||||
goto sriov_cfg_exit;
|
||||
|
||||
bnxt_sriov_enable(bp, &num_vfs);
|
||||
|
||||
sriov_cfg_exit:
|
||||
bp->sriov_cfg = false;
|
||||
wake_up(&bp->sriov_cfg_wait);
|
||||
|
||||
|
@ -5,7 +5,8 @@
|
||||
config NET_VENDOR_HISILICON
|
||||
bool "Hisilicon devices"
|
||||
default y
|
||||
depends on OF && (ARM || ARM64 || COMPILE_TEST)
|
||||
depends on OF && HAS_DMA
|
||||
depends on ARM || ARM64 || COMPILE_TEST
|
||||
---help---
|
||||
If you have a network (Ethernet) card belonging to this class, say Y.
|
||||
|
||||
|
@ -44,6 +44,7 @@ config MVNETA
|
||||
tristate "Marvell Armada 370/38x/XP network interface support"
|
||||
depends on PLAT_ORION
|
||||
select MVMDIO
|
||||
select FIXED_PHY
|
||||
---help---
|
||||
This driver supports the network interface units in the
|
||||
Marvell ARMADA XP, ARMADA 370 and ARMADA 38x SoC family.
|
||||
|
@ -1493,9 +1493,9 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
|
||||
struct mvneta_rx_desc *rx_desc = rxq->descs + i;
|
||||
void *data = (void *)rx_desc->buf_cookie;
|
||||
|
||||
mvneta_frag_free(pp, data);
|
||||
dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
|
||||
MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
|
||||
mvneta_frag_free(pp, data);
|
||||
}
|
||||
|
||||
if (rx_done)
|
||||
|
@ -94,6 +94,7 @@ config NETXEN_NIC
|
||||
config QED
|
||||
tristate "QLogic QED 25/40/100Gb core driver"
|
||||
depends on PCI
|
||||
select ZLIB_INFLATE
|
||||
---help---
|
||||
This enables the support for ...
|
||||
|
||||
|
@ -223,6 +223,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
|
||||
if (!p_hwfn->p_tx_cids) {
|
||||
DP_NOTICE(p_hwfn,
|
||||
"Failed to allocate memory for Tx Cids\n");
|
||||
rc = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
|
||||
@ -230,6 +231,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
|
||||
if (!p_hwfn->p_rx_cids) {
|
||||
DP_NOTICE(p_hwfn,
|
||||
"Failed to allocate memory for Rx Cids\n");
|
||||
rc = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
}
|
||||
@ -281,14 +283,17 @@ int qed_resc_alloc(struct qed_dev *cdev)
|
||||
|
||||
/* EQ */
|
||||
p_eq = qed_eq_alloc(p_hwfn, 256);
|
||||
|
||||
if (!p_eq)
|
||||
if (!p_eq) {
|
||||
rc = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
p_hwfn->p_eq = p_eq;
|
||||
|
||||
p_consq = qed_consq_alloc(p_hwfn);
|
||||
if (!p_consq)
|
||||
if (!p_consq) {
|
||||
rc = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
p_hwfn->p_consq = p_consq;
|
||||
|
||||
/* DMA info initialization */
|
||||
@ -303,6 +308,7 @@ int qed_resc_alloc(struct qed_dev *cdev)
|
||||
cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_KERNEL);
|
||||
if (!cdev->reset_stats) {
|
||||
DP_NOTICE(cdev, "Failed to allocate reset statistics\n");
|
||||
rc = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
|
||||
@ -562,7 +568,7 @@ static int qed_hw_init_pf(struct qed_hwfn *p_hwfn,
|
||||
}
|
||||
|
||||
/* Enable classification by MAC if needed */
|
||||
if (hw_mode & MODE_MF_SI) {
|
||||
if (hw_mode & (1 << MODE_MF_SI)) {
|
||||
DP_VERBOSE(p_hwfn, NETIF_MSG_HW,
|
||||
"Configuring TAGMAC_CLS_TYPE\n");
|
||||
STORE_RT_REG(p_hwfn,
|
||||
|
@ -251,11 +251,6 @@ void qed_int_sp_dpc(unsigned long hwfn_cookie)
|
||||
int arr_size;
|
||||
u16 rc = 0;
|
||||
|
||||
if (!p_hwfn) {
|
||||
DP_ERR(p_hwfn->cdev, "DPC called - no hwfn!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!p_hwfn->p_sp_sb) {
|
||||
DP_ERR(p_hwfn->cdev, "DPC called - no p_sp_sb\n");
|
||||
return;
|
||||
|
@ -353,7 +353,8 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
|
||||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EINVAL;
|
||||
|
||||
if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data))
|
||||
if (ether_addr_equal_unaligned(adapter->mac_addr, addr->sa_data) &&
|
||||
ether_addr_equal_unaligned(netdev->dev_addr, addr->sa_data))
|
||||
return 0;
|
||||
|
||||
if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
|
||||
|
@ -1098,7 +1098,7 @@ static struct mdiobb_ops bb_ops = {
|
||||
static void sh_eth_ring_free(struct net_device *ndev)
|
||||
{
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
int i;
|
||||
int ringsize, i;
|
||||
|
||||
/* Free Rx skb ringbuffer */
|
||||
if (mdp->rx_skbuff) {
|
||||
@ -1115,6 +1115,20 @@ static void sh_eth_ring_free(struct net_device *ndev)
|
||||
}
|
||||
kfree(mdp->tx_skbuff);
|
||||
mdp->tx_skbuff = NULL;
|
||||
|
||||
if (mdp->rx_ring) {
|
||||
ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
|
||||
mdp->rx_desc_dma);
|
||||
mdp->rx_ring = NULL;
|
||||
}
|
||||
|
||||
if (mdp->tx_ring) {
|
||||
ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->tx_ring,
|
||||
mdp->tx_desc_dma);
|
||||
mdp->tx_ring = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* format skb and descriptor buffer */
|
||||
@ -1199,7 +1213,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
|
||||
static int sh_eth_ring_init(struct net_device *ndev)
|
||||
{
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
int rx_ringsize, tx_ringsize, ret = 0;
|
||||
int rx_ringsize, tx_ringsize;
|
||||
|
||||
/* +26 gets the maximum ethernet encapsulation, +7 & ~7 because the
|
||||
* card needs room to do 8 byte alignment, +2 so we can reserve
|
||||
@ -1214,26 +1228,20 @@ static int sh_eth_ring_init(struct net_device *ndev)
|
||||
/* Allocate RX and TX skb rings */
|
||||
mdp->rx_skbuff = kcalloc(mdp->num_rx_ring, sizeof(*mdp->rx_skbuff),
|
||||
GFP_KERNEL);
|
||||
if (!mdp->rx_skbuff) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
if (!mdp->rx_skbuff)
|
||||
return -ENOMEM;
|
||||
|
||||
mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff),
|
||||
GFP_KERNEL);
|
||||
if (!mdp->tx_skbuff) {
|
||||
ret = -ENOMEM;
|
||||
goto skb_ring_free;
|
||||
}
|
||||
if (!mdp->tx_skbuff)
|
||||
goto ring_free;
|
||||
|
||||
/* Allocate all Rx descriptors. */
|
||||
rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
|
||||
mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma,
|
||||
GFP_KERNEL);
|
||||
if (!mdp->rx_ring) {
|
||||
ret = -ENOMEM;
|
||||
goto skb_ring_free;
|
||||
}
|
||||
if (!mdp->rx_ring)
|
||||
goto ring_free;
|
||||
|
||||
mdp->dirty_rx = 0;
|
||||
|
||||
@ -1241,42 +1249,15 @@ static int sh_eth_ring_init(struct net_device *ndev)
|
||||
tx_ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
|
||||
mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
|
||||
GFP_KERNEL);
|
||||
if (!mdp->tx_ring) {
|
||||
ret = -ENOMEM;
|
||||
goto desc_ring_free;
|
||||
}
|
||||
return ret;
|
||||
if (!mdp->tx_ring)
|
||||
goto ring_free;
|
||||
return 0;
|
||||
|
||||
desc_ring_free:
|
||||
/* free DMA buffer */
|
||||
dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma);
|
||||
|
||||
skb_ring_free:
|
||||
/* Free Rx and Tx skb ring buffer */
|
||||
ring_free:
|
||||
/* Free Rx and Tx skb ring buffer and DMA buffer */
|
||||
sh_eth_ring_free(ndev);
|
||||
mdp->tx_ring = NULL;
|
||||
mdp->rx_ring = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp)
|
||||
{
|
||||
int ringsize;
|
||||
|
||||
if (mdp->rx_ring) {
|
||||
ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
|
||||
mdp->rx_desc_dma);
|
||||
mdp->rx_ring = NULL;
|
||||
}
|
||||
|
||||
if (mdp->tx_ring) {
|
||||
ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->tx_ring,
|
||||
mdp->tx_desc_dma);
|
||||
mdp->tx_ring = NULL;
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int sh_eth_dev_init(struct net_device *ndev, bool start)
|
||||
@ -2239,10 +2220,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
|
||||
|
||||
sh_eth_dev_exit(ndev);
|
||||
|
||||
/* Free all the skbuffs in the Rx queue. */
|
||||
/* Free all the skbuffs in the Rx queue and the DMA buffers. */
|
||||
sh_eth_ring_free(ndev);
|
||||
/* Free DMA buffer */
|
||||
sh_eth_free_dma_buffer(mdp);
|
||||
}
|
||||
|
||||
/* Set new parameters */
|
||||
@ -2487,12 +2466,9 @@ static int sh_eth_close(struct net_device *ndev)
|
||||
|
||||
free_irq(ndev->irq, ndev);
|
||||
|
||||
/* Free all the skbuffs in the Rx queue. */
|
||||
/* Free all the skbuffs in the Rx queue and the DMA buffer. */
|
||||
sh_eth_ring_free(ndev);
|
||||
|
||||
/* free DMA buffer */
|
||||
sh_eth_free_dma_buffer(mdp);
|
||||
|
||||
pm_runtime_put_sync(&mdp->pdev->dev);
|
||||
|
||||
mdp->is_opened = 0;
|
||||
|
@ -354,7 +354,7 @@ static int gmac_clk_init(struct rk_priv_data *bsp_priv)
|
||||
|
||||
static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
|
||||
{
|
||||
int phy_iface = phy_iface = bsp_priv->phy_iface;
|
||||
int phy_iface = bsp_priv->phy_iface;
|
||||
|
||||
if (enable) {
|
||||
if (!bsp_priv->clk_enabled) {
|
||||
|
@ -2970,8 +2970,7 @@ err_out_unregister_netdev:
|
||||
err_out_clk_dis_aper:
|
||||
clk_disable_unprepare(lp->apb_pclk);
|
||||
err_out_free_netdev:
|
||||
if (lp->phy_node)
|
||||
of_node_put(lp->phy_node);
|
||||
of_node_put(lp->phy_node);
|
||||
free_netdev(ndev);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
return ret;
|
||||
|
@ -2037,6 +2037,19 @@ static int cpsw_probe_dt(struct cpsw_priv *priv,
|
||||
continue;
|
||||
|
||||
priv->phy_node = of_parse_phandle(slave_node, "phy-handle", 0);
|
||||
if (of_phy_is_fixed_link(slave_node)) {
|
||||
struct phy_device *pd;
|
||||
|
||||
ret = of_phy_register_fixed_link(slave_node);
|
||||
if (ret)
|
||||
return ret;
|
||||
pd = of_phy_find_device(slave_node);
|
||||
if (!pd)
|
||||
return -ENODEV;
|
||||
snprintf(slave_data->phy_id, sizeof(slave_data->phy_id),
|
||||
PHY_ID_FMT, pd->bus->id, pd->phy_id);
|
||||
goto no_phy_slave;
|
||||
}
|
||||
parp = of_get_property(slave_node, "phy_id", &lenp);
|
||||
if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
|
||||
dev_err(&pdev->dev, "Missing slave[%d] phy_id property\n", i);
|
||||
|
@ -143,9 +143,7 @@ static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
|
||||
|
||||
static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
|
||||
{
|
||||
if (epbh->buffer)
|
||||
vfree(epbh->buffer);
|
||||
|
||||
vfree(epbh->buffer);
|
||||
epbh->buffer = NULL;
|
||||
epbh->size = 0;
|
||||
|
||||
|
@ -935,6 +935,9 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
|
||||
/* Nothing to read, let's sleep */
|
||||
schedule();
|
||||
}
|
||||
if (!noblock)
|
||||
finish_wait(sk_sleep(&q->sk), &wait);
|
||||
|
||||
if (skb) {
|
||||
ret = macvtap_put_user(q, skb, to);
|
||||
if (unlikely(ret < 0))
|
||||
@ -942,8 +945,6 @@ static ssize_t macvtap_do_read(struct macvtap_queue *q,
|
||||
else
|
||||
consume_skb(skb);
|
||||
}
|
||||
if (!noblock)
|
||||
finish_wait(sk_sleep(&q->sk), &wait);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -771,6 +771,7 @@ static const struct usb_device_id products[] = {
|
||||
{QMI_GOBI_DEVICE(0x05c6, 0x9245)}, /* Samsung Gobi 2000 Modem device (VL176) */
|
||||
{QMI_GOBI_DEVICE(0x03f0, 0x251d)}, /* HP Gobi 2000 Modem device (VP412) */
|
||||
{QMI_GOBI_DEVICE(0x05c6, 0x9215)}, /* Acer Gobi 2000 Modem device (VP413) */
|
||||
{QMI_FIXED_INTF(0x05c6, 0x9215, 4)}, /* Quectel EC20 Mini PCIe */
|
||||
{QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */
|
||||
{QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */
|
||||
{QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */
|
||||
@ -802,10 +803,24 @@ static const struct usb_device_id products[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
|
||||
static bool quectel_ec20_detected(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_device *dev = interface_to_usbdev(intf);
|
||||
|
||||
if (dev->actconfig &&
|
||||
le16_to_cpu(dev->descriptor.idVendor) == 0x05c6 &&
|
||||
le16_to_cpu(dev->descriptor.idProduct) == 0x9215 &&
|
||||
dev->actconfig->desc.bNumInterfaces == 5)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int qmi_wwan_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *prod)
|
||||
{
|
||||
struct usb_device_id *id = (struct usb_device_id *)prod;
|
||||
struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc;
|
||||
|
||||
/* Workaround to enable dynamic IDs. This disables usbnet
|
||||
* blacklisting functionality. Which, if required, can be
|
||||
@ -817,6 +832,12 @@ static int qmi_wwan_probe(struct usb_interface *intf,
|
||||
id->driver_info = (unsigned long)&qmi_wwan_info;
|
||||
}
|
||||
|
||||
/* Quectel EC20 quirk where we've QMI on interface 4 instead of 0 */
|
||||
if (quectel_ec20_detected(intf) && desc->bInterfaceNumber == 0) {
|
||||
dev_dbg(&intf->dev, "Quectel EC20 quirk, skipping interface 0\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return usbnet_probe(intf, id);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ config NFC_MRVL_I2C
|
||||
|
||||
config NFC_MRVL_SPI
|
||||
tristate "Marvell NFC-over-SPI driver"
|
||||
depends on NFC_MRVL && SPI
|
||||
depends on NFC_MRVL && NFC_NCI_SPI
|
||||
help
|
||||
Marvell NFC-over-SPI driver.
|
||||
|
||||
|
@ -113,9 +113,12 @@ static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error)
|
||||
}
|
||||
|
||||
atomic_set(&priv->ndev->cmd_cnt, 0);
|
||||
del_timer_sync(&priv->ndev->cmd_timer);
|
||||
|
||||
del_timer_sync(&priv->fw_dnld.timer);
|
||||
if (timer_pending(&priv->ndev->cmd_timer))
|
||||
del_timer_sync(&priv->ndev->cmd_timer);
|
||||
|
||||
if (timer_pending(&priv->fw_dnld.timer))
|
||||
del_timer_sync(&priv->fw_dnld.timer);
|
||||
|
||||
nfc_info(priv->dev, "FW loading over (%d)]\n", error);
|
||||
|
||||
@ -472,9 +475,12 @@ void nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv)
|
||||
void nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
/* Discard command timer */
|
||||
if (timer_pending(&priv->ndev->cmd_timer))
|
||||
del_timer_sync(&priv->ndev->cmd_timer);
|
||||
|
||||
/* Allow next command */
|
||||
atomic_set(&priv->ndev->cmd_cnt, 1);
|
||||
del_timer_sync(&priv->ndev->cmd_timer);
|
||||
|
||||
/* Queue and trigger rx work */
|
||||
skb_queue_tail(&priv->fw_dnld.rx_q, skb);
|
||||
|
@ -194,6 +194,9 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
|
||||
|
||||
nfcmrvl_fw_dnld_deinit(priv);
|
||||
|
||||
if (priv->config.reset_n_io)
|
||||
devm_gpio_free(priv->dev, priv->config.reset_n_io);
|
||||
|
||||
nci_unregister_device(ndev);
|
||||
nci_free_device(ndev);
|
||||
kfree(priv);
|
||||
@ -251,8 +254,6 @@ void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
|
||||
gpio_set_value(priv->config.reset_n_io, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
int nfcmrvl_parse_dt(struct device_node *node,
|
||||
struct nfcmrvl_platform_data *pdata)
|
||||
{
|
||||
@ -275,16 +276,6 @@ int nfcmrvl_parse_dt(struct device_node *node,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int nfcmrvl_parse_dt(struct device_node *node,
|
||||
struct nfcmrvl_platform_data *pdata)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt);
|
||||
|
||||
MODULE_AUTHOR("Marvell International Ltd.");
|
||||
|
@ -67,8 +67,6 @@ static struct nfcmrvl_if_ops uart_ops = {
|
||||
.nci_update_config = nfcmrvl_uart_nci_update_config
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
||||
static int nfcmrvl_uart_parse_dt(struct device_node *node,
|
||||
struct nfcmrvl_platform_data *pdata)
|
||||
{
|
||||
@ -102,16 +100,6 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int nfcmrvl_uart_parse_dt(struct device_node *node,
|
||||
struct nfcmrvl_platform_data *pdata)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** NCI UART OPS
|
||||
*/
|
||||
@ -152,10 +140,6 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
|
||||
nu->drv_data = priv;
|
||||
nu->ndev = priv->ndev;
|
||||
|
||||
/* Set BREAK */
|
||||
if (priv->config.break_control && nu->tty->ops->break_ctl)
|
||||
nu->tty->ops->break_ctl(nu->tty, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -174,6 +158,9 @@ static void nfcmrvl_nci_uart_tx_start(struct nci_uart *nu)
|
||||
{
|
||||
struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;
|
||||
|
||||
if (priv->ndev->nfc_dev->fw_download_in_progress)
|
||||
return;
|
||||
|
||||
/* Remove BREAK to wake up the NFCC */
|
||||
if (priv->config.break_control && nu->tty->ops->break_ctl) {
|
||||
nu->tty->ops->break_ctl(nu->tty, 0);
|
||||
@ -185,13 +172,18 @@ static void nfcmrvl_nci_uart_tx_done(struct nci_uart *nu)
|
||||
{
|
||||
struct nfcmrvl_private *priv = (struct nfcmrvl_private *)nu->drv_data;
|
||||
|
||||
if (priv->ndev->nfc_dev->fw_download_in_progress)
|
||||
return;
|
||||
|
||||
/*
|
||||
** To ensure that if the NFCC goes in DEEP SLEEP sate we can wake him
|
||||
** up. we set BREAK. Once we will be ready to send again we will remove
|
||||
** it.
|
||||
*/
|
||||
if (priv->config.break_control && nu->tty->ops->break_ctl)
|
||||
if (priv->config.break_control && nu->tty->ops->break_ctl) {
|
||||
nu->tty->ops->break_ctl(nu->tty, -1);
|
||||
usleep_range(1000, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
static struct nci_uart nfcmrvl_nci_uart = {
|
||||
|
@ -1322,6 +1322,7 @@ enum netdev_priv_flags {
|
||||
#define IFF_L3MDEV_MASTER IFF_L3MDEV_MASTER
|
||||
#define IFF_NO_QUEUE IFF_NO_QUEUE
|
||||
#define IFF_OPENVSWITCH IFF_OPENVSWITCH
|
||||
#define IFF_L3MDEV_SLAVE IFF_L3MDEV_SLAVE
|
||||
|
||||
/**
|
||||
* struct net_device - The DEVICE structure.
|
||||
|
@ -397,6 +397,13 @@ static inline void fastopen_queue_tune(struct sock *sk, int backlog)
|
||||
queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn);
|
||||
}
|
||||
|
||||
static inline void tcp_move_syn(struct tcp_sock *tp,
|
||||
struct request_sock *req)
|
||||
{
|
||||
tp->saved_syn = req->saved_syn;
|
||||
req->saved_syn = NULL;
|
||||
}
|
||||
|
||||
static inline void tcp_saved_syn_free(struct tcp_sock *tp)
|
||||
{
|
||||
kfree(tp->saved_syn);
|
||||
|
@ -275,6 +275,8 @@ struct l2cap_conn_rsp {
|
||||
#define L2CAP_CR_AUTHORIZATION 0x0006
|
||||
#define L2CAP_CR_BAD_KEY_SIZE 0x0007
|
||||
#define L2CAP_CR_ENCRYPTION 0x0008
|
||||
#define L2CAP_CR_INVALID_SCID 0x0009
|
||||
#define L2CAP_CR_SCID_IN_USE 0x0010
|
||||
|
||||
/* connect/create channel status */
|
||||
#define L2CAP_CS_NO_INFO 0x0000
|
||||
|
@ -63,12 +63,13 @@ static inline struct metadata_dst *tun_rx_dst(int md_size)
|
||||
static inline struct metadata_dst *tun_dst_unclone(struct sk_buff *skb)
|
||||
{
|
||||
struct metadata_dst *md_dst = skb_metadata_dst(skb);
|
||||
int md_size = md_dst->u.tun_info.options_len;
|
||||
int md_size;
|
||||
struct metadata_dst *new_md;
|
||||
|
||||
if (!md_dst)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
md_size = md_dst->u.tun_info.options_len;
|
||||
new_md = metadata_dst_alloc(md_size, GFP_ATOMIC);
|
||||
if (!new_md)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -210,6 +210,18 @@ struct inet_sock {
|
||||
#define IP_CMSG_ORIGDSTADDR BIT(6)
|
||||
#define IP_CMSG_CHECKSUM BIT(7)
|
||||
|
||||
/* SYNACK messages might be attached to request sockets.
|
||||
* Some places want to reach the listener in this case.
|
||||
*/
|
||||
static inline struct sock *skb_to_full_sk(const struct sk_buff *skb)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
|
||||
if (sk && sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
sk = inet_reqsk(sk)->rsk_listener;
|
||||
return sk;
|
||||
}
|
||||
|
||||
static inline struct inet_sock *inet_sk(const struct sock *sk)
|
||||
{
|
||||
return (struct inet_sock *)sk;
|
||||
|
@ -434,7 +434,7 @@ config UPROBE_EVENT
|
||||
|
||||
config BPF_EVENTS
|
||||
depends on BPF_SYSCALL
|
||||
depends on KPROBE_EVENT || UPROBE_EVENT
|
||||
depends on (KPROBE_EVENT || UPROBE_EVENT) && PERF_EVENTS
|
||||
bool
|
||||
default y
|
||||
help
|
||||
|
@ -5055,6 +5055,36 @@ static struct bpf_test tests[] = {
|
||||
{},
|
||||
{ {0x1, 0x0 } },
|
||||
},
|
||||
{
|
||||
"MOD default X",
|
||||
.u.insns = {
|
||||
/*
|
||||
* A = 0x42
|
||||
* A = A mod X ; this halt the filter execution if X is 0
|
||||
* ret 0x42
|
||||
*/
|
||||
BPF_STMT(BPF_LD | BPF_IMM, 0x42),
|
||||
BPF_STMT(BPF_ALU | BPF_MOD | BPF_X, 0),
|
||||
BPF_STMT(BPF_RET | BPF_K, 0x42),
|
||||
},
|
||||
CLASSIC | FLAG_NO_DATA,
|
||||
{},
|
||||
{ {0x1, 0x0 } },
|
||||
},
|
||||
{
|
||||
"MOD default A",
|
||||
.u.insns = {
|
||||
/*
|
||||
* A = A mod 1
|
||||
* ret A
|
||||
*/
|
||||
BPF_STMT(BPF_ALU | BPF_MOD | BPF_K, 0x1),
|
||||
BPF_STMT(BPF_RET | BPF_A, 0x0),
|
||||
},
|
||||
CLASSIC | FLAG_NO_DATA,
|
||||
{},
|
||||
{ {0x1, 0x0 } },
|
||||
},
|
||||
{
|
||||
"JMP EQ default A",
|
||||
.u.insns = {
|
||||
|
@ -508,12 +508,6 @@ static void le_setup(struct hci_request *req)
|
||||
/* Read LE Supported States */
|
||||
hci_req_add(req, HCI_OP_LE_READ_SUPPORTED_STATES, 0, NULL);
|
||||
|
||||
/* Read LE White List Size */
|
||||
hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE, 0, NULL);
|
||||
|
||||
/* Clear LE White List */
|
||||
hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
|
||||
|
||||
/* LE-only controllers have LE implicitly enabled */
|
||||
if (!lmp_bredr_capable(hdev))
|
||||
hci_dev_set_flag(hdev, HCI_LE_ENABLED);
|
||||
@ -832,6 +826,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
|
||||
hci_req_add(req, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL);
|
||||
}
|
||||
|
||||
if (hdev->commands[26] & 0x40) {
|
||||
/* Read LE White List Size */
|
||||
hci_req_add(req, HCI_OP_LE_READ_WHITE_LIST_SIZE,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
if (hdev->commands[26] & 0x80) {
|
||||
/* Clear LE White List */
|
||||
hci_req_add(req, HCI_OP_LE_CLEAR_WHITE_LIST, 0, NULL);
|
||||
}
|
||||
|
||||
if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
|
||||
/* Read LE Maximum Data Length */
|
||||
hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
|
||||
|
@ -239,7 +239,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
|
||||
else
|
||||
dyn_end = L2CAP_CID_DYN_END;
|
||||
|
||||
for (cid = L2CAP_CID_DYN_START; cid < dyn_end; cid++) {
|
||||
for (cid = L2CAP_CID_DYN_START; cid <= dyn_end; cid++) {
|
||||
if (!__l2cap_get_chan_by_scid(conn, cid))
|
||||
return cid;
|
||||
}
|
||||
@ -5250,7 +5250,9 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
|
||||
credits = __le16_to_cpu(rsp->credits);
|
||||
result = __le16_to_cpu(rsp->result);
|
||||
|
||||
if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23))
|
||||
if (result == L2CAP_CR_SUCCESS && (mtu < 23 || mps < 23 ||
|
||||
dcid < L2CAP_CID_DYN_START ||
|
||||
dcid > L2CAP_CID_LE_DYN_END))
|
||||
return -EPROTO;
|
||||
|
||||
BT_DBG("dcid 0x%4.4x mtu %u mps %u credits %u result 0x%2.2x",
|
||||
@ -5270,6 +5272,11 @@ static int l2cap_le_connect_rsp(struct l2cap_conn *conn,
|
||||
|
||||
switch (result) {
|
||||
case L2CAP_CR_SUCCESS:
|
||||
if (__l2cap_get_chan_by_dcid(conn, dcid)) {
|
||||
err = -EBADSLT;
|
||||
break;
|
||||
}
|
||||
|
||||
chan->ident = 0;
|
||||
chan->dcid = dcid;
|
||||
chan->omtu = mtu;
|
||||
@ -5437,9 +5444,16 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
|
||||
goto response_unlock;
|
||||
}
|
||||
|
||||
/* Check for valid dynamic CID range */
|
||||
if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) {
|
||||
result = L2CAP_CR_INVALID_SCID;
|
||||
chan = NULL;
|
||||
goto response_unlock;
|
||||
}
|
||||
|
||||
/* Check if we already have channel with that dcid */
|
||||
if (__l2cap_get_chan_by_dcid(conn, scid)) {
|
||||
result = L2CAP_CR_NO_MEM;
|
||||
result = L2CAP_CR_SCID_IN_USE;
|
||||
chan = NULL;
|
||||
goto response_unlock;
|
||||
}
|
||||
|
@ -600,12 +600,17 @@ void __br_set_forward_delay(struct net_bridge *br, unsigned long t)
|
||||
int br_set_forward_delay(struct net_bridge *br, unsigned long val)
|
||||
{
|
||||
unsigned long t = clock_t_to_jiffies(val);
|
||||
|
||||
if (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)
|
||||
return -ERANGE;
|
||||
int err = -ERANGE;
|
||||
|
||||
spin_lock_bh(&br->lock);
|
||||
if (br->stp_enabled != BR_NO_STP &&
|
||||
(t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY))
|
||||
goto unlock;
|
||||
|
||||
__br_set_forward_delay(br, t);
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
spin_unlock_bh(&br->lock);
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
@ -6402,7 +6402,7 @@ int __netdev_update_features(struct net_device *dev)
|
||||
struct net_device *upper, *lower;
|
||||
netdev_features_t features;
|
||||
struct list_head *iter;
|
||||
int err = 0;
|
||||
int err = -1;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
@ -6419,7 +6419,7 @@ int __netdev_update_features(struct net_device *dev)
|
||||
features = netdev_sync_upper_features(dev, upper, features);
|
||||
|
||||
if (dev->features == features)
|
||||
return 0;
|
||||
goto sync_lower;
|
||||
|
||||
netdev_dbg(dev, "Features changed: %pNF -> %pNF\n",
|
||||
&dev->features, &features);
|
||||
@ -6434,6 +6434,7 @@ int __netdev_update_features(struct net_device *dev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sync_lower:
|
||||
/* some features must be disabled on lower devices when disabled
|
||||
* on an upper device (think: bonding master or bridge)
|
||||
*/
|
||||
@ -6443,7 +6444,7 @@ int __netdev_update_features(struct net_device *dev)
|
||||
if (!err)
|
||||
dev->features = features;
|
||||
|
||||
return 1;
|
||||
return err < 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -306,7 +306,7 @@ void dst_release(struct dst_entry *dst)
|
||||
if (unlikely(newrefcnt < 0))
|
||||
net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
|
||||
__func__, dst, newrefcnt);
|
||||
if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt)
|
||||
if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
|
||||
call_rcu(&dst->rcu_head, dst_destroy_rcu);
|
||||
}
|
||||
}
|
||||
|
@ -923,14 +923,21 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
|
||||
if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
|
||||
fib_prefsrc != cfg->fc_dst) {
|
||||
u32 tb_id = cfg->fc_table;
|
||||
int rc;
|
||||
|
||||
if (tb_id == RT_TABLE_MAIN)
|
||||
tb_id = RT_TABLE_LOCAL;
|
||||
|
||||
if (inet_addr_type_table(cfg->fc_nlinfo.nl_net,
|
||||
fib_prefsrc, tb_id) != RTN_LOCAL) {
|
||||
return false;
|
||||
rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
|
||||
fib_prefsrc, tb_id);
|
||||
|
||||
if (rc != RTN_LOCAL && tb_id != RT_TABLE_LOCAL) {
|
||||
rc = inet_addr_type_table(cfg->fc_nlinfo.nl_net,
|
||||
fib_prefsrc, RT_TABLE_LOCAL);
|
||||
}
|
||||
|
||||
if (rc != RTN_LOCAL)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -2392,11 +2392,11 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
||||
struct ip_sf_socklist *psl;
|
||||
struct net *net = sock_net(sk);
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!ipv4_is_multicast(addr))
|
||||
return -EINVAL;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
imr.imr_multiaddr.s_addr = msf->imsf_multiaddr;
|
||||
imr.imr_address.s_addr = msf->imsf_interface;
|
||||
imr.imr_ifindex = 0;
|
||||
@ -2417,7 +2417,6 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
||||
goto done;
|
||||
msf->imsf_fmode = pmc->sfmode;
|
||||
psl = rtnl_dereference(pmc->sflist);
|
||||
rtnl_unlock();
|
||||
if (!psl) {
|
||||
len = 0;
|
||||
count = 0;
|
||||
@ -2436,7 +2435,6 @@ int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
done:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -2450,6 +2448,8 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
struct ip_sf_socklist *psl;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
psin = (struct sockaddr_in *)&gsf->gf_group;
|
||||
if (psin->sin_family != AF_INET)
|
||||
return -EINVAL;
|
||||
@ -2457,8 +2457,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
||||
if (!ipv4_is_multicast(addr))
|
||||
return -EINVAL;
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
err = -EADDRNOTAVAIL;
|
||||
|
||||
for_each_pmc_rtnl(inet, pmc) {
|
||||
@ -2470,7 +2468,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
||||
goto done;
|
||||
gsf->gf_fmode = pmc->sfmode;
|
||||
psl = rtnl_dereference(pmc->sflist);
|
||||
rtnl_unlock();
|
||||
count = psl ? psl->sl_count : 0;
|
||||
copycount = count < gsf->gf_numsrc ? count : gsf->gf_numsrc;
|
||||
gsf->gf_numsrc = count;
|
||||
@ -2490,7 +2487,6 @@ int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
|
||||
}
|
||||
return 0;
|
||||
done:
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1251,11 +1251,22 @@ EXPORT_SYMBOL(compat_ip_setsockopt);
|
||||
* the _received_ ones. The set sets the _sent_ ones.
|
||||
*/
|
||||
|
||||
static bool getsockopt_needs_rtnl(int optname)
|
||||
{
|
||||
switch (optname) {
|
||||
case IP_MSFILTER:
|
||||
case MCAST_MSFILTER:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
||||
char __user *optval, int __user *optlen, unsigned int flags)
|
||||
{
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
int val;
|
||||
bool needs_rtnl = getsockopt_needs_rtnl(optname);
|
||||
int val, err = 0;
|
||||
int len;
|
||||
|
||||
if (level != SOL_IP)
|
||||
@ -1269,6 +1280,8 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (needs_rtnl)
|
||||
rtnl_lock();
|
||||
lock_sock(sk);
|
||||
|
||||
switch (optname) {
|
||||
@ -1386,39 +1399,35 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
||||
case IP_MSFILTER:
|
||||
{
|
||||
struct ip_msfilter msf;
|
||||
int err;
|
||||
|
||||
if (len < IP_MSFILTER_SIZE(0)) {
|
||||
release_sock(sk);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
|
||||
release_sock(sk);
|
||||
return -EFAULT;
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
err = ip_mc_msfget(sk, &msf,
|
||||
(struct ip_msfilter __user *)optval, optlen);
|
||||
release_sock(sk);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
case MCAST_MSFILTER:
|
||||
{
|
||||
struct group_filter gsf;
|
||||
int err;
|
||||
|
||||
if (len < GROUP_FILTER_SIZE(0)) {
|
||||
release_sock(sk);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
|
||||
release_sock(sk);
|
||||
return -EFAULT;
|
||||
err = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
err = ip_mc_gsfget(sk, &gsf,
|
||||
(struct group_filter __user *)optval,
|
||||
optlen);
|
||||
release_sock(sk);
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
case IP_MULTICAST_ALL:
|
||||
val = inet->mc_all;
|
||||
@ -1485,6 +1494,12 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
out:
|
||||
release_sock(sk);
|
||||
if (needs_rtnl)
|
||||
rtnl_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
int ip_getsockopt(struct sock *sk, int level,
|
||||
|
@ -67,10 +67,9 @@ static unsigned int ipv4_conntrack_defrag(void *priv,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
struct inet_sock *inet = inet_sk(skb->sk);
|
||||
|
||||
if (sk && (sk->sk_family == PF_INET) &&
|
||||
inet->nodefrag)
|
||||
if (sk && sk_fullsock(sk) && (sk->sk_family == PF_INET) &&
|
||||
inet_sk(sk)->nodefrag)
|
||||
return NF_ACCEPT;
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
|
||||
|
@ -48,14 +48,14 @@ static void set_local_port_range(struct net *net, int range[2])
|
||||
{
|
||||
bool same_parity = !((range[0] ^ range[1]) & 1);
|
||||
|
||||
write_seqlock(&net->ipv4.ip_local_ports.lock);
|
||||
write_seqlock_bh(&net->ipv4.ip_local_ports.lock);
|
||||
if (same_parity && !net->ipv4.ip_local_ports.warned) {
|
||||
net->ipv4.ip_local_ports.warned = true;
|
||||
pr_err_ratelimited("ip_local_port_range: prefer different parity for start/end values.\n");
|
||||
}
|
||||
net->ipv4.ip_local_ports.range[0] = range[0];
|
||||
net->ipv4.ip_local_ports.range[1] = range[1];
|
||||
write_sequnlock(&net->ipv4.ip_local_ports.lock);
|
||||
write_sequnlock_bh(&net->ipv4.ip_local_ports.lock);
|
||||
}
|
||||
|
||||
/* Validate changes from /proc interface. */
|
||||
|
@ -1326,6 +1326,8 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
|
||||
if (__inet_inherit_port(sk, newsk) < 0)
|
||||
goto put_and_exit;
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
if (*own_req)
|
||||
tcp_move_syn(newtp, req);
|
||||
|
||||
return newsk;
|
||||
|
||||
|
@ -551,9 +551,6 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
|
||||
newtp->rack.mstamp.v64 = 0;
|
||||
newtp->rack.advanced = 0;
|
||||
|
||||
newtp->saved_syn = req->saved_syn;
|
||||
req->saved_syn = NULL;
|
||||
|
||||
TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS);
|
||||
}
|
||||
return newsk;
|
||||
|
@ -418,6 +418,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
|
||||
if (err) {
|
||||
ipv6_mc_destroy_dev(ndev);
|
||||
del_timer(&ndev->regen_timer);
|
||||
snmp6_unregister_dev(ndev);
|
||||
goto err_release;
|
||||
}
|
||||
/* protected by rtnl_lock */
|
||||
|
@ -1140,14 +1140,18 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *
|
||||
goto out;
|
||||
}
|
||||
*own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash));
|
||||
/* Clone pktoptions received with SYN, if we own the req */
|
||||
if (*own_req && ireq->pktopts) {
|
||||
newnp->pktoptions = skb_clone(ireq->pktopts,
|
||||
sk_gfp_atomic(sk, GFP_ATOMIC));
|
||||
consume_skb(ireq->pktopts);
|
||||
ireq->pktopts = NULL;
|
||||
if (newnp->pktoptions)
|
||||
skb_set_owner_r(newnp->pktoptions, newsk);
|
||||
if (*own_req) {
|
||||
tcp_move_syn(newtp, req);
|
||||
|
||||
/* Clone pktoptions received with SYN, if we own the req */
|
||||
if (ireq->pktopts) {
|
||||
newnp->pktoptions = skb_clone(ireq->pktopts,
|
||||
sk_gfp_atomic(sk, GFP_ATOMIC));
|
||||
consume_skb(ireq->pktopts);
|
||||
ireq->pktopts = NULL;
|
||||
if (newnp->pktoptions)
|
||||
skb_set_owner_r(newnp->pktoptions, newsk);
|
||||
}
|
||||
}
|
||||
|
||||
return newsk;
|
||||
|
@ -55,7 +55,7 @@ nf_nat_redirect_ipv4(struct sk_buff *skb,
|
||||
|
||||
rcu_read_lock();
|
||||
indev = __in_dev_get_rcu(skb->dev);
|
||||
if (indev != NULL) {
|
||||
if (indev && indev->ifa_list) {
|
||||
ifa = indev->ifa_list;
|
||||
newdst = ifa->ifa_local;
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ static int nfnetlink_bind(struct net *net, int group)
|
||||
type = nfnl_group2type[group];
|
||||
|
||||
rcu_read_lock();
|
||||
ss = nfnetlink_get_subsys(type);
|
||||
ss = nfnetlink_get_subsys(type << 8);
|
||||
rcu_read_unlock();
|
||||
if (!ss)
|
||||
request_module("nfnetlink-subsys-%d", type);
|
||||
|
@ -31,6 +31,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
|
||||
const struct nft_meta *priv = nft_expr_priv(expr);
|
||||
const struct sk_buff *skb = pkt->skb;
|
||||
const struct net_device *in = pkt->in, *out = pkt->out;
|
||||
struct sock *sk;
|
||||
u32 *dest = ®s->data[priv->dreg];
|
||||
|
||||
switch (priv->key) {
|
||||
@ -86,33 +87,35 @@ void nft_meta_get_eval(const struct nft_expr *expr,
|
||||
*(u16 *)dest = out->type;
|
||||
break;
|
||||
case NFT_META_SKUID:
|
||||
if (skb->sk == NULL || !sk_fullsock(skb->sk))
|
||||
sk = skb_to_full_sk(skb);
|
||||
if (!sk || !sk_fullsock(sk))
|
||||
goto err;
|
||||
|
||||
read_lock_bh(&skb->sk->sk_callback_lock);
|
||||
if (skb->sk->sk_socket == NULL ||
|
||||
skb->sk->sk_socket->file == NULL) {
|
||||
read_unlock_bh(&skb->sk->sk_callback_lock);
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
if (sk->sk_socket == NULL ||
|
||||
sk->sk_socket->file == NULL) {
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*dest = from_kuid_munged(&init_user_ns,
|
||||
skb->sk->sk_socket->file->f_cred->fsuid);
|
||||
read_unlock_bh(&skb->sk->sk_callback_lock);
|
||||
sk->sk_socket->file->f_cred->fsuid);
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
break;
|
||||
case NFT_META_SKGID:
|
||||
if (skb->sk == NULL || !sk_fullsock(skb->sk))
|
||||
sk = skb_to_full_sk(skb);
|
||||
if (!sk || !sk_fullsock(sk))
|
||||
goto err;
|
||||
|
||||
read_lock_bh(&skb->sk->sk_callback_lock);
|
||||
if (skb->sk->sk_socket == NULL ||
|
||||
skb->sk->sk_socket->file == NULL) {
|
||||
read_unlock_bh(&skb->sk->sk_callback_lock);
|
||||
read_lock_bh(&sk->sk_callback_lock);
|
||||
if (sk->sk_socket == NULL ||
|
||||
sk->sk_socket->file == NULL) {
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
goto err;
|
||||
}
|
||||
*dest = from_kgid_munged(&init_user_ns,
|
||||
skb->sk->sk_socket->file->f_cred->fsgid);
|
||||
read_unlock_bh(&skb->sk->sk_callback_lock);
|
||||
sk->sk_socket->file->f_cred->fsgid);
|
||||
read_unlock_bh(&sk->sk_callback_lock);
|
||||
break;
|
||||
#ifdef CONFIG_IP_ROUTE_CLASSID
|
||||
case NFT_META_RTCLASSID: {
|
||||
@ -168,9 +171,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
|
||||
break;
|
||||
#ifdef CONFIG_CGROUP_NET_CLASSID
|
||||
case NFT_META_CGROUP:
|
||||
if (skb->sk == NULL || !sk_fullsock(skb->sk))
|
||||
sk = skb_to_full_sk(skb);
|
||||
if (!sk || !sk_fullsock(sk))
|
||||
goto err;
|
||||
*dest = skb->sk->sk_classid;
|
||||
*dest = sk->sk_classid;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -31,8 +31,9 @@ static unsigned int
|
||||
tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_tee_tginfo *info = par->targinfo;
|
||||
int oif = info->priv ? info->priv->oif : 0;
|
||||
|
||||
nf_dup_ipv4(par->net, skb, par->hooknum, &info->gw.in, info->priv->oif);
|
||||
nf_dup_ipv4(par->net, skb, par->hooknum, &info->gw.in, oif);
|
||||
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
@ -42,8 +43,9 @@ static unsigned int
|
||||
tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_tee_tginfo *info = par->targinfo;
|
||||
int oif = info->priv ? info->priv->oif : 0;
|
||||
|
||||
nf_dup_ipv6(par->net, skb, par->hooknum, &info->gw.in6, info->priv->oif);
|
||||
nf_dup_ipv6(par->net, skb, par->hooknum, &info->gw.in6, oif);
|
||||
|
||||
return XT_CONTINUE;
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/file.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/inet_sock.h>
|
||||
#include <linux/netfilter/x_tables.h>
|
||||
#include <linux/netfilter/xt_owner.h>
|
||||
|
||||
@ -33,8 +34,9 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
{
|
||||
const struct xt_owner_match_info *info = par->matchinfo;
|
||||
const struct file *filp;
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (skb->sk == NULL || skb->sk->sk_socket == NULL)
|
||||
if (sk == NULL || sk->sk_socket == NULL)
|
||||
return (info->match ^ info->invert) == 0;
|
||||
else if (info->match & info->invert & XT_OWNER_SOCKET)
|
||||
/*
|
||||
@ -43,7 +45,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
*/
|
||||
return false;
|
||||
|
||||
filp = skb->sk->sk_socket->file;
|
||||
filp = sk->sk_socket->file;
|
||||
if (filp == NULL)
|
||||
return ((info->match ^ info->invert) &
|
||||
(XT_OWNER_UID | XT_OWNER_GID)) == 0;
|
||||
|
@ -2911,22 +2911,40 @@ static int packet_release(struct socket *sock)
|
||||
* Attach a packet hook.
|
||||
*/
|
||||
|
||||
static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
|
||||
static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
|
||||
__be16 proto)
|
||||
{
|
||||
struct packet_sock *po = pkt_sk(sk);
|
||||
struct net_device *dev_curr;
|
||||
__be16 proto_curr;
|
||||
bool need_rehook;
|
||||
struct net_device *dev = NULL;
|
||||
int ret = 0;
|
||||
bool unlisted = false;
|
||||
|
||||
if (po->fanout) {
|
||||
if (dev)
|
||||
dev_put(dev);
|
||||
|
||||
if (po->fanout)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lock_sock(sk);
|
||||
spin_lock(&po->bind_lock);
|
||||
rcu_read_lock();
|
||||
|
||||
if (name) {
|
||||
dev = dev_get_by_name_rcu(sock_net(sk), name);
|
||||
if (!dev) {
|
||||
ret = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
} else if (ifindex) {
|
||||
dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
|
||||
if (!dev) {
|
||||
ret = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev)
|
||||
dev_hold(dev);
|
||||
|
||||
proto_curr = po->prot_hook.type;
|
||||
dev_curr = po->prot_hook.dev;
|
||||
@ -2934,14 +2952,29 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
|
||||
need_rehook = proto_curr != proto || dev_curr != dev;
|
||||
|
||||
if (need_rehook) {
|
||||
unregister_prot_hook(sk, true);
|
||||
if (po->running) {
|
||||
rcu_read_unlock();
|
||||
__unregister_prot_hook(sk, true);
|
||||
rcu_read_lock();
|
||||
dev_curr = po->prot_hook.dev;
|
||||
if (dev)
|
||||
unlisted = !dev_get_by_index_rcu(sock_net(sk),
|
||||
dev->ifindex);
|
||||
}
|
||||
|
||||
po->num = proto;
|
||||
po->prot_hook.type = proto;
|
||||
po->prot_hook.dev = dev;
|
||||
|
||||
po->ifindex = dev ? dev->ifindex : 0;
|
||||
packet_cached_dev_assign(po, dev);
|
||||
if (unlikely(unlisted)) {
|
||||
dev_put(dev);
|
||||
po->prot_hook.dev = NULL;
|
||||
po->ifindex = -1;
|
||||
packet_cached_dev_reset(po);
|
||||
} else {
|
||||
po->prot_hook.dev = dev;
|
||||
po->ifindex = dev ? dev->ifindex : 0;
|
||||
packet_cached_dev_assign(po, dev);
|
||||
}
|
||||
}
|
||||
if (dev_curr)
|
||||
dev_put(dev_curr);
|
||||
@ -2949,7 +2982,7 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
|
||||
if (proto == 0 || !need_rehook)
|
||||
goto out_unlock;
|
||||
|
||||
if (!dev || (dev->flags & IFF_UP)) {
|
||||
if (!unlisted && (!dev || (dev->flags & IFF_UP))) {
|
||||
register_prot_hook(sk);
|
||||
} else {
|
||||
sk->sk_err = ENETDOWN;
|
||||
@ -2958,9 +2991,10 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 proto)
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
rcu_read_unlock();
|
||||
spin_unlock(&po->bind_lock);
|
||||
release_sock(sk);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2972,8 +3006,6 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
char name[15];
|
||||
struct net_device *dev;
|
||||
int err = -ENODEV;
|
||||
|
||||
/*
|
||||
* Check legality
|
||||
@ -2983,19 +3015,13 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr,
|
||||
return -EINVAL;
|
||||
strlcpy(name, uaddr->sa_data, sizeof(name));
|
||||
|
||||
dev = dev_get_by_name(sock_net(sk), name);
|
||||
if (dev)
|
||||
err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
|
||||
return err;
|
||||
return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
|
||||
}
|
||||
|
||||
static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
|
||||
struct sock *sk = sock->sk;
|
||||
struct net_device *dev = NULL;
|
||||
int err;
|
||||
|
||||
|
||||
/*
|
||||
* Check legality
|
||||
@ -3006,16 +3032,8 @@ static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len
|
||||
if (sll->sll_family != AF_PACKET)
|
||||
return -EINVAL;
|
||||
|
||||
if (sll->sll_ifindex) {
|
||||
err = -ENODEV;
|
||||
dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex);
|
||||
if (dev == NULL)
|
||||
goto out;
|
||||
}
|
||||
err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num);
|
||||
|
||||
out:
|
||||
return err;
|
||||
return packet_do_bind(sk, NULL, sll->sll_ifindex,
|
||||
sll->sll_protocol ? : pkt_sk(sk)->num);
|
||||
}
|
||||
|
||||
static struct proto packet_proto = {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <net/inet_sock.h>
|
||||
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/ip.h>
|
||||
@ -197,8 +198,11 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb)
|
||||
|
||||
static u32 flow_get_skuid(const struct sk_buff *skb)
|
||||
{
|
||||
if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
|
||||
kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid;
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (sk && sk->sk_socket && sk->sk_socket->file) {
|
||||
kuid_t skuid = sk->sk_socket->file->f_cred->fsuid;
|
||||
|
||||
return from_kuid(&init_user_ns, skuid);
|
||||
}
|
||||
return 0;
|
||||
@ -206,8 +210,11 @@ static u32 flow_get_skuid(const struct sk_buff *skb)
|
||||
|
||||
static u32 flow_get_skgid(const struct sk_buff *skb)
|
||||
{
|
||||
if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) {
|
||||
kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid;
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (sk && sk->sk_socket && sk->sk_socket->file) {
|
||||
kgid_t skgid = sk->sk_socket->file->f_cred->fsgid;
|
||||
|
||||
return from_kgid(&init_user_ns, skgid);
|
||||
}
|
||||
return 0;
|
||||
|
@ -343,119 +343,145 @@ META_COLLECTOR(int_sk_refcnt)
|
||||
|
||||
META_COLLECTOR(int_sk_rcvbuf)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_rcvbuf;
|
||||
dst->value = sk->sk_rcvbuf;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_shutdown)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_shutdown;
|
||||
dst->value = sk->sk_shutdown;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_proto)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_protocol;
|
||||
dst->value = sk->sk_protocol;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_type)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_type;
|
||||
dst->value = sk->sk_type;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_rmem_alloc)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = sk_rmem_alloc_get(skb->sk);
|
||||
dst->value = sk_rmem_alloc_get(sk);
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_wmem_alloc)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = sk_wmem_alloc_get(skb->sk);
|
||||
dst->value = sk_wmem_alloc_get(sk);
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_omem_alloc)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = atomic_read(&skb->sk->sk_omem_alloc);
|
||||
dst->value = atomic_read(&sk->sk_omem_alloc);
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_rcv_qlen)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_receive_queue.qlen;
|
||||
dst->value = sk->sk_receive_queue.qlen;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_snd_qlen)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_write_queue.qlen;
|
||||
dst->value = sk->sk_write_queue.qlen;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_wmem_queued)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_wmem_queued;
|
||||
dst->value = sk->sk_wmem_queued;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_fwd_alloc)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_forward_alloc;
|
||||
dst->value = sk->sk_forward_alloc;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_sndbuf)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_sndbuf;
|
||||
dst->value = sk->sk_sndbuf;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_alloc)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = (__force int) skb->sk->sk_allocation;
|
||||
dst->value = (__force int) sk->sk_allocation;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_hash)
|
||||
@ -469,92 +495,112 @@ META_COLLECTOR(int_sk_hash)
|
||||
|
||||
META_COLLECTOR(int_sk_lingertime)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_lingertime / HZ;
|
||||
dst->value = sk->sk_lingertime / HZ;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_err_qlen)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_error_queue.qlen;
|
||||
dst->value = sk->sk_error_queue.qlen;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_ack_bl)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_ack_backlog;
|
||||
dst->value = sk->sk_ack_backlog;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_max_ack_bl)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_max_ack_backlog;
|
||||
dst->value = sk->sk_max_ack_backlog;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_prio)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_priority;
|
||||
dst->value = sk->sk_priority;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_rcvlowat)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_rcvlowat;
|
||||
dst->value = sk->sk_rcvlowat;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_rcvtimeo)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_rcvtimeo / HZ;
|
||||
dst->value = sk->sk_rcvtimeo / HZ;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_sndtimeo)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_sndtimeo / HZ;
|
||||
dst->value = sk->sk_sndtimeo / HZ;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_sendmsg_off)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_frag.offset;
|
||||
dst->value = sk->sk_frag.offset;
|
||||
}
|
||||
|
||||
META_COLLECTOR(int_sk_write_pend)
|
||||
{
|
||||
if (skip_nonlocal(skb)) {
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
|
||||
if (!sk) {
|
||||
*err = -1;
|
||||
return;
|
||||
}
|
||||
dst->value = skb->sk->sk_write_pending;
|
||||
dst->value = sk->sk_write_pending;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -1234,7 +1234,7 @@ vmci_transport_recv_connecting_server(struct sock *listener,
|
||||
/* Callers of accept() will be be waiting on the listening socket, not
|
||||
* the pending socket.
|
||||
*/
|
||||
listener->sk_state_change(listener);
|
||||
listener->sk_data_ready(listener);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -4933,7 +4933,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
|
||||
int ifindex,
|
||||
u16 family)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
struct sk_security_struct *sksec;
|
||||
struct common_audit_data ad;
|
||||
struct lsm_network_audit net = {0,};
|
||||
@ -4988,7 +4988,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
|
||||
if (!secmark_active && !peerlbl_active)
|
||||
return NF_ACCEPT;
|
||||
|
||||
sk = skb->sk;
|
||||
sk = skb_to_full_sk(skb);
|
||||
|
||||
#ifdef CONFIG_XFRM
|
||||
/* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
|
||||
@ -5033,8 +5033,6 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb,
|
||||
u32 skb_sid;
|
||||
struct sk_security_struct *sksec;
|
||||
|
||||
if (sk->sk_state == TCP_NEW_SYN_RECV)
|
||||
sk = inet_reqsk(sk)->rsk_listener;
|
||||
sksec = sk->sk_security;
|
||||
if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
|
||||
return NF_DROP;
|
||||
|
@ -245,7 +245,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
|
||||
|
||||
/* if this is a locally generated packet check to see if it is already
|
||||
* being labeled by it's parent socket, if it is just exit */
|
||||
sk = skb->sk;
|
||||
sk = skb_to_full_sk(skb);
|
||||
if (sk != NULL) {
|
||||
struct sk_security_struct *sksec = sk->sk_security;
|
||||
if (sksec->nlbl_state != NLBL_REQSKB)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/netfilter_ipv4.h>
|
||||
#include <linux/netfilter_ipv6.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/inet_sock.h>
|
||||
#include "smack.h"
|
||||
|
||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||
@ -25,11 +26,12 @@ static unsigned int smack_ipv6_output(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
struct socket_smack *ssp;
|
||||
struct smack_known *skp;
|
||||
|
||||
if (skb && skb->sk && skb->sk->sk_security) {
|
||||
ssp = skb->sk->sk_security;
|
||||
if (sk && sk->sk_security) {
|
||||
ssp = sk->sk_security;
|
||||
skp = ssp->smk_out;
|
||||
skb->secmark = skp->smk_secid;
|
||||
}
|
||||
@ -42,11 +44,12 @@ static unsigned int smack_ipv4_output(void *priv,
|
||||
struct sk_buff *skb,
|
||||
const struct nf_hook_state *state)
|
||||
{
|
||||
struct sock *sk = skb_to_full_sk(skb);
|
||||
struct socket_smack *ssp;
|
||||
struct smack_known *skp;
|
||||
|
||||
if (skb && skb->sk && skb->sk->sk_security) {
|
||||
ssp = skb->sk->sk_security;
|
||||
if (sk && sk->sk_security) {
|
||||
ssp = sk->sk_security;
|
||||
skp = ssp->smk_out;
|
||||
skb->secmark = skp->smk_secid;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user