1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
From: Benda Xu <heroxbd@gentoo.org>
Date: Fri, 28 Dec 2018 00:00:00 +0000
Subject: Support SIIT-DC styled EAM static maps
Introduce Explicit Address Mapping as defined in RFC7757. This extends the
`map <ipv4> <ipv6>` into `map <ipv4 subnet> <ipv6 subnet>`.
Forwarded: Nathan Lutchansky <lutchann@litech.org>
---
addrmap.c | 29 +++++++++++++++++++++++------
conffile.c | 40 +++++++++++++++++++++++++++++++++++++---
2 files changed, 60 insertions(+), 9 deletions(-)
--- a/addrmap.c
+++ b/addrmap.c
@@ -22,10 +22,6 @@
int validate_ip4_addr(const struct in_addr *a)
{
- /* First octet == 0 */
- if (!(a->s_addr & htonl(0xff000000)))
- return -1;
-
/* First octet == 127 */
if ((a->s_addr & htonl(0xff000000)) == htonl(0x7f000000))
return -1;
@@ -97,7 +93,7 @@
int calc_ip4_mask(struct in_addr *mask, const struct in_addr *addr, int len)
{
- mask->s_addr = htonl(~((1 << (32 - len)) - 1));
+ mask->s_addr = htonl(~(0xffffffff >> len));
if (addr && (addr->s_addr & ~mask->s_addr))
return -1;
return 0;
@@ -422,6 +418,9 @@
case MAP_TYPE_STATIC:
s = container_of(map4, struct map_static, map4);
*addr6 = s->map6.addr;
+ if (map4->prefix_len < 32) {
+ addr6->s6_addr32[3] = s->map6.addr.s6_addr32[3] | (addr4->s_addr & ~map4->mask.s_addr);
+ }
break;
case MAP_TYPE_RFC6052:
s = container_of(map4, struct map_static, map4);
@@ -564,7 +563,13 @@
switch (map6->type) {
case MAP_TYPE_STATIC:
s = container_of(map6, struct map_static, map6);
- *addr4 = s->map4.addr;
+
+ if (map6->prefix_len < 128) {
+ addr4->s_addr = s->map4.addr.s_addr | (addr6->s6_addr32[3] & ~map6->mask.s6_addr32[3]);
+ } else {
+ *addr4 = s->map4.addr;
+ }
+
break;
case MAP_TYPE_RFC6052:
if (extract_from_prefix(addr4, addr6, map6->prefix_len) < 0)
@@ -629,3 +634,10 @@
}
}
}
+
+/*
+Local Variables:
+c-basic-offset: 8
+indent-tabs-mode: t
+End:
+*/
--- a/conffile.c
+++ b/conffile.c
@@ -217,16 +217,43 @@
m = alloc_map_static(ln);
+ char *slash;
+ slash = strchr(args[0], '/');
+ unsigned int prefix4 = 32;
+ if (slash) {
+ prefix4 = atoi(slash+1);
+ slash[0] = NULL;
+ }
+
if (!inet_pton(AF_INET, args[0], &m->map4.addr)) {
- slog(LOG_CRIT, "Expected an IPv4 address but found \"%s\" on "
- "line %d\n", args[0], ln);
+ slog(LOG_CRIT, "Expected an IPv4 subnet but found \"%s\" on "
+ "line %d\n", args[0], ln);
+ exit(1);
+ }
+ m->map4.prefix_len = prefix4;
+ calc_ip4_mask(&m->map4.mask, NULL, prefix4);
+
+ unsigned int prefix6 = 128;
+ slash = strchr(args[1], '/');
+ if (slash) {
+ prefix6 = atoi(slash+1);
+ slash[0] = NULL;
+ }
+
+ if ((32 - prefix4) != (128 - prefix6)) {
+ slog(LOG_CRIT, "IPv4 and IPv6 subnet must be of the same size, but found"
+ " %s and %s on line %d\n", args[0], args[1], ln);
exit(1);
}
+
if (!inet_pton(AF_INET6, args[1], &m->map6.addr)) {
- slog(LOG_CRIT, "Expected an IPv6 address but found \"%s\" on "
+ slog(LOG_CRIT, "Expected an IPv6 subnet but found \"%s\" on "
"line %d\n", args[1], ln);
exit(1);
}
+ m->map6.prefix_len = prefix6;
+ calc_ip6_mask(&m->map6.mask, NULL, prefix6);
+
if (validate_ip4_addr(&m->map4.addr) < 0) {
slog(LOG_CRIT, "Cannot use reserved address %s in map "
"directive, aborting...\n", args[0]);
@@ -490,3 +517,10 @@
slog(LOG_CRIT, "Unable to allocate config memory\n");
exit(1);
}
+
+/*
+Local Variables:
+c-basic-offset: 8
+indent-tabs-mode: t
+End:
+*/
|