Mitigator BPF API
Functions and types programs can use to filter packets.
mitigator_bpf.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2020 BIFIT Mitigator Team <info@mitigator.ru>
3  */
4 #pragma once
5 
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #define ENTRYPOINT_SECTION "filter_v2"
11 
12 #define SECTION(name) __attribute__((section(name), used))
13 
14 #ifdef __cplusplus
15 #define STATIC_ASSERT(x) static_assert(x, "")
16 #else
17 #define STATIC_ASSERT(x) _Static_assert(x, "")
18 #endif
19 
43 #define PROGRAM_DISPLAY_ID(id) \
44  SECTION("meta.display_id") \
45  static const char _mitigator_meta_program_id[] = id;
46 
64 #define ENTRYPOINT SECTION(ENTRYPOINT_SECTION)
65 
82 #define LOCAL static inline __attribute__((always_inline))
83 
109 #if defined(__clang__)
110 #define UNROLL _Pragma("unroll")
111 #else
112 #define UNROLL
113 #endif
114 
125 #define MAX_PAYLOAD_LENGTH 1536
126 
136 #define MAX_PARAMETERS_LENGTH 1024
137 
138 #ifdef __cplusplus
139 namespace mitigator {
140 extern "C" {
141 #endif
142 
144 typedef void* Context;
145 
152 enum Result {
167 };
168 
174 typedef uint64_t Bool;
175 
181 typedef uint32_t Time;
182 
184 struct EtherAddr {
185  uint8_t u8[6];
186 };
187 
193 struct EtherHeader {
194  struct EtherAddr ether_dhost;
195  struct EtherAddr ether_shost;
196  uint16_t ether_type;
197 };
198 
207 struct VlanHeader {
208  uint16_t control;
209  uint16_t type;
210 };
211 
216 enum EtherType {
217  ETHER_TYPE_IP = 0x0800,
218  ETHER_TYPE_ARP = 0x0806,
219  ETHER_TYPE_8021Q = 0x8100,
220  ETHER_TYPE_IP6 = 0x86DD
221 };
222 
224 typedef uint32_t IpAddr;
225 
244 struct IpHeader {
245  uint32_t ip_hl : 4; /* 0 header length */
246  uint32_t ip_v : 4; /* version == 4 */
247  uint8_t ip_tos; /* 1 type of service */
248  uint16_t ip_len; /* 2-3 total length */
249  uint16_t ip_id; /* 4-5 packet ID */
250  uint16_t ip_off; /* 6-7 fragmentation offset */
251  uint8_t ip_ttl; /* 8 time to live */
252  uint8_t ip_p; /* 9 protocol ID */
253  uint16_t ip_sum; /* 10-11 header checksum */
254  uint32_t ip_src; /* 12-15 source address */
255  uint32_t ip_dst; /* 16-19 destination address */
256 };
257 
264 struct Ip6Addr {
265  uint8_t u8[16];
266 };
267 
287 struct Ip6Header {
288  uint32_t ip6_vfc; /* version, traffic class, flow label */
289  uint16_t ip6_plen; /* payload length */
290  uint8_t ip6_next; /* next header */
291  uint8_t ip6_hoplim; /* hop limit */
292  struct Ip6Addr ip6_src; /* source address */
293  struct Ip6Addr ip6_dst; /* destination address */
294 };
295 
301 enum IpProto {
307 };
308 
329 struct UdpHeader {
330  uint16_t uh_sport; /* 0-1 source port */
331  uint16_t uh_dport; /* 2-3 destination port */
332  uint16_t uh_ulen; /* 4-5 UDP length */
333  uint16_t uh_sum; /* 6-7 checksum */
334 };
335 
356 struct TcpHeader {
357  uint16_t th_sport; /* 0-1 source port */
358  uint16_t th_dport; /* 2-3 destination port */
359  uint32_t th_seq; /* 4-7 sequence number */
360  uint32_t th_ack; /* 8-11 acknowledgement number */
361  uint32_t th_flags2 : 4; /* 12 more flags */
362  uint32_t th_off : 4; /* data offset in words */
363  uint8_t th_flags; /* 13 flags */
364  uint16_t th_win; /* 14-15 window */
365  uint16_t th_sum; /* 16-17 checksum */
366  uint16_t th_urp; /* 18-19 urgent pointer */
367 };
368 
397 enum TcpFlags {
398  TCP_FLAG_FIN = 0x01,
399  TCP_FLAG_SYN = 0x02,
400  TCP_FLAG_RST = 0x04,
401  TCP_FLAG_PUSH = 0x08,
402  TCP_FLAG_ACK = 0x10,
403  TCP_FLAG_URG = 0x20,
404  TCP_FLAG_ECE = 0x40,
405  TCP_FLAG_CWR = 0x80
406 };
407 
416 enum TcpOption {
423  TCP_OPT_TIMESTAMPS = 8
424 };
425 
427 union NetAddr {
428  struct {
429  uint8_t padding[12];
430  IpAddr v4;
431  };
432  struct Ip6Addr v6;
433 };
434 
446 struct Flow {
447  union NetAddr src_ip;
448  union NetAddr dst_ip;
449  uint16_t src_port;
450  uint16_t dst_port;
451  uint32_t padding;
452 };
453 
460 void packet_flow(Context ctx, struct Flow* info);
461 
476 
488 
506 
516 
534 
547 void* packet_transport_payload(Context ctx, uint16_t* length);
548 
555 void set_packet_length(Context ctx, uint16_t length);
556 
566 void set_packet_offset(Context ctx, uint16_t offset);
567 
579 
595 
602 void set_src_blacklisted(Context ctx, Time duration);
603 
610 void set_src_whitelisted(Context ctx, Time duration);
611 
620 typedef uint64_t TableKey;
621 
627 typedef uint64_t TableValue;
628 
641 struct TableRecord {
644  uint32_t padding;
645 };
646 
652 Bool table_find(Context ctx, TableKey key, struct TableRecord* record);
653 
661 Bool table_get(Context ctx, TableKey key, struct TableRecord* record);
662 
672 
674 uint64_t table_size(Context ctx);
675 
694  bool found;
695  uint8_t reserved[3];
697 };
698 
700 #define TABLE_EX_KEY_SIZE 16
701 
703 #define TABLE_EX_VALUE_SIZE 8
704 
713 struct TableExResult
714 table_ex_find(Context ctx, const void* key, const void* key_end,
715  void* value, void* value_end);
716 
725 struct TableExResult
726 table_ex_get(Context ctx, const void* key, const void* key_end,
727  void* value, void* value_end);
728 
739 Bool table_ex_put(Context ctx, const void* key, const void* key_end,
740  const void* value, const void* value_end);
741 
743 uint64_t table_ex_size(Context ctx);
744 
746 typedef uint32_t Cookie;
747 
757 
772 Bool syncookie_check(Context ctx, uint32_t seqnum_offset, uint32_t acknum_offset);
773 
798 Cookie cookie_make(Context ctx, const struct Flow* id);
799 
821 Bool cookie_check(Context ctx, const struct Flow* id, Cookie cookie);
822 
831 const void* parameters_get(Context ctx);
832 
847 uint32_t hash_crc32_u32(uint32_t value, uint32_t init);
848 
854 uint32_t hash_crc32_u64(uint64_t value, uint32_t init);
855 
886 uint32_t hash_crc32_data(const void* data, const void* end, uint32_t init);
887 
890 
892 uint64_t rand64(void);
893 
895 LOCAL uint16_t
896 bswap16(uint16_t value) {
897  return __builtin_bswap16(value);
898 }
899 
901 LOCAL uint32_t
902 bswap32(uint32_t value) {
903  return __builtin_bswap32(value);
904 }
905 
906 #define VLAN_ID_MASK 0x0fff
907 
909 LOCAL uint16_t
910 vlan_get_id(const struct VlanHeader* vlan) {
911  return bswap16(vlan->control) & VLAN_ID_MASK;
912 }
913 
922 LOCAL void
923 vlan_set_id(struct VlanHeader* vlan, uint16_t id) {
924  uint16_t bits = vlan->control & ~bswap16(VLAN_ID_MASK);
925  vlan->control = bswap16(bswap16(bits) | id);
926 }
927 
928 STATIC_ASSERT(sizeof(struct Ip6Addr) == 16);
929 STATIC_ASSERT(sizeof(struct EtherHeader) == 14);
930 STATIC_ASSERT(sizeof(struct VlanHeader) == 4);
931 STATIC_ASSERT(sizeof(struct IpHeader) == 20);
932 STATIC_ASSERT(sizeof(struct Ip6Header) == 40);
933 STATIC_ASSERT(sizeof(struct TcpHeader) == 20);
934 STATIC_ASSERT(sizeof(struct UdpHeader) == 8);
935 STATIC_ASSERT(sizeof(struct TableExResult) == 8);
936 STATIC_ASSERT(sizeof(union NetAddr) == sizeof(struct Ip6Addr));
937 
938 #ifdef __cplusplus
939 } // extern "C"
940 } // namespace mitigator
941 #endif
LOCAL void vlan_set_id(struct VlanHeader *vlan, uint16_t id)
Set VLAN ID in 802.1q header.
Definition: mitigator_bpf.h:923
EtherType
Ethernet frame type codes.
Definition: mitigator_bpf.h:216
@ ETHER_TYPE_IP
Definition: mitigator_bpf.h:217
@ ETHER_TYPE_ARP
Definition: mitigator_bpf.h:218
@ ETHER_TYPE_IP6
Definition: mitigator_bpf.h:220
@ ETHER_TYPE_8021Q
Definition: mitigator_bpf.h:219
uint8_t packet_transport_proto(Context ctx)
Get packet transport protocol code, e.g. TCP, UDP, or ICMP.
struct TableExResult table_ex_get(Context ctx, const void *key, const void *key_end, void *value, void *value_end)
Lookup value in the extended table by key and modify record update time.
uint64_t TableValue
Definition: mitigator_bpf.h:627
void * Context
Opaque filter context.
Definition: mitigator_bpf.h:144
LOCAL uint16_t bswap16(uint16_t value)
Change byte order of a 16-bit value.
Definition: mitigator_bpf.h:896
uint64_t table_ex_size(Context ctx)
Get number of records in the extended table.
uint32_t hash_crc32_data(const void *data, const void *end, uint32_t init)
Compute CRC32 (Castagnoli) over [data; end).
uint32_t Time
Definition: mitigator_bpf.h:181
void set_packet_offset(Context ctx, uint16_t offset)
Set number of bytes to strip from the beginning of transport payload.
uint16_t packet_network_proto(Context ctx)
Get packet network protocol code, e.g. IPv4.
Result
Filter verdict.
Definition: mitigator_bpf.h:152
@ RESULT_LIMIT
Definition: mitigator_bpf.h:160
@ RESULT_DROP
Definition: mitigator_bpf.h:156
@ RESULT_SORB
Definition: mitigator_bpf.h:166
@ RESULT_PASS
Definition: mitigator_bpf.h:154
@ RESULT_BACK
Definition: mitigator_bpf.h:158
LOCAL uint16_t vlan_get_id(const struct VlanHeader *vlan)
Get VLAN ID from 802.1q header.
Definition: mitigator_bpf.h:910
#define LOCAL
Force the compiler to inline a local function.
Definition: mitigator_bpf.h:82
Bool table_get(Context ctx, TableKey key, struct TableRecord *record)
Lookup value in the basic table by key and modify record update time.
uint32_t hash_crc32_u64(uint64_t value, uint32_t init)
Compute CRC32 (Castagnoli) of a 64-bit value.
TcpOption
TCP option codes.
Definition: mitigator_bpf.h:416
@ TCP_OPT_MAXSEG
Definition: mitigator_bpf.h:419
@ TCP_OPT_SACK_PERM
Definition: mitigator_bpf.h:421
@ TCP_OPT_SACK
Definition: mitigator_bpf.h:422
@ TCP_OPT_WSCALE
Definition: mitigator_bpf.h:420
@ TCP_OPT_TIMESTAMPS
Definition: mitigator_bpf.h:423
@ TCP_OPT_NOP
Definition: mitigator_bpf.h:418
@ TCP_OPT_EOL
Definition: mitigator_bpf.h:417
IpProto
IPv4 and IPv6 transport protocol codes.
Definition: mitigator_bpf.h:301
@ IP_PROTO_IPV6
Definition: mitigator_bpf.h:305
@ IP_PROTO_ICMP
Definition: mitigator_bpf.h:302
@ IP_PROTO_ICMPV6
Definition: mitigator_bpf.h:306
@ IP_PROTO_UDP
Definition: mitigator_bpf.h:304
@ IP_PROTO_TCP
Definition: mitigator_bpf.h:303
Cookie cookie_make(Context ctx, const struct Flow *id)
Make a generic cookie value based on random seed, current time, and flow fields that identify the cli...
TcpFlags
TCP flags.
Definition: mitigator_bpf.h:397
Cookie syncookie_make(Context ctx)
Make a cookie value for use as a sequence number in a SYN+ACK packet.
void set_packet_length(Context ctx, uint16_t length)
Set new packet transport payload length (max 1400).
uint64_t table_size(Context ctx)
Get number of records in the table.
uint32_t IpAddr
IPv4 address.
Definition: mitigator_bpf.h:224
Bool table_ex_put(Context ctx, const void *key, const void *key_end, const void *value, const void *value_end)
Update value in the extended table, creating a new record if needed.
void * packet_transport_payload(Context ctx, uint16_t *length)
Get packet transport payload for TCP or UDP.
struct TableExResult table_ex_find(Context ctx, const void *key, const void *key_end, void *value, void *value_end)
Lookup value in the extended table by key.
LOCAL uint32_t bswap32(uint32_t value)
Change byte order of a 32-bit value.
Definition: mitigator_bpf.h:902
uint64_t rand64(void)
Generate a pseudo-random, non cryptographically-secure value.
void * packet_ether_header(Context ctx)
Get packet Ethernet header.
uint32_t hash_crc32_u32(uint32_t value, uint32_t init)
Compute CRC32 (Castagnoli) of a 32-bit value.
Bool syncookie_check(Context ctx, uint32_t seqnum_offset, uint32_t acknum_offset)
Check if packet is a TCP ACK carrying a SYN cookie.
void * packet_transport_header(Context ctx)
Get packet transport header, e.g. TCP header.
Bool cookie_check(Context ctx, const struct Flow *id, Cookie cookie)
Check if a generic cookie matches the flow and has not expired.
void set_src_blacklisted(Context ctx, Time duration)
Add packet source address to temporary blacklist.
Bool table_put(Context ctx, TableKey key, TableValue value)
Update value in the basic table, creating a new record if needed.
const void * parameters_get(Context ctx)
Get a pointer to read-only program parameters.
void * packet_network_header(Context ctx)
Get packet network header, e.g. IPv4 header.
Time time_sec(Context ctx)
Get wallclock time in seconds.
uint64_t Bool
ABI-safe, EBPF-friendly boolean type.
Definition: mitigator_bpf.h:174
Bool table_find(Context ctx, TableKey key, struct TableRecord *record)
Lookup value in the basic table by key.
void set_src_whitelisted(Context ctx, Time duration)
Add packet source address to temporary whitelist.
uint64_t TableKey
Definition: mitigator_bpf.h:620
void set_packet_mangled(Context ctx)
Mark the packet as mangled by the program.
void set_packet_syncookie(Context ctx)
Convert response packet to an empty TCP SYN+ACK with syncookie.
void packet_flow(Context ctx, struct Flow *info)
Get packet flow information, including source and destination.
uint32_t Cookie
Definition: mitigator_bpf.h:746
Ethernet address (MAC address).
Definition: mitigator_bpf.h:184
Ethernet header (802.1).
Definition: mitigator_bpf.h:193
uint16_t ether_type
Definition: mitigator_bpf.h:196
Packet flow information.
Definition: mitigator_bpf.h:446
uint16_t src_port
Definition: mitigator_bpf.h:449
uint16_t dst_port
Definition: mitigator_bpf.h:450
uint32_t padding
Definition: mitigator_bpf.h:451
IPv6 address representation.
Definition: mitigator_bpf.h:264
IPv6 header.
Definition: mitigator_bpf.h:287
IPv4 header.
Definition: mitigator_bpf.h:244
Result of a lookup in the extended table.
Definition: mitigator_bpf.h:693
Time update_time
Definition: mitigator_bpf.h:696
bool found
Definition: mitigator_bpf.h:694
Record in the program-wide table.
Definition: mitigator_bpf.h:641
Time update_time
Definition: mitigator_bpf.h:643
TableValue value
Definition: mitigator_bpf.h:642
uint32_t padding
Definition: mitigator_bpf.h:644
TCP header.
Definition: mitigator_bpf.h:356
UDP header.
Definition: mitigator_bpf.h:329
VLAN header (802.1q).
Definition: mitigator_bpf.h:207
uint16_t control
Definition: mitigator_bpf.h:208
uint16_t type
Definition: mitigator_bpf.h:209
Network address, either IPv4 or IPv6.
Definition: mitigator_bpf.h:427