[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210929094514.15048-3-tparkin@katalix.com>
Date: Wed, 29 Sep 2021 10:45:13 +0100
From: Tom Parkin <tparkin@...alix.com>
To: netdev@...r.kernel.org
Cc: jchapman@...alix.com, Tom Parkin <tparkin@...alix.com>
Subject: [RFC PATCH net-next 2/3] net/l2tp: add flow-based session create API
In order to support multiple logical sessions over a single L2TP tunnel
virtual netdev, the L2TP session creation API needs to be extended. The
new "flow-based" sessions will not create a virtual net device
per-session, but instead will use tc rules and tunnel metadata to direct
traffic:
tc qdisc add dev l2tpt1 handle ffff: ingress
tc filter add dev l2tpt1 parent ffff: flower enc_key_id 1 \
action mirred egress redirect dev eth0
To allow this session type to co-exist with the existing pseudowire
types, define a new API for creating flow-based sessions which the
l2tp netlink code can call directly.
Signed-off-by: Tom Parkin <tparkin@...alix.com>
---
net/l2tp/l2tp_core.c | 46 ++++++++++++++++++++++++++++++++++++++++++++
net/l2tp/l2tp_core.h | 8 ++++++++
2 files changed, 54 insertions(+)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 6a4d3d785c65..dd0b1d64fd14 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1661,6 +1661,52 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
}
EXPORT_SYMBOL_GPL(l2tp_session_create);
+static void l2tp_flow_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+{
+ struct metadata_dst *mdst;
+ __be64 id;
+
+ if (!session->tunnel->dev)
+ goto drop;
+
+ id = key32_to_tunnel_id(htonl(session->session_id));
+
+ mdst = ip_tun_rx_dst(skb, TUNNEL_KEY, id, sizeof(*mdst));
+ if (!mdst)
+ goto drop;
+
+ skb->skb_iif = skb->dev->ifindex;
+ skb->dev = session->tunnel->dev;
+ skb_dst_set(skb, (struct dst_entry *)mdst);
+ skb_reset_mac_header(skb);
+ netif_receive_skb(skb);
+ return;
+
+drop:
+ kfree_skb(skb);
+}
+
+int l2tp_flow_session_create(struct l2tp_tunnel *tunnel,
+ u32 session_id, u32 peer_session_id,
+ struct l2tp_session_cfg *cfg)
+{
+ struct l2tp_session *session;
+ int ret;
+
+ session = l2tp_session_create(0, tunnel, session_id, peer_session_id, cfg);
+ if (IS_ERR(session)) {
+ ret = PTR_ERR(session);
+ goto out;
+ }
+
+ session->recv_skb = l2tp_flow_recv;
+
+ ret = l2tp_session_register(session, tunnel);
+out:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(l2tp_flow_session_create);
+
/*****************************************************************************
* Tunnel virtual netdev
*****************************************************************************/
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 4d2aeb852f38..1a0b9859a7e1 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -252,6 +252,14 @@ int l2tp_session_register(struct l2tp_session *session,
struct l2tp_tunnel *tunnel);
void l2tp_session_delete(struct l2tp_session *session);
+/* Flow-based session.
+ * Optimised datapath which doesn't require a netdev per session instance
+ * and which is managed from userspace using tc rules.
+ */
+int l2tp_flow_session_create(struct l2tp_tunnel *tunnel,
+ u32 session_id, u32 peer_session_id,
+ struct l2tp_session_cfg *cfg);
+
/* Receive path helpers. If data sequencing is enabled for the session these
* functions handle queuing and reordering prior to passing packets to the
* pseudowire code to be passed to userspace.
--
2.17.1
Powered by blists - more mailing lists