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

Feature: Implement Support for Enhanced ACL Counters #164

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ add skipto :IN ip from any to any in

:IN
add allow tcp from 10.0.0.0/24 to 1.2.3.4 53
add dump ring1 ip from any to any
add dump:ring1 ip from any to any
add deny ip from any to any

add allow udp from 10.0.0.0/24 to 1.2.3.4 53
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
add skipto :IN ip from any to any in

:IN
add dump ring1 tcp from 10.0.0.0/24 to 1.2.3.4 53
add dump:ring1 tcp from 10.0.0.0/24 to 1.2.3.4 53
add allow tcp from 10.0.0.0/24 to 1.2.3.4 53
add deny ip from any to any

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
add skipto :IN ip from any to any in

:IN
add dump ring1 ip from any to any
add dump:ring1 ip from any to any
add allow tcp from 10.0.0.0/24 to 1.2.3.4 53
add deny ip from any to any

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
add skipto :IN ip from any to any in

:IN
add dump ring1 ip from any to any
add dump ring2 tcp from any to any
add dump:ring1 ip from any to any
add dump:ring2 tcp from any to any
add allow tcp from 10.0.0.0/24 to 1.2.3.4 53
add deny ip from any to any

Expand Down
51 changes: 22 additions & 29 deletions common/acl.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,25 @@ struct transport_key_t
// shouldn't be stored in common::globalBase::tFlow
class action_t
{
using action = globalBase::eActionType;

public:
action_t() :
dump_id(0),
dump_tag("")
type(action::size),
id(0),
tag("")
{}

action_t(std::string dump_tag) :
dump_id(0),
dump_tag(dump_tag)
action_t(action type, std::string tag) :
type(type),
id(0),
tag(tag)
{}

inline bool operator==(const action_t& o) const
{
return std::tie(dump_id, dump_tag) ==
std::tie(o.dump_id, o.dump_tag);
return std::tie(type, id, tag) ==
std::tie(o.type, o.id, o.tag);
}

inline bool operator!=(const action_t& o) const
Expand All @@ -142,24 +146,18 @@ class action_t

constexpr bool operator<(const action_t& o) const
{
return std::tie(dump_id, dump_tag) <
std::tie(o.dump_id, o.dump_tag);
return std::tie(type, id, tag) <
std::tie(o.type, o.id, o.tag);
}

void pop(stream_in_t& stream)
std::string to_string()
{
stream.pop(dump_id);
stream.pop(dump_tag);
return std::string(eActionType_to_str(type)) + ":" + tag;
}

void push(stream_out_t& stream) const
{
stream.push(dump_id);
stream.push(dump_tag);
}

uint64_t dump_id;
std::string dump_tag;
action type;
uint32_t id;
std::string tag;
};

struct total_key_t
Expand All @@ -186,30 +184,25 @@ struct total_key_t

struct value_t
{
value_t()
{
memset(dump_ids, 0, sizeof(dump_ids));
}

constexpr bool operator<(const value_t& second) const
{
return flow < second.flow;
return std::tie(flow, actions) < std::tie(second.flow, second.actions);
}

void pop(stream_in_t& stream)
{
stream.pop(flow);
stream.pop(dump_ids);
stream.pop(actions);
}

void push(stream_out_t& stream) const
{
stream.push(flow);
stream.push(dump_ids);
stream.push(actions);
}

common::globalBase::tFlow flow;
uint32_t dump_ids[YANET_CONFIG_DUMP_ID_SIZE];
common::globalBase::tActions<uint32_t> actions;
};

template<typename type_t>
Expand Down
4 changes: 2 additions & 2 deletions common/config.release.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@
#define YANET_CONFIG_STATE_TIMEOUT_DEFAULT (180)
#define YANET_CONFIG_STATE_TIMEOUT_MAX (32 * 1024)
#define YANET_CONFIG_ACL_TREE_CHUNKS_BUCKET_SIZE (64 * 1024)
#define YANET_CONFIG_DUMP_ID_SIZE (8)
#define YANET_CONFIG_DUMP_ID_TO_TAG_SIZE (1024 * 1024)
#define YANET_CONFIG_ACTION_ID_TO_TAG_SIZE (1024 * 1024)
#define YANET_CONFIG_SHARED_RINGS_NUMBER (32)
#define YANET_DEFAULT_IPC_SHMKEY (12345)
#define YANET_CONFIG_KERNEL_INTERFACE_QUEUE_SIZE (4096)
#define YANET_CONFIG_NAT46CLATS_SIZE (32)
#define YANET_CONFIG_TSC_ACTIVE_STATE (0)
#define YANET_CONFIG_BALANCER_STATE_TIMEOUT_DEFAULT (60)
#define YANET_CONFIG_ACL_VALUE_ACTIONS_SIZE (int(common::globalBase::eActionType::size))
15 changes: 11 additions & 4 deletions common/idp.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ enum class requestType : uint32_t
acl_transport_table,
acl_total_table,
acl_values,
acl_value_actions,
dregress_prefix_update,
dregress_prefix_remove,
dregress_prefix_clear,
Expand All @@ -166,7 +167,7 @@ enum class requestType : uint32_t
tun64mappings_update,
serial_update,
nat46clat_update,
dump_tags_ids,
action_tags_ids,
tsc_state_update,
tscs_base_value_update
};
Expand Down Expand Up @@ -371,9 +372,14 @@ namespace acl_values
using request = std::vector<acl::value_t>;
}

namespace dump_tags_ids
namespace acl_value_actions
{
using request = std::vector<std::string>;
using request = common::globalBase::tActions<std::vector<common::acl::action_array_t>>;
}

