Skip to content

Commit

Permalink
bpf - strongly-typed map definitions, use __inline instead of __attri…
Browse files Browse the repository at this point in the history
…bute__...

Also removed ppc and s390x arches, added arm.
  • Loading branch information
ti-mo committed Mar 31, 2020
1 parent 201329f commit e73cf57
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 68 deletions.
62 changes: 24 additions & 38 deletions bpf/acct.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ struct bpf_map_def SEC("maps/perf_acct_end") perf_acct_end = {
// the flow may send its next update event to userspace.
struct bpf_map_def SEC("maps/flow_cooldown") flow_cooldown = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(int),
.value_size = sizeof(__u64),
.key_size = sizeof(u64),
.value_size = sizeof(u64),
.max_entries = 512000,
};

// Hash that holds a timestamp per flow indicating when the flow
// was first seen. Used to implement age-based event rate limiting.
struct bpf_map_def SEC("maps/flow_origin") flow_origin = {
.type = BPF_MAP_TYPE_HASH,
.key_size = sizeof(int),
.value_size = sizeof(__u64),
.key_size = sizeof(struct nf_conn *),
.value_size = sizeof(u64),
.max_entries = 512000,
};

Expand All @@ -75,17 +75,17 @@ struct bpf_map_def SEC("maps/flow_origin") flow_origin = {
// reads + deletes it in the kretprobe.
struct bpf_map_def SEC("maps/currct") currct = {
.type = BPF_MAP_TYPE_PERCPU_HASH,
.key_size = sizeof(int),
.value_size = sizeof(void *),
.key_size = sizeof(u32),
.value_size = sizeof(struct nf_conn *),
.max_entries = 2048,
};

// Map holding configuration values for this BPF program.
// Indexed by enum o_config.
struct bpf_map_def SEC("maps/config") config = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(void *),
.key_size = sizeof(enum o_config),
.value_size = sizeof(u64),
.max_entries = ConfigMax,
};

Expand All @@ -94,15 +94,14 @@ struct bpf_map_def SEC("maps/config") config = {
// Indexed by enum o_config_ratecurve.
struct bpf_map_def SEC("maps/config_ratecurve") config_ratecurve = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(void *),
.key_size = sizeof(enum o_config_ratecurve),
.value_size = sizeof(u64),
.max_entries = ConfigCurveMax,
};

