]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/netdev: add attach(), detach(), set_ifindex(), and get_ifindex() to netdev...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Sep 2024 08:37:42 +0000 (17:37 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 10 Sep 2024 10:30:17 +0000 (19:30 +0900)
Currently no vtable sets these functions, but will be used later.

src/network/netdev/netdev.c
src/network/netdev/netdev.h

index d6c78c318ddd251eb8168013dc6019f87350b077..d37476bb7165fd9d1dd5be43f93b9abc378ca8c8 100644 (file)
@@ -203,6 +203,11 @@ NetDev* netdev_detach_name(NetDev *netdev, const char *name) {
 static NetDev* netdev_detach_impl(NetDev *netdev) {
         assert(netdev);
 
+        if (netdev->state != _NETDEV_STATE_INVALID &&
+            NETDEV_VTABLE(netdev) &&
+            NETDEV_VTABLE(netdev)->detach)
+                NETDEV_VTABLE(netdev)->detach(netdev);
+
         NetDev *n = netdev_detach_name(netdev, netdev->ifname);
 
         netdev->manager = NULL;
@@ -218,6 +223,8 @@ void netdev_detach(NetDev *netdev) {
 static NetDev* netdev_free(NetDev *netdev) {
         assert(netdev);
 
+        netdev_detach_impl(netdev);
+
         /* Invoke the per-kind done() destructor, but only if the state field is initialized. We conditionalize that
          * because we parse .netdev files twice: once to determine the kind (with a short, minimal NetDev structure
          * allocation, with no room for per-kind fields), and once to read the kind's properties (with a full,
@@ -230,8 +237,6 @@ static NetDev* netdev_free(NetDev *netdev) {
             NETDEV_VTABLE(netdev)->done)
                 NETDEV_VTABLE(netdev)->done(netdev);
 
-        netdev_detach_impl(netdev);
-
         condition_free_list(netdev->conditions);
         free(netdev->filename);
         strv_free(netdev->dropins);
@@ -303,6 +308,12 @@ static int netdev_attach(NetDev *netdev) {
         if (r < 0)
                 return r;
 
+        if (NETDEV_VTABLE(netdev)->attach) {
+                r = NETDEV_VTABLE(netdev)->attach(netdev);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
@@ -335,7 +346,10 @@ void link_assign_netdev(Link *link) {
         if (netdev_get(link->manager, link->ifname, &netdev) < 0)
                 return;
 
-        if (netdev->ifindex != link->ifindex)
+        int ifindex = NETDEV_VTABLE(netdev)->get_ifindex ?
+                NETDEV_VTABLE(netdev)->get_ifindex(netdev, link->ifname) :
+                netdev->ifindex;
+        if (ifindex != link->ifindex)
                 return;
 
         if (NETDEV_VTABLE(netdev)->iftype != link->iftype)
@@ -426,6 +440,9 @@ static int netdev_set_ifindex_impl(NetDev *netdev, const char *name, int ifindex
         assert(name);
         assert(ifindex > 0);
 
+        if (NETDEV_VTABLE(netdev)->set_ifindex)
+                return NETDEV_VTABLE(netdev)->set_ifindex(netdev, name, ifindex);
+
         if (!streq(netdev->ifname, name))
                 return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
                                                 "Received netlink message with unexpected interface name %s (ifindex=%i).",
index 0b942caa4b41d1012293c9e0883e6b6dec5231c1..10b9d0dd77a0d34ec3a2b3fcf70ea5c207a5c54b 100644 (file)
@@ -169,6 +169,16 @@ typedef struct NetDevVTable {
         /* verify that compulsory configuration options were specified */
         int (*config_verify)(NetDev *netdev, const char *filename);
 
+        /* attach/detach additional interfaces, e.g. veth peer or L2TP sessions. */
+        int (*attach)(NetDev *netdev);
+        void (*detach)(NetDev *netdev);
+
+        /* set ifindex of the created interface. */
+        int (*set_ifindex)(NetDev *netdev, const char *name, int ifindex);
+
+        /* get ifindex of the netdev. */
+        int (*get_ifindex)(NetDev *netdev, const char *name);
+
         /* expected iftype, e.g. ARPHRD_ETHER. */
         uint16_t iftype;