net: mptcp: convert netlink from small_ops to ops

in the current MPTCP control plane, all operations use a netlink
attribute of the same type "MPTCP_PM_ATTR". However, add/del/get/flush
operations only parse the first element in the message _ the one that
describes MPTCP endpoints (that was named MPTCP_PM_ATTR_ADDR and
mostly used in ADD_ADDR operations _ probably the similarity of "attr",
"addr" and "add" might cause some confusion to human readers).
Convert MPTCP from 'small_ops' to 'ops', thus allowing different attributes
for each single operation, hopefully makes all this clearer to human
readers.

- use a separate attribute set for add/del/get/flush address operation,
  binary compatible with the existing one, to store the endpoint address.
  MPTCP_PM_ENDPOINT_ADDR is added to the uAPI (with the same value as
  MPTCP_PM_ATTR_ADDR) for these operations.
- convert mptcp_pm_ops[] and add policy files accordingly.

this prepares MPTCP control plane to be described as YAML spec.

Link: https://github.com/multipath-tcp/mptcp_net-next/issues/340
Acked-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: Mat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20231023-send-net-next-20231023-1-v2-3-16b1f701f900@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Davide Caratti 2023-10-23 11:17:07 -07:00 committed by Jakub Kicinski
parent 0c63ad3795
commit 1d0507f468
2 changed files with 135 additions and 64 deletions

View File

