[master] 51523bc88 vcc_acl: change compare functions to differentiate cases

Nils Goroll nils.goroll at uplex.de
Mon Dec 4 11:33:03 UTC 2023


commit 51523bc883525005a0d87c83467e753a88abb0ed
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Fri Dec 13 18:08:59 2019 +0100

    vcc_acl: change compare functions to differentiate cases
    
    This is in preparation of a follow-up commit to merge acl entries and
    detect supersedes from supernets, but these changes are backwards
    compatible with the previous CMP() if being used as a comparison
    function for which only negative, zero and positive result are
    relevant.
    
    The A in CMPA() stands for "adjacent". CMPA() returns -3/3 for left
    of/right of.

diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c
index c8219dcc8..d4b78ad8d 100644
--- a/lib/libvcc/vcc_acl.c
+++ b/lib/libvcc/vcc_acl.c
@@ -74,14 +74,29 @@ struct acl_e {
 	struct token		*t_mask;
 };
 
-/* Compare two acl rules for ordering */
+/*
+ * Compare two acl rules for ordering
+ * returns:
+ * 0	same
+ * -1/1	strictly less/greater
+ * -2/2	b contains a / a contains b
+ * -3/3	a left of b / b left of a
+ */
 
-#define CMP(a, b)							\
+#define CMP(n, a, b)							\
 	do {								\
 		if ((a) < (b))						\
-			return (-1);					\
+			return (-n);					\
 		else if ((b) < (a))					\
-			return (1);					\
+			return (n);					\
+	} while (0)
+
+#define CMPA(a, b)							\
+	do {								\
+		if (((a) | 1) == (b))					\
+			return (-3);					\
+		else if (((b) | 1) == (a))				\
+			return (3);					\
 	} while (0)
 
 static void
@@ -99,6 +114,7 @@ vcl_acl_cmp(const struct acl_e *ae1, const struct acl_e *ae2)
 {
 	const unsigned char *p1, *p2;
 	unsigned m;
+	unsigned char a1, a2;
 
 	CHECK_OBJ_NOTNULL(ae1, VCC_ACL_E_MAGIC);
 	CHECK_OBJ_NOTNULL(ae2, VCC_ACL_E_MAGIC);
@@ -107,17 +123,22 @@ vcl_acl_cmp(const struct acl_e *ae1, const struct acl_e *ae2)
 	p2 = ae2->data;
 	m = vmin_t(unsigned, ae1->mask, ae2->mask);
 	for (; m >= 8; m -= 8) {
-		CMP(*p1, *p2);
+		CMP(1, *p1, *p2);
 		p1++;
 		p2++;
 	}
 	if (m) {
-		m = 0xff00 >> m;
-		m &= 0xff;
-		CMP(*p1 & m, *p2 & m);
+		assert (m < 8);
+		a1 = *p1 >> (8 - m);
+		a2 = *p2 >> (8 - m);
+		if (ae1->mask == ae2->mask)
+			CMPA(a1, a2);
+		CMP(1, a1, a2);
+	} else if (ae1->mask == ae2->mask) {
+		CMPA(*p1, *p2);
 	}
 	/* Long mask is less than short mask */
-	CMP(ae2->mask, ae1->mask);
+	CMP(2, ae2->mask, ae1->mask);
 
 	return (0);
 }
@@ -135,14 +156,14 @@ vcl_acl_disjoint(const struct acl_e *ae1, const struct acl_e *ae2)
 	p2 = ae2->data;
 	m = vmin_t(unsigned, ae1->mask, ae2->mask);
 	for (; m >= 8; m -= 8) {
-		CMP(*p1, *p2);
+		CMP(1, *p1, *p2);
 		p1++;
 		p2++;
 	}
 	if (m) {
 		m = 0xff00 >> m;
 		m &= 0xff;
-		CMP(*p1 & m, *p2 & m);
+		CMP(1, *p1 & m, *p2 & m);
 	}
 	return (0);
 }


More information about the varnish-commit mailing list