blob: 4fe29673b2551dbf12b0b3ae30a369fe4ca7f038 [file] [log] [blame]
Brenden Blanco3f12ca22015-07-28 10:47:33 -07001// Copyright (c) PLUMgrid, Inc.
2// Licensed under the Apache License, Version 2.0 (the "License")
3#include <bcc/proto.h>
4
5BPF_TABLE("hash", u32, int, vni2if, 1024);
6
7struct vni_key {
8 u64 mac;
9 int ifindex;
10 int pad;
11};
12struct host {
13 u32 tunnel_id;
14 u32 remote_ipv4;
15 u64 rx_pkts;
16 u64 tx_pkts;
17};
18BPF_TABLE("hash", struct vni_key, struct host, mac2host, 10240);
19
20struct config {
21 int tunnel_ifindex;
22};
23BPF_TABLE("hash", int, struct config, conf, 1);
24
25// Handle packets from the encap device, demux into the dest tenant
26int handle_ingress(struct __sk_buff *skb) {
27 u8 *cursor = 0;
28
29 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
30
31 struct bpf_tunnel_key tkey = {};
Alexei Starovoitovb37f8a02015-07-30 14:14:09 -070032 bpf_skb_get_tunnel_key(skb, &tkey, sizeof(tkey), 0);
Brenden Blanco3f12ca22015-07-28 10:47:33 -070033
34 int *ifindex = vni2if.lookup(&tkey.tunnel_id);
35 if (ifindex) {
36 //bpf_trace_printk("ingress tunnel_id=%d ifindex=%d\n", tkey.tunnel_id, *ifindex);
37 struct vni_key vk = {ethernet->src, *ifindex, 0};
38 struct host *src_host = mac2host.lookup_or_init(&vk,
39 &(struct host){tkey.tunnel_id, tkey.remote_ipv4, 0, 0});
40 lock_xadd(&src_host->rx_pkts, 1);
41 bpf_clone_redirect(skb, *ifindex, 1/*ingress*/);
42 } else {
43 bpf_trace_printk("ingress invalid tunnel_id=%d\n", tkey.tunnel_id);
44 }
45
46 return 1;
47}
48
49// Handle packets from the tenant, mux into the encap device
50int handle_egress(struct __sk_buff *skb) {
51 u8 *cursor = 0;
52
53 int one = 1;
54 struct config *cfg = conf.lookup(&one);
55 if (!cfg) return 1;
56
57 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
58
59 struct vni_key vk = {ethernet->dst, skb->ifindex, 0};
60 struct host *dst_host = mac2host.lookup(&vk);
61 struct bpf_tunnel_key tkey = {};
62 if (dst_host) {
63 u32 zero = 0;
64 tkey.tunnel_id = dst_host->tunnel_id;
65 tkey.remote_ipv4 = dst_host->remote_ipv4;
Alexei Starovoitovb37f8a02015-07-30 14:14:09 -070066 bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), 0);
Brenden Blanco3f12ca22015-07-28 10:47:33 -070067 lock_xadd(&dst_host->tx_pkts, 1);
68 } else {
69 struct bpf_tunnel_key tkey = {};
70 vk.mac = 0xFFFFFFFFFFFFull;
71 dst_host = mac2host.lookup(&vk);
72 if (!dst_host)
73 return 1;
74 tkey.tunnel_id = dst_host->tunnel_id;
75 tkey.remote_ipv4 = dst_host->remote_ipv4;
Alexei Starovoitovb37f8a02015-07-30 14:14:09 -070076 bpf_skb_set_tunnel_key(skb, &tkey, sizeof(tkey), 0);
Brenden Blanco3f12ca22015-07-28 10:47:33 -070077 }
78 bpf_clone_redirect(skb, cfg->tunnel_ifindex, 0/*egress*/);
79 return 1;
80}