Example #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")
Example #2
0
    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()
Example #3
0
    def test_probe_read2(self):
        text = """
#include <linux/sched.h>
#include <uapi/linux/ptrace.h>
int count_foo(struct pt_regs *ctx, unsigned long a, unsigned long b) {
    return (a != b);
}
"""
        b = BPF(text=text, debug=0)
        fn = b.load_func("count_foo", BPF.KPROBE)
Example #4
0
 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)
Example #5
0
    def test_probe_read1(self):
        text = """
#include <linux/sched.h>
#include <uapi/linux/ptrace.h>
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
    pid_t p = prev->pid;
    return (p != -1);
}
"""
        b = BPF(text=text, debug=0)
        fn = b.load_func("count_sched", BPF.KPROBE)
Example #6
0
    def test_blk_start_request(self):
        text = """
#include <linux/blkdev.h>
#include <uapi/linux/ptrace.h>
int do_request(struct pt_regs *ctx, int req) {
    bpf_trace_printk("req ptr: 0x%x\\n", req);
    return 0;
}
"""
        b = BPF(text=text, debug=0)
        fn = b.load_func("do_request", BPF.KPROBE)
Example #7
0
    def test_printk(self):
        text = """
#include <bcc/proto.h>
int handle_packet(void *ctx) {
  u8 *cursor = 0;
  struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
  bpf_trace_printk("ethernet->dst = %llx, ethernet->src = %llx\\n",
                   ethernet->dst, ethernet->src);
  return 0;
}
"""
        b = BPF(text=text, debug=0)
        fn = b.load_func("handle_packet", BPF.SCHED_CLS)
Example #8
0
 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)
Example #9
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")
Example #10
0
    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)
Example #11
0
    def test_iosnoop(self):
        text = """
#include <linux/blkdev.h>
#include <uapi/linux/ptrace.h>

struct key_t {
    struct request *req;
};

BPF_TABLE("hash", struct key_t, u64, start, 1024);
int do_request(struct pt_regs *ctx, struct request *req) {
    struct key_t key = {};

    bpf_trace_printk("traced start %d\\n", req->__data_len);

    return 0;
}
"""
        b = BPF(text=text, debug=0)
        fn = b.load_func("do_request", BPF.KPROBE)
Example #12
0
    def __init__(self, login_info):
        # bind the h3c client to the EAP protocol
        try:
            self.client = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                                        socket.htons(ETHERTYPE_PAE))
            self.client.bind((login_info['ethernet_interface'], ETHERTYPE_PAE))
            # get local ethernet card address
            self.mac_addr = self.client.getsockname()[4]
        except AttributeError:
            self.client = BPF(ETHERTYPE_PAE)
            self.client.bind(login_info['ethernet_interface'])
            self.mac_addr = self.client.get_mac_address(
                login_info['ethernet_interface'])

        self.ethernet_header = get_ethernet_header(self.mac_addr,
                                                   PAE_GROUP_ADDR,
                                                   ETHERTYPE_PAE)
        self.has_sent_logoff = False
        self.login_info = login_info
        self.version_info = '\x06\x07bjQ7SE8BZ3MqHhs3clMregcDY3Y=\x20\x20'
Example #13
0
 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)
Example #14
0
class TestKprobeRgx(TestCase):
    def setUp(self):
        self.b = BPF(
            text="""
        typedef struct { int idx; } Key;
        typedef struct { u64 val; } Val;
        BPF_TABLE("array", Key, Val, stats, 3);
        int hello(void *ctx) {
          stats.lookup_or_init(&(Key){1}, &(Val){0})->val++;
          return 0;
        }
        int goodbye(void *ctx) {
          stats.lookup_or_init(&(Key){2}, &(Val){0})->val++;
          return 0;
        }
        """
        )
        self.b.attach_kprobe(event_re="^SyS_bp.*", fn_name="hello")
        self.b.attach_kretprobe(event_re="^SyS_bp.*", fn_name="goodbye")

    def test_send1(self):
        k1 = self.b["stats"].Key(1)
        k2 = self.b["stats"].Key(2)
        self.assertEqual(self.b["stats"][k1].val, self.b["stats"][k2].val + 1)
