[RFC PATCH net-next 3/3] net/l2tp: add netlink attribute to enable flow-based session creation
From: Tom Parkin <hidden>
Date: 2021-09-29 09:45:37
Subsystem:
networking [general], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add an attribute to be used with L2TP_CMD_SESSION_CREATE in order to enable the use of the flow-based datapath. If the attribute is not included in the message, or is set false, the traditional pseudowire lookup is used, which will lead to a virtual session netdev being created. If the attribute is included and is set, no virtual session netdev will be created, and the administrator must use appropriate tc filter/action rules in order to manage session data packets. Signed-off-by: Tom Parkin <redacted> --- include/uapi/linux/l2tp.h | 1 + net/l2tp/l2tp_netlink.c | 36 +++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index bab8c9708611..86e02c8e97a4 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h@@ -127,6 +127,7 @@ enum { L2TP_ATTR_UDP_ZERO_CSUM6_TX, /* flag */ L2TP_ATTR_UDP_ZERO_CSUM6_RX, /* flag */ L2TP_ATTR_PAD, + L2TP_ATTR_FLOW_DATAPATH, /* flag */ __L2TP_ATTR_MAX, };
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 96eb91be9238..5fb5fca74abd 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c@@ -528,6 +528,7 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf struct l2tp_session *session; struct l2tp_session_cfg cfg = { 0, }; struct net *net = genl_info_net(info); + bool flow_path = false; if (!info->attrs[L2TP_ATTR_CONN_ID]) { ret = -EINVAL;
@@ -617,22 +618,30 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); + if (info->attrs[L2TP_ATTR_FLOW_DATAPATH]) + flow_path = nla_get_flag(info->attrs[L2TP_ATTR_FLOW_DATAPATH]); + + if (flow_path) { + ret = l2tp_flow_session_create(tunnel, session_id, peer_session_id, &cfg); + } else { #ifdef CONFIG_MODULES - if (!l2tp_nl_cmd_ops[cfg.pw_type]) { - genl_unlock(); - request_module("net-l2tp-type-%u", cfg.pw_type); - genl_lock(); - } + if (!l2tp_nl_cmd_ops[cfg.pw_type]) { + genl_unlock(); + request_module("net-l2tp-type-%u", cfg.pw_type); + genl_lock(); + } #endif - if (!l2tp_nl_cmd_ops[cfg.pw_type] || !l2tp_nl_cmd_ops[cfg.pw_type]->session_create) { - ret = -EPROTONOSUPPORT; - goto out_tunnel; - } + if (!l2tp_nl_cmd_ops[cfg.pw_type] || + !l2tp_nl_cmd_ops[cfg.pw_type]->session_create) { + ret = -EPROTONOSUPPORT; + goto out_tunnel; + } - ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel, - session_id, - peer_session_id, - &cfg); + ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel, + session_id, + peer_session_id, + &cfg); + } if (ret >= 0) { session = l2tp_tunnel_get_session(tunnel, session_id);
@@ -918,6 +927,7 @@ static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = { .type = NLA_BINARY, .len = 8, }, + [L2TP_ATTR_FLOW_DATAPATH] = { .type = NLA_U8 }, }; static const struct genl_small_ops l2tp_nl_ops[] = {
--
2.17.1