Blame SOURCES/0035-libxtables-Make-sure-extensions-register-in-revision.patch

87db66
From e6eede725bbd395fb8b385aec4d0a32ce99e842c Mon Sep 17 00:00:00 2001
87db66
From: Phil Sutter <phil@nwl.cc>
87db66
Date: Mon, 21 Sep 2020 13:42:06 +0200
87db66
Subject: [PATCH] libxtables: Make sure extensions register in revision order
87db66
87db66
Insert extensions into pending lists in ordered fashion: Group by
87db66
extension name (and, for matches, family) and order groups by descending
87db66
revision number.
87db66
87db66
This allows to simplify the later full registration considerably. Since
87db66
that involves kernel compatibility checks, the extra cycles here pay off
87db66
eventually.
87db66
87db66
Signed-off-by: Phil Sutter <phil@nwl.cc>
87db66
(cherry picked from commit b3ac87038f4e45141831d9ab485a2f627daba3f1)
87db66
Signed-off-by: Phil Sutter <psutter@redhat.com>
87db66
---
87db66
 libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++-----
87db66
 1 file changed, 64 insertions(+), 7 deletions(-)
87db66
87db66
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
87db66
index 777c2b08e9896..13139d7f8ad62 100644
87db66
--- a/libxtables/xtables.c
87db66
+++ b/libxtables/xtables.c
87db66
@@ -902,8 +902,14 @@ static void xtables_check_options(const char *name, const struct option *opt)
87db66
 		}
87db66
 }
87db66
 
87db66
+static int xtables_match_prefer(const struct xtables_match *a,
87db66
+				const struct xtables_match *b);
87db66
+
87db66
 void xtables_register_match(struct xtables_match *me)
87db66
 {
87db66
+	struct xtables_match **pos;
87db66
+	bool seen_myself = false;
87db66
+
87db66
 	if (me->next) {
87db66
 		fprintf(stderr, "%s: match \"%s\" already registered\n",
87db66
 			xt_params->program_name, me->name);
87db66
@@ -955,10 +961,34 @@ void xtables_register_match(struct xtables_match *me)
87db66
 	if (me->extra_opts != NULL)
87db66
 		xtables_check_options(me->name, me->extra_opts);
87db66
 
87db66
-
87db66
-	/* place on linked list of matches pending full registration */
87db66
-	me->next = xtables_pending_matches;
87db66
-	xtables_pending_matches = me;
87db66
+	/* order into linked list of matches pending full registration */
87db66
+	for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
87db66
+		/* group by name and family */
87db66
+		if (strcmp(me->name, (*pos)->name) ||
87db66
+		    me->family != (*pos)->family) {
87db66
+			if (seen_myself)
87db66
+				break; /* end of own group, append to it */
87db66
+			continue;
87db66
+		}
87db66
+		/* found own group */
87db66
+		seen_myself = true;
87db66
+		if (xtables_match_prefer(me, *pos) >= 0)
87db66
+			break; /* put preferred items first in group */
87db66
+	}
87db66
+	/* if own group was not found, prepend item */
87db66
+	if (!*pos && !seen_myself)
87db66
+		pos = &xtables_pending_matches;
87db66
+
87db66
+	me->next = *pos;
87db66
+	*pos = me;
87db66
+#ifdef DEBUG
87db66
+	printf("%s: inserted match %s (family %d, revision %d):\n",
87db66
+			__func__, me->name, me->family, me->revision);
87db66
+	for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
87db66
+		printf("%s:\tmatch %s (family %d, revision %d)\n", __func__,
87db66
+		       (*pos)->name, (*pos)->family, (*pos)->revision);
87db66
+	}
87db66
+#endif
87db66
 }
87db66
 
87db66
 /**
87db66
@@ -1097,6 +1127,9 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n)
87db66
 
87db66
 void xtables_register_target(struct xtables_target *me)
87db66
 {
87db66
+	struct xtables_target **pos;
87db66
+	bool seen_myself = false;
87db66
+
87db66
 	if (me->next) {
87db66
 		fprintf(stderr, "%s: target \"%s\" already registered\n",
87db66
 			xt_params->program_name, me->name);
87db66
@@ -1152,9 +1185,33 @@ void xtables_register_target(struct xtables_target *me)
87db66
 	if (me->family != afinfo->family && me->family != AF_UNSPEC)
87db66
 		return;
87db66
 
87db66
-	/* place on linked list of targets pending full registration */
87db66
-	me->next = xtables_pending_targets;
87db66
-	xtables_pending_targets = me;
87db66
+	/* order into linked list of targets pending full registration */
87db66
+	for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
87db66
+		/* group by name */
87db66
+		if (!extension_cmp(me->name, (*pos)->name, (*pos)->family)) {
87db66
+			if (seen_myself)
87db66
+				break; /* end of own group, append to it */
87db66
+			continue;
87db66
+		}
87db66
+		/* found own group */
87db66
+		seen_myself = true;
87db66
+		if (xtables_target_prefer(me, *pos) >= 0)
87db66
+			break; /* put preferred items first in group */
87db66
+	}
87db66
+	/* if own group was not found, prepend item */
87db66
+	if (!*pos && !seen_myself)
87db66
+		pos = &xtables_pending_targets;
87db66
+
87db66
+	me->next = *pos;
87db66
+	*pos = me;
87db66
+#ifdef DEBUG
87db66
+	printf("%s: inserted target %s (family %d, revision %d):\n",
87db66
+			__func__, me->name, me->family, me->revision);
87db66
+	for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
87db66
+		printf("%s:\ttarget %s (family %d, revision %d)\n", __func__,
87db66
+		       (*pos)->name, (*pos)->family, (*pos)->revision);
87db66
+	}
87db66
+#endif
87db66
 }
87db66
 
87db66
 static bool xtables_fully_register_pending_target(struct xtables_target *me)
87db66
-- 
87db66
2.28.0
87db66