blob: 0af351f4946c1d6be117964cfab96a855370f10d [file] [log] [blame]
Brenden Blanco246b9422015-06-05 11:15:27 -07001// Copyright (c) PLUMgrid, Inc.
2// Licensed under the Apache License, Version 2.0 (the "License")
Brenden Blanco83102912015-06-09 17:43:27 -07003#include <bcc/proto.h>
Brenden Blanco22a419b2015-05-29 11:14:20 -07004struct IPKey {
5 u32 dip;
6 u32 sip;
7};
8struct IPLeaf {
9 u32 xdip;
10 u32 xsip;
Brenden Blancobb7200c2015-06-04 18:01:42 -070011 u64 ip_xlated_pkts;
12 u64 arp_xlated_pkts;
Brenden Blanco22a419b2015-05-29 11:14:20 -070013};
14BPF_TABLE("hash", struct IPKey, struct IPLeaf, xlate, 1024);
15
Brenden Blanco22a419b2015-05-29 11:14:20 -070016int on_packet(struct __sk_buff *skb) {
Brenden Blanco6ec65e42015-07-02 10:02:04 -070017 u8 *cursor = 0;
Brenden Blanco22a419b2015-05-29 11:14:20 -070018
19 u32 orig_dip = 0;
20 u32 orig_sip = 0;
21 struct IPLeaf *xleaf;
22
Brenden Blanco6ec65e42015-07-02 10:02:04 -070023 ethernet: {
24 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
Brenden Blanco22a419b2015-05-29 11:14:20 -070025 switch (ethernet->type) {
Brenden Blanco6ec65e42015-07-02 10:02:04 -070026 case ETH_P_IP: goto ip;
27 case ETH_P_ARP: goto arp;
28 case ETH_P_8021Q: goto dot1q;
29 default: goto EOP;
Brenden Blanco22a419b2015-05-29 11:14:20 -070030 }
Brenden Blanco22a419b2015-05-29 11:14:20 -070031 }
32
Brenden Blanco6ec65e42015-07-02 10:02:04 -070033 dot1q: {
34 struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
Brenden Blanco22a419b2015-05-29 11:14:20 -070035 switch (dot1q->type) {
Brenden Blanco6ec65e42015-07-02 10:02:04 -070036 case ETH_P_IP: goto ip;
37 case ETH_P_ARP: goto arp;
38 default: goto EOP;
Brenden Blanco22a419b2015-05-29 11:14:20 -070039 }
Brenden Blanco22a419b2015-05-29 11:14:20 -070040 }
Brenden Blanco6ec65e42015-07-02 10:02:04 -070041
42 arp: {
43 struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
Brenden Blancobb7200c2015-06-04 18:01:42 -070044 orig_dip = arp->tpa;
45 orig_sip = arp->spa;
46 struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
47 xleaf = xlate.lookup(&key);
48 if (xleaf) {
49 arp->tpa = xleaf->xdip;
50 arp->spa = xleaf->xsip;
51 lock_xadd(&xleaf->arp_xlated_pkts, 1);
52 }
53 goto EOP;
54 }
Brenden Blanco22a419b2015-05-29 11:14:20 -070055
Brenden Blanco6ec65e42015-07-02 10:02:04 -070056 ip: {
57 struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
Brenden Blanco22a419b2015-05-29 11:14:20 -070058 orig_dip = ip->dst;
59 orig_sip = ip->src;
60 struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
61 xleaf = xlate.lookup(&key);
62 if (xleaf) {
63 ip->dst = xleaf->xdip;
64 incr_cksum_l3(&ip->hchecksum, orig_dip, xleaf->xdip);
65 ip->src = xleaf->xsip;
66 incr_cksum_l3(&ip->hchecksum, orig_sip, xleaf->xsip);
Brenden Blancobb7200c2015-06-04 18:01:42 -070067 lock_xadd(&xleaf->ip_xlated_pkts, 1);
Brenden Blanco22a419b2015-05-29 11:14:20 -070068 }
69 switch (ip->nextp) {
70 case 6: goto tcp;
71 case 17: goto udp;
Brenden Blanco6ec65e42015-07-02 10:02:04 -070072 default: goto EOP;
Brenden Blanco22a419b2015-05-29 11:14:20 -070073 }
Brenden Blanco22a419b2015-05-29 11:14:20 -070074 }
75
Brenden Blanco6ec65e42015-07-02 10:02:04 -070076 udp: {
77 struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
Brenden Blanco22a419b2015-05-29 11:14:20 -070078 if (xleaf) {
79 incr_cksum_l4(&udp->crc, orig_dip, xleaf->xdip, 1);
80 incr_cksum_l4(&udp->crc, orig_sip, xleaf->xsip, 1);
81 }
82 goto EOP;
83 }
84
Brenden Blanco6ec65e42015-07-02 10:02:04 -070085 tcp: {
86 struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
Brenden Blanco22a419b2015-05-29 11:14:20 -070087 if (xleaf) {
88 incr_cksum_l4(&tcp->cksum, orig_dip, xleaf->xdip, 1);
89 incr_cksum_l4(&tcp->cksum, orig_sip, xleaf->xsip, 1);
90 }
91 goto EOP;
92 }
93
94EOP:
Brenden Blancob4111172015-09-11 09:27:45 -070095 return 0;
Brenden Blanco22a419b2015-05-29 11:14:20 -070096}