mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-17 12:34:01 +00:00
Networking fixes for 5.19-rc2, including fixes from bpf and netfilter.
Current release - regressions: - eth: amt: fix possible null-ptr-deref in amt_rcv() Previous releases - regressions: - tcp: use alloc_large_system_hash() to allocate table_perturb - af_unix: fix a data-race in unix_dgram_peer_wake_me() - nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling - eth: ixgbe: fix unexpected VLAN rx in promisc mode on VF Previous releases - always broken: - ipv6: fix signed integer overflow in __ip6_append_data - netfilter: - nat: really support inet nat without l3 address - nf_tables: memleak flow rule from commit path - bpf: fix calling global functions from BPF_PROG_TYPE_EXT programs - openvswitch: fix misuse of the cached connection on tuple changes - nfc: nfcmrvl: fix memory leak in nfcmrvl_play_deferred - eth: altera: fix refcount leak in altera_tse_mdio_create Misc: - add Quentin Monnet to bpftool maintainers Signed-off-by: Paolo Abeni <pabeni@redhat.com> -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmKhykgSHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOkN7sQAIn+ZmzQqTm5MVWnlvt/GcRGjjMP2VQY 60oS2re8QC773yWoP6PvXqxCSFc99paDCC5BmCK6DMLbp9yuVSp5W8iAPuFuyjXE /Nur4Ti57LcGJ8ZpcJheBD4cRFbf+xtsGzx9a1WhUDrCYASo7vqRes5Eos2dT7P7 qjgTduhUtaj6S1CfenfTnYqemZPzSGa+1euDuQ/Bu4mjCPUTrNZZQVYjmfTYM9p1 UzwfCQr9TtmRKo8wLFHnYDLoWHNpfp55SNL0ShAwIQqgldiJ2OdMje+a2Sa4m6uF etRz8H0WrGVqfneD424tdyZv4nwhHw5dnaSrGe8DGq98c4/lIIcVyC38oDAbfWqI l8p7ZmtvNid7rpgoQFcxKpb2TAYAI+jaFq5GySEhvj5ZAblNQgFyghfMGPoncXCO XW6va8TtP2lmHFScAljQiQb6GNwDO52x77/q14Jkwvr+DILRKXMZZ3hCGrKUn5JM lafGkdL5ufm+E9C9RlaWN3imb2KoRj+wdThgV79efEPGG1py7yLOPVMoOCP3qmLq torcGcfDi1LGb7ohQxN6tCMv0JgXjS5nd1i+qJnImpkhRrUmahOfmpnElHoPuzs3 6FU8HR77Eo15x70Jt+WOMy4oXrNh2MeEm8/Fhpj84MEhKpxVn+2o/53M+++5h+ru YtiLwEri0dCA =rdoB -----END PGP SIGNATURE----- Merge tag 'net-5.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from bpf and netfilter. Current release - regressions: - eth: amt: fix possible null-ptr-deref in amt_rcv() Previous releases - regressions: - tcp: use alloc_large_system_hash() to allocate table_perturb - af_unix: fix a data-race in unix_dgram_peer_wake_me() - nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling - eth: ixgbe: fix unexpected VLAN rx in promisc mode on VF Previous releases - always broken: - ipv6: fix signed integer overflow in __ip6_append_data - netfilter: - nat: really support inet nat without l3 address - nf_tables: memleak flow rule from commit path - bpf: fix calling global functions from BPF_PROG_TYPE_EXT programs - openvswitch: fix misuse of the cached connection on tuple changes - nfc: nfcmrvl: fix memory leak in nfcmrvl_play_deferred - eth: altera: fix refcount leak in altera_tse_mdio_create Misc: - add Quentin Monnet to bpftool maintainers" * tag 'net-5.19-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (45 commits) net: amd-xgbe: fix clang -Wformat warning tcp: use alloc_large_system_hash() to allocate table_perturb net: dsa: realtek: rtl8365mb: fix GMII caps for ports with internal PHY net: dsa: mv88e6xxx: correctly report serdes link failure net: dsa: mv88e6xxx: fix BMSR error to be consistent with others net: dsa: mv88e6xxx: use BMSR_ANEGCOMPLETE bit for filling an_complete net: altera: Fix refcount leak in altera_tse_mdio_create net: openvswitch: fix misuse of the cached connection on tuple changes net: ethernet: mtk_eth_soc: fix misuse of mem alloc interface netdev[napi]_alloc_frag ip_gre: test csum_start instead of transport header au1000_eth: stop using virt_to_bus() ipv6: Fix signed integer overflow in l2tp_ip6_sendmsg ipv6: Fix signed integer overflow in __ip6_append_data nfc: nfcmrvl: Fix memory leak in nfcmrvl_play_deferred nfc: st21nfca: fix incorrect sizing calculations in EVT_TRANSACTION nfc: st21nfca: fix memory leaks in EVT_TRANSACTION handling nfc: st21nfca: fix incorrect validating logic in EVT_TRANSACTION net: ipv6: unexport __init-annotated seg6_hmac_init() net: xfrm: unexport __init-annotated xfrm4_protocol_init() net: mdio: unexport __init-annotated mdio_bus_init() ...
This commit is contained in:
commit
825464e79d
44 changed files with 370 additions and 192 deletions
|
@ -3757,6 +3757,13 @@ F: include/linux/bpf_lsm.h
|
|||
F: kernel/bpf/bpf_lsm.c
|
||||
F: security/bpf/
|
||||
|
||||
BPFTOOL
|
||||
M: Quentin Monnet <quentin@isovalent.com>
|
||||
L: bpf@vger.kernel.org
|
||||
S: Maintained
|
||||
F: kernel/bpf/disasm.*
|
||||
F: tools/bpf/bpftool/
|
||||
|
||||
BROADCOM B44 10/100 ETHERNET DRIVER
|
||||
M: Michael Chan <michael.chan@broadcom.com>
|
||||
L: netdev@vger.kernel.org
|
||||
|
|
|
@ -1478,6 +1478,7 @@ skip_init_ctx:
|
|||
bpf_jit_binary_free(header);
|
||||
prog->bpf_func = NULL;
|
||||
prog->jited = 0;
|
||||
prog->jited_len = 0;
|
||||
goto out_off;
|
||||
}
|
||||
bpf_jit_binary_lock_ro(header);
|
||||
|
|
|
@ -51,6 +51,7 @@ static char *status_str[] = {
|
|||
};
|
||||
|
||||
static char *type_str[] = {
|
||||
"", /* Type 0 is not defined */
|
||||
"AMT_MSG_DISCOVERY",
|
||||
"AMT_MSG_ADVERTISEMENT",
|
||||
"AMT_MSG_REQUEST",
|
||||
|
@ -2220,8 +2221,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
|
|||
struct amt_header_advertisement *amta;
|
||||
int hdr_size;
|
||||
|
||||
hdr_size = sizeof(*amta) - sizeof(struct amt_header);
|
||||
|
||||
hdr_size = sizeof(*amta) + sizeof(struct udphdr);
|
||||
if (!pskb_may_pull(skb, hdr_size))
|
||||
return true;
|
||||
|
||||
|
@ -2251,19 +2251,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
|
|||
struct ethhdr *eth;
|
||||
struct iphdr *iph;
|
||||
|
||||
hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
|
||||
if (!pskb_may_pull(skb, hdr_size))
|
||||
return true;
|
||||
|
||||
amtmd = (struct amt_header_mcast_data *)(udp_hdr(skb) + 1);
|
||||
if (amtmd->reserved || amtmd->version)
|
||||
return true;
|
||||
|
||||
hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
|
||||
if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_IP), false))
|
||||
return true;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
skb_push(skb, sizeof(*eth));
|
||||
skb_reset_mac_header(skb);
|
||||
skb_pull(skb, sizeof(*eth));
|
||||
eth = eth_hdr(skb);
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(*iph)))
|
||||
return true;
|
||||
iph = ip_hdr(skb);
|
||||
|
||||
if (iph->version == 4) {
|
||||
if (!ipv4_is_multicast(iph->daddr))
|
||||
return true;
|
||||
|
@ -2274,6 +2282,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
|
|||
} else if (iph->version == 6) {
|
||||
struct ipv6hdr *ip6h;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(*ip6h)))
|
||||
return true;
|
||||
|
||||
ip6h = ipv6_hdr(skb);
|
||||
if (!ipv6_addr_is_multicast(&ip6h->daddr))
|
||||
return true;
|
||||
|
@ -2306,8 +2317,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
|
|||
struct iphdr *iph;
|
||||
int hdr_size, len;
|
||||
|
||||
hdr_size = sizeof(*amtmq) - sizeof(struct amt_header);
|
||||
|
||||
hdr_size = sizeof(*amtmq) + sizeof(struct udphdr);
|
||||
if (!pskb_may_pull(skb, hdr_size))
|
||||
return true;
|
||||
|
||||
|
@ -2315,22 +2325,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
|
|||
if (amtmq->reserved || amtmq->version)
|
||||
return true;
|
||||
|
||||
hdr_size = sizeof(*amtmq) + sizeof(struct udphdr) - sizeof(*eth);
|
||||
hdr_size -= sizeof(*eth);
|
||||
if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
|
||||
return true;
|
||||
|
||||
oeth = eth_hdr(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
skb_pull(skb, sizeof(*eth));
|
||||
skb_reset_network_header(skb);
|
||||
eth = eth_hdr(skb);
|
||||
if (!pskb_may_pull(skb, sizeof(*iph)))
|
||||
return true;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
if (iph->version == 4) {
|
||||
if (!ipv4_is_multicast(iph->daddr))
|
||||
return true;
|
||||
if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
|
||||
sizeof(*ihv3)))
|
||||
return true;
|
||||
|
||||
if (!ipv4_is_multicast(iph->daddr))
|
||||
return true;
|
||||
|
||||
ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
|
||||
skb_reset_transport_header(skb);
|
||||
skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
|
||||
|
@ -2345,15 +2360,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
|
|||
ip_eth_mc_map(iph->daddr, eth->h_dest);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
} else if (iph->version == 6) {
|
||||
struct ipv6hdr *ip6h = ipv6_hdr(skb);
|
||||
struct mld2_query *mld2q;
|
||||
struct ipv6hdr *ip6h;
|
||||
|
||||
if (!ipv6_addr_is_multicast(&ip6h->daddr))
|
||||
return true;
|
||||
if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
|
||||
sizeof(*mld2q)))
|
||||
return true;
|
||||
|
||||
ip6h = ipv6_hdr(skb);
|
||||
if (!ipv6_addr_is_multicast(&ip6h->daddr))
|
||||
return true;
|
||||
|
||||
mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
|
||||
skb_reset_transport_header(skb);
|
||||
skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
|
||||
|
@ -2389,23 +2406,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
|
|||
{
|
||||
struct amt_header_membership_update *amtmu;
|
||||
struct amt_tunnel_list *tunnel;
|
||||
struct udphdr *udph;
|
||||
struct ethhdr *eth;
|
||||
struct iphdr *iph;
|
||||
int len;
|
||||
int len, hdr_size;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
udph = udp_hdr(skb);
|
||||
|
||||
if (__iptunnel_pull_header(skb, sizeof(*udph), skb->protocol,
|
||||
false, false))
|
||||
hdr_size = sizeof(*amtmu) + sizeof(struct udphdr);
|
||||
if (!pskb_may_pull(skb, hdr_size))
|
||||
return true;
|
||||
|
||||
amtmu = (struct amt_header_membership_update *)skb->data;
|
||||
amtmu = (struct amt_header_membership_update *)(udp_hdr(skb) + 1);
|
||||
if (amtmu->reserved || amtmu->version)
|
||||
return true;
|
||||
|
||||
skb_pull(skb, sizeof(*amtmu));
|
||||
if (iptunnel_pull_header(skb, hdr_size, skb->protocol, false))
|
||||
return true;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
|
||||
|
@ -2426,6 +2443,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
|
|||
return true;
|
||||
|
||||
report:
|
||||
if (!pskb_may_pull(skb, sizeof(*iph)))
|
||||
return true;
|
||||
|
||||
iph = ip_hdr(skb);
|
||||
if (iph->version == 4) {
|
||||
if (ip_mc_check_igmp(skb)) {
|
||||
|
@ -2679,7 +2699,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
|
|||
amt = rcu_dereference_sk_user_data(sk);
|
||||
if (!amt) {
|
||||
err = true;
|
||||
goto drop;
|
||||
kfree_skb(skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
skb->dev = amt->dev;
|
||||
|
|
|
@ -2070,8 +2070,10 @@ static int gswip_gphy_fw_list(struct gswip_priv *priv,
|
|||
for_each_available_child_of_node(gphy_fw_list_np, gphy_fw_np) {
|
||||
err = gswip_gphy_fw_probe(priv, &priv->gphy_fw[i],
|
||||
gphy_fw_np, i);
|
||||
if (err)
|
||||
if (err) {
|
||||
of_node_put(gphy_fw_np);
|
||||
goto remove_gphy;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,22 +50,25 @@ static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
|
|||
}
|
||||
|
||||
static int mv88e6xxx_serdes_pcs_get_state(struct mv88e6xxx_chip *chip,
|
||||
u16 ctrl, u16 status, u16 lpa,
|
||||
u16 bmsr, u16 lpa, u16 status,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
state->link = false;
|
||||
|
||||
/* If the BMSR reports that the link had failed, report this to
|
||||
* phylink.
|
||||
*/
|
||||
if (!(bmsr & BMSR_LSTATUS))
|
||||
return 0;
|
||||
|
||||
state->link = !!(status & MV88E6390_SGMII_PHY_STATUS_LINK);
|
||||
state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
|
||||
|
||||
if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
|
||||
/* The Spped and Duplex Resolved register is 1 if AN is enabled
|
||||
* and complete, or if AN is disabled. So with disabled AN we
|
||||
* still get here on link up. But we want to set an_complete
|
||||
* only if AN was enabled, thus we look at BMCR_ANENABLE.
|
||||
* (According to 802.3-2008 section 22.2.4.2.10, we should be
|
||||
* able to get this same value from BMSR_ANEGCAPABLE, but tests
|
||||
* show that these Marvell PHYs don't conform to this part of
|
||||
* the specificaion - BMSR_ANEGCAPABLE is simply always 1.)
|
||||
* still get here on link up.
|
||||
*/
|
||||
state->an_complete = !!(ctrl & BMCR_ANENABLE);
|
||||
state->duplex = status &
|
||||
MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
|
||||
DUPLEX_FULL : DUPLEX_HALF;
|
||||
|
@ -191,12 +194,12 @@ int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
|
|||
int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
||||
int lane, struct phylink_link_state *state)
|
||||
{
|
||||
u16 lpa, status, ctrl;
|
||||
u16 bmsr, lpa, status;
|
||||
int err;
|
||||
|
||||
err = mv88e6352_serdes_read(chip, MII_BMCR, &ctrl);
|
||||
err = mv88e6352_serdes_read(chip, MII_BMSR, &bmsr);
|
||||
if (err) {
|
||||
dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
|
||||
dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -212,7 +215,7 @@ int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
|
|||
return err;
|
||||
}
|
||||
|
||||
return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
|
||||
return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
|
||||
}
|
||||
|
||||
int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
|
||||
|
@ -918,13 +921,13 @@ int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
|
|||
static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
|
||||
int port, int lane, struct phylink_link_state *state)
|
||||
{
|
||||
u16 lpa, status, ctrl;
|
||||
u16 bmsr, lpa, status;
|
||||
int err;
|
||||
|
||||
err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
|
||||
MV88E6390_SGMII_BMCR, &ctrl);
|
||||
MV88E6390_SGMII_BMSR, &bmsr);
|
||||
if (err) {
|
||||
dev_err(chip->dev, "can't read Serdes PHY control: %d\n", err);
|
||||
dev_err(chip->dev, "can't read Serdes PHY BMSR: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -942,7 +945,7 @@ static int mv88e6390_serdes_pcs_get_state_sgmii(struct mv88e6xxx_chip *chip,
|
|||
return err;
|
||||
}
|
||||
|
||||
return mv88e6xxx_serdes_pcs_get_state(chip, ctrl, status, lpa, state);
|
||||
return mv88e6xxx_serdes_pcs_get_state(chip, bmsr, lpa, status, state);
|
||||
}
|
||||
|
||||
static int mv88e6390_serdes_pcs_get_state_10g(struct mv88e6xxx_chip *chip,
|
||||
|
|
|
@ -955,35 +955,21 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
int ext_int;
|
||||
|
||||
ext_int = rtl8365mb_extint_port_map[port];
|
||||
|
||||
if (ext_int < 0 &&
|
||||
(interface == PHY_INTERFACE_MODE_NA ||
|
||||
interface == PHY_INTERFACE_MODE_INTERNAL ||
|
||||
interface == PHY_INTERFACE_MODE_GMII))
|
||||
/* Internal PHY */
|
||||
return true;
|
||||
else if ((ext_int >= 1) &&
|
||||
phy_interface_mode_is_rgmii(interface))
|
||||
/* Extension MAC */
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
if (dsa_is_user_port(ds, port))
|
||||
if (dsa_is_user_port(ds, port)) {
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
else if (dsa_is_cpu_port(ds, port))
|
||||
|
||||
/* GMII is the default interface mode for phylib, so
|
||||
* we have to support it for ports with integrated PHY.
|
||||
*/
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
} else if (dsa_is_cpu_port(ds, port)) {
|
||||
phy_interface_set_rgmii(config->supported_interfaces);
|
||||
}
|
||||
|
||||
config->mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
|
||||
MAC_10 | MAC_100 | MAC_1000FD;
|
||||
|
@ -996,12 +982,6 @@ static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port,
|
|||
struct realtek_priv *priv = ds->priv;
|
||||
int ret;
|
||||
|
||||
if (!rtl8365mb_phy_mode_supported(ds, port, state->interface)) {
|
||||
dev_err(priv->dev, "phy mode %s is unsupported on port %d\n",
|
||||
phy_modes(state->interface), port);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode != MLO_AN_PHY && mode != MLO_AN_FIXED) {
|
||||
dev_err(priv->dev,
|
||||
"port %d supports only conventional PHY or fixed-link\n",
|
||||
|
|
|
@ -163,7 +163,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
mdio = mdiobus_alloc();
|
||||
if (mdio == NULL) {
|
||||
netdev_err(dev, "Error allocating MDIO bus\n");
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto put_node;
|
||||
}
|
||||
|
||||
mdio->name = ALTERA_TSE_RESOURCE_NAME;
|
||||
|
@ -180,6 +181,7 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
mdio->id);
|
||||
goto out_free_mdio;
|
||||
}
|
||||
of_node_put(mdio_node);
|
||||
|
||||
if (netif_msg_drv(priv))
|
||||
netdev_info(dev, "MDIO bus %s: created\n", mdio->id);
|
||||
|
@ -189,6 +191,8 @@ static int altera_tse_mdio_create(struct net_device *dev, unsigned int id)
|
|||
out_free_mdio:
|
||||
mdiobus_free(mdio);
|
||||
mdio = NULL;
|
||||
put_node:
|
||||
of_node_put(mdio_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -820,7 +820,7 @@ static int au1000_rx(struct net_device *dev)
|
|||
pr_cont("\n");
|
||||
}
|
||||
}
|
||||
prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
|
||||
prxd->buff_stat = lower_32_bits(pDB->dma_addr) | RX_DMA_ENABLE;
|
||||
aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
|
||||
wmb(); /* drain writebuffer */
|
||||
|
||||
|
@ -996,7 +996,7 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev)
|
|||
ps->tx_packets++;
|
||||
ps->tx_bytes += ptxd->len;
|
||||
|
||||
ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
|
||||
ptxd->buff_stat = lower_32_bits(pDB->dma_addr) | TX_DMA_ENABLE;
|
||||
wmb(); /* drain writebuffer */
|
||||
dev_kfree_skb(skb);
|
||||
aup->tx_head = (aup->tx_head + 1) & (NUM_TX_DMA - 1);
|
||||
|
@ -1131,9 +1131,9 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
/* Allocate the data buffers
|
||||
* Snooping works fine with eth on all au1xxx
|
||||
*/
|
||||
aup->vaddr = (u32)dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE *
|
||||
(NUM_TX_BUFFS + NUM_RX_BUFFS),
|
||||
&aup->dma_addr, 0);
|
||||
aup->vaddr = dma_alloc_coherent(&pdev->dev, MAX_BUF_SIZE *
|
||||
(NUM_TX_BUFFS + NUM_RX_BUFFS),
|
||||
&aup->dma_addr, 0);
|
||||
if (!aup->vaddr) {
|
||||
dev_err(&pdev->dev, "failed to allocate data buffers\n");
|
||||
err = -ENOMEM;
|
||||
|
@ -1234,8 +1234,8 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
|
||||
pDB->pnext = pDBfree;
|
||||
pDBfree = pDB;
|
||||
pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
|
||||
pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
|
||||
pDB->vaddr = aup->vaddr + MAX_BUF_SIZE * i;
|
||||
pDB->dma_addr = aup->dma_addr + MAX_BUF_SIZE * i;
|
||||
pDB++;
|
||||
}
|
||||
aup->pDBfree = pDBfree;
|
||||
|
@ -1246,7 +1246,7 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
if (!pDB)
|
||||
goto err_out;
|
||||
|
||||
aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
|
||||
aup->rx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr);
|
||||
aup->rx_db_inuse[i] = pDB;
|
||||
}
|
||||
|
||||
|
@ -1255,7 +1255,7 @@ static int au1000_probe(struct platform_device *pdev)
|
|||
if (!pDB)
|
||||
goto err_out;
|
||||
|
||||
aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
|
||||
aup->tx_dma_ring[i]->buff_stat = lower_32_bits(pDB->dma_addr);
|
||||
aup->tx_dma_ring[i]->len = 0;
|
||||
aup->tx_db_inuse[i] = pDB;
|
||||
}
|
||||
|
@ -1310,7 +1310,7 @@ err_remap2:
|
|||
iounmap(aup->mac);
|
||||
err_remap1:
|
||||
dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
|
||||
(void *)aup->vaddr, aup->dma_addr);
|
||||
aup->vaddr, aup->dma_addr);
|
||||
err_vaddr:
|
||||
free_netdev(dev);
|
||||
err_alloc:
|
||||
|
@ -1343,7 +1343,7 @@ static int au1000_remove(struct platform_device *pdev)
|
|||
au1000_ReleaseDB(aup, aup->tx_db_inuse[i]);
|
||||
|
||||
dma_free_coherent(&pdev->dev, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS),
|
||||
(void *)aup->vaddr, aup->dma_addr);
|
||||
aup->vaddr, aup->dma_addr);
|
||||
|
||||
iounmap(aup->macdma);
|
||||
iounmap(aup->mac);
|
||||
|
|
|
@ -106,8 +106,8 @@ struct au1000_private {
|
|||
struct mac_reg *mac; /* mac registers */
|
||||
u32 *enable; /* address of MAC Enable Register */
|
||||
void __iomem *macdma; /* base of MAC DMA port */
|
||||
u32 vaddr; /* virtual address of rx/tx buffers */
|
||||
dma_addr_t dma_addr; /* dma address of rx/tx buffers */
|
||||
void *vaddr; /* virtual address of rx/tx buffers */
|
||||
dma_addr_t dma_addr; /* dma address of rx/tx buffers */
|
||||
|
||||
spinlock_t lock; /* Serialise access to device */
|
||||
|
||||
|
|
|
@ -2784,7 +2784,7 @@ void xgbe_print_pkt(struct net_device *netdev, struct sk_buff *skb, bool tx_rx)
|
|||
|
||||
netdev_dbg(netdev, "Dst MAC addr: %pM\n", eth->h_dest);
|
||||
netdev_dbg(netdev, "Src MAC addr: %pM\n", eth->h_source);
|
||||
netdev_dbg(netdev, "Protocol: %#06hx\n", ntohs(eth->h_proto));
|
||||
netdev_dbg(netdev, "Protocol: %#06x\n", ntohs(eth->h_proto));
|
||||
|
||||
for (i = 0; i < skb->len; i += 32) {
|
||||
unsigned int len = min(skb->len - i, 32U);
|
||||
|
|
|
@ -234,6 +234,7 @@ struct mii_bus *bcma_mdio_mii_register(struct bgmac *bgmac)
|
|||
np = of_get_child_by_name(core->dev.of_node, "mdio");
|
||||
|
||||
err = of_mdiobus_register(mii_bus, np);
|
||||
of_node_put(np);
|
||||
if (err) {
|
||||
dev_err(&core->dev, "Registration of mii bus failed\n");
|
||||
goto err_free_bus;
|
||||
|
|
|
@ -1184,9 +1184,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
|
|||
|
||||
switch (xcast_mode) {
|
||||
case IXGBEVF_XCAST_MODE_NONE:
|
||||
disable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
|
||||
disable = IXGBE_VMOLR_ROMPE |
|
||||
IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
|
||||
enable = 0;
|
||||
enable = IXGBE_VMOLR_BAM;
|
||||
break;
|
||||
case IXGBEVF_XCAST_MODE_MULTI:
|
||||
disable = IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
|
||||
|
@ -1208,9 +1208,9 @@ static int ixgbe_update_vf_xcast_mode(struct ixgbe_adapter *adapter,
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
disable = 0;
|
||||
disable = IXGBE_VMOLR_VPE;
|
||||
enable = IXGBE_VMOLR_BAM | IXGBE_VMOLR_ROMPE |
|
||||
IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE | IXGBE_VMOLR_VPE;
|
||||
IXGBE_VMOLR_MPE | IXGBE_VMOLR_UPE;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
@ -899,6 +899,17 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void *mtk_max_lro_buf_alloc(gfp_t gfp_mask)
|
||||
{
|
||||
unsigned int size = mtk_max_frag_size(MTK_MAX_LRO_RX_LENGTH);
|
||||
unsigned long data;
|
||||
|
||||
data = __get_free_pages(gfp_mask | __GFP_COMP | __GFP_NOWARN,
|
||||
get_order(size));
|
||||
|
||||
return (void *)data;
|
||||
}
|
||||
|
||||
/* the qdma core needs scratch memory to be setup */
|
||||
static int mtk_init_fq_dma(struct mtk_eth *eth)
|
||||
{
|
||||
|
@ -1467,7 +1478,10 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
|
|||
goto release_desc;
|
||||
|
||||
/* alloc new buffer */
|
||||
new_data = napi_alloc_frag(ring->frag_size);
|
||||
if (ring->frag_size <= PAGE_SIZE)
|
||||
new_data = napi_alloc_frag(ring->frag_size);
|
||||
else
|
||||
new_data = mtk_max_lro_buf_alloc(GFP_ATOMIC);
|
||||
if (unlikely(!new_data)) {
|
||||
netdev->stats.rx_dropped++;
|
||||
goto release_desc;
|
||||
|
@ -1914,7 +1928,10 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
|
|||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < rx_dma_size; i++) {
|
||||
ring->data[i] = netdev_alloc_frag(ring->frag_size);
|
||||
if (ring->frag_size <= PAGE_SIZE)
|
||||
ring->data[i] = netdev_alloc_frag(ring->frag_size);
|
||||
else
|
||||
ring->data[i] = mtk_max_lro_buf_alloc(GFP_KERNEL);
|
||||
if (!ring->data[i])
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
|
@ -2110,7 +2110,7 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
|
|||
en_err(priv,
|
||||
"mlx4_get_module_info i(%d) offset(%d) bytes_to_read(%d) - FAILED (0x%x)\n",
|
||||
i, offset, ee->len - i, ret);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
i += ret;
|
||||
|
|
|
@ -1072,13 +1072,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
|
|||
|
||||
ret = stmmac_dvr_probe(&pdev->dev, plat, &res);
|
||||
if (ret) {
|
||||
goto err_dvr_probe;
|
||||
goto err_alloc_irq;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_dvr_probe:
|
||||
pci_free_irq_vectors(pdev);
|
||||
err_alloc_irq:
|
||||
clk_disable_unprepare(plat->stmmac_clk);
|
||||
clk_unregister_fixed_rate(plat->stmmac_clk);
|
||||
|
|
|
@ -137,6 +137,7 @@
|
|||
#define DP83867_DOWNSHIFT_2_COUNT 2
|
||||
#define DP83867_DOWNSHIFT_4_COUNT 4
|
||||
#define DP83867_DOWNSHIFT_8_COUNT 8
|
||||
#define DP83867_SGMII_AUTONEG_EN BIT(7)
|
||||
|
||||
/* CFG3 bits */
|
||||
#define DP83867_CFG3_INT_OE BIT(7)
|
||||
|
@ -855,6 +856,32 @@ static int dp83867_phy_reset(struct phy_device *phydev)
|
|||
DP83867_PHYCR_FORCE_LINK_GOOD, 0);
|
||||
}
|
||||
|
||||
static void dp83867_link_change_notify(struct phy_device *phydev)
|
||||
{
|
||||
/* There is a limitation in DP83867 PHY device where SGMII AN is
|
||||
* only triggered once after the device is booted up. Even after the
|
||||
* PHY TPI is down and up again, SGMII AN is not triggered and
|
||||
* hence no new in-band message from PHY to MAC side SGMII.
|
||||
* This could cause an issue during power up, when PHY is up prior
|
||||
* to MAC. At this condition, once MAC side SGMII is up, MAC side
|
||||
* SGMII wouldn`t receive new in-band message from TI PHY with
|
||||
* correct link status, speed and duplex info.
|
||||
* Thus, implemented a SW solution here to retrigger SGMII Auto-Neg
|
||||
* whenever there is a link change.
|
||||
*/
|
||||
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
|
||||
int val = 0;
|
||||
|
||||
val = phy_clear_bits(phydev, DP83867_CFG2,
|
||||
DP83867_SGMII_AUTONEG_EN);
|
||||
if (val < 0)
|
||||
return;
|
||||
|
||||
phy_set_bits(phydev, DP83867_CFG2,
|
||||
DP83867_SGMII_AUTONEG_EN);
|
||||
}
|
||||
}
|
||||
|
||||
static struct phy_driver dp83867_driver[] = {
|
||||
{
|
||||
.phy_id = DP83867_PHY_ID,
|
||||
|
@ -879,6 +906,8 @@ static struct phy_driver dp83867_driver[] = {
|
|||
|
||||
.suspend = genphy_suspend,
|
||||
.resume = genphy_resume,
|
||||
|
||||
.link_change_notify = dp83867_link_change_notify,
|
||||
},
|
||||
};
|
||||
module_phy_driver(dp83867_driver);
|
||||
|
|
|
@ -1046,7 +1046,6 @@ int __init mdio_bus_init(void)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mdio_bus_init);
|
||||
|
||||
#if IS_ENABLED(CONFIG_PHYLIB)
|
||||
void mdio_bus_exit(void)
|
||||
|
|
|
@ -388,13 +388,25 @@ static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
|
|||
int err;
|
||||
|
||||
while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
|
||||
usb_anchor_urb(urb, &drv_data->tx_anchor);
|
||||
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err)
|
||||
if (err) {
|
||||
kfree(urb->setup_packet);
|
||||
usb_unanchor_urb(urb);
|
||||
usb_free_urb(urb);
|
||||
break;
|
||||
}
|
||||
|
||||
drv_data->tx_in_flight++;
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
/* Cleanup the rest deferred urbs. */
|
||||
while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
|
||||
kfree(urb->setup_packet);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
usb_scuttle_anchored_urbs(&drv_data->deferred);
|
||||
}
|
||||
|
||||
static int nfcmrvl_resume(struct usb_interface *intf)
|
||||
|
|
|
@ -300,6 +300,8 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
|
|||
int r = 0;
|
||||
struct device *dev = &hdev->ndev->dev;
|
||||
struct nfc_evt_transaction *transaction;
|
||||
u32 aid_len;
|
||||
u8 params_len;
|
||||
|
||||
pr_debug("connectivity gate event: %x\n", event);
|
||||
|
||||
|
@ -308,43 +310,48 @@ int st21nfca_connectivity_event_received(struct nfc_hci_dev *hdev, u8 host,
|
|||
r = nfc_se_connectivity(hdev->ndev, host);
|
||||
break;
|
||||
case ST21NFCA_EVT_TRANSACTION:
|
||||
/*
|
||||
* According to specification etsi 102 622
|
||||
/* According to specification etsi 102 622
|
||||
* 11.2.2.4 EVT_TRANSACTION Table 52
|
||||
* Description Tag Length
|
||||
* AID 81 5 to 16
|
||||
* PARAMETERS 82 0 to 255
|
||||
*
|
||||
* The key differences are aid storage length is variably sized
|
||||
* in the packet, but fixed in nfc_evt_transaction, and that the aid_len
|
||||
* is u8 in the packet, but u32 in the structure, and the tags in
|
||||
* the packet are not included in nfc_evt_transaction.
|
||||
*
|
||||
* size in bytes: 1 1 5-16 1 1 0-255
|
||||
* offset: 0 1 2 aid_len + 2 aid_len + 3 aid_len + 4
|
||||
* member name: aid_tag(M) aid_len aid params_tag(M) params_len params
|
||||
* example: 0x81 5-16 X 0x82 0-255 X
|
||||
*/
|
||||
if (skb->len < NFC_MIN_AID_LENGTH + 2 &&
|
||||
skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
|
||||
if (skb->len < 2 || skb->data[0] != NFC_EVT_TRANSACTION_AID_TAG)
|
||||
return -EPROTO;
|
||||
|
||||
transaction = devm_kzalloc(dev, skb->len - 2, GFP_KERNEL);
|
||||
aid_len = skb->data[1];
|
||||
|
||||
if (skb->len < aid_len + 4 || aid_len > sizeof(transaction->aid))
|
||||
return -EPROTO;
|
||||
|
||||
params_len = skb->data[aid_len + 3];
|
||||
|
||||
/* Verify PARAMETERS tag is (82), and final check that there is enough
|
||||
* space in the packet to read everything.
|
||||
*/
|
||||
if ((skb->data[aid_len + 2] != NFC_EVT_TRANSACTION_PARAMS_TAG) ||
|
||||
(skb->len < aid_len + 4 + params_len))
|
||||
return -EPROTO;
|
||||
|
||||
transaction = devm_kzalloc(dev, sizeof(*transaction) + params_len, GFP_KERNEL);
|
||||
if (!transaction)
|
||||
return -ENOMEM;
|
||||
|
||||
transaction->aid_len = skb->data[1];
|
||||
transaction->aid_len = aid_len;
|
||||
transaction->params_len = params_len;
|
||||
|
||||
/* Checking if the length of the AID is valid */
|
||||
if (transaction->aid_len > sizeof(transaction->aid))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(transaction->aid, &skb->data[2],
|
||||
transaction->aid_len);
|
||||
|
||||
/* Check next byte is PARAMETERS tag (82) */
|
||||
if (skb->data[transaction->aid_len + 2] !=
|
||||
NFC_EVT_TRANSACTION_PARAMS_TAG)
|
||||
return -EPROTO;
|
||||
|
||||
transaction->params_len = skb->data[transaction->aid_len + 3];
|
||||
|
||||
/* Total size is allocated (skb->len - 2) minus fixed array members */
|
||||
if (transaction->params_len > ((skb->len - 2) - sizeof(struct nfc_evt_transaction)))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(transaction->params, skb->data +
|
||||
transaction->aid_len + 4, transaction->params_len);
|
||||
memcpy(transaction->aid, &skb->data[2], aid_len);
|
||||
memcpy(transaction->params, &skb->data[aid_len + 4], params_len);
|
||||
|
||||
r = nfc_se_transaction(hdev->ndev, host, transaction);
|
||||
break;
|
||||
|
|
|
@ -612,5 +612,6 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch,
|
|||
enum tc_setup_type type, void *data,
|
||||
struct flow_block_offload *bo,
|
||||
void (*cleanup)(struct flow_block_cb *block_cb));
|
||||
bool flow_indr_dev_exists(void);
|
||||
|
||||
#endif /* _NET_FLOW_OFFLOAD_H */
|
||||
|
|
|
@ -1063,7 +1063,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
|
|||
int ip6_append_data(struct sock *sk,
|
||||
int getfrag(void *from, char *to, int offset, int len,
|
||||
int odd, struct sk_buff *skb),
|
||||
void *from, int length, int transhdrlen,
|
||||
void *from, size_t length, int transhdrlen,
|
||||
struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
|
||||
struct rt6_info *rt, unsigned int flags);
|
||||
|
||||
|
@ -1079,7 +1079,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, struct sk_buff_head *queue,
|
|||
struct sk_buff *ip6_make_skb(struct sock *sk,
|
||||
int getfrag(void *from, char *to, int offset,
|
||||
int len, int odd, struct sk_buff *skb),
|
||||
void *from, int length, int transhdrlen,
|
||||
void *from, size_t length, int transhdrlen,
|
||||
struct ipcm6_cookie *ipc6,
|
||||
struct rt6_info *rt, unsigned int flags,
|
||||
struct inet_cork_full *cork);
|
||||
|
|
|
@ -1090,7 +1090,6 @@ struct nft_stats {
|
|||
|
||||
struct nft_hook {
|
||||
struct list_head list;
|
||||
bool inactive;
|
||||
struct nf_hook_ops ops;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
|
|
@ -92,7 +92,7 @@ int nft_flow_rule_offload_commit(struct net *net);
|
|||
NFT_OFFLOAD_MATCH(__key, __base, __field, __len, __reg) \
|
||||
memset(&(__reg)->mask, 0xff, (__reg)->len);
|
||||
|
||||
int nft_chain_offload_priority(struct nft_base_chain *basechain);
|
||||
bool nft_chain_offload_support(const struct nft_base_chain *basechain);
|
||||
|
||||
int nft_offload_init(void);
|
||||
void nft_offload_exit(void);
|
||||
|
|
|
@ -6054,6 +6054,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
|
|||
struct bpf_reg_state *regs,
|
||||
bool ptr_to_mem_ok)
|
||||
{
|
||||
enum bpf_prog_type prog_type = resolve_prog_type(env->prog);
|
||||
struct bpf_verifier_log *log = &env->log;
|
||||
u32 i, nargs, ref_id, ref_obj_id = 0;
|
||||
bool is_kfunc = btf_is_kernel(btf);
|
||||
|
@ -6171,7 +6172,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env,
|
|||
return -EINVAL;
|
||||
}
|
||||
/* rest of the arguments can be anything, like normal kfunc */
|
||||
} else if (btf_get_prog_ctx_type(log, btf, t, env->prog->type, i)) {
|
||||
} else if (btf_get_prog_ctx_type(log, btf, t, prog_type, i)) {
|
||||
/* If function expects ctx type in BTF check that caller
|
||||
* is passing PTR_TO_CTX.
|
||||
*/
|
||||
|
|
|
@ -2263,11 +2263,11 @@ static int copy_user_syms(struct user_syms *us, unsigned long __user *usyms, u32
|
|||
int err = -ENOMEM;
|
||||
unsigned int i;
|
||||
|
||||
syms = kvmalloc(cnt * sizeof(*syms), GFP_KERNEL);
|
||||
syms = kvmalloc_array(cnt, sizeof(*syms), GFP_KERNEL);
|
||||
if (!syms)
|
||||
goto error;
|
||||
|
||||
buf = kvmalloc(cnt * KSYM_NAME_LEN, GFP_KERNEL);
|
||||
buf = kvmalloc_array(cnt, KSYM_NAME_LEN, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto error;
|
||||
|
||||
|
@ -2464,7 +2464,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
|
|||
return -EINVAL;
|
||||
|
||||
size = cnt * sizeof(*addrs);
|
||||
addrs = kvmalloc(size, GFP_KERNEL);
|
||||
addrs = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL);
|
||||
if (!addrs)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -2489,7 +2489,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
|
|||
|
||||
ucookies = u64_to_user_ptr(attr->link_create.kprobe_multi.cookies);
|
||||
if (ucookies) {
|
||||
cookies = kvmalloc(size, GFP_KERNEL);
|
||||
cookies = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL);
|
||||
if (!cookies) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
|
|
|
@ -595,3 +595,9 @@ int flow_indr_dev_setup_offload(struct net_device *dev, struct Qdisc *sch,
|
|||
return (bo && list_empty(&bo->cb_list)) ? -EOPNOTSUPP : count;
|
||||
}
|
||||
EXPORT_SYMBOL(flow_indr_dev_setup_offload);
|
||||
|
||||
bool flow_indr_dev_exists(void)
|
||||
{
|
||||
return !list_empty(&flow_block_indr_dev_list);
|
||||
}
|
||||
EXPORT_SYMBOL(flow_indr_dev_exists);
|
||||
|
|
|
@ -1026,10 +1026,12 @@ void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name,
|
|||
init_hashinfo_lhash2(h);
|
||||
|
||||
/* this one is used for source ports of outgoing connections */
|
||||
table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE,
|
||||
sizeof(*table_perturb), GFP_KERNEL);
|
||||
if (!table_perturb)
|
||||
panic("TCP: failed to alloc table_perturb");
|
||||
table_perturb = alloc_large_system_hash("Table-perturb",
|
||||
sizeof(*table_perturb),
|
||||
INET_TABLE_PERTURB_SIZE,
|
||||
0, 0, NULL, NULL,
|
||||
INET_TABLE_PERTURB_SIZE,
|
||||
INET_TABLE_PERTURB_SIZE);
|
||||
}
|
||||
|
||||
int inet_hashinfo2_init_mod(struct inet_hashinfo *h)
|
||||
|
|
|
@ -629,21 +629,20 @@ static netdev_tx_t ipgre_xmit(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
if (dev->header_ops) {
|
||||
const int pull_len = tunnel->hlen + sizeof(struct iphdr);
|
||||
|
||||
if (skb_cow_head(skb, 0))
|
||||
goto free_skb;
|
||||
|
||||
tnl_params = (const struct iphdr *)skb->data;
|
||||
|
||||
if (pull_len > skb_transport_offset(skb))
|
||||
goto free_skb;
|
||||
|
||||
/* Pull skb since ip_tunnel_xmit() needs skb->data pointing
|
||||
* to gre header.
|
||||
*/
|
||||
skb_pull(skb, pull_len);
|
||||
skb_pull(skb, tunnel->hlen + sizeof(struct iphdr));
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
if (skb->ip_summed == CHECKSUM_PARTIAL &&
|
||||
skb_checksum_start(skb) < skb->data)
|
||||
goto free_skb;
|
||||
} else {
|
||||
if (skb_cow_head(skb, dev->needed_headroom))
|
||||
goto free_skb;
|
||||
|
|
|
@ -304,4 +304,3 @@ void __init xfrm4_protocol_init(void)
|
|||
{
|
||||
xfrm_input_register_afinfo(&xfrm4_input_afinfo);
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm4_protocol_init);
|
||||
|
|
|
@ -1450,7 +1450,7 @@ static int __ip6_append_data(struct sock *sk,
|
|||
struct page_frag *pfrag,
|
||||
int getfrag(void *from, char *to, int offset,
|
||||
int len, int odd, struct sk_buff *skb),
|
||||
void *from, int length, int transhdrlen,
|
||||
void *from, size_t length, int transhdrlen,
|
||||
unsigned int flags, struct ipcm6_cookie *ipc6)
|
||||
{
|
||||
struct sk_buff *skb, *skb_prev = NULL;
|
||||
|
@ -1798,7 +1798,7 @@ error:
|
|||
int ip6_append_data(struct sock *sk,
|
||||
int getfrag(void *from, char *to, int offset, int len,
|
||||
int odd, struct sk_buff *skb),
|
||||
void *from, int length, int transhdrlen,
|
||||
void *from, size_t length, int transhdrlen,
|
||||
struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
|
||||
struct rt6_info *rt, unsigned int flags)
|
||||
{
|
||||
|
@ -1995,7 +1995,7 @@ EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
|
|||
struct sk_buff *ip6_make_skb(struct sock *sk,
|
||||
int getfrag(void *from, char *to, int offset,
|
||||
int len, int odd, struct sk_buff *skb),
|
||||
void *from, int length, int transhdrlen,
|
||||
void *from, size_t length, int transhdrlen,
|
||||
struct ipcm6_cookie *ipc6, struct rt6_info *rt,
|
||||
unsigned int flags, struct inet_cork_full *cork)
|
||||
{
|
||||
|
|
|
@ -399,7 +399,6 @@ int __init seg6_hmac_init(void)
|
|||
{
|
||||
return seg6_hmac_init_algo();
|
||||
}
|
||||
EXPORT_SYMBOL(seg6_hmac_init);
|
||||
|
||||
int __net_init seg6_hmac_net_init(struct net *net)
|
||||
{
|
||||
|
|
|
@ -504,14 +504,15 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
|||
struct ipcm6_cookie ipc6;
|
||||
int addr_len = msg->msg_namelen;
|
||||
int transhdrlen = 4; /* zero session-id */
|
||||
int ulen = len + transhdrlen;
|
||||
int ulen;
|
||||
int err;
|
||||
|
||||
/* Rough check on arithmetic overflow,
|
||||
* better check is made in ip6_append_data().
|
||||
*/
|
||||
if (len > INT_MAX)
|
||||
if (len > INT_MAX - transhdrlen)
|
||||
return -EMSGSIZE;
|
||||
ulen = len + transhdrlen;
|
||||
|
||||
/* Mirror BSD error message compatibility */
|
||||
if (msg->msg_flags & MSG_OOB)
|
||||
|
|
|
@ -544,6 +544,7 @@ static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type,
|
|||
if (msg_type == NFT_MSG_NEWFLOWTABLE)
|
||||
nft_activate_next(ctx->net, flowtable);
|
||||
|
||||
INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
|
||||
nft_trans_flowtable(trans) = flowtable;
|
||||
nft_trans_commit_list_add_tail(ctx->net, trans);
|
||||
|
||||
|
@ -1914,7 +1915,6 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net,
|
|||
goto err_hook_dev;
|
||||
}
|
||||
hook->ops.dev = dev;
|
||||
hook->inactive = false;
|
||||
|
||||
return hook;
|
||||
|
||||
|
@ -2166,7 +2166,7 @@ static int nft_basechain_init(struct nft_base_chain *basechain, u8 family,
|
|||
chain->flags |= NFT_CHAIN_BASE | flags;
|
||||
basechain->policy = NF_ACCEPT;
|
||||
if (chain->flags & NFT_CHAIN_HW_OFFLOAD &&
|
||||
nft_chain_offload_priority(basechain) < 0)
|
||||
!nft_chain_offload_support(basechain))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
flow_block_init(&basechain->flow_block);
|
||||
|
@ -7332,7 +7332,7 @@ static void __nft_unregister_flowtable_net_hooks(struct net *net,
|
|||
nf_unregister_net_hook(net, &hook->ops);
|
||||
if (release_netdev) {
|
||||
list_del(&hook->list);
|
||||
kfree_rcu(hook);
|
||||
kfree_rcu(hook, rcu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7433,11 +7433,15 @@ static int nft_flowtable_update(struct nft_ctx *ctx, const struct nlmsghdr *nlh,
|
|||
|
||||
if (nla[NFTA_FLOWTABLE_FLAGS]) {
|
||||
flags = ntohl(nla_get_be32(nla[NFTA_FLOWTABLE_FLAGS]));
|
||||
if (flags & ~NFT_FLOWTABLE_MASK)
|
||||
return -EOPNOTSUPP;
|
||||
if (flags & ~NFT_FLOWTABLE_MASK) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto err_flowtable_update_hook;
|
||||
}
|
||||
if ((flowtable->data.flags & NFT_FLOWTABLE_HW_OFFLOAD) ^
|
||||
(flags & NFT_FLOWTABLE_HW_OFFLOAD))
|
||||
return -EOPNOTSUPP;
|
||||
(flags & NFT_FLOWTABLE_HW_OFFLOAD)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto err_flowtable_update_hook;
|
||||
}
|
||||
} else {
|
||||
flags = flowtable->data.flags;
|
||||
}
|
||||
|
@ -7618,6 +7622,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
|
|||
{
|
||||
const struct nlattr * const *nla = ctx->nla;
|
||||
struct nft_flowtable_hook flowtable_hook;
|
||||
LIST_HEAD(flowtable_del_list);
|
||||
struct nft_hook *this, *hook;
|
||||
struct nft_trans *trans;
|
||||
int err;
|
||||
|
@ -7633,7 +7638,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
|
|||
err = -ENOENT;
|
||||
goto err_flowtable_del_hook;
|
||||
}
|
||||
hook->inactive = true;
|
||||
list_move(&hook->list, &flowtable_del_list);
|
||||
}
|
||||
|
||||
trans = nft_trans_alloc(ctx, NFT_MSG_DELFLOWTABLE,
|
||||
|
@ -7646,6 +7651,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
|
|||
nft_trans_flowtable(trans) = flowtable;
|
||||
nft_trans_flowtable_update(trans) = true;
|
||||
INIT_LIST_HEAD(&nft_trans_flowtable_hooks(trans));
|
||||
list_splice(&flowtable_del_list, &nft_trans_flowtable_hooks(trans));
|
||||
nft_flowtable_hook_release(&flowtable_hook);
|
||||
|
||||
nft_trans_commit_list_add_tail(ctx->net, trans);
|
||||
|
@ -7653,13 +7659,7 @@ static int nft_delflowtable_hook(struct nft_ctx *ctx,
|
|||
return 0;
|
||||
|
||||
err_flowtable_del_hook:
|
||||
list_for_each_entry(this, &flowtable_hook.list, list) {
|
||||
hook = nft_hook_list_find(&flowtable->hook_list, this);
|
||||
if (!hook)
|
||||
break;
|
||||
|
||||
hook->inactive = false;
|
||||
}
|
||||
list_splice(&flowtable_del_list, &flowtable->hook_list);
|
||||
nft_flowtable_hook_release(&flowtable_hook);
|
||||
|
||||
return err;
|
||||
|
@ -8329,6 +8329,9 @@ static void nft_commit_release(struct nft_trans *trans)
|
|||
nf_tables_chain_destroy(&trans->ctx);
|
||||
break;
|
||||
case NFT_MSG_DELRULE:
|
||||
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
|
||||
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
|
||||
|
||||
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
|
||||
break;
|
||||
case NFT_MSG_DELSET:
|
||||
|
@ -8563,17 +8566,6 @@ void nft_chain_del(struct nft_chain *chain)
|
|||
list_del_rcu(&chain->list);
|
||||
}
|
||||
|
||||
static void nft_flowtable_hooks_del(struct nft_flowtable *flowtable,
|
||||
struct list_head *hook_list)
|
||||
{
|
||||
struct nft_hook *hook, *next;
|
||||
|
||||
list_for_each_entry_safe(hook, next, &flowtable->hook_list, list) {
|
||||
if (hook->inactive)
|
||||
list_move(&hook->list, hook_list);
|
||||
}
|
||||
}
|
||||
|
||||
static void nf_tables_module_autoload_cleanup(struct net *net)
|
||||
{
|
||||
struct nftables_pernet *nft_net = nft_pernet(net);
|
||||
|
@ -8828,6 +8820,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
nf_tables_rule_notify(&trans->ctx,
|
||||
nft_trans_rule(trans),
|
||||
NFT_MSG_NEWRULE);
|
||||
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
|
||||
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
|
||||
|
||||
nft_trans_destroy(trans);
|
||||
break;
|
||||
case NFT_MSG_DELRULE:
|
||||
|
@ -8918,8 +8913,6 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
|
|||
break;
|
||||
case NFT_MSG_DELFLOWTABLE:
|
||||
if (nft_trans_flowtable_update(trans)) {
|
||||
nft_flowtable_hooks_del(nft_trans_flowtable(trans),
|
||||
&nft_trans_flowtable_hooks(trans));
|
||||
nf_tables_flowtable_notify(&trans->ctx,
|
||||
nft_trans_flowtable(trans),
|
||||
&nft_trans_flowtable_hooks(trans),
|
||||
|
@ -9000,7 +8993,6 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
|||
struct nftables_pernet *nft_net = nft_pernet(net);
|
||||
struct nft_trans *trans, *next;
|
||||
struct nft_trans_elem *te;
|
||||
struct nft_hook *hook;
|
||||
|
||||
if (action == NFNL_ABORT_VALIDATE &&
|
||||
nf_tables_validate(net) < 0)
|
||||
|
@ -9131,8 +9123,8 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action)
|
|||
break;
|
||||
case NFT_MSG_DELFLOWTABLE:
|
||||
if (nft_trans_flowtable_update(trans)) {
|
||||
list_for_each_entry(hook, &nft_trans_flowtable(trans)->hook_list, list)
|
||||
hook->inactive = false;
|
||||
list_splice(&nft_trans_flowtable_hooks(trans),
|
||||
&nft_trans_flowtable(trans)->hook_list);
|
||||
} else {
|
||||
trans->ctx.table->use++;
|
||||
nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
|
||||
|
|
|
@ -208,7 +208,7 @@ static int nft_setup_cb_call(enum tc_setup_type type, void *type_data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int nft_chain_offload_priority(struct nft_base_chain *basechain)
|
||||
static int nft_chain_offload_priority(const struct nft_base_chain *basechain)
|
||||
{
|
||||
if (basechain->ops.priority <= 0 ||
|
||||
basechain->ops.priority > USHRT_MAX)
|
||||
|
@ -217,6 +217,27 @@ int nft_chain_offload_priority(struct nft_base_chain *basechain)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool nft_chain_offload_support(const struct nft_base_chain *basechain)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct nft_hook *hook;
|
||||
|
||||
if (nft_chain_offload_priority(basechain) < 0)
|
||||
return false;
|
||||
|
||||
list_for_each_entry(hook, &basechain->hook_list, list) {
|
||||
if (hook->ops.pf != NFPROTO_NETDEV ||
|
||||
hook->ops.hooknum != NF_NETDEV_INGRESS)
|
||||
return false;
|
||||
|
||||
dev = hook->ops.dev;
|
||||
if (!dev->netdev_ops->ndo_setup_tc && !flow_indr_dev_exists())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nft_flow_cls_offload_setup(struct flow_cls_offload *cls_flow,
|
||||
const struct nft_base_chain *basechain,
|
||||
const struct nft_rule *rule,
|
||||
|
|
|
@ -335,7 +335,8 @@ static void nft_nat_inet_eval(const struct nft_expr *expr,
|
|||
{
|
||||
const struct nft_nat *priv = nft_expr_priv(expr);
|
||||
|
||||
if (priv->family == nft_pf(pkt))
|
||||
if (priv->family == nft_pf(pkt) ||
|
||||
priv->family == NFPROTO_INET)
|
||||
nft_nat_eval(expr, regs, pkt);
|
||||
}
|
||||
|
||||
|
|
|
@ -373,6 +373,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
|
|||
update_ip_l4_checksum(skb, nh, *addr, new_addr);
|
||||
csum_replace4(&nh->check, *addr, new_addr);
|
||||
skb_clear_hash(skb);
|
||||
ovs_ct_clear(skb, NULL);
|
||||
*addr = new_addr;
|
||||
}
|
||||
|
||||
|
@ -420,6 +421,7 @@ static void set_ipv6_addr(struct sk_buff *skb, u8 l4_proto,
|
|||
update_ipv6_checksum(skb, l4_proto, addr, new_addr);
|
||||
|
||||
skb_clear_hash(skb);
|
||||
ovs_ct_clear(skb, NULL);
|
||||
memcpy(addr, new_addr, sizeof(__be32[4]));
|
||||
}
|
||||
|
||||
|
@ -660,6 +662,7 @@ static int set_nsh(struct sk_buff *skb, struct sw_flow_key *flow_key,
|
|||
static void set_tp_port(struct sk_buff *skb, __be16 *port,
|
||||
__be16 new_port, __sum16 *check)
|
||||
{
|
||||
ovs_ct_clear(skb, NULL);
|
||||
inet_proto_csum_replace2(check, skb, *port, new_port, false);
|
||||
*port = new_port;
|
||||
}
|
||||
|
@ -699,6 +702,7 @@ static int set_udp(struct sk_buff *skb, struct sw_flow_key *flow_key,
|
|||
uh->dest = dst;
|
||||
flow_key->tp.src = src;
|
||||
flow_key->tp.dst = dst;
|
||||
ovs_ct_clear(skb, NULL);
|
||||
}
|
||||
|
||||
skb_clear_hash(skb);
|
||||
|
@ -761,6 +765,8 @@ static int set_sctp(struct sk_buff *skb, struct sw_flow_key *flow_key,
|
|||
sh->checksum = old_csum ^ old_correct_csum ^ new_csum;
|
||||
|
||||
skb_clear_hash(skb);
|
||||
ovs_ct_clear(skb, NULL);
|
||||
|
||||
flow_key->tp.src = sh->source;
|
||||
flow_key->tp.dst = sh->dest;
|
||||
|
||||
|
|
|
@ -1342,7 +1342,9 @@ int ovs_ct_clear(struct sk_buff *skb, struct sw_flow_key *key)
|
|||
|
||||
nf_ct_put(ct);
|
||||
nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
|
||||
ovs_ct_fill_key(skb, key, false);
|
||||
|
||||
if (key)
|
||||
ovs_ct_fill_key(skb, key, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
|
|||
* -ECONNREFUSED. Otherwise, if we haven't queued any skbs
|
||||
* to other and its full, we will hang waiting for POLLOUT.
|
||||
*/
|
||||
if (unix_recvq_full(other) && !sock_flag(other, SOCK_DEAD))
|
||||
if (unix_recvq_full_lockless(other) && !sock_flag(other, SOCK_DEAD))
|
||||
return 1;
|
||||
|
||||
if (connected)
|
||||
|
|
|
@ -373,7 +373,8 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
|
|||
goto out;
|
||||
}
|
||||
|
||||
nb_pkts = xskq_cons_peek_desc_batch(xs->tx, pool, max_entries);
|
||||
max_entries = xskq_cons_nb_entries(xs->tx, max_entries);
|
||||
nb_pkts = xskq_cons_read_desc_batch(xs->tx, pool, max_entries);
|
||||
if (!nb_pkts) {
|
||||
xs->tx->queue_empty_descs++;
|
||||
goto out;
|
||||
|
@ -389,7 +390,7 @@ u32 xsk_tx_peek_release_desc_batch(struct xsk_buff_pool *pool, u32 max_entries)
|
|||
if (!nb_pkts)
|
||||
goto out;
|
||||
|
||||
xskq_cons_release_n(xs->tx, nb_pkts);
|
||||
xskq_cons_release_n(xs->tx, max_entries);
|
||||
__xskq_cons_release(xs->tx);
|
||||
xs->sk.sk_write_space(&xs->sk);
|
||||
|
||||
|
|
|
@ -282,14 +282,6 @@ static inline bool xskq_cons_peek_desc(struct xsk_queue *q,
|
|||
return xskq_cons_read_desc(q, desc, pool);
|
||||
}
|
||||
|
||||
static inline u32 xskq_cons_peek_desc_batch(struct xsk_queue *q, struct xsk_buff_pool *pool,
|
||||
u32 max)
|
||||
{
|
||||
u32 entries = xskq_cons_nb_entries(q, max);
|
||||
|
||||
return xskq_cons_read_desc_batch(q, pool, entries);
|
||||
}
|
||||
|
||||
/* To improve performance in the xskq_cons_release functions, only update local state here.
|
||||
* Reflect this to global state when we get new entries from the ring in
|
||||
* xskq_cons_get_entries() and whenever Rx or Tx processing are completed in the NAPI loop.
|
||||
|
|
|
@ -395,6 +395,18 @@ static void test_func_map_prog_compatibility(void)
|
|||
"./test_attach_probe.o");
|
||||
}
|
||||
|
||||
static void test_func_replace_global_func(void)
|
||||
{
|
||||
const char *prog_name[] = {
|
||||
"freplace/test_pkt_access",
|
||||
};
|
||||
|
||||
test_fexit_bpf2bpf_common("./freplace_global_func.o",
|
||||
"./test_pkt_access.o",
|
||||
ARRAY_SIZE(prog_name),
|
||||
prog_name, false, NULL);
|
||||
}
|
||||
|
||||
/* NOTE: affect other tests, must run in serial mode */
|
||||
void serial_test_fexit_bpf2bpf(void)
|
||||
{
|
||||
|
@ -416,4 +428,6 @@ void serial_test_fexit_bpf2bpf(void)
|
|||
test_func_replace_multi();
|
||||
if (test__start_subtest("fmod_ret_freplace"))
|
||||
test_fmod_ret_freplace();
|
||||
if (test__start_subtest("func_replace_global_func"))
|
||||
test_func_replace_global_func();
|
||||
}
|
||||
|
|
18
tools/testing/selftests/bpf/progs/freplace_global_func.c
Normal file
18
tools/testing/selftests/bpf/progs/freplace_global_func.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/bpf.h>
|
||||
#include <bpf/bpf_helpers.h>
|
||||
|
||||
__noinline
|
||||
int test_ctx_global_func(struct __sk_buff *skb)
|
||||
{
|
||||
volatile int retval = 1;
|
||||
return retval;
|
||||
}
|
||||
|
||||
SEC("freplace/test_pkt_access")
|
||||
int new_test_pkt_access(struct __sk_buff *skb)
|
||||
{
|
||||
return test_ctx_global_func(skb);
|
||||
}
|
||||
|
||||
char _license[] SEC("license") = "GPL";
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
CLANG ?= clang
|
||||
CCINCLUDE += -I../../bpf
|
||||
CCINCLUDE += -I../../../lib
|
||||
CCINCLUDE += -I../../../../../usr/include/
|
||||
|
||||
TEST_CUSTOM_PROGS = $(OUTPUT)/bpf/nat6to4.o
|
||||
|
@ -10,5 +11,4 @@ all: $(TEST_CUSTOM_PROGS)
|
|||
$(OUTPUT)/%.o: %.c
|
||||
$(CLANG) -O2 -target bpf -c $< $(CCINCLUDE) -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(TEST_CUSTOM_PROGS)
|
||||
EXTRA_CLEAN := $(TEST_CUSTOM_PROGS)
|
||||
|
|
|
@ -374,6 +374,45 @@ EOF
|
|||
return $lret
|
||||
}
|
||||
|
||||
test_local_dnat_portonly()
|
||||
{
|
||||
local family=$1
|
||||
local daddr=$2
|
||||
local lret=0
|
||||
local sr_s
|
||||
local sr_r
|
||||
|
||||
ip netns exec "$ns0" nft -f /dev/stdin <<EOF
|
||||
table $family nat {
|
||||
chain output {
|
||||
type nat hook output priority 0; policy accept;
|
||||
meta l4proto tcp dnat to :2000
|
||||
|
||||
}
|
||||
}
|
||||
EOF
|
||||
if [ $? -ne 0 ]; then
|
||||
if [ $family = "inet" ];then
|
||||
echo "SKIP: inet port test"
|
||||
test_inet_nat=false
|
||||
return
|
||||
fi
|
||||
echo "SKIP: Could not add $family dnat hook"
|
||||
return
|
||||
fi
|
||||
|
||||
echo SERVER-$family | ip netns exec "$ns1" timeout 5 socat -u STDIN TCP-LISTEN:2000 &
|
||||
sc_s=$!
|
||||
|
||||
result=$(ip netns exec "$ns0" timeout 1 socat TCP:$daddr:2000 STDOUT)
|
||||
|
||||
if [ "$result" = "SERVER-inet" ];then
|
||||
echo "PASS: inet port rewrite without l3 address"
|
||||
else
|
||||
echo "ERROR: inet port rewrite"
|
||||
ret=1
|
||||
fi
|
||||
}
|
||||
|
||||
test_masquerade6()
|
||||
{
|
||||
|
@ -1148,6 +1187,10 @@ fi
|
|||
reset_counters
|
||||
test_local_dnat ip
|
||||
test_local_dnat6 ip6
|
||||
|
||||
reset_counters
|
||||
test_local_dnat_portonly inet 10.0.1.99
|
||||
|
||||
reset_counters
|
||||
$test_inet_nat && test_local_dnat inet
|
||||
$test_inet_nat && test_local_dnat6 inet
|
||||
|
|
Loading…
Add table
Reference in a new issue