Blame SOURCES/0036-libxtables-Simplify-pending-extension-registration.patch

b144b7
From 1a842fb1cfb3b36f3081aee37c5fdd4a897d77d5 Mon Sep 17 00:00:00 2001
b144b7
From: Phil Sutter <phil@nwl.cc>
b144b7
Date: Fri, 18 Sep 2020 18:48:14 +0200
b144b7
Subject: [PATCH] libxtables: Simplify pending extension registration
b144b7
b144b7
Assuming that pending extensions are sorted by first name and family,
b144b7
then descending revision, the decision where to insert a newly
b144b7
registered extension may be simplified by memorizing the previous
b144b7
registration (which obviously is of same name and family and higher
b144b7
revision).
b144b7
b144b7
As a side-effect, fix for unsupported old extension revisions lingering
b144b7
in pending extension list forever and being retried with every use of
b144b7
the given extension. Any revision being rejected by the kernel may
b144b7
safely be dropped iff a previous (read: higher) revision was accepted
b144b7
already.
b144b7
b144b7
Yet another side-effect of this change is the removal of an unwanted
b144b7
recursion by xtables_fully_register_pending_*() into itself via
b144b7
xtables_find_*().
b144b7
b144b7
Signed-off-by: Phil Sutter <phil@nwl.cc>
b144b7
(cherry picked from commit a1eaaceb0460b338294e40bdd5bc5186320a478c)
b144b7
Signed-off-by: Phil Sutter <psutter@redhat.com>
b144b7
---
b144b7
 libxtables/xtables.c | 128 +++++++++++--------------------------------
b144b7
 1 file changed, 33 insertions(+), 95 deletions(-)
b144b7
b144b7
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
b144b7
index 13139d7f8ad62..409128333e0e6 100644
b144b7
--- a/libxtables/xtables.c
b144b7
+++ b/libxtables/xtables.c
b144b7
@@ -203,8 +203,10 @@ struct xtables_match *xtables_matches;
b144b7
 struct xtables_target *xtables_targets;
b144b7
 
b144b7
 /* Fully register a match/target which was previously partially registered. */
b144b7
-static bool xtables_fully_register_pending_match(struct xtables_match *me);
b144b7
-static bool xtables_fully_register_pending_target(struct xtables_target *me);
b144b7
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
b144b7
+						 struct xtables_match *prev);
b144b7
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
b144b7
+						  struct xtables_target *prev);
b144b7
 
b144b7
 void xtables_init(void)
b144b7
 {
b144b7
@@ -616,6 +618,7 @@ struct xtables_match *
b144b7
 xtables_find_match(const char *name, enum xtables_tryload tryload,
b144b7
 		   struct xtables_rule_match **matches)
b144b7
 {
b144b7
+	struct xtables_match *prev = NULL;
b144b7
 	struct xtables_match **dptr;
b144b7
 	struct xtables_match *ptr;
b144b7
 	const char *icmp6 = "icmp6";
b144b7
@@ -637,8 +640,12 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
b144b7
 		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
b144b7
 			ptr = *dptr;
b144b7
 			*dptr = (*dptr)->next;
b144b7
-			if (xtables_fully_register_pending_match(ptr))
b144b7
+			if (xtables_fully_register_pending_match(ptr, prev)) {
b144b7
+				prev = ptr;
b144b7
 				continue;
b144b7
+			} else if (prev) {
b144b7
+				continue;
b144b7
+			}
b144b7
 			*dptr = ptr;
b144b7
 		}
b144b7
 		dptr = &((*dptr)->next);
b144b7
@@ -732,6 +739,7 @@ xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
b144b7
 struct xtables_target *
b144b7
 xtables_find_target(const char *name, enum xtables_tryload tryload)
b144b7
 {
b144b7
+	struct xtables_target *prev = NULL;
b144b7
 	struct xtables_target **dptr;
b144b7
 	struct xtables_target *ptr;
b144b7
 
b144b7
@@ -748,8 +756,12 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
b144b7
 		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) {
b144b7
 			ptr = *dptr;
b144b7
 			*dptr = (*dptr)->next;
b144b7
-			if (xtables_fully_register_pending_target(ptr))
b144b7
+			if (xtables_fully_register_pending_target(ptr, prev)) {
b144b7
+				prev = ptr;
b144b7
 				continue;
b144b7
+			} else if (prev) {
b144b7
+				continue;
b144b7
+			}
b144b7
 			*dptr = ptr;
b144b7
 		}
b144b7
 		dptr = &((*dptr)->next);
b144b7
@@ -1052,64 +1064,27 @@ static int xtables_target_prefer(const struct xtables_target *a,
b144b7
 				 b->revision, b->family);
b144b7
 }
b144b7
 
