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

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