mirror of
https://github.com/matrix-construct/construct
synced 2024-05-19 19:33:45 +02:00
ircd::net::bpf: Add preliminary epbf support.
This commit is contained in:
parent
11e75db293
commit
d3584274ac
|
@ -1258,6 +1258,7 @@ RB_CHK_SYSHEADER(linux/hw_breakpoint.h, [LINUX_HW_BREAKPOINT_H])
|
||||||
RB_CHK_SYSHEADER(linux/io_uring.h, [LINUX_IO_URING_H])
|
RB_CHK_SYSHEADER(linux/io_uring.h, [LINUX_IO_URING_H])
|
||||||
RB_CHK_SYSHEADER(linux/icmp.h, [LINUX_ICMP_H])
|
RB_CHK_SYSHEADER(linux/icmp.h, [LINUX_ICMP_H])
|
||||||
RB_CHK_SYSHEADER(linux/input-event-codes.h, [LINUX_INPUT_EVENT_CODES_H])
|
RB_CHK_SYSHEADER(linux/input-event-codes.h, [LINUX_INPUT_EVENT_CODES_H])
|
||||||
|
RB_CHK_SYSHEADER(linux/bpf.h, [LINUX_BPF_H])
|
||||||
|
|
||||||
dnl windows platform
|
dnl windows platform
|
||||||
RB_CHK_SYSHEADER(windows.h, [WINDOWS_H])
|
RB_CHK_SYSHEADER(windows.h, [WINDOWS_H])
|
||||||
|
|
51
include/ircd/net/bpf.h
Normal file
51
include/ircd/net/bpf.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Matrix Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2022 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#define HAVE_IRCD_NET_BPF_H
|
||||||
|
|
||||||
|
namespace ircd::net::bpf
|
||||||
|
{
|
||||||
|
struct map;
|
||||||
|
struct prog;
|
||||||
|
|
||||||
|
extern log::log log;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ircd::net::bpf::map
|
||||||
|
{
|
||||||
|
fs::fd fd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit operator bool() const
|
||||||
|
{
|
||||||
|
return bool(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
map();
|
||||||
|
~map() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ircd::net::bpf::prog
|
||||||
|
{
|
||||||
|
const_buffer insns;
|
||||||
|
mutable_buffer log_buf;
|
||||||
|
fs::fd fd;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit operator bool() const
|
||||||
|
{
|
||||||
|
return bool(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
prog(const const_buffer &, const mutable_buffer &log_buf);
|
||||||
|
prog(const const_buffer &);
|
||||||
|
~prog() noexcept;
|
||||||
|
};
|
|
@ -37,6 +37,7 @@ namespace ircd::net
|
||||||
#include "hostport.h"
|
#include "hostport.h"
|
||||||
#include "ipaddr.h"
|
#include "ipaddr.h"
|
||||||
#include "ipport.h"
|
#include "ipport.h"
|
||||||
|
#include "bpf.h"
|
||||||
#include "dns.h"
|
#include "dns.h"
|
||||||
#include "dns_cache.h"
|
#include "dns_cache.h"
|
||||||
#include "listener.h"
|
#include "listener.h"
|
||||||
|
|
|
@ -247,6 +247,9 @@ libircd_la_SOURCES += net_dns_cache.cc
|
||||||
libircd_la_SOURCES += net_dns_resolver.cc
|
libircd_la_SOURCES += net_dns_resolver.cc
|
||||||
libircd_la_SOURCES += net_listener.cc
|
libircd_la_SOURCES += net_listener.cc
|
||||||
libircd_la_SOURCES += net_listener_udp.cc
|
libircd_la_SOURCES += net_listener_udp.cc
|
||||||
|
if LINUX
|
||||||
|
libircd_la_SOURCES += net_bpf.cc
|
||||||
|
endif
|
||||||
libircd_la_SOURCES += server.cc
|
libircd_la_SOURCES += server.cc
|
||||||
libircd_la_SOURCES += client.cc
|
libircd_la_SOURCES += client.cc
|
||||||
libircd_la_SOURCES += resource.cc
|
libircd_la_SOURCES += resource.cc
|
||||||
|
|
218
ircd/net_bpf.cc
Normal file
218
ircd/net_bpf.cc
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
// The Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2022 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <linux/bpf.h>
|
||||||
|
|
||||||
|
namespace ircd::net::bpf
|
||||||
|
{
|
||||||
|
struct [[clang::internal_linkage]] call;
|
||||||
|
|
||||||
|
static constexpr uint
|
||||||
|
log_bufs{8},
|
||||||
|
log_buf_sz{4_KiB};
|
||||||
|
|
||||||
|
static thread_local uint log_bufn;
|
||||||
|
static thread_local char log_buf[log_bufs][log_buf_sz];
|
||||||
|
}
|
||||||
|
|
||||||
|
class [[gnu::visibility("internal")]]
|
||||||
|
ircd::net::bpf::call
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
public:
|
||||||
|
operator const int &() const;
|
||||||
|
|
||||||
|
call(const int &, union bpf_attr *const &);
|
||||||
|
call(const int &, const union bpf_attr &);
|
||||||
|
};
|
||||||
|
|
||||||
|
decltype(ircd::net::bpf::log)
|
||||||
|
ircd::net::bpf::log
|
||||||
|
{
|
||||||
|
"net.bpf"
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// bpf::prog
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::net::bpf::prog::prog(const const_buffer &insns)
|
||||||
|
:prog
|
||||||
|
{
|
||||||
|
insns, mutable_buffer
|
||||||
|
{
|
||||||
|
bpf::log_buf[log_bufn++ % log_bufs], log_buf_sz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
assert(log_bufn <= log_bufs); //TODO: XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::net::bpf::prog::prog(const const_buffer &insns,
|
||||||
|
const mutable_buffer &log_buf)
|
||||||
|
try
|
||||||
|
:insns
|
||||||
|
{
|
||||||
|
insns
|
||||||
|
}
|
||||||
|
,log_buf
|
||||||
|
{
|
||||||
|
log_buf
|
||||||
|
}
|
||||||
|
,fd
|
||||||
|
{
|
||||||
|
#if defined(__clang__) || RB_CXX_EPOCH >= 11
|
||||||
|
empty(insns)? -1: call
|
||||||
|
{
|
||||||
|
BPF_PROG_LOAD, bpf_attr
|
||||||
|
{
|
||||||
|
.prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
|
||||||
|
.insn_cnt = u32(size(insns) / sizeof(bpf_insn)),
|
||||||
|
.insns = uintptr_t(data(insns)),
|
||||||
|
#ifdef _GNU_SOURCE
|
||||||
|
.license = uintptr_t("GPL"),
|
||||||
|
#endif
|
||||||
|
.log_level = !empty(log_buf)? 1U: 0,
|
||||||
|
.log_size = u32(size(log_buf)),
|
||||||
|
.log_buf = uintptr_t(data(log_buf)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if(!fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log::debug
|
||||||
|
{
|
||||||
|
log, "Loaded prog:%p fd:%d bin:%p bytes:%zu",
|
||||||
|
this,
|
||||||
|
int(fd),
|
||||||
|
ircd::data(insns),
|
||||||
|
ircd::size(insns),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
const string_view log_str
|
||||||
|
{
|
||||||
|
data(log_buf), strnlen(data(log_buf), size(log_buf))
|
||||||
|
};
|
||||||
|
|
||||||
|
uint i(0);
|
||||||
|
ircd::tokens(log_str, '\n', [this, &i]
|
||||||
|
(const string_view &line)
|
||||||
|
{
|
||||||
|
if(likely(line))
|
||||||
|
log::error
|
||||||
|
{
|
||||||
|
log, "Log prog:%p %2u :%s",
|
||||||
|
this,
|
||||||
|
i++,
|
||||||
|
line,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
log::critical
|
||||||
|
{
|
||||||
|
log, "Failed to load prog:%p bin:%p bytes:%zu :%s",
|
||||||
|
this,
|
||||||
|
data(insns),
|
||||||
|
size(insns),
|
||||||
|
e.what(),
|
||||||
|
};
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::net::bpf::prog::~prog()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
if(!fd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
log::debug
|
||||||
|
{
|
||||||
|
log, "Unloading prog:%p fd:%d ...",
|
||||||
|
this,
|
||||||
|
int(fd),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// bpf::map
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::net::bpf::map::map()
|
||||||
|
try
|
||||||
|
:fd
|
||||||
|
{
|
||||||
|
#if defined(__clang__) || RB_CXX_EPOCH >= 11
|
||||||
|
call
|
||||||
|
{
|
||||||
|
BPF_MAP_CREATE, bpf_attr
|
||||||
|
{
|
||||||
|
.map_type = BPF_MAP_TYPE_UNSPEC,
|
||||||
|
.key_size = 8,
|
||||||
|
.value_size = 8,
|
||||||
|
.max_entries = 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch(const std::exception &e)
|
||||||
|
{
|
||||||
|
char pbuf[48];
|
||||||
|
log::error
|
||||||
|
{
|
||||||
|
log, "Mapping failed :%s",
|
||||||
|
e.what(),
|
||||||
|
};
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::net::bpf::map::~map()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// internal
|
||||||
|
//
|
||||||
|
|
||||||
|
ircd::net::bpf::call::call(const int &cmd,
|
||||||
|
const union bpf_attr &attr)
|
||||||
|
:call
|
||||||
|
{
|
||||||
|
cmd, mutable_cast(&attr)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::net::bpf::call::call(const int &cmd,
|
||||||
|
union bpf_attr *const &attr)
|
||||||
|
:ret
|
||||||
|
{
|
||||||
|
int(sys::call<SYS_bpf>(cmd, attr, sizeof(union bpf_attr)))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ircd::net::bpf::call::operator
|
||||||
|
const int &()
|
||||||
|
const
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in a new issue