コード例 #1
0
ファイル: datastructures.py プロジェクト: ounie-os/py2bpf
    def lookup(self, key):
        if not isinstance(key, self.KEY_TYPE):
            raise TypeError('key {} is not instance of key_type {}'.format(
                repr(key), repr(self.KEY_TYPE)))

        key_p = ctypes.cast(ctypes.pointer(key), ctypes.c_char_p)

        value = self.VALUE_TYPE()
        value_p = ctypes.cast(ctypes.pointer(value), ctypes.c_char_p)
        attr = _BpfAttrMapElem(
            map_fd=self.fd,
            key=key_p,
            value_or_next_key=value_p,
            flags=0,
        )
        attr_p = ctypes.pointer(attr)
        ret = _syscall.bpf(_MapCmd.LOOKUP_ELEM, attr_p, ctypes.sizeof(attr))
        if ret == 0:
            return value

        eno = _syscall._get_errno()
        if eno == errno.ENOENT:
            raise KeyError(key)

        raise OSError(eno,
                      'Failed to lookup bpf map: {}'.format(os.strerror(eno)))
コード例 #2
0
ファイル: datastructures.py プロジェクト: ounie-os/py2bpf
    def get_next_key(self, last_key):
        if not isinstance(last_key, self.KEY_TYPE):
            raise TypeError('key {} is not instance of key_type {}'.format(
                repr(last_key), repr(self.KEY_TYPE)))
        key_p = ctypes.cast(ctypes.pointer(last_key), ctypes.c_char_p)

        next_key = self.KEY_TYPE()
        next_key_p = ctypes.cast(ctypes.pointer(next_key), ctypes.c_char_p)

        attr = _BpfAttrMapElem(
            map_fd=self.fd,
            key=key_p,
            value_or_next_key=next_key_p,
            flags=0,
        )
        attr_p = ctypes.pointer(attr)
        ret = _syscall.bpf(_MapCmd.GET_NEXT_KEY, attr_p, ctypes.sizeof(attr))
        if ret == 0:
            return next_key

        eno = _syscall._get_errno()
        if eno == errno.ENOENT:
            return None

        raise OSError(eno,
                      'Failed to get next key: {}'.format(os.strerror(eno)))
コード例 #3
0
ファイル: _perf_event.py プロジェクト: tisma/py2bpf
def perf_event_open(attr, pid=-1, cpu=-1, group_fd=-1, flags=0):
    _NR_perf_event_open = 298
    ret = _syscall.syscall(_NR_perf_event_open, ctypes.byref(attr), pid, cpu,
                           group_fd, flags)
    if ret < 0:
        eno = _syscall._get_errno()
        raise OSError(eno,
                      'Failed to open perf event: {}'.format(os.strerror(eno)))
    return ret
コード例 #4
0
ファイル: datastructures.py プロジェクト: ounie-os/py2bpf
def _map_create(map_type, key_size, value_size, max_entries):
    attr = _BpfAttrMapCreate(map_type=map_type,
                             key_size=key_size,
                             value_size=value_size,
                             max_entries=max_entries,
                             map_flags=0)
    fd = _syscall.bpf(_MapCmd.CREATE, ctypes.pointer(attr),
                      ctypes.sizeof(attr))
    if fd < 0:
        eno = _syscall._get_errno()
        raise OSError(eno,
                      'Failed to create bpf map: {}'.format(os.strerror(eno)))
    return fd
コード例 #5
0
ファイル: datastructures.py プロジェクト: ounie-os/py2bpf
def _update_elem(fd, key, value):
    key_p = ctypes.cast(ctypes.pointer(key), ctypes.c_char_p)
    value_p = ctypes.cast(ctypes.pointer(value), ctypes.c_char_p)
    attr = _BpfAttrMapElem(
        map_fd=fd,
        key=key_p,
        value_or_next_key=value_p,
        flags=0,
    )
    attr_p = ctypes.pointer(attr)
    if _syscall.bpf(_MapCmd.UPDATE_ELEM, attr_p, ctypes.sizeof(attr)) != 0:
        eno = _syscall._get_errno()
        raise OSError(eno,
                      'Failed to update bpf map: {}'.format(os.strerror(eno)))
コード例 #6
0
ファイル: datastructures.py プロジェクト: ounie-os/py2bpf
    def __init__(self, data_type, cpu, num_pages=9):
        self.mm_fd = -1
        self.data_type = data_type
        self.num_pages = num_pages

        try:
            attr = pe.PerfEventAttr()
            attr.type = pe.PERF_TYPE_SOFTWARE
            attr.config = pe.PERF_COUNT_SW_BPF_OUTPUT
            attr.sample_type = pe.PERF_SAMPLE_RAW
            self.mm_fd = pe.perf_event_open(attr, cpu=cpu)
            if self.mm_fd < 0:
                eno = _syscall._get_errno()
                raise OSError(
                    eno,
                    'Failed to create perf event: {}'.format(os.strerror(eno)))

            fcntl.ioctl(self.mm_fd, pe.PERF_EVENT_IOC_ENABLE, 0)
            self.pagesz = resource.getpagesize()
            self.mm = mmap.mmap(self.mm_fd, self.num_pages * self.pagesz)
        except Exception:
            self.close()
            raise
コード例 #7
0
ファイル: prog.py プロジェクト: tisma/py2bpf
def _load_prog(prog_type, insns_arr, insns_to_info):
    log = ctypes.create_string_buffer(2**20)

    attr = BpfAttrLoadProg(
        prog_type=prog_type,
        insn_cnt=len(insns_arr),
        insns=ctypes.cast(ctypes.byref(insns_arr), ctypes.c_char_p),
        license=ctypes.c_char_p('GPL'.encode()),
        log_level=100,
        log_size=ctypes.sizeof(log),
        log_buf=ctypes.addressof(log),
        kern_version=_get_kern_version(),
    )

    fd = _syscall.bpf(BpfCmd.PROG_LOAD, ctypes.pointer(attr),
                      ctypes.sizeof(attr))
    if fd < 0:
        eno = _syscall._get_errno()

        last_num = None
        for l in log.value.decode().splitlines():
            m = re.match('^(\d+): .*', l)
            if m is not None:
                num = int(m.group(1))
                if last_num != num and num in insns_to_info:
                    last_num = num
                    if num > 0:
                        print(file=sys.stderr)
                    print(insns_to_info[num], file=sys.stderr)
            print('', l, file=sys.stderr)

        print(file=sys.stderr)

        raise OSError(eno,
                      'Failed to load bpf prog: {}'.format(os.strerror(eno)))

    return fd, log.value.decode()