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