libbcc: add msg_redirect_hash() and sk_redirect_hash() for sockhash
authorchenyuezhou <zcy.chenyue.zhou@gmail.com>
Tue, 8 Jun 2021 16:09:31 +0000 (12:09 -0400)
committeryonghong-song <ys114321@gmail.com>
Tue, 8 Jun 2021 17:45:38 +0000 (10:45 -0700)
docs/reference_guide.md
src/cc/export/helpers.h
src/cc/frontends/clang/b_frontend_action.cc
tests/cc/test_sock_table.cc

index 954ad7d1acd0db216b8de4ac10b0b1e6d216090a..63c82d22aaffd0548b9271f4351d241f7ce9d958 100644 (file)
@@ -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)
 
@@ -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)
 
@@ -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:
 
@@ -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.
index e447486bcae85c3ff07cbd13c35898255d89bb46..0be3572b1473d6d1a5f69f86fcdb6c779729771f 100644 (file)
@@ -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"))) \
index 1c67322650d706a21346468f8187eeb57a3996e9..e78ceb3ced645da2d78c938edb528610e6ba4a0d 100644 (file)
@@ -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";
index db5ce5257ef962458092901f8b4b912f85604bd5..6db184efa95a7265274d563f974bc34acd585c15 100644 (file)
@@ -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;
 }