Networking fixes for 5.17-rc5, including fixes from wireless and
netfilter. Current release - regressions: - dsa: lantiq_gswip: fix use after free in gswip_remove() - smc: avoid overwriting the copies of clcsock callback functions Current release - new code bugs: - iwlwifi: - fix use-after-free when no FW is present - mei: fix the pskb_may_pull check in ipv4 - mei: retry mapping the shared area - mvm: don't feed the hardware RFKILL into iwlmei Previous releases - regressions: - ipv6: mcast: use rcu-safe version of ipv6_get_lladdr() - tipc: fix wrong publisher node address in link publications - iwlwifi: mvm: don't send SAR GEO command for 3160 devices, avoid FW assertion - bgmac: make idm and nicpm resource optional again - atl1c: fix tx timeout after link flap Previous releases - always broken: - vsock: remove vsock from connected table when connect is interrupted by a signal - ping: change destination interface checks to match raw sockets - crypto: af_alg - get rid of alg_memory_allocated to avoid confusing semantics (and null-deref) after SO_RESERVE_MEM was added - ipv6: make exclusive flowlabel checks per-netns - bonding: force carrier update when releasing slave - sched: limit TC_ACT_REPEAT loops - bridge: multicast: notify switchdev driver whenever MC processing gets disabled because of max entries reached - wifi: brcmfmac: fix crash in brcm_alt_fw_path when WLAN not found - iwlwifi: fix locking when "HW not ready" - phy: mediatek: remove PHY mode check on MT7531 - dsa: mv88e6xxx: flush switchdev FDB workqueue before removing VLAN - dsa: lan9303: - fix polarity of reset during probe - fix accelerated VLAN handling Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmIOm44ACgkQMUZtbf5S IruWWBAAmNJBxVoVUahidwIVKHnKYeHClzDee3B6sYSupRW22Eeuh7Q8fqPMO4J7 KO9nP/vGibFuhKfjApvS6wPvpYWCuXAoSozfOa+JWNrFg9uVpdyHIhfdXl0WPZqx A4+p2vIs1ldV0yOac/7ZGMWg57dzlYUurkld3xFwf7KyOOhV5/PkxkxpGN9eFkv1 NTFWTaIsVzFMXMjNXkGfGHmt/8mSmZHgsH+tYd+KXsjbs2UpbGM3SyfHBlUf3aA0 bceT4h07xA6C4rlUCbmalRqwvtcdM15MwlDBtSBXm5fXy0c59XxQOqj/dLhPuAO4 42sQlO2MhqDrZjR0tOjmuP2cpc7llj1lIZe1Qs3nKiNFHcuOJEHGw1PYCO85jKdn xiWquuoe3G5YkQeoOoi+HqmXcP6aBZpUbROvYNjSJhcci4Ck0Qjna5J1rk8IRjb8 AkDf68dodn8I+W5dx/EnopH/ShPQcqGw1+tH4215UB7b40Ecpc+laqFAHRcgs654 ONuJVdRC4k3TyES1B9z8vawLcGYWa06fz8Mh/dS3gnLDphe5ZiH2tTrESfBdYixH idmuO5C/YDhsVelVuO+B0RT/yziPb3Lr+BTplSfkODCXT6LuOdCYUcHx5nGZ1TYW EeZ9hMSaxp2E06llEyD6JQQ+0Q17wnDGjLxtOMk+A8fmNX2F17g= =Nrzq -----END PGP SIGNATURE----- Merge tag 'net-5.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from wireless and netfilter. Current release - regressions: - dsa: lantiq_gswip: fix use after free in gswip_remove() - smc: avoid overwriting the copies of clcsock callback functions Current release - new code bugs: - iwlwifi: - fix use-after-free when no FW is present - mei: fix the pskb_may_pull check in ipv4 - mei: retry mapping the shared area - mvm: don't feed the hardware RFKILL into iwlmei Previous releases - regressions: - ipv6: mcast: use rcu-safe version of ipv6_get_lladdr() - tipc: fix wrong publisher node address in link publications - iwlwifi: mvm: don't send SAR GEO command for 3160 devices, avoid FW assertion - bgmac: make idm and nicpm resource optional again - atl1c: fix tx timeout after link flap Previous releases - always broken: - vsock: remove vsock from connected table when connect is interrupted by a signal - ping: change destination interface checks to match raw sockets - crypto: af_alg - get rid of alg_memory_allocated to avoid confusing semantics (and null-deref) after SO_RESERVE_MEM was added - ipv6: make exclusive flowlabel checks per-netns - bonding: force carrier update when releasing slave - sched: limit TC_ACT_REPEAT loops - bridge: multicast: notify switchdev driver whenever MC processing gets disabled because of max entries reached - wifi: brcmfmac: fix crash in brcm_alt_fw_path when WLAN not found - iwlwifi: fix locking when "HW not ready" - phy: mediatek: remove PHY mode check on MT7531 - dsa: mv88e6xxx: flush switchdev FDB workqueue before removing VLAN - dsa: lan9303: - fix polarity of reset during probe - fix accelerated VLAN handling" * tag 'net-5.17-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (65 commits) bonding: force carrier update when releasing slave nfp: flower: netdev offload check for ip6gretap ipv6: fix data-race in fib6_info_hw_flags_set / fib6_purge_rt ipv4: fix data races in fib_alias_hw_flags_set net: dsa: lan9303: add VLAN IDs to master device net: dsa: lan9303: handle hwaccel VLAN tags vsock: remove vsock from connected table when connect is interrupted by a signal Revert "net: ethernet: bgmac: Use devm_platform_ioremap_resource_byname" ping: fix the dif and sdif check in ping_lookup net: usb: cdc_mbim: avoid altsetting toggling for Telit FN990 net: sched: limit TC_ACT_REPEAT loops tipc: fix wrong notification node addresses net: dsa: lantiq_gswip: fix use after free in gswip_remove() ipv6: per-netns exclusive flowlabel checks net: bridge: multicast: notify switchdev driver whenever MC processing gets disabled CDC-NCM: avoid overflow in sanity checking mctp: fix use after free net: mscc: ocelot: fix use-after-free in ocelot_vlan_del() bonding: fix data-races around agg_select_timer dpaa2-eth: Initialize mutex used in one step timestamping path ...
This commit is contained in:
commit
8b97cae315
15
MAINTAINERS
15
MAINTAINERS
|
@ -3139,11 +3139,9 @@ W: https://wireless.wiki.kernel.org/en/users/Drivers/ath5k
|
|||
F: drivers/net/wireless/ath/ath5k/
|
||||
|
||||
ATHEROS ATH6KL WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
S: Orphan
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath6kl
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
F: drivers/net/wireless/ath/ath6kl/
|
||||
|
||||
ATI_REMOTE2 DRIVER
|
||||
|
@ -7188,7 +7186,7 @@ F: drivers/net/can/usb/etas_es58x/
|
|||
|
||||
ETHERNET BRIDGE
|
||||
M: Roopa Prabhu <roopa@nvidia.com>
|
||||
M: Nikolay Aleksandrov <nikolay@nvidia.com>
|
||||
M: Nikolay Aleksandrov <razor@blackwall.org>
|
||||
L: bridge@lists.linux-foundation.org (moderated for non-subscribers)
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -15912,6 +15910,7 @@ S: Supported
|
|||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
F: drivers/net/wireless/ath/ath10k/
|
||||
F: Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
|
||||
|
||||
QUALCOMM ATHEROS ATH11K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
|
@ -15919,11 +15918,12 @@ L: ath11k@lists.infradead.org
|
|||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
|
||||
F: drivers/net/wireless/ath/ath11k/
|
||||
F: Documentation/devicetree/bindings/net/wireless/qcom,ath11k.txt
|
||||
|
||||
QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
|
||||
M: ath9k-devel@qca.qualcomm.com
|
||||
M: Toke Høiland-Jørgensen <toke@toke.dk>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
S: Maintained
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/ath9k
|
||||
F: Documentation/devicetree/bindings/net/wireless/qca,ath9k.yaml
|
||||
F: drivers/net/wireless/ath/ath9k/
|
||||
|
@ -16104,11 +16104,10 @@ F: Documentation/devicetree/bindings/media/*venus*
|
|||
F: drivers/media/platform/qcom/venus/
|
||||
|
||||
QUALCOMM WCN36XX WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@kernel.org>
|
||||
M: Loic Poulain <loic.poulain@linaro.org>
|
||||
L: wcn36xx@lists.infradead.org
|
||||
S: Supported
|
||||
W: https://wireless.wiki.kernel.org/en/users/Drivers/wcn36xx
|
||||
T: git git://github.com/KrasnikovEugene/wcn36xx.git
|
||||
F: drivers/net/wireless/ath/wcn36xx/
|
||||
|
||||
QUANTENNA QTNFMAC WIRELESS DRIVER
|
||||
|
|
|
@ -25,12 +25,9 @@ struct alg_type_list {
|
|||
struct list_head list;
|
||||
};
|
||||
|
||||
static atomic_long_t alg_memory_allocated;
|
||||
|
||||
static struct proto alg_proto = {
|
||||
.name = "ALG",
|
||||
.owner = THIS_MODULE,
|
||||
.memory_allocated = &alg_memory_allocated,
|
||||
.obj_size = sizeof(struct alg_sock),
|
||||
};
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ static inline int __check_agg_selection_timer(struct port *port)
|
|||
if (bond == NULL)
|
||||
return 0;
|
||||
|
||||
return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0;
|
||||
return atomic_read(&BOND_AD_INFO(bond).agg_select_timer) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1995,7 +1995,7 @@ static void ad_marker_response_received(struct bond_marker *marker,
|
|||
*/
|
||||
void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout)
|
||||
{
|
||||
BOND_AD_INFO(bond).agg_select_timer = timeout;
|
||||
atomic_set(&BOND_AD_INFO(bond).agg_select_timer, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2278,6 +2278,28 @@ void bond_3ad_update_ad_actor_settings(struct bonding *bond)
|
|||
spin_unlock_bh(&bond->mode_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_agg_timer_advance - advance agg_select_timer
|
||||
* @bond: bonding structure
|
||||
*
|
||||
* Return true when agg_select_timer reaches 0.
|
||||
*/
|
||||
static bool bond_agg_timer_advance(struct bonding *bond)
|
||||
{
|
||||
int val, nval;
|
||||
|
||||
while (1) {
|
||||
val = atomic_read(&BOND_AD_INFO(bond).agg_select_timer);
|
||||
if (!val)
|
||||
return false;
|
||||
nval = val - 1;
|
||||
if (atomic_cmpxchg(&BOND_AD_INFO(bond).agg_select_timer,
|
||||
val, nval) == val)
|
||||
break;
|
||||
}
|
||||
return nval == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_3ad_state_machine_handler - handle state machines timeout
|
||||
* @work: work context to fetch bonding struct to work on from
|
||||
|
@ -2313,9 +2335,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
|
|||
if (!bond_has_slaves(bond))
|
||||
goto re_arm;
|
||||
|
||||
/* check if agg_select_timer timer after initialize is timed out */
|
||||
if (BOND_AD_INFO(bond).agg_select_timer &&
|
||||
!(--BOND_AD_INFO(bond).agg_select_timer)) {
|
||||
if (bond_agg_timer_advance(bond)) {
|
||||
slave = bond_first_slave_rcu(bond);
|
||||
port = slave ? &(SLAVE_AD_INFO(slave)->port) : NULL;
|
||||
|
||||
|
|
|
@ -2379,10 +2379,9 @@ static int __bond_release_one(struct net_device *bond_dev,
|
|||
bond_select_active_slave(bond);
|
||||
}
|
||||
|
||||
if (!bond_has_slaves(bond)) {
|
||||
bond_set_carrier(bond);
|
||||
bond_set_carrier(bond);
|
||||
if (!bond_has_slaves(bond))
|
||||
eth_hw_addr_random(bond_dev);
|
||||
}
|
||||
|
||||
unblock_netpoll_tx();
|
||||
synchronize_rcu();
|
||||
|
|
|
@ -82,6 +82,7 @@ config NET_DSA_REALTEK_SMI
|
|||
|
||||
config NET_DSA_SMSC_LAN9303
|
||||
tristate
|
||||
depends on VLAN_8021Q || VLAN_8021Q=n
|
||||
select NET_DSA_TAG_LAN9303
|
||||
select REGMAP
|
||||
help
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/mii.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include "lan9303.h"
|
||||
|
@ -1083,21 +1084,27 @@ static void lan9303_adjust_link(struct dsa_switch *ds, int port,
|
|||
static int lan9303_port_enable(struct dsa_switch *ds, int port,
|
||||
struct phy_device *phy)
|
||||
{
|
||||
struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
struct lan9303 *chip = ds->priv;
|
||||
|
||||
if (!dsa_is_user_port(ds, port))
|
||||
if (!dsa_port_is_user(dp))
|
||||
return 0;
|
||||
|
||||
vlan_vid_add(dp->cpu_dp->master, htons(ETH_P_8021Q), port);
|
||||
|
||||
return lan9303_enable_processing_port(chip, port);
|
||||
}
|
||||
|
||||
static void lan9303_port_disable(struct dsa_switch *ds, int port)
|
||||
{
|
||||
struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
struct lan9303 *chip = ds->priv;
|
||||
|
||||
if (!dsa_is_user_port(ds, port))
|
||||
if (!dsa_port_is_user(dp))
|
||||
return;
|
||||
|
||||
vlan_vid_del(dp->cpu_dp->master, htons(ETH_P_8021Q), port);
|
||||
|
||||
lan9303_disable_processing_port(chip, port);
|
||||
lan9303_phy_write(ds, chip->phy_addr_base + port, MII_BMCR, BMCR_PDOWN);
|
||||
}
|
||||
|
@ -1310,7 +1317,7 @@ static int lan9303_probe_reset_gpio(struct lan9303 *chip,
|
|||
struct device_node *np)
|
||||
{
|
||||
chip->reset_gpio = devm_gpiod_get_optional(chip->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(chip->reset_gpio))
|
||||
return PTR_ERR(chip->reset_gpio);
|
||||
|
||||
|
|
|
@ -2176,8 +2176,8 @@ static int gswip_remove(struct platform_device *pdev)
|
|||
|
||||
if (priv->ds->slave_mii_bus) {
|
||||
mdiobus_unregister(priv->ds->slave_mii_bus);
|
||||
mdiobus_free(priv->ds->slave_mii_bus);
|
||||
of_node_put(priv->ds->slave_mii_bus->dev.of_node);
|
||||
mdiobus_free(priv->ds->slave_mii_bus);
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->num_gphy_fw; i++)
|
||||
|
|
|
@ -2284,6 +2284,13 @@ static int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port,
|
|||
if (!mv88e6xxx_max_vid(chip))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* The ATU removal procedure needs the FID to be mapped in the VTU,
|
||||
* but FDB deletion runs concurrently with VLAN deletion. Flush the DSA
|
||||
* switchdev workqueue to ensure that all FDB entries are deleted
|
||||
* before we remove the VLAN.
|
||||
*/
|
||||
dsa_flush_workqueue();
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
|
||||
err = mv88e6xxx_port_get_pvid(chip, port, &pvid);
|
||||
|
|
|
@ -900,7 +900,7 @@ static void atl1c_clean_tx_ring(struct atl1c_adapter *adapter,
|
|||
atl1c_clean_buffer(pdev, buffer_info);
|
||||
}
|
||||
|
||||
netdev_reset_queue(adapter->netdev);
|
||||
netdev_tx_reset_queue(netdev_get_tx_queue(adapter->netdev, queue));
|
||||
|
||||
/* Zero out Tx-buffers */
|
||||
memset(tpd_ring->desc, 0, sizeof(struct atl1c_tpd_desc) *
|
||||
|
|
|
@ -172,6 +172,7 @@ static int bgmac_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct bgmac *bgmac;
|
||||
struct resource *regs;
|
||||
int ret;
|
||||
|
||||
bgmac = bgmac_alloc(&pdev->dev);
|
||||
|
@ -208,15 +209,23 @@ static int bgmac_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(bgmac->plat.base))
|
||||
return PTR_ERR(bgmac->plat.base);
|
||||
|
||||
bgmac->plat.idm_base = devm_platform_ioremap_resource_byname(pdev, "idm_base");
|
||||
if (IS_ERR(bgmac->plat.idm_base))
|
||||
return PTR_ERR(bgmac->plat.idm_base);
|
||||
else
|
||||
/* The idm_base resource is optional for some platforms */
|
||||
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base");
|
||||
if (regs) {
|
||||
bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
|
||||
if (IS_ERR(bgmac->plat.idm_base))
|
||||
return PTR_ERR(bgmac->plat.idm_base);
|
||||
bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK;
|
||||
}
|
||||
|
||||
bgmac->plat.nicpm_base = devm_platform_ioremap_resource_byname(pdev, "nicpm_base");
|
||||
if (IS_ERR(bgmac->plat.nicpm_base))
|
||||
return PTR_ERR(bgmac->plat.nicpm_base);
|
||||
/* The nicpm_base resource is optional for some platforms */
|
||||
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
|
||||
if (regs) {
|
||||
bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
|
||||
regs);
|
||||
if (IS_ERR(bgmac->plat.nicpm_base))
|
||||
return PTR_ERR(bgmac->plat.nicpm_base);
|
||||
}
|
||||
|
||||
bgmac->read = platform_bgmac_read;
|
||||
bgmac->write = platform_bgmac_write;
|
||||
|
|
|
@ -4338,7 +4338,7 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
|
|||
}
|
||||
|
||||
INIT_WORK(&priv->tx_onestep_tstamp, dpaa2_eth_tx_onestep_tstamp);
|
||||
|
||||
mutex_init(&priv->onestep_tstamp_lock);
|
||||
skb_queue_head_init(&priv->tx_skbs);
|
||||
|
||||
priv->rx_copybreak = DPAA2_ETH_DEFAULT_COPYBREAK;
|
||||
|
|
|
@ -532,6 +532,7 @@ static int dpaa2_switch_flower_parse_mirror_key(struct flow_cls_offload *cls,
|
|||
struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
|
||||
struct flow_dissector *dissector = rule->match.dissector;
|
||||
struct netlink_ext_ack *extack = cls->common.extack;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
if (dissector->used_keys &
|
||||
~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
||||
|
@ -561,9 +562,10 @@ static int dpaa2_switch_flower_parse_mirror_key(struct flow_cls_offload *cls,
|
|||
}
|
||||
|
||||
*vlan = (u16)match.key->vlan_id;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1684,6 +1684,12 @@ static void ice_vsi_set_rss_flow_fld(struct ice_vsi *vsi)
|
|||
if (status)
|
||||
dev_dbg(dev, "ice_add_rss_cfg failed for sctp6 flow, vsi = %d, error = %d\n",
|
||||
vsi_num, status);
|
||||
|
||||
status = ice_add_rss_cfg(hw, vsi_handle, ICE_FLOW_HASH_ESP_SPI,
|
||||
ICE_FLOW_SEG_HDR_ESP);
|
||||
if (status)
|
||||
dev_dbg(dev, "ice_add_rss_cfg failed for esp/spi flow, vsi = %d, error = %d\n",
|
||||
vsi_num, status);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -549,14 +549,18 @@ EXPORT_SYMBOL(ocelot_vlan_add);
|
|||
int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid)
|
||||
{
|
||||
struct ocelot_port *ocelot_port = ocelot->ports[port];
|
||||
bool del_pvid = false;
|
||||
int err;
|
||||
|
||||
if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
|
||||
del_pvid = true;
|
||||
|
||||
err = ocelot_vlan_member_del(ocelot, port, vid);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Ingress */
|
||||
if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid)
|
||||
if (del_pvid)
|
||||
ocelot_port_set_pvid(ocelot, port, NULL);
|
||||
|
||||
/* Egress */
|
||||
|
|
|
@ -723,6 +723,8 @@ static inline bool nfp_fl_is_netdev_to_offload(struct net_device *netdev)
|
|||
return true;
|
||||
if (netif_is_gretap(netdev))
|
||||
return true;
|
||||
if (netif_is_ip6gretap(netdev))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2975,8 +2975,8 @@ static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
|
|||
ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND;
|
||||
ca8210_hw->phy->cca_ed_level = -9800;
|
||||
ca8210_hw->phy->symbol_duration = 16;
|
||||
ca8210_hw->phy->lifs_period = 40;
|
||||
ca8210_hw->phy->sifs_period = 12;
|
||||
ca8210_hw->phy->lifs_period = 40 * ca8210_hw->phy->symbol_duration;
|
||||
ca8210_hw->phy->sifs_period = 12 * ca8210_hw->phy->symbol_duration;
|
||||
ca8210_hw->flags =
|
||||
IEEE802154_HW_AFILT |
|
||||
IEEE802154_HW_OMIT_CKSUM |
|
||||
|
|
|
@ -403,8 +403,16 @@ static void mctp_serial_tty_receive_buf(struct tty_struct *tty,
|
|||
mctp_serial_push(dev, c[i]);
|
||||
}
|
||||
|
||||
static void mctp_serial_uninit(struct net_device *ndev)
|
||||
{
|
||||
struct mctp_serial *dev = netdev_priv(ndev);
|
||||
|
||||
cancel_work_sync(&dev->tx_work);
|
||||
}
|
||||
|
||||
static const struct net_device_ops mctp_serial_netdev_ops = {
|
||||
.ndo_start_xmit = mctp_serial_tx,
|
||||
.ndo_uninit = mctp_serial_uninit,
|
||||
};
|
||||
|
||||
static void mctp_serial_setup(struct net_device *ndev)
|
||||
|
@ -483,7 +491,6 @@ static void mctp_serial_close(struct tty_struct *tty)
|
|||
int idx = dev->idx;
|
||||
|
||||
unregister_netdev(dev->netdev);
|
||||
cancel_work_sync(&dev->tx_work);
|
||||
ida_free(&mctp_serial_ida, idx);
|
||||
}
|
||||
|
||||
|
|
|
@ -623,14 +623,14 @@ static int nsim_fib6_rt_append(struct nsim_fib_data *data,
|
|||
if (err)
|
||||
goto err_fib6_rt_nh_del;
|
||||
|
||||
fib6_event->rt_arr[i]->trap = true;
|
||||
WRITE_ONCE(fib6_event->rt_arr[i]->trap, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_fib6_rt_nh_del:
|
||||
for (i--; i >= 0; i--) {
|
||||
fib6_event->rt_arr[i]->trap = false;
|
||||
WRITE_ONCE(fib6_event->rt_arr[i]->trap, false);
|
||||
nsim_fib6_rt_nh_del(fib6_rt, fib6_event->rt_arr[i]);
|
||||
}
|
||||
return err;
|
||||
|
|
|
@ -55,9 +55,6 @@ static int mt7530_phy_config_init(struct phy_device *phydev)
|
|||
|
||||
static int mt7531_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
if (phydev->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
return -EINVAL;
|
||||
|
||||
mtk_gephy_config_init(phydev);
|
||||
|
||||
/* PHY link down power saving enable */
|
||||
|
|
|
@ -583,6 +583,11 @@ static const struct usb_device_id products[] = {
|
|||
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
|
||||
.bInterfaceProtocol = USB_CDC_PROTO_NONE
|
||||
|
||||
#define ZAURUS_FAKE_INTERFACE \
|
||||
.bInterfaceClass = USB_CLASS_COMM, \
|
||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \
|
||||
.bInterfaceProtocol = USB_CDC_PROTO_NONE
|
||||
|
||||
/* SA-1100 based Sharp Zaurus ("collie"), or compatible;
|
||||
* wire-incompatible with true CDC Ethernet implementations.
|
||||
* (And, it seems, needlessly so...)
|
||||
|
@ -636,6 +641,13 @@ static const struct usb_device_id products[] = {
|
|||
.idProduct = 0x9032, /* SL-6000 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x9032, /* SL-6000 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = 0,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
|
|
|
@ -659,6 +659,11 @@ static const struct usb_device_id mbim_devs[] = {
|
|||
.driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
|
||||
},
|
||||
|
||||
/* Telit FN990 */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x1bc7, 0x1071, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&cdc_mbim_info_avoid_altsetting_toggle,
|
||||
},
|
||||
|
||||
/* default entry */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
|
||||
.driver_info = (unsigned long)&cdc_mbim_info_zlp,
|
||||
|
|
|
@ -1715,10 +1715,10 @@ int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
|
|||
{
|
||||
struct sk_buff *skb;
|
||||
struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
|
||||
int len;
|
||||
unsigned int len;
|
||||
int nframes;
|
||||
int x;
|
||||
int offset;
|
||||
unsigned int offset;
|
||||
union {
|
||||
struct usb_cdc_ncm_ndp16 *ndp16;
|
||||
struct usb_cdc_ncm_ndp32 *ndp32;
|
||||
|
@ -1790,8 +1790,8 @@ next_ndp:
|
|||
break;
|
||||
}
|
||||
|
||||
/* sanity checking */
|
||||
if (((offset + len) > skb_in->len) ||
|
||||
/* sanity checking - watch out for integer wrap*/
|
||||
if ((offset > skb_in->len) || (len > skb_in->len - offset) ||
|
||||
(len > ctx->rx_max) || (len < ETH_HLEN)) {
|
||||
netif_dbg(dev, rx_err, dev->net,
|
||||
"invalid frame detected (ignored) offset[%u]=%u, length=%u, skb=%p\n",
|
||||
|
|
|
@ -256,6 +256,11 @@ static const struct usb_device_id products [] = {
|
|||
.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, \
|
||||
.bInterfaceProtocol = USB_CDC_PROTO_NONE
|
||||
|
||||
#define ZAURUS_FAKE_INTERFACE \
|
||||
.bInterfaceClass = USB_CLASS_COMM, \
|
||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, \
|
||||
.bInterfaceProtocol = USB_CDC_PROTO_NONE
|
||||
|
||||
/* SA-1100 based Sharp Zaurus ("collie"), or compatible. */
|
||||
{
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
|
@ -313,6 +318,13 @@ static const struct usb_device_id products [] = {
|
|||
.idProduct = 0x9032, /* SL-6000 */
|
||||
ZAURUS_MASTER_INTERFACE,
|
||||
.driver_info = ZAURUS_PXA_INFO,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
.idVendor = 0x04DD,
|
||||
.idProduct = 0x9032, /* SL-6000 */
|
||||
ZAURUS_FAKE_INTERFACE,
|
||||
.driver_info = (unsigned long)&bogus_mdlm_info,
|
||||
}, {
|
||||
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
|
||||
| USB_DEVICE_ID_MATCH_DEVICE,
|
||||
|
|
|
@ -693,7 +693,7 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
|
|||
{
|
||||
struct brcmf_fw_item *first = &req->items[0];
|
||||
struct brcmf_fw *fwctx;
|
||||
char *alt_path;
|
||||
char *alt_path = NULL;
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
|
||||
|
@ -712,7 +712,9 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
|
|||
fwctx->done = fw_cb;
|
||||
|
||||
/* First try alternative board-specific path if any */
|
||||
alt_path = brcm_alt_fw_path(first->path, fwctx->req->board_type);
|
||||
if (fwctx->req->board_type)
|
||||
alt_path = brcm_alt_fw_path(first->path,
|
||||
fwctx->req->board_type);
|
||||
if (alt_path) {
|
||||
ret = request_firmware_nowait(THIS_MODULE, true, alt_path,
|
||||
fwctx->dev, GFP_KERNEL, fwctx,
|
||||
|
|
|
@ -80,19 +80,6 @@ config IWLWIFI_OPMODE_MODULAR
|
|||
comment "WARNING: iwlwifi is useless without IWLDVM or IWLMVM"
|
||||
depends on IWLDVM=n && IWLMVM=n
|
||||
|
||||
config IWLWIFI_BCAST_FILTERING
|
||||
bool "Enable broadcast filtering"
|
||||
depends on IWLMVM
|
||||
help
|
||||
Say Y here to enable default bcast filtering configuration.
|
||||
|
||||
Enabling broadcast filtering will drop any incoming wireless
|
||||
broadcast frames, except some very specific predefined
|
||||
patterns (e.g. incoming arp requests).
|
||||
|
||||
If unsure, don't enable this option, as some programs might
|
||||
expect incoming broadcasts for their normal operations.
|
||||
|
||||
menu "Debugging Options"
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2019-2021 Intel Corporation
|
||||
* Copyright (C) 2019-2022 Intel Corporation
|
||||
*/
|
||||
#include <linux/uuid.h>
|
||||
#include "iwl-drv.h"
|
||||
|
@ -888,10 +888,11 @@ bool iwl_sar_geo_support(struct iwl_fw_runtime *fwrt)
|
|||
* only one using version 36, so skip this version entirely.
|
||||
*/
|
||||
return IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) >= 38 ||
|
||||
IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 ||
|
||||
(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
|
||||
((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
|
||||
CSR_HW_REV_TYPE_7265D));
|
||||
(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 17 &&
|
||||
fwrt->trans->hw_rev != CSR_HW_REV_TYPE_3160) ||
|
||||
(IWL_UCODE_SERIAL(fwrt->fw->ucode_ver) == 29 &&
|
||||
((fwrt->trans->hw_rev & CSR_HW_REV_TYPE_MSK) ==
|
||||
CSR_HW_REV_TYPE_7265D));
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_sar_geo_support);
|
||||
|
||||
|
|
|
@ -501,11 +501,6 @@ enum iwl_legacy_cmds {
|
|||
*/
|
||||
DEBUG_LOG_MSG = 0xf7,
|
||||
|
||||
/**
|
||||
* @BCAST_FILTER_CMD: &struct iwl_bcast_filter_cmd
|
||||
*/
|
||||
BCAST_FILTER_CMD = 0xcf,
|
||||
|
||||
/**
|
||||
* @MCAST_FILTER_CMD: &struct iwl_mcast_filter_cmd
|
||||
*/
|
||||
|
|
|
@ -36,92 +36,4 @@ struct iwl_mcast_filter_cmd {
|
|||
u8 addr_list[0];
|
||||
} __packed; /* MCAST_FILTERING_CMD_API_S_VER_1 */
|
||||
|
||||
#define MAX_BCAST_FILTERS 8
|
||||
#define MAX_BCAST_FILTER_ATTRS 2
|
||||
|
||||
/**
|
||||
* enum iwl_mvm_bcast_filter_attr_offset - written by fw for each Rx packet
|
||||
* @BCAST_FILTER_OFFSET_PAYLOAD_START: offset is from payload start.
|
||||
* @BCAST_FILTER_OFFSET_IP_END: offset is from ip header end (i.e.
|
||||
* start of ip payload).
|
||||
*/
|
||||
enum iwl_mvm_bcast_filter_attr_offset {
|
||||
BCAST_FILTER_OFFSET_PAYLOAD_START = 0,
|
||||
BCAST_FILTER_OFFSET_IP_END = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_bcast_filter_attr - broadcast filter attribute
|
||||
* @offset_type: &enum iwl_mvm_bcast_filter_attr_offset.
|
||||
* @offset: starting offset of this pattern.
|
||||
* @reserved1: reserved
|
||||
* @val: value to match - big endian (MSB is the first
|
||||
* byte to match from offset pos).
|
||||
* @mask: mask to match (big endian).
|
||||
*/
|
||||
struct iwl_fw_bcast_filter_attr {
|
||||
u8 offset_type;
|
||||
u8 offset;
|
||||
__le16 reserved1;
|
||||
__be32 val;
|
||||
__be32 mask;
|
||||
} __packed; /* BCAST_FILTER_ATT_S_VER_1 */
|
||||
|
||||
/**
|
||||
* enum iwl_mvm_bcast_filter_frame_type - filter frame type
|
||||
* @BCAST_FILTER_FRAME_TYPE_ALL: consider all frames.
|
||||
* @BCAST_FILTER_FRAME_TYPE_IPV4: consider only ipv4 frames
|
||||
*/
|
||||
enum iwl_mvm_bcast_filter_frame_type {
|
||||
BCAST_FILTER_FRAME_TYPE_ALL = 0,
|
||||
BCAST_FILTER_FRAME_TYPE_IPV4 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_fw_bcast_filter - broadcast filter
|
||||
* @discard: discard frame (1) or let it pass (0).
|
||||
* @frame_type: &enum iwl_mvm_bcast_filter_frame_type.
|
||||
* @reserved1: reserved
|
||||
* @num_attrs: number of valid attributes in this filter.
|
||||
* @attrs: attributes of this filter. a filter is considered matched
|
||||
* only when all its attributes are matched (i.e. AND relationship)
|
||||
*/
|
||||
struct iwl_fw_bcast_filter {
|
||||
u8 discard;
|
||||
u8 frame_type;
|
||||
u8 num_attrs;
|
||||
u8 reserved1;
|
||||
struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS];
|
||||
} __packed; /* BCAST_FILTER_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration.
|
||||
* @default_discard: default action for this mac (discard (1) / pass (0)).
|
||||
* @reserved1: reserved
|
||||
* @attached_filters: bitmap of relevant filters for this mac.
|
||||
*/
|
||||
struct iwl_fw_bcast_mac {
|
||||
u8 default_discard;
|
||||
u8 reserved1;
|
||||
__le16 attached_filters;
|
||||
} __packed; /* BCAST_MAC_CONTEXT_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_bcast_filter_cmd - broadcast filtering configuration
|
||||
* @disable: enable (0) / disable (1)
|
||||
* @max_bcast_filters: max number of filters (MAX_BCAST_FILTERS)
|
||||
* @max_macs: max number of macs (NUM_MAC_INDEX_DRIVER)
|
||||
* @reserved1: reserved
|
||||
* @filters: broadcast filters
|
||||
* @macs: broadcast filtering configuration per-mac
|
||||
*/
|
||||
struct iwl_bcast_filter_cmd {
|
||||
u8 disable;
|
||||
u8 max_bcast_filters;
|
||||
u8 max_macs;
|
||||
u8 reserved1;
|
||||
struct iwl_fw_bcast_filter filters[MAX_BCAST_FILTERS];
|
||||
struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER];
|
||||
} __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */
|
||||
|
||||
#endif /* __iwl_fw_api_filter_h__ */
|
||||
|
|
|
@ -752,7 +752,6 @@ struct iwl_lq_cmd {
|
|||
|
||||
u8 iwl_fw_rate_idx_to_plcp(int idx);
|
||||
u32 iwl_new_rate_from_v1(u32 rate_v1);
|
||||
u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags);
|
||||
const struct iwl_rate_mcs_info *iwl_rate_mcs(int idx);
|
||||
const char *iwl_rs_pretty_ant(u8 ant);
|
||||
const char *iwl_rs_pretty_bw(int bw);
|
||||
|
|
|
@ -181,7 +181,6 @@ struct iwl_ucode_capa {
|
|||
* @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version)
|
||||
* @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
|
||||
* @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
|
||||
* @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
|
||||
* @IWL_UCODE_TLV_FLAGS_EBS_SUPPORT: this uCode image supports EBS.
|
||||
*/
|
||||
enum iwl_ucode_tlv_flag {
|
||||
|
@ -196,7 +195,6 @@ enum iwl_ucode_tlv_flag {
|
|||
IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24),
|
||||
IWL_UCODE_TLV_FLAGS_EBS_SUPPORT = BIT(25),
|
||||
IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD = BIT(26),
|
||||
IWL_UCODE_TLV_FLAGS_BCAST_FILTERING = BIT(29),
|
||||
};
|
||||
|
||||
typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
||||
|
|
|
@ -91,6 +91,20 @@ const char *iwl_rs_pretty_bw(int bw)
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_rs_pretty_bw);
|
||||
|
||||
static u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
|
||||
{
|
||||
int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
|
||||
int idx;
|
||||
bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
|
||||
int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
|
||||
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
for (idx = offset; idx < last; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - offset;
|
||||
return IWL_RATE_INVALID;
|
||||
}
|
||||
|
||||
u32 iwl_new_rate_from_v1(u32 rate_v1)
|
||||
{
|
||||
u32 rate_v2 = 0;
|
||||
|
@ -144,7 +158,10 @@ u32 iwl_new_rate_from_v1(u32 rate_v1)
|
|||
} else {
|
||||
u32 legacy_rate = iwl_legacy_rate_to_fw_idx(rate_v1);
|
||||
|
||||
WARN_ON(legacy_rate < 0);
|
||||
if (WARN_ON_ONCE(legacy_rate == IWL_RATE_INVALID))
|
||||
legacy_rate = (rate_v1 & RATE_MCS_CCK_MSK_V1) ?
|
||||
IWL_FIRST_CCK_RATE : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
rate_v2 |= legacy_rate;
|
||||
if (!(rate_v1 & RATE_MCS_CCK_MSK_V1))
|
||||
rate_v2 |= RATE_MCS_LEGACY_OFDM_MSK;
|
||||
|
@ -172,20 +189,6 @@ u32 iwl_new_rate_from_v1(u32 rate_v1)
|
|||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_new_rate_from_v1);
|
||||
|
||||
u32 iwl_legacy_rate_to_fw_idx(u32 rate_n_flags)
|
||||
{
|
||||
int rate = rate_n_flags & RATE_LEGACY_RATE_MSK_V1;
|
||||
int idx;
|
||||
bool ofdm = !(rate_n_flags & RATE_MCS_CCK_MSK_V1);
|
||||
int offset = ofdm ? IWL_FIRST_OFDM_RATE : 0;
|
||||
int last = ofdm ? IWL_RATE_COUNT_LEGACY : IWL_FIRST_OFDM_RATE;
|
||||
|
||||
for (idx = offset; idx < last; idx++)
|
||||
if (iwl_fw_rate_idx_to_plcp(idx) == rate)
|
||||
return idx - offset;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate)
|
||||
{
|
||||
char *type;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2005-2014, 2018-2021 Intel Corporation
|
||||
* Copyright (C) 2005-2014, 2018-2022 Intel Corporation
|
||||
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016 Intel Deutschland GmbH
|
||||
*/
|
||||
|
@ -329,6 +329,7 @@ enum {
|
|||
#define CSR_HW_REV_TYPE_2x00 (0x0000100)
|
||||
#define CSR_HW_REV_TYPE_105 (0x0000110)
|
||||
#define CSR_HW_REV_TYPE_135 (0x0000120)
|
||||
#define CSR_HW_REV_TYPE_3160 (0x0000164)
|
||||
#define CSR_HW_REV_TYPE_7265D (0x0000210)
|
||||
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
|
||||
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
|
||||
|
|
|
@ -1707,6 +1707,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
|||
out_unbind:
|
||||
complete(&drv->request_firmware_complete);
|
||||
device_release_driver(drv->trans->dev);
|
||||
/* drv has just been freed by the release */
|
||||
failure = false;
|
||||
free:
|
||||
if (failure)
|
||||
iwl_dealloc_ucode(drv);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 Intel Corporation
|
||||
* Copyright (C) 2021-2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
@ -146,6 +146,7 @@ struct iwl_mei_filters {
|
|||
* @csme_taking_ownership: true when CSME is taking ownership. Used to remember
|
||||
* to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
|
||||
* flow.
|
||||
* @link_prot_state: true when we are in link protection PASSIVE
|
||||
* @csa_throttle_end_wk: used when &csa_throttled is true
|
||||
* @data_q_lock: protects the access to the data queues which are
|
||||
* accessed without the mutex.
|
||||
|
@ -165,6 +166,7 @@ struct iwl_mei {
|
|||
bool amt_enabled;
|
||||
bool csa_throttled;
|
||||
bool csme_taking_ownership;
|
||||
bool link_prot_state;
|
||||
struct delayed_work csa_throttle_end_wk;
|
||||
spinlock_t data_q_lock;
|
||||
|
||||
|
@ -229,8 +231,6 @@ static int iwl_mei_alloc_shared_mem(struct mei_cl_device *cldev)
|
|||
if (IS_ERR(mem->ctrl)) {
|
||||
int ret = PTR_ERR(mem->ctrl);
|
||||
|
||||
dev_err(&cldev->dev, "Couldn't allocate the shared memory: %d\n",
|
||||
ret);
|
||||
mem->ctrl = NULL;
|
||||
|
||||
return ret;
|
||||
|
@ -669,6 +669,8 @@ iwl_mei_handle_conn_status(struct mei_cl_device *cldev,
|
|||
|
||||
iwl_mei_cache.ops->me_conn_status(iwl_mei_cache.priv, &conn_info);
|
||||
|
||||
mei->link_prot_state = status->link_prot_state;
|
||||
|
||||
/*
|
||||
* Update the Rfkill state in case the host does not own the device:
|
||||
* if we are in Link Protection, ask to not touch the device, else,
|
||||
|
@ -1663,9 +1665,11 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
|
|||
mei_cldev_get_drvdata(iwl_mei_global_cldev);
|
||||
|
||||
/* we have already a SAP connection */
|
||||
if (iwl_mei_is_connected())
|
||||
if (iwl_mei_is_connected()) {
|
||||
iwl_mei_send_sap_msg(mei->cldev,
|
||||
SAP_MSG_NOTIF_WIFIDR_UP);
|
||||
ops->rfkill(priv, mei->link_prot_state);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
|
@ -1784,6 +1788,8 @@ static void iwl_mei_dbgfs_unregister(struct iwl_mei *mei) {}
|
|||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
#define ALLOC_SHARED_MEM_RETRY_MAX_NUM 3
|
||||
|
||||
/*
|
||||
* iwl_mei_probe - the probe function called by the mei bus enumeration
|
||||
*
|
||||
|
@ -1795,6 +1801,7 @@ static void iwl_mei_dbgfs_unregister(struct iwl_mei *mei) {}
|
|||
static int iwl_mei_probe(struct mei_cl_device *cldev,
|
||||
const struct mei_cl_device_id *id)
|
||||
{
|
||||
int alloc_retry = ALLOC_SHARED_MEM_RETRY_MAX_NUM;
|
||||
struct iwl_mei *mei;
|
||||
int ret;
|
||||
|
||||
|
@ -1812,15 +1819,31 @@ static int iwl_mei_probe(struct mei_cl_device *cldev,
|
|||
mei_cldev_set_drvdata(cldev, mei);
|
||||
mei->cldev = cldev;
|
||||
|
||||
/*
|
||||
* The CSME firmware needs to boot the internal WLAN client. Wait here
|
||||
* so that the DMA map request will succeed.
|
||||
*/
|
||||
msleep(20);
|
||||
do {
|
||||
ret = iwl_mei_alloc_shared_mem(cldev);
|
||||
if (!ret)
|
||||
break;
|
||||
/*
|
||||
* The CSME firmware needs to boot the internal WLAN client.
|
||||
* This can take time in certain configurations (usually
|
||||
* upon resume and when the whole CSME firmware is shut down
|
||||
* during suspend).
|
||||
*
|
||||
* Wait a bit before retrying and hope we'll succeed next time.
|
||||
*/
|
||||
|
||||
ret = iwl_mei_alloc_shared_mem(cldev);
|
||||
if (ret)
|
||||
dev_dbg(&cldev->dev,
|
||||
"Couldn't allocate the shared memory: %d, attempt %d / %d\n",
|
||||
ret, alloc_retry, ALLOC_SHARED_MEM_RETRY_MAX_NUM);
|
||||
msleep(100);
|
||||
alloc_retry--;
|
||||
} while (alloc_retry);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&cldev->dev, "Couldn't allocate the shared memory: %d\n",
|
||||
ret);
|
||||
goto free;
|
||||
}
|
||||
|
||||
iwl_mei_init_shared_mem(mei);
|
||||
|
||||
|
|
|
@ -195,8 +195,7 @@ static bool iwl_mei_rx_filter_ipv4(struct sk_buff *skb,
|
|||
bool match;
|
||||
|
||||
if (!pskb_may_pull(skb, skb_network_offset(skb) + sizeof(*iphdr)) ||
|
||||
!pskb_may_pull(skb, skb_network_offset(skb) +
|
||||
sizeof(ip_hdrlen(skb) - sizeof(*iphdr))))
|
||||
!pskb_may_pull(skb, skb_network_offset(skb) + ip_hdrlen(skb)))
|
||||
return false;
|
||||
|
||||
iphdrlen = ip_hdrlen(skb);
|
||||
|
|
|
@ -1369,189 +1369,6 @@ static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm,
|
|||
return count;
|
||||
}
|
||||
|
||||
#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
const struct iwl_fw_bcast_filter *filter;
|
||||
char *buf;
|
||||
int bufsz = 1024;
|
||||
int i, j, pos = 0;
|
||||
ssize_t ret;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
|
||||
ADD_TEXT("None\n");
|
||||
mutex_unlock(&mvm->mutex);
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
for (i = 0; cmd.filters[i].attrs[0].mask; i++) {
|
||||
filter = &cmd.filters[i];
|
||||
|
||||
ADD_TEXT("Filter [%d]:\n", i);
|
||||
ADD_TEXT("\tDiscard=%d\n", filter->discard);
|
||||
ADD_TEXT("\tFrame Type: %s\n",
|
||||
filter->frame_type ? "IPv4" : "Generic");
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) {
|
||||
const struct iwl_fw_bcast_filter_attr *attr;
|
||||
|
||||
attr = &filter->attrs[j];
|
||||
if (!attr->mask)
|
||||
break;
|
||||
|
||||
ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n",
|
||||
j, attr->offset,
|
||||
attr->offset_type ? "IP End" :
|
||||
"Payload Start",
|
||||
be32_to_cpu(attr->mask),
|
||||
be32_to_cpu(attr->val),
|
||||
le16_to_cpu(attr->reserved1));
|
||||
}
|
||||
}
|
||||
out:
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
int pos, next_pos;
|
||||
struct iwl_fw_bcast_filter filter = {};
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
u32 filter_id, attr_id, mask, value;
|
||||
int err = 0;
|
||||
|
||||
if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard,
|
||||
&filter.frame_type, &pos) != 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) ||
|
||||
filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4)
|
||||
return -EINVAL;
|
||||
|
||||
for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs);
|
||||
attr_id++) {
|
||||
struct iwl_fw_bcast_filter_attr *attr =
|
||||
&filter.attrs[attr_id];
|
||||
|
||||
if (pos >= count)
|
||||
break;
|
||||
|
||||
if (sscanf(&buf[pos], "%hhi %hhi %i %i %n",
|
||||
&attr->offset, &attr->offset_type,
|
||||
&mask, &value, &next_pos) != 4)
|
||||
return -EINVAL;
|
||||
|
||||
attr->mask = cpu_to_be32(mask);
|
||||
attr->val = cpu_to_be32(value);
|
||||
if (mask)
|
||||
filter.num_attrs++;
|
||||
|
||||
pos += next_pos;
|
||||
}
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id],
|
||||
&filter, sizeof(filter));
|
||||
|
||||
/* send updated bcast filtering configuration */
|
||||
if (iwl_mvm_firmware_running(mvm) &&
|
||||
mvm->dbgfs_bcast_filtering.override &&
|
||||
iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
|
||||
sizeof(cmd), &cmd);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return err ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
char *buf;
|
||||
int bufsz = 1024;
|
||||
int i, pos = 0;
|
||||
ssize_t ret;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) {
|
||||
ADD_TEXT("None\n");
|
||||
mutex_unlock(&mvm->mutex);
|
||||
goto out;
|
||||
}
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) {
|
||||
const struct iwl_fw_bcast_mac *mac = &cmd.macs[i];
|
||||
|
||||
ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n",
|
||||
i, mac->default_discard, mac->attached_filters);
|
||||
}
|
||||
out:
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
struct iwl_fw_bcast_mac mac = {};
|
||||
u32 mac_id, attached_filters;
|
||||
int err = 0;
|
||||
|
||||
if (!mvm->bcast_filters)
|
||||
return -ENOENT;
|
||||
|
||||
if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard,
|
||||
&attached_filters) != 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (mac_id >= ARRAY_SIZE(cmd.macs) ||
|
||||
mac.default_discard > 1 ||
|
||||
attached_filters >= BIT(ARRAY_SIZE(cmd.filters)))
|
||||
return -EINVAL;
|
||||
|
||||
mac.attached_filters = cpu_to_le16(attached_filters);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id],
|
||||
&mac, sizeof(mac));
|
||||
|
||||
/* send updated bcast filtering configuration */
|
||||
if (iwl_mvm_firmware_running(mvm) &&
|
||||
mvm->dbgfs_bcast_filtering.override &&
|
||||
iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
|
||||
sizeof(cmd), &cmd);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return err ?: count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
|
||||
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm)
|
||||
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
|
||||
|
@ -1881,11 +1698,6 @@ MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512);
|
|||
|
||||
MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
|
||||
#endif
|
||||
|
@ -2097,21 +1909,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm)
|
|||
|
||||
MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
|
||||
bcast_dir = debugfs_create_dir("bcast_filtering",
|
||||
mvm->debugfs_dir);
|
||||
|
||||
debugfs_create_bool("override", 0600, bcast_dir,
|
||||
&mvm->dbgfs_bcast_filtering.override);
|
||||
|
||||
MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters,
|
||||
bcast_dir, 0600);
|
||||
MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs,
|
||||
bcast_dir, 0600);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
|
||||
debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
|
||||
|
|
|
@ -1741,7 +1741,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
|
|||
ret = iwl_mvm_sar_init(mvm);
|
||||
if (ret == 0)
|
||||
ret = iwl_mvm_sar_geo_init(mvm);
|
||||
else if (ret < 0)
|
||||
if (ret < 0)
|
||||
goto error;
|
||||
|
||||
ret = iwl_mvm_sgom_init(mvm);
|
||||
|
|
|
@ -55,79 +55,6 @@ static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
/*
|
||||
* Use the reserved field to indicate magic values.
|
||||
* these values will only be used internally by the driver,
|
||||
* and won't make it to the fw (reserved will be 0).
|
||||
* BC_FILTER_MAGIC_IP - configure the val of this attribute to
|
||||
* be the vif's ip address. in case there is not a single
|
||||
* ip address (0, or more than 1), this attribute will
|
||||
* be skipped.
|
||||
* BC_FILTER_MAGIC_MAC - set the val of this attribute to
|
||||
* the LSB bytes of the vif's mac address
|
||||
*/
|
||||
enum {
|
||||
BC_FILTER_MAGIC_NONE = 0,
|
||||
BC_FILTER_MAGIC_IP,
|
||||
BC_FILTER_MAGIC_MAC,
|
||||
};
|
||||
|
||||
static const struct iwl_fw_bcast_filter iwl_mvm_default_bcast_filters[] = {
|
||||
{
|
||||
/* arp */
|
||||
.discard = 0,
|
||||
.frame_type = BCAST_FILTER_FRAME_TYPE_ALL,
|
||||
.attrs = {
|
||||
{
|
||||
/* frame type - arp, hw type - ethernet */
|
||||
.offset_type =
|
||||
BCAST_FILTER_OFFSET_PAYLOAD_START,
|
||||
.offset = sizeof(rfc1042_header),
|
||||
.val = cpu_to_be32(0x08060001),
|
||||
.mask = cpu_to_be32(0xffffffff),
|
||||
},
|
||||
{
|
||||
/* arp dest ip */
|
||||
.offset_type =
|
||||
BCAST_FILTER_OFFSET_PAYLOAD_START,
|
||||
.offset = sizeof(rfc1042_header) + 2 +
|
||||
sizeof(struct arphdr) +
|
||||
ETH_ALEN + sizeof(__be32) +
|
||||
ETH_ALEN,
|
||||
.mask = cpu_to_be32(0xffffffff),
|
||||
/* mark it as special field */
|
||||
.reserved1 = cpu_to_le16(BC_FILTER_MAGIC_IP),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
/* dhcp offer bcast */
|
||||
.discard = 0,
|
||||
.frame_type = BCAST_FILTER_FRAME_TYPE_IPV4,
|
||||
.attrs = {
|
||||
{
|
||||
/* udp dest port - 68 (bootp client)*/
|
||||
.offset_type = BCAST_FILTER_OFFSET_IP_END,
|
||||
.offset = offsetof(struct udphdr, dest),
|
||||
.val = cpu_to_be32(0x00440000),
|
||||
.mask = cpu_to_be32(0xffff0000),
|
||||
},
|
||||
{
|
||||
/* dhcp - lsb bytes of client hw address */
|
||||
.offset_type = BCAST_FILTER_OFFSET_IP_END,
|
||||
.offset = 38,
|
||||
.mask = cpu_to_be32(0xffffffff),
|
||||
/* mark it as special field */
|
||||
.reserved1 = cpu_to_le16(BC_FILTER_MAGIC_MAC),
|
||||
},
|
||||
},
|
||||
},
|
||||
/* last filter must be empty */
|
||||
{},
|
||||
};
|
||||
#endif
|
||||
|
||||
static const struct cfg80211_pmsr_capabilities iwl_mvm_pmsr_capa = {
|
||||
.max_peers = IWL_MVM_TOF_MAX_APS,
|
||||
.report_ap_tsf = 1,
|
||||
|
@ -693,11 +620,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
/* assign default bcast filtering configuration */
|
||||
mvm->bcast_filters = iwl_mvm_default_bcast_filters;
|
||||
#endif
|
||||
|
||||
ret = iwl_mvm_leds_init(mvm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1853,162 +1775,6 @@ static void iwl_mvm_config_iface_filter(struct ieee80211_hw *hw,
|
|||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
struct iwl_bcast_iter_data {
|
||||
struct iwl_mvm *mvm;
|
||||
struct iwl_bcast_filter_cmd *cmd;
|
||||
u8 current_filter;
|
||||
};
|
||||
|
||||
static void
|
||||
iwl_mvm_set_bcast_filter(struct ieee80211_vif *vif,
|
||||
const struct iwl_fw_bcast_filter *in_filter,
|
||||
struct iwl_fw_bcast_filter *out_filter)
|
||||
{
|
||||
struct iwl_fw_bcast_filter_attr *attr;
|
||||
int i;
|
||||
|
||||
memcpy(out_filter, in_filter, sizeof(*out_filter));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(out_filter->attrs); i++) {
|
||||
attr = &out_filter->attrs[i];
|
||||
|
||||
if (!attr->mask)
|
||||
break;
|
||||
|
||||
switch (attr->reserved1) {
|
||||
case cpu_to_le16(BC_FILTER_MAGIC_IP):
|
||||
if (vif->bss_conf.arp_addr_cnt != 1) {
|
||||
attr->mask = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
attr->val = vif->bss_conf.arp_addr_list[0];
|
||||
break;
|
||||
case cpu_to_le16(BC_FILTER_MAGIC_MAC):
|
||||
attr->val = *(__be32 *)&vif->addr[2];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
attr->reserved1 = 0;
|
||||
out_filter->num_attrs++;
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_mvm_bcast_filter_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_bcast_iter_data *data = _data;
|
||||
struct iwl_mvm *mvm = data->mvm;
|
||||
struct iwl_bcast_filter_cmd *cmd = data->cmd;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_fw_bcast_mac *bcast_mac;
|
||||
int i;
|
||||
|
||||
if (WARN_ON(mvmvif->id >= ARRAY_SIZE(cmd->macs)))
|
||||
return;
|
||||
|
||||
bcast_mac = &cmd->macs[mvmvif->id];
|
||||
|
||||
/*
|
||||
* enable filtering only for associated stations, but not for P2P
|
||||
* Clients
|
||||
*/
|
||||
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p ||
|
||||
!vif->bss_conf.assoc)
|
||||
return;
|
||||
|
||||
bcast_mac->default_discard = 1;
|
||||
|
||||
/* copy all configured filters */
|
||||
for (i = 0; mvm->bcast_filters[i].attrs[0].mask; i++) {
|
||||
/*
|
||||
* Make sure we don't exceed our filters limit.
|
||||
* if there is still a valid filter to be configured,
|
||||
* be on the safe side and just allow bcast for this mac.
|
||||
*/
|
||||
if (WARN_ON_ONCE(data->current_filter >=
|
||||
ARRAY_SIZE(cmd->filters))) {
|
||||
bcast_mac->default_discard = 0;
|
||||
bcast_mac->attached_filters = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
iwl_mvm_set_bcast_filter(vif,
|
||||
&mvm->bcast_filters[i],
|
||||
&cmd->filters[data->current_filter]);
|
||||
|
||||
/* skip current filter if it contains no attributes */
|
||||
if (!cmd->filters[data->current_filter].num_attrs)
|
||||
continue;
|
||||
|
||||
/* attach the filter to current mac */
|
||||
bcast_mac->attached_filters |=
|
||||
cpu_to_le16(BIT(data->current_filter));
|
||||
|
||||
data->current_filter++;
|
||||
}
|
||||
}
|
||||
|
||||
bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_bcast_filter_cmd *cmd)
|
||||
{
|
||||
struct iwl_bcast_iter_data iter_data = {
|
||||
.mvm = mvm,
|
||||
.cmd = cmd,
|
||||
};
|
||||
|
||||
if (IWL_MVM_FW_BCAST_FILTER_PASS_ALL)
|
||||
return false;
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->max_bcast_filters = ARRAY_SIZE(cmd->filters);
|
||||
cmd->max_macs = ARRAY_SIZE(cmd->macs);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
/* use debugfs filters/macs if override is configured */
|
||||
if (mvm->dbgfs_bcast_filtering.override) {
|
||||
memcpy(cmd->filters, &mvm->dbgfs_bcast_filtering.cmd.filters,
|
||||
sizeof(cmd->filters));
|
||||
memcpy(cmd->macs, &mvm->dbgfs_bcast_filtering.cmd.macs,
|
||||
sizeof(cmd->macs));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if no filters are configured, do nothing */
|
||||
if (!mvm->bcast_filters)
|
||||
return false;
|
||||
|
||||
/* configure and attach these filters for each associated sta vif */
|
||||
ieee80211_iterate_active_interfaces(
|
||||
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_bcast_filter_iterator, &iter_data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
|
||||
if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING))
|
||||
return 0;
|
||||
|
||||
if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
|
||||
return 0;
|
||||
|
||||
return iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0,
|
||||
sizeof(cmd), &cmd);
|
||||
}
|
||||
#else
|
||||
static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -2520,7 +2286,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
iwl_mvm_recalc_multicast(mvm);
|
||||
iwl_mvm_configure_bcast_filter(mvm);
|
||||
|
||||
/* reset rssi values */
|
||||
mvmvif->bf_data.ave_beacon_signal = 0;
|
||||
|
@ -2570,11 +2335,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
}
|
||||
}
|
||||
|
||||
if (changes & BSS_CHANGED_ARP_FILTER) {
|
||||
IWL_DEBUG_MAC80211(mvm, "arp filter changed\n");
|
||||
iwl_mvm_configure_bcast_filter(mvm);
|
||||
}
|
||||
|
||||
if (changes & BSS_CHANGED_BANDWIDTH)
|
||||
iwl_mvm_apply_fw_smps_request(vif);
|
||||
}
|
||||
|
|
|
@ -884,17 +884,6 @@ struct iwl_mvm {
|
|||
/* rx chain antennas set through debugfs for the scan command */
|
||||
u8 scan_rx_ant;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
/* broadcast filters to configure for each associated station */
|
||||
const struct iwl_fw_bcast_filter *bcast_filters;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct {
|
||||
bool override;
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
} dbgfs_bcast_filtering;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Internal station */
|
||||
struct iwl_mvm_int_sta aux_sta;
|
||||
struct iwl_mvm_int_sta snif_sta;
|
||||
|
@ -1593,8 +1582,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm);
|
|||
int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
|
||||
|
||||
int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm);
|
||||
bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm,
|
||||
struct iwl_bcast_filter_cmd *cmd);
|
||||
|
||||
/*
|
||||
* FW notifications / CMD responses handlers
|
||||
|
@ -2225,7 +2212,7 @@ static inline void iwl_mvm_mei_device_down(struct iwl_mvm *mvm)
|
|||
static inline void iwl_mvm_mei_set_sw_rfkill_state(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool sw_rfkill =
|
||||
mvm->hw_registered ? rfkill_blocked(mvm->hw->wiphy->rfkill) : false;
|
||||
mvm->hw_registered ? rfkill_soft_blocked(mvm->hw->wiphy->rfkill) : false;
|
||||
|
||||
if (mvm->mei_registered)
|
||||
iwl_mei_set_rfkill_state(iwl_mvm_is_radio_killed(mvm),
|
||||
|
|
|
@ -469,7 +469,6 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
|
|||
HCMD_NAME(MCC_CHUB_UPDATE_CMD),
|
||||
HCMD_NAME(MARKER_CMD),
|
||||
HCMD_NAME(BT_PROFILE_NOTIFICATION),
|
||||
HCMD_NAME(BCAST_FILTER_CMD),
|
||||
HCMD_NAME(MCAST_FILTER_CMD),
|
||||
HCMD_NAME(REPLY_SF_CFG_CMD),
|
||||
HCMD_NAME(REPLY_BEACON_FILTERING_CMD),
|
||||
|
|
|
@ -1427,7 +1427,7 @@ static void iwl_mvm_hwrate_to_tx_status(const struct iwl_fw *fw,
|
|||
struct ieee80211_tx_rate *r = &info->status.rates[0];
|
||||
|
||||
if (iwl_fw_lookup_notif_ver(fw, LONG_GROUP,
|
||||
TX_CMD, 0) > 6)
|
||||
TX_CMD, 0) <= 6)
|
||||
rate_n_flags = iwl_new_rate_from_v1(rate_n_flags);
|
||||
|
||||
info->status.antenna =
|
||||
|
|
|
@ -385,8 +385,7 @@ int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
|
|||
/* This may fail if AMT took ownership of the device */
|
||||
if (iwl_pcie_prepare_card_hw(trans)) {
|
||||
IWL_WARN(trans, "Exit HW not ready\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
iwl_enable_rfkill_int(trans);
|
||||
|
|
|
@ -1329,8 +1329,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
|
|||
/* This may fail if AMT took ownership of the device */
|
||||
if (iwl_pcie_prepare_card_hw(trans)) {
|
||||
IWL_WARN(trans, "Exit HW not ready\n");
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
iwl_enable_rfkill_int(trans);
|
||||
|
|
|
@ -2336,6 +2336,15 @@ static void hw_scan_work(struct work_struct *work)
|
|||
if (req->ie_len)
|
||||
skb_put_data(probe, req->ie, req->ie_len);
|
||||
|
||||
if (!ieee80211_tx_prepare_skb(hwsim->hw,
|
||||
hwsim->hw_scan_vif,
|
||||
probe,
|
||||
hwsim->tmp_chan->band,
|
||||
NULL)) {
|
||||
kfree_skb(probe);
|
||||
continue;
|
||||
}
|
||||
|
||||
local_bh_disable();
|
||||
mac80211_hwsim_tx_frame(hwsim->hw, probe,
|
||||
hwsim->tmp_chan);
|
||||
|
@ -3770,6 +3779,10 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
|
|||
}
|
||||
txi->flags |= IEEE80211_TX_STAT_ACK;
|
||||
}
|
||||
|
||||
if (hwsim_flags & HWSIM_TX_CTL_NO_ACK)
|
||||
txi->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
|
||||
ieee80211_tx_status_irqsafe(data2->hw, skb);
|
||||
return 0;
|
||||
out:
|
||||
|
|
|
@ -2158,7 +2158,7 @@ struct net_device {
|
|||
struct netdev_queue *_tx ____cacheline_aligned_in_smp;
|
||||
unsigned int num_tx_queues;
|
||||
unsigned int real_num_tx_queues;
|
||||
struct Qdisc *qdisc;
|
||||
struct Qdisc __rcu *qdisc;
|
||||
unsigned int tx_queue_len;
|
||||
spinlock_t tx_global_lock;
|
||||
|
||||
|
|
|
@ -109,8 +109,6 @@ struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
|
|||
int ipv6_dev_get_saddr(struct net *net, const struct net_device *dev,
|
||||
const struct in6_addr *daddr, unsigned int srcprefs,
|
||||
struct in6_addr *saddr);
|
||||
int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
||||
u32 banned_flags);
|
||||
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
|
||||
u32 banned_flags);
|
||||
bool inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
|
||||
|
|
|
@ -262,7 +262,7 @@ struct ad_system {
|
|||
struct ad_bond_info {
|
||||
struct ad_system system; /* 802.3ad system structure */
|
||||
struct bond_3ad_stats stats;
|
||||
u32 agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */
|
||||
atomic_t agg_select_timer; /* Timer to select aggregator after all adapter's hand shakes */
|
||||
u16 aggregator_identifier;
|
||||
};
|
||||
|
||||
|
|
|
@ -1187,6 +1187,7 @@ void dsa_unregister_switch(struct dsa_switch *ds);
|
|||
int dsa_register_switch(struct dsa_switch *ds);
|
||||
void dsa_switch_shutdown(struct dsa_switch *ds);
|
||||
struct dsa_switch *dsa_switch_find(int tree_index, int sw_index);
|
||||
void dsa_flush_workqueue(void);
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int dsa_switch_suspend(struct dsa_switch *ds);
|
||||
int dsa_switch_resume(struct dsa_switch *ds);
|
||||
|
|
|
@ -190,14 +190,16 @@ struct fib6_info {
|
|||
u32 fib6_metric;
|
||||
u8 fib6_protocol;
|
||||
u8 fib6_type;
|
||||
|
||||
u8 offload;
|
||||
u8 trap;
|
||||
u8 offload_failed;
|
||||
|
||||
u8 should_flush:1,
|
||||
dst_nocount:1,
|
||||
dst_nopolicy:1,
|
||||
fib6_destroying:1,
|
||||
offload:1,
|
||||
trap:1,
|
||||
offload_failed:1,
|
||||
unused:1;
|
||||
unused:4;
|
||||
|
||||
struct rcu_head rcu;
|
||||
struct nexthop *nh;
|
||||
|
|
|
@ -393,17 +393,20 @@ static inline void txopt_put(struct ipv6_txoptions *opt)
|
|||
kfree_rcu(opt, rcu);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label);
|
||||
|
||||
extern struct static_key_false_deferred ipv6_flowlabel_exclusive;
|
||||
static inline struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk,
|
||||
__be32 label)
|
||||
{
|
||||
if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key))
|
||||
if (static_branch_unlikely(&ipv6_flowlabel_exclusive.key) &&
|
||||
READ_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl))
|
||||
return __fl6_sock_lookup(sk, label) ? : ERR_PTR(-ENOENT);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
|
||||
struct ip6_flowlabel *fl,
|
||||
|
|
|
@ -77,9 +77,10 @@ struct netns_ipv6 {
|
|||
spinlock_t fib6_gc_lock;
|
||||
unsigned int ip6_rt_gc_expire;
|
||||
unsigned long ip6_rt_last_gc;
|
||||
unsigned char flowlabel_has_excl;
|
||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||
unsigned int fib6_rules_require_fldissect;
|
||||
bool fib6_has_custom_rules;
|
||||
unsigned int fib6_rules_require_fldissect;
|
||||
#ifdef CONFIG_IPV6_SUBTREES
|
||||
unsigned int fib6_routes_require_src;
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,9 @@ static void br_multicast_find_del_pg(struct net_bridge *br,
|
|||
struct net_bridge_port_group *pg);
|
||||
static void __br_multicast_stop(struct net_bridge_mcast *brmctx);
|
||||
|
||||
static int br_mc_disabled_update(struct net_device *dev, bool value,
|
||||
struct netlink_ext_ack *extack);
|
||||
|
||||
static struct net_bridge_port_group *
|
||||
br_sg_port_find(struct net_bridge *br,
|
||||
struct net_bridge_port_group_sg_key *sg_p)
|
||||
|
@ -1156,6 +1159,7 @@ struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
|
|||
return mp;
|
||||
|
||||
if (atomic_read(&br->mdb_hash_tbl.nelems) >= br->hash_max) {
|
||||
br_mc_disabled_update(br->dev, false, NULL);
|
||||
br_opt_toggle(br, BROPT_MULTICAST_ENABLED, false);
|
||||
return ERR_PTR(-E2BIG);
|
||||
}
|
||||
|
|
|
@ -283,13 +283,17 @@ static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi,
|
|||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(new_stat, &hw_stats_list, list) {
|
||||
struct net_device *dev;
|
||||
|
||||
/*
|
||||
* only add a note to our monitor buffer if:
|
||||
* 1) this is the dev we received on
|
||||
* 2) its after the last_rx delta
|
||||
* 3) our rx_dropped count has gone up
|
||||
*/
|
||||
if ((new_stat->dev == napi->dev) &&
|
||||
/* Paired with WRITE_ONCE() in dropmon_net_event() */
|
||||
dev = READ_ONCE(new_stat->dev);
|
||||
if ((dev == napi->dev) &&
|
||||
(time_after(jiffies, new_stat->last_rx + dm_hw_check_delta)) &&
|
||||
(napi->dev->stats.rx_dropped != new_stat->last_drop_val)) {
|
||||
trace_drop_common(NULL, NULL);
|
||||
|
@ -1576,7 +1580,10 @@ static int dropmon_net_event(struct notifier_block *ev_block,
|
|||
mutex_lock(&net_dm_mutex);
|
||||
list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
|
||||
if (new_stat->dev == dev) {
|
||||
new_stat->dev = NULL;
|
||||
|
||||
/* Paired with READ_ONCE() in trace_napi_poll_hit() */
|
||||
WRITE_ONCE(new_stat->dev, NULL);
|
||||
|
||||
if (trace_state == TRACE_OFF) {
|
||||
list_del_rcu(&new_stat->list);
|
||||
kfree_rcu(new_stat, rcu);
|
||||
|
|
|
@ -1699,6 +1699,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
|
|||
{
|
||||
struct ifinfomsg *ifm;
|
||||
struct nlmsghdr *nlh;
|
||||
struct Qdisc *qdisc;
|
||||
|
||||
ASSERT_RTNL();
|
||||
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
|
||||
|
@ -1716,6 +1717,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
|
|||
if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_TARGET_NETNSID, tgt_netnsid))
|
||||
goto nla_put_failure;
|
||||
|
||||
qdisc = rtnl_dereference(dev->qdisc);
|
||||
if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
|
||||
nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) ||
|
||||
nla_put_u8(skb, IFLA_OPERSTATE,
|
||||
|
@ -1735,8 +1737,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
|
|||
#endif
|
||||
put_master_ifindex(skb, dev) ||
|
||||
nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
|
||||
(dev->qdisc &&
|
||||
nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
|
||||
(qdisc &&
|
||||
nla_put_string(skb, IFLA_QDISC, qdisc->ops->id)) ||
|
||||
nla_put_ifalias(skb, dev) ||
|
||||
nla_put_u32(skb, IFLA_CARRIER_CHANGES,
|
||||
atomic_read(&dev->carrier_up_count) +
|
||||
|
|
|
@ -349,6 +349,7 @@ void dsa_flush_workqueue(void)
|
|||
{
|
||||
flush_workqueue(dsa_owq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dsa_flush_workqueue);
|
||||
|
||||
int dsa_devlink_param_get(struct devlink *dl, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
|
|
|
@ -147,7 +147,6 @@ void dsa_tag_driver_put(const struct dsa_device_ops *ops);
|
|||
const struct dsa_device_ops *dsa_find_tagger_by_name(const char *buf);
|
||||
|
||||
bool dsa_schedule_work(struct work_struct *work);
|
||||
void dsa_flush_workqueue(void);
|
||||
const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops);
|
||||
|
||||
static inline int dsa_tag_protocol_overhead(const struct dsa_device_ops *ops)
|
||||
|
|
|
@ -77,7 +77,6 @@ static struct sk_buff *lan9303_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
__be16 *lan9303_tag;
|
||||
u16 lan9303_tag1;
|
||||
unsigned int source_port;
|
||||
|
||||
|
@ -87,14 +86,15 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lan9303_tag = dsa_etype_header_pos_rx(skb);
|
||||
|
||||
if (lan9303_tag[0] != htons(ETH_P_8021Q)) {
|
||||
dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid VLAN marker\n");
|
||||
return NULL;
|
||||
if (skb_vlan_tag_present(skb)) {
|
||||
lan9303_tag1 = skb_vlan_tag_get(skb);
|
||||
__vlan_hwaccel_clear_tag(skb);
|
||||
} else {
|
||||
skb_push_rcsum(skb, ETH_HLEN);
|
||||
__skb_vlan_pop(skb, &lan9303_tag1);
|
||||
skb_pull_rcsum(skb, ETH_HLEN);
|
||||
}
|
||||
|
||||
lan9303_tag1 = ntohs(lan9303_tag[1]);
|
||||
source_port = lan9303_tag1 & 0x3;
|
||||
|
||||
skb->dev = dsa_master_find_slave(dev, 0, source_port);
|
||||
|
@ -103,13 +103,6 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* remove the special VLAN tag between the MAC addresses
|
||||
* and the current ethertype field.
|
||||
*/
|
||||
skb_pull_rcsum(skb, 2 + 2);
|
||||
|
||||
dsa_strip_etype_header(skb, LAN9303_TAG_LEN);
|
||||
|
||||
if (!(lan9303_tag1 & LAN9303_TAG_RX_TRAPPED_TO_CPU))
|
||||
dsa_default_offload_fwd_mark(skb);
|
||||
|
||||
|
|
|
@ -436,6 +436,9 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
|
|||
if (net->ipv4.fib_has_custom_local_routes ||
|
||||
fib4_has_custom_rules(net))
|
||||
goto full_check;
|
||||
/* Within the same container, it is regarded as a martian source,
|
||||
* and the same host but different containers are not.
|
||||
*/
|
||||
if (inet_lookup_ifaddr_rcu(net, src))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
@ -16,10 +16,9 @@ struct fib_alias {
|
|||
u8 fa_slen;
|
||||
u32 tb_id;
|
||||
s16 fa_default;
|
||||
u8 offload:1,
|
||||
trap:1,
|
||||
offload_failed:1,
|
||||
unused:5;
|
||||
u8 offload;
|
||||
u8 trap;
|
||||
u8 offload_failed;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
|
|
@ -525,9 +525,9 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
|
|||
fri.dst_len = dst_len;
|
||||
fri.tos = fa->fa_tos;
|
||||
fri.type = fa->fa_type;
|
||||
fri.offload = fa->offload;
|
||||
fri.trap = fa->trap;
|
||||
fri.offload_failed = fa->offload_failed;
|
||||
fri.offload = READ_ONCE(fa->offload);
|
||||
fri.trap = READ_ONCE(fa->trap);
|
||||
fri.offload_failed = READ_ONCE(fa->offload_failed);
|
||||
err = fib_dump_info(skb, info->portid, seq, event, &fri, nlm_flags);
|
||||
if (err < 0) {
|
||||
/* -EMSGSIZE implies BUG in fib_nlmsg_size() */
|
||||
|
|
|
@ -1047,19 +1047,23 @@ void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri)
|
|||
if (!fa_match)
|
||||
goto out;
|
||||
|
||||
if (fa_match->offload == fri->offload && fa_match->trap == fri->trap &&
|
||||
fa_match->offload_failed == fri->offload_failed)
|
||||
/* These are paired with the WRITE_ONCE() happening in this function.
|
||||
* The reason is that we are only protected by RCU at this point.
|
||||
*/
|
||||
if (READ_ONCE(fa_match->offload) == fri->offload &&
|
||||
READ_ONCE(fa_match->trap) == fri->trap &&
|
||||
READ_ONCE(fa_match->offload_failed) == fri->offload_failed)
|
||||
goto out;
|
||||
|
||||
fa_match->offload = fri->offload;
|
||||
fa_match->trap = fri->trap;
|
||||
WRITE_ONCE(fa_match->offload, fri->offload);
|
||||
WRITE_ONCE(fa_match->trap, fri->trap);
|
||||
|
||||
/* 2 means send notifications only if offload_failed was changed. */
|
||||
if (net->ipv4.sysctl_fib_notify_on_flag_change == 2 &&
|
||||
fa_match->offload_failed == fri->offload_failed)
|
||||
READ_ONCE(fa_match->offload_failed) == fri->offload_failed)
|
||||
goto out;
|
||||
|
||||
fa_match->offload_failed = fri->offload_failed;
|
||||
WRITE_ONCE(fa_match->offload_failed, fri->offload_failed);
|
||||
|
||||
if (!net->ipv4.sysctl_fib_notify_on_flag_change)
|
||||
goto out;
|
||||
|
@ -2297,9 +2301,9 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
|
|||
fri.dst_len = KEYLENGTH - fa->fa_slen;
|
||||
fri.tos = fa->fa_tos;
|
||||
fri.type = fa->fa_type;
|
||||
fri.offload = fa->offload;
|
||||
fri.trap = fa->trap;
|
||||
fri.offload_failed = fa->offload_failed;
|
||||
fri.offload = READ_ONCE(fa->offload);
|
||||
fri.trap = READ_ONCE(fa->trap);
|
||||
fri.offload_failed = READ_ONCE(fa->offload_failed);
|
||||
err = fib_dump_info(skb,
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
|
|
|
@ -172,16 +172,23 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
|
|||
struct sock *sk = NULL;
|
||||
struct inet_sock *isk;
|
||||
struct hlist_nulls_node *hnode;
|
||||
int dif = skb->dev->ifindex;
|
||||
int dif, sdif;
|
||||
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
dif = inet_iif(skb);
|
||||
sdif = inet_sdif(skb);
|
||||
pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
|
||||
(int)ident, &ip_hdr(skb)->daddr, dif);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
dif = inet6_iif(skb);
|
||||
sdif = inet6_sdif(skb);
|
||||
pr_debug("try to find: num = %d, daddr = %pI6c, dif = %d\n",
|
||||
(int)ident, &ipv6_hdr(skb)->daddr, dif);
|
||||
#endif
|
||||
} else {
|
||||
pr_err("ping: protocol(%x) is not supported\n", ntohs(skb->protocol));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
read_lock_bh(&ping_table.lock);
|
||||
|
@ -221,7 +228,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
|
|||
}
|
||||
|
||||
if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
|
||||
sk->sk_bound_dev_if != inet_sdif(skb))
|
||||
sk->sk_bound_dev_if != sdif)
|
||||
continue;
|
||||
|
||||
sock_hold(sk);
|
||||
|
|
|
@ -3395,8 +3395,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
|
|||
fa->fa_tos == fri.tos &&
|
||||
fa->fa_info == res.fi &&
|
||||
fa->fa_type == fri.type) {
|
||||
fri.offload = fa->offload;
|
||||
fri.trap = fa->trap;
|
||||
fri.offload = READ_ONCE(fa->offload);
|
||||
fri.trap = READ_ONCE(fa->trap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1839,8 +1839,8 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(ipv6_dev_get_saddr);
|
||||
|
||||
int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
||||
u32 banned_flags)
|
||||
static int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
|
||||
u32 banned_flags)
|
||||
{
|
||||
struct inet6_ifaddr *ifp;
|
||||
int err = -EADDRNOTAVAIL;
|
||||
|
|
|
@ -450,8 +450,10 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
|
|||
err = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if (fl_shared_exclusive(fl) || fl->opt)
|
||||
if (fl_shared_exclusive(fl) || fl->opt) {
|
||||
WRITE_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl, 1);
|
||||
static_branch_deferred_inc(&ipv6_flowlabel_exclusive);
|
||||
}
|
||||
return fl;
|
||||
|
||||
done:
|
||||
|
|
|
@ -1759,7 +1759,7 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu)
|
|||
skb_reserve(skb, hlen);
|
||||
skb_tailroom_reserve(skb, mtu, tlen);
|
||||
|
||||
if (__ipv6_get_lladdr(idev, &addr_buf, IFA_F_TENTATIVE)) {
|
||||
if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) {
|
||||
/* <draft-ietf-magma-mld-source-05.txt>:
|
||||
* use unspecified address as the source address
|
||||
* when a valid link-local address is not available.
|
||||
|
|
|
@ -5753,11 +5753,11 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
|
|||
}
|
||||
|
||||
if (!dst) {
|
||||
if (rt->offload)
|
||||
if (READ_ONCE(rt->offload))
|
||||
rtm->rtm_flags |= RTM_F_OFFLOAD;
|
||||
if (rt->trap)
|
||||
if (READ_ONCE(rt->trap))
|
||||
rtm->rtm_flags |= RTM_F_TRAP;
|
||||
if (rt->offload_failed)
|
||||
if (READ_ONCE(rt->offload_failed))
|
||||
rtm->rtm_flags |= RTM_F_OFFLOAD_FAILED;
|
||||
}
|
||||
|
||||
|
@ -6215,19 +6215,20 @@ void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
|
|||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
if (f6i->offload == offload && f6i->trap == trap &&
|
||||
f6i->offload_failed == offload_failed)
|
||||
if (READ_ONCE(f6i->offload) == offload &&
|
||||
READ_ONCE(f6i->trap) == trap &&
|
||||
READ_ONCE(f6i->offload_failed) == offload_failed)
|
||||
return;
|
||||
|
||||
f6i->offload = offload;
|
||||
f6i->trap = trap;
|
||||
WRITE_ONCE(f6i->offload, offload);
|
||||
WRITE_ONCE(f6i->trap, trap);
|
||||
|
||||
/* 2 means send notifications only if offload_failed was changed. */
|
||||
if (net->ipv6.sysctl.fib_notify_on_flag_change == 2 &&
|
||||
f6i->offload_failed == offload_failed)
|
||||
READ_ONCE(f6i->offload_failed) == offload_failed)
|
||||
return;
|
||||
|
||||
f6i->offload_failed = offload_failed;
|
||||
WRITE_ONCE(f6i->offload_failed, offload_failed);
|
||||
|
||||
if (!rcu_access_pointer(f6i->fib6_node))
|
||||
/* The route was removed from the tree, do not send
|
||||
|
|
|
@ -666,7 +666,7 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_ie_build_he_6ghz_cap(sdata, skb);
|
||||
}
|
||||
|
||||
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
static int ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
@ -686,6 +686,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
|
||||
const struct ieee80211_sband_iftype_data *iftd;
|
||||
struct ieee80211_prep_tx_info info = {};
|
||||
int ret;
|
||||
|
||||
/* we know it's writable, cast away the const */
|
||||
if (assoc_data->ie_len)
|
||||
|
@ -699,7 +700,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (WARN_ON(!chanctx_conf)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
|
@ -750,7 +751,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
(iftd ? iftd->vendor_elems.len : 0),
|
||||
GFP_KERNEL);
|
||||
if (!skb)
|
||||
return;
|
||||
return -ENOMEM;
|
||||
|
||||
skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
|
||||
|
@ -1031,15 +1032,22 @@ skip_rates:
|
|||
skb_put_data(skb, assoc_data->ie + offset, noffset - offset);
|
||||
}
|
||||
|
||||
if (assoc_data->fils_kek_len &&
|
||||
fils_encrypt_assoc_req(skb, assoc_data) < 0) {
|
||||
dev_kfree_skb(skb);
|
||||
return;
|
||||
if (assoc_data->fils_kek_len) {
|
||||
ret = fils_encrypt_assoc_req(skb, assoc_data);
|
||||
if (ret < 0) {
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
pos = skb_tail_pointer(skb);
|
||||
kfree(ifmgd->assoc_req_ies);
|
||||
ifmgd->assoc_req_ies = kmemdup(ie_start, pos - ie_start, GFP_ATOMIC);
|
||||
if (!ifmgd->assoc_req_ies) {
|
||||
dev_kfree_skb(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ifmgd->assoc_req_ies_len = pos - ie_start;
|
||||
|
||||
drv_mgd_prepare_tx(local, sdata, &info);
|
||||
|
@ -1049,6 +1057,8 @@ skip_rates:
|
|||
IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
|
||||
IEEE80211_TX_INTFL_MLME_CONN_TX;
|
||||
ieee80211_tx_skb(sdata, skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ieee80211_send_pspoll(struct ieee80211_local *local,
|
||||
|
@ -4497,6 +4507,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
{
|
||||
struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
int ret;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
|
@ -4517,7 +4528,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
sdata_info(sdata, "associate with %pM (try %d/%d)\n",
|
||||
assoc_data->bss->bssid, assoc_data->tries,
|
||||
IEEE80211_ASSOC_MAX_TRIES);
|
||||
ieee80211_send_assoc(sdata);
|
||||
ret = ieee80211_send_assoc(sdata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
|
||||
assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
|
||||
|
|
|
@ -412,13 +412,14 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
|
|||
* this function.
|
||||
*/
|
||||
rc = mctp_key_add(key, msk);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
kfree(key);
|
||||
} else {
|
||||
trace_mctp_key_acquire(key);
|
||||
|
||||
trace_mctp_key_acquire(key);
|
||||
|
||||
/* we don't need to release key->lock on exit */
|
||||
mctp_key_unref(key);
|
||||
/* we don't need to release key->lock on exit */
|
||||
mctp_key_unref(key);
|
||||
}
|
||||
key = NULL;
|
||||
|
||||
} else {
|
||||
|
|
|
@ -191,8 +191,10 @@ static int nft_synproxy_do_init(const struct nft_ctx *ctx,
|
|||
if (err)
|
||||
goto nf_ct_failure;
|
||||
err = nf_synproxy_ipv6_init(snet, ctx->net);
|
||||
if (err)
|
||||
if (err) {
|
||||
nf_synproxy_ipv4_fini(snet, ctx->net);
|
||||
goto nf_ct_failure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ static void socket_mt_destroy(const struct xt_mtdtor_param *par)
|
|||
if (par->family == NFPROTO_IPV4)
|
||||
nf_defrag_ipv4_disable(par->net);
|
||||
else if (par->family == NFPROTO_IPV6)
|
||||
nf_defrag_ipv4_disable(par->net);
|
||||
nf_defrag_ipv6_disable(par->net);
|
||||
}
|
||||
|
||||
static struct xt_match socket_mt_reg[] __read_mostly = {
|
||||
|
|
|
@ -1037,6 +1037,7 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
|
|||
restart_act_graph:
|
||||
for (i = 0; i < nr_actions; i++) {
|
||||
const struct tc_action *a = actions[i];
|
||||
int repeat_ttl;
|
||||
|
||||
if (jmp_prgcnt > 0) {
|
||||
jmp_prgcnt -= 1;
|
||||
|
@ -1045,11 +1046,17 @@ restart_act_graph:
|
|||
|
||||
if (tc_act_skip_sw(a->tcfa_flags))
|
||||
continue;
|
||||
|
||||
repeat_ttl = 32;
|
||||
repeat:
|
||||
ret = a->ops->act(skb, a, res);
|
||||
if (ret == TC_ACT_REPEAT)
|
||||
goto repeat; /* we need a ttl - JHS */
|
||||
|
||||
if (unlikely(ret == TC_ACT_REPEAT)) {
|
||||
if (--repeat_ttl != 0)
|
||||
goto repeat;
|
||||
/* suspicious opcode, stop pipeline */
|
||||
net_warn_ratelimited("TC_ACT_REPEAT abuse ?\n");
|
||||
return TC_ACT_OK;
|
||||
}
|
||||
if (TC_ACT_EXT_CMP(ret, TC_ACT_JUMP)) {
|
||||
jmp_prgcnt = ret & TCA_ACT_MAX_PRIO_MASK;
|
||||
if (!jmp_prgcnt || (jmp_prgcnt > nr_actions)) {
|
||||
|
|
|
@ -1044,7 +1044,7 @@ static int __tcf_qdisc_find(struct net *net, struct Qdisc **q,
|
|||
|
||||
/* Find qdisc */
|
||||
if (!*parent) {
|
||||
*q = dev->qdisc;
|
||||
*q = rcu_dereference(dev->qdisc);
|
||||
*parent = (*q)->handle;
|
||||
} else {
|
||||
*q = qdisc_lookup_rcu(dev, TC_H_MAJ(*parent));
|
||||
|
@ -2587,7 +2587,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
|
||||
parent = tcm->tcm_parent;
|
||||
if (!parent)
|
||||
q = dev->qdisc;
|
||||
q = rtnl_dereference(dev->qdisc);
|
||||
else
|
||||
q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
|
||||
if (!q)
|
||||
|
@ -2962,7 +2962,7 @@ static int tc_dump_chain(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
return skb->len;
|
||||
|
||||
if (!tcm->tcm_parent)
|
||||
q = dev->qdisc;
|
||||
q = rtnl_dereference(dev->qdisc);
|
||||
else
|
||||
q = qdisc_lookup(dev, TC_H_MAJ(tcm->tcm_parent));
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
|
|||
|
||||
if (!handle)
|
||||
return NULL;
|
||||
q = qdisc_match_from_root(dev->qdisc, handle);
|
||||
q = qdisc_match_from_root(rtnl_dereference(dev->qdisc), handle);
|
||||
if (q)
|
||||
goto out;
|
||||
|
||||
|
@ -320,7 +320,7 @@ struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle)
|
|||
|
||||
if (!handle)
|
||||
return NULL;
|
||||
q = qdisc_match_from_root(dev->qdisc, handle);
|
||||
q = qdisc_match_from_root(rcu_dereference(dev->qdisc), handle);
|
||||
if (q)
|
||||
goto out;
|
||||
|
||||
|
@ -1082,10 +1082,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
|
|||
skip:
|
||||
if (!ingress) {
|
||||
notify_and_destroy(net, skb, n, classid,
|
||||
dev->qdisc, new);
|
||||
rtnl_dereference(dev->qdisc), new);
|
||||
if (new && !new->ops->attach)
|
||||
qdisc_refcount_inc(new);
|
||||
dev->qdisc = new ? : &noop_qdisc;
|
||||
rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc);
|
||||
|
||||
if (new && new->ops->attach)
|
||||
new->ops->attach(new);
|
||||
|
@ -1451,7 +1451,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
q = dev_ingress_queue(dev)->qdisc_sleeping;
|
||||
}
|
||||
} else {
|
||||
q = dev->qdisc;
|
||||
q = rtnl_dereference(dev->qdisc);
|
||||
}
|
||||
if (!q) {
|
||||
NL_SET_ERR_MSG(extack, "Cannot find specified qdisc on specified device");
|
||||
|
@ -1540,7 +1540,7 @@ replay:
|
|||
q = dev_ingress_queue(dev)->qdisc_sleeping;
|
||||
}
|
||||
} else {
|
||||
q = dev->qdisc;
|
||||
q = rtnl_dereference(dev->qdisc);
|
||||
}
|
||||
|
||||
/* It may be default qdisc, ignore it */
|
||||
|
@ -1762,7 +1762,8 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
s_q_idx = 0;
|
||||
q_idx = 0;
|
||||
|
||||
if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx,
|
||||
if (tc_dump_qdisc_root(rtnl_dereference(dev->qdisc),
|
||||
skb, cb, &q_idx, s_q_idx,
|
||||
true, tca[TCA_DUMP_INVISIBLE]) < 0)
|
||||
goto done;
|
||||
|
||||
|
@ -2033,7 +2034,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
} else if (qid1) {
|
||||
qid = qid1;
|
||||
} else if (qid == 0)
|
||||
qid = dev->qdisc->handle;
|
||||
qid = rtnl_dereference(dev->qdisc)->handle;
|
||||
|
||||
/* Now qid is genuine qdisc handle consistent
|
||||
* both with parent and child.
|
||||
|
@ -2044,7 +2045,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
|
|||
portid = TC_H_MAKE(qid, portid);
|
||||
} else {
|
||||
if (qid == 0)
|
||||
qid = dev->qdisc->handle;
|
||||
qid = rtnl_dereference(dev->qdisc)->handle;
|
||||
}
|
||||
|
||||
/* OK. Locate qdisc */
|
||||
|
@ -2205,7 +2206,8 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
s_t = cb->args[0];
|
||||
t = 0;
|
||||
|
||||
if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t, true) < 0)
|
||||
if (tc_dump_tclass_root(rtnl_dereference(dev->qdisc),
|
||||
skb, tcm, cb, &t, s_t, true) < 0)
|
||||
goto done;
|
||||
|
||||
dev_queue = dev_ingress_queue(dev);
|
||||
|
|
|
@ -1164,30 +1164,33 @@ static void attach_default_qdiscs(struct net_device *dev)
|
|||
if (!netif_is_multiqueue(dev) ||
|
||||
dev->priv_flags & IFF_NO_QUEUE) {
|
||||
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
|
||||
dev->qdisc = txq->qdisc_sleeping;
|
||||
qdisc_refcount_inc(dev->qdisc);
|
||||
qdisc = txq->qdisc_sleeping;
|
||||
rcu_assign_pointer(dev->qdisc, qdisc);
|
||||
qdisc_refcount_inc(qdisc);
|
||||
} else {
|
||||
qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT, NULL);
|
||||
if (qdisc) {
|
||||
dev->qdisc = qdisc;
|
||||
rcu_assign_pointer(dev->qdisc, qdisc);
|
||||
qdisc->ops->attach(qdisc);
|
||||
}
|
||||
}
|
||||
qdisc = rtnl_dereference(dev->qdisc);
|
||||
|
||||
/* Detect default qdisc setup/init failed and fallback to "noqueue" */
|
||||
if (dev->qdisc == &noop_qdisc) {
|
||||
if (qdisc == &noop_qdisc) {
|
||||
netdev_warn(dev, "default qdisc (%s) fail, fallback to %s\n",
|
||||
default_qdisc_ops->id, noqueue_qdisc_ops.id);
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
|
||||
dev->qdisc = txq->qdisc_sleeping;
|
||||
qdisc_refcount_inc(dev->qdisc);
|
||||
qdisc = txq->qdisc_sleeping;
|
||||
rcu_assign_pointer(dev->qdisc, qdisc);
|
||||
qdisc_refcount_inc(qdisc);
|
||||
dev->priv_flags ^= IFF_NO_QUEUE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
if (dev->qdisc != &noop_qdisc)
|
||||
qdisc_hash_add(dev->qdisc, false);
|
||||
if (qdisc != &noop_qdisc)
|
||||
qdisc_hash_add(qdisc, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1220,7 @@ void dev_activate(struct net_device *dev)
|
|||
* and noqueue_qdisc for virtual interfaces
|
||||
*/
|
||||
|
||||
if (dev->qdisc == &noop_qdisc)
|
||||
if (rtnl_dereference(dev->qdisc) == &noop_qdisc)
|
||||
attach_default_qdiscs(dev);
|
||||
|
||||
if (!netif_carrier_ok(dev))
|
||||
|
@ -1383,7 +1386,7 @@ static int qdisc_change_tx_queue_len(struct net_device *dev,
|
|||
void dev_qdisc_change_real_num_tx(struct net_device *dev,
|
||||
unsigned int new_real_tx)
|
||||
{
|
||||
struct Qdisc *qdisc = dev->qdisc;
|
||||
struct Qdisc *qdisc = rtnl_dereference(dev->qdisc);
|
||||
|
||||
if (qdisc->ops->change_real_num_tx)
|
||||
qdisc->ops->change_real_num_tx(qdisc, new_real_tx);
|
||||
|
@ -1447,7 +1450,7 @@ static void dev_init_scheduler_queue(struct net_device *dev,
|
|||
|
||||
void dev_init_scheduler(struct net_device *dev)
|
||||
{
|
||||
dev->qdisc = &noop_qdisc;
|
||||
rcu_assign_pointer(dev->qdisc, &noop_qdisc);
|
||||
netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
|
||||
if (dev_ingress_queue(dev))
|
||||
dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
|
||||
|
@ -1475,8 +1478,8 @@ void dev_shutdown(struct net_device *dev)
|
|||
netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
|
||||
if (dev_ingress_queue(dev))
|
||||
shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
|
||||
qdisc_put(dev->qdisc);
|
||||
dev->qdisc = &noop_qdisc;
|
||||
qdisc_put(rtnl_dereference(dev->qdisc));
|
||||
rcu_assign_pointer(dev->qdisc, &noop_qdisc);
|
||||
|
||||
WARN_ON(timer_pending(&dev->watchdog_timer));
|
||||
}
|
||||
|
|
|
@ -667,14 +667,17 @@ static void smc_fback_error_report(struct sock *clcsk)
|
|||
static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
|
||||
{
|
||||
struct sock *clcsk;
|
||||
int rc = 0;
|
||||
|
||||
mutex_lock(&smc->clcsock_release_lock);
|
||||
if (!smc->clcsock) {
|
||||
mutex_unlock(&smc->clcsock_release_lock);
|
||||
return -EBADF;
|
||||
rc = -EBADF;
|
||||
goto out;
|
||||
}
|
||||
clcsk = smc->clcsock->sk;
|
||||
|
||||
if (smc->use_fallback)
|
||||
goto out;
|
||||
smc->use_fallback = true;
|
||||
smc->fallback_rsn = reason_code;
|
||||
smc_stat_fallback(smc);
|
||||
|
@ -702,8 +705,9 @@ static int smc_switch_to_fallback(struct smc_sock *smc, int reason_code)
|
|||
smc->clcsock->sk->sk_user_data =
|
||||
(void *)((uintptr_t)smc | SK_USER_DATA_NOCOPY);
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&smc->clcsock_release_lock);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* fall back during connect */
|
||||
|
|
|
@ -3448,7 +3448,7 @@ EXPORT_SYMBOL(kernel_connect);
|
|||
* @addr: address holder
|
||||
*
|
||||
* Fills the @addr pointer with the address which the socket is bound.
|
||||
* Returns 0 or an error code.
|
||||
* Returns the length of the address in bytes or an error code.
|
||||
*/
|
||||
|
||||
int kernel_getsockname(struct socket *sock, struct sockaddr *addr)
|
||||
|
@ -3463,7 +3463,7 @@ EXPORT_SYMBOL(kernel_getsockname);
|
|||
* @addr: address holder
|
||||
*
|
||||
* Fills the @addr pointer with the address which the socket is connected.
|
||||
* Returns 0 or an error code.
|
||||
* Returns the length of the address in bytes or an error code.
|
||||
*/
|
||||
|
||||
int kernel_getpeername(struct socket *sock, struct sockaddr *addr)
|
||||
|
|
|
@ -2276,7 +2276,7 @@ static bool tipc_crypto_key_rcv(struct tipc_crypto *rx, struct tipc_msg *hdr)
|
|||
struct tipc_crypto *tx = tipc_net(rx->net)->crypto_tx;
|
||||
struct tipc_aead_key *skey = NULL;
|
||||
u16 key_gen = msg_key_gen(hdr);
|
||||
u16 size = msg_data_sz(hdr);
|
||||
u32 size = msg_data_sz(hdr);
|
||||
u8 *data = msg_data(hdr);
|
||||
unsigned int keylen;
|
||||
|
||||
|
|
|
@ -403,7 +403,7 @@ static void tipc_node_write_unlock(struct tipc_node *n)
|
|||
u32 flags = n->action_flags;
|
||||
struct list_head *publ_list;
|
||||
struct tipc_uaddr ua;
|
||||
u32 bearer_id;
|
||||
u32 bearer_id, node;
|
||||
|
||||
if (likely(!flags)) {
|
||||
write_unlock_bh(&n->lock);
|
||||
|
@ -413,7 +413,8 @@ static void tipc_node_write_unlock(struct tipc_node *n)
|
|||
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_NODE_SCOPE,
|
||||
TIPC_LINK_STATE, n->addr, n->addr);
|
||||
sk.ref = n->link_id;
|
||||
sk.node = n->addr;
|
||||
sk.node = tipc_own_addr(net);
|
||||
node = n->addr;
|
||||
bearer_id = n->link_id & 0xffff;
|
||||
publ_list = &n->publ_list;
|
||||
|
||||
|
@ -423,17 +424,17 @@ static void tipc_node_write_unlock(struct tipc_node *n)
|
|||
write_unlock_bh(&n->lock);
|
||||
|
||||
if (flags & TIPC_NOTIFY_NODE_DOWN)
|
||||
tipc_publ_notify(net, publ_list, sk.node, n->capabilities);
|
||||
tipc_publ_notify(net, publ_list, node, n->capabilities);
|
||||
|
||||
if (flags & TIPC_NOTIFY_NODE_UP)
|
||||
tipc_named_node_up(net, sk.node, n->capabilities);
|
||||
tipc_named_node_up(net, node, n->capabilities);
|
||||
|
||||
if (flags & TIPC_NOTIFY_LINK_UP) {
|
||||
tipc_mon_peer_up(net, sk.node, bearer_id);
|
||||
tipc_mon_peer_up(net, node, bearer_id);
|
||||
tipc_nametbl_publish(net, &ua, &sk, sk.ref);
|
||||
}
|
||||
if (flags & TIPC_NOTIFY_LINK_DOWN) {
|
||||
tipc_mon_peer_down(net, sk.node, bearer_id);
|
||||
tipc_mon_peer_down(net, node, bearer_id);
|
||||
tipc_nametbl_withdraw(net, &ua, &sk, sk.ref);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1401,6 +1401,7 @@ static int vsock_connect(struct socket *sock, struct sockaddr *addr,
|
|||
sk->sk_state = sk->sk_state == TCP_ESTABLISHED ? TCP_CLOSING : TCP_CLOSE;
|
||||
sock->state = SS_UNCONNECTED;
|
||||
vsock_transport_cancel_pkt(vsk);
|
||||
vsock_remove_connected(vsk);
|
||||
goto out_wait;
|
||||
} else if (timeout == 0) {
|
||||
err = -ETIMEDOUT;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2021 Intel Corporation
|
||||
* Copyright (C) 2018-2022 Intel Corporation
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
@ -332,29 +332,20 @@ static void cfg80211_event_work(struct work_struct *work)
|
|||
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
struct wireless_dev *wdev, *tmp;
|
||||
bool found = false;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->nl_owner_dead) {
|
||||
if (wdev->netdev)
|
||||
dev_close(wdev->netdev);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return;
|
||||
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->nl_owner_dead) {
|
||||
wiphy_lock(&rdev->wiphy);
|
||||
cfg80211_leave(rdev, wdev);
|
||||
rdev_del_virtual_intf(rdev, wdev);
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
}
|
||||
}
|
||||
wiphy_unlock(&rdev->wiphy);
|
||||
}
|
||||
|
||||
static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
||||
|
|
|
@ -6,7 +6,7 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \
|
|||
nft_concat_range.sh nft_conntrack_helper.sh \
|
||||
nft_queue.sh nft_meta.sh nf_nat_edemux.sh \
|
||||
ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \
|
||||
conntrack_vrf.sh
|
||||
conntrack_vrf.sh nft_synproxy.sh
|
||||
|
||||
LDLIBS = -lmnl
|
||||
TEST_GEN_FILES = nf-queue
|
||||
|
|
|
@ -1601,4 +1601,4 @@ for name in ${TESTS}; do
|
|||
done
|
||||
done
|
||||
|
||||
[ ${passed} -eq 0 ] && exit ${KSELFTEST_SKIP}
|
||||
[ ${passed} -eq 0 ] && exit ${KSELFTEST_SKIP} || exit 0
|
||||
|
|
|
@ -174,6 +174,7 @@ test_ping() {
|
|||
ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
|
||||
ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
|
||||
ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
|
||||
ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.rp_filter=0 > /dev/null
|
||||
|
||||
sleep 3
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
ret=0
|
||||
|
||||
rnd=$(mktemp -u XXXXXXXX)
|
||||
nsr="nsr-$rnd" # synproxy machine
|
||||
ns1="ns1-$rnd" # iperf client
|
||||
ns2="ns2-$rnd" # iperf server
|
||||
|
||||
checktool (){
|
||||
if ! $1 > /dev/null 2>&1; then
|
||||
echo "SKIP: Could not $2"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
}
|
||||
|
||||
checktool "nft --version" "run test without nft tool"
|
||||
checktool "ip -Version" "run test without ip tool"
|
||||
checktool "iperf3 --version" "run test without iperf3"
|
||||
checktool "ip netns add $nsr" "create net namespace"
|
||||
|
||||
modprobe -q nf_conntrack
|
||||
|
||||
ip netns add $ns1
|
||||
ip netns add $ns2
|
||||
|
||||
cleanup() {
|
||||
ip netns pids $ns1 | xargs kill 2>/dev/null
|
||||
ip netns pids $ns2 | xargs kill 2>/dev/null
|
||||
ip netns del $ns1
|
||||
ip netns del $ns2
|
||||
|
||||
ip netns del $nsr
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
ip link add veth0 netns $nsr type veth peer name eth0 netns $ns1
|
||||
ip link add veth1 netns $nsr type veth peer name eth0 netns $ns2
|
||||
|
||||
for dev in lo veth0 veth1; do
|
||||
ip -net $nsr link set $dev up
|
||||
done
|
||||
|
||||
ip -net $nsr addr add 10.0.1.1/24 dev veth0
|
||||
ip -net $nsr addr add 10.0.2.1/24 dev veth1
|
||||
|
||||
ip netns exec $nsr sysctl -q net.ipv4.conf.veth0.forwarding=1
|
||||
ip netns exec $nsr sysctl -q net.ipv4.conf.veth1.forwarding=1
|
||||
ip netns exec $nsr sysctl -q net.netfilter.nf_conntrack_tcp_loose=0
|
||||
|
||||
for n in $ns1 $ns2; do
|
||||
ip -net $n link set lo up
|
||||
ip -net $n link set eth0 up
|
||||
done
|
||||
ip -net $ns1 addr add 10.0.1.99/24 dev eth0
|
||||
ip -net $ns2 addr add 10.0.2.99/24 dev eth0
|
||||
ip -net $ns1 route add default via 10.0.1.1
|
||||
ip -net $ns2 route add default via 10.0.2.1
|
||||
|
||||
# test basic connectivity
|
||||
if ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then
|
||||
echo "ERROR: $ns1 cannot reach $ns2" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then
|
||||
echo "ERROR: $ns2 cannot reach $ns1" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ip netns exec $ns2 iperf3 -s > /dev/null 2>&1 &
|
||||
# ip netns exec $nsr tcpdump -vvv -n -i veth1 tcp | head -n 10 &
|
||||
|
||||
sleep 1
|
||||
|
||||
ip netns exec $nsr nft -f - <<EOF
|
||||
table inet filter {
|
||||
chain prerouting {
|
||||
type filter hook prerouting priority -300; policy accept;
|
||||
meta iif veth0 tcp flags syn counter notrack
|
||||
}
|
||||
|
||||
chain forward {
|
||||
type filter hook forward priority 0; policy accept;
|
||||
|
||||
ct state new,established counter accept
|
||||
|
||||
meta iif veth0 meta l4proto tcp ct state untracked,invalid synproxy mss 1460 sack-perm timestamp
|
||||
|
||||
ct state invalid counter drop
|
||||
|
||||
# make ns2 unreachable w.o. tcp synproxy
|
||||
tcp flags syn counter drop
|
||||
}
|
||||
}
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: Cannot add nft synproxy"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
ip netns exec $ns1 timeout 5 iperf3 -c 10.0.2.99 -n $((1 * 1024 * 1024)) > /dev/null
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "FAIL: iperf3 returned an error" 1>&2
|
||||
ret=$?
|
||||
ip netns exec $nsr nft list ruleset
|
||||
else
|
||||
echo "PASS: synproxy connection successful"
|
||||
fi
|
||||
|
||||
exit $ret
|
Loading…
Reference in New Issue