From 1321c1bd8fe921986c4eb39c3783ddd827b79543 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 30 Dec 2019 14:57:47 +0200 Subject: add basic support for jail network namespaces Prepare netifd for handling procd service jails having their own network namespace. Intefaces having the jail attribute will only be brought inside the jail's network namespace by procd calling the newly introduced ubus method 'netns_updown'. Currently proto 'static' is supported and configuration changes are not yet being handled (ie. you'll have to restart the jailed service for changes to take effect). Example /etc/config/network snippet: config device 'veth0' option type 'veth' option name 'vhost0' option peer_name 'virt0' config interface 'virt' option type 'bridge' list ifname 'vhost0' option proto 'static' option ipaddr '10.0.0.1' option netmask '255.255.255.0' config interface 'virt0' option ifname 'virt0' option proto 'static' option ipaddr '10.0.0.2' option netmask '255.255.255.0' option gateway '10.0.0.1' option dns '10.0.0.1' option jail 'transmission' Signed-off-by: Daniel Golle --- interface-ip.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) (limited to 'interface-ip.c') diff --git a/interface-ip.c b/interface-ip.c index c159e09..91c305b 100644 --- a/interface-ip.c +++ b/interface-ip.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -1443,7 +1445,7 @@ static int resolv_conf_iface_cmp(const void *k1, const void *k2, void *ptr) } static void -__interface_write_dns_entries(FILE *f) +__interface_write_dns_entries(FILE *f, const char *jail) { struct interface *iface; struct { @@ -1457,6 +1459,9 @@ __interface_write_dns_entries(FILE *f) if (iface->state != IFS_UP) continue; + if (jail && (!iface->jail || strcmp(jail, iface->jail))) + continue; + if (vlist_simple_empty(&iface->proto_ip.dns_search) && vlist_simple_empty(&iface->proto_ip.dns_servers) && vlist_simple_empty(&iface->config_ip.dns_search) && @@ -1488,21 +1493,33 @@ __interface_write_dns_entries(FILE *f) } void -interface_write_resolv_conf(void) +interface_write_resolv_conf(const char *jail) { - char *path = alloca(strlen(resolv_conf) + 5); + size_t plen = (jail ? strlen(jail) + 1 : 0 ) + strlen(resolv_conf) + 1; + char *path = alloca(plen); + char *dpath = alloca(plen); + char *tmppath = alloca(plen + 4); FILE *f; uint32_t crcold, crcnew; - sprintf(path, "%s.tmp", resolv_conf); - unlink(path); - f = fopen(path, "w+"); + if (jail) { + sprintf(path, "/tmp/resolv.conf-%s.d/resolv.conf.auto", jail); + strcpy(dpath, path); + dpath = dirname(dpath); + mkdir(dpath, 0755); + } else { + strcpy(path, resolv_conf); + } + + sprintf(tmppath, "%s.tmp", path); + unlink(tmppath); + f = fopen(tmppath, "w+"); if (!f) { D(INTERFACE, "Failed to open %s for writing\n", path); return; } - __interface_write_dns_entries(f); + __interface_write_dns_entries(f, jail); fflush(f); rewind(f); @@ -1510,17 +1527,17 @@ interface_write_resolv_conf(void) fclose(f); crcold = crcnew + 1; - f = fopen(resolv_conf, "r"); + f = fopen(path, "r"); if (f) { crcold = crc32_file(f); fclose(f); } if (crcold == crcnew) { - unlink(path); - } else if (rename(path, resolv_conf) < 0) { - D(INTERFACE, "Failed to replace %s\n", resolv_conf); - unlink(path); + unlink(tmppath); + } else if (rename(tmppath, path) < 0) { + D(INTERFACE, "Failed to replace %s\n", path); + unlink(tmppath); } } @@ -1640,7 +1657,7 @@ interface_ip_update_complete(struct interface_ip_settings *ip) vlist_flush(&ip->addr); vlist_flush(&ip->prefix); vlist_flush(&ip->neighbor); - interface_write_resolv_conf(); + interface_write_resolv_conf(ip->iface->jail); } void -- cgit v1.2.1