int bpf_prog1(struct pt_regs *ctx) { /* attaches to kprobe netif_receive_skb, * looks for packets on loobpack device and prints them */ char devname[IFNAMSIZ] = {}; struct net_device *dev; struct sk_buff *skb; int len; /* non-portable! works for the given kernel only */ skb = (struct sk_buff *) PT_REGS_PARM1(ctx); dev = _(skb->dev); len = _(skb->len); bpf_probe_read(devname, sizeof(devname), dev->name); if (devname[0] == 'l' && devname[1] == 'o') { char fmt[] = "skb %p len %d\n"; /* using bpf_trace_printk() for DEBUG ONLY */ bpf_trace_printk(fmt, sizeof(fmt), skb, len); } return 0; }
int handle_rx_wrapper(struct __sk_buff *skb) { int md_id = skb->cb[0]; struct metadata *md = metadata.lookup(&md_id); if (!md) { bpf_trace_printk("metadata lookup failed\n"); return TC_ACT_SHOT; } // copy to stack in cases llvm spills map pointers to stack //struct metadata local_md = *md; //local_md.flags = 0; //local_md.redir_ifc = 0; //local_md.clone_ifc = 0; md->flags = 0; md->redir_ifc = 0; md->clone_ifc = 0; int rc = handle_rx(skb, md); // TODO: implementation switch (rc) { case RX_OK: break; case RX_REDIRECT: break; case RX_RECIRCULATE: modules.call(skb, 1); break; case RX_DROP: return TC_ACT_SHOT; } //metadata.update(&md_id, &local_md); modules.call(skb, 0); return TC_ACT_SHOT; }
int bpf_prog1(struct pt_regs *ctx) { u64 count; u32 key = bpf_get_smp_processor_id(); char fmt[] = "CPU-%d %llu\n"; count = bpf_perf_event_read(&my_map, key); bpf_trace_printk(fmt, sizeof(fmt), key, count); return 0; }
PROG(__NR_read)(struct pt_regs *ctx) { struct seccomp_data sd; bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM1(ctx)); if (sd.args[2] > 128 && sd.args[2] <= 1024) { char fmt[] = "read(fd=%d, buf=%p, size=%d)\n"; bpf_trace_printk(fmt, sizeof(fmt), sd.args[0], sd.args[1], sd.args[2]); } return 0; }
/* we jump here when syscall number == __NR_write */ PROG(__NR_write)(struct pt_regs *ctx) { struct seccomp_data sd; bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM2(ctx)); if (sd.args[2] == 512) { char fmt[] = "write(fd=%d, buf=%p, size=%d)\n"; bpf_trace_printk(fmt, sizeof(fmt), sd.args[0], sd.args[1], sd.args[2]); } return 0; }
int kprobe___do_fork(struct pt_regs *ctx, unsigned long clone_flags) { int lowbit = clone_flags & 1023; int n=0; bpf_probe_read(&n, sizeof(int), (void*)0xffffffff81fde2b0/*0xffffffff81ef2f24*/); bpf_trace_printk("total cpu: %d\n", n); u64 zero = 0; u64* tmp = dist.lookup_or_init(&lowbit, &zero); if(tmp) { (*tmp)++; } return 0; }
int bpf_prog1(struct pt_regs *ctx) { int sc_nr = (int)PT_REGS_PARM1(ctx); /* dispatch into next BPF program depending on syscall number */ bpf_tail_call(ctx, &progs, sc_nr); /* fall through -> unknown syscall */ if (sc_nr >= __NR_getuid && sc_nr <= __NR_getsid) { char fmt[] = "syscall=%d (one of get/set uid/pid/gid)\n"; bpf_trace_printk(fmt, sizeof(fmt), sc_nr); } return 0; }
int bpf_prog1(struct pt_regs *ctx) { struct seccomp_data sd; bpf_probe_read(&sd, sizeof(sd), (void *)PT_REGS_PARM1(ctx)); /* dispatch into next BPF program depending on syscall number */ bpf_tail_call(ctx, &progs, sd.nr); /* fall through -> unknown syscall */ if (sd.nr >= __NR_getuid && sd.nr <= __NR_getsid) { char fmt[] = "syscall=%d (one of get/set uid/pid/gid)\n"; bpf_trace_printk(fmt, sizeof(fmt), sd.nr); } return 0; }
static int udp(void *data, uint64_t tp_off, void *data_end) { struct udphdr *udp = data + tp_off; if (udp + 1 > data_end) return 0; if (udp->dest == htons(DEFAULT_PKTGEN_UDP_PORT) || udp->source == htons(DEFAULT_PKTGEN_UDP_PORT)) { if (DEBUG) { char fmt[] = "udp port 9 indeed\n"; bpf_trace_printk(fmt, sizeof(fmt)); } return TC_ACT_SHOT; } return 0; }
static int main_prog (struct __sk_buff *skb) { int from = skb->cb[0]; int me = 0; if (from == 0) me = 1; else me = 2; char msg [] = "In module of container: %d\n"; bpf_trace_printk(msg, sizeof(msg), me); if (me == 2) { bpf_redirect(skb->ifindex, 1); } skb->cb[0] = me; bpf_tail_call(skb, &jmp_table, 0); return 0; }
static inline int do_redirect(struct __sk_buff *skb, int nh_off, int dir) { __u16 dport, off; __u8 ip_proto, ip_vl; int *ifindex; __be32 ip_dest, ip_src; char fmt[] = "skb %p len %d ip_dest %x\n"; ip_proto = load_byte(skb, nh_off + offsetof(struct iphdr, protocol)); ip_src = load_word(skb, nh_off + offsetof(struct iphdr, saddr)); ip_dest = load_word(skb, nh_off + offsetof(struct iphdr, daddr)); if (ip_proto != IPPROTO_TCP) return 0; ip_vl = load_byte(skb, nh_off); if (likely(ip_vl == 0x45)) nh_off += sizeof(struct iphdr); else nh_off += (ip_vl & 0xF) << 2; bpf_trace_printk(fmt, sizeof(fmt), skb, skb->len, ip_dest); dport = load_half(skb, nh_off + offsetof(struct tcphdr, dest)); if (dport != 80) return 0; if (dir == 0) { ifindex = bpf_map_lookup_elem(&container_map, &ip_dest); if (ifindex) { set_tcp_dest_port(skb, 8080); bpf_clone_redirect(skb, *ifindex, 1); } } else { ifindex = bpf_map_lookup_elem(&container_map, &ip_src); if (ifindex) set_tcp_dest_port(skb, 80); } return -1; }
int bpf_prog2(struct pt_regs *ctx) { long rq = ctx->di; struct request *req = (struct request *)ctx->di; u64 *value, l, base, cur_time, delta; u32 index; /* calculate latency */ value = bpf_map_lookup_elem(&start_ts, &rq); if (!value) return 0; cur_time = bpf_ktime_get_ns(); delta = cur_time - *value; bpf_map_delete_elem(&start_ts, &rq); /* using bpf_trace_printk() for DEBUG ONLY; limited to 3 args. */ char fmt[] = "%d %x %d\n"; bpf_trace_printk(fmt, sizeof(fmt), _(req->__data_len), /* bytes */ _(req->cmd_flags), /* flags */ delta / 1000); /* lat_us */ return 0; }
PROG(__NR_mmap)(struct pt_regs *ctx) { char fmt[] = "mmap\n"; bpf_trace_printk(fmt, sizeof(fmt)); return 0; }
int main_prog (struct __sk_buff * skb) { char msg [] = "In container's module\n\n"; bpf_trace_printk(msg, sizeof(msg)); return 0; }
int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\n"); return 0; }
static int handle_rx(void *skb, struct metadata *md) { struct __sk_buff *skb2 = (struct __sk_buff *)skb; void *data = (void *)(long)skb2->data; void *data_end = (void *)(long)skb2->data_end; struct eth_hdr *eth = data; if (data + sizeof(*eth) > data_end) return RX_DROP; u32 in_ifc = md->in_ifc; #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: in_ifc=%d\n", md->module_id, in_ifc); #endif // port security on source mac #ifdef MAC_SECURITY_INGRESS __be64 *mac_lookup = securitymac.lookup(&in_ifc); if (mac_lookup) if (eth->src != *mac_lookup) { #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: mac INGRESS %lx mismatch %lx -> DROP\n", md->module_id, PRINT_MAC(eth->src), PRINT_MAC(*mac_lookup)); #endif return RX_DROP; } #endif // port security on source ip #ifdef IP_SECURITY_INGRESS if (eth->proto == bpf_htons(ETH_P_IP)) { __be32 *ip_lookup = securityip.lookup(&in_ifc); if (ip_lookup) { struct ip_t *ip = data + sizeof(*eth); if (data + sizeof(*eth) + sizeof(*ip) > data_end) return RX_DROP; if (ip->src != *ip_lookup) { #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: IP INGRESS %x mismatch %x -> DROP\n", md->module_id, bpf_htonl(ip->src), bpf_htonl(*ip_lookup)); #endif return RX_DROP; } } } #endif #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: mac src:%lx dst:%lx\n", md->module_id, PRINT_MAC(eth->src), PRINT_MAC(eth->dst)); #endif //LEARNING PHASE: mapping in_ifc with src_interface __be64 src_key = eth->src; //lookup in fwdtable. if no key present initialize with interface u32 *interface_lookup = fwdtable.lookup_or_init(&src_key, &in_ifc); //if the same mac has changed interface, update it if (*interface_lookup != in_ifc) *interface_lookup = in_ifc; //FORWARDING PHASE: select interface(s) to send the packet __be64 dst_mac = eth->dst; //lookup in forwarding table fwdtable u32 *dst_interface = fwdtable.lookup(&dst_mac); if (dst_interface) { //HIT in forwarding table //redirect packet to dst_interface #ifdef MAC_SECURITY_EGRESS u32 out_iface = *dst_interface; __be64 *mac_lookup = securitymac.lookup(&out_iface); if (mac_lookup) if (eth->dst != *mac_lookup){ #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: mac EGRESS %lx mismatch %lx -> DROP\n", md->module_id, PRINT_MAC(eth->dst), PRINT_MAC(*mac_lookup)); #endif return RX_DROP; } #endif /* do not send packet back on the ingress interface */ if (*dst_interface == in_ifc) return RX_DROP; pkt_redirect(skb, md, *dst_interface); #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: redirect out_ifc=%d\n", md->module_id, *dst_interface); #endif return RX_REDIRECT; } else { #ifdef BPF_TRACE bpf_trace_printk("[switch-%d]: Broadcast\n", md->module_id); #endif pkt_controller(skb, md, PKT_BROADCAST); return RX_CONTROLLER; } }