MINOR: acl: add types to ACL patterns

We cannot currently match IPv6 addresses in ACL simply because we don't
support types on the patterns. Let's introduce this notion. For now, we
rely on the SMP_TYPES though it doesn't seem like it will last forever
given that some types are not present there (eg: regex, meth). Still it
should be enough to support mixed matchings for most types.

We use the special impossible value SMP_TYPES for types that don't exist
in the SMP_T_* space.
diff --git a/include/types/acl.h b/include/types/acl.h
index ed8582b..492e963 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -181,9 +181,16 @@
 	int h2:5, m2:6;         /* 0..24:0..60. Use 24:0 for all day. */
 };
 
-/* The acl will be linked to from the proxy where it is declared */
+/* This describes one ACL pattern, which might be a single value or a tree of
+ * values. All patterns for a single ACL expression are linked together. Some
+ * of them might have a type (eg: IP). Right now, the types are shared with
+ * the samples, though it is possible that in the future this will change to
+ * accommodate for other types (eg: meth, regex). Unsigned and constant types
+ * are preferred when there is a doubt.
+ */
 struct acl_pattern {
 	struct list list;                       /* chaining */
+	int type;                               /* type of the ACL pattern (SMP_T_*) */
 	union {
 		int i;                          /* integer value */
 		struct {
@@ -209,15 +216,14 @@
 	int flags;                      /* expr or pattern flags. */
 };
 
-/*
- * ACL keyword: Associates keywords with parsers, methods to retrieve the value and testers.
- */
-
 /* some dummy declarations to silent the compiler */
 struct proxy;
 struct session;
 
 /*
+ * ACL keyword: Associates keywords with parsers, methods to retrieve the value and testers.
+ */
+/*
  * NOTE:
  * The 'parse' function is called to parse words in the configuration. It must
  * return the number of valid words read. 0 = error. The 'opaque' argument may
@@ -268,6 +274,7 @@
 	struct eb_root pattern_tree;  /* may be used for lookup in large datasets */
 };
 
+/* The acl will be linked to from the proxy where it is declared */
 struct acl {
 	struct list list;           /* chaining */
 	char *name;		    /* acl name */
diff --git a/src/acl.c b/src/acl.c
index a1346b8..0138203 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -709,7 +709,7 @@
 {
 	struct in_addr *s;
 
-	if (smp->type != SMP_T_IPV4)
+	if (smp->type != SMP_T_IPV4 || pattern->type != SMP_T_IPV4)
 		return ACL_PAT_FAIL;
 
 	s = &smp->data.ipv4;
@@ -738,6 +738,7 @@
 	int len;
 
 	len  = strlen(*text);
+	pattern->type = SMP_T_CSTR;
 
 	if (pattern->flags & ACL_PAT_F_TREE_OK) {
 		/* we're allowed to put the data in a tree whose root is pointed
@@ -779,6 +780,7 @@
 	for (i = 0; *text[i]; i++)
 		len += strlen(text[i])+1;
 
+	pattern->type = SMP_T_CSTR;
 	pattern->ptr.str = s = calloc(1, len);
 	if (!pattern->ptr.str) {
 		if (err)
@@ -847,7 +849,7 @@
 	unsigned int j, last, skip = 0;
 	const char *ptr = *text;
 
-
+	pattern->type = SMP_T_UINT;
 	while (!isdigit((unsigned char)*ptr)) {
 		switch (get_std_op(ptr)) {
 		case STD_OP_EQ: *opaque = 0; break;
@@ -1023,7 +1025,7 @@
 /* Parse an IP address and an optional mask in the form addr[/mask].
  * The addr may either be an IPv4 address or a hostname. The mask
  * may either be a dotted mask or a number of bits. Returns 1 if OK,
- * otherwise 0.
+ * otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
  */
 int acl_parse_ip(const char **text, struct acl_pattern *pattern, int *opaque, char **err)
 {
@@ -1031,6 +1033,7 @@
 	if (pattern->flags & ACL_PAT_F_TREE_OK)
 		tree = pattern->val.tree;
 
+	pattern->type = SMP_T_IPV4;
 	if (str2net(*text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
 		unsigned int mask = ntohl(pattern->val.ipv4.mask.s_addr);
 		struct ebmb_node *node;
@@ -1248,6 +1251,7 @@
 			pattern->val.tree = &expr->pattern_tree;
 		}
 
+		pattern->type = SMP_TYPES; /* unspecified type by default */
 		if (!aclkw->parse(args, pattern, &opaque, err))
 			goto out_free_pattern;
 
@@ -1416,6 +1420,7 @@
 		}
 		pattern->flags = patflags;
 
+		pattern->type = SMP_TYPES; /* unspecified type */
 		ret = aclkw->parse(args, pattern, &opaque, err);
 		if (!ret)
 			goto out_free_pattern;