xref: /aosp_15_r20/external/bcc/examples/networking/distributed_bridge/tunnel_mesh.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1 // Copyright (c) PLUMgrid, Inc.
2 // Licensed under the Apache License, Version 2.0 (the "License")
3 #include <bcc/proto.h>
4 
5 struct config {
6   int tunnel_ifindex;
7 };
8 BPF_HASH(conf, int, struct config, 1);
9 
10 struct tunnel_key {
11   u32 tunnel_id;
12   u32 remote_ipv4;
13 };
14 BPF_HASH(tunkey2if, struct tunnel_key, int, 1024);
15 
16 BPF_HASH(if2tunkey, int, struct tunnel_key, 1024);
17 
18 // Handle packets from the encap device, demux into the dest tenant
handle_ingress(struct __sk_buff * skb)19 int handle_ingress(struct __sk_buff *skb) {
20   struct bpf_tunnel_key tkey = {};
21   struct tunnel_key key;
22   bpf_skb_get_tunnel_key(skb, &tkey,
23       offsetof(struct bpf_tunnel_key, remote_ipv6[1]), 0);
24 
25   key.tunnel_id = tkey.tunnel_id;
26   key.remote_ipv4 = tkey.remote_ipv4;
27   int *ifindex = tunkey2if.lookup(&key);
28   if (ifindex) {
29     //bpf_trace_printk("ingress tunnel_id=%d remote_ip=%08x ifindex=%d\n",
30     //                 key.tunnel_id, key.remote_ipv4, *ifindex);
31     // mark from external
32     skb->tc_index = 1;
33     bpf_clone_redirect(skb, *ifindex, 1/*ingress*/);
34   } else {
35     bpf_trace_printk("ingress invalid tunnel_id=%d\n", key.tunnel_id);
36   }
37 
38   return 1;
39 }
40 
41 // Handle packets from the tenant, mux into the encap device
handle_egress(struct __sk_buff * skb)42 int handle_egress(struct __sk_buff *skb) {
43   int ifindex = skb->ifindex;
44   struct bpf_tunnel_key tkey = {};
45   struct tunnel_key *key_p;
46   int one = 1;
47   struct config *cfg = conf.lookup(&one);
48 
49   if (!cfg) return 1;
50 
51   if (skb->tc_index) {
52     //bpf_trace_printk("from external\n");
53     // don't send it back out to encap device
54     return 1;
55   }
56 
57   key_p = if2tunkey.lookup(&ifindex);
58   if (key_p) {
59     tkey.tunnel_id = key_p->tunnel_id;
60     tkey.remote_ipv4 = key_p->remote_ipv4;
61     bpf_skb_set_tunnel_key(skb, &tkey,
62         offsetof(struct bpf_tunnel_key, remote_ipv6[1]), 0);
63     bpf_clone_redirect(skb, cfg->tunnel_ifindex, 0/*egress*/);
64   }
65   return 1;
66 }
67