Skip to content

Commit

Permalink
libbcc: add msg_redirect_hash() and sk_redirect_hash() for sockhash
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyuezhou authored and yonghong-song committed Jun 8, 2021
1 parent 6d88feb commit 1aeec1f
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
30 changes: 27 additions & 3 deletions docs/reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ This guide is incomplete. If something feels missing, check the bcc and kernel s
- [30. map.pop()](#30-mappop)
- [31. map.peek()](#31-mappeek)
- [32. map.sock_hash_update()](#32-mapsock_hash_update)
- [33. map.msg_redirect_hash()](#33-mapmsg_redirect_hash)
- [34. map.sk_redirect_hash()](#34-mapsk_redirect_hash)
- [Licensing](#licensing)
- [Rewriter](#rewriter)

Expand Down Expand Up @@ -1234,11 +1236,11 @@ 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```).
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 (```map.sk_redirect_hash()/map.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().
Methods (covered later): map.sock_hash_update(), map.msg_redirect_hash(), map.sk_redirect_hash().
[search /tests](https://github.com/iovisor/bcc/search?q=BPF_SOCKHASH+path%3Atests&type=Code)
Expand Down Expand Up @@ -1436,7 +1438,7 @@ Examples in situ:

### 32. map.sock_hash_update()

Syntax: ```int map.sock_hash_update(struct bpf_sock_ops *, &key, int flags)```
Syntax: ```int map.sock_hash_update(struct bpf_sock_ops *skops, &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:

Expand All @@ -1453,6 +1455,28 @@ 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),

### 33. map.msg_redirect_hash()

Syntax: ```int map.msg_redirect_hash(struct sk_msg_buff *msg, void *key, u64 flags)```

This helper is used in programs implementing policies at the socket level. If the message msg is allowed to pass (i.e. if the verdict eBPF program returns SK_PASS), redirect it to the socket referenced by map (of type BPF_MAP_TYPE_SOCKHASH) using hash key. Both ingress and egress interfaces can be used for redirection. The BPF_F_INGRESS value in flags is used to make the distinction (ingress path is selected if the flag is present, egress path otherwise). This is the only flag supported for now.

Return SK_PASS on success, or SK_DROP on error.

Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=msg_redirect_hash+path%3Atests&type=Code),

### 34. map.sk_redirect_hash()

Syntax: ```int map.sk_redirect_hash(struct sk_buff *skb, void *key, u64 flags)```

This helper is used in programs implementing policies at the skb socket level. If the sk_buff skb is allowed to pass (i.e. if the verdict eBPF program returns SK_PASS), redirect it to the socket referenced by map (of type BPF_MAP_TYPE_SOCKHASH) using hash key. Both ingress and egress interfaces can be used for redirection. The BPF_F_INGRESS value in flags is used to make the distinction (ingress path is selected if the flag is present, egress otherwise). This is the only flag supported for now.

Return SK_PASS on success, or SK_DROP on error.

Examples in situ:
[search /tests](https://github.com/iovisor/bcc/search?q=sk_redirect_hash+path%3Atests&type=Code),

## Licensing

Depending on which [BPF helpers](kernel-versions.md#helpers) are used, a GPL-compatible license is required.
Expand Down
2 changes: 2 additions & 0 deletions src/cc/export/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ struct _name##_table_t {\
int (*update) (_key_type *, int *); \
int (*delete) (_key_type *); \
int (*sock_hash_update) (void *, void *, u64); \
int (*msg_redirect_hash) (void *, void *, u64); \
int (*sk_redirect_hash) (void *, void *, u64); \
u32 max_entries; \
}; \
__attribute__((section("maps/sockhash"))) \
Expand Down
7 changes: 7 additions & 0 deletions src/cc/frontends/clang/b_frontend_action.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,13 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
}
fe_.perf_events_[name] = perf_event;
}
} else if (memb_name == "msg_redirect_hash" || memb_name == "sk_redirect_hash") {
string arg0 = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
string args_other = rewriter_.getRewrittenText(expansionRange(SourceRange(GET_BEGINLOC(Call->getArg(1)),
GET_ENDLOC(Call->getArg(2)))));

txt = "bpf_" + string(memb_name) + "(" + arg0 + ", (void *)bpf_pseudo_fd(1, " + fd + "), ";
txt += args_other + ")";
} else {
if (memb_name == "lookup") {
prefix = "bpf_map_lookup_elem";
Expand Down
4 changes: 4 additions & 0 deletions tests/cc/test_sock_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,14 @@ BPF_SOCKHASH(sk_hash2, u32, 10);
int test(struct bpf_sock_ops *skops)
{
u32 key = 0, val = 0;
struct sk_msg_buff *msg;
struct sk_buff *skb;
sk_hash2.update(&key, &val);
sk_hash2.delete(&key);
sk_hash2.sock_hash_update(skops, &key, 0);
sk_hash2.msg_redirect_hash(msg, &key, 0);
sk_hash2.sk_redirect_hash(skb, &key, 0);
return 0;
}
Expand Down

0 comments on commit 1aeec1f

Please sign in to comment.