Example #15
0
File: eapauth.py Project: lpy/YaH3C
    def __init__(self, login_info):
        # bind the h3c client to the EAP protocol
        try:
            self.client = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETHERTYPE_PAE))
            self.client.bind((login_info['ethernet_interface'], ETHERTYPE_PAE))
            # get local ethernet card address
            self.mac_addr = self.client.getsockname()[4]
        except AttributeError:
            self.client = BPF(ETHERTYPE_PAE)
            self.client.bind(login_info['ethernet_interface'])
            self.mac_addr = self.client.get_mac_address(login_info['ethernet_interface'])

        self.ethernet_header = get_ethernet_header(self.mac_addr, PAE_GROUP_ADDR, ETHERTYPE_PAE)
        self.has_sent_logoff = False
        self.login_info = login_info
        self.version_info = '\x06\x07bjQ7SE8BZ3MqHhs3clMregcDY3Y=\x20\x20'
Example #16
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)
Example #17
0
 def setUp(self):
     self.b = BPF(
         text="""
     typedef struct { int idx; } Key;
     typedef struct { u64 val; } Val;
     BPF_TABLE("array", Key, Val, stats, 3);
     int hello(void *ctx) {
       stats.lookup_or_init(&(Key){1}, &(Val){0})->val++;
       return 0;
     }
     int goodbye(void *ctx) {
       stats.lookup_or_init(&(Key){2}, &(Val){0})->val++;
       return 0;
     }
     """
     )
     self.b.attach_kprobe(event_re="^SyS_bp.*", fn_name="hello")
     self.b.attach_kretprobe(event_re="^SyS_bp.*", fn_name="goodbye")
Example #18
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)
Example #19
0
File: tunnel.py Project: hgn/bcc
# Licensed under the Apache License, Version 2.0 (the "License")

from sys import argv
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 = []
Example #20
0
from bpf import BPF
from builtins import input
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
from random import shuffle
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")
Example #21
0
File: simple_tc.py Project: hgn/bcc
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from bpf import BPF
from pyroute2 import IPRoute

ipr = IPRoute()

text = """
int hello(struct __sk_buff *skb) {
  return 1;
}
"""

try:
    b = BPF(text=text, debug=0)
    fn = b.load_func("hello", BPF.SCHED_CLS)
    ipr.link_create(ifname="t1a", kind="veth", peer="t1b")
    idx = ipr.link_lookup(ifname="t1a")[0]

    ipr.tc("add", "ingress", idx, "ffff:")
    ipr.tc("add-filter", "bpf", idx, ":1", fd=fn.fd,
           name=fn.name, parent="ffff:", action="ok", classid=1)
    ipr.tc("add", "sfq", idx, "1:")
    ipr.tc("add-filter", "bpf", idx, ":1", fd=fn.fd,
           name=fn.name, parent="1:", action="ok", classid=1)
finally:
    if "idx" in locals(): ipr.link_remove(idx)
Example #22
0
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# run in project examples directory with:
# sudo ./hello_world.py"

from bpf import BPF
from subprocess import call

prog = """
int hello(void *ctx) {
  bpf_trace_printk("Hello, World!\\n");
  return 0;
};
"""
b = BPF(text=prog)
fn = b.load_func("hello", BPF.KPROBE)
BPF.attach_kprobe(fn, "sys_clone")
try:
    call(["cat", "/sys/kernel/debug/tracing/trace_pipe"])
except KeyboardInterrupt:
    pass
Example #23
0
 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)
