def test_brb2(self): try: b = BPF(src_file=arg1, debug=0) self.pem_fn = b.load_func("pem", BPF.SCHED_CLS) self.pem_dest= b.get_table("pem_dest") self.pem_stats = b.get_table("pem_stats") # set up the topology self.set_default_const() (ns1_ipdb, self.ns1_eth_out, _) = sim._create_ns(self.ns1, ipaddr=self.vm1_ip+'/24', fn=self.pem_fn, action='drop', disable_ipv6=True) (ns2_ipdb, self.ns2_eth_out, _) = sim._create_ns(self.ns2, ipaddr=self.vm2_ip+'/24', fn=self.pem_fn, action='drop', disable_ipv6=True) ns1_ipdb.routes.add({'dst': self.vm2_rtr_mask, 'gateway': self.vm1_rtr_ip}).commit() ns2_ipdb.routes.add({'dst': self.vm1_rtr_mask, 'gateway': self.vm2_rtr_ip}).commit() (_, self.nsrtr_eth0_out, _) = sim._create_ns(self.ns_router, ipaddr=self.vm1_rtr_ip+'/24', disable_ipv6=True) (rt_ipdb, self.nsrtr_eth1_out, _) = sim._ns_add_ifc(self.ns_router, "eth1", "ns_router2", ipaddr=self.vm2_rtr_ip+'/24', disable_ipv6=True) # enable ip forwarding in router ns nsp = NSPopen(rt_ipdb.nl.netns, ["sysctl", "-w", "net.ipv4.ip_forward=1"]) nsp.wait(); nsp.release() # for each VM connecting to pem, there will be a corresponding veth connecting to the bridge self.setup_br(self.br1, self.nsrtr_eth0_out.ifname, self.veth_pem_2_br1, self.veth_br1_2_pem) self.setup_br(self.br2, self.nsrtr_eth1_out.ifname, self.veth_pem_2_br2, self.veth_br2_2_pem) # load the program and configure maps self.config_maps() # ping nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"]); nsp.wait(); nsp.release() # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total self.assertEqual(self.pem_stats[c_uint(0)].value, 12) nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"]) sleep(1) nsp = NSPopen(ns1_ipdb.nl.netns, ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"]) nsp.wait(); nsp.release() nsp_server.kill(); nsp_server.wait(); nsp_server.release() nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"]) sleep(1) nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"]) nsp.wait(); nsp.release() nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"]) nsp.wait(); nsp.release() nsp_server.kill(); nsp_server.wait(); nsp_server.release() finally: if self.br1 in ipdb.interfaces: ipdb.interfaces[self.br1].remove().commit() if self.br2 in ipdb.interfaces: ipdb.interfaces[self.br2].remove().commit() if self.veth_pem_2_br1 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br1].remove().commit() if self.veth_pem_2_br2 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br2].remove().commit() sim.release() ipdb.release()
def setUp(self): b = BPF(arg1, arg2, debug=0) fn1 = b.load_func("probe_blk_start_request", BPF.KPROBE) fn2 = b.load_func("probe_blk_update_request", BPF.KPROBE) self.latency = b.get_table("latency", c_uint, c_ulong) BPF.attach_kprobe(fn1, "blk_start_request", -1, 0) BPF.attach_kprobe(fn2, "blk_update_request", -1, 0)
def setUp(self): b = BPF(arg1, arg2, debug=0) fn = b.load_func("on_packet", BPF.SCHED_CLS) ip = IPRoute() ifindex = ip.link_lookup(ifname="eth0")[0] # set up a network to change the flow: # outside | inside # 172.16.1.1 - 172.16.1.2 | 192.168.1.1 - 192.16.1.2 ip.addr("del", index=ifindex, address="172.16.1.2", mask=24) ip.addr("add", index=ifindex, address="192.168.1.2", mask=24) # add an ingress and egress qdisc ip.tc("add", "ingress", ifindex, "ffff:") ip.tc("add", "sfq", ifindex, "1:") # add same program to both ingress/egress, so pkt is translated in both directions ip.tc("add-filter", "bpf", ifindex, ":1", fd=fn.fd, name=fn.name, parent="ffff:", action="ok", classid=1) ip.tc("add-filter", "bpf", ifindex, ":2", fd=fn.fd, name=fn.name, parent="1:", action="ok", classid=1) self.xlate = b.get_table("xlate")
def setUp(self): b = BPF(arg1, arg2, debug=0) self.latency = b.get_table("latency", c_uint, c_ulong) b.attach_kprobe(event="blk_start_request", fn_name="probe_blk_start_request", pid=-1, cpu=0) b.attach_kprobe(event="blk_update_request", fn_name="probe_blk_update_request", pid=-1, cpu=0)
def setUp(self): b = BPF(src_file=arg1, debug=0) ether_fn = b.load_func("parse_ether", BPF.SCHED_CLS) arp_fn = b.load_func("parse_arp", BPF.SCHED_CLS) ip_fn = b.load_func("parse_ip", BPF.SCHED_CLS) eop_fn = b.load_func("eop", BPF.SCHED_CLS) ip = IPRoute() ifindex = ip.link_lookup(ifname="eth0")[0] ip.tc("add", "sfq", ifindex, "1:") ip.tc("add-filter", "bpf", ifindex, ":1", fd=ether_fn.fd, name=ether_fn.name, parent="1:", action="ok", classid=1) self.jump = b.get_table("jump", c_int, c_int) self.jump[c_int(S_ARP)] = c_int(arp_fn.fd) self.jump[c_int(S_IP)] = c_int(ip_fn.fd) self.jump[c_int(S_EOP)] = c_int(eop_fn.fd) self.stats = b.get_table("stats", c_int, c_ulonglong)
def setUp(self): b = BPF(arg1, arg2, debug=0) fn1 = b.load_func("sys_wr", BPF.KPROBE) fn2 = b.load_func("sys_rd", BPF.KPROBE) fn3 = b.load_func("sys_bpf", BPF.KPROBE) self.stats = b.get_table("stats", Key, Leaf) BPF.attach_kprobe(fn1, "sys_write", 0, -1) BPF.attach_kprobe(fn2, "sys_read", 0, -1) BPF.attach_kprobe(fn2, "htab_map_get_next_key", 0, -1)
def test_sscanf(self): text = """ BPF_TABLE("hash", int, struct { u64 a; u64 b; u64 c:36; u64 d:28; struct { u32 a; u32 b; } s; }, stats, 10); int foo(void *ctx) { return 0; } """ b = BPF(text=text, debug=0) fn = b.load_func("foo", BPF.KPROBE) t = b.get_table("stats") s1 = t.key_sprintf(t.Key(2)) self.assertEqual(s1, b"0x2") s2 = t.leaf_sprintf(t.Leaf(2, 3, 4, 1, (5, 6))) l = t.leaf_scanf(s2) self.assertEqual(l.a, 2) self.assertEqual(l.b, 3) self.assertEqual(l.c, 4) self.assertEqual(l.d, 1) self.assertEqual(l.s.a, 5) self.assertEqual(l.s.b, 6)
def setUp(self): b = BPF(arg1, arg2, debug=0) fn = b.load_func("on_packet", BPF.SOCKET_FILTER) BPF.attach_raw_socket(fn, "eth0") self.stats = b.get_table("stats", Key, Leaf)
start = mid if start == -1: return "[unknown]" return ksym_names[start] load_kallsyms() # load BPF program b = BPF(src_file="vfscount.c") fn = b.load_func("do_count", BPF.KPROBE) BPF.attach_kprobe(fn, "vfs_read") BPF.attach_kprobe(fn, "vfs_write") BPF.attach_kprobe(fn, "vfs_fsync") BPF.attach_kprobe(fn, "vfs_open") BPF.attach_kprobe(fn, "vfs_create") counts = b.get_table("counts") # header print "Tracing... Ctrl-C to end." # output try: sleep(99999999) except KeyboardInterrupt: pass print "\n%-16s %-12s %8s" % ("ADDR", "FUNC", "COUNT") for k, v in sorted(counts.items(), key=lambda counts: counts[1].value): print "%-16x %-12s %8d" % (k.ip, ksym(k.ip), v.value)
def setUp(self): b = BPF(text=text, debug=0) self.stats = b.get_table("stats") b.attach_kprobe(event="schedule+50", fn_name="count_sched", pid=0, cpu=-1)
def setUp(self): b = BPF(text=text, debug=0) fn = b.load_func("count_sched", BPF.KPROBE) self.stats = b.get_table("stats") BPF.attach_kprobe(fn, "schedule+50", 0, -1)
from bpf import BPF from builtins import input from ctypes import c_int, c_uint from http.server import HTTPServer, SimpleHTTPRequestHandler import json from netaddr import EUI, IPAddress from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from socket import htons, AF_INET from threading import Thread host_id = int(argv[1]) b = BPF(src_file="tunnel.c") ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) mac2host = b.get_table("mac2host") vni2if = b.get_table("vni2if") conf = b.get_table("conf") ipr = IPRoute() ipdb = IPDB(nl=ipr) ifc = ipdb.interfaces.eth0 mcast = IPAddress("239.1.1.1") # ifcs to cleanup at the end ifc_gc = [] def run(): ipdb.routes.add({"dst": "224.0.0.0/4", "oif": ifc.index}).commit() with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0,
interval = int(argv[1]) if interval == 0: raise if len(argv) > 2: count = int(argv[2]) except: # also catches -h, --help usage() # load BPF program b = BPF(src_file = "vfsstat.c") BPF.attach_kprobe(b.load_func("do_read", BPF.KPROBE), "vfs_read") BPF.attach_kprobe(b.load_func("do_write", BPF.KPROBE), "vfs_write") BPF.attach_kprobe(b.load_func("do_fsync", BPF.KPROBE), "vfs_fsync") BPF.attach_kprobe(b.load_func("do_open", BPF.KPROBE), "vfs_open") BPF.attach_kprobe(b.load_func("do_create", BPF.KPROBE), "vfs_create") stats = b.get_table("stats", c_int, c_ulonglong) # stat column labels and indexes stat_types = { "READ" : 1, "WRITE" : 2, "FSYNC" : 3, "OPEN" : 4, "CREATE" : 5 } # header print("%-8s " % "TIME", end="") last = {} for stype in stat_types.keys(): print(" %8s" % (stype + "/s"), end="")
from time import sleep from simulation import Simulation import sys ipr = IPRoute() ipdb = IPDB(nl=ipr) num_clients = 3 num_vlans = 16 # load the bpf program b = BPF(src_file="vlan_learning.c", debug=0) phys_fn = b.load_func("handle_phys2virt", BPF.SCHED_CLS) virt_fn = b.load_func("handle_virt2phys", BPF.SCHED_CLS) ingress = b.get_table("ingress") egress = b.get_table("egress") class VlanSimulation(Simulation): def __init__(self, ipdb): super(VlanSimulation, self).__init__(ipdb) def start(self): # start identical workers each in a namespace for i in range(0, num_clients): httpmod = ("SimpleHTTPServer" if sys.version_info[0] < 3 else "http.server") cmd = ["python", "-m", httpmod, "80"] self._create_ns("worker%d" % i, cmd=cmd, fn=virt_fn, action="drop", ipaddr="172.16.1.5/24")
import json from netaddr import IPAddress from os import rename from pyroute2 import IPRoute, NetNS, IPDB, NSPopen import sys from time import sleep ipr = IPRoute() ipdb = IPDB(nl=ipr) b = BPF(src_file="monitor.c", debug=0) ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) outer_fn = b.load_func("handle_outer", BPF.SCHED_CLS) inner_fn = b.load_func("handle_inner", BPF.SCHED_CLS) stats = b.get_table("stats") # using jump table for inner and outer packet split parser = b.get_table("parser") parser[c_int(1)] = c_int(outer_fn.fd) parser[c_int(2)] = c_int(inner_fn.fd) ifc = ipdb.interfaces.eth0 ipr.tc("add", "ingress", ifc.index, "ffff:") ipr.tc("add-filter", "bpf", ifc.index, ":1", fd=ingress_fn.fd, name=ingress_fn.name, parent="ffff:",
# # pidpersec.py Count new processes (via fork). # For Linux, uses BCC, eBPF. See .c file. # # Written as a basic example of counting an event. # # 11-Aug-2015 Brendan Gregg Created this. from bpf import BPF from ctypes import c_ushort, c_int, c_ulonglong from time import sleep, strftime # load BPF program b = BPF(src_file="pidpersec.c") BPF.attach_kprobe(b.load_func("do_count", BPF.KPROBE), "sched_fork") stats = b.get_table("stats", c_int, c_ulonglong) # stat indexes S_COUNT = 1 # header print "Tracing... Ctrl-C to end." # output last = 0 while (1): try: sleep(1) except KeyboardInterrupt: pass exit()
def setUp(self): b = BPF(arg1, arg2, debug=0) self.stats = b.get_table("stats", Key, Leaf) b.attach_kprobe(event="sys_write", fn_name="sys_wr", pid=0, cpu=-1) b.attach_kprobe(event="sys_read", fn_name="sys_rd", pid=0, cpu=-1) b.attach_kprobe(event="htab_map_get_next_key", fn_name="sys_rd", pid=0, cpu=-1)
end = mid else: start = mid if start == -1: return "[unknown]" return ksym_names[start] load_kallsyms() # load BPF program b = BPF(src_file = "vfscount.c") fn = b.load_func("do_count", BPF.KPROBE) BPF.attach_kprobe(fn, "vfs_read") BPF.attach_kprobe(fn, "vfs_write") BPF.attach_kprobe(fn, "vfs_fsync") BPF.attach_kprobe(fn, "vfs_open") BPF.attach_kprobe(fn, "vfs_create") counts = b.get_table("counts") # header print "Tracing... Ctrl-C to end." # output try: sleep(99999999) except KeyboardInterrupt: pass print "\n%-16s %-12s %8s" % ("ADDR", "FUNC", "COUNT") for k, v in sorted(counts.items(), key=lambda counts: counts[1].value): print "%-16x %-12s %8d" % (k.ip, ksym(k.ip), v.value)
from http.server import HTTPServer, SimpleHTTPRequestHandler import json from netaddr import EUI, IPAddress from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from socket import htons, AF_INET from threading import Thread from subprocess import call, Popen, PIPE num_hosts = int(argv[1]) host_id = int(argv[2]) dhcp = int(argv[3]) b = BPF(src_file="tunnel_mesh.c") ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) tunkey2if = b.get_table("tunkey2if") if2tunkey = b.get_table("if2tunkey") conf = b.get_table("conf") ipr = IPRoute() ipdb = IPDB(nl=ipr) ifc = ipdb.interfaces.eth0 # ifcs to cleanup at the end ifc_gc = [] # dhcp server and client processes d_serv = [] d_client = []
import json from netaddr import IPAddress from os import rename from pyroute2 import IPRoute, NetNS, IPDB, NSPopen import sys from time import sleep ipr = IPRoute() ipdb = IPDB(nl=ipr) b = BPF(src_file="monitor.c", debug=0) ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) outer_fn = b.load_func("handle_outer", BPF.SCHED_CLS) inner_fn = b.load_func("handle_inner", BPF.SCHED_CLS) stats = b.get_table("stats") # using jump table for inner and outer packet split parser = b.get_table("parser") parser[c_int(1)] = c_int(outer_fn.fd) parser[c_int(2)] = c_int(inner_fn.fd) ifc = ipdb.interfaces.eth0 ipr.tc("add", "ingress", ifc.index, "ffff:") ipr.tc("add-filter", "bpf", ifc.index, ":1", fd=ingress_fn.fd, name=ingress_fn.name, parent="ffff:", action="ok", classid=1) ipr.tc("add", "sfq", ifc.index, "1:") ipr.tc("add-filter", "bpf", ifc.index, ":1", fd=egress_fn.fd, name=egress_fn.name, parent="1:", action="ok", classid=1) def stats2json(k, v):
count = -1 if len(argv) > 1: try: interval = int(argv[1]) if interval == 0: raise if len(argv) > 2: count = int(argv[2]) except: # also catches -h, --help usage() # load BPF program b = BPF(src_file = "vfsreadlat.c") BPF.attach_kprobe(b.load_func("do_entry", BPF.KPROBE), "vfs_read") BPF.attach_kretprobe(b.load_func("do_return", BPF.KPROBE), "vfs_read") dist = b.get_table("dist", c_int, c_ulonglong) dist_max = 64 # header print("Tracing... Hit Ctrl-C to end.") last = {} for i in range(1, dist_max + 1): last[i] = 0 # functions stars_max = 38 def stars(val, val_max, width): i = 0 text = "" while (1): if (i > (width * val / val_max) - 1) or (i > width - 1):
#!/usr/bin/python # Copyright (c) PLUMgrid, Inc. # Licensed under the Apache License, Version 2.0 (the "License") from bpf import BPF from time import sleep b = BPF(src_file="task_switch.c") fn = b.load_func("count_sched", BPF.KPROBE) stats = b.get_table("stats") BPF.attach_kprobe(fn, "finish_task_switch") # generate many schedule events for i in range(0, 100): sleep(0.01) for k, v in stats.items(): print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))
def test_brb2(self): try: b = BPF(src_file=arg1, debug=0) self.pem_fn = b.load_func("pem", BPF.SCHED_CLS) self.pem_dest = b.get_table("pem_dest") self.pem_stats = b.get_table("pem_stats") # set up the topology self.set_default_const() (ns1_ipdb, self.ns1_eth_out, _) = sim._create_ns(self.ns1, ipaddr=self.vm1_ip + '/24', fn=self.pem_fn, action='drop', disable_ipv6=True) (ns2_ipdb, self.ns2_eth_out, _) = sim._create_ns(self.ns2, ipaddr=self.vm2_ip + '/24', fn=self.pem_fn, action='drop', disable_ipv6=True) ns1_ipdb.routes.add({ 'dst': self.vm2_rtr_mask, 'gateway': self.vm1_rtr_ip }).commit() ns2_ipdb.routes.add({ 'dst': self.vm1_rtr_mask, 'gateway': self.vm2_rtr_ip }).commit() (_, self.nsrtr_eth0_out, _) = sim._create_ns(self.ns_router, ipaddr=self.vm1_rtr_ip + '/24', disable_ipv6=True) (rt_ipdb, self.nsrtr_eth1_out, _) = sim._ns_add_ifc(self.ns_router, "eth1", "ns_router2", ipaddr=self.vm2_rtr_ip + '/24', disable_ipv6=True) # enable ip forwarding in router ns nsp = NSPopen(rt_ipdb.nl.netns, ["sysctl", "-w", "net.ipv4.ip_forward=1"]) nsp.wait() nsp.release() # for each VM connecting to pem, there will be a corresponding veth connecting to the bridge self.setup_br(self.br1, self.nsrtr_eth0_out.ifname, self.veth_pem_2_br1, self.veth_br1_2_pem) self.setup_br(self.br2, self.nsrtr_eth1_out.ifname, self.veth_pem_2_br2, self.veth_br2_2_pem) # load the program and configure maps self.config_maps() # ping nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"]) nsp.wait() nsp.release() # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total self.assertEqual(self.pem_stats[c_uint(0)].value, 12) nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"]) sleep(1) nsp = NSPopen(ns1_ipdb.nl.netns, ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"]) nsp.wait() nsp.release() nsp_server.kill() nsp_server.wait() nsp_server.release() nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"]) sleep(1) nsp = NSPopen( ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"]) nsp.wait() nsp.release() nsp = NSPopen( ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"]) nsp.wait() nsp.release() nsp_server.kill() nsp_server.wait() nsp_server.release() finally: if self.br1 in ipdb.interfaces: ipdb.interfaces[self.br1].remove().commit() if self.br2 in ipdb.interfaces: ipdb.interfaces[self.br2].remove().commit() if self.veth_pem_2_br1 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br1].remove().commit() if self.veth_pem_2_br2 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br2].remove().commit() sim.release() ipdb.release()
from builtins import input from ctypes import c_int, c_uint from http.server import HTTPServer, SimpleHTTPRequestHandler import json from netaddr import EUI, IPAddress from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from socket import htons, AF_INET from threading import Thread from subprocess import call host_id = int(argv[1]) b = BPF(src_file="tunnel.c") ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) mac2host = b.get_table("mac2host") vni2if = b.get_table("vni2if") conf = b.get_table("conf") ipr = IPRoute() ipdb = IPDB(nl=ipr) ifc = ipdb.interfaces.eth0 mcast = IPAddress("239.1.1.1") # ifcs to cleanup at the end ifc_gc = [] def run(): ipdb.routes.add({"dst": "224.0.0.0/4", "oif": ifc.index}).commit()
from builtins import input from ctypes import c_int, c_uint from http.server import HTTPServer, SimpleHTTPRequestHandler import json from netaddr import EUI, IPAddress from pyroute2 import IPRoute, NetNS, IPDB, NSPopen from socket import htons, AF_INET from threading import Thread num_hosts = int(argv[1]) host_id = int(argv[2]) b = BPF(src_file="tunnel_mesh.c") ingress_fn = b.load_func("handle_ingress", BPF.SCHED_CLS) egress_fn = b.load_func("handle_egress", BPF.SCHED_CLS) tunkey2if = b.get_table("tunkey2if") if2tunkey = b.get_table("if2tunkey") conf = b.get_table("conf") ipr = IPRoute() ipdb = IPDB(nl=ipr) ifc = ipdb.interfaces.eth0 # ifcs to cleanup at the end ifc_gc = [] def run(): with ipdb.create(ifname="vxlan0", kind="vxlan", vxlan_id=0, vxlan_link=ifc, vxlan_port=htons(4789), vxlan_flowbased=True,