Skip to content

Commit bde2a9e

Browse files
committed
Renames & cleanups
1 parent b0b80ef commit bde2a9e

6 files changed

Lines changed: 108 additions & 94 deletions

File tree

‎src/bpf/egress.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ int egress_handler(struct __sk_buff* skb) {
6565
__u32 log_verbosity = *(__u32*)try_p_shot(bpf_map_lookup_elem(&mimic_settings, &vkey));
6666

6767
struct conn_tuple conn_key = gen_conn_key(QUARTET_UDP, false);
68-
log_quartet(log_verbosity, LOG_LEVEL_DEBUG, false, LOG_TYPE_MATCHED, conn_key);
68+
log_conn(log_verbosity, LOG_LEVEL_DEBUG, false, LOG_TYPE_MATCHED, &conn_key);
6969
struct connection* conn = try_p_shot(get_conn(&conn_key));
7070

7171
struct udphdr old_udphdr = *udp;
@@ -97,7 +97,7 @@ int egress_handler(struct __sk_buff* skb) {
9797
break;
9898
}
9999
bpf_spin_unlock(&conn->lock);
100-
send_ctrl_packet(conn_key, true, false, false, seq, ack_seq);
100+
send_ctrl_packet(&conn_key, SYN, seq, ack_seq);
101101
// TODO: store packet in userspace buffer and send them after establishing
102102
return TC_ACT_STOLEN;
103103
}