b144b7
-static bool xtables_fully_register_pending_match(struct xtables_match *me)
b144b7
+static bool xtables_fully_register_pending_match(struct xtables_match *me,
b144b7
+						 struct xtables_match *prev)
b144b7
 {
b144b7
-	struct xtables_match **i, *old, *pos = NULL;
b144b7
+	struct xtables_match **i;
b144b7
 	const char *rn;
b144b7
-	int compare;
b144b7
 
b144b7
 	/* See if new match can be used. */
b144b7
 	rn = (me->real_name != NULL) ? me->real_name : me->name;
b144b7
 	if (!compatible_match_revision(rn, me->revision))
b144b7
 		return false;
b144b7
 
b144b7
-	old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL);
b144b7
-	while (old) {
b144b7
-		compare = xtables_match_prefer(old, me);
b144b7
-		if (compare == 0) {
b144b7
-			fprintf(stderr,
b144b7
-				"%s: match `%s' already registered.\n",
b144b7
-				xt_params->program_name, me->name);
b144b7
-			exit(1);
b144b7
-		}
b144b7
-
b144b7
-		/* Now we have two (or more) options, check compatibility. */
b144b7
-		rn = (old->real_name != NULL) ? old->real_name : old->name;
b144b7
-		if (compare > 0) {
b144b7
-			/* Kernel tells old isn't compatible anymore??? */
b144b7
-			if (!compatible_match_revision(rn, old->revision)) {
b144b7
-				/* Delete old one. */
b144b7
-				for (i = &xtables_matches; *i != old;)
b144b7
-				     i = &(*i)->next;
b144b7
-				*i = old->next;
b144b7
-			}
b144b7
-			pos = old;
b144b7
-			old = old->next;
b144b7
-			if (!old)
b144b7
-				break;
b144b7
-			if (!extension_cmp(me->name, old->name, old->family))
b144b7
-				break;
b144b7
-			continue;
b144b7
-		}
b144b7
-
b144b7
-		/* Found right old */
b144b7
-		pos = old;
b144b7
-		break;
b144b7
-	}
b144b7
-
b144b7
-	if (!pos) {
b144b7
+	if (!prev) {
b144b7
 		/* Append to list. */
b144b7
 		for (i = &xtables_matches; *i; i = &(*i)->next);
b144b7
-	} else if (compare < 0) {
b144b7
-		/* Prepend it */
b144b7
-		for (i = &xtables_matches; *i != pos; i = &(*i)->next);
b144b7
-	} else if (compare > 0) {
b144b7
+	} else {
b144b7
 		/* Append it */
b144b7
-		i = &pos->next;
b144b7
-		pos = pos->next;
b144b7
+		i = &prev->next;
b144b7
+		prev = prev->next;
b144b7
 	}
b144b7
 
b144b7
-	me->next = pos;
b144b7
+	me->next = prev;
b144b7
 	*i = me;
b144b7
 
b144b7
 	me->m = NULL;
b144b7
@@ -1214,11 +1189,11 @@ void xtables_register_target(struct xtables_target *me)
b144b7
 #endif
b144b7
 }
b144b7
 
b144b7
-static bool xtables_fully_register_pending_target(struct xtables_target *me)
b144b7
+static bool xtables_fully_register_pending_target(struct xtables_target *me,
b144b7
+						  struct xtables_target *prev)
b144b7
 {
b144b7
-	struct xtables_target **i, *old, *pos = NULL;
b144b7
+	struct xtables_target **i;
b144b7
 	const char *rn;
b144b7
-	int compare;
b144b7
 
b144b7
 	if (strcmp(me->name, "standard") != 0) {
b144b7
 		/* See if new target can be used. */
b144b7
@@ -1227,54 +1202,17 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me)
b144b7
 			return false;
b144b7
 	}
b144b7
 
b144b7
-	old = xtables_find_target(me->name, XTF_DURING_LOAD);
b144b7
-	while (old) {
b144b7
-		compare = xtables_target_prefer(old, me);
b144b7
-		if (compare == 0) {
b144b7
-			fprintf(stderr,
b144b7
-				"%s: target `%s' already registered.\n",
b144b7
-				xt_params->program_name, me->name);
b144b7
-			exit(1);
b144b7
-		}
b144b7
-
b144b7
-		/* Now we have two (or more) options, check compatibility. */
b144b7
-		rn = (old->real_name != NULL) ? old->real_name : old->name;
b144b7
-		if (compare > 0) {
b144b7
-			/* Kernel tells old isn't compatible anymore??? */
b144b7
-			if (!compatible_target_revision(rn, old->revision)) {
b144b7
-				/* Delete old one. */
b144b7
-				for (i = &xtables_targets; *i != old;)
b144b7
-				     i = &(*i)->next;
b144b7
-				*i = old->next;
b144b7
-			}
b144b7
-			pos = old;
b144b7
-			old = old->next;
b144b7
-			if (!old)
b144b7
-				break;
b144b7
-			if (!extension_cmp(me->name, old->name, old->family))
b144b7
-				break;
b144b7
-			continue;
b144b7
-		}
b144b7
-
b144b7
-		/* Found right old */
b144b7
-		pos = old;
b144b7
-		break;
b144b7
-	}
b144b7
-
b144b7
-	if (!pos) {
b144b7
+	if (!prev) {
b144b7
 		/* Prepend to list. */
b144b7
 		i = &xtables_targets;
b144b7
-		pos = xtables_targets;
b144b7
-	} else if (compare < 0) {
b144b7
-		/* Prepend it */
b144b7
-		for (i = &xtables_targets; *i != pos; i = &(*i)->next);
b144b7
-	} else if (compare > 0) {
b144b7
+		prev = xtables_targets;
b144b7
+	} else {
b144b7
 		/* Append it */
b144b7
-		i = &pos->next;
b144b7
-		pos = pos->next;
b144b7
+		i = &prev->next;
b144b7
+		prev = prev->next;
b144b7
 	}
b144b7
 
b144b7
-	me->next = pos;
b144b7
+	me->next = prev;
b144b7
 	*i = me;
b144b7
 
b144b7
 	me->t = NULL;
b144b7
-- 
b144b7
2.28.0
b144b7