forked from mirrors/nixpkgs
c1ee8fefd4
This provides support for Ubuntu Fan Networking [1]. This includes: * The fanctl package, and a corresponding NixOS service. * iproute patches. * kernel patches. closes #9188 1: https://wiki.ubuntu.com/FanNetworking
165 lines
4.1 KiB
Diff
165 lines
4.1 KiB
Diff
This provides support for Ubuntu's Fan Networking [1].
|
|
|
|
These patches were pulled from:
|
|
https://code.launchpad.net/~ubuntu-branches/ubuntu/vivid/iproute2/vivid-proposed
|
|
|
|
See revisions 18 and 19.
|
|
|
|
[1] https://wiki.ubuntu.com/FanNetworking
|
|
|
|
diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
|
|
index 102ce7a..7b8f0e5 100644
|
|
--- a/include/linux/if_tunnel.h
|
|
+++ b/include/linux/if_tunnel.h
|
|
@@ -57,6 +57,9 @@ enum {
|
|
IFLA_IPTUN_ENCAP_FLAGS,
|
|
IFLA_IPTUN_ENCAP_SPORT,
|
|
IFLA_IPTUN_ENCAP_DPORT,
|
|
+
|
|
+ IFLA_IPTUN_FAN_UNDERLAY = 32,
|
|
+ IFLA_IPTUN_FAN_MAP = 33,
|
|
__IFLA_IPTUN_MAX,
|
|
};
|
|
#define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1)
|
|
@@ -131,4 +134,20 @@ enum {
|
|
};
|
|
|
|
#define IFLA_VTI_MAX (__IFLA_VTI_MAX - 1)
|
|
+
|
|
+enum {
|
|
+ IFLA_FAN_UNSPEC,
|
|
+ IFLA_FAN_MAPPING,
|
|
+ __IFLA_FAN_MAX,
|
|
+};
|
|
+
|
|
+#define IFLA_FAN_MAX (__IFLA_FAN_MAX - 1)
|
|
+
|
|
+struct ip_tunnel_fan_map {
|
|
+ __be32 underlay;
|
|
+ __be32 overlay;
|
|
+ __u16 underlay_prefix;
|
|
+ __u16 overlay_prefix;
|
|
+};
|
|
+
|
|
#endif /* _IF_TUNNEL_H_ */
|
|
diff --git a/ip/link_iptnl.c b/ip/link_iptnl.c
|
|
index 9d6bc98..ec3f05d 100644
|
|
--- a/ip/link_iptnl.c
|
|
+++ b/ip/link_iptnl.c
|
|
@@ -49,6 +49,42 @@ static void usage(int sit)
|
|
print_usage(stderr, sit);
|
|
exit(-1);
|
|
}
|
|
+static int fan_parse_map(int *argcp, char ***argvp, struct nlmsghdr *n)
|
|
+{
|
|
+ inet_prefix underlay, overlay;
|
|
+ struct ip_tunnel_fan_map map;
|
|
+ struct rtattr *nest;
|
|
+ char **argv = *argvp;
|
|
+ int argc = *argcp;
|
|
+
|
|
+ nest = addattr_nest(n, 1024, IFLA_IPTUN_FAN_MAP);
|
|
+ while (argc > 0) {
|
|
+ char *colon = strchr(*argv, ':');
|
|
+
|
|
+ if (!colon)
|
|
+ break;
|
|
+ *colon = '\0';
|
|
+
|
|
+ if (get_prefix(&overlay, *argv, AF_INET))
|
|
+ invarg("invalid fan-map overlay", *argv);
|
|
+ if (get_prefix(&underlay, colon + 1, AF_INET))
|
|
+ invarg("invalid fan-map underlay", colon + 1);
|
|
+
|
|
+ memcpy(&map.underlay, underlay.data, 4);
|
|
+ map.underlay_prefix = underlay.bitlen;
|
|
+ memcpy(&map.overlay, overlay.data, 4);
|
|
+ map.overlay_prefix = overlay.bitlen;
|
|
+
|
|
+ argc--, argv++;
|
|
+
|
|
+ addattr_l(n, 1024, IFLA_FAN_MAPPING, &map, sizeof(map));
|
|
+ }
|
|
+ addattr_nest_end(n, nest);
|
|
+
|
|
+ *argcp = argc;
|
|
+ *argvp = argv;
|
|
+ return 0;
|
|
+}
|
|
|
|
static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
|
|
struct nlmsghdr *n)
|
|
@@ -66,6 +102,7 @@ static int iptunnel_parse_opt(struct link_util *lu, int argc, char **argv,
|
|
__u32 link = 0;
|
|
__u32 laddr = 0;
|
|
__u32 raddr = 0;
|
|
+ __u32 underlay = 0;
|
|
__u8 ttl = 0;
|
|
__u8 tos = 0;
|
|
__u8 pmtudisc = 1;
|
|
@@ -174,6 +211,13 @@ get_failed:
|
|
raddr = get_addr32(*argv);
|
|
else
|
|
raddr = 0;
|
|
+ } else if (strcmp(*argv, "underlay") == 0) {
|
|
+ NEXT_ARG();
|
|
+ underlay = get_addr32(*argv);
|
|
+ } else if (strcmp(*argv, "fan-map") == 0) {
|
|
+ NEXT_ARG();
|
|
+ if (fan_parse_map(&argc, &argv, n))
|
|
+ invarg("invalid fan-map", *argv);
|
|
} else if (strcmp(*argv, "local") == 0) {
|
|
NEXT_ARG();
|
|
if (strcmp(*argv, "any"))
|
|
@@ -318,9 +362,32 @@ get_failed:
|
|
}
|
|
}
|
|
|
|
+ if (underlay)
|
|
+ addattr32(n, 1024, IFLA_IPTUN_FAN_UNDERLAY, underlay);
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
+static void fan_print_map(FILE *f, struct rtattr *attr)
|
|
+{
|
|
+ char b1[INET_ADDRSTRLEN], b2[INET_ADDRSTRLEN];
|
|
+ struct ip_tunnel_fan_map *m;
|
|
+ struct rtattr *i;
|
|
+ int rem;
|
|
+
|
|
+ fprintf(f, "fan-map ");
|
|
+
|
|
+ rem = RTA_PAYLOAD(attr);
|
|
+ for (i = RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
|
|
+ m = RTA_DATA(i);
|
|
+ fprintf(f, "%s/%d:%s/%d ",
|
|
+ rt_addr_n2a(AF_INET, sizeof(m->overlay), &m->overlay, b1, INET_ADDRSTRLEN),
|
|
+ m->overlay_prefix,
|
|
+ rt_addr_n2a(AF_INET, sizeof(m->overlay), &m->underlay, b2, INET_ADDRSTRLEN),
|
|
+ m->underlay_prefix);
|
|
+ }
|
|
+}
|
|
+
|
|
static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|
{
|
|
char s1[1024];
|
|
@@ -349,6 +416,17 @@ static void iptunnel_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[
|
|
|
|
fprintf(f, "local %s ", local);
|
|
|
|
+ if (tb[IFLA_IPTUN_FAN_UNDERLAY]) {
|
|
+ unsigned addr = rta_getattr_u32(tb[IFLA_IPTUN_FAN_UNDERLAY]);
|
|
+
|
|
+ if (addr)
|
|
+ fprintf(f, "underlay %s ",
|
|
+ format_host(AF_INET, 4, &addr, s1, sizeof(s1)));
|
|
+ }
|
|
+
|
|
+ if (tb[IFLA_IPTUN_FAN_MAP])
|
|
+ fan_print_map(f, tb[IFLA_IPTUN_FAN_MAP]);
|
|
+
|
|
if (tb[IFLA_IPTUN_LINK] && rta_getattr_u32(tb[IFLA_IPTUN_LINK])) {
|
|
unsigned link = rta_getattr_u32(tb[IFLA_IPTUN_LINK]);
|
|
const char *n = if_indextoname(link, s2);
|