Commit fbd01410 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull networking fixes from David Miller:
 "The iwlwifi firmware compat fix is in here as well as some other
  stuff:

  1) Fix request socket leak introduced by BPF deadlock fix, from Eric
     Dumazet.

  2) Fix VLAN handling with TXQs in mac80211, from Johannes Berg.

  3) Missing __qdisc_drop conversions in prio and qfq schedulers, from
     Gao Feng.

  4) Use after free in netlink nlk groups handling, from Xin Long.

  5) Handle MTU update properly in ipv6 gre tunnels, from Xin Long.

  6) Fix leak of ipv6 fib tables on netns teardown, from Sabrina Dubroca
     with follow-on fix from Eric Dumazet.

  7) Need RCU and preemption disabled during generic XDP data patch,
     from John Fastabend"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (54 commits)
  bpf: make error reporting in bpf_warn_invalid_xdp_action more clear
  Revert "mdio_bus: Remove unneeded gpiod NULL check"
  bpf: devmap, use cond_resched instead of cpu_relax
  bpf: add support for sockmap detach programs
  net: rcu lock and preempt disable missing around generic xdp
  bpf: don't select potentially stale ri->map from buggy xdp progs
  net: tulip: Constify tulip_tbl
  net: ethernet: ti: netcp_core: no need in netif_napi_del
  davicom: Display proper debug level up to 6
  net: phy: sfp: rename dt properties to match the binding
  dt-binding: net: sfp binding documentation
  dt-bindings: add SFF vendor prefix
  dt-bindings: net: don't confuse with generic PHY property
  ip6_tunnel: fix setting hop_limit value for ipv6 tunnel
  ip_tunnel: fix setting ttl and tos value in collect_md mode
  ipv6: fix typo in fib6_net_exit()
  tcp: fix a request socket leak
  sctp: fix missing wake ups in some situations
  netfilter: xt_hashlimit: fix build error caused by 64bit division
  netfilter: xt_hashlimit: alloc hashtable with right size
  ...
