Add IPv6 support

Implement IPv6 in libgtpnl and the gtp-tunnel testing tool. Allow to
combine:

- GTPA_MS_ADDRESS and GTPA_PEER_ADDR6
- GTPA_MS_ADDR6 and GTPA_PEER_ADDRESS

to specify IPv4-in-IPv6-GTP and IPv6-in-IPv4-GTP in the tunnel
declaration from control plane.

This patch is based on multiple patches from Pablo in OS#6123. I decided
to squash them to directly implement v4-in-v6 and vice versa, instead of
implementing another variant first and then changing it again.

Co-developed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Related: OS#6096
Change-Id: If864c9170f74af52a95cbc4cdb1b866e0309306b
diff --git a/tools/gtp-tunnel.c b/tools/gtp-tunnel.c
index 1868097..b29e386 100644
--- a/tools/gtp-tunnel.c
+++ b/tools/gtp-tunnel.c
@@ -49,12 +49,32 @@
 	       name);
 }
 
+static void set_addr(const char *addr, bool is_ms, struct gtp_tunnel *t)
+{
+	struct in_addr ip4;
+	struct in6_addr ip6;
+
+	if (inet_pton(AF_INET, addr, &ip4) == 1) {
+		if (is_ms)
+			return gtp_tunnel_set_ms_ip4(t, &ip4);
+		return gtp_tunnel_set_sgsn_ip4(t, &ip4);
+	}
+
+	if (inet_pton(AF_INET6, addr, &ip6) == 1) {
+		if (is_ms)
+			return gtp_tunnel_set_ms_ip6(t, &ip6);
+		return gtp_tunnel_set_sgsn_ip6(t, &ip6);
+	}
+
+	fprintf(stderr, "bad address: %s\n", addr);
+	exit(EXIT_FAILURE);
+}
+
 static int
 add_tunnel(int argc, char *argv[], int genl_id, struct mnl_socket *nl)
 {
 	struct gtp_tunnel *t;
 	uint32_t gtp_ifidx;
-	struct in_addr ms, sgsn;
 	uint32_t gtp_version;
 	int optidx;
 
@@ -95,17 +115,8 @@
 		gtp_tunnel_set_o_tei(t, atoi(argv[optidx++]));
 	}
 
-	if (inet_aton(argv[optidx++], &ms) < 0) {
-		perror("bad address for ms");
-		exit(EXIT_FAILURE);
-	}
-	gtp_tunnel_set_ms_ip4(t, &ms);
-
-	if (inet_aton(argv[optidx++], &sgsn) < 0) {
-		perror("bad address for sgsn");
-		exit(EXIT_FAILURE);
-	}
-	gtp_tunnel_set_sgsn_ip4(t, &sgsn);
+	set_addr(argv[optidx++], true, t);
+	set_addr(argv[optidx++], false, t);
 
 	gtp_add_tunnel(genl_id, nl, t);