]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/l2tp: manage l2tp session name by Manager
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Sep 2024 08:54:01 +0000 (17:54 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 10 Sep 2024 10:30:17 +0000 (19:30 +0900)
Then, Link object for an L2TP session can have reference to the
corresponding NetDev object.

src/network/netdev/l2tp-tunnel.c
src/network/netdev/l2tp-tunnel.h

index b9be66c113152b51ecf0b0f6277f40c371622768..c1372bb1e07d2fb01c84c3a5972f96f85e700dc6 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
 #include <netinet/in.h>
+#include <linux/if_arp.h>
 #include <linux/l2tp.h>
 #include <linux/genetlink.h>
 
@@ -819,6 +820,78 @@ static int netdev_l2tp_tunnel_verify(NetDev *netdev, const char *filename) {
         return 0;
 }
 
+static int netdev_l2tp_tunnel_attach(NetDev *netdev) {
+        L2tpTunnel *t = L2TP(netdev);
+        L2tpSession *session;
+        int r;
+
+        ORDERED_HASHMAP_FOREACH(session, t->sessions_by_section) {
+                assert(session->name);
+
+                r = netdev_attach_name(netdev, session->name);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+static void netdev_l2tp_tunnel_detach(NetDev *netdev) {
+        L2tpTunnel *t = L2TP(netdev);
+        L2tpSession *session;
+
+        ORDERED_HASHMAP_FOREACH(session, t->sessions_by_section)
+                netdev_detach_name(netdev, session->name);
+}
+
+static int netdev_l2tp_tunnel_set_ifindex(NetDev *netdev, const char *name, int ifindex) {
+        L2tpTunnel *t = L2TP(netdev);
+        L2tpSession *session;
+        bool found = false;
+
+        assert(name);
+        assert(ifindex > 0);
+
+        ORDERED_HASHMAP_FOREACH(session, t->sessions_by_section)
+                if (streq(session->name, name)) {
+                        if (session->ifindex == ifindex)
+                                return 0; /* already set. */
+                        if (session->ifindex > 0 && session->ifindex != ifindex)
+                                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EEXIST),
+                                                                "Could not set ifindex %i for session %s, already set to %i.",
+                                                                ifindex, session->name, session->ifindex);
+
+                        session->ifindex = ifindex;
+                        log_netdev_debug(netdev, "Session %s gained ifindex %i.", session->name, session->ifindex);
+                        found = true;
+                        break;
+                }
+
+        if (!found)
+                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+                                                "Received netlink message with unexpected interface name %s (ifindex=%i).",
+                                                name, ifindex);
+
+        ORDERED_HASHMAP_FOREACH(session, t->sessions_by_section)
+                if (session->ifindex <= 0)
+                        return 0; /* This session is not ready yet. */
+
+        return netdev_enter_ready(netdev);
+}
+
+static int netdev_l2tp_tunnel_get_ifindex(NetDev *netdev, const char *name) {
+        L2tpTunnel *t = L2TP(netdev);
+        L2tpSession *session;
+
+        assert(name);
+
+        ORDERED_HASHMAP_FOREACH(session, t->sessions_by_section)
+                if (streq(session->name, name))
+                        return session->ifindex;
+
+        return -ENODEV;
+}
+
 static void l2tp_tunnel_done(NetDev *netdev) {
         L2tpTunnel *t = L2TP(netdev);
 
@@ -835,4 +908,10 @@ const NetDevVTable l2tptnl_vtable = {
         .create_type = NETDEV_CREATE_INDEPENDENT,
         .is_ready_to_create = netdev_l2tp_is_ready_to_create,
         .config_verify = netdev_l2tp_tunnel_verify,
+        .attach = netdev_l2tp_tunnel_attach,
+        .detach = netdev_l2tp_tunnel_detach,
+        .set_ifindex = netdev_l2tp_tunnel_set_ifindex,
+        .get_ifindex = netdev_l2tp_tunnel_get_ifindex,
+        .iftype = ARPHRD_ETHER,
+        .skip_netdev_kind_check = true,
 };
index 6028b35205774e19053414cf24b1ca4af4b9a21d..c558ed49def629e9c0693160d866b5f00c9be42e 100644 (file)
@@ -37,6 +37,7 @@ typedef struct L2tpSession {
         ConfigSection *section;
 
         char *name;
+        int ifindex;
 
         uint32_t session_id;
         uint32_t peer_session_id;