netlink: Explicitly pass netlink sockets to operations
All the netlink operations currently implicitly use one of the two global netlink sockets, sometimes depending on an 'ns' parameter. Change them all to explicitly take the socket to use (or two sockets to use in the case of the *_dup() functions). As well as making these functions strictly more general, it makes the callers easier to follow because we're passing a socket variable with a name rather than an unexplained '0' or '1' for the ns parameter. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [sbrivio: Minor formatting changes in pasta_ns_conf()] Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
cfe7509e5c
commit
576df71e8b
4 changed files with 105 additions and 76 deletions
15
conf.c
15
conf.c
|
@ -641,7 +641,7 @@ static unsigned int conf_ip4(unsigned int ifi,
|
||||||
struct ip4_ctx *ip4, unsigned char *mac)
|
struct ip4_ctx *ip4, unsigned char *mac)
|
||||||
{
|
{
|
||||||
if (!ifi)
|
if (!ifi)
|
||||||
ifi = nl_get_ext_if(AF_INET);
|
ifi = nl_get_ext_if(nl_sock, AF_INET);
|
||||||
|
|
||||||
if (!ifi) {
|
if (!ifi) {
|
||||||
warn("No external routable interface for IPv4");
|
warn("No external routable interface for IPv4");
|
||||||
|
@ -649,10 +649,11 @@ static unsigned int conf_ip4(unsigned int ifi,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw))
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->gw))
|
||||||
nl_route_get_def(ifi, AF_INET, &ip4->gw);
|
nl_route_get_def(nl_sock, ifi, AF_INET, &ip4->gw);
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr))
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr))
|
||||||
nl_addr_get(ifi, AF_INET, &ip4->addr, &ip4->prefix_len, NULL);
|
nl_addr_get(nl_sock, ifi, AF_INET,
|
||||||
|
&ip4->addr, &ip4->prefix_len, NULL);
|
||||||
|
|
||||||
if (!ip4->prefix_len) {
|
if (!ip4->prefix_len) {
|
||||||
in_addr_t addr = ntohl(ip4->addr.s_addr);
|
in_addr_t addr = ntohl(ip4->addr.s_addr);
|
||||||
|
@ -669,7 +670,7 @@ static unsigned int conf_ip4(unsigned int ifi,
|
||||||
memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen));
|
memcpy(&ip4->addr_seen, &ip4->addr, sizeof(ip4->addr_seen));
|
||||||
|
|
||||||
if (MAC_IS_ZERO(mac))
|
if (MAC_IS_ZERO(mac))
|
||||||
nl_link_get_mac(0, ifi, mac);
|
nl_link_get_mac(nl_sock, ifi, mac);
|
||||||
|
|
||||||
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) ||
|
if (IN4_IS_ADDR_UNSPECIFIED(&ip4->addr) ||
|
||||||
MAC_IS_ZERO(mac))
|
MAC_IS_ZERO(mac))
|
||||||
|
@ -692,7 +693,7 @@ static unsigned int conf_ip6(unsigned int ifi,
|
||||||
int prefix_len = 0;
|
int prefix_len = 0;
|
||||||
|
|
||||||
if (!ifi)
|
if (!ifi)
|
||||||
ifi = nl_get_ext_if(AF_INET6);
|
ifi = nl_get_ext_if(nl_sock, AF_INET6);
|
||||||
|
|
||||||
if (!ifi) {
|
if (!ifi) {
|
||||||
warn("No external routable interface for IPv6");
|
warn("No external routable interface for IPv6");
|
||||||
|
@ -700,9 +701,9 @@ static unsigned int conf_ip6(unsigned int ifi,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw))
|
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->gw))
|
||||||
nl_route_get_def(ifi, AF_INET6, &ip6->gw);
|
nl_route_get_def(nl_sock, ifi, AF_INET6, &ip6->gw);
|
||||||
|
|
||||||
nl_addr_get(ifi, AF_INET6,
|
nl_addr_get(nl_sock, ifi, AF_INET6,
|
||||||
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL,
|
IN6_IS_ADDR_UNSPECIFIED(&ip6->addr) ? &ip6->addr : NULL,
|
||||||
&prefix_len, &ip6->addr_ll);
|
&prefix_len, &ip6->addr_ll);
|
||||||
|
|
||||||
|
|
92
netlink.c
92
netlink.c
|
@ -38,8 +38,8 @@
|
||||||
#define NLBUFSIZ (8192 * sizeof(struct nlmsghdr)) /* See netlink(7) */
|
#define NLBUFSIZ (8192 * sizeof(struct nlmsghdr)) /* See netlink(7) */
|
||||||
|
|
||||||
/* Socket in init, in target namespace, sequence (just needs to be monotonic) */
|
/* Socket in init, in target namespace, sequence (just needs to be monotonic) */
|
||||||
static int nl_sock = -1;
|
int nl_sock = -1;
|
||||||
static int nl_sock_ns = -1;
|
int nl_sock_ns = -1;
|
||||||
static int nl_seq;
|
static int nl_seq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,17 +98,17 @@ fail:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_req() - Send netlink request and read response
|
* nl_req() - Send netlink request and read response
|
||||||
* @ns: Use netlink socket in namespace
|
* @s: Netlink socket
|
||||||
* @buf: Buffer for response (at least NLBUFSIZ long)
|
* @buf: Buffer for response (at least NLBUFSIZ long)
|
||||||
* @req: Request with netlink header
|
* @req: Request with netlink header
|
||||||
* @len: Request length
|
* @len: Request length
|
||||||
*
|
*
|
||||||
* Return: received length on success, negative error code on failure
|
* Return: received length on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
static int nl_req(int ns, char *buf, const void *req, ssize_t len)
|
static int nl_req(int s, char *buf, const void *req, ssize_t len)
|
||||||
{
|
{
|
||||||
int s = ns ? nl_sock_ns : nl_sock, done = 0;
|
|
||||||
char flush[NLBUFSIZ];
|
char flush[NLBUFSIZ];
|
||||||
|
int done = 0;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
while (!done && (n = recv(s, flush, sizeof(flush), MSG_DONTWAIT)) > 0) {
|
while (!done && (n = recv(s, flush, sizeof(flush), MSG_DONTWAIT)) > 0) {
|
||||||
|
@ -133,12 +133,13 @@ static int nl_req(int ns, char *buf, const void *req, ssize_t len)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_get_ext_if() - Get interface index supporting IP version being probed
|
* nl_get_ext_if() - Get interface index supporting IP version being probed
|
||||||
|
* @s: Netlink socket
|
||||||
* @af: Address family (AF_INET or AF_INET6) to look for connectivity
|
* @af: Address family (AF_INET or AF_INET6) to look for connectivity
|
||||||
* for.
|
* for.
|
||||||
*
|
*
|
||||||
* Return: interface index, 0 if not found
|
* Return: interface index, 0 if not found
|
||||||
*/
|
*/
|
||||||
unsigned int nl_get_ext_if(sa_family_t af)
|
unsigned int nl_get_ext_if(int s, sa_family_t af)
|
||||||
{
|
{
|
||||||
struct { struct nlmsghdr nlh; struct rtmsg rtm; } req = {
|
struct { struct nlmsghdr nlh; struct rtmsg rtm; } req = {
|
||||||
.nlh.nlmsg_type = RTM_GETROUTE,
|
.nlh.nlmsg_type = RTM_GETROUTE,
|
||||||
|
@ -157,7 +158,7 @@ unsigned int nl_get_ext_if(sa_family_t af)
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
size_t na;
|
size_t na;
|
||||||
|
|
||||||
if ((n = nl_req(0, buf, &req, sizeof(req))) < 0)
|
if ((n = nl_req(s, buf, &req, sizeof(req))) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
nh = (struct nlmsghdr *)buf;
|
nh = (struct nlmsghdr *)buf;
|
||||||
|
@ -186,11 +187,12 @@ unsigned int nl_get_ext_if(sa_family_t af)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_route_get_def() - Get default route for given interface and address family
|
* nl_route_get_def() - Get default route for given interface and address family
|
||||||
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
* @gw: Default gateway to fill on NL_GET
|
* @gw: Default gateway to fill on NL_GET
|
||||||
*/
|
*/
|
||||||
void nl_route_get_def(unsigned int ifi, sa_family_t af, void *gw)
|
void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -216,7 +218,7 @@ void nl_route_get_def(unsigned int ifi, sa_family_t af, void *gw)
|
||||||
char buf[NLBUFSIZ];
|
char buf[NLBUFSIZ];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
if ((n = nl_req(0, buf, &req, req.nlh.nlmsg_len)) < 0)
|
if ((n = nl_req(s, buf, &req, req.nlh.nlmsg_len)) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (nh = (struct nlmsghdr *)buf;
|
for (nh = (struct nlmsghdr *)buf;
|
||||||
|
@ -245,11 +247,12 @@ void nl_route_get_def(unsigned int ifi, sa_family_t af, void *gw)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_route_set_def() - Set default route for given interface and address family
|
* nl_route_set_def() - Set default route for given interface and address family
|
||||||
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index in target namespace
|
* @ifi: Interface index in target namespace
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
* @gw: Default gateway to set
|
* @gw: Default gateway to set
|
||||||
*/
|
*/
|
||||||
void nl_route_set_def(unsigned int ifi, sa_family_t af, void *gw)
|
void nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -314,16 +317,19 @@ void nl_route_set_def(unsigned int ifi, sa_family_t af, void *gw)
|
||||||
req.set.r4.rta_gw.rta_len = rta_len;
|
req.set.r4.rta_gw.rta_len = rta_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
nl_req(1, buf, &req, req.nlh.nlmsg_len);
|
nl_req(s, buf, &req, req.nlh.nlmsg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_route_dup() - Copy routes for given interface and address family
|
* nl_route_dup() - Copy routes for given interface and address family
|
||||||
* @ifi: Interface index in outer network namespace
|
* @s_src: Netlink socket in source namespace
|
||||||
* @ifi_ns: Interface index in target namespace for NL_SET, NL_DUP
|
* @ifi_src: Source interface index
|
||||||
|
* @s_dst: Netlink socket in destination namespace
|
||||||
|
* @ifi_dst: Interface index in destination namespace
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
*/
|
*/
|
||||||
void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
void nl_route_dup(int s_src, unsigned int ifi_src,
|
||||||
|
int s_dst, unsigned int ifi_dst, sa_family_t af)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -343,7 +349,7 @@ void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
|
|
||||||
.rta.rta_type = RTA_OIF,
|
.rta.rta_type = RTA_OIF,
|
||||||
.rta.rta_len = RTA_LENGTH(sizeof(unsigned int)),
|
.rta.rta_len = RTA_LENGTH(sizeof(unsigned int)),
|
||||||
.ifi = ifi,
|
.ifi = ifi_src,
|
||||||
};
|
};
|
||||||
char buf[NLBUFSIZ], resp[NLBUFSIZ];
|
char buf[NLBUFSIZ], resp[NLBUFSIZ];
|
||||||
unsigned dup_routes = 0;
|
unsigned dup_routes = 0;
|
||||||
|
@ -351,7 +357,7 @@ void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
struct nlmsghdr *nh;
|
struct nlmsghdr *nh;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if ((n = nl_req(0, buf, &req, req.nlh.nlmsg_len)) < 0)
|
if ((n = nl_req(s_src, buf, &req, req.nlh.nlmsg_len)) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nlmsgs_size = n;
|
nlmsgs_size = n;
|
||||||
|
@ -376,7 +382,7 @@ void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
for (rta = RTM_RTA(rtm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
for (rta = RTM_RTA(rtm), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
||||||
rta = RTA_NEXT(rta, na)) {
|
rta = RTA_NEXT(rta, na)) {
|
||||||
if (rta->rta_type == RTA_OIF)
|
if (rta->rta_type == RTA_OIF)
|
||||||
*(unsigned int *)RTA_DATA(rta) = ifi_ns;
|
*(unsigned int *)RTA_DATA(rta) = ifi_dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,19 +395,20 @@ void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
* avoids the need to calculate dependencies: let the kernel do that.
|
* avoids the need to calculate dependencies: let the kernel do that.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < dup_routes; i++)
|
for (i = 0; i < dup_routes; i++)
|
||||||
nl_req(1, resp, nh, nlmsgs_size);
|
nl_req(s_dst, resp, nh, nlmsgs_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_addr_get() - Get IP address for given interface and address family
|
* nl_addr_get() - Get IP address for given interface and address family
|
||||||
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index in outer network namespace
|
* @ifi: Interface index in outer network namespace
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
* @addr: Global address to fill
|
* @addr: Global address to fill
|
||||||
* @prefix_len: Mask or prefix length, to fill (for IPv4)
|
* @prefix_len: Mask or prefix length, to fill (for IPv4)
|
||||||
* @addr_l: Link-scoped address to fill (for IPv6)
|
* @addr_l: Link-scoped address to fill (for IPv6)
|
||||||
*/
|
*/
|
||||||
void nl_addr_get(unsigned int ifi, sa_family_t af, void *addr,
|
void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
||||||
int *prefix_len, void *addr_l)
|
void *addr, int *prefix_len, void *addr_l)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -419,7 +426,7 @@ void nl_addr_get(unsigned int ifi, sa_family_t af, void *addr,
|
||||||
char buf[NLBUFSIZ];
|
char buf[NLBUFSIZ];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
if ((n = nl_req(0, buf, &req, req.nlh.nlmsg_len)) < 0)
|
if ((n = nl_req(s, buf, &req, req.nlh.nlmsg_len)) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (nh = (struct nlmsghdr *)buf;
|
for (nh = (struct nlmsghdr *)buf;
|
||||||
|
@ -457,12 +464,14 @@ void nl_addr_get(unsigned int ifi, sa_family_t af, void *addr,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_add_set() - Set IP addresses for given interface and address family
|
* nl_add_set() - Set IP addresses for given interface and address family
|
||||||
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
* @addr: Global address to set
|
* @addr: Global address to set
|
||||||
* @prefix_len: Mask or prefix length to set
|
* @prefix_len: Mask or prefix length to set
|
||||||
*/
|
*/
|
||||||
void nl_addr_set(unsigned int ifi, sa_family_t af, void *addr, int prefix_len)
|
void nl_addr_set(int s, unsigned int ifi, sa_family_t af,
|
||||||
|
void *addr, int prefix_len)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -523,16 +532,19 @@ void nl_addr_set(unsigned int ifi, sa_family_t af, void *addr, int prefix_len)
|
||||||
req.set.a4.rta_a.rta_type = IFA_ADDRESS;
|
req.set.a4.rta_a.rta_type = IFA_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
nl_req(1, buf, &req, req.nlh.nlmsg_len);
|
nl_req(s, buf, &req, req.nlh.nlmsg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_addr_dup() - Copy IP addresses for given interface and address family
|
* nl_addr_dup() - Copy IP addresses for given interface and address family
|
||||||
* @ifi: Interface index in outer network namespace
|
* @s_src: Netlink socket in source network namespace
|
||||||
* @ifi_ns: Interface index in target namespace
|
* @ifi_src: Interface index in source network namespace
|
||||||
|
* @s_dst: Netlink socket in destination network namespace
|
||||||
|
* @ifi_dst: Interface index in destination namespace
|
||||||
* @af: Address family
|
* @af: Address family
|
||||||
*/
|
*/
|
||||||
void nl_addr_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
void nl_addr_dup(int s_src, unsigned int ifi_src,
|
||||||
|
int s_dst, unsigned int ifi_dst, sa_family_t af)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -544,14 +556,14 @@ void nl_addr_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
.nlh.nlmsg_seq = nl_seq++,
|
.nlh.nlmsg_seq = nl_seq++,
|
||||||
|
|
||||||
.ifa.ifa_family = af,
|
.ifa.ifa_family = af,
|
||||||
.ifa.ifa_index = ifi,
|
.ifa.ifa_index = ifi_src,
|
||||||
.ifa.ifa_prefixlen = 0,
|
.ifa.ifa_prefixlen = 0,
|
||||||
};
|
};
|
||||||
char buf[NLBUFSIZ], resp[NLBUFSIZ];
|
char buf[NLBUFSIZ], resp[NLBUFSIZ];
|
||||||
ssize_t n, nlmsgs_size;
|
ssize_t n, nlmsgs_size;
|
||||||
struct nlmsghdr *nh;
|
struct nlmsghdr *nh;
|
||||||
|
|
||||||
if ((n = nl_req(0, buf, &req, sizeof(req))) < 0)
|
if ((n = nl_req(s_src, buf, &req, sizeof(req))) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nlmsgs_size = n;
|
nlmsgs_size = n;
|
||||||
|
@ -573,12 +585,13 @@ void nl_addr_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
|
|
||||||
ifa = (struct ifaddrmsg *)NLMSG_DATA(nh);
|
ifa = (struct ifaddrmsg *)NLMSG_DATA(nh);
|
||||||
|
|
||||||
if (ifa->ifa_scope == RT_SCOPE_LINK || ifa->ifa_index != ifi) {
|
if (ifa->ifa_scope == RT_SCOPE_LINK ||
|
||||||
|
ifa->ifa_index != ifi_src) {
|
||||||
ifa->ifa_family = AF_UNSPEC;
|
ifa->ifa_family = AF_UNSPEC;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifa->ifa_index = ifi_ns;
|
ifa->ifa_index = ifi_dst;
|
||||||
|
|
||||||
for (rta = IFA_RTA(ifa), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
for (rta = IFA_RTA(ifa), na = RTM_PAYLOAD(nh); RTA_OK(rta, na);
|
||||||
rta = RTA_NEXT(rta, na)) {
|
rta = RTA_NEXT(rta, na)) {
|
||||||
|
@ -587,16 +600,16 @@ void nl_addr_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nl_req(1, resp, buf, nlmsgs_size);
|
nl_req(s_dst, resp, buf, nlmsgs_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_link_get_mac() - Get link MAC address
|
* nl_link_get_mac() - Get link MAC address
|
||||||
* @ns: Use netlink socket in namespace
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @mac: Fill with current MAC address
|
* @mac: Fill with current MAC address
|
||||||
*/
|
*/
|
||||||
void nl_link_get_mac(int ns, unsigned int ifi, void *mac)
|
void nl_link_get_mac(int s, unsigned int ifi, void *mac)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -613,7 +626,7 @@ void nl_link_get_mac(int ns, unsigned int ifi, void *mac)
|
||||||
char buf[NLBUFSIZ];
|
char buf[NLBUFSIZ];
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
n = nl_req(ns, buf, &req, sizeof(req));
|
n = nl_req(s, buf, &req, sizeof(req));
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -641,11 +654,12 @@ void nl_link_get_mac(int ns, unsigned int ifi, void *mac)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_link_set_mac() - Set link MAC address
|
* nl_link_set_mac() - Set link MAC address
|
||||||
|
* @s: Netlink socket
|
||||||
* @ns: Use netlink socket in namespace
|
* @ns: Use netlink socket in namespace
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @mac: MAC address to set
|
* @mac: MAC address to set
|
||||||
*/
|
*/
|
||||||
void nl_link_set_mac(int ns, unsigned int ifi, void *mac)
|
void nl_link_set_mac(int s, unsigned int ifi, void *mac)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -666,16 +680,16 @@ void nl_link_set_mac(int ns, unsigned int ifi, void *mac)
|
||||||
|
|
||||||
memcpy(req.mac, mac, ETH_ALEN);
|
memcpy(req.mac, mac, ETH_ALEN);
|
||||||
|
|
||||||
nl_req(ns, buf, &req, sizeof(req));
|
nl_req(s, buf, &req, sizeof(req));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nl_link_up() - Bring link up
|
* nl_link_up() - Bring link up
|
||||||
* @ns: Use netlink socket in namespace
|
* @s: Netlink socket
|
||||||
* @ifi: Interface index
|
* @ifi: Interface index
|
||||||
* @mtu: If non-zero, set interface MTU
|
* @mtu: If non-zero, set interface MTU
|
||||||
*/
|
*/
|
||||||
void nl_link_up(int ns, unsigned int ifi, int mtu)
|
void nl_link_up(int s, unsigned int ifi, int mtu)
|
||||||
{
|
{
|
||||||
struct req_t {
|
struct req_t {
|
||||||
struct nlmsghdr nlh;
|
struct nlmsghdr nlh;
|
||||||
|
@ -701,5 +715,5 @@ void nl_link_up(int ns, unsigned int ifi, int mtu)
|
||||||
/* Shorten request to drop MTU attribute */
|
/* Shorten request to drop MTU attribute */
|
||||||
req.nlh.nlmsg_len = offsetof(struct req_t, rta);
|
req.nlh.nlmsg_len = offsetof(struct req_t, rta);
|
||||||
|
|
||||||
nl_req(ns, buf, &req, req.nlh.nlmsg_len);
|
nl_req(s, buf, &req, req.nlh.nlmsg_len);
|
||||||
}
|
}
|
||||||
|
|
28
netlink.h
28
netlink.h
|
@ -6,17 +6,23 @@
|
||||||
#ifndef NETLINK_H
|
#ifndef NETLINK_H
|
||||||
#define NETLINK_H
|
#define NETLINK_H
|
||||||
|
|
||||||
|
extern int nl_sock;
|
||||||
|
extern int nl_sock_ns;
|
||||||
|
|
||||||
void nl_sock_init(const struct ctx *c, bool ns);
|
void nl_sock_init(const struct ctx *c, bool ns);
|
||||||
unsigned int nl_get_ext_if(sa_family_t af);
|
unsigned int nl_get_ext_if(int s, sa_family_t af);
|
||||||
void nl_route_get_def(unsigned int ifi, sa_family_t af, void *gw);
|
void nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
||||||
void nl_route_set_def(unsigned int ifi, sa_family_t af, void *gw);
|
void nl_route_set_def(int s, unsigned int ifi, sa_family_t af, void *gw);
|
||||||
void nl_route_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af);
|
void nl_route_dup(int s_src, unsigned int ifi_src,
|
||||||
void nl_addr_get(unsigned int ifi, sa_family_t af, void *addr,
|
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
||||||
int *prefix_len, void *addr_l);
|
void nl_addr_get(int s, unsigned int ifi, sa_family_t af,
|
||||||
void nl_addr_set(unsigned int ifi, sa_family_t af, void *addr, int prefix_len);
|
void *addr, int *prefix_len, void *addr_l);
|
||||||
void nl_addr_dup(unsigned int ifi, unsigned int ifi_ns, sa_family_t af);
|
void nl_addr_set(int s, unsigned int ifi, sa_family_t af,
|
||||||
void nl_link_get_mac(int ns, unsigned int ifi, void *mac);
|
void *addr, int prefix_len);
|
||||||
void nl_link_set_mac(int ns, unsigned int ifi, void *mac);
|
void nl_addr_dup(int s_src, unsigned int ifi_src,
|
||||||
void nl_link_up(int ns, unsigned int ifi, int mtu);
|
int s_dst, unsigned int ifi_dst, sa_family_t af);
|
||||||
|
void nl_link_get_mac(int s, unsigned int ifi, void *mac);
|
||||||
|
void nl_link_set_mac(int s, unsigned int ifi, void *mac);
|
||||||
|
void nl_link_up(int s, unsigned int ifi, int mtu);
|
||||||
|
|
||||||
#endif /* NETLINK_H */
|
#endif /* NETLINK_H */
|
||||||
|
|
46
pasta.c
46
pasta.c
|
@ -272,45 +272,53 @@ void pasta_start_ns(struct ctx *c, uid_t uid, gid_t gid,
|
||||||
*/
|
*/
|
||||||
void pasta_ns_conf(struct ctx *c)
|
void pasta_ns_conf(struct ctx *c)
|
||||||
{
|
{
|
||||||
nl_link_up(1, 1 /* lo */, 0);
|
nl_link_up(nl_sock_ns, 1 /* lo */, 0);
|
||||||
|
|
||||||
/* Get or set MAC in target namespace */
|
/* Get or set MAC in target namespace */
|
||||||
if (MAC_IS_ZERO(c->mac_guest))
|
if (MAC_IS_ZERO(c->mac_guest))
|
||||||
nl_link_get_mac(1, c->pasta_ifi, c->mac_guest);
|
nl_link_get_mac(nl_sock_ns, c->pasta_ifi, c->mac_guest);
|
||||||
else
|
else
|
||||||
nl_link_set_mac(1, c->pasta_ifi, c->mac_guest);
|
nl_link_set_mac(nl_sock_ns, c->pasta_ifi, c->mac_guest);
|
||||||
|
|
||||||
if (c->pasta_conf_ns) {
|
if (c->pasta_conf_ns) {
|
||||||
nl_link_up(1, c->pasta_ifi, c->mtu);
|
nl_link_up(nl_sock_ns, c->pasta_ifi, c->mtu);
|
||||||
|
|
||||||
if (c->ifi4) {
|
if (c->ifi4) {
|
||||||
if (c->no_copy_addrs) {
|
if (c->no_copy_addrs) {
|
||||||
nl_addr_set(c->pasta_ifi, AF_INET,
|
nl_addr_set(nl_sock_ns, c->pasta_ifi, AF_INET,
|
||||||
&c->ip4.addr, c->ip4.prefix_len);
|
&c->ip4.addr, c->ip4.prefix_len);
|
||||||
} else {
|
} else {
|
||||||
nl_addr_dup(c->ifi4, c->pasta_ifi, AF_INET);
|
nl_addr_dup(nl_sock, c->ifi4,
|
||||||
|
nl_sock_ns, c->pasta_ifi, AF_INET);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->no_copy_routes)
|
if (c->no_copy_routes) {
|
||||||
nl_route_set_def(c->pasta_ifi, AF_INET,
|
nl_route_set_def(nl_sock_ns, c->pasta_ifi,
|
||||||
&c->ip4.gw);
|
AF_INET, &c->ip4.gw);
|
||||||
else
|
} else {
|
||||||
nl_route_dup(c->ifi4, c->pasta_ifi, AF_INET);
|
nl_route_dup(nl_sock, c->ifi4, nl_sock_ns,
|
||||||
|
c->pasta_ifi, AF_INET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->ifi6) {
|
if (c->ifi6) {
|
||||||
if (c->no_copy_addrs) {
|
if (c->no_copy_addrs) {
|
||||||
nl_addr_set(c->pasta_ifi, AF_INET6,
|
nl_addr_set(nl_sock_ns, c->pasta_ifi,
|
||||||
&c->ip6.addr, 64);
|
AF_INET6, &c->ip6.addr, 64);
|
||||||
} else {
|
} else {
|
||||||
nl_addr_dup(c->ifi6, c->pasta_ifi, AF_INET6);
|
nl_addr_dup(nl_sock, c->ifi6,
|
||||||
|
nl_sock_ns, c->pasta_ifi,
|
||||||
|
AF_INET6);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->no_copy_routes)
|
if (c->no_copy_routes) {
|
||||||
nl_route_set_def(c->pasta_ifi, AF_INET6,
|
nl_route_set_def(nl_sock_ns, c->pasta_ifi,
|
||||||
&c->ip6.gw);
|
AF_INET6, &c->ip6.gw);
|
||||||
else
|
} else {
|
||||||
nl_route_dup(c->ifi6, c->pasta_ifi, AF_INET6);
|
nl_route_dup(nl_sock, c->ifi6,
|
||||||
|
nl_sock_ns, c->pasta_ifi,
|
||||||
|
AF_INET6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue