Skip to content

Commit d76e193

Browse files
committed
Improve tap device initialization
1 parent 91738d2 commit d76e193

3 files changed

Lines changed: 130 additions & 0 deletions

File tree

src/port/posix/tap_darwin.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,42 @@ static int tap_setup_ipv4(const char *ifname, uint32_t host_ip, uint32_t peer_ip
245245
return 0;
246246
}
247247

248+
static int tap_wait_ready(const char *ifname, uint32_t host_ip)
249+
{
250+
const int max_tries = 50;
251+
const useconds_t delay_us = 100 * 1000;
252+
253+
for (int i = 0; i < max_tries; i++) {
254+
struct ifaddrs *ifas = NULL;
255+
int ready = 0;
256+
257+
if (getifaddrs(&ifas) == 0) {
258+
for (struct ifaddrs *ifa = ifas; ifa; ifa = ifa->ifa_next) {
259+
struct sockaddr_in *sin;
260+
if (!ifa->ifa_addr)
261+
continue;
262+
if (strcmp(ifa->ifa_name, ifname) != 0)
263+
continue;
264+
if ((ifa->ifa_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
265+
continue;
266+
if (ifa->ifa_addr->sa_family != AF_INET)
267+
continue;
268+
sin = (struct sockaddr_in *)ifa->ifa_addr;
269+
if (sin->sin_addr.s_addr == host_ip) {
270+
ready = 1;
271+
break;
272+
}
273+
}
274+
freeifaddrs(ifas);
275+
}
276+
277+
if (ready)
278+
return 0;
279+
usleep(delay_us);
280+
}
281+
return -1;
282+
}
283+
248284
int tap_init(struct wolfIP_ll_dev *ll, const char *requested_ifname, uint32_t host_ip)
249285
{
250286
struct ctl_info info;
@@ -309,6 +345,13 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *requested_ifname, uint32_t ho
309345
return -1;
310346
}
311347

348+
if (tap_wait_ready(ifname_buf, host_ip) < 0) {
349+
fprintf(stderr, "tap_init: interface %s not ready\n", ifname_buf);
350+
close(utun_fd);
351+
utun_fd = -1;
352+
return -1;
353+
}
354+
312355
return 0;
313356
}
314357

src/port/posix/tap_freebsd.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,42 @@ static void tap_fetch_mac(struct wolfIP_ll_dev *ll)
167167
freeifaddrs(ifas);
168168
}
169169

170+
static int tap_wait_ready(const char *ifname, uint32_t host_ip)
171+
{
172+
const int max_tries = 50;
173+
const useconds_t delay_us = 100 * 1000;
174+
175+
for (int i = 0; i < max_tries; i++) {
176+
struct ifaddrs *ifas = NULL;
177+
int ready = 0;
178+
179+
if (getifaddrs(&ifas) == 0) {
180+
for (struct ifaddrs *ifa = ifas; ifa; ifa = ifa->ifa_next) {
181+
struct sockaddr_in *sin;
182+
if (!ifa->ifa_addr)
183+
continue;
184+
if (strcmp(ifa->ifa_name, ifname) != 0)
185+
continue;
186+
if ((ifa->ifa_flags & (IFF_UP | IFF_RUNNING)) != (IFF_UP | IFF_RUNNING))
187+
continue;
188+
if (ifa->ifa_addr->sa_family != AF_INET)
189+
continue;
190+
sin = (struct sockaddr_in *)ifa->ifa_addr;
191+
if (sin->sin_addr.s_addr == host_ip) {
192+
ready = 1;
193+
break;
194+
}
195+
}
196+
freeifaddrs(ifas);
197+
}
198+
199+
if (ready)
200+
return 0;
201+
usleep(delay_us);
202+
}
203+
return -1;
204+
}
205+
170206
int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip)
171207
{
172208
char devpath[PATH_MAX];
@@ -232,6 +268,14 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip)
232268
return -1;
233269
}
234270

271+
if (tap_wait_ready(ll->ifname, host_ip) < 0) {
272+
fprintf(stderr, "tap_init: interface %s not ready\n", ll->ifname);
273+
close(sock_fd);
274+
close(tap_fd);
275+
tap_fd = -1;
276+
return -1;
277+
}
278+
235279
close(sock_fd);
236280
printf("Successfully initialized tap device %s\n", ll->ifname);
237281
return 0;

src/port/posix/tap_linux.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,44 @@ static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len)
7777
return write(tap_fd, buf, len);
7878
}
7979

80+
static int tap_wait_ready(const char *ifname, uint32_t host_ip)
81+
{
82+
const int max_tries = 50;
83+
const useconds_t delay_us = 100 * 1000;
84+
85+
for (int i = 0; i < max_tries; i++) {
86+
int sock_fd;
87+
struct ifreq ifr;
88+
struct sockaddr_in *addr;
89+
int flags_ready = 0;
90+
int addr_ready = 0;
91+
92+
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
93+
if (sock_fd < 0) {
94+
perror("socket");
95+
return -1;
96+
}
97+
memset(&ifr, 0, sizeof(ifr));
98+
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
99+
ifr.ifr_name[IFNAMSIZ - 1] = '\0';
100+
if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == 0) {
101+
if ((ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
102+
flags_ready = 1;
103+
}
104+
if (ioctl(sock_fd, SIOCGIFADDR, &ifr) == 0) {
105+
addr = (struct sockaddr_in *)&ifr.ifr_addr;
106+
if (addr->sin_addr.s_addr == host_ip)
107+
addr_ready = 1;
108+
}
109+
close(sock_fd);
110+
111+
if (flags_ready && addr_ready)
112+
return 0;
113+
usleep(delay_us);
114+
}
115+
return -1;
116+
}
117+
80118
int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip)
81119
{
82120
struct ifreq ifr;
@@ -173,6 +211,11 @@ int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip)
173211
close(sock_fd);
174212
return -1;
175213
}
214+
if (tap_wait_ready(ifname, host_ip) < 0) {
215+
fprintf(stderr, "tap_init: interface %s not ready\n", ifname);
216+
close(sock_fd);
217+
return -1;
218+
}
176219
printf("Successfully initialized tap device %s\n", ifname);
177220
return 0;
178221
}

0 commit comments

Comments
 (0)