Revision: 14779
Author: adrian.chadd
Date: Sat Sep 4 05:33:15 2010
Log: Merge r13331 from /playpen/ipv6_acl
* Fix a bug in the splay tree IP acl walk function - print out mask when
needed, not just addr2 again! tsk adrian.
* Hack together a basic IPv6 address parsing and IP ACL list builder
function; there's a bit of code copying going on which needs to be
looked at -and- the code doesn't yet do host lookups for IP ACLs.
That can all come later.
* Implement src6/myip6 ACL types using the above.
The ACLs load and dump out right in mgr:config; they're just not yet used
anywhere!
http://code.google.com/p/lusca-cache/source/detail?r=14779
Modified:
/playpen/LUSCA_HEAD_ipv6/src/acl.c
/playpen/LUSCA_HEAD_ipv6/src/cf.data.pre
/playpen/LUSCA_HEAD_ipv6/src/enums.h
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/acl.c Sat Sep 4 05:24:18 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/acl.c Sat Sep 4 05:33:15 2010
@@ -42,7 +42,7 @@
static void aclParseDomainList(void *curlist);
static void aclParseUserList(void **current);
-static void aclParseIpList(void *curlist);
+static void aclParseIpList(void *curlist, int family);
static void aclParseIntlist(void *curlist);
static void aclParseWordList(void *curlist);
static void aclParseProtoList(void *curlist);
@@ -153,6 +153,10 @@
return ACL_DST_IP;
if (!strcmp(s, "myip"))
return ACL_MY_IP;
+ if (!strcmp(s, "src6"))
+ return ACL_SRC_IP6;
+ if (!strcmp(s, "myip6"))
+ return ACL_MY_IP6;
if (!strcmp(s, "domain"))
return ACL_DST_DOMAIN;
if (!strcmp(s, "dstdomain"))
@@ -259,6 +263,10 @@
return "dst";
if (type == ACL_MY_IP)
return "myip";
+ if (type == ACL_SRC_IP6)
+ return "src6";
+ if (type == ACL_MY_IP6)
+ return "myip6";
if (type == ACL_DST_DOMAIN)
return "dstdomain";
if (type == ACL_SRC_DOMAIN)
@@ -483,14 +491,123 @@
return 1;
}
+/*
+ * Decode a v6 address and/or cidr mask assignment
+ *
+ * The passed-in sqaddr_t -must- be init'ed and set to the correct family.
+ */
+static int
+decode_v6_addr(const char *asc, sqaddr_t *A)
+{
+ int a, r;
+
+ /* Is it a CIDR netmask? Store it away */
+ r = sscanf(asc, "%d", &a);
+ if (r > 0) {
+ return sqinet_set_mask_addr(A, a);
+ }
+
+ /* Try to parse an IPv6 address */
+ return sqinet_aton(A, asc, SQATON_NONE);
+}
+
+/* Stolen shamelessly from Squid-3; thanks Amos! */
+
+#define
SCAN_ACL1_6 "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]/%[0123456789]"
+#define
SCAN_ACL2_6 "%[0123456789ABCDEFabcdef:]-%[0123456789ABCDEFabcdef:]%c"
+#define SCAN_ACL3_6 "%[0123456789ABCDEFabcdef:]/%[0123456789]"
+#define SCAN_ACL4_6 "%[0123456789ABCDEFabcdef:]/%c"
+
+acl_ip_data *
+aclParseIpData6(const char *t)
+{
+ LOCAL_ARRAY(char, addr1, MAX_IPSTRLEN);
+ LOCAL_ARRAY(char, addr2, MAX_IPSTRLEN);
+ LOCAL_ARRAY(char, mask, MAX_IPSTRLEN);
+ LOCAL_ARRAY(char, buf, MAX_IPSTRLEN);
+
+ acl_ip_data *q;
+ char c;
+
+ q = memPoolAlloc(acl_ip_data_pool);
+ sqinet_init(&q->addr1);
+ sqinet_init(&q->addr2);
+ sqinet_init(&q->mask);
+ sqinet_set_family(&q->addr1, AF_INET6);
+ sqinet_set_family(&q->addr2, AF_INET6);
+ sqinet_set_family(&q->mask, AF_INET6);
+
+ /* "all" matches entire ipv6 internet */
+ if ((strcasecmp(t, "all") == 0) || (strcasecmp(t, "ipv6") == 0)) {
+ sqinet_set_anyaddr(&q->addr1);
+ sqinet_set_anyaddr(&q->addr2);
+ sqinet_set_anyaddr(&q->mask);
+ return q;
+ }
+
+ /* start matching on the available formats */
+ if (sscanf(t, SCAN_ACL1_6, addr1, addr2, mask) == 3) {
+ (void) 0;
+ } else if (sscanf(t, SCAN_ACL2_6, addr1, addr2, &c) >= 2) {
+ mask[0] = '\0';
+ } else if (sscanf(t, SCAN_ACL3_6, addr1, mask) == 2) {
+ addr2[0] = '\0';
+ } else if (sscanf(t, SCAN_ACL4_6, addr1, &c) == 2) {
+ addr2[0] = '\0';
+ mask[0] = '\0';
+ } else {
+ debug(28, 0) ("aclParseIpData6: Entry '%s' can't be parsed!\n",
t);
+ memPoolFree(acl_ip_data_pool, q);
+ return NULL;
+ }
+
+ /*
+ * XXX - The rest of this is a blatant copy from aclParseIpData(); yes
these
+ * XXX - two functions should be merged!
+ */
+ /* Decode addr1 */
+ if (!decode_v6_addr(addr1, &q->addr1)) {
+ debug(28, 0) ("%s line %d: %s\n",
+ cfg_filename, config_lineno, config_input_line);
+ debug(28, 0) ("aclParseIpData6: Ignoring invalid IP acl entry: unknown
first address '%s'\n", addr1);
+ safe_free(q);
+ return NULL;
+ }
+ /* Decode addr2 */
+ if (*addr2 && !decode_v6_addr(addr2, &q->addr2)) {
+ debug(28, 0) ("%s line %d: %s\n",
+ cfg_filename, config_lineno, config_input_line);
+ debug(28, 0) ("aclParseIpData6: Ignoring invalid IP acl entry: unknown
second address '%s'\n", addr2);
+ safe_free(q);
+ return NULL;
+ }
+ /* Decode mask */
+ if (*mask && !decode_v6_addr(mask, &q->mask)) {
+ debug(28, 0) ("%s line %d: %s\n",
+ cfg_filename, config_lineno, config_input_line);
+ debug(28, 0) ("aclParseIpData6: Ignoring invalid IP acl entry: unknown
netmask '%s'\n", mask);
+ safe_free(q);
+ return NULL;
+ }
+ sqinet_ntoa(&q->mask, buf, sizeof(buf), SQADDR_NONE);
+
+ if (sqinet_host_is_netaddr(&q->addr1, &q->mask) ||
sqinet_host_is_netaddr(&q->addr2, &q->mask))
+ debug(28, 0) ("aclParseIpData6: WARNING: Netmask masks away part of the
specified IP in '%s'\n", t);
+ /* Store the masked version of the IP address */
+ sqinet_mask_addr(&q->addr1, &q->mask);
+ sqinet_mask_addr(&q->addr2, &q->mask);
+ /* 1.2.3.4/255.255.255.0 --> 1.2.3.0 */
+ return q;
+
+}
#define SCAN_ACL1 "%[0123456789.]-%[0123456789.]/%[0123456789.]"
#define SCAN_ACL2 "%[0123456789.]-%[0123456789.]%c"
#define SCAN_ACL3 "%[0123456789.]/%[0123456789.]"
#define SCAN_ACL4 "%[0123456789.]%c"
-static acl_ip_data *
-aclParseIpData(const char *t, int af_family)
+acl_ip_data *
+aclParseIpData(const char *t)
{
LOCAL_ARRAY(char, addr1, 256);
LOCAL_ARRAY(char, addr2, 256);
@@ -500,9 +617,9 @@
sqinet_init(&q->addr1);
sqinet_init(&q->addr2);
sqinet_init(&q->mask);
- sqinet_set_family(&q->addr1, af_family);
- sqinet_set_family(&q->addr2, af_family);
- sqinet_set_family(&q->mask, af_family);
+ sqinet_set_family(&q->addr1, AF_INET);
+ sqinet_set_family(&q->addr2, AF_INET);
+ sqinet_set_family(&q->mask, AF_INET);
acl_ip_data *r;
acl_ip_data **Q;
struct hostent *hp;
@@ -601,7 +718,7 @@
/******************/
static void
-aclParseIpList(void *curlist)
+aclParseIpList(void *curlist, int family)
{
char *t = NULL;
splayNode **Top = curlist;
@@ -609,7 +726,7 @@
while ((t = strtokFile())) {
acl_ip_data *next;
/* XXX how do we determine whether the AF is INET or INET6? */
- for (q = aclParseIpData(t, AF_INET); q != NULL; q = next) {
+ for (q = (family == AF_INET ? aclParseIpData(t) : aclParseIpData6(t));
q != NULL; q = next) {
next = q->next;
*Top = splay_insert(q, *Top, aclIpNetworkCompare);
if (splayLastResult == 0)
@@ -1048,7 +1165,11 @@
case ACL_DST_IP:
case ACL_MY_IP:
case ACL_DSTFWD_IP:
- aclParseIpList(&A->data);
+ aclParseIpList(&A->data, AF_INET);
+ break;
+ case ACL_SRC_IP6:
+ case ACL_MY_IP6:
+ aclParseIpList(&A->data, AF_INET6);
break;
case ACL_SRC_DOMAIN:
case ACL_DST_DOMAIN:
@@ -1903,6 +2024,10 @@
return 0;
}
/* NOTREACHED */
+ case ACL_SRC_IP6:
+ return 0; /* XXX for now; no v6 address to compare! */
+ case ACL_MY_IP6:
+ return 0; /* XXX for now; no v6 address to compare! */
case ACL_DST_DOMAIN:
if (aclMatchDomainList(&ae->data, r->host))
return 1;
@@ -2621,6 +2746,8 @@
case ACL_DST_IP:
case ACL_MY_IP:
case ACL_DSTFWD_IP:
+ case ACL_SRC_IP6:
+ case ACL_MY_IP6:
splay_destroy(a->data, aclFreeIpData);
break;
#if USE_ARP_ACL
@@ -2947,7 +3074,7 @@
memBufPrintf(&mb, "-%s", buf);
}
if (! sqinet_is_noaddr(&ip->mask)) {
- (void) sqinet_ntoa(&ip->addr2, buf, sizeof(buf), SQATON_NONE);
+ (void) sqinet_ntoa(&ip->mask, buf, sizeof(buf), SQATON_NONE);
memBufPrintf(&mb, "/%s", buf);
}
wordlistAdd(W, mb.buf);
@@ -3071,6 +3198,8 @@
case ACL_DST_IP:
case ACL_MY_IP:
case ACL_DSTFWD_IP:
+ case ACL_SRC_IP6:
+ case ACL_MY_IP6:
return aclDumpIpList(a->data);
case ACL_SRC_DOMAIN:
case ACL_DST_DOMAIN:
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre Tue Aug 31 09:02:21 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre Sat Sep 4 05:33:15 2010
@@ -688,6 +688,7 @@
NOCOMMENT_START
#Recommended minimum configuration:
acl all src all
+acl all6 src6 ::0/0
acl manager proto cache_object
acl localhost src 127.0.0.1/32
acl to_localhost dst 127.0.0.0/8
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/enums.h Sun Jul 4 06:56:53 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/enums.h Sat Sep 4 05:33:15 2010
@@ -105,6 +105,8 @@
ACL_SRC_IP,
ACL_DST_IP,
ACL_MY_IP,
+ ACL_SRC_IP6,
+ ACL_MY_IP6,
ACL_SRC_DOMAIN,
ACL_DST_DOMAIN,
ACL_SRC_DOM_REGEX,
--
You received this message because you are subscribed to the Google Groups
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/lusca-commit?hl=en.