Commit 2631f6dc authored by Brenden Blanco's avatar Brenden Blanco Committed by GitHub

Merge pull request #1185 from gospo/master

Add support for generic XDP mode
parents 4b3d2b08 9f3cab70
......@@ -12,11 +12,28 @@ import pyroute2
import time
import sys
if len(sys.argv) != 2:
print("Usage: {0} <ifdev>\n\ne.g.: {0} eth0".format(sys.argv[0]))
flags = 0
def usage():
print("Usage: {0} [-S] <ifdev>".format(sys.argv[0]))
print(" -S: use skb mode\n")
print("e.g.: {0} eth0\n".format(sys.argv[0]))
exit(1)
device = sys.argv[1]
if len(sys.argv) < 2 or len(sys.argv) > 3:
usage()
if len(sys.argv) == 2:
device = sys.argv[1]
if len(sys.argv) == 3:
if "-S" in sys.argv:
# XDP_FLAGS_SKB_MODE
flags |= 2 << 0
if "-S" == sys.argv[1]:
device = sys.argv[2]
else:
device = sys.argv[1]
mode = BPF.XDP
#mode = BPF.SCHED_CLS
......@@ -116,7 +133,7 @@ int xdp_prog1(struct CTXTYPE *ctx) {
fn = b.load_func("xdp_prog1", mode)
if mode == BPF.XDP:
b.attach_xdp(device, fn)
b.attach_xdp(device, fn, flags)
else:
ip = pyroute2.IPRoute()
ipdb = pyroute2.IPDB(nl=ip)
......
......@@ -649,7 +649,7 @@ int bpf_open_perf_event(uint32_t type, uint64_t config, int pid, int cpu) {
return fd;
}
int bpf_attach_xdp(const char *dev_name, int progfd) {
int bpf_attach_xdp(const char *dev_name, int progfd, uint32_t flags) {
struct sockaddr_nl sa;
int sock, seq = 0, len, ret = -1;
char buf[4096];
......@@ -694,12 +694,22 @@ int bpf_attach_xdp(const char *dev_name, int progfd) {
nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
nla_xdp = (struct nlattr *)((char *)nla + NLA_HDRLEN);
nla->nla_len = NLA_HDRLEN;
// we specify the FD passed over by the user
nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(progfd);
memcpy((char *)nla_xdp + NLA_HDRLEN, &progfd, sizeof(progfd));
nla->nla_len = NLA_HDRLEN + nla_xdp->nla_len;
nla->nla_len += nla_xdp->nla_len;
// parse flags as passed by the user
if (flags) {
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
nla_xdp->nla_type = 3/*IFLA_XDP_SKB*/;
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
nla->nla_len += nla_xdp->nla_len;
}
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
......
......@@ -75,7 +75,7 @@ void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb,
int pid, int cpu, int page_cnt);
/* attached a prog expressed by progfd to the device specified in dev_name */
int bpf_attach_xdp(const char *dev_name, int progfd);
int bpf_attach_xdp(const char *dev_name, int progfd, uint32_t flags);
// attach a prog expressed by progfd to run on a specific perf event, with
// certain sample period or sample frequency
......
......@@ -571,14 +571,14 @@ class BPF(object):
self._del_kprobe(ev_name)
@staticmethod
def attach_xdp(dev, fn):
def attach_xdp(dev, fn, flags):
'''
This function attaches a BPF function to a device on the device
driver level (XDP)
'''
if not isinstance(fn, BPF.Function):
raise Exception("arg 1 must be of type BPF.Function")
res = lib.bpf_attach_xdp(dev.encode("ascii"), fn.fd)
res = lib.bpf_attach_xdp(dev.encode("ascii"), fn.fd, flags)
if res < 0:
err_no = ct.get_errno()
if err_no == errno.EBADMSG:
......@@ -595,7 +595,7 @@ class BPF(object):
This function removes any BPF function from a device on the
device driver level (XDP)
'''
res = lib.bpf_attach_xdp(dev.encode("ascii"), -1)
res = lib.bpf_attach_xdp(dev.encode("ascii"), -1, 0)
if res < 0:
errstr = os.strerror(ct.get_errno())
raise Exception("Failed to detach BPF from device %s: %s"
......
......@@ -116,7 +116,7 @@ lib.perf_reader_fd.restype = int
lib.perf_reader_fd.argtypes = [ct.c_void_p]
lib.bpf_attach_xdp.restype = ct.c_int;
lib.bpf_attach_xdp.argtypes = [ct.c_char_p, ct.c_int]
lib.bpf_attach_xdp.argtypes = [ct.c_char_p, ct.c_int, ct.c_uint]
lib.bpf_attach_perf_event.restype = ct.c_int;
lib.bpf_attach_perf_event.argtype = [ct.c_int, ct.c_uint, ct.c_uint, ct.c_ulonglong, ct.c_ulonglong,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment