From c1ee8fefd40bdd6acb3d0eb3ed27f47674fc33f9 Mon Sep 17 00:00:00 2001 From: Charles Strahan Date: Sun, 9 Aug 2015 19:13:40 -0400 Subject: nixos: add support for Ubuntu Fan Networking 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 --- pkgs/os-specific/linux/iproute/default.nix | 6 +- pkgs/os-specific/linux/iproute/ubuntu-fan.patch | 164 ++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 pkgs/os-specific/linux/iproute/ubuntu-fan.patch (limited to 'pkgs/os-specific/linux/iproute') diff --git a/pkgs/os-specific/linux/iproute/default.nix b/pkgs/os-specific/linux/iproute/default.nix index 6fea4ba05e0d..6f5ec27c638e 100644 --- a/pkgs/os-specific/linux/iproute/default.nix +++ b/pkgs/os-specific/linux/iproute/default.nix @@ -1,4 +1,6 @@ -{ fetchurl, stdenv, flex, bison, db, iptables, pkgconfig }: +{ fetchurl, stdenv, lib, flex, bison, db, iptables, pkgconfig +, enableFan ? false +}: stdenv.mkDerivation rec { name = "iproute2-4.1.1"; @@ -8,6 +10,8 @@ stdenv.mkDerivation rec { sha256 = "0vz6m2k6hdrjlg4x0r3cd75lg9ysmndbsp35pm8494zvksc7l1vk"; }; + patches = lib.optionals enableFan [ ./ubuntu-fan.patch ]; + preConfigure = '' patchShebangs ./configure sed -e '/ARPDDIR/d' -i Makefile diff --git a/pkgs/os-specific/linux/iproute/ubuntu-fan.patch b/pkgs/os-specific/linux/iproute/ubuntu-fan.patch new file mode 100644 index 000000000000..e55425c2ce6a --- /dev/null +++ b/pkgs/os-specific/linux/iproute/ubuntu-fan.patch @@ -0,0 +1,164 @@ +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); -- cgit 1.4.1