You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.3 KiB
99 lines
2.3 KiB
// Copyright (c) PLUMgrid, Inc.
|
|
// Licensed under the Apache License, Version 2.0 (the "License")
|
|
#include <bcc/proto.h>
|
|
struct IPKey {
|
|
u32 dip;
|
|
u32 sip;
|
|
};
|
|
struct IPLeaf {
|
|
u32 xdip;
|
|
u32 xsip;
|
|
u64 ip_xlated_pkts;
|
|
u64 arp_xlated_pkts;
|
|
};
|
|
BPF_HASH(xlate, struct IPKey, struct IPLeaf, 1024);
|
|
|
|
int on_packet(struct __sk_buff *skb) {
|
|
u8 *cursor = 0;
|
|
|
|
u32 orig_dip = 0;
|
|
u32 orig_sip = 0;
|
|
struct IPLeaf xleaf = {};
|
|
|
|
ethernet: {
|
|
struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
|
|
switch (ethernet->type) {
|
|
case ETH_P_IP: goto ip;
|
|
case ETH_P_ARP: goto arp;
|
|
case ETH_P_8021Q: goto dot1q;
|
|
default: goto EOP;
|
|
}
|
|
}
|
|
|
|
dot1q: {
|
|
struct dot1q_t *dot1q = cursor_advance(cursor, sizeof(*dot1q));
|
|
switch (dot1q->type) {
|
|
case ETH_P_IP: goto ip;
|
|
case ETH_P_ARP: goto arp;
|
|
default: goto EOP;
|
|
}
|
|
}
|
|
|
|
arp: {
|
|
struct arp_t *arp = cursor_advance(cursor, sizeof(*arp));
|
|
orig_dip = arp->tpa;
|
|
orig_sip = arp->spa;
|
|
struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
|
|
struct IPLeaf *xleafp = xlate.lookup(&key);
|
|
if (xleafp) {
|
|
xleaf = *xleafp;
|
|
arp->tpa = xleaf.xdip;
|
|
arp->spa = xleaf.xsip;
|
|
lock_xadd(&xleafp->arp_xlated_pkts, 1);
|
|
}
|
|
goto EOP;
|
|
}
|
|
|
|
ip: {
|
|
struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
|
|
orig_dip = ip->dst;
|
|
orig_sip = ip->src;
|
|
struct IPKey key = {.dip=orig_dip, .sip=orig_sip};
|
|
struct IPLeaf *xleafp = xlate.lookup(&key);
|
|
if (xleafp) {
|
|
xleaf = *xleafp;
|
|
ip->dst = xleaf.xdip;
|
|
incr_cksum_l3(&ip->hchecksum, orig_dip, xleaf.xdip);
|
|
ip->src = xleaf.xsip;
|
|
incr_cksum_l3(&ip->hchecksum, orig_sip, xleaf.xsip);
|
|
lock_xadd(&xleafp->ip_xlated_pkts, 1);
|
|
}
|
|
switch (ip->nextp) {
|
|
case 6: goto tcp;
|
|
case 17: goto udp;
|
|
default: goto EOP;
|
|
}
|
|
}
|
|
|
|
udp: {
|
|
struct udp_t *udp = cursor_advance(cursor, sizeof(*udp));
|
|
if (xleaf.xdip) {
|
|
incr_cksum_l4(&udp->crc, orig_dip, xleaf.xdip, 1);
|
|
incr_cksum_l4(&udp->crc, orig_sip, xleaf.xsip, 1);
|
|
}
|
|
goto EOP;
|
|
}
|
|
|
|
tcp: {
|
|
struct tcp_t *tcp = cursor_advance(cursor, sizeof(*tcp));
|
|
if (xleaf.xdip) {
|
|
incr_cksum_l4(&tcp->cksum, orig_dip, xleaf.xdip, 1);
|
|
incr_cksum_l4(&tcp->cksum, orig_sip, xleaf.xsip, 1);
|
|
}
|
|
goto EOP;
|
|
}
|
|
|
|
EOP:
|
|
return 0;
|
|
}
|