blob: 4ca91a96533caef8616e611976261757abe4c54a [file] [log] [blame]
Brenden Blancoaf956732015-06-09 13:58:42 -07001// Copyright (c) PLUMgrid, Inc.
2// Licensed under the Apache License, Version 2.0 (the "License")
3
4#include <bcc/proto.h>
5
6struct ifindex_leaf_t {
7 int out_ifindex;
Yonghong Song540d45a2015-07-22 10:17:39 -07008 int vlan_tci; // populated by phys2virt and used by virt2phys
9 int vlan_proto; // populated by phys2virt and used by virt2phys
Brenden Blancoaf956732015-06-09 13:58:42 -070010 u64 tx_pkts;
11 u64 tx_bytes;
12};
13
14// redirect based on mac -> out_ifindex (auto-learning)
Teng Qin7a3e5bc2017-03-29 13:39:17 -070015BPF_HASH(egress, int, struct ifindex_leaf_t, 4096);
Brenden Blancoaf956732015-06-09 13:58:42 -070016
17// redirect based on mac -> out_ifindex (config-driven)
Prashant Bhole53e3afd2017-09-04 09:26:08 +090018BPF_HASH(ingress, u64, struct ifindex_leaf_t, 4096);
Brenden Blancoaf956732015-06-09 13:58:42 -070019
Brenden Blancoaf956732015-06-09 13:58:42 -070020int handle_phys2virt(struct __sk_buff *skb) {
Yonghong Song540d45a2015-07-22 10:17:39 -070021 // only handle vlan packets
22 if (!skb->vlan_present)
23 return 1;
Brenden Blanco6ec65e42015-07-02 10:02:04 -070024 u8 *cursor = 0;
25 ethernet: {
26 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
Brenden Blancoaf956732015-06-09 13:58:42 -070027 u64 src_mac = ethernet->src;
28 struct ifindex_leaf_t *leaf = ingress.lookup(&src_mac);
29 if (leaf) {
30 lock_xadd(&leaf->tx_pkts, 1);
31 lock_xadd(&leaf->tx_bytes, skb->len);
32 // auto-program reverse direction table
Brenden Blanco6bf723d2015-06-18 17:53:31 -070033 int out_ifindex = leaf->out_ifindex;
Brenden Blancoaf956732015-06-09 13:58:42 -070034 struct ifindex_leaf_t zleaf = {0};
yonghong-song82f43022019-10-31 08:16:12 -070035 struct ifindex_leaf_t *out_leaf = egress.lookup_or_try_init(&out_ifindex, &zleaf);
Philip Gladstoneba64f032019-09-20 01:12:01 -040036 if (out_leaf) {
37 // to capture potential configuration changes
38 out_leaf->out_ifindex = skb->ifindex;
39 out_leaf->vlan_tci = skb->vlan_tci;
40 out_leaf->vlan_proto = skb->vlan_proto;
41 }
Yonghong Song540d45a2015-07-22 10:17:39 -070042 // pop the vlan header and send to the destination
43 bpf_skb_vlan_pop(skb);
Brenden Blancoaf956732015-06-09 13:58:42 -070044 bpf_clone_redirect(skb, leaf->out_ifindex, 0);
45 }
46 }
Brenden Blancoaf956732015-06-09 13:58:42 -070047 return 1;
48}
49
Brenden Blancoaf956732015-06-09 13:58:42 -070050int handle_virt2phys(struct __sk_buff *skb) {
Brenden Blanco6ec65e42015-07-02 10:02:04 -070051 u8 *cursor = 0;
52 ethernet: {
53 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
Brenden Blanco6bf723d2015-06-18 17:53:31 -070054 int src_ifindex = skb->ifindex;
55 struct ifindex_leaf_t *leaf = egress.lookup(&src_ifindex);
Brenden Blancoaf956732015-06-09 13:58:42 -070056 if (leaf) {
57 lock_xadd(&leaf->tx_pkts, 1);
58 lock_xadd(&leaf->tx_bytes, skb->len);
Yonghong Song540d45a2015-07-22 10:17:39 -070059 bpf_skb_vlan_push(skb, leaf->vlan_proto, leaf->vlan_tci);
Brenden Blancoaf956732015-06-09 13:58:42 -070060 bpf_clone_redirect(skb, leaf->out_ifindex, 0);
61 }
62 }
Brenden Blancoaf956732015-06-09 13:58:42 -070063 return 1;
64}