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 Jul 19, 2019
1 parent 560f93f commit 08b1f34
Show file tree
Hide file tree
Showing 12 changed files with 456 additions and 22 deletions.
4 changes: 2 additions & 2 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -1947,7 +1947,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 @@ -2503,7 +2503,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 @@ -1922,6 +1922,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 @@ -3616,7 +3617,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 @@ -3688,6 +3689,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 @@ -968,6 +968,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
145 changes: 134 additions & 11 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,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 @@ -154,11 +165,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 @@ -872,6 +892,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 @@ -4329,16 +4379,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 @@ -4384,7 +4437,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);
}

off = xdp->data - orig_data;
if (off > 0)
Expand Down Expand Up @@ -4425,7 +4489,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 @@ -4456,22 +4521,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 @@ -4507,7 +4577,8 @@ static int netif_rx_internal(struct sk_buff *skb)

preempt_disable();
rcu_read_lock();
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb,
rcu_dereference(skb->dev->xdp_lua_funcname));
rcu_read_unlock();
preempt_enable();

Expand Down Expand Up @@ -5169,6 +5240,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 All @@ -5183,7 +5284,8 @@ static int netif_receive_skb_internal(struct sk_buff *skb)

preempt_disable();
rcu_read_lock();
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb,
rcu_dereference(skb->dev->xdp_lua_funcname));
rcu_read_unlock();
preempt_enable();

Expand Down Expand Up @@ -5212,6 +5314,7 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
static void netif_receive_skb_list_internal(struct list_head *head)
{
struct bpf_prog *xdp_prog = NULL;
char *lua_funcname = NULL;
struct sk_buff *skb, *next;
struct list_head sublist;

Expand All @@ -5229,8 +5332,9 @@ static void netif_receive_skb_list_internal(struct list_head *head)
rcu_read_lock();
list_for_each_entry_safe(skb, next, head, list) {
xdp_prog = rcu_dereference(skb->dev->xdp_prog);
lua_funcname = rcu_dereference(skb->dev->xdp_lua_funcname);
skb_list_del_init(skb);
if (do_xdp_generic(xdp_prog, skb) == XDP_PASS)
if (do_xdp_generic(xdp_prog, skb, lua_funcname) == XDP_PASS)
list_add_tail(&skb->list, &sublist);
}
rcu_read_unlock();
Expand Down Expand Up @@ -9813,6 +9917,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 @@ -9827,6 +9932,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 @@ -9857,6 +9963,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 @@ -3505,10 +3505,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 @@ -3629,10 +3633,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 @@ -3688,10 +3695,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 @@ -3719,11 +3730,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 08b1f34

Please sign in to comment.