| 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; |
| 21 | struct IPLeaf *xleaf; |
| 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}; |
| 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 Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 55 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 56 | ip: { |
| 57 | struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 58 | 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 Blanco | bb7200c | 2015-06-04 18:01:42 -0700 | [diff] [blame] | 67 | lock_xadd(&xleaf->ip_xlated_pkts, 1); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 68 | } |
| 69 | switch (ip->nextp) { |
| 70 | case 6: goto tcp; |
| 71 | case 17: goto udp; |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 72 | default: goto EOP; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 73 | } |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 74 | } |
| 75 | |
| Brenden Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 76 | udp: { |
| 77 | struct udp_t *udp = cursor_advance(cursor, sizeof(*udp)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 78 | 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 Blanco | 6ec65e4 | 2015-07-02 10:02:04 -0700 | [diff] [blame] | 85 | tcp: { |
| 86 | struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp)); |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 87 | 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 | |
| 94 | EOP: |
| Brenden Blanco | b411117 | 2015-09-11 09:27:45 -0700 | [diff] [blame^] | 95 | return 0; |
| Brenden Blanco | 22a419b | 2015-05-29 11:14:20 -0700 | [diff] [blame] | 96 | } |