tap: Bring up tap device too, configure previous MAC address if any
In case we need to reinitialise the tap interface, make that relatively transparent to processes running in the namespace. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
a491c8ee3c
commit
8cc50c346b
1 changed files with 74 additions and 2 deletions
76
tap.c
76
tap.c
|
@ -20,6 +20,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <net/ethernet.h>
|
#include <net/ethernet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -868,6 +869,72 @@ fail:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct tap_sock_if_up_ns_arg - Arguments for tap_sock_if_up_ns()
|
||||||
|
* @c: Execution context
|
||||||
|
* @target_pid: Target namespace PID
|
||||||
|
* @ifname: Interface name of tap device
|
||||||
|
*/
|
||||||
|
struct tap_sock_if_up_ns_arg {
|
||||||
|
struct ctx *c;
|
||||||
|
int target_pid;
|
||||||
|
char ifname[IFNAMSIZ];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tap_sock_if_up_ns() - Bring up tap, get or set MAC address (if we have one)
|
||||||
|
* @ifname: Interface name
|
||||||
|
*
|
||||||
|
* Return: 0 -- not fundamental, the interface can be brought up later
|
||||||
|
*/
|
||||||
|
static int tap_sock_if_up_ns(void *arg)
|
||||||
|
{
|
||||||
|
struct ifreq ifr = { .ifr_flags = IFF_UP };
|
||||||
|
struct tap_sock_if_up_ns_arg *a;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
a = (struct tap_sock_if_up_ns_arg *)arg;
|
||||||
|
|
||||||
|
if (ns_enter(a->target_pid))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||||
|
perror("socket for ioctl");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, a->ifname, IFNAMSIZ);
|
||||||
|
if (ioctl(fd, SIOCSIFFLAGS, &ifr)) {
|
||||||
|
perror("SIOCSIFFLAGS ioctl for tap");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(a->c->mac_guest,
|
||||||
|
((uint8_t [ETH_ALEN]){ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }),
|
||||||
|
ETH_ALEN)) {
|
||||||
|
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
|
||||||
|
memcpy(ifr.ifr_hwaddr.sa_data, a->c->mac_guest, ETH_ALEN);
|
||||||
|
|
||||||
|
if (ioctl(fd, SIOCSIFHWADDR, &ifr) < 0) {
|
||||||
|
perror("SIOCSIFHWADDR ioctl for tap");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
|
||||||
|
perror("SIOCGIFHWADDR ioctl for tap");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(a->c->mac_guest, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||||
|
proto_update_l2_buf(a->c->mac_guest, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tap_sock_init_tun() - Set up tuntap file descriptor
|
* tap_sock_init_tun() - Set up tuntap file descriptor
|
||||||
* @c: Execution context
|
* @c: Execution context
|
||||||
|
@ -875,8 +942,7 @@ fail:
|
||||||
static void tap_sock_init_tun(struct ctx *c)
|
static void tap_sock_init_tun(struct ctx *c)
|
||||||
{
|
{
|
||||||
struct ifreq ifr = { .ifr_flags = IFF_TAP | IFF_NO_PI };
|
struct ifreq ifr = { .ifr_flags = IFF_TAP | IFF_NO_PI };
|
||||||
|
struct tap_sock_if_up_ns_arg ifup_arg;
|
||||||
strncpy(ifr.ifr_name, c->pasta_ifn, IFNAMSIZ);
|
|
||||||
|
|
||||||
NS_CALL(tap_sock_init_tun_ns, &c->pasta_pid);
|
NS_CALL(tap_sock_init_tun_ns, &c->pasta_pid);
|
||||||
if (tun_ns_fd == -1) {
|
if (tun_ns_fd == -1) {
|
||||||
|
@ -884,11 +950,17 @@ static void tap_sock_init_tun(struct ctx *c)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strncpy(ifr.ifr_name, c->pasta_ifn, IFNAMSIZ);
|
||||||
if (ioctl(tun_ns_fd, TUNSETIFF, &ifr)) {
|
if (ioctl(tun_ns_fd, TUNSETIFF, &ifr)) {
|
||||||
perror("TUNSETIFF ioctl");
|
perror("TUNSETIFF ioctl");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strncpy(ifup_arg.ifname, c->pasta_ifn, IFNAMSIZ);
|
||||||
|
ifup_arg.target_pid = c->pasta_pid;
|
||||||
|
ifup_arg.c = c;
|
||||||
|
NS_CALL(tap_sock_if_up_ns, (void *)&ifup_arg);
|
||||||
|
|
||||||
pcap_init(c, c->pasta_pid);
|
pcap_init(c, c->pasta_pid);
|
||||||
|
|
||||||
c->fd_tap = tun_ns_fd;
|
c->fd_tap = tun_ns_fd;
|
||||||
|
|
Loading…
Reference in a new issue