import iptables-1.8.4-17.el8
This commit is contained in:
		
							parent
							
								
									d24e02cc5e
								
							
						
					
					
						commit
						c3f048e40a
					
				| @ -1,4 +1,4 @@ | ||||
| From b38c6a7e467380f7938a125cfd2f3a2902a4dad4 Mon Sep 17 00:00:00 2001 | ||||
| From 2c183a2457d8640aaee3a98fc8fea70bf64d46f2 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Sat, 29 Feb 2020 02:08:26 +0100 | ||||
| Subject: [PATCH] nft: cache: Make nft_rebuild_cache() respect fake cache | ||||
| @ -1,4 +1,4 @@ | ||||
| From 53cc2b467618f35cadd337066ceae2fd6bcb5fe1 Mon Sep 17 00:00:00 2001 | ||||
| From 74a62264d4615ae7f76454e7ca406c46a62c7999 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Mon, 28 Sep 2020 18:57:18 +0200 | ||||
| Subject: [PATCH] nft: Fix for broken address mask match detection | ||||
| @ -1,4 +1,4 @@ | ||||
| From 0fbb274e7ab043cf7d967852dbf0d4e6e4ea6449 Mon Sep 17 00:00:00 2001 | ||||
| From 87a2128fcfd4c5b0847a8c611652ade8c54d8185 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Fri, 2 Oct 2020 09:44:38 +0200 | ||||
| Subject: [PATCH] nft: Optimize class-based IP prefix matches | ||||
| @ -1,4 +1,4 @@ | ||||
| From 3e25174a3e3f4757b471bb238d50f213baac50b9 Mon Sep 17 00:00:00 2001 | ||||
| From 03a484b63c5a61678555bcaca68fa36dc81468c1 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Fri, 30 Oct 2020 14:08:33 +0100 | ||||
| Subject: [PATCH] ebtables: Optimize masked MAC address matches | ||||
| @ -1,4 +1,4 @@ | ||||
| From 485916fc4cda691818bad9e0c63d6166eb8cadb8 Mon Sep 17 00:00:00 2001 | ||||
| From 6aef90100bebe2b00d4edffe59fb9c43643816de Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Tue, 10 Nov 2020 14:50:46 +0100 | ||||
| Subject: [PATCH] tests/shell: Add test for bitwise avoidance fixes | ||||
| @ -0,0 +1,128 @@ | ||||
| From e6eede725bbd395fb8b385aec4d0a32ce99e842c 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) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++----- | ||||
|  1 file changed, 64 insertions(+), 7 deletions(-) | ||||
| 
 | ||||
| diff --git a/libxtables/xtables.c b/libxtables/xtables.c
 | ||||
| index 777c2b08e9896..13139d7f8ad62 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) | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,241 @@ | ||||
| From 1a842fb1cfb3b36f3081aee37c5fdd4a897d77d5 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Fri, 18 Sep 2020 18:48:14 +0200 | ||||
| Subject: [PATCH] libxtables: Simplify pending extension registration | ||||
| 
 | ||||
| Assuming that pending extensions are sorted by first name and family, | ||||
| then descending revision, the decision where to insert a newly | ||||
| registered extension may be simplified by memorizing the previous | ||||
| registration (which obviously is of same name and family and higher | ||||
| revision). | ||||
| 
 | ||||
| As a side-effect, fix for unsupported old extension revisions lingering | ||||
| in pending extension list forever and being retried with every use of | ||||
| the given extension. Any revision being rejected by the kernel may | ||||
| safely be dropped iff a previous (read: higher) revision was accepted | ||||
| already. | ||||
| 
 | ||||
| Yet another side-effect of this change is the removal of an unwanted | ||||
| recursion by xtables_fully_register_pending_*() into itself via | ||||
| xtables_find_*(). | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| (cherry picked from commit a1eaaceb0460b338294e40bdd5bc5186320a478c) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  libxtables/xtables.c | 128 +++++++++++-------------------------------- | ||||
|  1 file changed, 33 insertions(+), 95 deletions(-) | ||||
| 
 | ||||
| diff --git a/libxtables/xtables.c b/libxtables/xtables.c
 | ||||
| index 13139d7f8ad62..409128333e0e6 100644
 | ||||
| --- a/libxtables/xtables.c
 | ||||
| +++ b/libxtables/xtables.c
 | ||||
| @@ -203,8 +203,10 @@ struct xtables_match *xtables_matches;
 | ||||
|  struct xtables_target *xtables_targets; | ||||
|   | ||||
|  /* Fully register a match/target which was previously partially registered. */ | ||||
| -static bool xtables_fully_register_pending_match(struct xtables_match *me);
 | ||||
| -static bool xtables_fully_register_pending_target(struct xtables_target *me);
 | ||||
| +static bool xtables_fully_register_pending_match(struct xtables_match *me,
 | ||||
| +						 struct xtables_match *prev);
 | ||||
| +static bool xtables_fully_register_pending_target(struct xtables_target *me,
 | ||||
| +						  struct xtables_target *prev);
 | ||||
|   | ||||
|  void xtables_init(void) | ||||
|  { | ||||
| @@ -616,6 +618,7 @@ struct xtables_match *
 | ||||
|  xtables_find_match(const char *name, enum xtables_tryload tryload, | ||||
|  		   struct xtables_rule_match **matches) | ||||
|  { | ||||
| +	struct xtables_match *prev = NULL;
 | ||||
|  	struct xtables_match **dptr; | ||||
|  	struct xtables_match *ptr; | ||||
|  	const char *icmp6 = "icmp6"; | ||||
| @@ -637,8 +640,12 @@ xtables_find_match(const char *name, enum xtables_tryload tryload,
 | ||||
|  		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { | ||||
|  			ptr = *dptr; | ||||
|  			*dptr = (*dptr)->next; | ||||
| -			if (xtables_fully_register_pending_match(ptr))
 | ||||
| +			if (xtables_fully_register_pending_match(ptr, prev)) {
 | ||||
| +				prev = ptr;
 | ||||
|  				continue; | ||||
| +			} else if (prev) {
 | ||||
| +				continue;
 | ||||
| +			}
 | ||||
|  			*dptr = ptr; | ||||
|  		} | ||||
|  		dptr = &((*dptr)->next); | ||||
| @@ -732,6 +739,7 @@ xtables_find_match_revision(const char *name, enum xtables_tryload tryload,
 | ||||
|  struct xtables_target * | ||||
|  xtables_find_target(const char *name, enum xtables_tryload tryload) | ||||
|  { | ||||
| +	struct xtables_target *prev = NULL;
 | ||||
|  	struct xtables_target **dptr; | ||||
|  	struct xtables_target *ptr; | ||||
|   | ||||
| @@ -748,8 +756,12 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
 | ||||
|  		if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { | ||||
|  			ptr = *dptr; | ||||
|  			*dptr = (*dptr)->next; | ||||
| -			if (xtables_fully_register_pending_target(ptr))
 | ||||
| +			if (xtables_fully_register_pending_target(ptr, prev)) {
 | ||||
| +				prev = ptr;
 | ||||
|  				continue; | ||||
| +			} else if (prev) {
 | ||||
| +				continue;
 | ||||
| +			}
 | ||||
|  			*dptr = ptr; | ||||
|  		} | ||||
|  		dptr = &((*dptr)->next); | ||||
| @@ -1052,64 +1064,27 @@ static int xtables_target_prefer(const struct xtables_target *a,
 | ||||
|  				 b->revision, b->family); | ||||
|  } | ||||
|   | ||||
| -static bool xtables_fully_register_pending_match(struct xtables_match *me)
 | ||||
| +static bool xtables_fully_register_pending_match(struct xtables_match *me,
 | ||||
| +						 struct xtables_match *prev)
 | ||||
|  { | ||||
| -	struct xtables_match **i, *old, *pos = NULL;
 | ||||
| +	struct xtables_match **i;
 | ||||
|  	const char *rn; | ||||
| -	int compare;
 | ||||
|   | ||||
|  	/* See if new match can be used. */ | ||||
|  	rn = (me->real_name != NULL) ? me->real_name : me->name; | ||||
|  	if (!compatible_match_revision(rn, me->revision)) | ||||
|  		return false; | ||||
|   | ||||
| -	old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL);
 | ||||
| -	while (old) {
 | ||||
| -		compare = xtables_match_prefer(old, me);
 | ||||
| -		if (compare == 0) {
 | ||||
| -			fprintf(stderr,
 | ||||
| -				"%s: match `%s' already registered.\n",
 | ||||
| -				xt_params->program_name, me->name);
 | ||||
| -			exit(1);
 | ||||
| -		}
 | ||||
| -
 | ||||
| -		/* Now we have two (or more) options, check compatibility. */
 | ||||
| -		rn = (old->real_name != NULL) ? old->real_name : old->name;
 | ||||
| -		if (compare > 0) {
 | ||||
| -			/* Kernel tells old isn't compatible anymore??? */
 | ||||
| -			if (!compatible_match_revision(rn, old->revision)) {
 | ||||
| -				/* Delete old one. */
 | ||||
| -				for (i = &xtables_matches; *i != old;)
 | ||||
| -				     i = &(*i)->next;
 | ||||
| -				*i = old->next;
 | ||||
| -			}
 | ||||
| -			pos = old;
 | ||||
| -			old = old->next;
 | ||||
| -			if (!old)
 | ||||
| -				break;
 | ||||
| -			if (!extension_cmp(me->name, old->name, old->family))
 | ||||
| -				break;
 | ||||
| -			continue;
 | ||||
| -		}
 | ||||
| -
 | ||||
| -		/* Found right old */
 | ||||
| -		pos = old;
 | ||||
| -		break;
 | ||||
| -	}
 | ||||
| -
 | ||||
| -	if (!pos) {
 | ||||
| +	if (!prev) {
 | ||||
|  		/* Append to list. */ | ||||
|  		for (i = &xtables_matches; *i; i = &(*i)->next); | ||||
| -	} else if (compare < 0) {
 | ||||
| -		/* Prepend it */
 | ||||
| -		for (i = &xtables_matches; *i != pos; i = &(*i)->next);
 | ||||
| -	} else if (compare > 0) {
 | ||||
| +	} else {
 | ||||
|  		/* Append it */ | ||||
| -		i = &pos->next;
 | ||||
| -		pos = pos->next;
 | ||||
| +		i = &prev->next;
 | ||||
| +		prev = prev->next;
 | ||||
|  	} | ||||
|   | ||||
| -	me->next = pos;
 | ||||
| +	me->next = prev;
 | ||||
|  	*i = me; | ||||
|   | ||||
|  	me->m = NULL; | ||||
| @@ -1214,11 +1189,11 @@ void xtables_register_target(struct xtables_target *me)
 | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| -static bool xtables_fully_register_pending_target(struct xtables_target *me)
 | ||||
| +static bool xtables_fully_register_pending_target(struct xtables_target *me,
 | ||||
| +						  struct xtables_target *prev)
 | ||||
|  { | ||||
| -	struct xtables_target **i, *old, *pos = NULL;
 | ||||
| +	struct xtables_target **i;
 | ||||
|  	const char *rn; | ||||
| -	int compare;
 | ||||
|   | ||||
|  	if (strcmp(me->name, "standard") != 0) { | ||||
|  		/* See if new target can be used. */ | ||||
| @@ -1227,54 +1202,17 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me)
 | ||||
|  			return false; | ||||
|  	} | ||||
|   | ||||
| -	old = xtables_find_target(me->name, XTF_DURING_LOAD);
 | ||||
| -	while (old) {
 | ||||
| -		compare = xtables_target_prefer(old, me);
 | ||||
| -		if (compare == 0) {
 | ||||
| -			fprintf(stderr,
 | ||||
| -				"%s: target `%s' already registered.\n",
 | ||||
| -				xt_params->program_name, me->name);
 | ||||
| -			exit(1);
 | ||||
| -		}
 | ||||
| -
 | ||||
| -		/* Now we have two (or more) options, check compatibility. */
 | ||||
| -		rn = (old->real_name != NULL) ? old->real_name : old->name;
 | ||||
| -		if (compare > 0) {
 | ||||
| -			/* Kernel tells old isn't compatible anymore??? */
 | ||||
| -			if (!compatible_target_revision(rn, old->revision)) {
 | ||||
| -				/* Delete old one. */
 | ||||
| -				for (i = &xtables_targets; *i != old;)
 | ||||
| -				     i = &(*i)->next;
 | ||||
| -				*i = old->next;
 | ||||
| -			}
 | ||||
| -			pos = old;
 | ||||
| -			old = old->next;
 | ||||
| -			if (!old)
 | ||||
| -				break;
 | ||||
| -			if (!extension_cmp(me->name, old->name, old->family))
 | ||||
| -				break;
 | ||||
| -			continue;
 | ||||
| -		}
 | ||||
| -
 | ||||
| -		/* Found right old */
 | ||||
| -		pos = old;
 | ||||
| -		break;
 | ||||
| -	}
 | ||||
| -
 | ||||
| -	if (!pos) {
 | ||||
| +	if (!prev) {
 | ||||
|  		/* Prepend to list. */ | ||||
|  		i = &xtables_targets; | ||||
| -		pos = xtables_targets;
 | ||||
| -	} else if (compare < 0) {
 | ||||
| -		/* Prepend it */
 | ||||
| -		for (i = &xtables_targets; *i != pos; i = &(*i)->next);
 | ||||
| -	} else if (compare > 0) {
 | ||||
| +		prev = xtables_targets;
 | ||||
| +	} else {
 | ||||
|  		/* Append it */ | ||||
| -		i = &pos->next;
 | ||||
| -		pos = pos->next;
 | ||||
| +		i = &prev->next;
 | ||||
| +		prev = prev->next;
 | ||||
|  	} | ||||
|   | ||||
| -	me->next = pos;
 | ||||
| +	me->next = prev;
 | ||||
|  	*i = me; | ||||
|   | ||||
|  	me->t = NULL; | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,52 @@ | ||||
| From cfcafd3638cdc06a8b4a1d267e58b5ad1e35922c Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Tue, 22 Sep 2020 20:01:15 +0200 | ||||
| Subject: [PATCH] libxtables: Register multiple extensions in ascending order | ||||
| 
 | ||||
| The newly introduced ordered insert algorithm in | ||||
| xtables_register_{match,target}() works best if extensions of same name | ||||
| are passed in ascending revisions. Since this is the case in about all | ||||
| extensions' arrays, iterate over them from beginning to end. | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| (cherry picked from commit b5f1a3beac1d1f2b96c8be8ebec450f5ea758090) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  libxtables/xtables.c | 14 ++++++++------ | ||||
|  1 file changed, 8 insertions(+), 6 deletions(-) | ||||
| 
 | ||||
| diff --git a/libxtables/xtables.c b/libxtables/xtables.c
 | ||||
| index 409128333e0e6..28ffffedd8147 100644
 | ||||
| --- a/libxtables/xtables.c
 | ||||
| +++ b/libxtables/xtables.c
 | ||||
| @@ -1095,9 +1095,10 @@ static bool xtables_fully_register_pending_match(struct xtables_match *me,
 | ||||
|   | ||||
|  void xtables_register_matches(struct xtables_match *match, unsigned int n) | ||||
|  { | ||||
| -	do {
 | ||||
| -		xtables_register_match(&match[--n]);
 | ||||
| -	} while (n > 0);
 | ||||
| +	int i;
 | ||||
| +
 | ||||
| +	for (i = 0; i < n; i++)
 | ||||
| +		xtables_register_match(&match[i]);
 | ||||
|  } | ||||
|   | ||||
|  void xtables_register_target(struct xtables_target *me) | ||||
| @@ -1223,9 +1224,10 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me,
 | ||||
|   | ||||
|  void xtables_register_targets(struct xtables_target *target, unsigned int n) | ||||
|  { | ||||
| -	do {
 | ||||
| -		xtables_register_target(&target[--n]);
 | ||||
| -	} while (n > 0);
 | ||||
| +	int i;
 | ||||
| +
 | ||||
| +	for (i = 0; i < n; i++)
 | ||||
| +		xtables_register_target(&target[i]);
 | ||||
|  } | ||||
|   | ||||
|  /* receives a list of xtables_rule_match, release them */ | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,53 @@ | ||||
| From f5185f4efad409fc7ec4ae05267b642ee4103a6c Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Fri, 4 Dec 2020 17:44:51 +0100 | ||||
| Subject: [PATCH] tests/shell: Test for fixed extension registration | ||||
| 
 | ||||
| Use strace to look at iptables-restore behaviour with typically | ||||
| problematic input (conntrack revision 0 is no longer supported by | ||||
| current kernels) to make sure the fix in commit a1eaaceb0460b | ||||
| ("libxtables: Simplify pending extension registration") is still | ||||
| effective. | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| (cherry picked from commit 93d0c97e8b6713f51ba679e01a1338d4f9076e7c) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  .../0017-pointless-compat-checks_0            | 25 +++++++++++++++++++ | ||||
|  1 file changed, 25 insertions(+) | ||||
|  create mode 100755 iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 | ||||
| 
 | ||||
| diff --git a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
 | ||||
| new file mode 100755 | ||||
| index 0000000000000..cf73de32df409
 | ||||
| --- /dev/null
 | ||||
| +++ b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0
 | ||||
| @@ -0,0 +1,25 @@
 | ||||
| +#!/bin/bash
 | ||||
| +
 | ||||
| +# A bug in extension registration would leave unsupported older extension
 | ||||
| +# revisions in pending list and get compatibility checked again for each rule
 | ||||
| +# using them. With SELinux enabled, the resulting socket() call per rule leads
 | ||||
| +# to significant slowdown (~50% performance in worst cases).
 | ||||
| +
 | ||||
| +set -e
 | ||||
| +
 | ||||
| +strace --version >/dev/null || { echo "skip for missing strace"; exit 0; }
 | ||||
| +
 | ||||
| +RULESET="$(
 | ||||
| +	echo "*filter"
 | ||||
| +	for ((i = 0; i < 100; i++)); do
 | ||||
| +		echo "-A FORWARD -m conntrack --ctstate NEW"
 | ||||
| +	done
 | ||||
| +	echo "COMMIT"
 | ||||
| +)"
 | ||||
| +
 | ||||
| +cmd="$XT_MULTI iptables-restore"
 | ||||
| +socketcount=$(strace -esocket $cmd <<< "$RULESET" 2>&1 | wc -l)
 | ||||
| +
 | ||||
| +# unpatched iptables-restore would open 111 sockets,
 | ||||
| +# patched only 12 but keep a certain margin for future changes
 | ||||
| +[[ $socketcount -lt 20 ]]
 | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,52 @@ | ||||
| From 6adcdca2aaf8cba6ee452c88f41ad8695bebdcfc Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Tue, 6 Oct 2020 19:07:19 +0200 | ||||
| Subject: [PATCH] extensions: libipt_icmp: Fix translation of type 'any' | ||||
| 
 | ||||
| By itself, '-m icmp --icmp-type any' is a noop, it matches any icmp | ||||
| types. Yet nft_ipv4_xlate() does not emit an 'ip protocol' match if | ||||
| there's an extension with same name present in the rule. Luckily, legacy | ||||
| iptables demands icmp match to be prepended by '-p icmp', so we can | ||||
| assume this is present and just emit the 'ip protocol' match from icmp | ||||
| xlate callback. | ||||
| 
 | ||||
| Fixes: aa158ca0fda65 ("extensions: libipt_icmp: Add translation to nft") | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| Reviewed-by: Florian Westphal <fw@strlen.de> | ||||
| (cherry picked from commit ad4b17b98bbedf93d2182a4dc9a37e9cf3adfe1b) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  extensions/libipt_icmp.c      | 5 +++++ | ||||
|  extensions/libipt_icmp.txlate | 3 +++ | ||||
|  2 files changed, 8 insertions(+) | ||||
| 
 | ||||
| diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c
 | ||||
| index e76257c54708c..e5e236613f39f 100644
 | ||||
| --- a/extensions/libipt_icmp.c
 | ||||
| +++ b/extensions/libipt_icmp.c
 | ||||
| @@ -256,6 +256,11 @@ static int icmp_xlate(struct xt_xlate *xl,
 | ||||
|  		if (!type_xlate_print(xl, info->type, info->code[0], | ||||
|  				      info->code[1])) | ||||
|  			return 0; | ||||
| +	} else {
 | ||||
| +		/* '-m icmp --icmp-type any' is a noop by itself,
 | ||||
| +		 * but it eats a (mandatory) previous '-p icmp' so
 | ||||
| +		 * emit it here */
 | ||||
| +		xt_xlate_add(xl, "ip protocol icmp");
 | ||||
|  	} | ||||
|  	return 1; | ||||
|  } | ||||
| diff --git a/extensions/libipt_icmp.txlate b/extensions/libipt_icmp.txlate
 | ||||
| index 434f8cc4eb1ae..a2aec8e26df75 100644
 | ||||
| --- a/extensions/libipt_icmp.txlate
 | ||||
| +++ b/extensions/libipt_icmp.txlate
 | ||||
| @@ -6,3 +6,6 @@ nft add rule ip filter INPUT icmp type destination-unreachable counter accept
 | ||||
|   | ||||
|  iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT | ||||
|  nft add rule ip filter INPUT icmp type != destination-unreachable counter accept | ||||
| +
 | ||||
| +iptables-translate -t filter -A INPUT -m icmp --icmp-type any -j ACCEPT
 | ||||
| +nft add rule ip filter INPUT ip protocol icmp counter accept
 | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,66 @@ | ||||
| From 1695f552d3947299e54978bcd5bc1cdc3a5c14f7 Mon Sep 17 00:00:00 2001 | ||||
| From: Pablo Neira Ayuso <pablo@netfilter.org> | ||||
| Date: Wed, 15 Apr 2020 18:16:41 +0200 | ||||
| Subject: [PATCH] extensions: libxt_CT: add translation for NOTRACK | ||||
| 
 | ||||
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||||
| (cherry picked from commit f3d4a3ddbcfca15a00dd9758f481420038f6de10) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  extensions/libxt_CT.c           | 16 ++++++++++++++++ | ||||
|  extensions/libxt_NOTRACK.txlate |  2 ++ | ||||
|  2 files changed, 18 insertions(+) | ||||
|  create mode 100644 extensions/libxt_NOTRACK.txlate | ||||
| 
 | ||||
| diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
 | ||||
| index 371b21766c56c..fbbbe2660e9fc 100644
 | ||||
| --- a/extensions/libxt_CT.c
 | ||||
| +++ b/extensions/libxt_CT.c
 | ||||
| @@ -348,6 +348,20 @@ static void notrack_ct2_tg_init(struct xt_entry_target *target)
 | ||||
|  	info->flags = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS; | ||||
|  } | ||||
|   | ||||
| +static int xlate_ct1_tg(struct xt_xlate *xl,
 | ||||
| +			const struct xt_xlate_tg_params *params)
 | ||||
| +{
 | ||||
| +	struct xt_ct_target_info_v1 *info =
 | ||||
| +		(struct xt_ct_target_info_v1 *)params->target->data;
 | ||||
| +
 | ||||
| +	if (info->flags & XT_CT_NOTRACK)
 | ||||
| +		xt_xlate_add(xl, "notrack");
 | ||||
| +	else
 | ||||
| +		return 0;
 | ||||
| +
 | ||||
| +	return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
|  static struct xtables_target ct_target_reg[] = { | ||||
|  	{ | ||||
|  		.family		= NFPROTO_UNSPEC, | ||||
| @@ -387,6 +401,7 @@ static struct xtables_target ct_target_reg[] = {
 | ||||
|  		.alias		= ct_print_name_alias, | ||||
|  		.x6_parse	= ct_parse_v1, | ||||
|  		.x6_options	= ct_opts_v1, | ||||
| +		.xlate		= xlate_ct1_tg,
 | ||||
|  	}, | ||||
|  	{ | ||||
|  		.family        = NFPROTO_UNSPEC, | ||||
| @@ -418,6 +433,7 @@ static struct xtables_target ct_target_reg[] = {
 | ||||
|  		.size          = XT_ALIGN(sizeof(struct xt_ct_target_info_v1)), | ||||
|  		.userspacesize = offsetof(struct xt_ct_target_info_v1, ct), | ||||
|  		.init          = notrack_ct2_tg_init, | ||||
| +		.xlate	       = xlate_ct1_tg,
 | ||||
|  	}, | ||||
|  	{ | ||||
|  		.family        = NFPROTO_UNSPEC, | ||||
| diff --git a/extensions/libxt_NOTRACK.txlate b/extensions/libxt_NOTRACK.txlate
 | ||||
| new file mode 100644 | ||||
| index 0000000000000..9d35619d3dbdd
 | ||||
| --- /dev/null
 | ||||
| +++ b/extensions/libxt_NOTRACK.txlate
 | ||||
| @@ -0,0 +1,2 @@
 | ||||
| +iptables-translate -A PREROUTING -t raw -j NOTRACK
 | ||||
| +nft add rule ip raw PREROUTING counter notrack
 | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,45 @@ | ||||
| From 6d8a390bd13bac294ff9de225a49fe9e4de2d6e5 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Fri, 7 Aug 2020 13:48:28 +0200 | ||||
| Subject: [PATCH] nft: Fix command name in ip6tables error message | ||||
| 
 | ||||
| Upon errors, ip6tables-nft would prefix its error messages with | ||||
| 'iptables:' instead of 'ip6tables:'. Turns out the command name was | ||||
| hard-coded, use 'progname' variable instead. | ||||
| While being at it, merge the two mostly identical fprintf() calls into | ||||
| one. | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||||
| (cherry picked from commit 3be40dcfb5af1438b6abdbda45a1e3b59c104e13) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  iptables/xtables-standalone.c | 12 ++++-------- | ||||
|  1 file changed, 4 insertions(+), 8 deletions(-) | ||||
| 
 | ||||
| diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c
 | ||||
| index 022d5dd44abbf..b5b7ccaf4e660 100644
 | ||||
| --- a/iptables/xtables-standalone.c
 | ||||
| +++ b/iptables/xtables-standalone.c
 | ||||
| @@ -74,14 +74,10 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
 | ||||
|  	nft_fini(&h); | ||||
|   | ||||
|  	if (!ret) { | ||||
| -		if (errno == EINVAL) {
 | ||||
| -			fprintf(stderr, "iptables: %s. "
 | ||||
| -					"Run `dmesg' for more information.\n",
 | ||||
| -				nft_strerror(errno));
 | ||||
| -		} else {
 | ||||
| -			fprintf(stderr, "iptables: %s.\n",
 | ||||
| -				nft_strerror(errno));
 | ||||
| -		}
 | ||||
| +		fprintf(stderr, "%s: %s.%s\n", progname, nft_strerror(errno),
 | ||||
| +			(errno == EINVAL ?
 | ||||
| +			 " Run `dmesg' for more information." : ""));
 | ||||
| +
 | ||||
|  		if (errno == EAGAIN) | ||||
|  			exit(RESOURCE_PROBLEM); | ||||
|  	} | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -0,0 +1,206 @@ | ||||
| From c5f07a7d718f812f916686926567adbac6c1b125 Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Thu, 6 Aug 2020 18:52:34 +0200 | ||||
| Subject: [PATCH] tests: shell: Merge and extend return codes test | ||||
| 
 | ||||
| Merge scripts for iptables and ip6tables, they were widely identical. | ||||
| Also extend the test by one check (removing a non-existent rule with | ||||
| valid chain and target) and quote the error messages where differences | ||||
| are deliberately ignored. | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||||
| (cherry picked from commit cd3e83d1b04fd2683f0fb06e496ee5be08a96b4f) | ||||
| 
 | ||||
| Conflicts: | ||||
| 	iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 | ||||
| 	iptables/tests/shell/testcases/iptables/0004-return-codes_0 | ||||
| -> Missing upstream commit a7f1e208cdf9c ("nft: split parsing from
 | ||||
|    netlink commands") which added a few tests to both files. | ||||
| 
 | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  .../testcases/ip6tables/0004-return-codes_0   |  38 ------- | ||||
|  .../testcases/iptables/0004-return-codes_0    | 104 ++++++++++-------- | ||||
|  2 files changed, 58 insertions(+), 84 deletions(-) | ||||
|  delete mode 100755 iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 | ||||
| 
 | ||||
| diff --git a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
 | ||||
| deleted file mode 100755 | ||||
| index f023b7915498e..0000000000000
 | ||||
| --- a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,38 +0,0 @@
 | ||||
| -#!/bin/sh
 | ||||
| -
 | ||||
| -# make sure error return codes are as expected useful cases
 | ||||
| -# (e.g. commands to check ruleset state)
 | ||||
| -
 | ||||
| -global_rc=0
 | ||||
| -
 | ||||
| -cmd() { # (rc, cmd, [args ...])
 | ||||
| -	rc_exp=$1; shift
 | ||||
| -
 | ||||
| -	$XT_MULTI "$@"
 | ||||
| -	rc=$?
 | ||||
| -
 | ||||
| -	[ $rc -eq $rc_exp ] || {
 | ||||
| -		echo "---> expected $rc_exp, got $rc for command '$@'"
 | ||||
| -		global_rc=1
 | ||||
| -	}
 | ||||
| -}
 | ||||
| -
 | ||||
| -# test chain creation
 | ||||
| -cmd 0 ip6tables -N foo
 | ||||
| -cmd 1 ip6tables -N foo
 | ||||
| -# iptables-nft allows this - bug or feature?
 | ||||
| -#cmd 2 ip6tables -N "invalid name"
 | ||||
| -
 | ||||
| -# test rule adding
 | ||||
| -cmd 0 ip6tables -A INPUT -j ACCEPT
 | ||||
| -cmd 1 ip6tables -A noexist -j ACCEPT
 | ||||
| -
 | ||||
| -# test rule checking
 | ||||
| -cmd 0 ip6tables -C INPUT -j ACCEPT
 | ||||
| -cmd 1 ip6tables -C FORWARD -j ACCEPT
 | ||||
| -cmd 1 ip6tables -C nonexist -j ACCEPT
 | ||||
| -cmd 2 ip6tables -C INPUT -j foobar
 | ||||
| -cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT
 | ||||
| -cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT
 | ||||
| -
 | ||||
| -exit $global_rc
 | ||||
| diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
 | ||||
| index ce02e0bcb128b..67f1698945753 100755
 | ||||
| --- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0
 | ||||
| +++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
 | ||||
| @@ -13,69 +13,81 @@ cmd() { # (rc, msg, cmd, [args ...])
 | ||||
|  		msg_exp="$1"; shift | ||||
|  	} | ||||
|   | ||||
| -	msg="$($XT_MULTI "$@" 2>&1 >/dev/null)"
 | ||||
| -	rc=$?
 | ||||
| +	for ipt in iptables ip6tables; do
 | ||||
| +		msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)"
 | ||||
| +		rc=$?
 | ||||
|   | ||||
| -	[ $rc -eq $rc_exp ] || {
 | ||||
| -		echo "---> expected return code $rc_exp, got $rc for command '$@'"
 | ||||
| -		global_rc=1
 | ||||
| -	}
 | ||||
| +		[ $rc -eq $rc_exp ] || {
 | ||||
| +			echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'"
 | ||||
| +			global_rc=1
 | ||||
| +		}
 | ||||
|   | ||||
| -	[ -n "$msg_exp" ] || return
 | ||||
| -	grep -q "$msg_exp" <<< $msg || {
 | ||||
| -		echo "---> expected error message '$msg_exp', got '$msg' for command '$@'"
 | ||||
| -		global_rc=1
 | ||||
| -	}
 | ||||
| +		[ -n "$msg_exp" ] || continue
 | ||||
| +		msg_exp_full="${ipt}$msg_exp"
 | ||||
| +		grep -q "$msg_exp_full" <<< $msg || {
 | ||||
| +			echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'"
 | ||||
| +			global_rc=1
 | ||||
| +		}
 | ||||
| +	done
 | ||||
|  } | ||||
|   | ||||
| -EEXIST_F="File exists."
 | ||||
| -EEXIST="Chain already exists."
 | ||||
| -ENOENT="No chain/target/match by that name."
 | ||||
| -E2BIG_I="Index of insertion too big."
 | ||||
| -E2BIG_D="Index of deletion too big."
 | ||||
| -E2BIG_R="Index of replacement too big."
 | ||||
| -EBADRULE="Bad rule (does a matching rule exist in that chain?)."
 | ||||
| -ENOTGT="Couldn't load target \`foobar':No such file or directory"
 | ||||
| -ENOMTH="Couldn't load match \`foobar':No such file or directory"
 | ||||
| -ENOTBL="can't initialize iptables table \`foobar': Table does not exist"
 | ||||
| +EEXIST_F=": File exists."
 | ||||
| +EEXIST=": Chain already exists."
 | ||||
| +ENOENT=": No chain/target/match by that name."
 | ||||
| +E2BIG_I=": Index of insertion too big."
 | ||||
| +E2BIG_D=": Index of deletion too big."
 | ||||
| +E2BIG_R=": Index of replacement too big."
 | ||||
| +EBADRULE=": Bad rule (does a matching rule exist in that chain?)."
 | ||||
| +#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory"
 | ||||
| +ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory"
 | ||||
| +ENOTBL=": can't initialize iptables table \`foobar': Table does not exist"
 | ||||
|   | ||||
|  # test chain creation | ||||
| -cmd 0 iptables -N foo
 | ||||
| -cmd 1 "$EEXIST" iptables -N foo
 | ||||
| +cmd 0 -N foo
 | ||||
| +cmd 1 "$EEXIST" -N foo
 | ||||
|  # iptables-nft allows this - bug or feature? | ||||
| -#cmd 2 iptables -N "invalid name"
 | ||||
| +#cmd 2 -N "invalid name"
 | ||||
|   | ||||
|  # test chain flushing/zeroing | ||||
| -cmd 0 iptables -F foo
 | ||||
| -cmd 0 iptables -Z foo
 | ||||
| -cmd 1 "$ENOENT" iptables -F bar
 | ||||
| -cmd 1 "$ENOENT" iptables -Z bar
 | ||||
| +cmd 0 -F foo
 | ||||
| +cmd 0 -Z foo
 | ||||
| +cmd 1 "$ENOENT" -F bar
 | ||||
| +cmd 1 "$ENOENT" -Z bar
 | ||||
|   | ||||
|  # test chain rename | ||||
| -cmd 0 iptables -E foo bar
 | ||||
| -cmd 1 "$EEXIST_F" iptables -E foo bar
 | ||||
| +cmd 0 -E foo bar
 | ||||
| +cmd 1 "$EEXIST_F" -E foo bar
 | ||||
|   | ||||
|  # test rule adding | ||||
| -cmd 0 iptables -A INPUT -j ACCEPT
 | ||||
| -cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT
 | ||||
| +cmd 0 -A INPUT -j ACCEPT
 | ||||
| +cmd 1 "$ENOENT" -A noexist -j ACCEPT
 | ||||
| +# next three differ:
 | ||||
| +# legacy: Couldn't load target `foobar':No such file or directory
 | ||||
| +# nft:    Chain 'foobar' does not exist
 | ||||
| +cmd 2 "" -I INPUT -j foobar
 | ||||
| +cmd 2 "" -R INPUT 1 -j foobar
 | ||||
| +cmd 2 "" -D INPUT -j foobar
 | ||||
| +cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT
 | ||||
|   | ||||
|  # test rulenum commands | ||||
| -cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT
 | ||||
| -cmd 1 "$E2BIG_D" iptables -D INPUT 23
 | ||||
| -cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT
 | ||||
| -cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT
 | ||||
| -cmd 1 "$ENOENT" iptables -D nonexist 23
 | ||||
| -cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT
 | ||||
| +cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT
 | ||||
| +cmd 1 "$E2BIG_D" -D INPUT 23
 | ||||
| +cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT
 | ||||
| +cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT
 | ||||
| +cmd 1 "$ENOENT" -D nonexist 23
 | ||||
| +cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT
 | ||||
|   | ||||
|  # test rule checking | ||||
| -cmd 0 iptables -C INPUT -j ACCEPT
 | ||||
| -cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT
 | ||||
| -cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT
 | ||||
| -cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT
 | ||||
| +cmd 0 -C INPUT -j ACCEPT
 | ||||
| +cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT
 | ||||
| +cmd 1 "$BADRULE" -C nonexist -j ACCEPT
 | ||||
| +cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT
 | ||||
|  # messages of those don't match, but iptables-nft ones are actually nicer. | ||||
| -#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar
 | ||||
| -#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT
 | ||||
| -cmd 2 "" iptables -C INPUT -j foobar
 | ||||
| -cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT
 | ||||
| +# legacy: Couldn't load target `foobar':No such file or directory
 | ||||
| +# nft:    Chain 'foobar' does not exist
 | ||||
| +cmd 2 "" -C INPUT -j foobar
 | ||||
| +# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?)
 | ||||
| +# nft:    table 'foobar' does not exist
 | ||||
| +cmd 3 "" -t foobar -C INPUT -j ACCEPT
 | ||||
|   | ||||
|  exit $global_rc | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
							
								
								
									
										177
									
								
								SOURCES/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								SOURCES/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,177 @@ | ||||
| From 98794894774a39927bc975921fc9e40f00db937b Mon Sep 17 00:00:00 2001 | ||||
| From: Phil Sutter <phil@nwl.cc> | ||||
| Date: Wed, 2 Dec 2020 13:37:06 +0100 | ||||
| Subject: [PATCH] extensions: dccp: Fix for DCCP type 'INVALID' | ||||
| 
 | ||||
| Support for matching on invalid DCCP type field values was pretty | ||||
| broken: While RFC4340 declares any type value from 10 to 15 invalid, the | ||||
| extension's type name 'INVALID' mapped to type value 10 only. Fix this | ||||
| by introduction of INVALID_OTHER_TYPE_MASK which has the remaining | ||||
| invalid type's bits set and apply it if bit 10 is set after parsing the | ||||
| type list. When printing, stop searching type names after printing | ||||
| 'INVALID' - unless numeric output was requested. The latter prints all | ||||
| actual type values. Since parsing types in numeric form is not | ||||
| supported, changing the output should not break existing scripts. | ||||
| 
 | ||||
| When translating into nftables syntax, the code returned prematurely if | ||||
| 'INVALID' was among the list of types - thereby emitting invalid syntax. | ||||
| Instead print a real match for invalid types by use of a range | ||||
| expression. | ||||
| 
 | ||||
| While being at it, fix syntax of translator output: If only | ||||
| '--dccp-types' was translated, the output contained an extra 'dccp'. On | ||||
| the other hand, if '--sport' and '--dport' was present, a required | ||||
| 'dccp' between the translations of both was missing. | ||||
| 
 | ||||
| Fixes: e40b11d7ef827 ("add support for new 'dccp' protocol match") | ||||
| Fixes: c94a998724143 ("extensions: libxt_dccp: Add translation to nft") | ||||
| Signed-off-by: Phil Sutter <phil@nwl.cc> | ||||
| (cherry picked from commit 4bcbc8e11a2764f4537dc405962f83cd072cccfe) | ||||
| Signed-off-by: Phil Sutter <psutter@redhat.com> | ||||
| ---
 | ||||
|  extensions/libxt_dccp.c      | 58 ++++++++++++++++++++++-------------- | ||||
|  extensions/libxt_dccp.txlate | 12 ++++++-- | ||||
|  2 files changed, 45 insertions(+), 25 deletions(-) | ||||
| 
 | ||||
| diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c
 | ||||
| index 5e67c264db2a9..aea3e20be4818 100644
 | ||||
| --- a/extensions/libxt_dccp.c
 | ||||
| +++ b/extensions/libxt_dccp.c
 | ||||
| @@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
 | ||||
|  	[DCCP_PKT_INVALID]	= "INVALID", | ||||
|  }; | ||||
|   | ||||
| +/* Bits for type values 11-15 */
 | ||||
| +#define INVALID_OTHER_TYPE_MASK		0xf800
 | ||||
| +
 | ||||
|  static uint16_t | ||||
|  parse_dccp_types(const char *typestring) | ||||
|  { | ||||
| @@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
 | ||||
|  			xtables_error(PARAMETER_PROBLEM, | ||||
|  				   "Unknown DCCP type `%s'", ptr); | ||||
|  	} | ||||
| +	if (typemask & (1 << DCCP_PKT_INVALID))
 | ||||
| +		typemask |= INVALID_OTHER_TYPE_MASK;
 | ||||
| +
 | ||||
|   | ||||
|  	free(buffer); | ||||
|  	return typemask; | ||||
| @@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric)
 | ||||
|   | ||||
|  		if (numeric) | ||||
|  			printf("%u", i); | ||||
| -		else
 | ||||
| +		else {
 | ||||
|  			printf("%s", dccp_pkt_types[i]); | ||||
|   | ||||
| +			if (i == DCCP_PKT_INVALID)
 | ||||
| +				break;
 | ||||
| +		}
 | ||||
| +
 | ||||
|  		types &= ~(1 << i); | ||||
|  	} | ||||
|  } | ||||
| @@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = {
 | ||||
|  	[DCCP_PKT_RESET]        = "reset", | ||||
|  	[DCCP_PKT_SYNC]         = "sync", | ||||
|  	[DCCP_PKT_SYNCACK]      = "syncack", | ||||
| +	[DCCP_PKT_INVALID]	= "10-15",
 | ||||
|  }; | ||||
|   | ||||
|  static int dccp_type_xlate(const struct xt_dccp_info *einfo, | ||||
| @@ -296,10 +307,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo,
 | ||||
|  	bool have_type = false, set_need = false; | ||||
|  	uint16_t types = einfo->typemask; | ||||
|   | ||||
| -	if (types & (1 << DCCP_PKT_INVALID))
 | ||||
| -		return 0;
 | ||||
| -
 | ||||
| -	xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
 | ||||
| +	if (types & INVALID_OTHER_TYPE_MASK) {
 | ||||
| +		types &= ~INVALID_OTHER_TYPE_MASK;
 | ||||
| +		types |= 1 << DCCP_PKT_INVALID;
 | ||||
| +	}
 | ||||
|   | ||||
|  	if ((types != 0) && !(types == (types & -types))) { | ||||
|  		xt_xlate_add(xl, "{"); | ||||
| @@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl,
 | ||||
|  	char *space = ""; | ||||
|  	int ret = 1; | ||||
|   | ||||
| -	xt_xlate_add(xl, "dccp ");
 | ||||
| -
 | ||||
|  	if (einfo->flags & XT_DCCP_SRC_PORTS) { | ||||
| +		xt_xlate_add(xl, "dccp sport%s %u",
 | ||||
| +			     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
 | ||||
| +			     einfo->spts[0]);
 | ||||
| +
 | ||||
|  		if (einfo->spts[0] != einfo->spts[1]) | ||||
| -			xt_xlate_add(xl, "sport%s %u-%u",
 | ||||
| -				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
 | ||||
| -				     einfo->spts[0], einfo->spts[1]);
 | ||||
| -		else
 | ||||
| -			xt_xlate_add(xl, "sport%s %u",
 | ||||
| -				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
 | ||||
| -				     einfo->spts[0]);
 | ||||
| +			xt_xlate_add(xl, "-%u", einfo->spts[1]);
 | ||||
| +
 | ||||
|  		space = " "; | ||||
|  	} | ||||
|   | ||||
|  	if (einfo->flags & XT_DCCP_DEST_PORTS) { | ||||
| +		xt_xlate_add(xl, "%sdccp dport%s %u", space,
 | ||||
| +			     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
 | ||||
| +			     einfo->dpts[0]);
 | ||||
| +
 | ||||
|  		if (einfo->dpts[0] != einfo->dpts[1]) | ||||
| -			xt_xlate_add(xl, "%sdport%s %u-%u", space,
 | ||||
| -				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
 | ||||
| -				     einfo->dpts[0], einfo->dpts[1]);
 | ||||
| -		else
 | ||||
| -			xt_xlate_add(xl, "%sdport%s %u", space,
 | ||||
| -				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
 | ||||
| -				     einfo->dpts[0]);
 | ||||
| +			xt_xlate_add(xl, "-%u", einfo->dpts[1]);
 | ||||
| +
 | ||||
| +		space = " ";
 | ||||
|  	} | ||||
|   | ||||
| -	if (einfo->flags & XT_DCCP_TYPE)
 | ||||
| +	if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
 | ||||
| +		xt_xlate_add(xl, "%sdccp type%s ", space,
 | ||||
| +			     einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
 | ||||
|  		ret = dccp_type_xlate(einfo, xl); | ||||
|   | ||||
| +		space = " ";
 | ||||
| +	}
 | ||||
| +
 | ||||
| +	/* FIXME: no dccp option support in nftables yet */
 | ||||
|  	if (einfo->flags & XT_DCCP_OPTION) | ||||
|  		ret = 0; | ||||
|   | ||||
| diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate
 | ||||
| index b47dc65f5bc4f..ea853f6acf627 100644
 | ||||
| --- a/extensions/libxt_dccp.txlate
 | ||||
| +++ b/extensions/libxt_dccp.txlate
 | ||||
| @@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter
 | ||||
|  iptables-translate -A INPUT -p dccp -m dccp ! --dport 100 | ||||
|  nft add rule ip filter INPUT dccp dport != 100 counter | ||||
|   | ||||
| -iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK
 | ||||
| -nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter
 | ||||
| +iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
 | ||||
| +nft add rule ip filter INPUT dccp type close counter
 | ||||
| +
 | ||||
| +iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID
 | ||||
| +nft add rule ip filter INPUT dccp type 10-15 counter
 | ||||
| +
 | ||||
| +iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID
 | ||||
| +nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter
 | ||||
|   | ||||
|  iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100 | ||||
| -nft add rule ip filter INPUT dccp sport 200 dport 100 counter
 | ||||
| +nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
 | ||||
| -- 
 | ||||
| 2.28.0 | ||||
| 
 | ||||
| @ -17,7 +17,7 @@ Name: iptables | ||||
| Summary: Tools for managing Linux kernel packet filtering capabilities | ||||
| URL: http://www.netfilter.org/projects/iptables | ||||
| Version: 1.8.4 | ||||
| Release: 15%{?dist}.3 | ||||
| Release: 17%{?dist} | ||||
| Source: %{url}/files/%{name}-%{version}.tar.bz2 | ||||
| Source1: iptables.init | ||||
| Source2: iptables-config | ||||
| @ -63,11 +63,20 @@ Patch26: 0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch | ||||
| Patch27: 0027-nft-Fix-error-reporting-for-refreshed-transactions.patch | ||||
| Patch28: 0028-nft-Fix-for-concurrent-noflush-restore-calls.patch | ||||
| Patch29: 0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch | ||||
| Patch30: 0030-nft-Fix-for-broken-address-mask-match-detection.patch | ||||
| Patch31: 0031-nft-Optimize-class-based-IP-prefix-matches.patch | ||||
| Patch32: 0032-ebtables-Optimize-masked-MAC-address-matches.patch | ||||
| Patch33: 0033-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch | ||||
| Patch34: 0034-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch | ||||
| Patch30: 0030-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch | ||||
| Patch31: 0031-nft-Fix-for-broken-address-mask-match-detection.patch | ||||
| Patch32: 0032-nft-Optimize-class-based-IP-prefix-matches.patch | ||||
| Patch33: 0033-ebtables-Optimize-masked-MAC-address-matches.patch | ||||
| Patch34: 0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch | ||||
| Patch35: 0035-libxtables-Make-sure-extensions-register-in-revision.patch | ||||
| Patch36: 0036-libxtables-Simplify-pending-extension-registration.patch | ||||
| Patch37: 0037-libxtables-Register-multiple-extensions-in-ascending.patch | ||||
| Patch38: 0038-tests-shell-Test-for-fixed-extension-registration.patch | ||||
| Patch39: 0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch | ||||
| Patch40: 0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch | ||||
| Patch41: 0041-nft-Fix-command-name-in-ip6tables-error-message.patch | ||||
| Patch42: 0042-tests-shell-Merge-and-extend-return-codes-test.patch | ||||
| Patch43: 0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch | ||||
| 
 | ||||
| # pf.os: ISC license | ||||
| # iptables-apply: Artistic Licence 2.0 | ||||
| @ -476,16 +485,23 @@ done | ||||
| %doc %{_mandir}/man8/ebtables*.8* | ||||
| 
 | ||||
| %changelog | ||||
| * Tue Nov 10 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.3 | ||||
| - nft: cache: Make nft_rebuild_cache() respect fake cache | ||||
| * Thu Dec 10 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-17 | ||||
| - extensions: dccp: Fix for DCCP type 'INVALID' | ||||
| - tests: shell: Merge and extend return codes test | ||||
| - nft: Fix command name in ip6tables error message | ||||
| - extensions: libxt_CT: add translation for NOTRACK | ||||
| - extensions: libipt_icmp: Fix translation of type 'any' | ||||
| - tests/shell: Test for fixed extension registration | ||||
| - libxtables: Register multiple extensions in ascending order | ||||
| - libxtables: Simplify pending extension registration | ||||
| - libxtables: Make sure extensions register in revision order | ||||
| 
 | ||||
| * Thu Nov 05 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.2 | ||||
| * Wed Oct 28 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-16 | ||||
| - tests/shell: Add test for bitwise avoidance fixes | ||||
| - ebtables: Optimize masked MAC address matches | ||||
| - nft: Optimize class-based IP prefix matches | ||||
| - nft: Fix for broken address mask match detection | ||||
| 
 | ||||
| * Wed Oct 28 2020 Phil Sutter <psutter@redhat.com> - 1.8.4-15.1 | ||||
| - nft: cache: Make nft_rebuild_cache() respect fake cache | ||||
| - tests: shell: Improve concurrent noflush restore test a bit | ||||
| - nft: Fix for concurrent noflush restore calls | ||||
| - nft: Fix error reporting for refreshed transactions | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user