summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2024-09-09 10:37:42 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2024-09-10 12:30:17 +0200
commitc60cd572bdac896dfda70e86aca3c0ead30807f9 (patch)
tree0589add60f2537df19ec603f840706dfbc5dcb97 /src/network
parentnetwork/netdev: allow to register the same NetDev object with multiple names (diff)
downloadsystemd-c60cd572bdac896dfda70e86aca3c0ead30807f9.tar.xz
systemd-c60cd572bdac896dfda70e86aca3c0ead30807f9.zip
network/netdev: add attach(), detach(), set_ifindex(), and get_ifindex() to netdev vtable
Currently no vtable sets these functions, but will be used later.
Diffstat (limited to 'src/network')
-rw-r--r--src/network/netdev/netdev.c23
-rw-r--r--src/network/netdev/netdev.h10
2 files changed, 30 insertions, 3 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index d6c78c318d..d37476bb71 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -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).",
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index 0b942caa4b..10b9d0dd77 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -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;