// probe_ready reads the `config` array map for the Ready flag.
// It returns true if the Ready flag is set to 0x90 (go).
__attribute__((always_inline))
static bool probe_ready() {
static __inline bool probe_ready() {

u64 oc_ready = ConfigReady;
u64 *rp = bpf_map_lookup_elem(&config, &oc_ready);
Expand All @@ -112,8 +111,7 @@ static bool probe_ready() {

// get_acct_ext gets a reference to the nf_conn's accounting extension.
// Returns non-zero on error.
__attribute__((always_inline))
static int get_acct_ext(struct nf_conn_acct **acct_ext, struct nf_conn *ct) {
static __inline int get_acct_ext(struct nf_conn_acct **acct_ext, struct nf_conn *ct) {

// Check if accounting extension is enabled and initialized
// for this connection. Important because the acct codepath
Expand All @@ -139,8 +137,7 @@ static int get_acct_ext(struct nf_conn_acct **acct_ext, struct nf_conn *ct) {

// get_ts_ext gets a reference to the nf_conn's timestamp extension.
// Returns non-zero on error.
__attribute__((always_inline))
static int get_ts_ext(struct nf_conn_tstamp **ts_ext, struct nf_conn *ct) {
static __inline int get_ts_ext(struct nf_conn_tstamp **ts_ext, struct nf_conn *ct) {

struct nf_ct_ext *ct_ext;
bpf_probe_read(&ct_ext, sizeof(ct_ext), &ct->ext);
Expand All @@ -161,8 +158,7 @@ static int get_ts_ext(struct nf_conn_tstamp **ts_ext, struct nf_conn *ct) {

// extract_counters extracts accounting info from an nf_conn into acct_event_t.
// Returns 0 if acct extension was present in ct.
__attribute__((always_inline))
static int extract_counters(struct acct_event_t *data, struct nf_conn *ct) {
static __inline int extract_counters(struct acct_event_t *data, struct nf_conn *ct) {

struct nf_conn_acct *acct_ext = 0;
if (get_acct_ext(&acct_ext, ct))
Expand All @@ -182,8 +178,7 @@ static int extract_counters(struct acct_event_t *data, struct nf_conn *ct) {

// extract_tstamp extracts the start timestamp of nf_conn_tstamp inside an nf_conn
// into acct_event_t. Returns 0 if timestamp extension was present in ct.
__attribute__((always_inline))
static int extract_tstamp(struct acct_event_t *data, struct nf_conn *ct) {
static __inline int extract_tstamp(struct acct_event_t *data, struct nf_conn *ct) {

struct nf_conn_tstamp *ts_ext = 0;
if (get_ts_ext(&ts_ext, ct))
Expand All @@ -196,8 +191,7 @@ static int extract_tstamp(struct acct_event_t *data, struct nf_conn *ct) {

// extract_tuple extracts tuple information (proto, src/dest ip and port) of an nf_conn
// into an acct_event_t.
__attribute__((always_inline))
static void extract_tuple(struct acct_event_t *data, struct nf_conn *ct) {
static __inline void extract_tuple(struct acct_event_t *data, struct nf_conn *ct) {

struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
bpf_probe_read(&tuplehash, sizeof(tuplehash), &ct->tuplehash);
Expand All @@ -213,8 +207,7 @@ static void extract_tuple(struct acct_event_t *data, struct nf_conn *ct) {
}

// extract_netns extracts the nf_conn's network namespace inode number into an acct_event_t.
__attribute__((always_inline))
static void extract_netns(struct acct_event_t *data, struct nf_conn *ct) {
static __inline void extract_netns(struct acct_event_t *data, struct nf_conn *ct) {

// Obtain reference to network namespace.
// Warning: ct_net is a possible_net_t with a single member,
Expand All @@ -231,8 +224,7 @@ static void extract_netns(struct acct_event_t *data, struct nf_conn *ct) {

// curve_get returns an entry from the curve array as a signed 64-bit integer.
// Returns negative if an entry was not found at the requested index.
__attribute__((always_inline))
static s64 curve_get(enum o_config_ratecurve curve_enum) {
static __inline s64 curve_get(enum o_config_ratecurve curve_enum) {

int offset = curve_enum;
u64 *confp = bpf_map_lookup_elem(&config_ratecurve, &offset);
Expand All @@ -243,8 +235,7 @@ static s64 curve_get(enum o_config_ratecurve curve_enum) {
}

// flow_cooldown_expired returns true if the flow's cooldown period is over.
__attribute__((always_inline))
static bool flow_cooldown_expired(struct nf_conn *ct, u64 ts) {
static __inline bool flow_cooldown_expired(struct nf_conn *ct, u64 ts) {

// Look up the flow's cooldown expiration time.
u64 *nextp = bpf_map_lookup_elem(&flow_cooldown, &ct);
Expand All @@ -262,8 +253,7 @@ static bool flow_cooldown_expired(struct nf_conn *ct, u64 ts) {
// the second age threshold (curve1age), to protect against event storms
// when the program is restarted.
// This call is write-once due to BPF_NOEXIST.
__attribute__((always_inline))
static u64 flow_initialize_origin(struct nf_conn *ct, u64 ts, u64 pkts_total) {
static __inline u64 flow_initialize_origin(struct nf_conn *ct, u64 ts, u64 pkts_total) {

u64 origin = ts;

Expand Down Expand Up @@ -293,8 +283,7 @@ static u64 flow_initialize_origin(struct nf_conn *ct, u64 ts, u64 pkts_total) {
// hashmap. The time elapsed between the origin and the given
// ts is returned. If there is no first-seen timestamp for the
// flow, returns a zero value.
__attribute__((always_inline))
static u64 flow_get_age(struct nf_conn *ct, u64 ts) {
static __inline u64 flow_get_age(struct nf_conn *ct, u64 ts) {

// Initialize origin to the current timestamp so a lookup miss
// causes a 0ns age to be returned. (new or unknown flows)
Expand All @@ -311,8 +300,7 @@ static u64 flow_get_age(struct nf_conn *ct, u64 ts) {
// for the flow during the current event.
// Returns negative if the flow is younger than the minimum age threshold,
// or if an internal curve lookup error occurred.
__attribute__((always_inline))
static s64 flow_get_interval(struct nf_conn *ct, u64 ts) {
static __inline s64 flow_get_interval(struct nf_conn *ct, u64 ts) {

// Always returns a positive or 0 value.
u64 age = flow_get_age(ct, ts);
Expand Down Expand Up @@ -340,8 +328,7 @@ static s64 flow_get_interval(struct nf_conn *ct, u64 ts) {
return curve_get(ConfigCurve2Interval);
}

__attribute__((always_inline))
static u64 flow_set_cooldown(struct nf_conn *ct, u64 ts) {
static __inline u64 flow_set_cooldown(struct nf_conn *ct, u64 ts) {

// Get the update interval for this flow.
// A negative result indicates that the event should be dropped
Expand All @@ -359,8 +346,7 @@ static u64 flow_set_cooldown(struct nf_conn *ct, u64 ts) {
}

// flow_cleanup removes all possible map entries related to the connection.
__attribute__((always_inline))
static void flow_cleanup(struct nf_conn *ct) {
static __inline void flow_cleanup(struct nf_conn *ct) {
bpf_map_delete_elem(&flow_cooldown, &ct);
bpf_map_delete_elem(&flow_origin, &ct);
}
Expand Down
41 changes: 12 additions & 29 deletions bpf/bpf_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,18 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->ip)

#elif defined(__s390x__)

#define PT_REGS_PARM1(x) ((x)->gprs[2])
#define PT_REGS_PARM2(x) ((x)->gprs[3])
#define PT_REGS_PARM3(x) ((x)->gprs[4])
#define PT_REGS_PARM4(x) ((x)->gprs[5])
#define PT_REGS_PARM5(x) ((x)->gprs[6])
#define PT_REGS_RET(x) ((x)->gprs[14])
#define PT_REGS_FP(x) ((x)->gprs[11]) /* Works only with CONFIG_FRAME_POINTER */
#define PT_REGS_RC(x) ((x)->gprs[2])
#define PT_REGS_SP(x) ((x)->gprs[15])
#define PT_REGS_IP(x) ((x)->ip)
#elif defined(__arm__)

#define PT_REGS_PARM1(x) ((x)->uregs[0])
#define PT_REGS_PARM2(x) ((x)->uregs[1])
#define PT_REGS_PARM3(x) ((x)->uregs[2])
#define PT_REGS_PARM4(x) ((x)->uregs[3])
#define PT_REGS_PARM5(x) ((x)->uregs[4])
#define PT_REGS_RET(x) ((x)->uregs[14])
#define PT_REGS_FP(x) ((x)->uregs[11]) /* Works only with CONFIG_FRAME_POINTER */
#define PT_REGS_RC(x) ((x)->uregs[0])
#define PT_REGS_SP(x) ((x)->uregs[13])
#define PT_REGS_IP(x) ((x)->uregs[12])

#elif defined(__aarch64__)

Expand All @@ -133,28 +133,11 @@ static int (*bpf_l4_csum_replace)(void *ctx, int off, int from, int to, int flag
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->pc)

#elif defined(__powerpc__)

#define PT_REGS_PARM1(x) ((x)->gpr[3])
#define PT_REGS_PARM2(x) ((x)->gpr[4])
#define PT_REGS_PARM3(x) ((x)->gpr[5])
#define PT_REGS_PARM4(x) ((x)->gpr[6])
#define PT_REGS_PARM5(x) ((x)->gpr[7])
#define PT_REGS_RC(x) ((x)->gpr[3])
#define PT_REGS_SP(x) ((x)->sp)
#define PT_REGS_IP(x) ((x)->nip)

#endif

#ifdef __powerpc__
#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; })
#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
#else
#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ \
bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ \
bpf_probe_read(&(ip), sizeof(ip), \
(void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
#endif

#endif
Loading

0 comments on commit e73cf57

Please sign in to comment.