Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add core version of XDPLua #13

Open
wants to merge 3 commits into
base: xdp_lua_core_version_base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1930,7 +1930,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
rcu_read_lock();
xdp_prog = rcu_dereference(tun->xdp_prog);
if (xdp_prog) {
ret = do_xdp_generic(xdp_prog, skb);
ret = do_xdp_generic(xdp_prog, skb, NULL);
if (ret != XDP_PASS) {
rcu_read_unlock();
local_bh_enable();
Expand Down Expand Up @@ -2486,7 +2486,7 @@ static int tun_xdp_one(struct tun_struct *tun,
skb_probe_transport_header(skb);

if (skb_xdp) {
err = do_xdp_generic(xdp_prog, skb);
err = do_xdp_generic(xdp_prog, skb, NULL);
if (err != XDP_PASS)
goto out;
}
Expand Down
5 changes: 4 additions & 1 deletion include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -1918,6 +1918,7 @@ struct net_device {
unsigned int real_num_rx_queues;

struct bpf_prog __rcu *xdp_prog;
char __rcu *xdp_lua_funcname;
unsigned long gro_flush_timeout;
rx_handler_func_t __rcu *rx_handler;
void __rcu *rx_handler_data;
Expand Down Expand Up @@ -3612,7 +3613,7 @@ static inline void dev_consume_skb_any(struct sk_buff *skb)
}

void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog);
int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb);
int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb, char *lua_funcname);
int netif_rx(struct sk_buff *skb);
int netif_rx_ni(struct sk_buff *skb);
int netif_receive_skb(struct sk_buff *skb);
Expand Down Expand Up @@ -3684,6 +3685,8 @@ u32 __dev_xdp_query(struct net_device *dev, bpf_op_t xdp_op,
enum bpf_netdev_command cmd);
int xdp_umem_query(struct net_device *dev, u16 queue_id);

void generic_xdp_lua_install_func(struct net_device *dev, char *lua_funcname);
int generic_xdp_lua_install_prog(char *lua_prog);
int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
bool is_skb_forwardable(const struct net_device *dev,
Expand Down
2 changes: 2 additions & 0 deletions include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,8 @@ enum {
IFLA_XDP_DRV_PROG_ID,
IFLA_XDP_SKB_PROG_ID,
IFLA_XDP_HW_PROG_ID,
IFLA_XDP_LUA_PROG,
IFLA_XDP_LUA_FUNC,
__IFLA_XDP_MAX,
};

Expand Down
1 change: 1 addition & 0 deletions net/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ obj-y := sock.o request_sock.o skbuff.o datagram.o stream.o scm.o \

obj-$(CONFIG_SYSCTL) += sysctl_net_core.o

CFLAGS_dev.o = -Iinclude/linux/lunatik/ -Iinclude/linux/luadata/ -D_KERNEL
obj-y += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \
neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
Expand Down
139 changes: 130 additions & 9 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@
* J Hadi Salim : - Backlog queue sampling
* - netif_rx() feedback
*/
#ifndef _LUNATIK_H
#define _LUNATIK_H
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif

#ifndef _LUADATA_H
#define _LUADATA_H
#include <luadata.h>
#endif

#include <linux/uaccess.h>
#include <linux/bitops.h>
Expand Down Expand Up @@ -150,11 +161,20 @@
/* This should be increased if a protocol with a bigger head is added. */
#define GRO_MAX_HEAD (MAX_HEADER + 128)

struct lua_state_cpu {
lua_State *L;
int cpu;
struct list_head list;
};

typedef struct lua_state_cpu lua_state_cpu;

static DEFINE_SPINLOCK(ptype_lock);
static DEFINE_SPINLOCK(offload_lock);
struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly;
struct list_head ptype_all __read_mostly; /* Taps */
static struct list_head offload_base __read_mostly;
static struct list_head lua_state_cpu_list;

static int netif_rx_internal(struct sk_buff *skb);
static int call_netdevice_notifiers_info(unsigned long val,
Expand Down Expand Up @@ -868,6 +888,36 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex)
}
EXPORT_SYMBOL(dev_get_by_index);

