diff --git a/nat46/Makefile b/nat46/Makefile index 3af8718..1140bcf 100644 --- a/nat46/Makefile +++ b/nat46/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=nat46 -PKG_VERSION:=9 +PKG_VERSION:=10 PKG_RELEASE:=$(PKG_SOURCE_VERSION) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz @@ -33,7 +33,7 @@ endef define Package/464xlat SECTION:=net CATEGORY:=Network - DEPENDS:=+kmod-nat46 + DEPENDS:=+kmod-nat46 +ip TITLE:=464xlat CLAT support endef diff --git a/nat46/files/464xlat.sh b/nat46/files/464xlat.sh index 2ec1094..4b3cd1c 100755 --- a/nat46/files/464xlat.sh +++ b/nat46/files/464xlat.sh @@ -43,6 +43,11 @@ proto_464xlat_setup() { return fi + ip -6 rule del from all lookup local + ip -6 rule add from all lookup local pref 1 + ip -6 rule add to $ip6addr lookup prelocal pref 0 + echo "$ip6addr" > /tmp/464-$cfg-anycast + proto_init_update "$link" 1 proto_add_ipv4_route "0.0.0.0" 0 "" "" 2048 proto_add_ipv6_route $ip6addr 128 "" "" "" "" 128 @@ -74,7 +79,20 @@ proto_464xlat_setup() { } proto_464xlat_teardown() { - 464xlatcfg "464-$1" + local cfg="$1" + local link="464-$cfg" + local ip6addr=$(cat /tmp/464-$cfg-anycast) + local anycast_active + + 464xlatcfg "$link" + + rm -rf /tmp/464-$cfg-anycast + ip -6 rule del to $ip6addr lookup prelocal + + if [ -z "$(ls /tmp/464-*-anycast 2>&-)" ]; then + ip -6 rule del from all lookup local + ip -6 rule add from all lookup local pref 0 + fi } proto_464xlat_init_config() { diff --git a/nat46/src/464xlatcfg.c b/nat46/src/464xlatcfg.c index f184616..288733e 100644 --- a/nat46/src/464xlatcfg.c +++ b/nat46/src/464xlatcfg.c @@ -1,6 +1,7 @@ /* 464xlatcfg.c * * Copyright (c) 2015 Steven Barth + * Copyright (c) 2017 Hans Dedecker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -31,28 +32,31 @@ int main(int argc, const char *argv[]) { char buf[INET6_ADDRSTRLEN], prefix[INET6_ADDRSTRLEN + 4]; int pid; - + if (argc <= 1) { fprintf(stderr, "Usage: %s [ifname] [ipv6prefix] [ipv4addr] [ipv6addr]\n", argv[0]); return 1; } - + snprintf(buf, sizeof(buf), "/var/run/%s.pid", argv[1]); FILE *fp = fopen(buf, "r"); if (fp) { - fscanf(fp, "%d", &pid); - kill(pid, SIGTERM); + if (fscanf(fp, "%d", &pid) == 1) + kill(pid, SIGTERM); + unlink(buf); fclose(fp); } - + if (!argv[2]) return 0; - + if (!argv[3] || !argv[4] || !(fp = fopen(buf, "wx"))) return 1; - signal(SIGTERM, sighandler); + signal(SIGTERM, SIG_DFL); + setvbuf(fp, NULL, _IOLBF, 0); + fprintf(fp, "%d\n", getpid()); prefix[sizeof(prefix) - 1] = 0; strncpy(prefix, argv[3], sizeof(prefix) - 1); @@ -70,7 +74,7 @@ int main(int argc, const char *argv[]) strcat(prefix, "/96"); freeaddrinfo(res); } - + int i = 0; int sock; struct sockaddr_in6 saddr; @@ -98,7 +102,7 @@ int main(int argc, const char *argv[]) sleep(3); i++; } while (i < 3); - + struct ipv6_mreq mreq = {saddr.sin6_addr, if_nametoindex(argv[2])}; if (!argv[5]) { if (IN6_IS_ADDR_LINKLOCAL(&mreq.ipv6mr_multiaddr)) @@ -111,21 +115,21 @@ int main(int argc, const char *argv[]) } else if (inet_pton(AF_INET6, argv[5], &mreq.ipv6mr_multiaddr) != 1) { return 1; } - + if (setsockopt(sock, SOL_IPV6, IPV6_JOIN_ANYCAST, &mreq, sizeof(mreq))) return 3; - + inet_ntop(AF_INET6, &mreq.ipv6mr_multiaddr, buf, sizeof(buf)); fputs(buf, stdout); fputc('\n', stdout); fflush(stdout); - + FILE *nat46 = fopen("/proc/net/nat46/control", "w"); if (!nat46 || fprintf(nat46, "add %s\nconfig %s local.style NONE local.v4 %s/32 local.v6 %s/128 " "remote.style RFC6052 remote.v6 %s\n", argv[1], argv[1], argv[4], buf, prefix) < 0 || fclose(nat46)) return 4; - + if (!(pid = fork())) { fclose(fp); fclose(stdin); @@ -133,6 +137,7 @@ int main(int argc, const char *argv[]) fclose(stderr); chdir("/"); setsid(); + signal(SIGTERM, sighandler); pause(); nat46 = fopen("/proc/net/nat46/control", "w"); @@ -141,8 +146,9 @@ int main(int argc, const char *argv[]) fclose(nat46); } } else { + rewind(fp); fprintf(fp, "%d\n", pid); } - + return 0; }