From: Yu Watanabe Date: Mon, 11 Mar 2019 07:11:47 +0000 (+0900) Subject: network: introduce new netdev create type NETDEV_CREATE_AFTER_CONFIGURED X-Git-Tag: v242-rc1~137^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7033af49df487900b5b8e223768de23c09024788;p=thirdparty%2Fsystemd.git network: introduce new netdev create type NETDEV_CREATE_AFTER_CONFIGURED It will be used to support L2TP tunnel in later commits. --- diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 33d646edd86..c14ee91fe3d 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 fb02ef67057..40f6b04f27f 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 42fcb500db8..752fcd56b1d 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),