@ -65,6 +65,14 @@ enum {
#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1) #define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
enum {
MPTCP_PM_ENDPOINT_ADDR = 1,
__MPTCP_PM_ENDPOINT_MAX
};
#define MPTCP_PM_ENDPOINT_MAX (__MPTCP_PM_ENDPOINT_MAX - 1)
enum { enum {
MPTCP_PM_ADDR_ATTR_UNSPEC, MPTCP_PM_ADDR_ATTR_UNSPEC,

View File

@ -48,6 +48,60 @@ struct pm_nl_pernet {
#define MPTCP_PM_ADDR_MAX 8 #define MPTCP_PM_ADDR_MAX 8
#define ADD_ADDR_RETRANS_MAX 3 #define ADD_ADDR_RETRANS_MAX 3
static
const struct nla_policy mptcp_pm_address_nl_policy[MPTCP_PM_ADDR_ATTR_IF_IDX + 1] = {
[MPTCP_PM_ADDR_ATTR_FAMILY] = { .type = NLA_U16, },
[MPTCP_PM_ADDR_ATTR_ID] = { .type = NLA_U8, },
[MPTCP_PM_ADDR_ATTR_ADDR4] = { .type = NLA_U32, },
[MPTCP_PM_ADDR_ATTR_ADDR6] = NLA_POLICY_EXACT_LEN(16),
[MPTCP_PM_ADDR_ATTR_PORT] = { .type = NLA_U16, },
[MPTCP_PM_ADDR_ATTR_FLAGS] = { .type = NLA_U32, },
[MPTCP_PM_ADDR_ATTR_IF_IDX] = { .type = NLA_S32, },
};
/* MPTCP_PM_CMD_ADD_ADDR / DEL / GET / FLUSH - do */
static
const struct nla_policy mptcp_pm_endpoint_nl_policy[MPTCP_PM_ENDPOINT_ADDR + 1] = {
[MPTCP_PM_ENDPOINT_ADDR] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
};
/* MPTCP_PM_CMD_SET_LIMITS - do */
static
const struct nla_policy mptcp_pm_set_limits_nl_policy[MPTCP_PM_ATTR_SUBFLOWS + 1] = {
[MPTCP_PM_ATTR_RCV_ADD_ADDRS] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_SUBFLOWS] = { .type = NLA_U32, },
};
/* MPTCP_PM_CMD_SET_FLAGS - do */
static
const struct nla_policy mptcp_pm_set_flags_nl_policy[MPTCP_PM_ATTR_ADDR_REMOTE + 1] = {
[MPTCP_PM_ATTR_ADDR] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
[MPTCP_PM_ATTR_TOKEN] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_ADDR_REMOTE] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
};
/* MPTCP_PM_CMD_ANNOUNCE - do */
static
const struct nla_policy mptcp_pm_announce_nl_policy[MPTCP_PM_ATTR_TOKEN + 1] = {
[MPTCP_PM_ATTR_ADDR] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
[MPTCP_PM_ATTR_TOKEN] = { .type = NLA_U32, },
};
/* MPTCP_PM_CMD_REMOVE - do */
static
const struct nla_policy mptcp_pm_remove_nl_policy[MPTCP_PM_ATTR_LOC_ID + 1] = {
[MPTCP_PM_ATTR_TOKEN] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_LOC_ID] = { .type = NLA_U8, },
};
/* MPTCP_PM_CMD_SUBFLOW_CREATE / DESTROY - do */
static
const struct nla_policy mptcp_pm_subflow_create_nl_policy[MPTCP_PM_ATTR_ADDR_REMOTE + 1] = {
[MPTCP_PM_ATTR_ADDR] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
[MPTCP_PM_ATTR_TOKEN] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_ADDR_REMOTE] = NLA_POLICY_NESTED(mptcp_pm_address_nl_policy),
};
static struct pm_nl_pernet *pm_nl_get_pernet(const struct net *net) static struct pm_nl_pernet *pm_nl_get_pernet(const struct net *net)
{ {
return net_generic(net, pm_nl_pernet_id); return net_generic(net, pm_nl_pernet_id);
@ -1104,29 +1158,6 @@ static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
}, },
}; };
static const struct nla_policy
mptcp_pm_addr_policy[MPTCP_PM_ADDR_ATTR_MAX + 1] = {
[MPTCP_PM_ADDR_ATTR_FAMILY] = { .type = NLA_U16, },
[MPTCP_PM_ADDR_ATTR_ID] = { .type = NLA_U8, },
[MPTCP_PM_ADDR_ATTR_ADDR4] = { .type = NLA_U32, },
[MPTCP_PM_ADDR_ATTR_ADDR6] =
NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
[MPTCP_PM_ADDR_ATTR_PORT] = { .type = NLA_U16 },
[MPTCP_PM_ADDR_ATTR_FLAGS] = { .type = NLA_U32 },
[MPTCP_PM_ADDR_ATTR_IF_IDX] = { .type = NLA_S32 },
};
static const struct nla_policy mptcp_pm_policy[MPTCP_PM_ATTR_MAX + 1] = {
[MPTCP_PM_ATTR_ADDR] =
NLA_POLICY_NESTED(mptcp_pm_addr_policy),
[MPTCP_PM_ATTR_RCV_ADD_ADDRS] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_SUBFLOWS] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_TOKEN] = { .type = NLA_U32, },
[MPTCP_PM_ATTR_LOC_ID] = { .type = NLA_U8, },
[MPTCP_PM_ATTR_ADDR_REMOTE] =
NLA_POLICY_NESTED(mptcp_pm_addr_policy),
};
void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk) void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
{ {
struct mptcp_subflow_context *iter, *subflow = mptcp_subflow_ctx(ssk); struct mptcp_subflow_context *iter, *subflow = mptcp_subflow_ctx(ssk);
@ -1188,7 +1219,7 @@ static int mptcp_pm_parse_pm_addr_attr(struct nlattr *tb[],
/* no validation needed - was already done via nested policy */ /* no validation needed - was already done via nested policy */
err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr, err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
mptcp_pm_addr_policy, info->extack); mptcp_pm_address_nl_policy, info->extack);
if (err) if (err)
return err; return err;
@ -1305,7 +1336,7 @@ next:
static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info) static int mptcp_nl_cmd_add_addr(struct sk_buff *skb, struct genl_info *info)
{ {
struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
struct pm_nl_pernet *pernet = genl_info_pm_nl(info); struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
struct mptcp_pm_addr_entry addr, *entry; struct mptcp_pm_addr_entry addr, *entry;
int ret; int ret;
@ -1486,7 +1517,7 @@ next:
static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info) static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
{ {
struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
struct pm_nl_pernet *pernet = genl_info_pm_nl(info); struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
struct mptcp_pm_addr_entry addr, *entry; struct mptcp_pm_addr_entry addr, *entry;
unsigned int addr_max; unsigned int addr_max;
@ -1677,7 +1708,7 @@ nla_put_failure:
static int mptcp_nl_cmd_get_addr(struct sk_buff *skb, struct genl_info *info) static int mptcp_nl_cmd_get_addr(struct sk_buff *skb, struct genl_info *info)
{ {
struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
struct pm_nl_pernet *pernet = genl_info_pm_nl(info); struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
struct mptcp_pm_addr_entry addr, *entry; struct mptcp_pm_addr_entry addr, *entry;
struct sk_buff *msg; struct sk_buff *msg;
@ -2283,72 +2314,104 @@ nla_put_failure:
nlmsg_free(skb); nlmsg_free(skb);
} }
static const struct genl_small_ops mptcp_pm_ops[] = { static const struct genl_ops mptcp_pm_ops[] = {
{ {
.cmd = MPTCP_PM_CMD_ADD_ADDR, .cmd = MPTCP_PM_CMD_ADD_ADDR,
.doit = mptcp_nl_cmd_add_addr, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_add_addr,
.policy = mptcp_pm_endpoint_nl_policy,
.maxattr = MPTCP_PM_ENDPOINT_ADDR,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_DEL_ADDR, .cmd = MPTCP_PM_CMD_DEL_ADDR,
.doit = mptcp_nl_cmd_del_addr, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_del_addr,
.policy = mptcp_pm_endpoint_nl_policy,
.maxattr = MPTCP_PM_ENDPOINT_ADDR,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_FLUSH_ADDRS, .cmd = MPTCP_PM_CMD_GET_ADDR,
.doit = mptcp_nl_cmd_flush_addrs, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_get_addr,
.dumpit = mptcp_nl_cmd_dump_addrs,
.policy = mptcp_pm_endpoint_nl_policy,
.maxattr = MPTCP_PM_ENDPOINT_ADDR,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_GET_ADDR, .cmd = MPTCP_PM_CMD_FLUSH_ADDRS,
.doit = mptcp_nl_cmd_get_addr, .validate = GENL_DONT_VALIDATE_STRICT,
.dumpit = mptcp_nl_cmd_dump_addrs, .doit = mptcp_nl_cmd_flush_addrs,
.policy = mptcp_pm_endpoint_nl_policy,
.maxattr = MPTCP_PM_ENDPOINT_ADDR,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_SET_LIMITS, .cmd = MPTCP_PM_CMD_SET_LIMITS,
.doit = mptcp_nl_cmd_set_limits, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_set_limits,
.policy = mptcp_pm_set_limits_nl_policy,
.maxattr = MPTCP_PM_ATTR_SUBFLOWS,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_GET_LIMITS, .cmd = MPTCP_PM_CMD_GET_LIMITS,
.doit = mptcp_nl_cmd_get_limits, .validate = GENL_DONT_VALIDATE_STRICT,
.doit = mptcp_nl_cmd_get_limits,
.policy = mptcp_pm_set_limits_nl_policy,
.maxattr = MPTCP_PM_ATTR_SUBFLOWS,
}, },
{ {
.cmd = MPTCP_PM_CMD_SET_FLAGS, .cmd = MPTCP_PM_CMD_SET_FLAGS,
.doit = mptcp_nl_cmd_set_flags, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_set_flags,
.policy = mptcp_pm_set_flags_nl_policy,
.maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_ANNOUNCE, .cmd = MPTCP_PM_CMD_ANNOUNCE,
.doit = mptcp_nl_cmd_announce, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_announce,
.policy = mptcp_pm_announce_nl_policy,
.maxattr = MPTCP_PM_ATTR_TOKEN,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_REMOVE, .cmd = MPTCP_PM_CMD_REMOVE,
.doit = mptcp_nl_cmd_remove, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_remove,
.policy = mptcp_pm_remove_nl_policy,
.maxattr = MPTCP_PM_ATTR_LOC_ID,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_SUBFLOW_CREATE, .cmd = MPTCP_PM_CMD_SUBFLOW_CREATE,
.doit = mptcp_nl_cmd_sf_create, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_sf_create,
.policy = mptcp_pm_subflow_create_nl_policy,
.maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
.flags = GENL_UNS_ADMIN_PERM,
}, },
{ {
.cmd = MPTCP_PM_CMD_SUBFLOW_DESTROY, .cmd = MPTCP_PM_CMD_SUBFLOW_DESTROY,
.doit = mptcp_nl_cmd_sf_destroy, .validate = GENL_DONT_VALIDATE_STRICT,
.flags = GENL_UNS_ADMIN_PERM, .doit = mptcp_nl_cmd_sf_destroy,
.policy = mptcp_pm_subflow_create_nl_policy,
.maxattr = MPTCP_PM_ATTR_ADDR_REMOTE,
.flags = GENL_UNS_ADMIN_PERM,
}, },
}; };
static struct genl_family mptcp_genl_family __ro_after_init = { static struct genl_family mptcp_genl_family __ro_after_init = {
.name = MPTCP_PM_NAME, .name = MPTCP_PM_NAME,
.version = MPTCP_PM_VER, .version = MPTCP_PM_VER,
.maxattr = MPTCP_PM_ATTR_MAX,
.policy = mptcp_pm_policy,
.netnsok = true, .netnsok = true,
.module = THIS_MODULE, .module = THIS_MODULE,
.small_ops = mptcp_pm_ops, .ops = mptcp_pm_ops,
.n_small_ops = ARRAY_SIZE(mptcp_pm_ops), .n_ops = ARRAY_SIZE(mptcp_pm_ops),
.resv_start_op = MPTCP_PM_CMD_SUBFLOW_DESTROY + 1, .resv_start_op = MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
.mcgrps = mptcp_pm_mcgrps, .mcgrps = mptcp_pm_mcgrps,
.n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps), .n_mcgrps = ARRAY_SIZE(mptcp_pm_mcgrps),