Skip to content

Instantly share code, notes, and snippets.

@tgraf
Created June 18, 2019 13:35
Show Gist options
  • Save tgraf/a9e9f5e7c3749eb3e825433bcd5cc403 to your computer and use it in GitHub Desktop.
Save tgraf/a9e9f5e7c3749eb3e825433bcd5cc403 to your computer and use it in GitHub Desktop.
static __always_inline void *xdp_data(const struct xdp_md *xdp)
{
return (void *)(unsigned long)xdp->data;
}
static __always_inline void *xdp_data_end(const struct xdp_md *xdp)
{
return (void *)(unsigned long)xdp->data_end;
}
static __always_inline bool xdp_no_room(const void *needed, const void *limit)
{
return needed > limit;
}
struct lpm_v4_key {
struct bpf_lpm_trie_key lpm;
__u8 addr[4];
};
struct lpm_val {
__u32 ref_count;
};
[...]
static __always_inline int check_v4(struct xdp_md *xdp)
{
void *data_end = xdp_data_end(xdp);
void *data = xdp_data(xdp);
struct iphdr *ipv4_hdr = data + sizeof(struct ethhdr);
struct lpm_v4_key pfx;
__u16 dest_port;
if (xdp_no_room(ipv4_hdr + 1, data_end)) {
return XDP_DROP;
}
__builtin_memcpy(pfx.lpm.data, &ipv4_hdr->saddr, sizeof(pfx.addr));
pfx.lpm.prefixlen = 32;
if (map_lookup_elem(&calico_prefilter_v4, &pfx)) {
[...]
}
static __always_inline int check_prefilter(struct xdp_md *xdp)
{
void *data_end = xdp_data_end(xdp);
void *data = xdp_data(xdp);
struct ethhdr *eth = data;
__u16 proto;
if (xdp_no_room(eth + 1, data_end)) {
return XDP_DROP;
}
proto = eth->h_proto;
if (proto == bpf_htons(ETH_P_IP)) {
return check_v4(xdp);
} else {
/* other traffic can continue */
return XDP_PASS;
}
}
__section("pre-filter")
int xdp_enter(struct xdp_md *xdp)
{
return check_prefilter(xdp);
}
char ____license[] __section("license") = "Apache-2.0";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment