From a0f631a0d2a90469affad31ea76c2f6e2c1541e9 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Jan 28 2021 16:14:57 +0000 Subject: Apply patch 0035-libxtables-Make-sure-extensions-register-in-revision.patch patch_name: 0035-libxtables-Make-sure-extensions-register-in-revision.patch present_in_specfile: true location_in_specfile: 35 --- diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 777c2b0..13139d7 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -902,8 +902,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); @@ -955,10 +961,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 } /** @@ -1097,6 +1127,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); @@ -1152,9 +1185,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)