Unverified Commit 36be8e6c by Stéphane Graber Committed by GitHub

Merge pull request #2640 from brauner/2018-09-23/netns_getifaddrs

network: add netns_getifaddrs() implementation
parents 7e270c97 61204b93
#ifndef _IFADDRS_H
#define _IFADDRS_H
#ifndef _LXC_NETNS_IFADDRS_H
#define _LXC_NETNS_IFADDRS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <features.h>
#include <linux/types.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <sys/socket.h>
struct ifaddrs {
struct ifaddrs *ifa_next;
struct netns_ifaddrs {
struct netns_ifaddrs *ifa_next;
/* Can - but shouldn't be - NULL. */
char *ifa_name;
/* This field is not present struct ifaddrs. */
int ifa_ifindex;
unsigned ifa_flags;
/* This field is not present struct ifaddrs. */
int ifa_mtu;
/* This field is not present struct ifaddrs. */
int ifa_prefixlen;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
union {
struct sockaddr *ifu_broadaddr;
struct sockaddr *ifu_dstaddr;
} ifa_ifu;
/* If you don't know what this is for don't touch it. */
void *ifa_data;
};
#define ifa_broadaddr ifa_ifu.ifu_broadaddr
#define ifa_dstaddr ifa_ifu.ifu_dstaddr
void freeifaddrs(struct ifaddrs *);
int getifaddrs(struct ifaddrs **);
#define __ifa_broadaddr ifa_ifu.ifu_broadaddr
#define __ifa_dstaddr ifa_ifu.ifu_dstaddr
extern void netns_freeifaddrs(struct netns_ifaddrs *);
extern int netns_getifaddrs(struct netns_ifaddrs **ifap, __s32 netns_id,
bool *netnsid_aware);
#ifdef __cplusplus
}
#endif
#endif
#endif /* _LXC_NETNS_IFADDRS_H */
......@@ -14,6 +14,7 @@ noinst_HEADERS = api_extensions.h \
criu.h \
error.h \
file_utils.h \
../include/netns_ifaddrs.h \
initutils.h \
list.h \
log.h \
......@@ -41,10 +42,6 @@ noinst_HEADERS = api_extensions.h \
tools/arguments.h \
utils.h
if !HAVE_IFADDRS_H
noinst_HEADERS += ../include/ifaddrs.h
endif
if IS_BIONIC
noinst_HEADERS += ../include/lxcmntent.h \
../include/openpty.h
......@@ -103,6 +100,7 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
execute.c \
freezer.c \
file_utils.c file_utils.h \
../include/netns_ifaddrs.c ../include/netns_ifaddrs.h \
initutils.c initutils.h \
list.h \
log.c log.h \
......@@ -139,10 +137,6 @@ liblxc_la_SOURCES = af_unix.c af_unix.h \
version.h \
$(LSM_SOURCES)
if !HAVE_IFADDRS_H
liblxc_la_SOURCES += ../include/ifaddrs.c ../include/ifaddrs.h
endif
if IS_BIONIC
liblxc_la_SOURCES += ../include/lxcmntent.c ../include/lxcmntent.h \
../include/openpty.c ../include/openpty.h
......@@ -347,6 +341,7 @@ init_lxc_SOURCES = cmd/lxc_init.c \
string_utils.c string_utils.h
lxc_monitord_SOURCES = cmd/lxc_monitord.c
lxc_user_nic_SOURCES = cmd/lxc_user_nic.c \
../include/netns_ifaddrs.c ../include/netns_ifaddrs.h \
log.c log.h \
namespace.c namespace.h \
network.c network.h \
......
......@@ -48,6 +48,7 @@
#include "config.h"
#include "confile.h"
#include "confile_utils.h"
#include <../include/netns_ifaddrs.h>
#include "log.h"
#include "lxcseccomp.h"
#include "network.h"
......@@ -55,12 +56,6 @@
#include "storage.h"
#include "utils.h"
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include <../include/ifaddrs.h>
#endif
#if HAVE_SYS_PERSONALITY_H
#include <sys/personality.h>
#endif
......@@ -324,14 +319,14 @@ static int set_config_net_flags(const char *key, const char *value,
static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf,
struct lxc_netdev *netdev)
{
struct ifaddrs *ifaddr, *ifa;
struct netns_ifaddrs *ifaddr, *ifa;
int n;
int ret = 0;
const char *type_key = "lxc.net.type";
const char *link_key = "lxc.net.link";
const char *tmpvalue = "phys";
if (getifaddrs(&ifaddr) == -1) {
if (netns_getifaddrs(&ifaddr, -1, &(bool){false}) < 0) {
SYSERROR("Get network interfaces failed");
return -1;
}
......@@ -359,7 +354,7 @@ static int create_matched_ifnames(const char *value, struct lxc_conf *lxc_conf,
}
}
freeifaddrs(ifaddr);
netns_freeifaddrs(ifaddr);
ifaddr = NULL;
return ret;
......
......@@ -53,6 +53,7 @@
#include "confile_utils.h"
#include "criu.h"
#include "error.h"
#include <../include/netns_ifaddrs.h>
#include "initutils.h"
#include "log.h"
#include "lxc.h"
......@@ -78,12 +79,6 @@
#include <sys/mkdev.h>
#endif
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include <../include/ifaddrs.h>
#endif
#if IS_BIONIC
#include <../include/lxcmntent.h>
#else
......@@ -2327,7 +2322,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c)
if (pid == 0) { /* child */
int ret = 1, nbytes;
struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
struct netns_ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
/* close the read-end of the pipe */
close(pipefd[0]);
......@@ -2338,7 +2333,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c)
}
/* Grab the list of interfaces */
if (getifaddrs(&interfaceArray)) {
if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) {
SYSERROR("Failed to get interfaces list");
goto out;
}
......@@ -2357,7 +2352,7 @@ static char **do_lxcapi_get_interfaces(struct lxc_container *c)
out:
if (interfaceArray)
freeifaddrs(interfaceArray);
netns_freeifaddrs(interfaceArray);
/* close the write-end of the pipe, thus sending EOF to the reader */
close(pipefd[1]);
......@@ -2429,7 +2424,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
int ret = 1;
char *address = NULL;
void *tempAddrPtr = NULL;
struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
struct netns_ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
/* close the read-end of the pipe */
close(pipefd[0]);
......@@ -2440,7 +2435,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
}
/* Grab the list of interfaces */
if (getifaddrs(&interfaceArray)) {
if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) {
SYSERROR("Failed to get interfaces list");
goto out;
}
......@@ -2496,7 +2491,7 @@ static char **do_lxcapi_get_ips(struct lxc_container *c, const char *interface,
out:
if (interfaceArray)
freeifaddrs(interfaceArray);
netns_freeifaddrs(interfaceArray);
/* close the write-end of the pipe, thus sending EOF to the reader */
close(pipefd[1]);
......
......@@ -272,10 +272,20 @@ extern int __build_bug_on_failed;
#define IFLA_NEW_NETNSID 45
#endif
#ifndef IFLA_IF_NETNSID
#ifdef IFLA_IF_NETNSID
#ifndef IFLA_TARGET_NETNSID
#define IFLA_TARGET_NETNSID = IFLA_IF_NETNSID
#endif
#else
#define IFLA_IF_NETNSID 46
#define IFLA_TARGET_NETNSID 46
#endif
#ifndef IFA_TARGET_NETNSID
#define IFA_TARGET_NETNSID 10
#endif
#ifndef RTM_NEWNSID
#define RTM_NEWNSID 88
#endif
......@@ -304,6 +314,16 @@ extern int __build_bug_on_failed;
#define MACVLAN_MODE_PASSTHRU 8
#endif
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
enum {
__LXC_NETNSA_NONE,
#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1
__LXC_NETNSA_NSID,
__LXC_NETNSA_PID,
__LXC_NETNSA_FD,
__LXC_NETNSA_MAX,
};
/* Length of abstract unix domain socket socket address. */
#define LXC_AUDS_ADDR_LEN sizeof(((struct sockaddr_un *)0)->sun_path)
......
......@@ -48,6 +48,7 @@
#include "af_unix.h"
#include "conf.h"
#include "config.h"
#include <../include/netns_ifaddrs.h>
#include "file_utils.h"
#include "log.h"
#include "macro.h"
......@@ -55,12 +56,6 @@
#include "nl.h"
#include "utils.h"
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include <../include/ifaddrs.h>
#endif
#ifndef HAVE_STRLCPY
#include "include/strlcpy.h"
#endif
......@@ -1950,7 +1945,7 @@ static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *lxc_mkifname(char *template)
{
int ret;
struct ifaddrs *ifa, *ifaddr;
struct netns_ifaddrs *ifa, *ifaddr;
char name[IFNAMSIZ];
bool exists = false;
size_t i = 0;
......@@ -1967,7 +1962,7 @@ char *lxc_mkifname(char *template)
return NULL;
/* Get all the network interfaces. */
ret = getifaddrs(&ifaddr);
ret = netns_getifaddrs(&ifaddr, -1, &(bool){false});
if (ret < 0) {
SYSERROR("Failed to get network interfaces");
return NULL;
......@@ -2001,7 +1996,7 @@ char *lxc_mkifname(char *template)
break;
}
freeifaddrs(ifaddr);
netns_freeifaddrs(ifaddr);
(void)strlcpy(template, name, strlen(template) + 1);
return template;
......@@ -3181,35 +3176,6 @@ void lxc_delete_network(struct lxc_handler *handler)
DEBUG("Deleted network devices");
}
int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data, size_t alen)
{
int len = RTA_LENGTH(alen);
struct rtattr *rta;
errno = EMSGSIZE;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
return -1;
rta = NLMSG_TAIL(n);
rta->rta_type = type;
rta->rta_len = len;
if (alen)
memcpy(RTA_DATA(rta), data, alen);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
return 0;
}
/* Attributes of RTM_NEWNSID/RTM_GETNSID messages */
enum {
__LXC_NETNSA_NONE,
#define __LXC_NETNSA_NSID_NOT_ASSIGNED -1
__LXC_NETNSA_NSID,
__LXC_NETNSA_PID,
__LXC_NETNSA_FD,
__LXC_NETNSA_MAX,
};
int lxc_netns_set_nsid(int fd)
{
int ret;
......
......@@ -345,3 +345,22 @@ extern int netlink_close(struct nl_handler *handler)
return 0;
}
int addattr(struct nlmsghdr *n, size_t maxlen, int type, const void *data,
size_t alen)
{
int len = RTA_LENGTH(alen);
struct rtattr *rta;
errno = EMSGSIZE;
if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen)
return -1;
rta = NLMSG_TAIL(n);
rta->rta_type = type;
rta->rta_len = len;
if (alen)
memcpy(RTA_DATA(rta), data, alen);
n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
return 0;
}
......@@ -23,6 +23,8 @@
#ifndef __LXC_NL_H
#define __LXC_NL_H
#include <stdio.h>
/*
* Use this as a good size to allocate generic netlink messages
*/
......@@ -259,5 +261,7 @@ void nlmsg_free(struct nlmsg *nlmsg);
*/
void *nlmsg_data(struct nlmsg *nlmsg);
extern int addattr(struct nlmsghdr *n, size_t maxlen, int type,
const void *data, size_t alen);
#endif
......@@ -30,15 +30,10 @@
#include <lxc/lxccontainer.h>
#include "arguments.h"
#include "../../include/netns_ifaddrs.h"
#include "log.h"
#include "utils.h"
#if HAVE_IFADDRS_H
#include <ifaddrs.h>
#else
#include "../include/ifaddrs.h"
#endif
lxc_log_define(lxc_device, lxc);
static bool is_interface(const char *dev_name, pid_t pid);
......@@ -73,7 +68,7 @@ static bool is_interface(const char *dev_name, pid_t pid)
}
if (p == 0) {
struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
struct netns_ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
if (!switch_to_ns(pid, "net")) {
ERROR("Failed to enter netns of container");
......@@ -81,7 +76,7 @@ static bool is_interface(const char *dev_name, pid_t pid)
}
/* Grab the list of interfaces */
if (getifaddrs(&interfaceArray)) {
if (netns_getifaddrs(&interfaceArray, -1, &(bool){false})) {
ERROR("Failed to get interfaces list");
_exit(-1);
}
......
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