summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2019-03-11 16:11:47 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-03-14 10:57:41 +0900
commit7033af49df487900b5b8e223768de23c09024788 (patch)
treee091a023d9e6e7e337adb88a92f6491720ab3599
parent859e9c048707d19fae08a2c6865676b945741e68 (diff)
downloadsystemd-7033af49df487900b5b8e223768de23c09024788.tar.gz
network: introduce new netdev create type NETDEV_CREATE_AFTER_CONFIGURED
It will be used to support L2TP tunnel in later commits.
-rw-r--r--src/network/netdev/netdev.c13
-rw-r--r--src/network/netdev/netdev.h5
-rw-r--r--src/network/networkd-link.c34
3 files changed, 52 insertions, 0 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c
index 33d646edd8..c14ee91fe3 100644
--- a/src/network/netdev/netdev.c
+++ b/src/network/netdev/netdev.c
@@ -598,6 +598,14 @@ static int netdev_create(NetDev *netdev, Link *link, link_netlink_message_handle
return 0;
}
+static int netdev_create_after_configured(NetDev *netdev, Link *link) {
+ assert(netdev);
+ assert(link);
+ assert(NETDEV_VTABLE(netdev)->create_after_configured);
+
+ return NETDEV_VTABLE(netdev)->create_after_configured(netdev, link);
+}
+
/* the callback must be called, possibly after a timeout, as otherwise the Link will hang */
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t callback) {
int r;
@@ -619,6 +627,11 @@ int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t callb
return r;
break;
+ case NETDEV_CREATE_AFTER_CONFIGURED:
+ r = netdev_create_after_configured(netdev, link);
+ if (r < 0)
+ return r;
+ break;
default:
assert_not_reached("Can not join independent netdev");
}
diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h
index fb02ef6705..40f6b04f27 100644
--- a/src/network/netdev/netdev.h
+++ b/src/network/netdev/netdev.h
@@ -65,6 +65,7 @@ typedef enum NetDevCreateType {
NETDEV_CREATE_INDEPENDENT,
NETDEV_CREATE_MASTER,
NETDEV_CREATE_STACKED,
+ NETDEV_CREATE_AFTER_CONFIGURED,
_NETDEV_CREATE_MAX,
_NETDEV_CREATE_INVALID = -1,
} NetDevCreateType;
@@ -123,6 +124,9 @@ typedef struct NetDevVTable {
/* create netdev, if not done via rtnl */
int (*create)(NetDev *netdev);
+ /* create netdev after link is fully configured */
+ int (*create_after_configured)(NetDev *netdev, Link *link);
+
/* perform additional configuration after netdev has been createad */
int (*post_create)(NetDev *netdev, Link *link, sd_netlink_message *message);
@@ -162,6 +166,7 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret);
int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
int netdev_get_mac(const char *ifname, struct ether_addr **ret);
int netdev_join(NetDev *netdev, Link *link, link_netlink_message_handler_t cb);
+int netdev_join_after_configured(NetDev *netdev, Link *link, link_netlink_message_handler_t callback);
const char *netdev_kind_to_string(NetDevKind d) _const_;
NetDevKind netdev_kind_from_string(const char *d) _pure_;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 42fcb500db..752fcd56b1 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -822,6 +822,35 @@ static Address* link_find_dhcp_server_address(Link *link) {
return NULL;
}
+static int link_join_netdevs_after_configured(Link *link) {
+ NetDev *netdev;
+ Iterator i;
+ int r;
+
+ HASHMAP_FOREACH(netdev, link->network->stacked_netdevs, i) {
+ if (netdev->ifindex > 0)
+ /* Assume already enslaved. */
+ continue;
+
+ if (netdev_get_create_type(netdev) != NETDEV_CREATE_AFTER_CONFIGURED)
+ continue;
+
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(netdev),
+ LOG_LINK_MESSAGE(link, "Enslaving by '%s'", netdev->ifname));
+
+ r = netdev_join(netdev, link, NULL);
+ if (r < 0)
+ return log_struct_errno(LOG_WARNING, r,
+ LOG_LINK_INTERFACE(link),
+ LOG_NETDEV_INTERFACE(netdev),
+ LOG_LINK_MESSAGE(link, "Could not join netdev '%s': %m", netdev->ifname));
+ }
+
+ return 0;
+}
+
static void link_enter_configured(Link *link) {
assert(link);
assert(link->network);
@@ -833,6 +862,8 @@ static void link_enter_configured(Link *link) {
link_set_state(link, LINK_STATE_CONFIGURED);
+ (void) link_join_netdevs_after_configured(link);
+
link_dirty(link);
}
@@ -2685,6 +2716,9 @@ static int link_enter_join_netdev(Link *link) {
/* Assume already enslaved. */
continue;
+ if (netdev_get_create_type(netdev) != NETDEV_CREATE_STACKED)
+ continue;
+
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
LOG_NETDEV_INTERFACE(netdev),