#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <bpf/bpf_endian.h>
#ifndef __BEEPER_H__
#define __BEEPER_H__
char LICENSE[] SEC("license") = "GPL";
#define MAX_BYTES 0x7FFF
#define MAX_MATCHES 32
#define MAX_MATCH_MASK 31
#ifndef bpf_clamp_uminmax
#define bpf_clamp_uminmax(VAR, UMIN, UMAX) \
asm volatile("if %0 >= %[min] goto +2\n" \
"%0 = %[min]\n" \
"goto +2\n" \
"if %0 <= %[max] goto +1\n" \
"%0 = %[max]\n" \
: "+r"(VAR) \
: [min] "i"(UMIN), [max] "i"(UMAX))
#endif
struct ip4_addr {
u32 ip4;
u32 port;
};
struct ip4_conn {
struct ip4_addr local;
struct ip4_addr remote;
};
struct hdr_match {
u16 idx;
u16 len;
bool in_msg;
bool huff;
};
struct hdr_str {
u32 len;
const u8* ptr;
};
struct parse_res {
struct hdr_match ms[MAX_MATCHES];
};
struct h2_frame {
u32 sid;
u8 type;
u8 flags;
u32 dt_count_before;
u32 dt_count;
};
#define BEEPER_H2_FIELD_MAXLEN 128
struct header_field {
u8 key[BEEPER_H2_FIELD_MAXLEN];
u8 key_len;
u8 val[BEEPER_H2_FIELD_MAXLEN];
u8 val_len;
u8 key_huff;
u8 val_huff;
};
struct trans {
u16 state;
u16 action;
};
#ifndef __sink
#define __sink(expr) asm volatile("" : "+g"(expr))
#endif
#define BEEPER_H1_PARSE_MSG(name) \
__noinline int name(struct sk_msg_md *msg, struct parse_res *pres __arg_nonnull) { \
int ret = -1; \
\
__sink(msg); \
__sink(pres); \
__sink(ret); \
\
\
\
bpf_msg_pull_data(msg, 0, msg->size, 0); \
\
return ret; \
}
#define BEEPER_H1_PARSE_SKB(name) \
__noinline int name(struct __sk_buff *skb, struct parse_res *pres __arg_nonnull, \
u16 *null_prefix) { \
int ret = -1; \
\
__sink(skb); \
__sink(pres); \
__sink(null_prefix); \
__sink(ret); \
\
\
\
bpf_skb_pull_data(skb, skb->len); \
\
return ret; \
}
#define BEEPER_H1_PARSE_BUF(name) \
__noinline int name(const struct bpf_dynptr *buf_ptr, u32 len, \
struct parse_res *pres __arg_nonnull, u16 *null_prefix) { \
int ret = -1; \
\
__sink(buf_ptr); \
__sink(len); \
__sink(pres); \
__sink(null_prefix); \
__sink(ret); \
\
return ret; \
}
#define BEEPER_H2_PARSE_MSG(name) \
__noinline int name(struct sk_msg_md *msg, struct parse_res *pres __arg_nonnull, \
struct h2_frame *frame __arg_nonnull) { \
int ret = -1; \
\
__sink(msg); \
__sink(pres); \
__sink(frame); \
__sink(ret); \
\
\
\
bpf_msg_pull_data(msg, 0, msg->size, 0); \
\
return ret; \
}
#define BEEPER_H2_PARSE_SKB(name) \
__noinline int name(struct __sk_buff *skb, struct parse_res *pres __arg_nonnull, \
struct h2_frame *frame __arg_nonnull, u16 *null_prefix) { \
int ret = -1; \
\
__sink(skb); \
__sink(pres); \
__sink(frame); \
__sink(null_prefix); \
__sink(ret); \
\
\
\
bpf_skb_pull_data(skb, skb->len); \
\
return ret; \
}
#define BEEPER_H2_PARSE_BUF(name) \
__noinline int name(const struct bpf_dynptr *buf_ptr, struct ip4_conn *conn, \
struct parse_res *pres __arg_nonnull, \
struct h2_frame *frame __arg_nonnull, u16 *null_prefix) { \
int ret = -1; \
\
__sink(buf_ptr); \
__sink(conn); \
__sink(pres); \
__sink(frame); \
__sink(null_prefix); \
__sink(ret); \
\
return ret; \
}
#define BEEPER_MATCHED(name) \
__noinline bool name(const struct sk_msg_md *msg, const struct parse_res *pres __arg_nonnull, \
u8 idx) { \
bool ret = false; \
\
__sink(msg); \
__sink(pres); \
__sink(idx); \
__sink(ret); \
\
return ret; \
}
#define BEEPER_EXTRACT_MATCH(name) \
__noinline int name(const struct sk_msg_md *msg, const struct parse_res *pres __arg_nonnull, \
u8 idx, struct hdr_str *str __arg_nonnull) { \
int ret = -1; \
\
__sink(msg); \
__sink(pres); \
__sink(idx); \
__sink(str); \
__sink(ret); \
\
return ret; \
}
#define BEEPER_H2_GET_DT_ENTRY(name) \
__noinline int name(const struct ip4_conn *conn __arg_nonnull, u32 idx, \
struct header_field *out __arg_nonnull) { \
int ret = -1; \
\
__sink(conn); \
__sink(idx); \
__sink(out); \
__sink(ret); \
\
return ret; \
}
#endif