Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bessctl: add init/cmd argument introspection #1012

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 67 additions & 6 deletions core/bessctl.cc
Original file line number Diff line number Diff line change
@@ -447,6 +447,55 @@ class BESSControlImpl final : public BESSControl::Service {
return Status::OK;
}

Status DumpDescriptors(ServerContext*, const EmptyRequest*,
DumpDescriptorsResponse* response) override {
std::lock_guard<std::recursive_mutex> lock(mutex_);

auto& module_descs = *response->mutable_modules();
for (const auto & [ mclass, builder ] :
ModuleBuilder::all_module_builders()) {
if (const auto dp = builder.init_descriptor(); dp != nullptr) {
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
module_descs[mclass] = desc;
}
}

auto& module_cmd_descs = *response->mutable_module_commands();
for (const auto & [ mclass, builder ] :
ModuleBuilder::all_module_builders()) {
auto& cmds = *module_cmd_descs[mclass].mutable_commands();
for (const auto & [ cmd, arg_type ] : builder.cmds()) {
if (std::holds_alternative<const google::protobuf::Descriptor*>(
arg_type)) {
const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
// to be safe
if (dp == nullptr) {
continue;
}
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
cmds[cmd] = desc;
}
}
}

auto& port_descs = *response->mutable_ports();
for (const auto & [ driver, builder ] : PortBuilder::all_port_builders()) {
if (const auto dp = builder.init_descriptor(); dp != nullptr) {
google::protobuf::DescriptorProto desc;
dp->CopyTo(&desc);
desc.set_name(dp->full_name());
port_descs[driver] = desc;
}
}

return Status::OK;
}

