1 // Copyright (c) PLUMgrid, Inc. 2 // Licensed under the Apache License, Version 2.0 (the "License") 3 4 #include <bcc/proto.h> 5 6 struct ipkey { 7 u32 client_ip; 8 }; 9 10 BPF_HASH(learned_ips, struct ipkey, int, 1024); 11 12 // trivial action 13 int pass(struct __sk_buff *skb) { 14 return 1; 15 } 16 17 // Process each wan packet, and determine if the packet is in the IP 18 // table or not. Learned IPs are rate-limited and unclassified are not. 19 // returns: > 0 when an IP is known 20 // = 0 when an IP is not known, or non-IP traffic 21 int classify_wan(struct __sk_buff *skb) { 22 u8 *cursor = 0; 23 ethernet: { 24 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); 25 switch (ethernet->type) { 26 case ETH_P_IP: goto ip; 27 default: goto EOP; 28 } 29 } 30 ip: { 31 struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); 32 u32 dip = ip->dst; 33 struct ipkey key = {.client_ip=dip}; 34 int *val = learned_ips.lookup(&key); 35 if (val) 36 return *val; 37 goto EOP; 38 } 39 EOP: 40 return 0; 41 } 42 43 // Process each neighbor packet, and store the source IP in the learned table. 44 // Mark the inserted entry with a non-zero value to be used by the classify_wan 45 // lookup. 46 int classify_neighbor(struct __sk_buff *skb) { 47 u8 *cursor = 0; 48 ethernet: { 49 struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet)); 50 switch (ethernet->type) { 51 case ETH_P_IP: goto ip; 52 default: goto EOP; 53 } 54 } 55 ip: { 56 struct ip_t *ip = cursor_advance(cursor, sizeof(*ip)); 57 u32 sip = ip->src; 58 struct ipkey key = {.client_ip=sip}; 59 int val = 1; 60 learned_ips.insert(&key, &val); 61 goto EOP; 62 } 63 EOP: 64 return 1; 65 } 66