‎src/bpf/ingress.c‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int ingress_handler(struct xdp_md* xdp) {
7878
__u32 log_verbosity = *(__u32*)try_p_drop(bpf_map_lookup_elem(&mimic_settings, &vkey));
7979

8080
struct conn_tuple conn_key = gen_conn_key(QUARTET_TCP, true);
81-
log_quartet(log_verbosity, LOG_LEVEL_DEBUG, true, LOG_TYPE_MATCHED, conn_key);
81+
log_conn(log_verbosity, LOG_LEVEL_DEBUG, true, LOG_TYPE_MATCHED, &conn_key);
8282
struct connection* conn = bpf_map_lookup_elem(&mimic_conns, &conn_key);
8383

8484
// TODO: verify checksum
@@ -99,9 +99,9 @@ int ingress_handler(struct xdp_md* xdp) {
9999
}
100100
// Drop the RST packet no matter if it is generated from Mimic or the peer's OS, since there are
101101
// no good ways to tell them apart.
102-
log_quartet(log_verbosity, LOG_LEVEL_WARN, true, LOG_TYPE_RST, conn_key);
102+
log_conn(log_verbosity, LOG_LEVEL_WARN, true, LOG_TYPE_RST, &conn_key);
103103
if (rst_result == RST_DESTROYED) {
104-
log_quartet(log_verbosity, LOG_LEVEL_WARN, true, LOG_TYPE_CONN_DESTROY, conn_key);
104+
log_conn(log_verbosity, LOG_LEVEL_WARN, true, LOG_TYPE_CONN_DESTROY, &conn_key);
105105
}
106106
return XDP_DROP;
107107
}
@@ -170,13 +170,15 @@ int ingress_handler(struct xdp_md* xdp) {
170170
bpf_spin_unlock(&conn->lock);
171171

172172
if (newly_estab) {
173-
log_quartet(log_verbosity, LOG_LEVEL_INFO, true, LOG_TYPE_CONN_ESTABLISH, conn_key);
173+
log_conn(log_verbosity, LOG_LEVEL_INFO, true, LOG_TYPE_CONN_ESTABLISH, &conn_key);
174174
}
175175
log_tcp(log_verbosity, LOG_LEVEL_TRACE, true, LOG_TYPE_TCP_PKT, 0, ntohl(tcp->seq), ntohl(tcp->ack_seq));
176176
log_tcp(log_verbosity, LOG_LEVEL_TRACE, true, LOG_TYPE_STATE, state, seq, ack_seq);
177177

178178
if (rst) bpf_map_delete_elem(&mimic_conns, &conn_key);
179-
if (will_send_ctrl_packet) send_ctrl_packet(conn_key, syn, ack, rst, seq, ack_seq);
179+
if (will_send_ctrl_packet) {
180+
send_ctrl_packet(&conn_key, (syn ? SYN : 0) | (ack ? ACK : 0) | (rst ? RST : 0), seq, ack_seq);
181+
}
180182
if (will_drop) return XDP_DROP;
181183

182184
__be32 ipv4_saddr = 0, ipv4_daddr = 0;

‎src/bpf/mimic.c‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,62 @@ struct mimic_conns_map mimic_conns SEC(".maps");
99
struct mimic_settings_map mimic_settings SEC(".maps");
1010
struct mimic_rb_map mimic_rb SEC(".maps");
1111

12+
bool matches_whitelist(QUARTET_DEF, bool ingress) {
13+
struct pkt_filter local = {.origin = ORIGIN_LOCAL}, remote = {.origin = ORIGIN_REMOTE};
14+
if (udp) {
15+
local.port = udp->source;
16+
remote.port = udp->dest;
17+
} else if (tcp) {
18+
local.port = tcp->source;
19+
remote.port = tcp->dest;
20+
}
21+
if (ipv4) {
22+
local.protocol = remote.protocol = PROTO_IPV4;
23+
local.ip.v4 = ipv4->saddr;
24+
remote.ip.v4 = ipv4->daddr;
25+
} else if (ipv6) {
26+
local.protocol = remote.protocol = PROTO_IPV6;
27+
local.ip.v6 = ipv6->saddr;
28+
remote.ip.v6 = ipv6->daddr;
29+
}
30+
if (ingress) {
31+
struct pkt_filter t = local;
32+
local = remote;
33+
remote = t;
34+
local.origin = ORIGIN_LOCAL;
35+
remote.origin = ORIGIN_REMOTE;
36+
}
37+
return bpf_map_lookup_elem(&mimic_whitelist, &local) || bpf_map_lookup_elem(&mimic_whitelist, &remote);
38+
}
39+
40+
int log_any(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type, union log_info* info) {
41+
if (log_verbosity < level || !info) return -1;
42+
struct rb_item* item = bpf_ringbuf_reserve(&mimic_rb, sizeof(*item), 0);
43+
if (!item) return -1;
44+
item->type = RB_ITEM_LOG_EVENT;
45+
item->log_event.level = level;
46+
item->log_event.type = type;
47+
item->log_event.ingress = ingress;
48+
item->log_event.info = *info;
49+
bpf_ringbuf_submit(item, 0);
50+
return 0;
51+
}
52+
53+
int send_ctrl_packet(struct conn_tuple* conn, __u32 flags, __u32 seq, __u32 ack_seq) {
54+
if (!conn) return -1;
55+
struct rb_item* item = bpf_ringbuf_reserve(&mimic_rb, sizeof(*item), 0);
56+
if (!item) return -1;
57+
item->type = RB_ITEM_SEND_OPTIONS;
58+
item->send_options = (struct send_options){
59+
.conn = *conn,
60+
.syn = flags & SYN,
61+
.ack = flags & ACK,
62+
.rst = flags & RST,
63+
.seq = seq,
64+
.ack_seq = ack_seq,
65+
};
66+
bpf_ringbuf_submit(item, 0);
67+
return 0;
68+
}
69+
1270
char _license[] SEC("license") = "GPL";

‎src/bpf/mimic.h‎

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -49,42 +49,16 @@ struct ipv6_ph_part {
4949
__u8 nexthdr;
5050
} __attribute__((packed));
5151

52-
struct sk_buff* mimic_inspect_skb(struct __sk_buff*) __ksym;
53-
int mimic_change_csum_offset(struct __sk_buff*, __u16) __ksym;
52+
struct sk_buff* mimic_inspect_skb(struct __sk_buff* skb) __ksym;
53+
int mimic_change_csum_offset(struct __sk_buff* skb, __u16 protocol) __ksym;
5454

5555
// clang-format off
5656
#define QUARTET_DEF struct iphdr* ipv4, struct ipv6hdr* ipv6, struct udphdr* udp, struct tcphdr* tcp
5757
#define QUARTET_UDP ipv4, ipv6, udp, NULL
5858
#define QUARTET_TCP ipv4, ipv6, NULL, tcp
5959
// clang-format on
6060

61-
static inline bool matches_whitelist(QUARTET_DEF, bool ingress) {
62-
struct pkt_filter local = {.origin = ORIGIN_LOCAL}, remote = {.origin = ORIGIN_REMOTE};
63-
if (udp) {
64-
local.port = udp->source;
65-
remote.port = udp->dest;
66-
} else if (tcp) {
67-
local.port = tcp->source;
68-
remote.port = tcp->dest;
69-
}
70-
if (ipv4) {
71-
local.protocol = remote.protocol = PROTO_IPV4;
72-
local.ip.v4 = ipv4->saddr;
73-
remote.ip.v4 = ipv4->daddr;
74-
} else if (ipv6) {
75-
local.protocol = remote.protocol = PROTO_IPV6;
76-
local.ip.v6 = ipv6->saddr;
77-
remote.ip.v6 = ipv6->daddr;
78-
}
79-
if (ingress) {
80-
struct pkt_filter t = local;
81-
local = remote;
82-
remote = t;
83-
local.origin = ORIGIN_LOCAL;
84-
remote.origin = ORIGIN_REMOTE;
85-
}
86-
return bpf_map_lookup_elem(&mimic_whitelist, &local) || bpf_map_lookup_elem(&mimic_whitelist, &remote);
87-
}
61+
bool matches_whitelist(QUARTET_DEF, bool ingress);
8862

8963
static inline struct conn_tuple gen_conn_key(QUARTET_DEF, bool ingress) {
9064
struct conn_tuple key = {};
@@ -115,62 +89,42 @@ static inline struct conn_tuple gen_conn_key(QUARTET_DEF, bool ingress) {
11589
return key;
11690
}
11791

118-
static inline struct connection* get_conn(struct conn_tuple* conn_key) {
119-
struct connection* conn = bpf_map_lookup_elem(&mimic_conns, conn_key);
92+
static inline struct connection* get_conn(struct conn_tuple* key) {
93+
struct connection* conn = bpf_map_lookup_elem(&mimic_conns, key);
12094
if (!conn) {
12195
struct connection conn_value = {};
122-
if (bpf_map_update_elem(&mimic_conns, conn_key, &conn_value, BPF_ANY)) return NULL;
123-
conn = bpf_map_lookup_elem(&mimic_conns, conn_key);
96+
if (bpf_map_update_elem(&mimic_conns, key, &conn_value, BPF_ANY)) return NULL;
97+
conn = bpf_map_lookup_elem(&mimic_conns, key);
12498
if (!conn) return NULL;
12599
}
126100
return conn;
127101
}
128102

129-
static inline void log_any(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type,
130-
union log_info info) {
131-
if (log_verbosity < level) return;
132-
struct rb_item* item = bpf_ringbuf_reserve(&mimic_rb, sizeof(*item), 0);
133-
if (!item) return;
134-
item->type = RB_ITEM_LOG_EVENT;
135-
item->log_event.level = level;
136-
item->log_event.type = type;
137-
item->log_event.ingress = ingress;
138-
item->log_event.info = info;
139-
bpf_ringbuf_submit(item, 0);
140-
}
103+
int log_any(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type, union log_info* info);
141104

142-
static inline void log_quartet(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type,
143-
struct conn_tuple quartet) {
144-
log_any(log_verbosity, level, ingress, type, (union log_info){.quartet = quartet});
105+
static inline int log_conn(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type,
106+
struct conn_tuple* conn) {
107+
if (!conn) return -1;
108+
return log_any(log_verbosity, level, ingress, type, &(union log_info){.conn = *conn});
145109
}
146110

147-
static __always_inline void log_tcp(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type,
148-
enum conn_state state, __u32 seq, __u32 ack_seq) {
149-
log_any(log_verbosity, level, ingress, type,
150-
(union log_info){.tcp = {.state = state, .seq = seq, .ack_seq = ack_seq}});
111+
static inline int log_tcp(__u32 log_verbosity, enum log_level level, bool ingress, enum log_type type,
112+
enum conn_state state, __u32 seq, __u32 ack_seq) {
113+
return log_any(log_verbosity, level, ingress, type,
114+
&(union log_info){.tcp = {.state = state, .seq = seq, .ack_seq = ack_seq}});
151115
}
152116

153-
static __always_inline void send_ctrl_packet(struct conn_tuple c, bool syn, bool ack, bool rst, __u32 seq,
154-
__u32 ack_seq) {
155-
struct rb_item* item = bpf_ringbuf_reserve(&mimic_rb, sizeof(*item), 0);
156-
if (!item) return;
157-
item->type = RB_ITEM_SEND_OPTIONS;
158-
item->send_options = (struct send_options){
159-
.c = c,
160-
.syn = syn,
161-
.ack = ack,
162-
.rst = rst,
163-
.seq = seq,
164-
.ack_seq = ack_seq,
165-
};
166-
bpf_ringbuf_submit(item, 0);
167-
}
117+
#define SYN 1
118+
#define ACK 1 << 1
119+
#define RST 1 << 2
120+
121+
int send_ctrl_packet(struct conn_tuple* conn, __u32 flags, __u32 seq, __u32 ack_seq);
168122

169123
#define _log_a(_0, _1, _2, _3, N, ...) _##N
170-
#define _log_b_0() (u64[0]){}, 0
171-
#define _log_b_1(_a) (u64[1]){(u64)(_a)}, sizeof(u64)
172-
#define _log_b_2(_a, _b) (u64[2]){(u64)(_a), (u64)(_b)}, 2 * sizeof(u64)
173-
#define _log_b_3(_a, _b, _c) (u64[2]){(u64)(_a), (u64)(_b), (u64)(_c)}, 3 * sizeof(u64)
124+
#define _log_b_0() (__u64[0]){}, 0
125+
#define _log_b_1(_a) (__u64[1]){(__u64)(_a)}, sizeof(__u64)
126+
#define _log_b_2(_a, _b) (__u64[2]){(__u64)(_a), (__u64)(_b)}, 2 * sizeof(__u64)
127+
#define _log_b_3(_a, _b, _c) (__u64[2]){(__u64)(_a), (__u64)(_b), (__u64)(_c)}, 3 * sizeof(__u64)
174128
#define _log_c(...) _log_a(__VA_ARGS__, 3, 2, 1, 0)
175129
#define _log_d(_x, _y) _x##_y
176130
#define _log_e(_x, _y) _log_d(_x, _y)

‎src/run.c‎

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ static int handle_log_event(struct log_event* e) {
157157
break;
158158
default: {
159159
char from[IP_PORT_MAX_LEN], to[IP_PORT_MAX_LEN];
160-
struct conn_tuple* pkt = &e->info.quartet;
160+
struct conn_tuple* pkt = &e->info.conn;
161161
// invert again, since conn_tuple passed to it is already inverted
162162
if (e->ingress) {
163163
ip_port_fmt(pkt->protocol, pkt->local, pkt->local_port, to);
@@ -174,32 +174,32 @@ static int handle_log_event(struct log_event* e) {
174174
}
175175

176176
static inline int send_ctrl_packet(struct send_options* s) {
177-
_cleanup_fd int sk = try(socket(s->c.protocol, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_TCP));
177+
_cleanup_fd int sk = try(socket(s->conn.protocol, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_TCP));
178178
__u32 csum = 0;
179179
struct sockaddr_storage saddr = {}, daddr = {};
180-
if (s->c.protocol == AF_INET) {
181-
__u32 local = s->c.local.v4, remote = s->c.remote.v4;
180+
if (s->conn.protocol == AF_INET) {
181+
__u32 local = s->conn.local.v4, remote = s->conn.remote.v4;
182182
*(struct sockaddr_in*)&saddr = (struct sockaddr_in){.sin_family = AF_INET, .sin_addr = local, .sin_port = 0};
183183
*(struct sockaddr_in*)&daddr = (struct sockaddr_in){.sin_family = AF_INET, .sin_addr = remote, .sin_port = 0};
184184
update_csum_ul(&csum, ntohl(local));
185185
update_csum_ul(&csum, ntohl(remote));
186186
} else {
187187
*(struct sockaddr_in6*)&saddr =
188-
(struct sockaddr_in6){.sin6_family = AF_INET6, .sin6_addr = s->c.local.v6, .sin6_port = 0};
188+
(struct sockaddr_in6){.sin6_family = AF_INET6, .sin6_addr = s->conn.local.v6, .sin6_port = 0};
189189
*(struct sockaddr_in6*)&daddr =
190-
(struct sockaddr_in6){.sin6_family = AF_INET6, .sin6_addr = s->c.remote.v6, .sin6_port = 0};
190+
(struct sockaddr_in6){.sin6_family = AF_INET6, .sin6_addr = s->conn.remote.v6, .sin6_port = 0};
191191
for (int i = 0; i < 8; i++) {
192-
update_csum(&csum, ntohs(s->c.local.v6.s6_addr16[i]));
193-
update_csum(&csum, ntohs(s->c.remote.v6.s6_addr16[i]));
192+
update_csum(&csum, ntohs(s->conn.local.v6.s6_addr16[i]));
193+
update_csum(&csum, ntohs(s->conn.remote.v6.s6_addr16[i]));
194194
}
195195
}
196196
update_csum(&csum, IPPROTO_TCP);
197197
update_csum(&csum, sizeof(struct tcphdr));
198198
try(bind(sk, (struct sockaddr*)&saddr, sizeof(saddr)), _("failed to bind: %s"), strerror(-_ret));
199199

200200
struct tcphdr tcp = {
201-
.source = s->c.local_port,
202-
.dest = s->c.remote_port,
201+
.source = s->conn.local_port,
202+
.dest = s->conn.remote_port,
203203
.seq = htonl(s->seq),
204204
.ack_seq = htonl(s->ack_seq),
205205
.doff = 5,

‎src/shared/misc.h‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ enum rst_result {
112112
};
113113

114114
struct send_options {
115-
struct conn_tuple c;
115+
struct conn_tuple conn;
116116
bool syn, ack, rst;
117117
__u32 seq, ack_seq;
118118
};
@@ -134,20 +134,20 @@ struct log_event {
134134
} level;
135135
bool ingress;
136136
enum log_type {
137-
LOG_TYPE_MATCHED, // quartet
138-
LOG_TYPE_CONN_ESTABLISH, // quartet
137+
LOG_TYPE_MATCHED, // conn
138+
LOG_TYPE_CONN_ESTABLISH, // conn
139139
LOG_TYPE_TCP_PKT, // tcp (ignore state)
140140
LOG_TYPE_STATE, // tcp
141-
LOG_TYPE_RST, // quartet
142-
LOG_TYPE_CONN_DESTROY, // quartet
141+
LOG_TYPE_RST, // conn
142+
LOG_TYPE_CONN_DESTROY, // conn
143143
LOG_TYPE_QUICK_MSG, // msg
144144
} type;
145145
union log_info {
146146
struct fake_tcp_info {
147147
enum conn_state state;
148148
__u32 seq, ack_seq;
149149
} tcp;
150-
struct conn_tuple quartet;
150+
struct conn_tuple conn;
151151
char msg[40];
152152
} info;
153153
};

0 commit comments

Comments
 (0)