Home | History | Annotate | Download | only in python
      1 // Copyright (c) PLUMgrid, Inc.
      2 // Licensed under the Apache License, Version 2.0 (the "License")
      3 #include <bcc/proto.h>
      4 struct IPKey {
      5   u32 dip;
      6   u32 sip;
      7 };
      8 struct IPLeaf {
      9   u32 xdip;
     10   u32 xsip;
     11   u64 ip_xlated_pkts;
     12   u64 arp_xlated_pkts;
     13 };
     14 BPF_HASH(xlate, struct IPKey, struct IPLeaf, 1024);
     15 
     16 int on_packet(struct __sk_buff *skb) {
     17   u8 *cursor = 0;
     18 
     19   u32 orig_dip = 0;
     20   u32 orig_sip = 0;
     21   struct IPLeaf xleaf = {};
     22 
     23   ethernet: {
     24     struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
     25     switch (ethernet->type) {
     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;
     30     }
     31   }
     32 
     33   dot1q: {
     34     struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
     35     switch (dot1q->type) {
     36       case ETH_P_IP: goto ip;
     37       case ETH_P_ARP: goto arp;
     38       default: goto EOP;
     39     }
     40   }
     41 
     42   arp: {
     43     struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
     44     orig_dip = arp->tpa;
     45     orig_sip = arp->spa;
     46     struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
     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);
     53     }
     54     goto EOP;
     55   }
     56 
     57   ip: {
     58     struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
     59     orig_dip = ip->dst;
     60     orig_sip = ip->src;
     61     struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
     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);
     70     }
     71     switch (ip->nextp) {
     72       case 6: goto tcp;
     73       case 17: goto udp;
     74       default: goto EOP;
     75     }
     76   }
     77 
     78   udp: {
     79     struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
     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);
     83     }
     84     goto EOP;
     85   }
     86 
     87   tcp: {
     88     struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
     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);
     92     }
     93     goto EOP;
     94   }
     95 
     96 EOP:
     97   return 0;
     98 }
     99