From d08ae9402429bfca69d72c7a7d99975aa356539f Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Mon, 8 Jul 2024 06:05:08 +0530 Subject: bpf/filter: init --- bpf/filter/bpf.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 bpf/filter/bpf.c (limited to 'bpf/filter/bpf.c') diff --git a/bpf/filter/bpf.c b/bpf/filter/bpf.c new file mode 100644 index 0000000..ae62cb8 --- /dev/null +++ b/bpf/filter/bpf.c @@ -0,0 +1,82 @@ +#include +#include +#include + +#include +#include + +#define MAX_MAP_ENTRIES 4096 + +char __license[] SEC("license") = "GPL"; + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, MAX_MAP_ENTRIES); + __type(key, __u64); // blocked mac address + // i just like her for the o(1) key lookup + // we don't care about the value + __type(value, __u16); +} mac_blacklist_map SEC(".maps"); + +static __always_inline __u64 nchar6_to_u64(unsigned char bytes[6]) +{ + union { + char bytes[6]; + __u64 i; + } ret; + + ret.i = 0; +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + ret.bytes[0] = bytes[5]; + ret.bytes[1] = bytes[4]; + ret.bytes[2] = bytes[3]; + ret.bytes[3] = bytes[2]; + ret.bytes[4] = bytes[1]; + ret.bytes[5] = bytes[0]; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + ret.bytes[0] = bytes[0]; + ret.bytes[1] = bytes[1]; + ret.bytes[2] = bytes[2]; + ret.bytes[3] = bytes[3]; + ret.bytes[4] = bytes[4]; + ret.bytes[5] = bytes[5]; +#endif + + return ret.i; +} + +static __always_inline int mac_src_parse(struct xdp_md *ctx, __u64 *mac) +{ + __u64 len, *usage; + + void *data_end = (void *)(long)ctx->data_end; + struct ethhdr *eth = (void *)(long)ctx->data; + + if ((void *) (eth + 1) > data_end) + return -1; + + if (eth->h_proto != bpf_htons(ETH_P_IP) && + eth->h_proto != bpf_htons(ETH_P_IPV6)) { + return -1; + } + + *mac = nchar6_to_u64(eth->h_source); + return 0; +} + +SEC("xdp") +int mac_filter(struct xdp_md *ctx) +{ + __u64 mac; + int ret, *blocked; + + ret = mac_src_parse(ctx, &mac); + if (ret < 0) + return XDP_PASS; + + blocked = bpf_map_lookup_elem(&mac_blacklist_map, &mac); + if (blocked) + return XDP_DROP; + + return XDP_PASS; +} -- cgit v1.2.3