namespace action_tags_ids
{
using request = common::globalBase::tActions<std::vector<std::string>>;
}

namespace route_lpm_update
Expand Down Expand Up @@ -527,7 +533,8 @@ using requestVariant = std::variant<std::tuple<>,
acl_transport_table::request,
acl_total_table::request,
acl_values::request,
dump_tags_ids::request,
action_tags_ids::request,
acl_value_actions::request,
lpm::request,
route_value_update::request,
route_tunnel_value_update::request,
Expand Down
3 changes: 3 additions & 0 deletions common/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ enum class result_e : uint32_t
missingRequiredOption,
invalidTun64Id,
errorInitSharedMemory,
invalidActionId,
};

static constexpr const char* result_to_c_str(common::result_e e)
Expand Down Expand Up @@ -177,6 +178,8 @@ static constexpr const char* result_to_c_str(common::result_e e)
return "invalidTun64Id";
case result_e::errorInitSharedMemory:
return "errorInitSharedMemory";
case result_e::invalidActionId:
return "invalidActionId";
}

return "?";
Expand Down
93 changes: 93 additions & 0 deletions common/type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2138,6 +2138,46 @@ enum class eNexthopType : unsigned int
repeat,
};

enum class eActionType : uint8_t
{
dump,
count,
// size should always be at the bottom of the list,
// this enum allows us to find out the size of the enum list
size
};

inline constexpr size_t eActionType_max_size(eActionType t)
{
switch (t)
{
case eActionType::dump:
return 8;
case eActionType::count:
return 16;
case eActionType::size:
// keep the maximum value of the above values here
return 16;
};

return 0;
}

inline const char* eActionType_to_str(eActionType t)
{
switch (t)
{
case eActionType::dump:
return "dump";
case eActionType::count:
return "count";
case eActionType::size:
return "unknown";
};

return "unknown";
}

enum class eFlowType : uint8_t
{
drop,
Expand Down Expand Up @@ -2405,6 +2445,58 @@ class tFlow
flow_data_t data;
};

template<typename type_t>
class tActions
{
public:
tActions()
{
}

inline bool operator==(const tActions& second) const
{
return item == second.item;
}

inline bool operator!=(const tActions& second) const
{
return !operator==(second);
}

inline bool operator<(const tActions& second) const
{
return item < second.item;
}

inline type_t& operator[](const int i)
{
return item[i];
}

inline const type_t& operator[](const int i) const
{
return item[i];
}

constexpr size_t size()
{
return item.size();
}

void pop(stream_in_t& stream)
{
stream.pop(item);
}

void push(stream_out_t& stream) const
{
stream.push(item);
}

private:
std::array<type_t, YANET_CONFIG_ACL_VALUE_ACTIONS_SIZE> item;
};

static_assert(YANET_CONFIG_ACL_COUNTERS_SIZE < (1 << 22));

using flow_t = tFlow;
Expand Down Expand Up @@ -2824,6 +2916,7 @@ using path_info_to_nexthop_stuff_ptr_t = std::unordered_map<std::string, ///< pa
namespace acl
{
typedef std::map<tAclId, std::set<std::tuple<bool, std::string>>> iface_map_t; // true -> ingress
typedef std::array<uint32_t, eActionType_max_size(globalBase::eActionType::size)> action_array_t;
}

}
Expand Down
33 changes: 22 additions & 11 deletions controlplane/acl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <unordered_set>
#include <vector>

//#define ACL_DEBUG
// #define ACL_DEBUG

#ifdef ACL_DEBUG
#define ACL_DEBUGLEVEL (1)
Expand All @@ -25,9 +25,7 @@
}

#include "acl.h"
#include "acl/bitset.h"
#include "acl/dict.h"
#include "acl/network.h"
#include "acl/rule.h"
#include "acl_compiler.h"

Expand Down Expand Up @@ -325,6 +323,7 @@ struct firewall_rules_t
[[fallthrough]];
case ipfw::rule_action_t::ALLOW:
case ipfw::rule_action_t::DUMP:
case ipfw::rule_action_t::COUNT:
case ipfw::rule_action_t::DENY:
{
// handle only meaning rules
Expand Down Expand Up @@ -925,16 +924,28 @@ std::vector<rule_t> unwind_used_rules(const std::map<std::string, controlplane::
else if (std::holds_alternative<common::acl::action_t>(rule.action))
{
auto& action = std::get<common::acl::action_t>(rule.action);
if (!action.dump_tag.empty())
auto action_id = int(action.type);

auto& tag_to_id = result.tag_to_action_id[action_id];
auto& id_to_tag = result.action_id_to_tag[action_id];

if (id_to_tag.size() >= YANET_CONFIG_ACTION_ID_TO_TAG_SIZE)
{
auto it = result.tag_to_dump_id.find(action.dump_tag);
if (it == result.tag_to_dump_id.end())
{
result.dump_id_to_tag.emplace_back(action.dump_tag);
it = result.tag_to_dump_id.emplace_hint(it, action.dump_tag, result.dump_id_to_tag.size());
}
action.dump_id = it->second;
YANET_LOG_WARNING("%s: rule %ld ignored: exceeding the maximum amount of '%s' rules : %s\n",
__func__,
rule.ruleno,
eActionType_to_str(action.type),
rule.text.data());
continue;
}

auto it = tag_to_id.find(action.tag);
if (it == tag_to_id.end())
{
id_to_tag.emplace_back(action.tag);
it = tag_to_id.emplace_hint(it, action.tag, id_to_tag.size());
}
action.id = it->second;
}
}

Expand Down
Loading