[MEDIUM] IPv6 support for stick-tables

Since IPv6 is a different type than IPv4, the pattern fetch functions
src6 and dst6 were added. IPv6 stick-tables can also fetch IPv4 addresses
with src and dst. In this case, the IPv4 addresses are mapped to their
IPv6 counterpart, according to RFC 4291.
diff --git a/include/common/standard.h b/include/common/standard.h
index e20eb77..e7a1052 100644
--- a/include/common/standard.h
+++ b/include/common/standard.h
@@ -549,4 +549,18 @@
 	return 0;
 }
 
+/* Return true if IPv4 address is part of the network */
+extern int in_net_ipv4(struct in_addr *addr, struct in_addr *mask, struct in_addr *net);
+
+/* Return true if IPv6 address is part of the network */
+extern int in_net_ipv6(struct in6_addr *addr, struct in6_addr *mask, struct in6_addr *net);
+
+/* Map IPv4 adress on IPv6 address, as specified in RFC 3513. */
+extern void v4tov6(struct in6_addr *sin6_addr, struct in_addr *sin_addr);
+
+/* Map IPv6 adress on IPv4 address, as specified in RFC 3513.
+ * Return true if conversion is possible and false otherwise.
+ */
+extern int v6tov4(struct in_addr *sin_addr, struct in6_addr *sin6_addr);
+
 #endif /* _COMMON_STANDARD_H */
diff --git a/include/proto/proto_tcp.h b/include/proto/proto_tcp.h
index 26e06df..c7aef6a 100644
--- a/include/proto/proto_tcp.h
+++ b/include/proto/proto_tcp.h
@@ -36,18 +36,19 @@
 int tcp_persist_rdp_cookie(struct session *s, struct buffer *req, int an_bit);
 int tcp_exec_req_rules(struct session *s);
 
-/* Converts the TCPv4 source address to a stick_table key usable for table
+/* Converts the TCP source address to a stick_table key usable for table
  * lookups. Returns either NULL if the source cannot be converted (eg: not
  * IPv4) or a pointer to the converted result in static_table_key in the
  * appropriate format (IP).
  */
-static inline struct stktable_key *tcpv4_src_to_stktable_key(struct session *s)
+static inline struct stktable_key *tcp_src_to_stktable_key(struct session *s)
 {
-	/* right now we only support IPv4 */
-	if (s->si[0].addr.c.from.ss_family != AF_INET)
-		return NULL;
-
-	static_table_key.key = (void *)&((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_addr;
+	switch (s->si[0].addr.c.from.ss_family) {
+	case AF_INET:
+		static_table_key.key = (void *)&((struct sockaddr_in *)&s->si[0].addr.c.from)->sin_addr;
+	case AF_INET6:
+		static_table_key.key = (void *)&((struct sockaddr_in6 *)&s->si[0].addr.c.from)->sin6_addr;
+	}
 	return &static_table_key;
 }
 
diff --git a/include/types/pattern.h b/include/types/pattern.h
index a3d5c36..9b4e340 100644
--- a/include/types/pattern.h
+++ b/include/types/pattern.h
@@ -29,6 +29,7 @@
 /* pattern in and out types */
 enum {
 	PATTERN_TYPE_IP = 0,      /* ipv4 type */
+	PATTERN_TYPE_IPV6,        /* ipv6 type */
 	PATTERN_TYPE_INTEGER,     /* unsigned 32bits integer type */
 	PATTERN_TYPE_STRING,      /* char string type */
 	PATTERN_TYPE_DATA,        /* buffer type */
@@ -41,6 +42,7 @@
 /* pattern arg types */
 enum {
 	PATTERN_ARG_TYPE_IP = 0,      /* ipv4 type */
+	PATTERN_ARG_TYPE_IPV6,        /* ipv6 type */
 	PATTERN_ARG_TYPE_INTEGER,     /* unsigned 32bits integer type */
 	PATTERN_ARG_TYPE_SINTEGER,    /* signed 32bits integer type */
 	PATTERN_ARG_TYPE_STRING       /* string type */
@@ -53,6 +55,7 @@
 
 union pattern_arg_data {
 	struct in_addr ip;        /* used for ipv4 type */
+	struct in6_addr ipv6;     /* used for ipv6 type */
 	uint32_t integer;         /* used for unsigned 32bits integer type */
 	int sinteger;             /* used for signed 32bits integer type */
 	struct chunk str;
@@ -66,6 +69,7 @@
 /* pattern result data */
 union pattern_data {
 	struct in_addr ip;        /* used for ipv4 type */
+	struct in6_addr ipv6;     /* used for ipv6 type */
 	uint32_t integer;         /* used for unsigned 32bits integer type */
 	struct chunk str;         /* used for char string type or buffers*/
 };
diff --git a/include/types/stick_table.h b/include/types/stick_table.h
index e519f49..cccf9fb 100644
--- a/include/types/stick_table.h
+++ b/include/types/stick_table.h
@@ -35,6 +35,7 @@
 /* stick table key types */
 enum {
 	STKTABLE_TYPE_IP = 0,     /* table key is ipv4 */
+	STKTABLE_TYPE_IPV6,       /* table key is ipv6 */
 	STKTABLE_TYPE_INTEGER,    /* table key is unsigned 32bit integer */
 	STKTABLE_TYPE_STRING,     /* table key is a null terminated string */
 	STKTABLE_TYPE_BINARY,     /* table key is a buffer of data  */
@@ -172,7 +173,8 @@
 
 /* stick table key data */
 union stktable_key_data {
-	struct in_addr ip;        /* used to store an ip key */
+	struct in_addr ip;        /* used to store an ipv4 key */
+	struct in6_addr ipv6;     /* used to store an ipv6 key */
 	uint32_t integer;         /* used to store an integer key */
 	char buf[BUFSIZE];        /* used to store a null terminated string key or a buffer of data */
 };