parents fbf4432f 9beb8bed
The following properties are common to the Ethernet controllers:
NOTE: All 'phy*' properties documented below are Ethernet specific. For the
generic PHY 'phys' property, see
Documentation/devicetree/bindings/phy/phy-bindings.txt.
- local-mac-address: array of 6 bytes, specifies the MAC address that was
assigned to the network device;
- mac-address: array of 6 bytes, specifies the MAC address that was last used by
......
Small Form Factor (SFF) Committee Small Form-factor Pluggable (SFP)
Transceiver
Required properties:
- compatible : must be "sff,sfp"
Optional Properties:
- i2c-bus : phandle of an I2C bus controller for the SFP two wire serial
interface
- mod-def0-gpios : GPIO phandle and a specifier of the MOD-DEF0 (AKA Mod_ABS)
module presence input gpio signal, active (module absent) high
- los-gpios : GPIO phandle and a specifier of the Receiver Loss of Signal
Indication input gpio signal, active (signal lost) high
- tx-fault-gpios : GPIO phandle and a specifier of the Module Transmitter
Fault input gpio signal, active (fault condition) high
- tx-disable-gpios : GPIO phandle and a specifier of the Transmitter Disable
output gpio signal, active (Tx disable) high
- rate-select0-gpios : GPIO phandle and a specifier of the Rx Signaling Rate
Select (AKA RS0) output gpio signal, low: low Rx rate, high: high Rx rate
- rate-select1-gpios : GPIO phandle and a specifier of the Tx Signaling Rate
Select (AKA RS1) output gpio signal (SFP+ only), low: low Tx rate, high:
high Tx rate
Example #1: Direct serdes to SFP connection
sfp_eth3: sfp-eth3 {
compatible = "sff,sfp";
i2c-bus = <&sfp_1g_i2c>;
los-gpios = <&cpm_gpio2 22 GPIO_ACTIVE_HIGH>;
mod-def0-gpios = <&cpm_gpio2 21 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&cpm_sfp_1g_pins &cps_sfp_1g_pins>;
tx-disable-gpios = <&cps_gpio1 24 GPIO_ACTIVE_HIGH>;
tx-fault-gpios = <&cpm_gpio2 19 GPIO_ACTIVE_HIGH>;
};
&cps_emac3 {
phy-names = "comphy";
phys = <&cps_comphy5 0>;
sfp = <&sfp_eth3>;
};
Example #2: Serdes to PHY to SFP connection
sfp_eth0: sfp-eth0 {
compatible = "sff,sfp";
i2c-bus = <&sfpp0_i2c>;
los-gpios = <&cps_gpio1 28 GPIO_ACTIVE_HIGH>;
mod-def0-gpios = <&cps_gpio1 27 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&cps_sfpp0_pins>;
tx-disable-gpios = <&cps_gpio1 29 GPIO_ACTIVE_HIGH>;
tx-fault-gpios = <&cps_gpio1 26 GPIO_ACTIVE_HIGH>;
};
p0_phy: [email protected] {
compatible = "ethernet-phy-ieee802.3-c45";
pinctrl-names = "default";
pinctrl-0 = <&cpm_phy0_pins &cps_phy0_pins>;
reg = <0>;
interrupt = <&cpm_gpio2 18 IRQ_TYPE_EDGE_FALLING>;
sfp = <&sfp_eth0>;
};
&cpm_eth0 {
phy = <&p0_phy>;
phy-mode = "10gbase-kr";
};
......@@ -34,7 +34,9 @@ PHY user node
=============
Required Properties:
phys : the phandle for the PHY device (used by the PHY subsystem)
phys : the phandle for the PHY device (used by the PHY subsystem; not to be
confused with the Ethernet specific 'phy' and 'phy-handle' properties,
see Documentation/devicetree/bindings/net/ethernet.txt for these)
phy-names : the names of the PHY corresponding to the PHYs present in the
*phys* phandle
......
......@@ -292,6 +292,7 @@ schindler Schindler
seagate Seagate Technology PLC
semtech Semtech Corporation
sensirion Sensirion AG
sff Small Form Factor Committee
sgx SGX Sensortech
sharp Sharp Corporation
si-en Si-En Technology Ltd.
......
......@@ -409,7 +409,7 @@ isdnloop_sendbuf(int channel, struct sk_buff *skb, isdnloop_card *card)
return -EINVAL;
}
if (len) {
if (!(card->flags & (channel) ? ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE))
if (!(card->flags & (channel ? ISDNLOOP_FLAGS_B2ACTIVE : ISDNLOOP_FLAGS_B1ACTIVE)))
return 0;
if (card->sndcount[channel] > ISDNLOOP_MAX_SQUEUE)
return 0;
......
......@@ -65,7 +65,7 @@ MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
*/
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "dm9000 debug level (0-4)");
MODULE_PARM_DESC(debug, "dm9000 debug level (0-6)");
/* DM9000 register address locking.
*
......
......@@ -515,7 +515,7 @@ void comet_timer(unsigned long data);
extern int tulip_debug;
extern const char * const medianame[];
extern const char tulip_media_cap[];
extern struct tulip_chip_table tulip_tbl[];
extern const struct tulip_chip_table tulip_tbl[];
void oom_timer(unsigned long data);
extern u8 t21040_csr13[];
......
......@@ -138,7 +138,7 @@ static void tulip_timer(unsigned long data)
* It is indexed via the values in 'enum chips'
*/
struct tulip_chip_table tulip_tbl[] = {
const struct tulip_chip_table tulip_tbl[] = {
{ }, /* placeholder for array, slot unused currently */
{ }, /* placeholder for array, slot unused currently */
......
......@@ -2145,7 +2145,6 @@ static void netcp_delete_interface(struct netcp_device *netcp_device,
of_node_put(netcp->node_interface);
unregister_netdev(ndev);
netif_napi_del(&netcp->rx_napi);
free_netdev(ndev);
}
......
......@@ -399,7 +399,8 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
}
/* Put PHYs in RESET to save power */
gpiod_set_value_cansleep(bus->reset_gpiod, 1);
if (bus->reset_gpiod)
gpiod_set_value_cansleep(bus->reset_gpiod, 1);
device_del(&bus->dev);
return err;
......@@ -424,7 +425,8 @@ void mdiobus_unregister(struct mii_bus *bus)
}
/* Put PHYs in RESET to save power */
gpiod_set_value_cansleep(bus->reset_gpiod, 1);
if (bus->reset_gpiod)
gpiod_set_value_cansleep(bus->reset_gpiod, 1);
device_del(&bus->dev);
}
......
......@@ -58,11 +58,11 @@ enum {
};
static const char *gpio_of_names[] = {
"moddef0",
"mod-def0",
"los",
"tx-fault",
"tx-disable",
"rate-select",
"rate-select0",
};
static const enum gpiod_flags gpio_flags[] = {
......
......@@ -159,7 +159,8 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
brcmf_feat_firmware_capabilities(ifp);
memset(&gscan_cfg, 0, sizeof(gscan_cfg));
if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID)
if (drvr->bus_if->chip != BRCM_CC_43430_CHIP_ID &&
drvr->bus_if->chip != BRCM_CC_4345_CHIP_ID)
brcmf_feat_iovar_data_set(ifp, BRCMF_FEAT_GSCAN,
"pfn_gscan_cfg",
&gscan_cfg, sizeof(gscan_cfg));
......
......@@ -378,6 +378,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG = (__force iwl_ucode_tlv_capa_t)80,
IWL_UCODE_TLV_CAPA_LQM_SUPPORT = (__force iwl_ucode_tlv_capa_t)81,
IWL_UCODE_TLV_CAPA_TX_POWER_ACK = (__force iwl_ucode_tlv_capa_t)84,
IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT = (__force iwl_ucode_tlv_capa_t)86,
IWL_UCODE_TLV_CAPA_MLME_OFFLOAD = (__force iwl_ucode_tlv_capa_t)96,
NUM_IWL_UCODE_TLV_CAPA
......
......@@ -92,7 +92,8 @@ static void iwl_mvm_send_led_fw_cmd(struct iwl_mvm *mvm, bool on)
static void iwl_mvm_led_set(struct iwl_mvm *mvm, bool on)
{
if (mvm->cfg->device_family >= IWL_DEVICE_FAMILY_8000) {
if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_LED_CMD_SUPPORT)) {
iwl_mvm_send_led_fw_cmd(mvm, on);
return;
}
......
......@@ -1362,8 +1362,6 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
txi->control.rates,
ARRAY_SIZE(txi->control.rates));
txi->rate_driver_data[0] = channel;
if (skb->len >= 24 + 8 &&
ieee80211_is_probe_resp(hdr->frame_control)) {
/* fake header transmission time */
......
......@@ -1183,7 +1183,10 @@ static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist,
}
/* fixed internal switch S1->WiFi, S0->BT */
btcoexist->btc_write_4byte(btcoexist, 0x948, 0x0);
if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
else
btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
switch (antpos_type) {
case BTC_ANT_WIFI_AT_MAIN:
......
......@@ -173,6 +173,16 @@ static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
{
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
/* override ant_num / ant_path */
if (mod_params->ant_sel) {
rtlpriv->btcoexist.btc_info.ant_num =
(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
rtlpriv->btcoexist.btc_info.single_ant_path =
(mod_params->ant_sel == 1 ? 0 : 1);
}
return rtlpriv->btcoexist.btc_info.single_ant_path;
}
......@@ -183,6 +193,7 @@ u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
{
struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
u8 num;
if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
......@@ -190,6 +201,10 @@ u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
else
num = 1;
/* override ant_num / ant_path */
if (mod_params->ant_sel)
num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1;
return num;
}
......@@ -876,7 +891,7 @@ bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
{
struct btc_coexist *btcoexist = &gl_bt_coexist;
struct rtl_priv *rtlpriv = adapter;
u8 ant_num = 2, chip_type, single_ant_path = 0;
u8 ant_num = 2, chip_type;
if (btcoexist->binded)
return false;
......@@ -911,12 +926,6 @@ bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
ant_num = rtl_get_hwpg_ant_num(rtlpriv);
exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
/* set default antenna position to main port */
btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv);
exhalbtc_set_single_ant_path(single_ant_path);
if (rtl_get_hwpg_package_type(rtlpriv) == 0)
btcoexist->board_info.tfbga_package = false;
else if (rtl_get_hwpg_package_type(rtlpriv) == 1)
......
......@@ -385,16 +385,16 @@ static inline void __dev_map_flush(struct bpf_map *map)
#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL)
struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
#else
static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
{
return NULL;
}
static inline int sock_map_attach_prog(struct bpf_map *map,
struct bpf_prog *prog,
u32 type)
static inline int sock_map_prog(struct bpf_map *map,
struct bpf_prog *prog,
u32 type)
{
return -EOPNOTSUPP;
}
......
......@@ -958,7 +958,7 @@ void kfree_skb(struct sk_buff *skb);
void kfree_skb_list(struct sk_buff *segs);
void skb_tx_error(struct sk_buff *skb);
void consume_skb(struct sk_buff *skb);
void consume_stateless_skb(struct sk_buff *skb);
void __consume_stateless_skb(struct sk_buff *skb);
void __kfree_skb(struct sk_buff *skb);
extern struct kmem_cache *skbuff_head_cache;
......
......@@ -919,21 +919,10 @@ struct ieee80211_tx_info {
unsigned long jiffies;
};
/* NB: vif can be NULL for injected frames */
union {
/* NB: vif can be NULL for injected frames */
struct ieee80211_vif *vif;
/* When packets are enqueued on txq it's easy
* to re-construct the vif pointer. There's no
* more space in tx_info so it can be used to
* store the necessary enqueue time for packet
* sojourn time computation.
*/
codel_time_t enqueue_time;
};
struct ieee80211_vif *vif;
struct ieee80211_key_conf *hw_key;
u32 flags;
/* 4 bytes free */
codel_time_t enqueue_time;
} control;
struct {
u64 cookie;
......
......@@ -17,7 +17,6 @@
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/atomic.h>
#include <linux/rhashtable.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <linux/netfilter/nf_conntrack_dccp.h>
......@@ -77,7 +76,7 @@ struct nf_conn {
possible_net_t ct_net;
#if IS_ENABLED(CONFIG_NF_NAT)
struct rhlist_head nat_bysource;
struct hlist_node nat_bysource;
#endif
/* all members below initialized via memset */
u8 __nfct_init_offset[0];
......
#ifndef _NF_NAT_H
#define _NF_NAT_H
#include <linux/rhashtable.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter/nf_nat.h>
#include <net/netfilter/nf_conntrack_tuple.h>
......
......@@ -766,8 +766,8 @@ struct bpf_sock {
/* User return codes for XDP prog type.
* A valid XDP program must return one of these defined values. All other
* return codes are reserved for future use. Unknown return codes will result
* in packet drop.
* return codes are reserved for future use. Unknown return codes will
* result in packet drops and a warning via bpf_warn_invalid_xdp_action().
*/
enum xdp_action {
XDP_ABORTED = 0,
......
......@@ -159,7 +159,7 @@ static void dev_map_free(struct bpf_map *map)
unsigned long *bitmap = per_cpu_ptr(dtab->flush_needed, cpu);
while (!bitmap_empty(bitmap, dtab->map.max_entries))
cpu_relax();
cond_resched();
}
for (i = 0; i < dtab->map.max_entries; i++) {
......
......@@ -792,7 +792,7 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
return err;
}
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
{
struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
struct bpf_prog *orig;
......
......@@ -1096,10 +1096,10 @@ static int bpf_obj_get(const union bpf_attr *attr)
#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
static int sockmap_get_from_fd(const union bpf_attr *attr)
static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
{
struct bpf_prog *prog = NULL;
int ufd = attr->target_fd;
struct bpf_prog *prog;
struct bpf_map *map;
struct fd f;
int err;
......@@ -1109,16 +1109,20 @@ static int sockmap_get_from_fd(const union bpf_attr *attr)
if (IS_ERR(map))
return PTR_ERR(map);
prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB);
if (IS_ERR(prog)) {
fdput(f);
return PTR_ERR(prog);
if (attach) {
prog = bpf_prog_get_type(attr->attach_bpf_fd,
BPF_PROG_TYPE_SK_SKB);
if (IS_ERR(prog)) {
fdput(f);
return PTR_ERR(prog);
}
}
err = sock_map_attach_prog(map, prog, attr->attach_type);
err = sock_map_prog(map, prog, attr->attach_type);
if (err) {
fdput(f);
bpf_prog_put(prog);
if (prog)
bpf_prog_put(prog);
return err;
}
......@@ -1155,7 +1159,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
break;
case BPF_SK_SKB_STREAM_PARSER:
case BPF_SK_SKB_STREAM_VERDICT:
return sockmap_get_from_fd(attr);
return sockmap_get_from_fd(attr, true);
default:
return -EINVAL;
}
......@@ -1204,7 +1208,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
cgroup_put(cgrp);
break;
case BPF_SK_SKB_STREAM_PARSER:
case BPF_SK_SKB_STREAM_VERDICT:
ret = sockmap_get_from_fd(attr, false);
break;
default:
return -EINVAL;
}
......
......@@ -4203,6 +4203,22 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env)
continue;
}
if (insn->imm == BPF_FUNC_redirect_map) {
u64 addr = (unsigned long)prog;
struct bpf_insn r4_ld[] = {
BPF_LD_IMM64(BPF_REG_4, addr),
*insn,
};
cnt = ARRAY_SIZE(r4_ld);
new_prog = bpf_patch_insn_data(env, i + delta, r4_ld, cnt);
if (!new_prog)
return -ENOMEM;
delta += cnt - 1;
env->prog = prog = new_prog;
insn = new_prog->insnsi + i + delta;
}
patch_call_imm:
fn = prog->aux->ops->get_func_proto(insn->imm);
/* all functions that have prototype and verifier allowed
......
......@@ -3981,8 +3981,13 @@ static int netif_rx_internal(struct sk_buff *skb)
trace_netif_rx(skb);
if (static_key_false(&generic_xdp_needed)) {
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
skb);
int ret;
preempt_disable();
rcu_read_lock();
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
rcu_read_unlock();
preempt_enable();
/* Consider XDP consuming the packet a success from
* the netdev point of view we do not want to count
......@@ -4500,18 +4505,20 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
if (skb_defer_rx_timestamp(skb))
return NET_RX_SUCCESS;
rcu_read_lock();
if (static_key_false(&generic_xdp_needed)) {
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
skb);
int ret;
if (ret != XDP_PASS) {
rcu_read_unlock();
preempt_disable();
rcu_read_lock();
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
rcu_read_unlock();
preempt_enable();
if (ret != XDP_PASS)
return NET_RX_DROP;
}
}
rcu_read_lock();
#ifdef CONFIG_RPS
if (static_key_false(&rps_needed)) {
struct rps_dev_flow voidflow, *rflow = &voidflow;
......
......@@ -1794,6 +1794,7 @@ struct redirect_info {
u32 flags;
struct bpf_map *map;
struct bpf_map *map_to_flush;
const struct bpf_prog *map_owner;
};
static DEFINE_PER_CPU(struct redirect_info, redirect_info);
......@@ -1807,7 +1808,6 @@ BPF_CALL_2(bpf_redirect, u32, ifindex, u64, flags)
ri->ifindex = ifindex;
ri->flags = flags;
ri->map = NULL;
return TC_ACT_REDIRECT;
}
......@@ -2504,6 +2504,7 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
struct bpf_prog *xdp_prog)
{
struct redirect_info *ri = this_cpu_ptr(&redirect_info);
const struct bpf_prog *map_owner = ri->map_owner;
struct bpf_map *map = ri->map;
u32 index = ri->ifindex;
struct net_device *fwd;
......@@ -2511,6 +2512,15 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
ri->ifindex = 0;
ri->map = NULL;
ri->map_owner = NULL;
/* This is really only caused by a deliberately crappy
* BPF program, normally we would never hit that case,
* so no need to inform someone via tracepoints either,
* just bail out.
*/
if (unlikely(map_owner != xdp_prog))
return -EINVAL;
fwd = __dev_map_lookup_elem(map, index);
if (!fwd) {
......@@ -2607,6 +2617,8 @@ BPF_CALL_2(bpf_xdp_redirect, u32, ifindex, u64, flags)
ri->ifindex = ifindex;
ri->flags = flags;
ri->map = NULL;
ri->map_owner = NULL;
return XDP_REDIRECT;
}
......@@ -2619,7 +2631,8 @@ static const struct bpf_func_proto bpf_xdp_redirect_proto = {
.arg2_type = ARG_ANYTHING,
};
BPF_CALL_3(bpf_xdp_redirect_map, struct bpf_map *, map, u32, ifindex, u64, flags)