Commit 89978baf authored by Brenden Blanco's avatar Brenden Blanco

Add ability to export maps, enables cross-program sharing

Allow a program to export a map for other programs to use. This enables
cross-program map sharing.

parent program syntax:
BPF_TABLE("array", int, int, shared, 10);
BPF_TABLE_EXPORT(shared);

child program syntax:
BPF_TABLE("extern", int, int, shared, 10);
Signed-off-by: default avatarBrenden Blanco <bblanco@plumgrid.com>
parent 1a6ee5ac
......@@ -35,7 +35,7 @@ endif()
# tell the shared library where it is being installed so it can find shared header files
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBCC_INSTALL_PREFIX='\"${CMAKE_INSTALL_PREFIX}\"'")
add_library(bcc SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c)
add_library(bcc SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c shared_table.cc)
set_target_properties(bcc PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0)
# BPF is still experimental otherwise it should be available
......
......@@ -46,6 +46,10 @@ struct _name##_table_t { \
__attribute__((section("maps/" _table_type))) \
struct _name##_table_t _name
#define BPF_TABLE_EXPORT(_name) \
__attribute__((section("maps/export"))) \
struct _name##_table_t __##_name
// Table for pushing custom events to userspace via ring buffer
#define BPF_PERF_OUTPUT(_name) \
struct _name##_table_t { \
......
......@@ -26,6 +26,7 @@
#include <clang/Rewrite/Core/Rewriter.h>
#include "b_frontend_action.h"
#include "shared_table.h"
#include "libbpf.h"
......@@ -548,6 +549,7 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
}
++i;
}
bool is_extern = false;
bpf_map_type map_type = BPF_MAP_TYPE_UNSPEC;
if (A->getName() == "maps/hash") {
map_type = BPF_MAP_TYPE_HASH;
......@@ -576,23 +578,48 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
} else if (A->getName() == "maps/perf_array") {
if (KERNEL_VERSION(major,minor,0) >= KERNEL_VERSION(4,3,0))
map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY;
} else if (A->getName() == "maps/extern") {
is_extern = true;
table.fd = SharedTables::instance()->lookup_fd(table.name);
} else if (A->getName() == "maps/export") {
if (table.name.substr(0, 2) == "__")
table.name = table.name.substr(2);
auto table_it = tables_.begin();
for (; table_it != tables_.end(); ++table_it)
if (table_it->name == table.name) break;
if (table_it == tables_.end()) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"reference to undefined table");
C.getDiagnostics().Report(Decl->getLocStart(), diag_id);
return false;
}
if (!SharedTables::instance()->insert_fd(table.name, table_it->fd)) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"could not export bpf map %0: %1");
C.getDiagnostics().Report(Decl->getLocStart(), diag_id) << table.name << "already in use";
return false;
}
return true;
}
if (map_type == BPF_MAP_TYPE_UNSPEC) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"unsupported map type: %0");
C.getDiagnostics().Report(Decl->getLocStart(), diag_id) << A->getName();
return false;
}
if (!is_extern) {
if (map_type == BPF_MAP_TYPE_UNSPEC) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"unsupported map type: %0");
C.getDiagnostics().Report(Decl->getLocStart(), diag_id) << A->getName();
return false;
}
table.type = map_type;
table.fd = bpf_create_map(map_type, table.key_size, table.leaf_size, table.max_entries);
table.type = map_type;
table.fd = bpf_create_map(map_type, table.key_size, table.leaf_size, table.max_entries);
}
if (table.fd < 0) {
unsigned diag_id = C.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
"could not open bpf map: %0");
C.getDiagnostics().Report(Decl->getLocStart(), diag_id) << strerror(errno);
return false;
}
tables_.push_back(std::move(table));
} else if (const PointerType *P = Decl->getType()->getAs<PointerType>()) {
// if var is a pointer to a packet type, clone the annotation into the var
......
/*
* Copyright (c) 2016 PLUMgrid, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "shared_table.h"
namespace ebpf {
using std::string;
SharedTables * SharedTables::instance_;
SharedTables * SharedTables::instance() {
if (!instance_) {
instance_ = new SharedTables;
}
return instance_;
}
int SharedTables::lookup_fd(const string &name) const {
auto table = tables_.find(name);
if (table == tables_.end())
return -1;
return table->second;
}
bool SharedTables::insert_fd(const string &name, int fd) {
if (tables_.find(name) != tables_.end())
return false;
tables_[name] = fd;
return true;
}
}
/*
* Copyright (c) 2016 PLUMgrid, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <map>
#include <string>
namespace ebpf {
struct TableDesc;
class SharedTables {
public:
static SharedTables * instance();
// add an fd to the shared table, return true if successfully inserted
bool insert_fd(const std::string &name, int fd);
// lookup an fd in the shared table, or -1 if not found
int lookup_fd(const std::string &name) const;
private:
static SharedTables *instance_;
std::map<std::string, int> tables_;
};
}
......@@ -14,6 +14,8 @@
* limitations under the License.
*/
#pragma once
#include <cstdint>
#include <string>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment