From a7f65b2442ab68a4662c3404e58b2a705ddf824a Mon Sep 17 00:00:00 2001 From: Alberto Leiva Popper Date: Thu, 24 Dec 2020 13:41:54 -0600 Subject: [PATCH] MAP-T: Add FMRT to atomic configuration Forgot this during development. --- src/common/config.h | 1 + src/common/global.c | 18 +++++++-------- src/mod/common/atomic_config.c | 37 ++++++++++++++++++++++++++++++ src/mod/common/nl/nl_handler.c | 1 + src/usr/nl/file.c | 41 ++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/common/config.h b/src/common/config.h index 89ec46d75..6744a8e8b 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -73,6 +73,7 @@ enum joolnl_attr_root { JNLAR_POOL4_ENTRIES, JNLAR_BIB_ENTRIES, JNLAR_SESSION_ENTRIES, + JNLAR_FMRT_ENTRIES, JNLAR_OFFSET, JNLAR_OFFSET_U8, JNLAR_OPERAND, diff --git a/src/common/global.c b/src/common/global.c index 2b2c3033b..dcc5f96f2 100644 --- a/src/common/global.c +++ b/src/common/global.c @@ -933,16 +933,16 @@ static struct jool_result j2n_mapping_rule(cJSON *json, struct nl_msg *msg, return joolnl_err_msgsize(); for (child = json->child; child; child = child->next) { - if (strcasecmp(json->string, "comment") == 0) + if (strcasecmp(child->string, "comment") == 0) result = result_success(); /* Skip */ - else if (strcasecmp(json->string, "IPv6 Prefix") == 0) - result = j2n_prefix6(json, msg, JNLAMR_PREFIX6); - else if (strcasecmp(json->string, "IPv4 Prefix") == 0) - result = j2n_prefix4(json, msg, JNLAMR_PREFIX4); - else if (strcasecmp(json->string, "EA-bits length") == 0) - result = __json2nl_u8(json, msg, JNLAMR_EA_BITS_LENGTH); - else if (strcasecmp(json->string, "a") == 0) - result = __json2nl_u8(json, msg, JNLAMR_a); + else if (strcasecmp(child->string, "IPv6 Prefix") == 0) + result = j2n_prefix6(child, msg, JNLAMR_PREFIX6); + else if (strcasecmp(child->string, "IPv4 Prefix") == 0) + result = j2n_prefix4(child, msg, JNLAMR_PREFIX4); + else if (strcasecmp(child->string, "EA-bits length") == 0) + result = __json2nl_u8(child, msg, JNLAMR_EA_BITS_LENGTH); + else if (strcasecmp(child->string, "a") == 0) + result = __json2nl_u8(child, msg, JNLAMR_a); else result = result_from_error(-EINVAL, "Unknown tag: '%s'", child->string); diff --git a/src/mod/common/atomic_config.c b/src/mod/common/atomic_config.c index 4a2ffb2a3..bae3c59f8 100644 --- a/src/mod/common/atomic_config.c +++ b/src/mod/common/atomic_config.c @@ -9,6 +9,7 @@ #include "mod/common/nl/nl_common.h" #include "mod/common/db/eam.h" #include "mod/common/db/denylist4.h" +#include "mod/common/db/fmr.h" #include "mod/common/joold.h" #include "mod/common/db/pool4/db.h" #include "mod/common/db/bib/db.h" @@ -303,6 +304,37 @@ static int handle_bib(struct config_candidate *new, struct nlattr *root) return 0; } +static int handle_fmrt(struct config_candidate *new, struct nlattr *root) +{ + struct nlattr *attr; + struct config_mapping_rule entry; + int rem; + int error; + + LOG_DEBUG("Handling atomic FMRT attribute."); + + error = check_xtype(new, XT_MAPT, "FMRT"); + if (error) + return error; + + nla_for_each_nested(attr, root, rem) { + if (nla_type(attr) != JNLAL_ENTRY) + continue; /* ? */ + error = jnla_get_mapping_rule(attr, "FMR", &entry); + if (error) + return error; + if (!entry.set) { + log_err("FMR is empty."); + return -EINVAL; + } + error = fmrt_add(new->xlator.mapt.fmrt, &entry.rule); + if (error) + return error; + } + + return 0; +} + static int commit(struct config_candidate *candidate) { int error; @@ -366,6 +398,11 @@ int atomconfig_add(struct sk_buff *skb, struct genl_info *info) if (error) goto revert; } + if (info->attrs[JNLAR_FMRT_ENTRIES]) { + error = handle_fmrt(candidate, info->attrs[JNLAR_FMRT_ENTRIES]); + if (error) + goto revert; + } if (info->attrs[JNLAR_ATOMIC_END]) { error = commit(candidate); if (error) diff --git a/src/mod/common/nl/nl_handler.c b/src/mod/common/nl/nl_handler.c index f51561369..0de4951f5 100644 --- a/src/mod/common/nl/nl_handler.c +++ b/src/mod/common/nl/nl_handler.c @@ -50,6 +50,7 @@ static struct nla_policy const jool_policy[JNLAR_COUNT] = { [JNLAR_POOL4_ENTRIES] = { .type = NLA_NESTED }, [JNLAR_BIB_ENTRIES] = { .type = NLA_NESTED }, [JNLAR_SESSION_ENTRIES] = { .type = NLA_NESTED }, + [JNLAR_FMRT_ENTRIES] = { .type = NLA_NESTED }, [JNLAR_OFFSET] = { .type = NLA_NESTED }, [JNLAR_OFFSET_U8] = { .type = NLA_U8 }, [JNLAR_OPERAND] = { .type = NLA_NESTED }, diff --git a/src/usr/nl/file.c b/src/usr/nl/file.c index 037b1beb1..f83ab4e4f 100644 --- a/src/usr/nl/file.c +++ b/src/usr/nl/file.c @@ -23,6 +23,7 @@ #define OPTNAME_POOL4 "pool4" #define OPTNAME_BIB "bib" #define OPTNAME_MAX_ITERATIONS "max-iterations" +#define OPTNAME_FMRT "fmrt" /* TODO (warning) These variables prevent this module from being thread-safe. */ static struct joolnl_socket sk; @@ -258,6 +259,18 @@ static struct jool_result handle_global(cJSON *json) * ================================= */ +static struct jool_result json2u8(cJSON *json, void const *arg1, void *arg2) +{ + __u8 *value; + + if (json->type != cJSON_Number || !(json->numflags & VALUENUM_UINT)) + return type_mismatch(json->string, json, "unsigned integer"); + + value = arg2; + *value = json->valueuint; + return result_success(); +} + static struct jool_result json2prefix6(cJSON *json, void const *arg1, void *arg2) { return (json->type == cJSON_String) @@ -454,6 +467,27 @@ static struct jool_result handle_bib_entry(cJSON *json, struct nl_msg *msg) : result_success(); } +static struct jool_result handle_fmrt_entry(cJSON *json, struct nl_msg *msg) +{ + struct mapping_rule entry = { .a = 6 }; + struct json_meta meta[] = { + { "ipv6 prefix", json2prefix6, NULL, &entry.prefix6, true }, + { "ipv4 prefix", json2prefix4, NULL, &entry.prefix4, true }, + { "ea-bits length", json2u8, NULL, &entry.o, true }, + { "a", json2u8, NULL, &entry.a, false }, + { NULL }, + }; + struct jool_result result; + + result = handle_object(json, meta); + if (result.error) + return result; + + return (nla_put_mapping_rule(msg, JNLAL_ENTRY, &entry) < 0) + ? joolnl_err_msgsize() + : result_success(); +} + /* * ========================================== * = Second level tag handlers, second pass = @@ -495,6 +529,11 @@ static struct jool_result handle_bib_tag(cJSON *json, void const *arg1, void *ar return handle_array(json, JNLAR_BIB_ENTRIES, OPTNAME_BIB, handle_bib_entry); } +static struct jool_result handle_fmrt_tag(cJSON *json, void const *arg1, void *arg2) +{ + return handle_array(json, JNLAR_FMRT_ENTRIES, OPTNAME_FMRT, handle_fmrt_entry); +} + /* * ================================== * = Root tag handlers, second pass = @@ -538,6 +577,7 @@ static struct jool_result parse_mapt_json(cJSON *json) { OPTNAME_INAME, do_nothing, NULL, NULL, true }, { OPTNAME_FW, do_nothing, NULL, NULL, true }, { OPTNAME_GLOBAL, handle_global_tag, NULL, NULL, false }, + { OPTNAME_FMRT, handle_fmrt_tag, NULL, NULL, false }, { NULL }, }; return handle_object(json, meta); @@ -614,6 +654,7 @@ static struct jool_result prepare_instance(char const *_iname, cJSON *json) { OPTNAME_DENYLIST, do_nothing }, { OPTNAME_POOL4, do_nothing }, { OPTNAME_BIB, do_nothing }, + { OPTNAME_FMRT, do_nothing }, { NULL }, }; struct jool_result result;