Example #24
0
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
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
Example #25
0
#
# syncsnoop.py	Trace sync() syscall.
#		For Linux, uses BCC, eBPF. Embedded C.
#
# Written as a basic example of BCC trace & reformat. See hello_world.py
# for a BCC trace with default output example.
#
# 13-Aug-2015	Brendan Gregg	Created this.

from bpf import BPF
import sys

# load BPF program
b = BPF(text = """
int do_sync(void *ctx) {
	bpf_trace_printk("sync()\\n");
	return 0;
};
""")
BPF.attach_kprobe(b.load_func("do_sync", BPF.KPROBE), "sys_sync")

# header
print "%-18s %s" % ("TIME(s)", "CALL")

# open trace pipe
try:
	trace = open("/sys/kernel/debug/tracing/trace_pipe", "r")
except:
	print >> sys.stderr, "ERROR: opening trace_pipe"
	exit(1)

# format output
Example #26
0
 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)
Example #27
0
 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)
Example #28
0
#!/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))
Example #29
0
    def test_brb(self):
        try:
            b = BPF(src_file=arg1, debug=0)
            self.pem_fn = b.load_func("pem", BPF.SCHED_CLS)
            self.br1_fn = b.load_func("br1", BPF.SCHED_CLS)
            self.br2_fn = b.load_func("br2", BPF.SCHED_CLS)
            self.get_table(b)

            # 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.vm1_mac = ns1_ipdb.interfaces['eth0'].address
            self.vm2_mac = ns2_ipdb.interfaces['eth0'].address

            (_, self.nsrtr_eth0_out,
             _) = sim._create_ns(self.ns_router,
                                 ipaddr=self.vm1_rtr_ip + '/24',
                                 fn=self.br1_fn,
                                 action='drop',
                                 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',
                                  fn=self.br2_fn,
                                  action='drop',
                                  disable_ipv6=True)
            nsp = NSPopen(rt_ipdb.nl.netns,
                          ["sysctl", "-w", "net.ipv4.ip_forward=1"])
            nsp.wait()
            nsp.release()

            # configure maps
            self.config_maps()

            # our bridge is not smart enough, so send arping for router learning to prevent router
            # from sending out arp request
            nsp = NSPopen(ns1_ipdb.nl.netns, [
                "arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm1_rtr_ip
            ])
            nsp.wait()
            nsp.release()
            nsp = NSPopen(ns2_ipdb.nl.netns, [
                "arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm2_rtr_ip
            ])
            nsp.wait()
            nsp.release()

            # ping
            nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"])
            nsp.wait()
            nsp.release()
            # pem_stats only counts pem->bridge traffic, each VM has 4: arping/arp request/2 icmp request
            # total 8 packets should be counted
            self.assertEqual(self.pem_stats[c_uint(0)].value, 8)

            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:
            sim.release()
            ipdb.release()
Example #30
0
#          | clsfy_neigh() |            |   ^    \------/        |
# lan1 ----|->->->->->->->-|    <--1Mb--|   |                    |
# lan2 ----|->->->->->->->-|            |   classify_wan()       |
#            ^             \------------/                        |
#            pass()                                              |

from bpf import BPF
from pyroute2 import IPRoute, NetNS, IPDB, NSPopen
from simulation import Simulation
import sys
from time import sleep
from builtins import input

ipr = IPRoute()
ipdb = IPDB(nl=ipr)
b = BPF(src_file="tc_neighbor_sharing.c", debug=0)

wan_fn = b.load_func("classify_wan", BPF.SCHED_CLS)
pass_fn = b.load_func("pass", BPF.SCHED_CLS)
neighbor_fn = b.load_func("classify_neighbor", BPF.SCHED_CLS)

num_neighbors = 3
num_locals = 2


# class to build the simulation network
class SharedNetSimulation(Simulation):
    def __init__(self, ipdb):
        super(SharedNetSimulation, self).__init__(ipdb)

        # Create the wan namespace, and attach an ingress filter for throttling
