blob: 05bc69263790fb8d532fcca51ad78b1fd39a02fc [file] [log] [blame]
#include "../../src/cc/bpf_helpers.h"
struct IPKey {
u32 dip;
u32 sip;
};
struct IPLeaf {
u64 rx_pkts;
u64 tx_pkts;
};
BPF_TABLE("hash", struct IPKey, struct IPLeaf, stats, 256);
BPF_EXPORT(main)
int foo(struct __sk_buff *skb) {
size_t next = 0, cur = 0;
ethernet:
{
cur = next; next += 14;
switch (bpf_dext_pkt(skb, cur + 12, 0, 16)) {
case 0x800: goto ip;
case 0x8100: goto dot1q;
default: goto EOP;
}
}
dot1q:
{
cur = next; next += 4;
switch (bpf_dext_pkt(skb, cur + 2, 0, 16)) {
case 0x0800: goto ip;
default: goto EOP;
}
}
ip:
{
cur = next; next += 20;
int rx = 0;
int tx = 0;
struct IPKey key = {0};
if (bpf_dext_pkt(skb, cur + 16, 0, 32) > bpf_dext_pkt(skb, cur + 12, 0, 32)) {
key.sip = bpf_dext_pkt(skb, cur + 12, 0, 32);
key.dip = bpf_dext_pkt(skb, cur + 16, 0, 32);
rx = 1;
} else {
key.dip = bpf_dext_pkt(skb, cur + 12, 0, 32);
key.sip = bpf_dext_pkt(skb, cur + 16, 0, 32);
tx = 1;
}
// try to get here:
//stats[key].rx_pkts += rx;
//stats[key].tx_pkts += tx;
// or here:
//struct IPLeaf *leaf = stats[key];
//if (leaf) {
// __sync_fetch_and_add(&leaf->rx_pkts, rx);
// __sync_fetch_and_add(&leaf->tx_pkts, tx);
//}
struct IPLeaf *leaf;
leaf = stats.get(&key);
if (!leaf) {
struct IPLeaf zleaf = {0};
stats.put(&key, &zleaf);
leaf = stats.get(&key);
}
if (leaf) {
__sync_fetch_and_add(&leaf->rx_pkts, rx);
__sync_fetch_and_add(&leaf->tx_pkts, tx);
}
switch (bpf_dext_pkt(skb, cur + 9, 0, 8)) {
case 6: goto tcp;
case 17: goto udp;
//case 47: goto gre;
default: goto EOP;
}
}
udp:
{
cur = next; next += 8;
switch (bpf_dext_pkt(skb, cur + 2, 0, 16)) {
//case 8472: goto vxlan;
//case 4789: goto vxlan;
default: goto EOP;
}
}
tcp:
{
cur = next; next += 20;
goto EOP;
}
EOP:
return 0;
}