1*387f9dfdSAndroid Build Coastguard Worker // Copyright (c) PLUMgrid, Inc.
2*387f9dfdSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License")
3*387f9dfdSAndroid Build Coastguard Worker
4*387f9dfdSAndroid Build Coastguard Worker #include <bcc/proto.h>
5*387f9dfdSAndroid Build Coastguard Worker
6*387f9dfdSAndroid Build Coastguard Worker struct IPKey {
7*387f9dfdSAndroid Build Coastguard Worker u32 dip;
8*387f9dfdSAndroid Build Coastguard Worker u32 sip;
9*387f9dfdSAndroid Build Coastguard Worker };
10*387f9dfdSAndroid Build Coastguard Worker struct IPLeaf {
11*387f9dfdSAndroid Build Coastguard Worker u64 rx_pkts;
12*387f9dfdSAndroid Build Coastguard Worker u64 tx_pkts;
13*387f9dfdSAndroid Build Coastguard Worker };
14*387f9dfdSAndroid Build Coastguard Worker
15*387f9dfdSAndroid Build Coastguard Worker BPF_HASH(stats, struct IPKey, struct IPLeaf, 256);
16*387f9dfdSAndroid Build Coastguard Worker
on_packet(struct __sk_buff * skb)17*387f9dfdSAndroid Build Coastguard Worker int on_packet(struct __sk_buff *skb) {
18*387f9dfdSAndroid Build Coastguard Worker u8 *cursor = 0;
19*387f9dfdSAndroid Build Coastguard Worker ethernet: {
20*387f9dfdSAndroid Build Coastguard Worker struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
21*387f9dfdSAndroid Build Coastguard Worker switch (ethernet->type) {
22*387f9dfdSAndroid Build Coastguard Worker case ETH_P_IP: goto ip;
23*387f9dfdSAndroid Build Coastguard Worker case ETH_P_8021Q: goto dot1q;
24*387f9dfdSAndroid Build Coastguard Worker default: goto EOP;
25*387f9dfdSAndroid Build Coastguard Worker }
26*387f9dfdSAndroid Build Coastguard Worker }
27*387f9dfdSAndroid Build Coastguard Worker
28*387f9dfdSAndroid Build Coastguard Worker dot1q: {
29*387f9dfdSAndroid Build Coastguard Worker struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
30*387f9dfdSAndroid Build Coastguard Worker switch (dot1q->type) {
31*387f9dfdSAndroid Build Coastguard Worker case ETH_P_8021Q: goto ip;
32*387f9dfdSAndroid Build Coastguard Worker default: goto EOP;
33*387f9dfdSAndroid Build Coastguard Worker }
34*387f9dfdSAndroid Build Coastguard Worker }
35*387f9dfdSAndroid Build Coastguard Worker
36*387f9dfdSAndroid Build Coastguard Worker ip: {
37*387f9dfdSAndroid Build Coastguard Worker struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
38*387f9dfdSAndroid Build Coastguard Worker int rx = 0, tx = 0;
39*387f9dfdSAndroid Build Coastguard Worker struct IPKey key;
40*387f9dfdSAndroid Build Coastguard Worker if (ip->dst > ip->src) {
41*387f9dfdSAndroid Build Coastguard Worker key.dip = ip->dst;
42*387f9dfdSAndroid Build Coastguard Worker key.sip = ip->src;
43*387f9dfdSAndroid Build Coastguard Worker rx = 1;
44*387f9dfdSAndroid Build Coastguard Worker } else {
45*387f9dfdSAndroid Build Coastguard Worker key.dip = ip->src;
46*387f9dfdSAndroid Build Coastguard Worker key.sip = ip->dst;
47*387f9dfdSAndroid Build Coastguard Worker tx = 1;
48*387f9dfdSAndroid Build Coastguard Worker }
49*387f9dfdSAndroid Build Coastguard Worker struct IPLeaf zleaf = {0};
50*387f9dfdSAndroid Build Coastguard Worker struct IPLeaf *leaf = stats.lookup_or_try_init(&key, &zleaf);
51*387f9dfdSAndroid Build Coastguard Worker if (leaf) {
52*387f9dfdSAndroid Build Coastguard Worker lock_xadd(&leaf->rx_pkts, rx);
53*387f9dfdSAndroid Build Coastguard Worker lock_xadd(&leaf->tx_pkts, tx);
54*387f9dfdSAndroid Build Coastguard Worker }
55*387f9dfdSAndroid Build Coastguard Worker }
56*387f9dfdSAndroid Build Coastguard Worker
57*387f9dfdSAndroid Build Coastguard Worker EOP:
58*387f9dfdSAndroid Build Coastguard Worker return 0;
59*387f9dfdSAndroid Build Coastguard Worker }
60