Status ResetAll(ServerContext* context, const EmptyRequest* request,
EmptyResponse* response) override {
std::lock_guard<std::recursive_mutex> lock(mutex_);
@@ -1472,9 +1521,15 @@ class BESSControlImpl final : public BESSControl::Service {

response->set_name(cls->class_name());
response->set_help(cls->help_text());
for (const auto& cmd : cls->cmds()) {
response->add_cmds(cmd.first);
response->add_cmd_args(cmd.second);
for (const auto & [ cmd, arg_type ] : cls->cmds()) {
response->add_cmds(cmd);
if (std::holds_alternative<std::string>(arg_type)) {
response->add_cmd_args(std::get<std::string>(arg_type));
} else if (const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
dp != nullptr) {
response->add_cmd_args(dp->name());
}
}
return Status::OK;
}
@@ -1750,9 +1805,15 @@ class BESSControlImpl final : public BESSControl::Service {

response->set_name(cls->class_name());
response->set_help(cls->help_text());
for (const auto& cmd : cls->cmds()) {
response->add_cmds(cmd.first);
response->add_cmd_args(cmd.second);
for (const auto & [ cmd, arg_type ] : cls->cmds()) {
response->add_cmds(cmd);
if (std::holds_alternative<std::string>(arg_type)) {
response->add_cmd_args(std::get<std::string>(arg_type));
} else if (const auto dp =
std::get<const google::protobuf::Descriptor*>(arg_type);
dp != nullptr) {
response->add_cmd_args(dp->name());
}
}
return Status::OK;
}
7 changes: 6 additions & 1 deletion core/commands.h
Original file line number Diff line number Diff line change
@@ -31,8 +31,11 @@
#ifndef BESS_COMMANDS_H_
#define BESS_COMMANDS_H_

#include <variant>
#include <vector>

#include <google/protobuf/descriptor.pb.h>

#include "message.h"

// TODO(torek): refactor; instead of "module command" and "gate command"
@@ -50,6 +53,8 @@ using module_cmd_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;
using gate_hook_cmd_func_t =
pb_func_t<CommandResponse, bess::GateHook, google::protobuf::Any>;
using CommandArgType =
std::variant<std::string, const google::protobuf::Descriptor *>;

// Describes a single command that can be issued to a module
// or gate hook (according to cmd_func_t).
@@ -58,7 +63,7 @@ struct GenericCommand {
enum ThreadSafety { THREAD_UNSAFE = 0, THREAD_SAFE = 1 };

std::string cmd;
std::string arg_type;
CommandArgType arg_type;
cmd_func_t func;

// If set to THREAD_SAFE, workers don't need to be paused in order to run
7 changes: 4 additions & 3 deletions core/gate.h
Original file line number Diff line number Diff line change
@@ -164,10 +164,11 @@ class GateHookBuilder {
const std::string &name_template() const { return name_template_; }
const std::string &help_text() const { return help_text_; }

const std::vector<std::pair<std::string, std::string>> cmds() const {
std::vector<std::pair<std::string, std::string>> ret;
for (auto &cmd : cmds_)
const std::vector<std::pair<std::string, CommandArgType>> cmds() const {
std::vector<std::pair<std::string, CommandArgType>> ret;
for (auto &cmd : cmds_) {
ret.push_back(std::make_pair(cmd.cmd, cmd.arg_type));
}
return ret;
}

5 changes: 3 additions & 2 deletions core/module.cc
Original file line number Diff line number Diff line change
@@ -47,11 +47,12 @@ bool ModuleBuilder::RegisterModuleClass(
std::function<Module *()> module_generator, const std::string &class_name,
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func) {
module_init_func_t init_func, const Descriptor *init_descriptor) {
all_module_builders_holder().emplace(
std::piecewise_construct, std::forward_as_tuple(class_name),
std::forward_as_tuple(module_generator, class_name, name_template,
help_text, igates, ogates, cmds, init_func));
help_text, igates, ogates, cmds, init_func,
init_descriptor));
return true;
}

45 changes: 29 additions & 16 deletions core/module.h
Original file line number Diff line number Diff line change
@@ -41,6 +41,9 @@
#include <utility>
#include <vector>

#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/message.h>

#include "commands.h"
#include "event.h"
#include "gate.h"
@@ -50,6 +53,7 @@
#include "worker.h"

using bess::gate_idx_t;
using google::protobuf::Descriptor;

#define INVALID_TASK_ID ((task_id_t)-1)
#define MAX_NUMA_NODE 16
@@ -74,8 +78,6 @@ struct Context {
gate_idx_t gate_without_hook[bess::PacketBatch::kMaxBurst];
};

using module_cmd_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;
using module_init_func_t =
pb_func_t<CommandResponse, Module, google::protobuf::Any>;

@@ -101,6 +103,12 @@ static inline module_init_func_t MODULE_INIT_FUNC(
};
}

template <typename T, typename M>
static inline const Descriptor *MODULE_INIT_DESC(
CommandResponse (M::*)(const T &)) {
return T::descriptor();
}

class Module;

// A class for managing modules of 'a particular type'.
@@ -112,23 +120,23 @@ class ModuleBuilder {
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
std::function<CommandResponse(Module *, const google::protobuf::Any &)>
init_func)
init_func,
const Descriptor *init_descriptor)
: module_generator_(module_generator),
num_igates_(igates),
num_ogates_(ogates),
class_name_(class_name),
name_template_(name_template),
help_text_(help_text),
cmds_(cmds),
init_func_(init_func) {}

static bool RegisterModuleClass(std::function<Module *()> module_generator,
const std::string &class_name,
const std::string &name_template,
const std::string &help_text,
const gate_idx_t igates,
const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func);
init_func_(init_func),
init_descriptor_(init_descriptor) {}

static bool RegisterModuleClass(
std::function<Module *()> module_generator, const std::string &class_name,
const std::string &name_template, const std::string &help_text,
const gate_idx_t igates, const gate_idx_t ogates, const Commands &cmds,
module_init_func_t init_func, const Descriptor *init_descriptor);
static bool DeregisterModuleClass(const std::string &class_name);

static std::map<std::string, ModuleBuilder> &all_module_builders_holder(
@@ -146,10 +154,11 @@ class ModuleBuilder {
const std::string &name_template() const { return name_template_; }
const std::string &help_text() const { return help_text_; }

const std::vector<std::pair<std::string, std::string>> cmds() const {
std::vector<std::pair<std::string, std::string>> ret;
for (auto &cmd : cmds_)
const std::vector<std::pair<std::string, CommandArgType>> cmds() const {
std::vector<std::pair<std::string, CommandArgType>> ret;
for (auto &cmd : cmds_) {
ret.push_back(std::make_pair(cmd.cmd, cmd.arg_type));
}
return ret;
}

@@ -158,6 +167,8 @@ class ModuleBuilder {

CommandResponse RunInit(Module *m, const google::protobuf::Any &arg) const;

const Descriptor *init_descriptor() const { return init_descriptor_; }

private:
const std::function<Module *()> module_generator_;

@@ -169,6 +180,7 @@ class ModuleBuilder {
const std::string help_text_;
const Commands cmds_;
const module_init_func_t init_func_;
const Descriptor *init_descriptor_;
};

class Task;
@@ -723,7 +735,8 @@ static inline void set_attr(Module *m, int attr_id, bess::Packet *pkt, T val) {
ModuleBuilder::RegisterModuleClass( \
std::function<Module *()>([]() { return new _MOD(); }), #_MOD, \
_NAME_TEMPLATE, _HELP, _MOD::kNumIGates, _MOD::kNumOGates, \
_MOD::cmds, MODULE_INIT_FUNC(&_MOD::Init)); \
_MOD::cmds, MODULE_INIT_FUNC(&_MOD::Init), \
MODULE_INIT_DESC(&_MOD::Init)); \
} \
~_MOD##_class() { ModuleBuilder::DeregisterModuleClass(#_MOD); } \
};
6 changes: 3 additions & 3 deletions core/modules/acl.cc
Original file line number Diff line number Diff line change
@@ -34,10 +34,10 @@
#include "../utils/udp.h"

const Commands ACL::cmds = {
{"add", "ACLArg", MODULE_CMD_FUNC(&ACL::CommandAdd),
{"add", bess::pb::ACLArg::descriptor(), MODULE_CMD_FUNC(&ACL::CommandAdd),
Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&ACL::CommandClear),
Command::THREAD_UNSAFE}};
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ACL::CommandClear), Command::THREAD_UNSAFE}};

CommandResponse ACL::Init(const bess::pb::ACLArg &arg) {
for (const auto &rule : arg.rules()) {
4 changes: 2 additions & 2 deletions core/modules/arp_responder.cc
Original file line number Diff line number Diff line change
@@ -36,8 +36,8 @@ using bess::utils::Arp;
using bess::utils::be16_t;

const Commands ArpResponder::cmds = {
{"add", "ArpResponderArg", MODULE_CMD_FUNC(&ArpResponder::CommandAdd),
Command::THREAD_UNSAFE}};
{"add", bess::pb::ArpResponderArg::descriptor(),
MODULE_CMD_FUNC(&ArpResponder::CommandAdd), Command::THREAD_UNSAFE}};

CommandResponse ArpResponder::CommandAdd(const bess::pb::ArpResponderArg &arg) {
be32_t ip_addr;
14 changes: 7 additions & 7 deletions core/modules/bpf.cc
Original file line number Diff line number Diff line change
@@ -49,14 +49,14 @@
#define SNAPLEN 0xffff

const Commands BPF::cmds = {
{"add", "BPFArg", MODULE_CMD_FUNC(&BPF::CommandAdd),
{"add", bess::pb::BPFArg::descriptor(), MODULE_CMD_FUNC(&BPF::CommandAdd),
Command::THREAD_UNSAFE},
{"delete", "BPFArg", MODULE_CMD_FUNC(&BPF::CommandDelete),
Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&BPF::CommandClear),
Command::THREAD_UNSAFE},
{"get_initial_arg", "EmptyArg", MODULE_CMD_FUNC(&BPF::GetInitialArg),
Command::THREAD_SAFE}};
{"delete", bess::pb::BPFArg::descriptor(),
MODULE_CMD_FUNC(&BPF::CommandDelete), Command::THREAD_UNSAFE},
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&BPF::CommandClear), Command::THREAD_UNSAFE},
{"get_initial_arg", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&BPF::GetInitialArg), Command::THREAD_SAFE}};

CommandResponse BPF::Init(const bess::pb::BPFArg &arg) {
return CommandAdd(arg);
8 changes: 5 additions & 3 deletions core/modules/drr.cc
Original file line number Diff line number Diff line change
@@ -51,9 +51,9 @@ uint32_t RoundToPowerTwo(uint32_t v) {
}

const Commands DRR::cmds = {
{"set_quantum_size", "DRRQuantumArg",
{"set_quantum_size", bess::pb::DRRQuantumArg::descriptor(),
MODULE_CMD_FUNC(&DRR::CommandQuantumSize), Command::THREAD_UNSAFE},
{"set_max_flow_queue_size", "DRRMaxFlowQueueSizeArg",
{"set_max_flow_queue_size", bess::pb::DRRMaxFlowQueueSizeArg::descriptor(),
MODULE_CMD_FUNC(&DRR::CommandMaxFlowQueueSize), Command::THREAD_UNSAFE}};

DRR::DRR()
@@ -152,7 +152,9 @@ struct task_result DRR::RunTask(Context *ctx, bess::PacketBatch *batch,
void *) {
if (children_overload_ > 0) {
return {
.block = true, .packets = 0, .bits = 0,
.block = true,
.packets = 0,
.bits = 0,
};
}

4 changes: 2 additions & 2 deletions core/modules/dump.cc
Original file line number Diff line number Diff line change
@@ -40,8 +40,8 @@
static const uint64_t DEFAULT_INTERVAL_NS = 1 * NS_PER_SEC; /* 1 sec */

const Commands Dump::cmds = {
{"set_interval", "DumpArg", MODULE_CMD_FUNC(&Dump::CommandSetInterval),
Command::THREAD_UNSAFE},
{"set_interval", bess::pb::DumpArg::descriptor(),
MODULE_CMD_FUNC(&Dump::CommandSetInterval), Command::THREAD_UNSAFE},
};

CommandResponse Dump::Init(const bess::pb::DumpArg &arg) {
21 changes: 11 additions & 10 deletions core/modules/exact_match.cc
Original file line number Diff line number Diff line change
@@ -43,19 +43,20 @@ static inline int is_valid_gate(gate_idx_t gate) {
}

const Commands ExactMatch::cmds = {
{"get_initial_arg", "EmptyArg", MODULE_CMD_FUNC(&ExactMatch::GetInitialArg),
Command::THREAD_SAFE},
{"get_runtime_config", "EmptyArg",
{"get_initial_arg", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::GetInitialArg), Command::THREAD_SAFE},
{"get_runtime_config", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::GetRuntimeConfig), Command::THREAD_SAFE},
{"set_runtime_config", "ExactMatchConfig",
{"set_runtime_config", bess::pb::ExactMatchConfig::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::SetRuntimeConfig), Command::THREAD_UNSAFE},
{"add", "ExactMatchCommandAddArg", MODULE_CMD_FUNC(&ExactMatch::CommandAdd),
Command::THREAD_UNSAFE},
{"delete", "ExactMatchCommandDeleteArg",
{"add", bess::pb::ExactMatchCommandAddArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandAdd), Command::THREAD_UNSAFE},
{"delete", bess::pb::ExactMatchCommandDeleteArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandDelete), Command::THREAD_UNSAFE},
{"clear", "EmptyArg", MODULE_CMD_FUNC(&ExactMatch::CommandClear),
Command::THREAD_UNSAFE},
{"set_default_gate", "ExactMatchCommandSetDefaultGateArg",
{"clear", bess::pb::EmptyArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandClear), Command::THREAD_UNSAFE},
{"set_default_gate",
bess::pb::ExactMatchCommandSetDefaultGateArg::descriptor(),
MODULE_CMD_FUNC(&ExactMatch::CommandSetDefaultGate),
Command::THREAD_SAFE}};

Loading