|
|
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 |
|