u32 lua_prog_run_xdp(lua_State *L, char *lua_funcname, struct xdp_buff *xdp)
{
u32 ret = 0;
int base;
int data_ref;

if (!L)
goto out;

base = lua_gettop(L);
if (lua_getglobal(L, lua_funcname) != LUA_TFUNCTION) {
pr_err("function %s not found\n", lua_funcname);
goto out;
}

data_ref = ldata_newref(L, xdp->data, xdp->data_end - xdp->data);
if (lua_pcall(L, 1, 1, 0)) {
pr_err("%s\n", lua_tostring(L, -1));
goto cleanup;
}

ret = lua_tointeger(L, -1);

cleanup:
lua_settop(L, base);
ldata_unref(L, data_ref);
out:
return ret;
}

/**
* dev_get_by_napi_id - find a device by napi_id
* @napi_id: ID of the NAPI struct
Expand Down Expand Up @@ -4317,16 +4367,19 @@ static struct netdev_rx_queue *netif_get_rxqueue(struct sk_buff *skb)

static u32 netif_receive_generic_xdp(struct sk_buff *skb,
struct xdp_buff *xdp,
struct bpf_prog *xdp_prog)
struct bpf_prog *xdp_prog,
char *lua_funcname)
{
struct netdev_rx_queue *rxqueue;
void *orig_data, *orig_data_end;
u32 metalen, act = XDP_DROP;
__be16 orig_eth_type;
struct ethhdr *eth;
bool orig_bcast;
int hlen, off;
int hlen, off, cpu;
u32 mac_len;
lua_State *L = NULL;
lua_state_cpu *sc;

/* Reinjected packets coming from act_mirred or similar should
* not get XDP generic processing.
Expand Down Expand Up @@ -4372,7 +4425,19 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
rxqueue = netif_get_rxqueue(skb);
xdp->rxq = &rxqueue->xdp_rxq;

act = bpf_prog_run_xdp(xdp_prog, xdp);
if (xdp_prog)
act = bpf_prog_run_xdp(xdp_prog, xdp);

if (act == XDP_PASS || !xdp_prog) {
cpu = smp_processor_id();
list_for_each_entry(sc, &lua_state_cpu_list, list) {
if (sc->cpu == cpu) {
L = sc->L;
break;
}
}
act = lua_prog_run_xdp(L, lua_funcname, xdp);
}

/* check if bpf_xdp_adjust_head was used */
off = xdp->data - orig_data;
Expand Down Expand Up @@ -4418,7 +4483,8 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,
bpf_warn_invalid_xdp_action(act);
/* fall through */
case XDP_ABORTED:
trace_xdp_exception(skb->dev, xdp_prog, act);
if (xdp_prog)
trace_xdp_exception(skb->dev, xdp_prog, act);
/* fall through */
case XDP_DROP:
do_drop:
Expand Down Expand Up @@ -4449,22 +4515,27 @@ void generic_xdp_tx(struct sk_buff *skb, struct bpf_prog *xdp_prog)
}
HARD_TX_UNLOCK(dev, txq);
if (free_skb) {
trace_xdp_exception(dev, xdp_prog, XDP_TX);
if (xdp_prog)
trace_xdp_exception(dev, xdp_prog, XDP_TX);

kfree_skb(skb);
}
}
EXPORT_SYMBOL_GPL(generic_xdp_tx);

static DEFINE_STATIC_KEY_FALSE(generic_xdp_needed_key);

int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb)
int do_xdp_generic(struct bpf_prog *xdp_prog, struct sk_buff *skb,
char *lua_funcname)
{
if (xdp_prog) {

if (xdp_prog || lua_funcname) {
struct xdp_buff xdp;
u32 act;
int err;

act = netif_receive_generic_xdp(skb, &xdp, xdp_prog);
act = netif_receive_generic_xdp(skb, &xdp, xdp_prog,
lua_funcname);
if (act != XDP_PASS) {
switch (act) {
case XDP_REDIRECT:
Expand Down Expand Up @@ -4836,7 +4907,8 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc,
int ret2;

preempt_disable();
ret2 = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
ret2 = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb,
rcu_dereference(skb->dev->xdp_lua_funcname));
preempt_enable();

if (ret2 != XDP_PASS)
Expand Down Expand Up @@ -5183,6 +5255,36 @@ static int generic_xdp_install(struct net_device *dev, struct netdev_bpf *xdp)
return ret;
}

void generic_xdp_lua_install_func(struct net_device *dev, char *lua_funcname)
{
char *old = rcu_dereference(dev->xdp_lua_funcname);

ASSERT_RTNL();
if (!lua_funcname && old)
static_branch_dec(&generic_xdp_needed_key);
else if(lua_funcname && !old)
static_branch_inc(&generic_xdp_needed_key);

if (old)
kfree(old);

rcu_assign_pointer(dev->xdp_lua_funcname, lua_funcname);
}

int generic_xdp_lua_install_prog(char *lua_prog)
{
lua_state_cpu *sc;

list_for_each_entry(sc, &lua_state_cpu_list, list) {
if (luaL_dostring(sc->L, lua_prog)) {
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
lua_tostring(sc->L, -1), sc->cpu);
return -EINVAL;
}
}
return 0;
}

static int netif_receive_skb_internal(struct sk_buff *skb)
{
int ret;
Expand Down Expand Up @@ -9800,6 +9902,7 @@ static struct pernet_operations __net_initdata default_device_ops = {
static int __init net_dev_init(void)
{
int i, rc = -ENOMEM;
lua_state_cpu *new_state_cpu;

BUG_ON(!dev_boot_phase);

Expand All @@ -9814,6 +9917,7 @@ static int __init net_dev_init(void)
INIT_LIST_HEAD(&ptype_base[i]);

INIT_LIST_HEAD(&offload_base);
INIT_LIST_HEAD(&lua_state_cpu_list);

if (register_pernet_subsys(&netdev_net_ops))
goto out;
Expand Down Expand Up @@ -9844,6 +9948,23 @@ static int __init net_dev_init(void)
init_gro_hash(&sd->backlog);
sd->backlog.poll = process_backlog;
sd->backlog.weight = weight_p;

new_state_cpu = (lua_state_cpu *) kmalloc(sizeof(lua_state_cpu),
GFP_ATOMIC);
if (!new_state_cpu)
continue;

new_state_cpu->L = luaL_newstate();
if (!new_state_cpu->L) {
kfree(new_state_cpu);
continue;
}

luaL_openlibs(new_state_cpu->L);
luaL_requiref(new_state_cpu->L, "data", luaopen_data, 1);
new_state_cpu->cpu = i;

list_add(&new_state_cpu->list, &lua_state_cpu_list);
}

dev_boot_phase = 0;
Expand Down
31 changes: 23 additions & 8 deletions net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -3502,10 +3502,14 @@ xdp_do_redirect_slow(struct net_device *dev, struct xdp_buff *xdp,
if (unlikely(err))
goto err;

_trace_xdp_redirect(dev, xdp_prog, index);
if (xdp_prog)
_trace_xdp_redirect(dev, xdp_prog, index);

return 0;
err:
_trace_xdp_redirect_err(dev, xdp_prog, index, err);
if (xdp_prog)
_trace_xdp_redirect_err(dev, xdp_prog, index, err);

return err;
}

Expand Down Expand Up @@ -3620,10 +3624,13 @@ static int xdp_do_redirect_map(struct net_device *dev, struct xdp_buff *xdp,
goto err;

ri->map_to_flush = map;
_trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index);
if (xdp_prog)
_trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index);

return 0;
err:
_trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err);
if (xdp_prog)
_trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err);
return err;
}

Expand Down Expand Up @@ -3674,10 +3681,14 @@ static int xdp_do_generic_redirect_map(struct net_device *dev,
goto err;
}

_trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index);
if (xdp_prog)
_trace_xdp_redirect_map(dev, xdp_prog, fwd, map, index);

return 0;
err:
_trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err);
if (xdp_prog)
_trace_xdp_redirect_map_err(dev, xdp_prog, fwd, map, index, err);

return err;
}

Expand Down Expand Up @@ -3705,11 +3716,15 @@ int xdp_do_generic_redirect(struct net_device *dev, struct sk_buff *skb,
goto err;

skb->dev = fwd;
_trace_xdp_redirect(dev, xdp_prog, index);
if (xdp_prog)
_trace_xdp_redirect(dev, xdp_prog, index);

generic_xdp_tx(skb, xdp_prog);
return 0;
err:
_trace_xdp_redirect_err(dev, xdp_prog, index, err);
if (xdp_prog)
_trace_xdp_redirect_err(dev, xdp_prog, index, err);

return err;
}
EXPORT_SYMBOL_GPL(xdp_do_generic_redirect);
Expand Down
Loading