Skip to content

Commit

Permalink
Add core version of XDPLua
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorNogueiraRio committed Sep 9, 2019
1 parent 77c2b24 commit a316240
Show file tree
Hide file tree
Showing 13 changed files with 452 additions and 20 deletions.
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
138 changes: 129 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,18 @@ 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);
} else {
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 +4482,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 +4514,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 +4906,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 +5254,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 +9901,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 +9916,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 +9947,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_KERNEL);
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

0 comments on commit a316240

Please sign in to comment.