summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c24
-rw-r--r--src/network/networkd-netdev-bond.c73
-rw-r--r--src/network/networkd-netdev-bond.h12
-rw-r--r--src/network/networkd-netdev-bridge.c65
-rw-r--r--src/network/networkd-netdev-bridge.h6
-rw-r--r--src/network/networkd-netdev-dummy.c56
-rw-r--r--src/network/networkd-netdev-dummy.h6
-rw-r--r--src/network/networkd-netdev-gperf.gperf50
-rw-r--r--src/network/networkd-netdev-macvlan.c88
-rw-r--r--src/network/networkd-netdev-macvlan.h12
-rw-r--r--src/network/networkd-netdev-tunnel.c391
-rw-r--r--src/network/networkd-netdev-tunnel.h14
-rw-r--r--src/network/networkd-netdev-tuntap.c83
-rw-r--r--src/network/networkd-netdev-tuntap.h12
-rw-r--r--src/network/networkd-netdev-veth.c80
-rw-r--r--src/network/networkd-netdev-veth.h9
-rw-r--r--src/network/networkd-netdev-vlan.c98
-rw-r--r--src/network/networkd-netdev-vlan.h8
-rw-r--r--src/network/networkd-netdev-vxlan.c71
-rw-r--r--src/network/networkd-netdev-vxlan.h14
-rw-r--r--src/network/networkd-netdev.c321
-rw-r--r--src/network/networkd-netdev.h101
-rw-r--r--src/network/networkd-network.c15
23 files changed, 686 insertions, 923 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 7a0f30bdf5..0a6f52408f 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1808,7 +1808,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bond->ifname,
- NETDEV(link->network->bond),
+ NETDEVIF(link->network->bond),
NULL);
r = netdev_join(link->network->bond, link, &netdev_join_handler);
@@ -1817,7 +1817,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bond->ifname, strerror(-r),
- NETDEV(link->network->bond),
+ NETDEVIF(link->network->bond),
NULL);
link_enter_failed(link);
return r;
@@ -1831,7 +1831,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname,
- NETDEV(link->network->bridge),
+ NETDEVIF(link->network->bridge),
NULL);
r = netdev_join(link->network->bridge, link, &netdev_join_handler);
@@ -1840,7 +1840,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->bridge->ifname, strerror(-r),
- NETDEV(link->network->bridge),
+ NETDEVIF(link->network->bridge),
NULL);
link_enter_failed(link);
return r;
@@ -1854,7 +1854,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
link->ifname, link->network->tunnel->ifname,
- NETDEV(link->network->tunnel),
+ NETDEVIF(link->network->tunnel),
NULL);
r = netdev_join(link->network->tunnel, link, &netdev_join_handler);
@@ -1863,7 +1863,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, link->network->tunnel->ifname, strerror(-r),
- NETDEV(link->network->tunnel),
+ NETDEVIF(link->network->tunnel),
NULL);
link_enter_failed(link);
return r;
@@ -1876,7 +1876,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
- link->ifname, vlan->ifname, NETDEV(vlan), NULL);
+ link->ifname, vlan->ifname, NETDEVIF(vlan), NULL);
r = netdev_join(vlan, link, &netdev_join_handler);
if (r < 0) {
@@ -1884,7 +1884,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, vlan->ifname, strerror(-r),
- NETDEV(vlan), NULL);
+ NETDEVIF(vlan), NULL);
link_enter_failed(link);
return r;
}
@@ -1896,7 +1896,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%-*s: enslaving by '%s'",
IFNAMSIZ,
- link->ifname, macvlan->ifname, NETDEV(macvlan), NULL);
+ link->ifname, macvlan->ifname, NETDEVIF(macvlan), NULL);
r = netdev_join(macvlan, link, &netdev_join_handler);
if (r < 0) {
@@ -1904,7 +1904,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%-*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, macvlan->ifname, strerror(-r),
- NETDEV(macvlan), NULL);
+ NETDEVIF(macvlan), NULL);
link_enter_failed(link);
return r;
}
@@ -1916,7 +1916,7 @@ static int link_enter_join_netdev(Link *link) {
log_struct_link(LOG_DEBUG, link,
"MESSAGE=%*s: enslaving by '%s'",
IFNAMSIZ,
- link->ifname, vxlan->ifname, NETDEV(vxlan), NULL);
+ link->ifname, vxlan->ifname, NETDEVIF(vxlan), NULL);
r = netdev_join(vxlan, link, &netdev_join_handler);
if (r < 0) {
@@ -1924,7 +1924,7 @@ static int link_enter_join_netdev(Link *link) {
"MESSAGE=%*s: could not join netdev '%s': %s",
IFNAMSIZ,
link->ifname, vxlan->ifname, strerror(-r),
- NETDEV(vxlan), NULL);
+ NETDEVIF(vxlan), NULL);
link_enter_failed(link);
return r;
}
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
index 561ca2a147..562f9eb9d4 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/networkd-netdev-bond.c
@@ -63,49 +63,18 @@ static uint8_t bond_mode_to_kernel(BondMode mode) {
}
}
-static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
+static int netdev_bond_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Bond *b = BOND(netdev);
int r;
+ assert(netdev);
+ assert(!link);
+ assert(b);
assert(m);
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->bond_mode != _NETDEV_BOND_MODE_INVALID) {
+ if (b->mode != _NETDEV_BOND_MODE_INVALID) {
r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE,
- bond_mode_to_kernel(netdev->bond_mode));
+ bond_mode_to_kernel(b->mode));
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_BOND_MODE attribute: %s",
@@ -114,26 +83,22 @@ static int netdev_bond_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
}
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
+ return 0;
+}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
+static void bond_init(NetDev *netdev) {
+ Bond *b = BOND(netdev);
+
+ assert(netdev);
+ assert(b);
- return r;
+ b->mode = _NETDEV_BOND_MODE_INVALID;
}
const NetDevVTable bond_vtable = {
+ .object_size = sizeof(Bond),
+ .init = bond_init,
+ .sections = "Match\0NetDev\0Bond\0",
.fill_message_create = netdev_bond_fill_message_create,
- .enslave = netdev_enslave,
+ .create_type = NETDEV_CREATE_MASTER,
};
diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h
index 03ef08167c..09731b73e2 100644
--- a/src/network/networkd-netdev-bond.h
+++ b/src/network/networkd-netdev-bond.h
@@ -21,9 +21,9 @@
#pragma once
-#include "networkd-netdev.h"
+typedef struct Bond Bond;
-extern const NetDevVTable bond_vtable;
+#include "networkd-netdev.h"
typedef enum BondMode {
NETDEV_BOND_MODE_BALANCE_RR,
@@ -37,6 +37,14 @@ typedef enum BondMode {
_NETDEV_BOND_MODE_INVALID = -1
} BondMode;
+struct Bond {
+ NetDev meta;
+
+ BondMode mode;
+};
+
+extern const NetDevVTable bond_vtable;
+
const char *bond_mode_to_string(BondMode d) _const_;
BondMode bond_mode_from_string(const char *d) _pure_;
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
index 7ae304e96f..91b7051a06 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/networkd-netdev-bridge.c
@@ -28,67 +28,8 @@
#include "networkd-netdev-bridge.h"
#include "missing.h"
-static int netdev_bridge_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
- int r;
-
- assert(netdev);
- assert(netdev->ifname);
- assert(m);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "bridge");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- return r;
-}
-
const NetDevVTable bridge_vtable = {
- .fill_message_create = netdev_bridge_fill_message_create,
- .enslave = netdev_enslave,
+ .object_size = sizeof(Bridge),
+ .sections = "Match\0NetDev\0",
+ .create_type = NETDEV_CREATE_MASTER,
};
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h
index 4d971c62e0..a7d02b1c91 100644
--- a/src/network/networkd-netdev-bridge.h
+++ b/src/network/networkd-netdev-bridge.h
@@ -21,6 +21,12 @@
#pragma once
+typedef struct Bridge Bridge;
+
#include "networkd-netdev.h"
+struct Bridge {
+ NetDev meta;
+};
+
extern const NetDevVTable bridge_vtable;
diff --git a/src/network/networkd-netdev-dummy.c b/src/network/networkd-netdev-dummy.c
index 2f861a73e9..01c10a2d73 100644
--- a/src/network/networkd-netdev-dummy.c
+++ b/src/network/networkd-netdev-dummy.c
@@ -28,58 +28,8 @@
#include "sd-rtnl.h"
#include "networkd-netdev-dummy.h"
-static int netdev_dummy_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
- int r;
-
- assert(netdev);
- assert(netdev->ifname);
- assert(m);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "dummy");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- return r;
-}
-
const NetDevVTable dummy_vtable = {
- .fill_message_create = netdev_dummy_fill_message_create,
+ .object_size = sizeof(Dummy),
+ .sections = "Match\0NetDev\0",
+ .create_type = NETDEV_CREATE_INDEPENDENT,
};
diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h
index dcbd3cc025..0d321e5ae6 100644
--- a/src/network/networkd-netdev-dummy.h
+++ b/src/network/networkd-netdev-dummy.h
@@ -21,6 +21,12 @@
#pragma once
+typedef struct Dummy Dummy;
+
#include "networkd-netdev.h"
+struct Dummy {
+ NetDev meta;
+};
+
extern const NetDevVTable dummy_vtable;
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index 090dfb35eb..b46b8dbfc9 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -27,28 +27,28 @@ NetDev.Name, config_parse_ifname, 0,
NetDev.Kind, config_parse_netdev_kind, 0, offsetof(NetDev, kind)
NetDev.MTUBytes, config_parse_iec_size, 0, offsetof(NetDev, mtu)
NetDev.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac)
-VLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vlanid)
-MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(NetDev, macvlan_mode)
-Tunnel.Local, config_parse_tunnel_address, 0, offsetof(NetDev, local)
-Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(NetDev, remote)
-Tunnel.TOS, config_parse_unsigned, 0, offsetof(NetDev, tos)
-Tunnel.TTL, config_parse_unsigned, 0, offsetof(NetDev, ttl)
-Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(NetDev, tunnel_pmtudisc)
-Peer.Name, config_parse_ifname, 0, offsetof(NetDev, ifname_peer)
-Peer.MACAddress, config_parse_hwaddr, 0, offsetof(NetDev, mac_peer)
-VXLAN.Id, config_parse_uint64, 0, offsetof(NetDev, vxlanid)
-VXLAN.Group, config_parse_tunnel_address, 0, offsetof(NetDev, group)
-VXLAN.TOS, config_parse_unsigned, 0, offsetof(NetDev, tos)
-VXLAN.TTL, config_parse_unsigned, 0, offsetof(NetDev, ttl)
-VXLAN.MacLearning, config_parse_bool, 0, offsetof(NetDev, learning)
-Tun.OneQueue, config_parse_bool, 0, offsetof(NetDev, one_queue)
-Tun.MultiQueue, config_parse_bool, 0, offsetof(NetDev, multi_queue)
-Tun.PacketInfo, config_parse_bool, 0, offsetof(NetDev, packet_info)
-Tun.User, config_parse_string, 0, offsetof(NetDev, user_name)
-Tun.Group, config_parse_string, 0, offsetof(NetDev, group_name)
-Tap.OneQueue, config_parse_bool, 0, offsetof(NetDev, one_queue)
-Tap.MultiQueue, config_parse_bool, 0, offsetof(NetDev, multi_queue)
-Tap.PacketInfo, config_parse_bool, 0, offsetof(NetDev, packet_info)
-Tap.User, config_parse_string, 0, offsetof(NetDev, user_name)
-Tap.Group, config_parse_string, 0, offsetof(NetDev, group_name)
-Bond.Mode, config_parse_bond_mode, 0, offsetof(NetDev, bond_mode)
+VLAN.Id, config_parse_uint64, 0, offsetof(VLan, id)
+MACVLAN.Mode, config_parse_macvlan_mode, 0, offsetof(MacVlan, mode)
+Tunnel.Local, config_parse_tunnel_address, 0, offsetof(Tunnel, local)
+Tunnel.Remote, config_parse_tunnel_address, 0, offsetof(Tunnel, remote)
+Tunnel.TOS, config_parse_unsigned, 0, offsetof(Tunnel, tos)
+Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl)
+Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc)
+Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer)
+Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer)
+VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id)
+VXLAN.Group, config_parse_tunnel_address, 0, offsetof(VxLan, group)
+VXLAN.TOS, config_parse_unsigned, 0, offsetof(VxLan, tos)
+VXLAN.TTL, config_parse_unsigned, 0, offsetof(VxLan, ttl)
+VXLAN.MacLearning, config_parse_bool, 0, offsetof(VxLan, learning)
+Tun.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
+Tun.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
+Tun.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
+Tun.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tun.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Tap.OneQueue, config_parse_bool, 0, offsetof(TunTap, one_queue)
+Tap.MultiQueue, config_parse_bool, 0, offsetof(TunTap, multi_queue)
+Tap.PacketInfo, config_parse_bool, 0, offsetof(TunTap, packet_info)
+Tap.User, config_parse_string, 0, offsetof(TunTap, user_name)
+Tap.Group, config_parse_string, 0, offsetof(TunTap, group_name)
+Bond.Mode, config_parse_bond_mode, 0, offsetof(Bond, mode)
diff --git a/src/network/networkd-netdev-macvlan.c b/src/network/networkd-netdev-macvlan.c
index bfa1ff1acd..2e5554a172 100644
--- a/src/network/networkd-netdev-macvlan.c
+++ b/src/network/networkd-netdev-macvlan.c
@@ -37,67 +37,16 @@ DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode);
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
+ MacVlan *m = MACVLAN(netdev);
int r;
assert(netdev);
- assert(netdev->kind == NETDEV_KIND_MACVLAN);
+ assert(m);
assert(link);
assert(netdev->ifname);
- r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINK attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mtu) {
- r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not open IFLA_LINKINFO container: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "macvlan");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not open IFLA_INFO_DATA container: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
- r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, netdev->macvlan_mode);
+ if (m->mode != _NETDEV_MACVLAN_MODE_INVALID) {
+ r = sd_rtnl_message_append_u32(req, IFLA_MACVLAN_MODE, m->mode);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_MACVLAN_MODE attribute: %s",
@@ -106,25 +55,22 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_rtn
}
}
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not close IFLA_INFO_DATA container %s",
- strerror(-r));
- return r;
- }
+ return 0;
+}
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not close IFLA_LINKINFO container %s",
- strerror(-r));
- return r;
- }
+static void macvlan_init(NetDev *n) {
+ MacVlan *m = MACVLAN(n);
- return 0;
+ assert(n);
+ assert(m);
+
+ m->mode = _NETDEV_MACVLAN_MODE_INVALID;
}
const NetDevVTable macvlan_vtable = {
- .fill_message_create_on_link = netdev_macvlan_fill_message_create,
+ .object_size = sizeof(MacVlan),
+ .init = macvlan_init,
+ .sections = "Match\0NetDev\0MACVLAN\0",
+ .fill_message_create = netdev_macvlan_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
};
diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h
index ea268cc270..d61efc16d4 100644
--- a/src/network/networkd-netdev-macvlan.h
+++ b/src/network/networkd-netdev-macvlan.h
@@ -21,9 +21,9 @@
#pragma once
-#include "networkd-netdev.h"
+typedef struct MacVlan MacVlan;
-extern const NetDevVTable macvlan_vtable;
+#include "networkd-netdev.h"
typedef enum MacVlanMode {
NETDEV_MACVLAN_MODE_PRIVATE = MACVLAN_MODE_PRIVATE,
@@ -34,6 +34,14 @@ typedef enum MacVlanMode {
_NETDEV_MACVLAN_MODE_INVALID = -1
} MacVlanMode;
+struct MacVlan {
+ NetDev meta;
+
+ MacVlanMode mode;
+};
+
+extern const NetDevVTable macvlan_vtable;
+
const char *macvlan_mode_to_string(MacVlanMode d) _const_;
MacVlanMode macvlan_mode_from_string(const char *d) _pure_;
diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c
index 2ecfef8e5a..4561f8d0a9 100644
--- a/src/network/networkd-netdev-tunnel.c
+++ b/src/network/networkd-netdev-tunnel.c
@@ -33,61 +33,14 @@
#include "conf-parser.h"
static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Tunnel *t = IPIP(netdev);
int r;
assert(netdev);
- assert(netdev->kind == NETDEV_KIND_IPIP);
- assert(netdev->ifname);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
assert(link);
assert(m);
- assert(netdev->family == AF_INET);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if(netdev->mtu) {
- r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
+ assert(t);
+ assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0) {
@@ -97,7 +50,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@@ -105,7 +58,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@@ -113,7 +66,7 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
- r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
+ r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_TTL attribute: %s",
@@ -121,81 +74,18 @@ static int netdev_ipip_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Tunnel *t = SIT(netdev);
int r;
assert(netdev);
- assert(netdev->kind == NETDEV_KIND_SIT);
- assert(netdev->ifname);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
assert(link);
assert(m);
- assert(netdev->family == AF_INET);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if(netdev->mtu) {
- r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
+ assert(t);
+ assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex);
if (r < 0) {
@@ -205,7 +95,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &netdev->local.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@@ -213,7 +103,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &netdev->remote.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_IPTUN_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@@ -221,7 +111,7 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, netdev->ttl);
+ r = sd_rtnl_message_append_u8(m, IFLA_IPTUN_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_TTL attribute: %s",
@@ -229,81 +119,18 @@ static int netdev_sit_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Tunnel *t = GRE(netdev);
int r;
assert(netdev);
- assert(netdev->kind == NETDEV_KIND_GRE);
- assert(netdev->ifname);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
assert(link);
assert(m);
- assert(netdev->family == AF_INET);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if(netdev->mtu) {
- r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
+ assert(t);
+ assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_GRE_LINK, link->ifindex);
if (r < 0) {
@@ -313,7 +140,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &netdev->local.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_LOCAL attribute: %s",
@@ -321,7 +148,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &netdev->remote.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_GRE_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_REMOTE attribute: %s",
@@ -329,7 +156,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, netdev->ttl);
+ r = sd_rtnl_message_append_u8(m, IFLA_GRE_TTL, t->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_TTL attribute: %s",
@@ -337,7 +164,7 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, netdev->tos);
+ r = sd_rtnl_message_append_u8(m, IFLA_GRE_TOS, t->tos);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_GRE_TOS attribute: %s",
@@ -345,81 +172,18 @@ static int netdev_gre_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Tunnel *t = VTI(netdev);
int r;
assert(netdev);
- assert(netdev->kind == NETDEV_KIND_VTI);
- assert(netdev->ifname);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
assert(link);
assert(m);
- assert(netdev->family == AF_INET);
-
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if(netdev->mtu) {
- r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
- netdev_kind_to_string(netdev->kind));
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
+ assert(t);
+ assert(t->family == AF_INET);
r = sd_rtnl_message_append_u32(m, IFLA_VTI_LINK, link->ifindex);
if (r < 0) {
@@ -429,7 +193,7 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &netdev->local.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_LOCAL, &t->local.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_LOCAL attribute: %s",
@@ -437,7 +201,7 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &netdev->remote.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_VTI_REMOTE, &t->remote.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_IPTUN_REMOTE attribute: %s",
@@ -445,40 +209,45 @@ static int netdev_vti_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_me
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
+ Tunnel *t = NULL;
+
assert(netdev);
assert(filename);
- if (netdev->local.in.s_addr == INADDR_ANY) {
+ switch (netdev->kind) {
+ case NETDEV_KIND_IPIP:
+ t = IPIP(netdev);
+ break;
+ case NETDEV_KIND_SIT:
+ t = SIT(netdev);
+ break;
+ case NETDEV_KIND_GRE:
+ t = GRE(netdev);
+ break;
+ case NETDEV_KIND_VTI:
+ t = VTI(netdev);
+ break;
+ default:
+ assert_not_reached("Invalid tunnel kind");
+ }
+
+ assert(t);
+
+ if (t->local.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without local address configured in %s. Ignoring", filename);
return -EINVAL;
}
- if (netdev->remote.in.s_addr == INADDR_ANY) {
+ if (t->remote.in.s_addr == INADDR_ANY) {
log_warning("Tunnel without remote address configured in %s. Ignoring", filename);
return -EINVAL;
}
- if (netdev->family != AF_INET) {
+ if (t->family != AF_INET) {
log_warning("Tunnel with invalid address family configured in %s. Ignoring", filename);
return -EINVAL;
}
@@ -496,7 +265,7 @@ int config_parse_tunnel_address(const char *unit,
const char *rvalue,
void *data,
void *userdata) {
- NetDev *n = userdata;
+ Tunnel *t = userdata;
union in_addr_union *addr = data;
int r;
@@ -505,7 +274,7 @@ int config_parse_tunnel_address(const char *unit,
assert(rvalue);
assert(data);
- r = net_parse_inaddr(rvalue, &n->family, addr);
+ r = net_parse_inaddr(rvalue, &t->family, addr);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Tunnel address is invalid, ignoring assignment: %s", rvalue);
@@ -515,22 +284,74 @@ int config_parse_tunnel_address(const char *unit,
return 0;
}
+static void ipip_init(NetDev *n) {
+ Tunnel *t = IPIP(n);
+
+ assert(n);
+ assert(t);
+
+ t->pmtudisc = true;
+}
+
+static void sit_init(NetDev *n) {
+ Tunnel *t = SIT(n);
+
+ assert(n);
+ assert(t);
+
+ t->pmtudisc = true;
+}
+
+static void vti_init(NetDev *n) {
+ Tunnel *t = VTI(n);
+
+ assert(n);
+ assert(t);
+
+ t->pmtudisc = true;
+}
+
+static void gre_init(NetDev *n) {
+ Tunnel *t = GRE(n);
+
+ assert(n);
+ assert(t);
+
+ t->pmtudisc = true;
+}
+
const NetDevVTable ipip_vtable = {
- .fill_message_create_on_link = netdev_ipip_fill_message_create,
+ .object_size = sizeof(Tunnel),
+ .init = ipip_init,
+ .sections = "Match\0NetDev\0Tunnel\0",
+ .fill_message_create = netdev_ipip_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable sit_vtable = {
- .fill_message_create_on_link = netdev_sit_fill_message_create,
+ .object_size = sizeof(Tunnel),
+ .init = sit_init,
+ .sections = "Match\0NetDev\0Tunnel\0",
+ .fill_message_create = netdev_sit_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable vti_vtable = {
- .fill_message_create_on_link = netdev_vti_fill_message_create,
+ .object_size = sizeof(Tunnel),
+ .init = vti_init,
+ .sections = "Match\0NetDev\0Tunnel\0",
+ .fill_message_create = netdev_vti_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
const NetDevVTable gre_vtable = {
- .fill_message_create_on_link = netdev_gre_fill_message_create,
+ .object_size = sizeof(Tunnel),
+ .init = gre_init,
+ .sections = "Match\0NetDev\0Tunnel\0",
+ .fill_message_create = netdev_gre_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_tunnel_verify,
};
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
index b30204b76b..000a6460e7 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/networkd-netdev-tunnel.h
@@ -21,8 +21,22 @@
#pragma once
+typedef struct Tunnel Tunnel;
+
#include "networkd-netdev.h"
+struct Tunnel {
+ NetDev meta;
+
+ int family;
+
+ unsigned ttl;
+ unsigned tos;
+ union in_addr_union local;
+ union in_addr_union remote;
+ bool pmtudisc;
+};
+
extern const NetDevVTable ipip_vtable;
extern const NetDevVTable sit_vtable;
extern const NetDevVTable vti_vtable;
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index 8f60461746..dd3bd96dbb 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -28,24 +28,27 @@
#define TUN_DEV "/dev/net/tun"
static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
+ TunTap *t;
assert(netdev);
+ assert(netdev->ifname);
assert(ifr);
- memset(ifr, 0, sizeof(*ifr));
-
- if (netdev->kind == NETDEV_KIND_TAP)
+ if (netdev->kind == NETDEV_KIND_TAP) {
+ t = TAP(netdev);
ifr->ifr_flags |= IFF_TAP;
- else
+ } else {
+ t = TUN(netdev);
ifr->ifr_flags |= IFF_TUN;
+ }
- if (!netdev->packet_info)
+ if (!t->packet_info)
ifr->ifr_flags |= IFF_NO_PI;
- if (netdev->one_queue)
+ if (t->one_queue)
ifr->ifr_flags |= IFF_ONE_QUEUE;
- if (netdev->multi_queue)
+ if (t->multi_queue)
ifr->ifr_flags |= IFF_MULTI_QUEUE;
strncpy(ifr->ifr_name, netdev->ifname, IFNAMSIZ-1);
@@ -55,12 +58,16 @@ static int netdev_fill_tuntap_message(NetDev *netdev, struct ifreq *ifr) {
static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
_cleanup_close_ int fd;
+ TunTap *t = NULL;
const char *user;
const char *group;
uid_t uid;
gid_t gid;
int r = 0;
+ assert(netdev);
+ assert(ifr);
+
fd = open(TUN_DEV, O_RDWR);
if (fd < 0) {
log_error_netdev(netdev,
@@ -77,14 +84,21 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return r;
}
- if(netdev->user_name) {
+ if (netdev->kind == NETDEV_KIND_TAP)
+ t = TAP(netdev);
+ else
+ t = TUN(netdev);
+
+ assert(t);
- user = netdev->user_name;
+ if(t->user_name) {
+
+ user = t->user_name;
r = get_user_creds(&user, &uid, NULL, NULL, NULL);
if (r < 0) {
log_error("Cannot resolve user name %s: %s",
- netdev->user_name, strerror(-r));
+ t->user_name, strerror(-r));
return 0;
}
@@ -96,14 +110,14 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
}
- if(netdev->group_name) {
+ if(t->group_name) {
- group = netdev->group_name;
+ group = t->group_name;
r = get_group_creds(&group, &gid);
if (r < 0) {
log_error("Cannot resolve group name %s: %s",
- netdev->group_name, strerror(-r));
+ t->group_name, strerror(-r));
return 0;
}
@@ -129,34 +143,47 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
}
static int netdev_create_tuntap(NetDev *netdev) {
- struct ifreq ifr;
+ struct ifreq ifr = {};
int r;
- assert(netdev);
- assert(netdev->ifname);
-
- switch(netdev->kind) {
- case NETDEV_KIND_TUN:
- case NETDEV_KIND_TAP:
- break;
- default:
- return -ENOTSUP;
- }
-
r = netdev_fill_tuntap_message(netdev, &ifr);
if(r < 0)
return r;
- log_debug_netdev(netdev, "Creating tuntap netdev: %s",
- netdev_kind_to_string(netdev->kind));
-
return netdev_tuntap_add(netdev, &ifr);
}
+static void tuntap_done(NetDev *netdev) {
+ TunTap *t = NULL;
+
+ assert(netdev);
+
+ if (netdev->kind == NETDEV_KIND_TUN)
+ t = TUN(netdev);
+ else
+ t = TAP(netdev);
+
+ assert(t);
+
+ free(t->user_name);
+ t->user_name = NULL;
+
+ free(t->group_name);
+ t->group_name = NULL;
+}
+
const NetDevVTable tun_vtable = {
+ .object_size = sizeof(TunTap),
+ .sections = "Match\0NetDev\0Tun\0",
+ .done = tuntap_done,
.create = netdev_create_tuntap,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
};
const NetDevVTable tap_vtable = {
+ .object_size = sizeof(TunTap),
+ .sections = "Match\0NetDev\0Tap\0",
+ .done = tuntap_done,
.create = netdev_create_tuntap,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
};
diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h
index 2b6e48f79b..b804875bbb 100644
--- a/src/network/networkd-netdev-tuntap.h
+++ b/src/network/networkd-netdev-tuntap.h
@@ -21,7 +21,19 @@
#pragma once
+typedef struct TunTap TunTap;
+
#include "networkd-netdev.h"
+struct TunTap {
+ NetDev meta;
+
+ char *user_name;
+ char *group_name;
+ bool one_queue;
+ bool multi_queue;
+ bool packet_info;
+};
+
extern const NetDevVTable tun_vtable;
extern const NetDevVTable tap_vtable;
diff --git a/src/network/networkd-netdev-veth.c b/src/network/networkd-netdev-veth.c
index c995bbb707..da09ef908f 100644
--- a/src/network/networkd-netdev-veth.c
+++ b/src/network/networkd-netdev-veth.c
@@ -27,47 +27,15 @@
#include "sd-rtnl.h"
#include "networkd-netdev-veth.h"
-static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
+static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ Veth *v = VETH(netdev);
int r;
assert(netdev);
- assert(netdev->ifname);
+ assert(!link);
+ assert(v);
assert(m);
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
r = sd_rtnl_message_open_container(m, VETH_INFO_PEER);
if (r < 0) {
log_error_netdev(netdev,
@@ -76,16 +44,16 @@ static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
- if (netdev->ifname_peer) {
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname_peer);
+ if (v->ifname_peer) {
+ r = sd_rtnl_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
if (r < 0) {
log_error("Failed to add netlink interface name: %s", strerror(-r));
return r;
}
}
- if (netdev->mac_peer) {
- r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac_peer);
+ if (v->mac_peer) {
+ r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_ADDRESS attribute: %s",
@@ -102,34 +70,28 @@ static int netdev_veth_fill_message_create(NetDev *netdev, sd_rtnl_message *m) {
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_veth_verify(NetDev *netdev, const char *filename) {
+ Veth *v = VETH(netdev);
int r;
assert(netdev);
+ assert(v);
assert(filename);
- if (!netdev->ifname_peer) {
+ if (!v->ifname_peer) {
log_warning("Veth NetDev without peer name configured in %s. Ignoring",
filename);
return -EINVAL;
}
- if (!netdev->mac_peer) {
- r = netdev_get_mac(netdev->ifname_peer, &netdev->mac_peer);
+ if (!v->mac_peer) {
+ r = netdev_get_mac(v->ifname_peer, &v->mac_peer);
if (r < 0) {
log_warning("Failed to generate predictable MAC address for %s. Ignoring",
- netdev->ifname_peer);
+ v->ifname_peer);
return -EINVAL;
}
}
@@ -137,7 +99,21 @@ static int netdev_veth_verify(NetDev *netdev, const char *filename) {
return 0;
}
+static void veth_done(NetDev *n) {
+ Veth *v = VETH(n);
+
+ assert(n);
+ assert(v);
+
+ free(v->ifname_peer);
+ free(v->mac_peer);
+}
+
const NetDevVTable veth_vtable = {
+ .object_size = sizeof(Veth),
+ .sections = "Match\0NetDev\0Peer\0",
+ .done = veth_done,
.fill_message_create = netdev_veth_fill_message_create,
+ .create_type = NETDEV_CREATE_INDEPENDENT,
.config_verify = netdev_veth_verify,
};
diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h
index 93dcdfa1a4..85d8b49a75 100644
--- a/src/network/networkd-netdev-veth.h
+++ b/src/network/networkd-netdev-veth.h
@@ -21,6 +21,15 @@
#pragma once
+typedef struct Veth Veth;
+
#include "networkd-netdev.h"
+struct Veth {
+ NetDev meta;
+
+ char *ifname_peer;
+ struct ether_addr *mac_peer;
+};
+
extern const NetDevVTable veth_vtable;
diff --git a/src/network/networkd-netdev-vlan.c b/src/network/networkd-netdev-vlan.c
index b625f4b079..13c4456733 100644
--- a/src/network/networkd-netdev-vlan.c
+++ b/src/network/networkd-netdev-vlan.c
@@ -26,68 +26,16 @@
#include "list.h"
static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *req) {
+ VLan *v = VLAN(netdev);
int r;
assert(netdev);
- assert(netdev->ifname);
- assert(netdev->kind == NETDEV_KIND_VLAN);
+ assert(v);
assert(link);
assert(req);
- r = sd_rtnl_message_append_u32(req, IFLA_LINK, link->ifindex);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINK attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_append_string(req, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->mtu) {
- r = sd_rtnl_message_append_u32(req, IFLA_MTU, netdev->mtu);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_MTU attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- if (netdev->mac) {
- r = sd_rtnl_message_append_ether_addr(req, IFLA_ADDRESS, netdev->mac);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_ADDRESS attribute: %s",
- strerror(-r));
- return r;
- }
- }
-
- r = sd_rtnl_message_open_container(req, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not open IFLA_LINKINFO container: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(req, IFLA_INFO_DATA, "vlan");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not open IFLA_INFO_DATA container: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->vlanid <= VLANID_MAX) {
- r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, netdev->vlanid);
+ if (v->id <= VLANID_MAX) {
+ r = sd_rtnl_message_append_u16(req, IFLA_VLAN_ID, v->id);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VLAN_ID attribute: %s",
@@ -96,38 +44,38 @@ static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_m
}
}
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not close IFLA_INFO_DATA container %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_close_container(req);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not close IFLA_LINKINFO container %s",
- strerror(-r));
- return r;
- }
-
return 0;
}
static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
+ VLan *v = VLAN(netdev);
+
assert(netdev);
+ assert(v);
assert(filename);
- if (netdev->vlanid > VLANID_MAX) {
- log_warning("VLAN without valid Id configured in %s. Ignoring", filename);
+ if (v->id > VLANID_MAX) {
+ log_warning("VLAN without valid Id (%"PRIu64") configured in %s. Ignoring", v->id, filename);
return -EINVAL;
}
return 0;
}
+static void vlan_init(NetDev *netdev) {
+ VLan *v = VLAN(netdev);
+
+ assert(netdev);
+ assert(v);
+
+ v->id = VLANID_MAX + 1;
+}
+
const NetDevVTable vlan_vtable = {
- .fill_message_create_on_link = netdev_vlan_fill_message_create,
+ .object_size = sizeof(VLan),
+ .init = vlan_init,
+ .sections = "Match\0NetDev\0VLAN\0",
+ .fill_message_create = netdev_vlan_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vlan_verify,
};
diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h
index 95f630f190..0c0fbbe093 100644
--- a/src/network/networkd-netdev-vlan.h
+++ b/src/network/networkd-netdev-vlan.h
@@ -21,8 +21,16 @@
#pragma once
+typedef struct VLan VLan;
+
#include "networkd-netdev.h"
#define VLANID_MAX 4094
+struct VLan {
+ NetDev meta;
+
+ uint64_t id;
+};
+
extern const NetDevVTable vlan_vtable;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
index 38692c687c..215c117291 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/networkd-netdev-vxlan.c
@@ -28,39 +28,17 @@
#include "missing.h"
static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
+ VxLan *v = VXLAN(netdev);
int r;
assert(netdev);
+ assert(v);
assert(link);
- assert(link->ifname);
assert(m);
- r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_IFNAME, attribute: %s",
- strerror(-r));
- return r;
- }
- r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "vxlan");
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_INFO_DATA attribute: %s",
- strerror(-r));
- return r;
- }
-
- if (netdev->vlanid <= VXLAN_VID_MAX) {
- r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, netdev->vxlanid);
+ if (v->id <= VXLAN_VID_MAX) {
+ r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_ID attribute: %s",
@@ -69,7 +47,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
- r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &netdev->group.in);
+ r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_GROUP attribute: %s",
@@ -85,8 +63,8 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
return r;
}
- if(netdev->ttl) {
- r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, netdev->ttl);
+ if(v->ttl) {
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_TTL attribute: %s",
@@ -95,8 +73,8 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
- if(netdev->tos) {
- r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, netdev->tos);
+ if(v->tos) {
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_TOS attribute: %s",
@@ -105,7 +83,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
}
}
- r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, netdev->learning);
+ r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
if (r < 0) {
log_error_netdev(netdev,
"Could not append IFLA_VXLAN_LEARNING attribute: %s",
@@ -113,22 +91,17 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_
return r;
}
- r = sd_rtnl_message_close_container(m);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not append IFLA_LINKINFO attribute: %s",
- strerror(-r));
- return r;
- }
-
return r;
}
static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
+ VxLan *v = VXLAN(netdev);
+
assert(netdev);
+ assert(v);
assert(filename);
- if (netdev->vxlanid > VXLAN_VID_MAX) {
+ if (v->id > VXLAN_VID_MAX) {
log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
return -EINVAL;
}
@@ -136,7 +109,21 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
return 0;
}
+static void vxlan_init(NetDev *netdev) {
+ VxLan *v = VXLAN(netdev);
+
+ assert(netdev);
+ assert(v);
+
+ v->id = VXLAN_VID_MAX + 1;
+ v->learning = true;
+}
+
const NetDevVTable vxlan_vtable = {
- .fill_message_create_on_link = netdev_vxlan_fill_message_create,
+ .object_size = sizeof(VxLan),
+ .init = vxlan_init,
+ .sections = "Match\0NetDev\0VXLAN\0",
+ .fill_message_create = netdev_vxlan_fill_message_create,
+ .create_type = NETDEV_CREATE_STACKED,
.config_verify = netdev_vxlan_verify,
};
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h
index a2de2713cc..8c906f1075 100644
--- a/src/network/networkd-netdev-vxlan.h
+++ b/src/network/networkd-netdev-vxlan.h
@@ -21,8 +21,22 @@
#pragma once
+typedef struct VxLan VxLan;
+
#include "networkd-netdev.h"
+#include "in-addr-util.h"
+
#define VXLAN_VID_MAX (1u << 24) - 1
+struct VxLan {
+ NetDev meta;
+
+ uint64_t id;
+ union in_addr_union group;
+ unsigned tos;
+ unsigned ttl;
+ bool learning;
+};
+
extern const NetDevVTable vxlan_vtable;
diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c
index 86f2250c8f..4a6f6e3475 100644
--- a/src/network/networkd-netdev.c
+++ b/src/network/networkd-netdev.c
@@ -22,15 +22,6 @@
#include <net/if.h>
#include "networkd-netdev.h"
-#include "networkd-netdev-bridge.h"
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-vlan.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd-netdev-vxlan.h"
-#include "networkd-netdev-tunnel.h"
-#include "networkd-netdev-veth.h"
-#include "networkd-netdev-dummy.h"
-#include "networkd-netdev-tuntap.h"
#include "network-internal.h"
#include "path-util.h"
#include "conf-files.h"
@@ -111,17 +102,17 @@ static void netdev_free(NetDev *netdev) {
free(netdev->description);
free(netdev->ifname);
- free(netdev->ifname_peer);
free(netdev->mac);
- free(netdev->mac_peer);
- free(netdev->user_name);
- free(netdev->group_name);
condition_free_list(netdev->match_host);
condition_free_list(netdev->match_virt);
condition_free_list(netdev->match_kernel);
condition_free_list(netdev->match_arch);
+ if (NETDEV_VTABLE(netdev) &&
+ NETDEV_VTABLE(netdev)->done)
+ NETDEV_VTABLE(netdev)->done(netdev);
+
free(netdev);
}
@@ -268,6 +259,8 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda
return 1;
}
+ log_debug_netdev(netdev, "created");
+
return 1;
}
@@ -294,46 +287,10 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callbac
link_ref(link);
LIST_PREPEND(callbacks, netdev->callbacks, cb);
- }
-
- return 0;
-}
-
-/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
-int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
- int r;
-
- assert(netdev);
- assert(netdev->manager);
- assert(netdev->manager->rtnl);
- assert(NETDEV_VTABLE(netdev));
-
- if (NETDEV_VTABLE(netdev)->fill_message_create_on_link) {
- _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
-
- r = sd_rtnl_message_new_link(netdev->manager->rtnl, &req,
- RTM_NEWLINK, 0);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not allocate RTM_SETLINK message: %s",
- strerror(-r));
- return r;
- }
-
- NETDEV_VTABLE(netdev)->fill_message_create_on_link(netdev, link, req);
- r = sd_rtnl_call_async(netdev->manager->rtnl, req, callback, link, 0, NULL);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not send rtnetlink message: %s", strerror(-r));
- return r;
- }
-
- link_ref(link);
- } else if (NETDEV_VTABLE(netdev)->enslave) {
- return NETDEV_VTABLE(netdev)->enslave(netdev, link, callback);
- } else
- assert_not_reached("Joining link to netdev of invalid kind");
+ log_debug_netdev(netdev, "will enslave '%s', when reday",
+ link->ifname);
+ }
return 0;
}
@@ -487,8 +444,156 @@ int netdev_get_mac(const char *ifname, struct ether_addr **ret) {
return 0;
}
+static int netdev_create(NetDev *netdev, Link *link) {
+ int r;
+
+ assert(netdev);
+
+ /* create netdev */
+ if (NETDEV_VTABLE(netdev)->create) {
+ r = NETDEV_VTABLE(netdev)->create(netdev);
+ if (r < 0)
+ return r;
+
+ log_debug_netdev(netdev, "created");
+ } else {
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+
+ r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not allocate RTM_NEWLINK message: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_IFNAME, attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ if (netdev->mac) {
+ r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, netdev->mac);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_ADDRESS attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (netdev->mtu) {
+ r = sd_rtnl_message_append_u32(m, IFLA_MTU, netdev->mtu);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_MTU attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ if (link) {
+ r = sd_rtnl_message_append_u32(m, IFLA_LINK, link->ifindex);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Colud not append IFLA_LINK attribute: %s",
+ strerror(-r));
+ return r;
+ }
+ }
+
+ r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_LINKINFO attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
+ netdev_kind_to_string(netdev->kind));
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_INFO_DATA attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ if (NETDEV_VTABLE(netdev)->fill_message_create) {
+ r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, link, m);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_rtnl_message_close_container(m);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_LINKINFO attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+ r = sd_rtnl_message_close_container(m);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not append IFLA_LINKINFO attribute: %s",
+ strerror(-r));
+ return r;
+ }
+
+
+ r = sd_rtnl_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
+ if (r < 0) {
+ log_error_netdev(netdev,
+ "Could not send rtnetlink message: %s", strerror(-r));
+ return r;
+ }
+
+ netdev_ref(netdev);
+
+ netdev->state = NETDEV_STATE_CREATING;
+
+ log_debug_netdev(netdev, "creating");
+ }
+
+ return 0;
+}
+
+/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
+int netdev_join(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
+ int r;
+
+ assert(netdev);
+ assert(netdev->manager);
+ assert(netdev->manager->rtnl);
+ assert(NETDEV_VTABLE(netdev));
+
+ switch (NETDEV_VTABLE(netdev)->create_type) {
+ case NETDEV_CREATE_MASTER:
+ r = netdev_enslave(netdev, link, callback);
+ if (r < 0)
+ return r;
+
+ break;
+ case NETDEV_CREATE_STACKED:
+ r = netdev_create(netdev, link);
+ if (r < 0)
+ return r;
+
+ break;
+ default:
+ assert_not_reached("Can not join independent netdev");
+ }
+
+ return 0;
+}
+
static int netdev_load_one(Manager *manager, const char *filename) {
_cleanup_netdev_unref_ NetDev *netdev = NULL;
+ _cleanup_free_ NetDev *netdev_raw = NULL;
_cleanup_fclose_ FILE *file = NULL;
int r;
@@ -508,69 +613,65 @@ static int netdev_load_one(Manager *manager, const char *filename) {
return 0;
}
- netdev = new0(NetDev, 1);
- if (!netdev)
+ netdev_raw = new0(NetDev, 1);
+ if (!netdev_raw)
return log_oom();
- netdev->n_ref = 1;
- netdev->manager = manager;
- netdev->state = _NETDEV_STATE_INVALID;
- netdev->kind = _NETDEV_KIND_INVALID;
- netdev->macvlan_mode = _NETDEV_MACVLAN_MODE_INVALID;
- netdev->bond_mode = _NETDEV_BOND_MODE_INVALID;
- netdev->vlanid = VLANID_MAX + 1;
- netdev->vxlanid = VXLAN_VID_MAX + 1;
- netdev->tunnel_pmtudisc = true;
- netdev->learning = true;
+ netdev_raw->kind = _NETDEV_KIND_INVALID;
r = config_parse(NULL, filename, file,
- "Match\0NetDev\0VLAN\0MACVLAN\0VXLAN\0Tunnel\0Peer\0Tun\0Tap\0Bond\0",
+ "Match\0NetDev\0",
config_item_perf_lookup, network_netdev_gperf_lookup,
- false, false, true, netdev);
+ true, false, true, netdev_raw);
if (r < 0)
return r;
+ r = fseek(file, 0, SEEK_SET);
+ if (r < 0)
+ return -errno;
+
/* skip out early if configuration does not match the environment */
if (net_match_config(NULL, NULL, NULL, NULL, NULL,
- netdev->match_host, netdev->match_virt,
- netdev->match_kernel, netdev->match_arch,
+ netdev_raw->match_host, netdev_raw->match_virt,
+ netdev_raw->match_kernel, netdev_raw->match_arch,
NULL, NULL, NULL, NULL, NULL, NULL) <= 0)
return 0;
- if (!NETDEV_VTABLE(netdev)) {
+ if (!NETDEV_VTABLE(netdev_raw)) {
log_warning("NetDev with invalid Kind configured in %s. Ignoring", filename);
return 0;
}
- /* verify configuration */
- if (NETDEV_VTABLE(netdev)->config_verify) {
- r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
- if (r < 0)
- return 0;
- }
-
- if (!netdev->ifname) {
+ if (!netdev_raw->ifname) {
log_warning("NetDev without Name configured in %s. Ignoring", filename);
return 0;
}
- if (netdev->kind != NETDEV_KIND_VLAN && netdev->vlanid <= VLANID_MAX) {
- log_warning("VLAN Id configured for a %s in %s. Ignoring",
- netdev_kind_to_string(netdev->kind), filename);
- return 0;
- }
+ netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
+ if (!netdev)
+ return log_oom();
- if (netdev->kind != NETDEV_KIND_VXLAN && netdev->vxlanid <= VXLAN_VID_MAX) {
- log_warning("VXLAN Id configured for a %s in %s. Ignoring",
- netdev_kind_to_string(netdev->kind), filename);
- return 0;
- }
+ netdev->n_ref = 1;
+ netdev->manager = manager;
+ netdev->state = _NETDEV_STATE_INVALID;
+ netdev->kind = netdev_raw->kind;
+ netdev->ifname = netdev_raw->ifname;
- if (netdev->kind != NETDEV_KIND_MACVLAN &&
- netdev->macvlan_mode != _NETDEV_MACVLAN_MODE_INVALID) {
- log_warning("MACVLAN Mode configured for a %s in %s. Ignoring",
- netdev_kind_to_string(netdev->kind), filename);
- return 0;
+ if (NETDEV_VTABLE(netdev)->init)
+ NETDEV_VTABLE(netdev)->init(netdev);
+
+ r = config_parse(NULL, filename, file,
+ NETDEV_VTABLE(netdev)->sections,
+ config_item_perf_lookup, network_netdev_gperf_lookup,
+ false, false, false, netdev);
+ if (r < 0)
+ return r;
+
+ /* verify configuration */
+ if (NETDEV_VTABLE(netdev)->config_verify) {
+ r = NETDEV_VTABLE(netdev)->config_verify(netdev, filename);
+ if (r < 0)
+ return 0;
}
netdev->filename = strdup(filename);
@@ -594,38 +695,16 @@ static int netdev_load_one(Manager *manager, const char *filename) {
log_debug_netdev(netdev, "loaded %s", netdev_kind_to_string(netdev->kind));
- /* create netdev */
- if (NETDEV_VTABLE(netdev)->fill_message_create) {
- _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
-
- r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not allocate RTM_NEWLINK message: %s",
- strerror(-r));
- return r;
- }
-
- r = NETDEV_VTABLE(netdev)->fill_message_create(netdev, m);
+ switch (NETDEV_VTABLE(netdev)->create_type) {
+ case NETDEV_CREATE_MASTER:
+ case NETDEV_CREATE_INDEPENDENT:
+ r = netdev_create(netdev, NULL);
if (r < 0)
return r;
- r = sd_rtnl_call_async(netdev->manager->rtnl, m, netdev_create_handler, netdev, 0, NULL);
- if (r < 0) {
- log_error_netdev(netdev,
- "Could not send rtnetlink message: %s", strerror(-r));
- return r;
- }
-
- netdev_ref(netdev);
-
- log_debug_netdev(netdev, "creating");
-
- netdev->state = NETDEV_STATE_CREATING;
- } else if (NETDEV_VTABLE(netdev)->create) {
- r = NETDEV_VTABLE(netdev)->create(netdev);
- if (r < 0)
- return r;
+ break;
+ default:
+ break;
}
netdev = NULL;
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 042e1601c6..e9a8a169db 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -66,6 +66,14 @@ typedef enum NetDevState {
_NETDEV_STATE_INVALID = -1,
} NetDevState;
+typedef enum NetDevCreateType {
+ NETDEV_CREATE_INDEPENDENT,
+ NETDEV_CREATE_MASTER,
+ NETDEV_CREATE_STACKED,
+ _NETDEV_CREATE_MAX,
+ _NETDEV_CREATE_INVALID = -1,
+} NetDevCreateType;
+
struct NetDev {
Manager *manager;
@@ -78,49 +86,50 @@ struct NetDev {
Condition *match_kernel;
Condition *match_arch;
+ NetDevState state;
+ NetDevKind kind;
char *description;
char *ifname;
- char *ifname_peer;
- char *user_name;
- char *group_name;
- size_t mtu;
struct ether_addr *mac;
- struct ether_addr *mac_peer;
- NetDevKind kind;
-
- uint64_t vlanid;
- uint64_t vxlanid;
- int32_t macvlan_mode;
- int32_t bond_mode;
-
+ size_t mtu;
int ifindex;
- NetDevState state;
-
- bool tunnel_pmtudisc;
- bool learning;
- bool one_queue;
- bool multi_queue;
- bool packet_info;
-
- unsigned ttl;
- unsigned tos;
- int family;
- union in_addr_union local;
- union in_addr_union remote;
- union in_addr_union group;
LIST_HEAD(netdev_join_callback, callbacks);
};
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-macvlan.h"
+#include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-dummy.h"
+#include "networkd-netdev-tuntap.h"
+
struct NetDevVTable {
- /* fill in message to create netdev */
- int (*fill_message_create)(NetDev *netdev, sd_rtnl_message *message);
+ /* How much memory does an object of this unit type need */
+ size_t object_size;
+
+ /* Config file sections this netdev kind understands, separated
+ * by NUL chars */
+ const char *sections;
- /* fill in message to create netdev on top of a given link */
- int (*fill_message_create_on_link)(NetDev *netdev, Link *link, sd_rtnl_message *message);
+ /* This should reset all type-specific variables. This should
+ * not allocate memory, and is called with zero-initialized
+ * data. It should hence only initialize variables that need
+ * to be set != 0. */
+ void (*init)(NetDev *n);
- /* fill in message to enslave link by netdev */
- int (*enslave)(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback);
+ /* This should free all kind-specific variables. It should be
+ * idempotent. */
+ void (*done)(NetDev *n);
+
+ /* fill in message to create netdev */
+ int (*fill_message_create)(NetDev *netdev, Link *link, sd_rtnl_message *message);
+
+ /* specifies if netdev is independent, or a master device or a stacked device */
+ NetDevCreateType create_type;
/* create netdev, if not done via rtnl */
int (*create)(NetDev *netdev);
@@ -133,6 +142,32 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
+/* For casting a netdev into the various netdev kinds */
+#define DEFINE_CAST(UPPERCASE, MixedCase) \
+ static inline MixedCase* UPPERCASE(NetDev *n) { \
+ if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE)) \
+ return NULL; \
+ \
+ return (MixedCase*) n; \
+ }
+
+/* For casting the various netdev kinds into a netdev */
+#define NETDEV(n) (&(n)->meta)
+
+DEFINE_CAST(BRIDGE, Bridge);
+DEFINE_CAST(BOND, Bond);
+DEFINE_CAST(VLAN, VLan);
+DEFINE_CAST(MACVLAN, MacVlan);
+DEFINE_CAST(VXLAN, VxLan);
+DEFINE_CAST(IPIP, Tunnel);
+DEFINE_CAST(GRE, Tunnel);
+DEFINE_CAST(SIT, Tunnel);
+DEFINE_CAST(VTI, Tunnel);
+DEFINE_CAST(VETH, Veth);
+DEFINE_CAST(DUMMY, Dummy);
+DEFINE_CAST(TUN, TunTap);
+DEFINE_CAST(TAP, TunTap);
+
int netdev_load(Manager *manager);
void netdev_drop(NetDev *netdev);
@@ -167,4 +202,4 @@ const struct ConfigPerfItem* network_netdev_gperf_lookup(const char *key, unsign
#define log_struct_netdev(level, netdev, ...) log_struct(level, "INTERFACE=%s", netdev->ifname, __VA_ARGS__)
-#define NETDEV(netdev) "INTERFACE=%s", netdev->ifname
+#define NETDEVIF(netdev) "INTERFACE=%s", netdev->ifname
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 3e46a1a80e..bc9304291e 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -66,11 +66,11 @@ static int network_load_one(Manager *manager, const char *filename) {
if (!network->vlans)
return log_oom();
- network->macvlans = hashmap_new(uint64_hash_func, uint64_compare_func);
+ network->macvlans = hashmap_new(string_hash_func, string_compare_func);
if (!network->macvlans)
return log_oom();
- network->vxlans = hashmap_new(uint64_hash_func, uint64_compare_func);
+ network->vxlans = hashmap_new(string_hash_func, string_compare_func);
if (!network->vxlans)
return log_oom();
@@ -323,10 +323,11 @@ int config_parse_netdev(const char *unit,
break;
case NETDEV_KIND_VLAN:
- r = hashmap_put(network->vlans, &netdev->vlanid, netdev);
+ r = hashmap_put(network->vlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Can not add VLAN to network: %s", rvalue);
+ "Can not add VLAN '%s' to network: %s",
+ rvalue, strerror(-r));
return 0;
}
@@ -335,7 +336,8 @@ int config_parse_netdev(const char *unit,
r = hashmap_put(network->macvlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Can not add MACVLAN to network: %s", rvalue);
+ "Can not add MACVLAN '%s' to network: %s",
+ rvalue, strerror(-r));
return 0;
}
@@ -344,7 +346,8 @@ int config_parse_netdev(const char *unit,
r = hashmap_put(network->vxlans, netdev->ifname, netdev);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
- "Can not add VXLAN to network: %s", rvalue);
+ "Can not add VXLAN '%s' to network: %s",
+ rvalue, strerror(-r));
return 0;
}