Skip to content

Commit 50e056a

Browse files
Add javascript challenge sample
1 parent 040b06b commit 50e056a

3 files changed

Lines changed: 149 additions & 0 deletions

File tree

samples/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ always-y += hbm_edt_kern.o
176176
always-y += xdpsock_kern.o
177177
# CONFIG_XDP_LUA
178178
always-y += xdplua_map_kern.o
179+
always-y += xdplua_cookie_kern.o
179180

180181
ifeq ($(ARCH), arm)
181182
# Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux

samples/bpf/checkcookie.lua

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--
2+
-- Copyright (C) 2020 ring-0 Ltda
3+
--
4+
-- This program is free software; you can redistribute it and/or
5+
-- modify it under the terms of the GNU General Public License as
6+
-- published by the Free Software Foundation version 2.
7+
--
8+
-- This program is distributed "as is" WITHOUT ANY WARRANTY of any
9+
-- kind, whether express or implied; without even the implied warranty
10+
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
-- GNU General Public License for more details.
12+
--
13+
cookies = {}
14+
15+
local function ip2int(ip)
16+
local oct1, oct2, oct3, oct4 = ip:match("(%d+)%.(%d+)%.(%d+)%.(%d+)")
17+
return (oct4 << 24) + (oct3 << 16) + (oct2 << 8) + oct1
18+
end
19+
20+
function loadcookieport(ip, port, cookie)
21+
local ip = ip2int(ip)
22+
23+
if not cookies[ip] then
24+
cookies[ip] = {}
25+
end
26+
27+
cookies[ip][port] = cookie
28+
end
29+
30+
function loadcookie(ip, cookie)
31+
cookies[ip2int(ip)] = cookie
32+
end
33+
34+
function checkcookieport(pkt, ip, port)
35+
local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n"))
36+
if not cookies[ip] then
37+
return true
38+
end
39+
40+
if not cookies[ip][port] then
41+
return true
42+
end
43+
44+
return cookies[ip][port] == cookiepkt and true or false
45+
end
46+
47+
function checkcookie(pkt, ip)
48+
local cookiepkt = tonumber(string.match(tostring(pkt), "Cookie:%s__xdp=(.-)\r\n"))
49+
50+
return cookies[ip] == cookiepkt and true or false
51+
end

samples/bpf/xdplua_cookie_kern.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (C) 2020 ring-0 Ltda
3+
*
4+
* This program is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU General Public License as
6+
* published by the Free Software Foundation version 2.
7+
*
8+
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
9+
* kind, whether express or implied; without even the implied warranty
10+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*/
13+
#define KBUILD_MODNAME "foo"
14+
#include <uapi/linux/bpf.h>
15+
#include <linux/if_ether.h>
16+
#include <linux/if_packet.h>
17+
#include <linux/if_vlan.h>
18+
#include <linux/in.h>
19+
#include <linux/ip.h>
20+
#include <linux/ipv6.h>
21+
#include <asm/byteorder.h>
22+
#include <bpf/bpf_helpers.h>
23+
24+
#define HTTPDSTPORT 80
25+
26+
static int parse_tcp(struct xdp_md *ctx, void *data, uint64_t tp_off,
27+
void *data_end, __be32 saddr) {
28+
29+
struct tcphdr *tcp = data + tp_off;
30+
char cookiefunc[] = "checkcookie";
31+
int data_ref;
32+
33+
if (tcp + 1 > data_end)
34+
return XDP_PASS;
35+
36+
if (tcp->dest == htons(HTTPDSTPORT)) {
37+
bool verdict;
38+
data_ref = bpf_lua_dataref(ctx, tp_off + tcp->doff * 4);
39+
if (data_ref < 0)
40+
return XDP_PASS;
41+
42+
bpf_lua_pushinteger(ctx, saddr);
43+
44+
bpf_lua_pcall(ctx, cookiefunc, 2, 1);
45+
46+
verdict = bpf_lua_toboolean(ctx, -1);
47+
48+
return verdict ? XDP_PASS : XDP_DROP;
49+
}
50+
51+
return XDP_PASS;
52+
}
53+
54+
static inline u64 parse_ipv4(struct xdp_md *ctx, void *data, u64 nh_off, void *data_end, __be32 *saddr)
55+
{
56+
struct iphdr *iph = data + nh_off;
57+
58+
if (iph + 1 > data_end)
59+
return -1;
60+
61+
nh_off += iph->ihl * 4;
62+
63+
*saddr = iph->saddr;
64+
65+
return nh_off;
66+
}
67+
68+
SEC("xdplua_cookie")
69+
int xdp_lua_cookie_prog(struct xdp_md *ctx)
70+
{
71+
void *data_end = (void *)(long)ctx->data_end;
72+
void *data = (void *)(long)ctx->data;
73+
int rc = XDP_PASS;
74+
struct ethhdr *eth = data;
75+
u16 h_proto;
76+
u64 nh_off;
77+
u64 ip_off;
78+
u_int8_t protonum;
79+
int verdict;
80+
__be32 saddr;
81+
82+
nh_off = sizeof(*eth);
83+
if (data + nh_off > data_end)
84+
return rc;
85+
86+
h_proto = eth->h_proto;
87+
if (h_proto != htons(ETH_P_IP))
88+
return rc;
89+
90+
ip_off = parse_ipv4(ctx, data, nh_off, data_end, &saddr);
91+
if (ip_off == -1)
92+
return rc;
93+
94+
return parse_tcp(ctx, data, ip_off, data_end, saddr);
95+
}
96+
97+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)