Example #31
0
#!/usr/bin/python
#
# disksnoop.py	Trace block device I/O: basic version of iosnoop.
#		For Linux, uses BCC, eBPF. See .c file.
#
# Written as a basic example of tracing latency.
#
# 11-Aug-2015	Brendan Gregg	Created this.

from bpf import BPF
import sys

REQ_WRITE = 1		# from include/linux/blk_types.h

# load BPF program
b = BPF(src_file="disksnoop.c")
BPF.attach_kprobe(b.load_func("do_request", BPF.KPROBE), "blk_start_request")
BPF.attach_kprobe(b.load_func("do_completion", BPF.KPROBE), "blk_update_request")

# header
print "%-18s %-2s %-7s %8s" % ("TIME(s)", "T", "BYTES", "LAT(ms)")

# open trace pipe
try:
	trace = open("/sys/kernel/debug/tracing/trace_pipe", "r")
except:
	print >> sys.stderr, "ERROR: opening trace_pipe"
	exit(1)

# format output
while 1:
Example #32
0
# arguments
interval = 5
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")
b.attach_kprobe(event="vfs_read", fn_name="do_entry")
b.attach_kretprobe(event="vfs_read", fn_name="do_return")
dist_max = 64

# header
print("Tracing... Hit Ctrl-C to end.")

# 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):
			break
Example #33
0
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from bpf import BPF
from ctypes import c_uint, c_int, c_ulonglong, Structure
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)
Example #34
0
 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)
Example #35
0
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from bpf import BPF
from ctypes import c_uint, c_int, c_ulonglong, Structure
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",
Example #36
0
 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)
Example #37
0
 def test_complex(self):
     b = BPF(src_file="test_clang_complex.c", debug=0)
     fn = b.load_func("handle_packet", BPF.SCHED_CLS)
Example #38
0
#!/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")
b.attach_kprobe(event="finish_task_switch", fn_name="count_sched")

# generate many schedule events
for i in range(0, 100): sleep(0.01)

for k, v in b["stats"].items():
    print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))
Example #39
0
# arguments
interval = 1
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="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="")
Example #40
0
    end = len(ksym_addrs)
    while end != start + 1:
        mid = (start + end) / 2
        if addr < ksym_addrs[mid]:
            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:
Example #41
0
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from bpf import BPF
from pyroute2 import IPRoute

ipr = IPRoute()

text = """
int hello(struct __sk_buff *skb) {
  return 1;
}
"""

try:
    b = BPF(text=text, debug=0)
    fn = b.load_func("hello", BPF.SCHED_CLS)
    ipr.link_create(ifname="t1a", kind="veth", peer="t1b")
    idx = ipr.link_lookup(ifname="t1a")[0]

    ipr.tc("add", "ingress", idx, "ffff:")
    ipr.tc("add-filter",
           "bpf",
           idx,
           ":1",
           fd=fn.fd,
           name=fn.name,
           parent="ffff:",
           action="ok",
           classid=1)
    ipr.tc("add", "sfq", idx, "1:")
Example #42
0
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# run in project examples directory with:
# sudo ./hello_world.py"

from bpf import BPF

prog = """
int hello(void *ctx) {
  bpf_trace_printk("Hello, World!\\n");
  return 0;
}
"""
b = BPF(text=prog)
b.attach_kprobe(event="sys_clone", fn_name="hello")
b.trace_print(fmt="{1} {5}")
Example #43
0
# arguments
interval = 5
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
Example #44
0
def ksym(addr):
	start = -1
	end = len(ksym_addrs)
	while end != start + 1:
		mid = (start + end) / 2
		if addr < ksym_addrs[mid]:
			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:
Example #45
0
    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()
Example #46
0
 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)
Example #47
0
# arguments
interval = 5
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="bitehist.c")
BPF.attach_kprobe(b.load_func("do_request", BPF.KPROBE), "blk_start_request")
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):
Example #48
0
#!/usr/bin/python
#
# 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