start: unify and simplify network creation

Make sure that network creation happens at the same time for containers started by privileged and unprivileged users. The only reason we didn't do this so far was to avoid sending network device ifindices around in the privileged case. Link: https://github.com/lxc/lxc/issues/3066Signed-off-by: 's avatarChristian Brauner <christian.brauner@ubuntu.com>
parent c121b300
...@@ -3563,16 +3563,19 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3563,16 +3563,19 @@ int lxc_setup(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
return -1; return -1;
ret = lxc_setup_network_in_child_namespaces(lxc_conf, &lxc_conf->network); if (handler->ns_clone_flags & CLONE_NEWNET) {
if (ret < 0) { ret = lxc_setup_network_in_child_namespaces(lxc_conf,
ERROR("Failed to setup network"); &lxc_conf->network);
return -1; if (ret < 0) {
} ERROR("Failed to setup network");
return -1;
}
ret = lxc_network_send_name_and_ifindex_to_parent(handler); ret = lxc_network_send_name_and_ifindex_to_parent(handler);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to send network device names and ifindices to parent"); ERROR("Failed to send network device names and ifindices to parent");
return -1; return -1;
}
} }
if (lxc_conf->autodev > 0) { if (lxc_conf->autodev > 0) {
......
...@@ -147,7 +147,10 @@ union netdev_p { ...@@ -147,7 +147,10 @@ union netdev_p {
* @flags : flag of the network device (IFF_UP, ... ) * @flags : flag of the network device (IFF_UP, ... )
* @link : lxc.net.[i].link, name of bridge or host iface to attach * @link : lxc.net.[i].link, name of bridge or host iface to attach
* if any * if any
* @name : lxc.net.[i].name, name of iface on the container side * @name : lxc.net.[i].name, name of iface on the container side
* @created_name : the name with which this interface got created before
* being renamed to final_name.
* Currenly only used for veth devices.
* @hwaddr : mac address * @hwaddr : mac address
* @mtu : maximum transmission unit * @mtu : maximum transmission unit
* @priv : information specific to the specificed network type * @priv : information specific to the specificed network type
...@@ -176,6 +179,7 @@ struct lxc_netdev { ...@@ -176,6 +179,7 @@ struct lxc_netdev {
char link[IFNAMSIZ]; char link[IFNAMSIZ];
bool l2proxy; bool l2proxy;
char name[IFNAMSIZ]; char name[IFNAMSIZ];
char created_name[IFNAMSIZ];
char *hwaddr; char *hwaddr;
char *mtu; char *mtu;
union netdev_p priv; union netdev_p priv;
...@@ -267,15 +271,9 @@ extern char *lxc_mkifname(char *template); ...@@ -267,15 +271,9 @@ extern char *lxc_mkifname(char *template);
extern const char *lxc_net_type_to_str(int type); extern const char *lxc_net_type_to_str(int type);
extern int setup_private_host_hw_addr(char *veth1); extern int setup_private_host_hw_addr(char *veth1);
extern int netdev_get_mtu(int ifindex); extern int netdev_get_mtu(int ifindex);
extern int lxc_create_network_priv(struct lxc_handler *handler); extern int lxc_network_move_created_netdev_priv(struct lxc_handler *handler);
extern int lxc_network_move_created_netdev_priv(const char *lxcpath,
const char *lxcname,
struct lxc_list *network,
pid_t pid);
extern void lxc_delete_network(struct lxc_handler *handler); extern void lxc_delete_network(struct lxc_handler *handler);
extern int lxc_find_gateway_addresses(struct lxc_handler *handler); extern int lxc_find_gateway_addresses(struct lxc_handler *handler);
extern int lxc_create_network_unpriv(const char *lxcpath, const char *lxcname,
struct lxc_list *network, pid_t pid, unsigned int hook_version);
extern int lxc_requests_empty_network(struct lxc_handler *handler); extern int lxc_requests_empty_network(struct lxc_handler *handler);
extern int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler); extern int lxc_restore_phys_nics_to_netns(struct lxc_handler *handler);
extern int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf, extern int lxc_setup_network_in_child_namespaces(const struct lxc_conf *conf,
...@@ -286,5 +284,6 @@ extern int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handl ...@@ -286,5 +284,6 @@ extern int lxc_network_send_name_and_ifindex_to_parent(struct lxc_handler *handl
extern int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler); extern int lxc_network_recv_name_and_ifindex_from_child(struct lxc_handler *handler);
extern int lxc_netns_set_nsid(int netns_fd); extern int lxc_netns_set_nsid(int netns_fd);
extern int lxc_netns_get_nsid(__s32 fd); extern int lxc_netns_get_nsid(__s32 fd);
extern int lxc_create_network(struct lxc_handler *handler);
#endif /* __LXC_NETWORK_H */ #endif /* __LXC_NETWORK_H */
...@@ -1194,10 +1194,12 @@ static int do_start(void *data) ...@@ -1194,10 +1194,12 @@ static int do_start(void *data)
if (ret < 0) if (ret < 0)
goto out_error; goto out_error;
ret = lxc_network_recv_veth_names_from_parent(handler); if (handler->ns_clone_flags & CLONE_NEWNET) {
if (ret < 0) { ret = lxc_network_recv_veth_names_from_parent(handler);
ERROR("Failed to receive veth names from parent"); if (ret < 0) {
goto out_warn_father; ERROR("Failed to receive veth names from parent");
goto out_warn_father;
}
} }
/* If we are in a new user namespace, become root there to have /* If we are in a new user namespace, become root there to have
...@@ -1694,31 +1696,6 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1694,31 +1696,6 @@ static int lxc_spawn(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
goto out_sync_fini; goto out_sync_fini;
if (handler->ns_clone_flags & CLONE_NEWNET) {
if (!lxc_list_empty(&conf->network)) {
/* Find gateway addresses from the link device, which is
* no longer accessible inside the container. Do this
* before creating network interfaces, since goto
* out_delete_net does not work before lxc_clone.
*/
ret = lxc_find_gateway_addresses(handler);
if (ret < 0) {
ERROR("Failed to find gateway addresses");
goto out_sync_fini;
}
/* That should be done before the clone because we will
* fill the netdev index and use them in the child.
*/
ret = lxc_create_network_priv(handler);
if (ret < 0) {
ERROR("Failed to create the network");
goto out_delete_net;
}
}
}
if (!cgroup_ops->payload_create(cgroup_ops, handler)) { if (!cgroup_ops->payload_create(cgroup_ops, handler)) {
ERROR("Failed creating cgroups"); ERROR("Failed creating cgroups");
goto out_delete_net; goto out_delete_net;
...@@ -1847,29 +1824,19 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1847,29 +1824,19 @@ static int lxc_spawn(struct lxc_handler *handler)
/* Create the network configuration. */ /* Create the network configuration. */
if (handler->ns_clone_flags & CLONE_NEWNET) { if (handler->ns_clone_flags & CLONE_NEWNET) {
ret = lxc_network_move_created_netdev_priv(handler->lxcpath, ret = lxc_create_network(handler);
handler->name,
&conf->network,
handler->pid);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create the configured network"); ERROR("Failed to create the network");
goto out_delete_net; goto out_delete_net;
} }
ret = lxc_create_network_unpriv(handler->lxcpath, handler->name, ret = lxc_network_send_veth_names_to_child(handler);
&conf->network, handler->pid, conf->hooks_version);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to create the configured network"); ERROR("Failed to send veth names to child");
goto out_delete_net; goto out_delete_net;
} }
} }
ret = lxc_network_send_veth_names_to_child(handler);
if (ret < 0) {
ERROR("Failed to send veth names to child");
goto out_delete_net;
}
if (!lxc_list_empty(&conf->procs)) { if (!lxc_list_empty(&conf->procs)) {
ret = setup_proc_filesystem(&conf->procs, handler->pid); ret = setup_proc_filesystem(&conf->procs, handler->pid);
if (ret < 0) if (ret < 0)
...@@ -1940,11 +1907,12 @@ static int lxc_spawn(struct lxc_handler *handler) ...@@ -1940,11 +1907,12 @@ static int lxc_spawn(struct lxc_handler *handler)
if (ret < 0) if (ret < 0)
goto out_delete_net; goto out_delete_net;
ret = lxc_network_recv_name_and_ifindex_from_child(handler); if (handler->ns_clone_flags & CLONE_NEWNET) {
if (ret < 0) { ret = lxc_network_recv_name_and_ifindex_from_child(handler);
ERROR("Failed to receive names and ifindices for network " if (ret < 0) {
"devices from child"); ERROR("Failed to receive names and ifindices for network devices from child");
goto out_delete_net; goto out_delete_net;
}
} }
/* Now all networks are created, network devices are moved into place, /* Now all networks are created, network devices are moved into place,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment