You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.2 KiB
128 lines
4.2 KiB
From 4616623e18cb1868960194cd7f695969c594a35b Mon Sep 17 00:00:00 2001
|
|
From: Phil Sutter <phil@nwl.cc>
|
|
Date: Mon, 21 Sep 2020 13:42:06 +0200
|
|
Subject: [PATCH] libxtables: Make sure extensions register in revision order
|
|
|
|
Insert extensions into pending lists in ordered fashion: Group by
|
|
extension name (and, for matches, family) and order groups by descending
|
|
revision number.
|
|
|
|
This allows to simplify the later full registration considerably. Since
|
|
that involves kernel compatibility checks, the extra cycles here pay off
|
|
eventually.
|
|
|
|
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
(cherry picked from commit b3ac87038f4e45141831d9ab485a2f627daba3f1)
|
|
---
|
|
libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++-----
|
|
1 file changed, 64 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
|
index 8907ba2069be7..de52e3e2bbc15 100644
|
|
--- a/libxtables/xtables.c
|
|
+++ b/libxtables/xtables.c
|
|
@@ -948,8 +948,14 @@ static void xtables_check_options(const char *name, const struct option *opt)
|
|
}
|
|
}
|
|
|
|
+static int xtables_match_prefer(const struct xtables_match *a,
|
|
+ const struct xtables_match *b);
|
|
+
|
|
void xtables_register_match(struct xtables_match *me)
|
|
{
|
|
+ struct xtables_match **pos;
|
|
+ bool seen_myself = false;
|
|
+
|
|
if (me->next) {
|
|
fprintf(stderr, "%s: match \"%s\" already registered\n",
|
|
xt_params->program_name, me->name);
|
|
@@ -1001,10 +1007,34 @@ void xtables_register_match(struct xtables_match *me)
|
|
if (me->extra_opts != NULL)
|
|
xtables_check_options(me->name, me->extra_opts);
|
|
|
|
-
|
|
- /* place on linked list of matches pending full registration */
|
|
- me->next = xtables_pending_matches;
|
|
- xtables_pending_matches = me;
|
|
+ /* order into linked list of matches pending full registration */
|
|
+ for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
|
|
+ /* group by name and family */
|
|
+ if (strcmp(me->name, (*pos)->name) ||
|
|
+ me->family != (*pos)->family) {
|
|
+ if (seen_myself)
|
|
+ break; /* end of own group, append to it */
|
|
+ continue;
|
|
+ }
|
|
+ /* found own group */
|
|
+ seen_myself = true;
|
|
+ if (xtables_match_prefer(me, *pos) >= 0)
|
|
+ break; /* put preferred items first in group */
|
|
+ }
|
|
+ /* if own group was not found, prepend item */
|
|
+ if (!*pos && !seen_myself)
|
|
+ pos = &xtables_pending_matches;
|
|
+
|
|
+ me->next = *pos;
|
|
+ *pos = me;
|
|
+#ifdef DEBUG
|
|
+ printf("%s: inserted match %s (family %d, revision %d):\n",
|
|
+ __func__, me->name, me->family, me->revision);
|
|
+ for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) {
|
|
+ printf("%s:\tmatch %s (family %d, revision %d)\n", __func__,
|
|
+ (*pos)->name, (*pos)->family, (*pos)->revision);
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
/**
|
|
@@ -1143,6 +1173,9 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n)
|
|
|
|
void xtables_register_target(struct xtables_target *me)
|
|
{
|
|
+ struct xtables_target **pos;
|
|
+ bool seen_myself = false;
|
|
+
|
|
if (me->next) {
|
|
fprintf(stderr, "%s: target \"%s\" already registered\n",
|
|
xt_params->program_name, me->name);
|
|
@@ -1198,9 +1231,33 @@ void xtables_register_target(struct xtables_target *me)
|
|
if (me->family != afinfo->family && me->family != AF_UNSPEC)
|
|
return;
|
|
|
|
- /* place on linked list of targets pending full registration */
|
|
- me->next = xtables_pending_targets;
|
|
- xtables_pending_targets = me;
|
|
+ /* order into linked list of targets pending full registration */
|
|
+ for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
|
|
+ /* group by name */
|
|
+ if (!extension_cmp(me->name, (*pos)->name, (*pos)->family)) {
|
|
+ if (seen_myself)
|
|
+ break; /* end of own group, append to it */
|
|
+ continue;
|
|
+ }
|
|
+ /* found own group */
|
|
+ seen_myself = true;
|
|
+ if (xtables_target_prefer(me, *pos) >= 0)
|
|
+ break; /* put preferred items first in group */
|
|
+ }
|
|
+ /* if own group was not found, prepend item */
|
|
+ if (!*pos && !seen_myself)
|
|
+ pos = &xtables_pending_targets;
|
|
+
|
|
+ me->next = *pos;
|
|
+ *pos = me;
|
|
+#ifdef DEBUG
|
|
+ printf("%s: inserted target %s (family %d, revision %d):\n",
|
|
+ __func__, me->name, me->family, me->revision);
|
|
+ for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) {
|
|
+ printf("%s:\ttarget %s (family %d, revision %d)\n", __func__,
|
|
+ (*pos)->name, (*pos)->family, (*pos)->revision);
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
static bool xtables_fully_register_pending_target(struct xtables_target *me)
|
|
--
|
|
2.40.0
|
|
|