]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/vxcan: also manage peer interface name by manager
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 9 Sep 2024 09:00:28 +0000 (18:00 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 10 Sep 2024 10:30:17 +0000 (19:30 +0900)
Then, the Link object for the peer interface can have a reference to the
corresponding NetDev object.

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

index c129d24734f1d08d05b4453bb3b1920b99034b1c..929d70f61af5f8a47518e09b6df3a272f60b17f8 100644 (file)
@@ -45,6 +45,67 @@ static int netdev_vxcan_verify(NetDev *netdev, const char *filename) {
         return 0;
 }
 
+static int netdev_vxcan_attach(NetDev *netdev) {
+        VxCan *v = VXCAN(netdev);
+        assert(v->ifname_peer);
+
+        return netdev_attach_name(netdev, v->ifname_peer);
+}
+
+static void netdev_vxcan_detach(NetDev *netdev) {
+        VxCan *v = VXCAN(netdev);
+
+        netdev_detach_name(netdev, v->ifname_peer);
+}
+
+static int netdev_vxcan_set_ifindex(NetDev *netdev, const char *name, int ifindex) {
+        VxCan *v = VXCAN(netdev);
+        int r;
+
+        assert(name);
+        assert(ifindex > 0);
+
+        if (streq(netdev->ifname, name)) {
+                r = netdev_set_ifindex_internal(netdev, ifindex);
+                if (r <= 0)
+                        return r;
+
+        } else if (streq(v->ifname_peer, name)) {
+                if (v->ifindex_peer == ifindex)
+                        return 0; /* already set */
+                if (v->ifindex_peer > 0 && v->ifindex_peer != ifindex)
+                        return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EEXIST),
+                                                        "Could not set ifindex %i for peer %s, already set to %i.",
+                                                        ifindex, v->ifname_peer, v->ifindex_peer);
+
+                v->ifindex_peer = ifindex;
+                log_netdev_debug(netdev, "Peer interface %s gained index %i.", v->ifname_peer, ifindex);
+
+        } else
+                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
+                                                "Received netlink message with unexpected interface name %s (ifindex=%i).",
+                                                name, ifindex);
+
+        if (netdev->ifindex > 0 && v->ifindex_peer > 0)
+                return netdev_enter_ready(netdev);
+
+        return 0;
+}
+
+static int netdev_vxcan_get_ifindex(NetDev *netdev, const char *name) {
+        VxCan *v = VXCAN(netdev);
+
+        assert(name);
+
+        if (streq(netdev->ifname, name))
+                return netdev->ifindex;
+
+        if (streq(v->ifname_peer, name))
+                return v->ifindex_peer;
+
+        return -ENODEV;
+}
+
 static void vxcan_done(NetDev *netdev) {
         VxCan *v = VXCAN(netdev);
 
@@ -58,5 +119,9 @@ const NetDevVTable vxcan_vtable = {
         .fill_message_create = netdev_vxcan_fill_message_create,
         .create_type = NETDEV_CREATE_INDEPENDENT,
         .config_verify = netdev_vxcan_verify,
+        .attach = netdev_vxcan_attach,
+        .detach = netdev_vxcan_detach,
+        .set_ifindex = netdev_vxcan_set_ifindex,
+        .get_ifindex = netdev_vxcan_get_ifindex,
         .iftype = ARPHRD_CAN,
 };
index 47be3f017dea83ea794c5ac891fa08d3e8d13526..b835ce2c91a4e4b9158838d0a1bc89fc1b187787 100644 (file)
@@ -9,6 +9,7 @@ struct VxCan {
         NetDev meta;
 
         char *ifname_peer;
+        int ifindex_peer;
 };
 
 DEFINE_NETDEV_CAST(VXCAN, VxCan);