@@ -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,
};
@@ -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[] = {
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 <tparkin@katalix.com> --- include/uapi/linux/l2tp.h | 1 + net/l2tp/l2tp_netlink.c | 36 +++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-)