- [15. BPF_HASH_OF_MAPS](#15-bpf_hash_of_maps)
- [16. BPF_STACK](#16-bpf_stack)
- [17. BPF_QUEUE](#17-bpf_queue)
- - [18. map.lookup()](#18-maplookup)
- - [19. map.lookup_or_try_init()](#19-maplookup_or_try_init)
- - [20. map.delete()](#20-mapdelete)
- - [21. map.update()](#21-mapupdate)
- - [22. map.insert()](#22-mapinsert)
- - [23. map.increment()](#23-mapincrement)
- - [24. map.get_stackid()](#24-mapget_stackid)
- - [25. map.perf_read()](#25-mapperf_read)
- - [26. map.call()](#26-mapcall)
- - [27. map.redirect_map()](#27-mapredirect_map)
- - [28. map.push()](#28-mappush)
- - [29. map.pop()](#29-mappop)
- - [30. map.peek()](#30-mappeek)
+ - [18. BPF_SOCKHASH](#18-bpf_sockhash)
+ - [19. map.lookup()](#19-maplookup)
+ - [20. map.lookup_or_try_init()](#20-maplookup_or_try_init)
+ - [21. map.delete()](#21-mapdelete)
+ - [22. map.update()](#22-mapupdate)
+ - [23. map.insert()](#23-mapinsert)
+ - [24. map.increment()](#24-mapincrement)
+ - [25. map.get_stackid()](#25-mapget_stackid)
+ - [26. map.perf_read()](#26-mapperf_read)
+ - [27. map.call()](#27-mapcall)
+ - [28. map.redirect_map()](#28-mapredirect_map)
+ - [29. map.push()](#29-mappush)
+ - [30. map.pop()](#30-mappop)
+ - [31. map.peek()](#31-mappeek)
+ - [32. map.sock_hash_update()](#32-mapsock_hash_update)
- [Licensing](#licensing)
- [Rewriter](#rewriter)
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_QUEUE+path%3Atests&type=Code),
-### 18. map.lookup()
+### 18. BPF_SOCKHASH
+
+Syntax: ```BPF_SOCKHASH(name[, key_type [, max_entries)```
+
+Creates a hash named ```name```, with optional parameters. sockhash is only available from Linux 4.18+.
+
+Default: ```BPF_SOCKHASH(name, key_type=u32, max_entries=10240)```
+
+For example:
+
+```C
+struct sock_key {
+ u32 remote_ip4;
+ u32 local_ip4;
+ u32 remote_port;
+ u32 local_port;
+};
+BPF_HASH(skh, struct sock_key, 65535);
+```
+
+This creates a hash named ```skh``` where the key is a ```struct sock_key```.
+
+A sockhash is a BPF map type that holds references to sock structs. Then with a new sk/msg redirect bpf helper BPF programs can use the map to redirect skbs/msgs between sockets (```bpf_sk_redirect_hash/bpf_msg_redirect_hash```).
+
+The difference between ```BPF_SOCKHASH``` and ```BPF_SOCKMAP``` is that ```BPF_SOCKMAP``` is implemented based on an array, and enforces keys to be four bytes. While ```BPF_SOCKHASH``` is implemented based on hash table, and the type of key can be specified freely.
+
+Methods (covered later): map.sock_hash_update().
+
+[search /tests](https://github.com/iovisor/bcc/search?q=BPF_SOCKHASH+path%3Atests&type=Code)
+
+### 19. map.lookup()
Syntax: ```*val map.lookup(&key)```
[search /examples](https://github.com/iovisor/bcc/search?q=lookup+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=lookup+path%3Atools&type=Code)
-### 19. map.lookup_or_try_init()
+### 20. map.lookup_or_try_init()
Syntax: ```*val map.lookup_or_try_init(&key, &zero)```
Note: The old map.lookup_or_init() may cause return from the function, so lookup_or_try_init() is recommended as it
does not have this side effect.
-### 20. map.delete()
+### 21. map.delete()
Syntax: ```map.delete(&key)```
[search /examples](https://github.com/iovisor/bcc/search?q=delete+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=delete+path%3Atools&type=Code)
-### 21. map.update()
+### 22. map.update()
Syntax: ```map.update(&key, &val)```
[search /examples](https://github.com/iovisor/bcc/search?q=update+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=update+path%3Atools&type=Code)
-### 22. map.insert()
+### 23. map.insert()
Syntax: ```map.insert(&key, &val)```
[search /examples](https://github.com/iovisor/bcc/search?q=insert+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=insert+path%3Atools&type=Code)
-### 23. map.increment()
+### 24. map.increment()
Syntax: ```map.increment(key[, increment_amount])```
[search /examples](https://github.com/iovisor/bcc/search?q=increment+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=increment+path%3Atools&type=Code)
-### 24. map.get_stackid()
+### 25. map.get_stackid()
Syntax: ```int map.get_stackid(void *ctx, u64 flags)```
[search /examples](https://github.com/iovisor/bcc/search?q=get_stackid+path%3Aexamples&type=Code),
[search /tools](https://github.com/iovisor/bcc/search?q=get_stackid+path%3Atools&type=Code)
-### 25. map.perf_read()
+### 26. map.perf_read()
Syntax: ```u64 map.perf_read(u32 cpu)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=perf_read+path%3Atests&type=Code)
-### 26. map.call()
+### 27. map.call()
Syntax: ```void map.call(void *ctx, int index)```
[search /examples](https://github.com/iovisor/bcc/search?l=C&q=call+path%3Aexamples&type=Code),
[search /tests](https://github.com/iovisor/bcc/search?l=C&q=call+path%3Atests&type=Code)
-### 27. map.redirect_map()
+### 28. map.redirect_map()
Syntax: ```int map.redirect_map(int index, int flags)```
Examples in situ:
[search /examples](https://github.com/iovisor/bcc/search?l=C&q=redirect_map+path%3Aexamples&type=Code),
-### 28. map.push()
+### 29. map.push()
Syntax: ```int map.push(&val, int flags)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=push+path%3Atests&type=Code),
-### 29. map.pop()
+### 30. map.pop()
Syntax: ```int map.pop(&val)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=pop+path%3Atests&type=Code),
-### 30. map.peek()
+### 31. map.peek()
Syntax: ```int map.peek(&val)```
Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=peek+path%3Atests&type=Code),
+### 32. map.sock_hash_update()
+
+Syntax: ```int map.sock_hash_update(struct bpf_sock_ops *, &key, int flags)```
+
+Add an entry to, or update a sockhash map referencing sockets. The skops is used as a new value for the entry associated to key. flags is one of:
+
+```
+BPF_NOEXIST: The entry for key must not exist in the map.
+BPF_EXIST: The entry for key must already exist in the map.
+BPF_ANY: No condition on the existence of the entry for key.
+```
+
+If the map has eBPF programs (parser and verdict), those will be inherited by the socket being added. If the socket is already attached to eBPF programs, this results in an error.
+
+Return 0 on success, or a negative error in case of failure.
+
+Examples in situ:
+[search /tests](https://github.com/iovisor/bcc/search?q=sock_hash_update+path%3Atests&type=Code),
+
## Licensing
Depending on which [BPF helpers](kernel-versions.md#helpers) are used, a GPL-compatible license is required.
Instruments the network driver described by ```dev``` , and then receives the packet, run the BPF function ```fn_name()``` with flags.
-Here is a list of optional flags.
+Here is a list of optional flags.
```Python
# from xdp_flags uapi/linux/if_link.h
If an XDP program is already attached to the specified driver, attaching the XDP program again will fail.
#### 2. XDP_FLAGS_SKB_MODE
-Driver doesn’t have support for XDP, but the kernel fakes it.
+Driver doesn’t have support for XDP, but the kernel fakes it.
XDP program works, but there’s no real performance benefit because packets are handed to kernel stack anyways which then emulates XDP – this is usually supported with generic network drivers used in home computers, laptops, and virtualized HW.
#### 3. XDP_FLAGS_DRV_MODE
u32 key; \
int leaf; \
int (*update) (u32 *, int *); \
- int (*delete) (int *); \
+ int (*delete) (u32 *); \
/* ret = map.sock_map_update(ctx, key, flag) */ \
int (* _helper_name) (void *, void *, u64); \
u32 max_entries; \
#define BPF_SOCKMAP(_name, _max_entries) \
BPF_SOCKMAP_COMMON(_name, _max_entries, "sockmap", sock_map_update)
-#define BPF_SOCKHASH(_name, _max_entries) \
- BPF_SOCKMAP_COMMON(_name, _max_entries, "sockhash", sock_hash_update)
+#define BPF_SOCKHASH_COMMON(_name, _key_type, _max_entries) \
+struct _name##_table_t {\
+ _key_type key;\
+ int leaf; \
+ int (*update) (_key_type *, int *); \
+ int (*delete) (_key_type *); \
+ int (*sock_hash_update) (void *, void *, u64); \
+ u32 max_entries; \
+}; \
+__attribute__((section("maps/sockhash"))) \
+struct _name##_table_t _name = { .max_entries = (_max_entries) }; \
+BPF_ANNOTATE_KV_PAIR(_name, _key_type, int)
+
+#define BPF_SOCKHASH1(_name) \
+ BPF_SOCKHASH_COMMON(_name, u32, 10240)
+#define BPF_SOCKHASH2(_name, _key_type) \
+ BPF_SOCKHASH_COMMON(_name, _key_type, 10240)
+#define BPF_SOCKHASH3(_name, _key_type, _max_entries) \
+ BPF_SOCKHASH_COMMON(_name, _key_type, _max_entries)
+
+#define BPF_SOCKHASHX(_1, _2, _3, NAME, ...) NAME
+// We can define a five-tuple as the key, and basically never define the val type.
+// BPF_SOCKHASH(name, key_type=u64, size=10240)
+#define BPF_SOCKHASH(...) \
+ BPF_SOCKHASHX(__VA_ARGS__, BPF_SOCKHASH3, BPF_SOCKHASH2, BPF_SOCKHASH1)(__VA_ARGS__)
#define BPF_CGROUP_STORAGE_COMMON(_name, _leaf_type, _kind) \
struct _name##_table_t { \