| Brenden Blanco | 246b942 | 2015-06-05 11:15:27 -0700 | [diff] [blame] | 1 | // Copyright (c) PLUMgrid, Inc. |
| 2 | // Licensed under the Apache License, Version 2.0 (the "License") |
| Brenden Blanco | 8310291 | 2015-06-09 17:43:27 -0700 | [diff] [blame] | 3 | #include <bcc/proto.h> |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 4 | struct IPKey { |
| 5 | u32 dip; |
| 6 | u32 sip; |
| 7 | }; |
| 8 | struct IPLeaf { |
| 9 | u32 xdip; |
| 10 | u32 xsip; |
| Brenden Blanco | bb7200c | 2015-06-04 18:01:42 -0700 | [diff] [blame] | 11 | u64 ip_xlated_pkts; |
| 12 | u64 arp_xlated_pkts; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 13 | }; |
| 14 | BPF_TABLE("hash", struct IPKey, struct IPLeaf, xlate, 1024); |
| 15 | |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 16 | int on_packet(struct __sk_buff *skb) { |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 17 | u8 *cursor = 0; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 18 | |
| 19 | u32 orig_dip = 0; |
| 20 | u32 orig_sip = 0; |
| Brenden Blanco | 35c7225 | 2016-11-23 16:26:01 -0800 | [diff] [blame] | 21 | struct IPLeaf xleaf = {}; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 22 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 23 | ethernet: { |
| 24 | struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 25 | switch (ethernet->type) { |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 26 | 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 Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 30 | } |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 31 | } |
| 32 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 33 | dot1q: { |
| 34 | struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 35 | switch (dot1q->type) { |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 36 | case ETH_P_IP: goto ip; |
| 37 | case ETH_P_ARP: goto arp; |
| 38 | default: goto EOP; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 39 | } |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 40 | } |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 41 | |
| 42 | arp: { |
| 43 | struct arp_t *arp = cursor_advance(cursor, sizeof(*arp)); |
| Brenden Blanco | bb7200c | 2015-06-04 18:01:42 -0700 | [diff] [blame] | 44 | orig_dip = arp->tpa; |
| 45 | orig_sip = arp->spa; |
| 46 | struct IPKey key = {.dip=orig_dip, .sip=orig_sip}; |
| Brenden Blanco | 35c7225 | 2016-11-23 16:26:01 -0800 | [diff] [blame] | 47 | struct IPLeaf *xleafp = xlate.lookup(&key); |
| 48 | if (xleafp) { |
| 49 | xleaf = *xleafp; |
| 50 | arp->tpa = xleaf.xdip; |
| 51 | arp->spa = xleaf.xsip; |
| 52 | lock_xadd(&xleafp->arp_xlated_pkts, 1); |
| Brenden Blanco | bb7200c | 2015-06-04 18:01:42 -0700 | [diff] [blame] | 53 | } |
| 54 | goto EOP; |
| 55 | } |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 56 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 57 | ip: { |
| 58 | struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 59 | orig_dip = ip->dst; |
| 60 | orig_sip = ip->src; |
| 61 | struct IPKey key = {.dip=orig_dip, .sip=orig_sip}; |
| Brenden Blanco | 35c7225 | 2016-11-23 16:26:01 -0800 | [diff] [blame] | 62 | struct IPLeaf *xleafp = xlate.lookup(&key); |
| 63 | if (xleafp) { |
| 64 | xleaf = *xleafp; |
| 65 | ip->dst = xleaf.xdip; |
| 66 | incr_cksum_l3(&ip->hchecksum, orig_dip, xleaf.xdip); |
| 67 | ip->src = xleaf.xsip; |
| 68 | incr_cksum_l3(&ip->hchecksum, orig_sip, xleaf.xsip); |
| 69 | lock_xadd(&xleafp->ip_xlated_pkts, 1); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 70 | } |
| 71 | switch (ip->nextp) { |
| 72 | case 6: goto tcp; |
| 73 | case 17: goto udp; |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 74 | default: goto EOP; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 75 | } |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 76 | } |
| 77 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 78 | udp: { |
| 79 | struct udp_t *udp = cursor_advance(cursor, sizeof(*udp)); |
| Brenden Blanco | 35c7225 | 2016-11-23 16:26:01 -0800 | [diff] [blame] | 80 | if (xleaf.xdip) { |
| 81 | incr_cksum_l4(&udp->crc, orig_dip, xleaf.xdip, 1); |
| 82 | incr_cksum_l4(&udp->crc, orig_sip, xleaf.xsip, 1); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 83 | } |
| 84 | goto EOP; |
| 85 | } |
| 86 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 87 | tcp: { |
| 88 | struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp)); |
| Brenden Blanco | 35c7225 | 2016-11-23 16:26:01 -0800 | [diff] [blame] | 89 | if (xleaf.xdip) { |
| 90 | incr_cksum_l4(&tcp->cksum, orig_dip, xleaf.xdip, 1); |
| 91 | incr_cksum_l4(&tcp->cksum, orig_sip, xleaf.xsip, 1); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 92 | } |
| 93 | goto EOP; |
| 94 | } |
| 95 | |
| 96 | EOP: |
| Brenden Blanco | b411117 | 2015-09-11 09:27:45 -0700 | [diff] [blame] | 97 | return 0; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 98 | } |