Mitigator BPF API
Functions and types programs can use to filter packets.
 
Loading...
Searching...
No Matches
mitigator_bpf.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (c) 2022 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
98#define PACKED __attribute__((packed))
99
125#if defined(__clang__)
126#define UNROLL _Pragma("unroll")
127#else
128#define UNROLL
129#endif
130
141#define MAX_PAYLOAD_LENGTH 1536
142
152#define MAX_PARAMETERS_LENGTH 1024
153
154#ifdef __cplusplus
155namespace mitigator {
156extern "C" {
157#endif
158
160typedef void* Context;
161
183
189typedef uint64_t Bool;
190
196typedef uint32_t Time;
197
206const void* parameters_get(Context ctx);
207
209struct EtherAddr {
210 uint8_t u8[6];
211};
212
219 struct EtherAddr ether_dhost; /* Destination host MAC address */
220 struct EtherAddr ether_shost; /* Source host MAC address */
221 uint16_t ether_type; /* Next protocol ID (big-endian) */
222};
223
231 uint16_t control; /* Tag Control Information (big-endian) */
232 uint16_t type; /* Next protocol ID (big-endian) */
233};
234
240 ETHER_TYPE_IP = 0x0800, /* Internet Protocol version 4 */
241 ETHER_TYPE_ARP = 0x0806, /* Address Resolution Protocol */
242 ETHER_TYPE_8021Q = 0x8100, /* IEEE 802.1q (VLAN) */
243 ETHER_TYPE_IP6 = 0x86DD /* Internet Protocol version 6 */
244};
245
247typedef uint32_t IpAddr;
248
267struct IpHeader {
268 uint32_t ip_hl : 4; /* 0 header length */
269 uint32_t ip_v : 4; /* version == 4 */
270 uint8_t ip_tos; /* 1 type of service */
271 uint16_t ip_len; /* 2-3 total length */
272 uint16_t ip_id; /* 4-5 packet ID */
273 uint16_t ip_off; /* 6-7 fragmentation offset */
274 uint8_t ip_ttl; /* 8 time to live */
275 uint8_t ip_p; /* 9 protocol ID */
276 uint16_t ip_sum; /* 10-11 header checksum */
277 uint32_t ip_src; /* 12-15 source address */
278 uint32_t ip_dst; /* 16-19 destination address */
279};
280
287struct Ip6Addr {
288 uint8_t u8[16];
289};
290
310struct Ip6Header {
311 uint32_t ip6_vfc; /* Version, traffic class, flow label */
312 uint16_t ip6_plen; /* Payload length */
313 uint8_t ip6_next; /* Next header */
314 uint8_t ip6_hoplim; /* Hop limit */
315 struct Ip6Addr ip6_src; /* Source address */
316 struct Ip6Addr ip6_dst; /* Destination address */
317};
318
325 IP_PROTO_ICMP = 1,
326 IP_PROTO_TCP = 6,
327 IP_PROTO_UDP = 17,
328 IP_PROTO_IPV6 = 41,
329 IP_PROTO_ICMPV6 = 58,
330};
331
352struct UdpHeader {
353 uint16_t uh_sport; /* 0-1 source port */
354 uint16_t uh_dport; /* 2-3 destination port */
355 uint16_t uh_ulen; /* 4-5 UDP length */
356 uint16_t uh_sum; /* 6-7 checksum */
357};
358
379struct TcpHeader {
380 uint16_t th_sport; /* 0-1 source port */
381 uint16_t th_dport; /* 2-3 destination port */
382 uint32_t th_seq; /* 4-7 sequence number */
383 uint32_t th_ack; /* 8-11 acknowledgement number */
384 uint32_t th_flags2 : 4; /* 12 more flags */
385 uint32_t th_off : 4; /* data offset in words */
386 uint8_t th_flags; /* 13 flags */
387 uint16_t th_win; /* 14-15 window */
388 uint16_t th_sum; /* 16-17 checksum */
389 uint16_t th_urp; /* 18-19 urgent pointer */
390};
391
421 TCP_FLAG_FIN = 0x01,
422 TCP_FLAG_SYN = 0x02,
423 TCP_FLAG_RST = 0x04,
424 TCP_FLAG_PUSH = 0x08,
425 TCP_FLAG_ACK = 0x10,
426 TCP_FLAG_URG = 0x20,
427 TCP_FLAG_ECE = 0x40,
428 TCP_FLAG_CWR = 0x80
429};
430
440 TCP_OPT_EOL = 0, /* End of Option List */
441 TCP_OPT_NOP = 1, /* No option (used for padding) */
442 TCP_OPT_MAXSEG = 2, /* Maximum segment size (MSS) */
443 TCP_OPT_WSCALE = 3, /* Window scaling factor */
444 TCP_OPT_SACK_PERM = 4, /* Selective acknowledgement permitted */
445 TCP_OPT_SACK = 5, /* Selective acknowledgement */
446 TCP_OPT_TIMESTAMPS = 8 /* Timestamps */
447};
448
461 uint8_t icmp_type; /* 0 ICMP type */
462 uint8_t icmp_code; /* 1 ICMP code */
463 uint16_t icmp_cksum; /* 2-3 checksum */
464};
465
468 ICMP_ECHO_REPLY = 0, /* Echo Reply Message */
469 ICMP_DEST_UNREACHABLE = 3, /* Destination Unreachable */
470 ICMP_SOURCE_QUENCH = 4, /* Source Quench */
471 ICMP_REDIRECT = 5, /* Redirect */
472 ICMP_ECHO = 8, /* Echo Message */
473 ICMP_TIME_EXCEEDED = 11, /* Time Exceeded */
474 ICMP_PARAM_PROBLEM = 12, /* Parameter Problem */
475 ICMP_TIMESTAMP_REQUEST = 13, /* Timestamp Request */
476 ICMP_TIMESTAMP_REPLY = 14, /* Timestamp Reply */
477 ICMP_INFO_REQUEST = 15, /* Information Request */
478 ICMP_INFO_REPLY = 16, /* Information Reply */
479};
480
483 ICMP6_DEST_UNREACHABLE = 1, /* Destination Unreachable */
484 ICMP6_PKT_TOO_BIG = 2, /* Packet Too Big */
485 ICMP6_TIME_EXCEEDED = 3, /* Time Exceeded */
486 ICMP6_PARAM_PROBLEM = 4, /* Parameter Problem */
487 ICMP6_ECHO_REQUEST = 128, /* Echo Request */
488 ICMP6_ECHO_REPLY = 129, /* Echo Reply */
489 ICMP6_ROUTER_SOL = 133, /* Router Advertisement */
490 ICMP6_ROUTER_ADV = 134, /* Router Solicitation */
491 ICMP6_NEIGHBOR_SOL = 135, /* Neighbor Solicitation */
492 ICMP6_NEIGHBOR_ADV = 136, /* Neighbor Advertisement */
493};
494
496union NetAddr {
497 struct {
498 uint8_t padding[12]; /* Reserved, zero-filled by API */
499 IpAddr addr; /* IPv4 address */
500 } v4;
501 struct Ip6Addr v6; /* IPv6 address */
502};
503
515struct Flow {
516 union NetAddr src_ip; /* Source address */
517 union NetAddr dst_ip; /* Destination address */
518 uint16_t src_port; /* Source port */
519 uint16_t dst_port; /* Destination port */
520 uint32_t padding; /* Not used and zero-filled by API */
521};
522
529void packet_flow(Context ctx, struct Flow* info);
530
544
556
574
584
602
615void* packet_transport_payload(Context ctx, uint16_t* length);
616
623void set_packet_length(Context ctx, uint16_t length);
624
634void set_packet_offset(Context ctx, uint16_t offset);
635
647
663
670void set_src_blacklisted(Context ctx, Time duration);
671
678void set_src_whitelisted(Context ctx, Time duration);
679
688typedef uint64_t TableKey;
689
695typedef uint64_t TableValue;
696
710 TableValue value; /* User data */
711 Time update_time; /* Update time maintained by the system */
712 uint32_t padding; /* Reserved, not used by API */
713};
714
720Bool table_find(Context ctx, TableKey key, struct TableRecord* record);
721
729Bool table_get(Context ctx, TableKey key, struct TableRecord* record);
730
740
742uint64_t table_size(Context ctx);
743
762 bool found; /* Indicates if the record has been found */
763 uint8_t reserved[3]; /* Reserved, do not use */
764 Time update_time; /* Record update time maintained by the system */
765};
766
768#define TABLE_EX_KEY_SIZE 16
769
771#define TABLE_EX_VALUE_SIZE 8
772
781struct TableExResult
782table_ex_find(Context ctx, const void* key, const void* key_end,
783 void* value, void* value_end);
784
793struct TableExResult
794table_ex_get(Context ctx, const void* key, const void* key_end,
795 void* value, void* value_end);
796
807Bool table_ex_put(Context ctx, const void* key, const void* key_end,
808 const void* value, const void* value_end);
809
811uint64_t table_ex_size(Context ctx);
812
814typedef uint32_t Cookie;
815
840Cookie cookie_make(Context ctx, const struct Flow* id);
841
863Bool cookie_check(Context ctx, const struct Flow* id, Cookie cookie);
864
874
889Bool syncookie_check(Context ctx, uint32_t seqnum_offset, uint32_t acknum_offset);
890
900
906Bool isn_syncookie_check(Context ctx, uint32_t seqnum_offset,
907 uint32_t acknum_offset);
908
916
922Bool bloom_check(Context ctx, uint64_t hash);
923
927void bloom_add(Context ctx, uint64_t hash);
928
933
940
955uint32_t hash_crc32_u32(uint32_t value, uint32_t init);
956
962uint32_t hash_crc32_u64(uint64_t value, uint32_t init);
963
994uint32_t hash_crc32_data(const void* data, const void* end, uint32_t init);
995
997uint64_t rand64(void);
998
1001
1003LOCAL uint16_t
1004bswap16(uint16_t value) {
1005 return __builtin_bswap16(value);
1006}
1007
1009LOCAL uint32_t
1010bswap32(uint32_t value) {
1011 return __builtin_bswap32(value);
1012}
1013
1015LOCAL uint64_t
1016bswap64(uint64_t value) {
1017 return __builtin_bswap64(value);
1018}
1019
1020STATIC_ASSERT(sizeof(struct EtherHeader) == 14);
1021STATIC_ASSERT(sizeof(struct VlanHeader) == 4);
1022STATIC_ASSERT(sizeof(struct IpHeader) == 20);
1023STATIC_ASSERT(sizeof(struct Ip6Addr) == 16);
1024STATIC_ASSERT(sizeof(struct Ip6Header) == 40);
1025STATIC_ASSERT(sizeof(struct TcpHeader) == 20);
1026STATIC_ASSERT(sizeof(struct UdpHeader) == 8);
1027STATIC_ASSERT(sizeof(struct IcmpHeader) == 4);
1028STATIC_ASSERT(sizeof(struct TableExResult) == 8);
1029STATIC_ASSERT(sizeof(union NetAddr) == sizeof(struct Ip6Addr));
1030
1031#ifdef __cplusplus
1032} // extern "C"
1033} // namespace mitigator
1034#endif
EtherType
Ethernet frame type codes.
Definition mitigator_bpf.h:239
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.
void * packet_ether_header(Context ctx)
Get packet Ethernet header.
uint64_t TableValue
Definition mitigator_bpf.h:695
void * Context
Opaque filter context.
Definition mitigator_bpf.h:160
LOCAL uint16_t bswap16(uint16_t value)
Change byte order of a 16-bit value.
Definition mitigator_bpf.h:1004
uint64_t table_ex_size(Context ctx)
Get number of records in the extended table.
IcmpType
ICMPv4 types.
Definition mitigator_bpf.h:467
void bloom_reset(Context ctx)
Reset bloom filter to the initial state.
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:196
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:167
@ RESULT_LIMIT
Definition mitigator_bpf.h:175
@ RESULT_DROP
Definition mitigator_bpf.h:171
@ RESULT_SORB
Definition mitigator_bpf.h:181
@ RESULT_PASS
Definition mitigator_bpf.h:169
@ RESULT_BACK
Definition mitigator_bpf.h:173
void * packet_transport_payload(Context ctx, uint16_t *length)
Get packet transport payload for TCP, UDP, or ICMP.
#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:439
void * packet_network_header(Context ctx)
Get packet network header, e.g. IPv4 header.
IpProto
IPv4 and IPv6 transport protocol codes.
Definition mitigator_bpf.h:324
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:420
Cookie syncookie_make(Context ctx)
Make a cookie value for use as a sequence number in a SYN+ACK packet.
LOCAL uint64_t bswap64(uint64_t value)
Change byte order of a 64-bit value.
Definition mitigator_bpf.h:1016
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:247
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_header(Context ctx)
Get packet transport header, e.g. TCP header.
Bool isn_syncookie_check(Context ctx, uint32_t seqnum_offset, uint32_t acknum_offset)
Check if packet is a TCP ACK carrying an ISN SYN cookie.
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:1010
uint64_t rand64(void)
Generate a pseudo-random, non cryptographically-secure value.
uint32_t hash_crc32_u32(uint32_t value, uint32_t init)
Compute CRC32 (Castagnoli) of a 32-bit value.
Icmp6Type
ICMPv6 types.
Definition mitigator_bpf.h:482
Bool syncookie_check(Context ctx, uint32_t seqnum_offset, uint32_t acknum_offset)
Check if packet is a TCP ACK carrying a SYN cookie.
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_packet_isn_syncookie(Context ctx)
Convert response packet to an empty TCP SYN+ACK with ISN syncookie.
Bool learning_check(Context ctx)
Check if CMON has learned session for current packet.
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.
Bool bloom_check(Context ctx, uint64_t hash)
Check if hash value is stored in the bloom filter.
void bloom_add(Context ctx, uint64_t hash)
Add hash value to the bloom filter.
Time time_sec(Context ctx)
Get system time in seconds.
uint64_t Bool
ABI-safe, EBPF-friendly boolean type.
Definition mitigator_bpf.h:189
void isn_send_ack_packet(Context ctx)
Send ACK packet with ISN syncookie.
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:688
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:814
Ethernet address (MAC address).
Definition mitigator_bpf.h:209
Ethernet header (802.1).
Definition mitigator_bpf.h:218
Packet flow information.
Definition mitigator_bpf.h:515
ICMP and ICMPv6 header.
Definition mitigator_bpf.h:460
IPv6 address representation.
Definition mitigator_bpf.h:287
IPv6 header.
Definition mitigator_bpf.h:310
IPv4 header.
Definition mitigator_bpf.h:267
Result of a lookup in the extended table.
Definition mitigator_bpf.h:761
Record in the program-wide table.
Definition mitigator_bpf.h:709
TCP header.
Definition mitigator_bpf.h:379
UDP header.
Definition mitigator_bpf.h:352
VLAN header (802.1q).
Definition mitigator_bpf.h:230
Network address, either IPv4 or IPv6.
Definition mitigator_bpf.h:496