import CS iputils-20210202-11.el9
This commit is contained in:
		
							parent
							
								
									01318bfa1c
								
							
						
					
					
						commit
						efc90e9db1
					
				| @ -0,0 +1,40 @@ | |||||||
|  | From a1890739e9d5953897cec43c59d5fea922384d5b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Wed, 22 May 2024 07:05:14 +0200 | ||||||
|  | Subject: [PATCH 1/2] arping: Fix 1s delay on exit for unsolicited arpings | ||||||
|  | 
 | ||||||
|  | Commit 67e070d introduced 1s poll() delay for unsolicited arpings, | ||||||
|  | when using -U or -A, e.g.: | ||||||
|  | 
 | ||||||
|  |     # arping -A -c1 -I eth0 [IP address of eth0 interface] | ||||||
|  |     # arping -U -c1 -I eth0 [IP address of eth0 interface] | ||||||
|  | 
 | ||||||
|  | Restore correct condition. | ||||||
|  | 
 | ||||||
|  | Fixes: 67e070d ("arping: use signalfd() and timerfd() rather than signals") | ||||||
|  | Fixes: https://github.com/iputils/iputils/issues/536 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/541 | ||||||
|  | Reported-by: <Curtis Taylor cjebpub@gmail.com> | ||||||
|  | Suggested-by: <Curtis Taylor cjebpub@gmail.com> | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 4db1de672559804bebcb7073d231924339ca8cd8) | ||||||
|  | ---
 | ||||||
|  |  arping.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/arping.c b/arping.c
 | ||||||
|  | index 53fdbb4..8929f8f 100644
 | ||||||
|  | --- a/arping.c
 | ||||||
|  | +++ b/arping.c
 | ||||||
|  | @@ -749,7 +749,7 @@ static int event_loop(struct run_state *ctl)
 | ||||||
|  |  	pfds[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP; | ||||||
|  |  	send_pack(ctl); | ||||||
|  |   | ||||||
|  | -	while (!exit_loop) {
 | ||||||
|  | +	while (!(exit_loop || ctl->unsolicited)) {
 | ||||||
|  |  		int ret; | ||||||
|  |  		size_t i; | ||||||
|  |   | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,61 @@ | |||||||
|  | From 5564dd9f224a7354a55c8f57ac0da9c2e58b18e5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Fri, 24 May 2024 00:05:53 +0200 | ||||||
|  | Subject: [PATCH 2/2] arping: Fix unsolicited ARP regressions on -c > 1 | ||||||
|  | 
 | ||||||
|  | 4db1de6 tried to fix a regression 1 sec delay due poll() for unsolicited | ||||||
|  | ARP, .i.e. -A and -U (introduced in 67e070d, reported as issue #536). | ||||||
|  | But skipping the while loop entirely introduced another regression for | ||||||
|  | -A and -U, which behave like -c1 (sending *always* only a single packet).
 | ||||||
|  | 
 | ||||||
|  | Fixing it by checking in while loop and comparing also count (as it was | ||||||
|  | done in 67e070d before the rewrite). | ||||||
|  | 
 | ||||||
|  | NOTE: use exit_loop with continue instead of simple break to keep things | ||||||
|  | consistent. | ||||||
|  | 
 | ||||||
|  | Fixes: 4db1de6 ("arping: Fix 1s delay on exit for unsolicited arpings") | ||||||
|  | Fixes: 67e070d ("arping: use signalfd() and timerfd() rather than signals") | ||||||
|  | Fixes: https://github.com/iputils/iputils/issues/536 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/543 | ||||||
|  | Reported-by: David Bond <dbond@suse.com> | ||||||
|  | Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com> | ||||||
|  | Reviewed-by: Cyril Hrubis <chrubis@suse.cz> | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 5de892d15eea467775420c4fd641df229f024259) | ||||||
|  | ---
 | ||||||
|  |  arping.c | 8 +++++++- | ||||||
|  |  1 file changed, 7 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/arping.c b/arping.c
 | ||||||
|  | index 8929f8f..ee9da1d 100644
 | ||||||
|  | --- a/arping.c
 | ||||||
|  | +++ b/arping.c
 | ||||||
|  | @@ -749,10 +749,15 @@ static int event_loop(struct run_state *ctl)
 | ||||||
|  |  	pfds[POLLFD_SOCKET].events = POLLIN | POLLERR | POLLHUP; | ||||||
|  |  	send_pack(ctl); | ||||||
|  |   | ||||||
|  | -	while (!(exit_loop || ctl->unsolicited)) {
 | ||||||
|  | +	while (!exit_loop) {
 | ||||||
|  |  		int ret; | ||||||
|  |  		size_t i; | ||||||
|  |   | ||||||
|  | +		if ((ctl->sent == ctl->count) && ctl->unsolicited) {
 | ||||||
|  | +			exit_loop = 1;
 | ||||||
|  | +			continue;
 | ||||||
|  | +		}
 | ||||||
|  | +
 | ||||||
|  |  		ret = poll(pfds, POLLFD_COUNT, -1); | ||||||
|  |  		if (ret <= 0) { | ||||||
|  |  			if (errno == EAGAIN) | ||||||
|  | @@ -813,6 +818,7 @@ static int event_loop(struct run_state *ctl)
 | ||||||
|  |  			} | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | +
 | ||||||
|  |  	close(sfd); | ||||||
|  |  	close(tfd); | ||||||
|  |  	freeifaddrs(ctl->ifa0); | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										33
									
								
								SOURCES/004-arping-fix-typo-in-error-checking.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								SOURCES/004-arping-fix-typo-in-error-checking.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | From 357b788e667bdd51b66bbc0cc88cf82ae3169455 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Noah Meyerhans <noahm@debian.org> | ||||||
|  | Date: Wed, 16 Feb 2022 22:25:30 -0800 | ||||||
|  | Subject: [PATCH 1/2] arping: fix typo in error checking | ||||||
|  | 
 | ||||||
|  | When attempting to check the return value of timerfd_create(), we were | ||||||
|  | not checking the value of the variable containing the return value. | ||||||
|  | 
 | ||||||
|  | Fixes: e594ca5 ("arping: use additional timerfd to control when timeout happens") | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Petr Vorel <petr.vorel@gmail.com> | ||||||
|  | Signed-off-by: Noah Meyerhans <noahm@debian.org> | ||||||
|  | (cherry picked from commit 8a6a2ce3cd0cdf69f0551a3a1e598a191561d18e) | ||||||
|  | ---
 | ||||||
|  |  arping.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/arping.c b/arping.c
 | ||||||
|  | index ee9da1d..8059517 100644
 | ||||||
|  | --- a/arping.c
 | ||||||
|  | +++ b/arping.c
 | ||||||
|  | @@ -733,7 +733,7 @@ static int event_loop(struct run_state *ctl)
 | ||||||
|  |   | ||||||
|  |  	/* timeout timerfd */ | ||||||
|  |  	timeoutfd = timerfd_create(CLOCK_MONOTONIC, 0); | ||||||
|  | -	if (tfd == -1) {
 | ||||||
|  | +	if (timeoutfd == -1) {
 | ||||||
|  |  		error(0, errno, "timerfd_create failed"); | ||||||
|  |  		return 1; | ||||||
|  |  	} | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | From bf2900d716397734136ec3014a591281504aa00b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Noah Meyerhans <noahm@debian.org> | ||||||
|  | Date: Wed, 16 Feb 2022 22:27:49 -0800 | ||||||
|  | Subject: [PATCH 2/2] arping: exit 0 if running in deadline mode and we see | ||||||
|  |  replies | ||||||
|  | 
 | ||||||
|  | The arping behavior when running in deadline mode without a packet | ||||||
|  | count (-w without -c) should match that of ping: any replies indicate | ||||||
|  | that the host is up and should result in a zero (success) exit status. | ||||||
|  | 
 | ||||||
|  | Fixes: https://github.com/iputils/iputils/issues/392 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/395 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Petr Vorel <petr.vorel@gmail.com> | ||||||
|  | Signed-off-by: Noah Meyerhans <noahm@debian.org> | ||||||
|  | (cherry picked from commit 854873bdd28fcdd9cc3fe0c2d29c083a07d07a86) | ||||||
|  | ---
 | ||||||
|  |  arping.c       |  2 ++ | ||||||
|  |  doc/arping.xml | 14 +++++++------- | ||||||
|  |  2 files changed, 9 insertions(+), 7 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/arping.c b/arping.c
 | ||||||
|  | index 8059517..6f94e90 100644
 | ||||||
|  | --- a/arping.c
 | ||||||
|  | +++ b/arping.c
 | ||||||
|  | @@ -828,6 +828,8 @@ static int event_loop(struct run_state *ctl)
 | ||||||
|  |  	else if (ctl->dad && ctl->quit_on_reply) | ||||||
|  |  		/* Duplicate address detection mode return value */ | ||||||
|  |  		rc |= !(ctl->brd_sent != ctl->received); | ||||||
|  | +	else if (ctl->timeout && !(ctl->count > 0))
 | ||||||
|  | +		rc |= !(ctl->received > 0);
 | ||||||
|  |  	else | ||||||
|  |  		rc |= (ctl->sent != ctl->received); | ||||||
|  |  	return rc; | ||||||
|  | diff --git a/doc/arping.xml b/doc/arping.xml
 | ||||||
|  | index 711718f..9adbc0c 100644
 | ||||||
|  | --- a/doc/arping.xml
 | ||||||
|  | +++ b/doc/arping.xml
 | ||||||
|  | @@ -202,13 +202,13 @@ xml:id="man.arping">
 | ||||||
|  |          <listitem> | ||||||
|  |            <para>Specify a timeout, in seconds, before | ||||||
|  |            <command>arping</command> exits regardless of how many | ||||||
|  | -          packets have been sent or received. In this case
 | ||||||
|  | -          <command>arping</command> does not stop after
 | ||||||
|  | -          <emphasis remap='I'>count</emphasis> packet are sent, it
 | ||||||
|  | -          waits either for
 | ||||||
|  | -          <emphasis remap='I'>deadline</emphasis> expire or until
 | ||||||
|  | -          <emphasis remap='I'>count</emphasis> probes are
 | ||||||
|  | -          answered.</para>
 | ||||||
|  | +          packets have been sent or received.  If any replies are
 | ||||||
|  | +          received, exit with status 0, otherwise status 1.  When
 | ||||||
|  | +          combined with the <emphasis remap="I">count</emphasis>
 | ||||||
|  | +          option, exit with status 0 if <emphasis
 | ||||||
|  | +          remap="I">count</emphasis> replies are received before the
 | ||||||
|  | +          deadline expiration, otherwise status 1.
 | ||||||
|  | +	  </para>
 | ||||||
|  |          </listitem> | ||||||
|  |        </varlistentry> | ||||||
|  |        <varlistentry> | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,119 @@ | |||||||
|  | From 7d62be648f03adba22bcccd2eb3506d51169b85d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Thu, 15 Apr 2021 07:48:03 +0200 | ||||||
|  | Subject: [PATCH 1/3] Revert "Add strict pattern matching on response when | ||||||
|  |  pattern was provided" | ||||||
|  | 
 | ||||||
|  | This reverts commit f7710a17c4d5994313a64583f511bcdb9559f2a9. | ||||||
|  | 
 | ||||||
|  | Commit broke report of truncated packets: | ||||||
|  | $ ping -c2 -s100 google.com | ||||||
|  | PING google.com (142.250.185.238) 100(128) bytes of data. | ||||||
|  | 
 | ||||||
|  | Running ping from both s20161105 (which does not contain f7710a1) and | ||||||
|  | reverted f7710a1 on master reports truncated packets: | ||||||
|  | 
 | ||||||
|  | $ ping -c2 -s100 google.com | ||||||
|  | PING google.com (142.250.185.238) 100(128) bytes of data. | ||||||
|  | 76 bytes from fra16s53-in-f14.1e100.net (142.250.185.238): icmp_seq=1 ttl=116 (truncated) | ||||||
|  | 76 bytes from fra16s53-in-f14.1e100.net (142.250.185.238): icmp_seq=2 ttl=116 (truncated) | ||||||
|  | 
 | ||||||
|  | There was unreachable code in gather_statistics() because | ||||||
|  | contains_pattern_in_payload() added in f7710a1 always found a mismatch | ||||||
|  | first. Due that all of these did not work: | ||||||
|  | * updating counters for statistics generation | ||||||
|  | * keeping track of timestamps and time-of-flight using the first section | ||||||
|  |   of the payload | ||||||
|  | * checking for duplicate replies and report them | ||||||
|  | * printing basic info about the reply | ||||||
|  | * printing "(truncated)" if the reply was truncated | ||||||
|  | * checking the checksum | ||||||
|  | * validating the rest of the payload (bytes 17 and above) against the | ||||||
|  |   ICMP request that was sent, and report any differences | ||||||
|  | 
 | ||||||
|  | Fixes: f7710a1 ("Add strict pattern matching on response when pattern was provided") | ||||||
|  | Closes: https://github.com/iputils/iputils/issues/320 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/331 | ||||||
|  | 
 | ||||||
|  | Reported-by: Paul Swirhun <paulswirhun@gmail.com> | ||||||
|  | Suggested-by: Paul Swirhun <paulswirhun@gmail.com> | ||||||
|  | Reviewed-by: Noah Meyerhans <noahm@debian.org> | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit dff5d82dadab1b04400b2f9e1eb10a0d124868ed) | ||||||
|  | ---
 | ||||||
|  |  ping/ping.c         |  2 -- | ||||||
|  |  ping/ping.h         |  1 - | ||||||
|  |  ping/ping6_common.c |  2 -- | ||||||
|  |  ping/ping_common.c  | 18 ------------------ | ||||||
|  |  4 files changed, 23 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping.c b/ping/ping.c
 | ||||||
|  | index 1c98733..0655bf4 100644
 | ||||||
|  | --- a/ping/ping.c
 | ||||||
|  | +++ b/ping/ping.c
 | ||||||
|  | @@ -1549,8 +1549,6 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
 | ||||||
|  |  			return 1; | ||||||
|  |  		if (!is_ours(rts, sock, icp->un.echo.id)) | ||||||
|  |  			return 1;			/* 'Twas not our ECHO */ | ||||||
|  | -		if (!contains_pattern_in_payload(rts, (uint8_t *)(icp + 1)))
 | ||||||
|  | -			return 1;			/* 'Twas really not our ECHO */
 | ||||||
|  |  		if (gather_statistics(rts, (uint8_t *)icp, sizeof(*icp), cc, | ||||||
|  |  				      ntohs(icp->un.echo.sequence), | ||||||
|  |  				      reply_ttl, 0, tv, pr_addr(rts, from, sizeof *from), | ||||||
|  | diff --git a/ping/ping.h b/ping/ping.h
 | ||||||
|  | index c8bbcf6..86652bf 100644
 | ||||||
|  | --- a/ping/ping.h
 | ||||||
|  | +++ b/ping/ping.h
 | ||||||
|  | @@ -380,7 +380,6 @@ int is_ours(struct ping_rts *rts, socket_st *sock, uint16_t id);
 | ||||||
|  |  extern int pinger(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock); | ||||||
|  |  extern void sock_setbufs(struct ping_rts *rts, socket_st *, int alloc); | ||||||
|  |  extern void setup(struct ping_rts *rts, socket_st *); | ||||||
|  | -extern int contains_pattern_in_payload(struct ping_rts *rts, uint8_t *ptr);
 | ||||||
|  |  extern int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st*, | ||||||
|  |  		     uint8_t *packet, int packlen); | ||||||
|  |  extern int finish(struct ping_rts *rts); | ||||||
|  | diff --git a/ping/ping6_common.c b/ping/ping6_common.c
 | ||||||
|  | index 459f63e..fcb48be 100644
 | ||||||
|  | --- a/ping/ping6_common.c
 | ||||||
|  | +++ b/ping/ping6_common.c
 | ||||||
|  | @@ -823,8 +823,6 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
 | ||||||
|  |  			return 1; | ||||||
|  |  		if (!is_ours(rts, sock, icmph->icmp6_id)) | ||||||
|  |  			return 1; | ||||||
|  | -	       if (!contains_pattern_in_payload(rts, (uint8_t *)(icmph + 1)))
 | ||||||
|  | -			return 1;	/* 'Twas really not our ECHO */
 | ||||||
|  |  		if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc, | ||||||
|  |  				      ntohs(icmph->icmp6_seq), | ||||||
|  |  				      hops, 0, tv, pr_addr(rts, from, sizeof *from), | ||||||
|  | diff --git a/ping/ping_common.c b/ping/ping_common.c
 | ||||||
|  | index 33e6003..357c39d 100644
 | ||||||
|  | --- a/ping/ping_common.c
 | ||||||
|  | +++ b/ping/ping_common.c
 | ||||||
|  | @@ -553,24 +553,6 @@ void setup(struct ping_rts *rts, socket_st *sock)
 | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -/*
 | ||||||
|  | - * Return 0 if pattern in payload point to be ptr did not match the pattern that was sent  
 | ||||||
|  | - */
 | ||||||
|  | -int contains_pattern_in_payload(struct ping_rts *rts, uint8_t *ptr)
 | ||||||
|  | -{
 | ||||||
|  | -	size_t i;
 | ||||||
|  | -	uint8_t *cp, *dp;
 | ||||||
|  | - 
 | ||||||
|  | -	/* check the data */
 | ||||||
|  | -	cp = ((u_char *)ptr) + sizeof(struct timeval);
 | ||||||
|  | -	dp = &rts->outpack[8 + sizeof(struct timeval)];
 | ||||||
|  | -	for (i = sizeof(struct timeval); i < rts->datalen; ++i, ++cp, ++dp) {
 | ||||||
|  | -		if (*cp != *dp)
 | ||||||
|  | -			return 0;
 | ||||||
|  | -	}
 | ||||||
|  | -	return 1;
 | ||||||
|  | -}
 | ||||||
|  | -
 | ||||||
|  |  int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock, | ||||||
|  |  	      uint8_t *packet, int packlen) | ||||||
|  |  { | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										36
									
								
								SOURCES/007-ping-Move-ping_rts-multicast.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								SOURCES/007-ping-Move-ping_rts-multicast.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | From 1c66917a079e95f00e9a1f2af1329c65501e8a60 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Mon, 18 Oct 2021 15:27:35 +0200 | ||||||
|  | Subject: [PATCH 1/4] ping: Move ping_rts->multicast | ||||||
|  | 
 | ||||||
|  | as it's used for both IPv4 and IPv6. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 7a4ec7532871772cb22a3b2c42f6006f95f8b263) | ||||||
|  | ---
 | ||||||
|  |  ping/ping.h | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping.h b/ping/ping.h
 | ||||||
|  | index 703296d..a5f05f4 100644
 | ||||||
|  | --- a/ping/ping.h
 | ||||||
|  | +++ b/ping/ping.h
 | ||||||
|  | @@ -192,6 +192,7 @@ struct ping_rts {
 | ||||||
|  |  	struct sockaddr_in6 source6; | ||||||
|  |  	struct sockaddr_in6 whereto6; | ||||||
|  |  	struct sockaddr_in6 firsthop6; | ||||||
|  | +	int multicast;
 | ||||||
|  |   | ||||||
|  |  	/* Used only in ping.c */ | ||||||
|  |  	int ts_type; | ||||||
|  | @@ -201,7 +202,6 @@ struct ping_rts {
 | ||||||
|  |  	int optlen; | ||||||
|  |  	int settos;			/* Set TOS, Precedence or other QOS options */ | ||||||
|  |  	int broadcast_pings; | ||||||
|  | -	int multicast;
 | ||||||
|  |  	struct sockaddr_in source; | ||||||
|  |   | ||||||
|  |  	/* Used only in ping_common.c */ | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,133 @@ | |||||||
|  | From aa75473cac4a37cd673da3a66904878efcfdbd6f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Mon, 18 Oct 2021 15:13:44 +0200 | ||||||
|  | Subject: [PATCH 2/3] ping: Print reply from Subnet-Router anycast address | ||||||
|  | 
 | ||||||
|  | by detecting Subnet-Router address for 64 bit prefix and suppress | ||||||
|  | address comparison check. | ||||||
|  | 
 | ||||||
|  | 5e052ad ("ping: discard packets with wrong source address") correctly | ||||||
|  | hid replies with wrong source address to comply RFC 1122 (Section | ||||||
|  | 3.2.1.3: "The IP source address in an ICMP Echo Reply MUST be the same | ||||||
|  | as the specific-destination address"). | ||||||
|  | 
 | ||||||
|  | While change in 5e052ad works for broadcast and multicast addresses and | ||||||
|  | some of anycast addresses, it does not work for (at least) Subnet-Router | ||||||
|  | anycast address): | ||||||
|  | 
 | ||||||
|  |     # VETH1_IPV6=fd00:dead:beef:1234::1 | ||||||
|  |     # VPEER1_IPV6=fd00:dead:beef:1234::2 | ||||||
|  |     # ip netns add ns-ipv6 | ||||||
|  |     # ip li add name veth1 type veth peer name vpeer1 | ||||||
|  |     # ip -6 addr add $VETH1_IPV6/64 dev veth1 | ||||||
|  |     # ip li set dev veth1 up | ||||||
|  |     # ip li set dev vpeer1 netns ns-ipv6 | ||||||
|  |     # ip netns exec ns-ipv6 ip li set dev lo up | ||||||
|  |     # ip netns exec ns-ipv6 ip -6 addr add $VPEER1_IPV6/64 dev vpeer1 | ||||||
|  |     # ip netns exec ns-ipv6 ip li set vpeer1 up | ||||||
|  |     # ip netns exec ns-ipv6 ip -6 route add default dev vpeer1 via $VETH1_IPV6 | ||||||
|  |     # sysctl -w net.ipv6.conf.all.forwarding=1 | ||||||
|  | 
 | ||||||
|  |     $ ping -c1 ff02::1 # anycast - all nodes | ||||||
|  |     PING ff02::1(ff02::1) 56 data bytes | ||||||
|  |     64 bytes from fe80::9c9c:ffff:fe14:e9d2%vpeer1: icmp_seq=1 ttl=64 time=0.064 ms | ||||||
|  | 
 | ||||||
|  |     $ ping -c1 ff02::2 # anycast - all routers | ||||||
|  |     PING ff02::2(ff02::2) 56 data bytes | ||||||
|  |     64 bytes from fe80::5496:9ff:fef5:8f01%vpeer1: icmp_seq=1 ttl=64 time=0.088 ms | ||||||
|  | 
 | ||||||
|  |     $ ping -c1 -W5 fd00:dead:beef:1234:: # Subnet-Router anycast | ||||||
|  |     PING fd00:dead:beef:1234::(fd00:dead:beef:1234::) 56 data bytes | ||||||
|  | 
 | ||||||
|  | Subnet-Router anycast address works for both busybox ping (without | ||||||
|  | printing the real source address) and fping: | ||||||
|  | 
 | ||||||
|  |     $ busybox ping -c1 fd00:dead:beef:1234:: | ||||||
|  |     PING fd00:dead:beef:1234:: (fd00:dead:beef:1234::): 56 data bytes | ||||||
|  |     64 bytes from fd00:dead:beef:1234::1: seq=0 ttl=64 time=0.122 ms | ||||||
|  | 
 | ||||||
|  |     $ fping -c1 fd00:dead:beef:1234:: | ||||||
|  |      [<- fd00:dead:beef:1234::1]fd00:dead:beef:1234:: : [0], 64 bytes, 0.096 ms (0.096 avg, 0% loss) | ||||||
|  | 
 | ||||||
|  | RFC 4291 specifies Subnet-Router anycast address as [1]: | ||||||
|  | 
 | ||||||
|  |     The Subnet-Router anycast address is predefined.  Its format is as | ||||||
|  |     follows: | ||||||
|  |     |                         n bits                 |   128-n bits   | | ||||||
|  |     +------------------------------------------------+----------------+ | ||||||
|  |     |                   subnet prefix                | 00000000000000 | | ||||||
|  |     +------------------------------------------------+----------------+ | ||||||
|  | 
 | ||||||
|  |     The "subnet prefix" in an anycast address is the prefix that | ||||||
|  |     identifies a specific link.  This anycast address is syntactically | ||||||
|  |     the same as a unicast address for an interface on the link with the | ||||||
|  |     interface identifier set to zero. | ||||||
|  | 
 | ||||||
|  | => to detect Subnet-Router anycast address we need to know prefix, which
 | ||||||
|  | we don't know, thus detect it for prefix 64 (the default IPv6 prefix). | ||||||
|  | 
 | ||||||
|  | [1] https://datatracker.ietf.org/doc/html/rfc4291#section-2.6.1 | ||||||
|  | 
 | ||||||
|  | Fixes: 5e052ad ("ping: discard packets with wrong source address") | ||||||
|  | Closes: https://github.com/iputils/iputils/issues/371 | ||||||
|  | 
 | ||||||
|  | Reported-by: Tim Sandquist | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 15a5e5c7aace5a7a782ff802988e04ed4c1148a5) | ||||||
|  | ---
 | ||||||
|  |  ping/ping.h         |  1 + | ||||||
|  |  ping/ping6_common.c | 12 +++++++++++- | ||||||
|  |  2 files changed, 12 insertions(+), 1 deletion(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping.h b/ping/ping.h
 | ||||||
|  | index 86652bf..f26fdac 100644
 | ||||||
|  | --- a/ping/ping.h
 | ||||||
|  | +++ b/ping/ping.h
 | ||||||
|  | @@ -212,6 +212,7 @@ struct ping_rts {
 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  	/* Used only in ping6_common.c */ | ||||||
|  | +	int subnet_router_anycast; /* Subnet-Router anycast (RFC 4291) */
 | ||||||
|  |  	struct sockaddr_in6 firsthop; | ||||||
|  |  	unsigned char cmsgbuf[4096]; | ||||||
|  |  	size_t cmsglen; | ||||||
|  | diff --git a/ping/ping6_common.c b/ping/ping6_common.c
 | ||||||
|  | index fcb48be..d0d2d84 100644
 | ||||||
|  | --- a/ping/ping6_common.c
 | ||||||
|  | +++ b/ping/ping6_common.c
 | ||||||
|  | @@ -101,6 +101,7 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
 | ||||||
|  |  	      struct socket_st *sock) | ||||||
|  |  { | ||||||
|  |  	int hold, packlen; | ||||||
|  | +	size_t i;
 | ||||||
|  |  	unsigned char *packet; | ||||||
|  |  	char *target; | ||||||
|  |  	struct icmp6_filter filter; | ||||||
|  | @@ -247,6 +248,15 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
 | ||||||
|  |  			rts->pmtudisc = IPV6_PMTUDISC_DO; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* detect Subnet-Router anycast at least for the default prefix 64 */
 | ||||||
|  | +	rts->subnet_router_anycast = 1;
 | ||||||
|  | +	for (i = 8; i < sizeof(struct in6_addr); i++) {
 | ||||||
|  | +		if (rts->whereto6.sin6_addr.s6_addr[i]) {
 | ||||||
|  | +			rts->subnet_router_anycast = 0;
 | ||||||
|  | +			break;
 | ||||||
|  | +		}
 | ||||||
|  | +	}
 | ||||||
|  | +
 | ||||||
|  |  	if (rts->pmtudisc >= 0) { | ||||||
|  |  		if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &rts->pmtudisc, | ||||||
|  |  			       sizeof rts->pmtudisc) == -1) | ||||||
|  | @@ -818,7 +828,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (icmph->icmp6_type == ICMP6_ECHO_REPLY) { | ||||||
|  | -		if (!rts->multicast &&
 | ||||||
|  | +		if (!rts->multicast && !rts->subnet_router_anycast &&
 | ||||||
|  |  		    memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16)) | ||||||
|  |  			return 1; | ||||||
|  |  		if (!is_ours(rts, sock, icmph->icmp6_id)) | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,149 @@ | |||||||
|  | From ea2808dc199b89c12dd3b3a968e67bc0f522d399 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Fri, 15 Oct 2021 17:38:51 +0200 | ||||||
|  | Subject: [PATCH 3/3] ping: Print reply with wrong source with warning | ||||||
|  | 
 | ||||||
|  | 5e052ad ("ping: discard packets with wrong source address") correctly | ||||||
|  | hid replies with wrong source address to comply RFC 1122 (Section | ||||||
|  | 3.2.1.3: "The IP source address in an ICMP Echo Reply MUST be the same | ||||||
|  | as the specific-destination address"). | ||||||
|  | 
 | ||||||
|  | This caused to hide reply when pinging Subnet-Router anycast address. | ||||||
|  | Although it was fixed in the previous commit, relax this to admit the | ||||||
|  | reply but print warning "DIFFERENT ADDRESS!". ping is diagnostic program, | ||||||
|  | with insisting on RFC we force people to use tcpdump to see replies. | ||||||
|  | 
 | ||||||
|  | Link: https://github.com/iputils/iputils/issues/371 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Matteo Croce <mcroce@microsoft.com> | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 5f6bec5ab57cc8beaa78f5756a0ffbdf01f28d36) | ||||||
|  | ---
 | ||||||
|  |  ping/ping.c         | 10 ++++++---- | ||||||
|  |  ping/ping.h         |  3 ++- | ||||||
|  |  ping/ping6_common.c | 13 ++++++++----- | ||||||
|  |  ping/ping_common.c  |  6 +++++- | ||||||
|  |  4 files changed, 21 insertions(+), 11 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping.c b/ping/ping.c
 | ||||||
|  | index 0655bf4..81ee7c8 100644
 | ||||||
|  | --- a/ping/ping.c
 | ||||||
|  | +++ b/ping/ping.c
 | ||||||
|  | @@ -1504,6 +1504,7 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
 | ||||||
|  |  	int reply_ttl; | ||||||
|  |  	uint8_t *opts, *tmp_ttl; | ||||||
|  |  	int olen; | ||||||
|  | +	int wrong_source = 0;
 | ||||||
|  |   | ||||||
|  |  	/* Check the IP header */ | ||||||
|  |  	ip = (struct iphdr *)buf; | ||||||
|  | @@ -1544,15 +1545,16 @@ int ping4_parse_reply(struct ping_rts *rts, struct socket_st *sock,
 | ||||||
|  |  	csfailed = in_cksum((unsigned short *)icp, cc, 0); | ||||||
|  |   | ||||||
|  |  	if (icp->type == ICMP_ECHOREPLY) { | ||||||
|  | -		if (!rts->broadcast_pings && !rts->multicast &&
 | ||||||
|  | -		    from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
 | ||||||
|  | -			return 1;
 | ||||||
|  |  		if (!is_ours(rts, sock, icp->un.echo.id)) | ||||||
|  |  			return 1;			/* 'Twas not our ECHO */ | ||||||
|  | +
 | ||||||
|  | +		if (!rts->broadcast_pings && !rts->multicast &&
 | ||||||
|  | +		    from->sin_addr.s_addr != rts->whereto.sin_addr.s_addr)
 | ||||||
|  | +			wrong_source = 1;
 | ||||||
|  |  		if (gather_statistics(rts, (uint8_t *)icp, sizeof(*icp), cc, | ||||||
|  |  				      ntohs(icp->un.echo.sequence), | ||||||
|  |  				      reply_ttl, 0, tv, pr_addr(rts, from, sizeof *from), | ||||||
|  | -				      pr_echo_reply, rts->multicast)) {
 | ||||||
|  | +				      pr_echo_reply, rts->multicast, wrong_source)) {
 | ||||||
|  |  			fflush(stdout); | ||||||
|  |  			return 0; | ||||||
|  |  		} | ||||||
|  | diff --git a/ping/ping.h b/ping/ping.h
 | ||||||
|  | index f26fdac..703296d 100644
 | ||||||
|  | --- a/ping/ping.h
 | ||||||
|  | +++ b/ping/ping.h
 | ||||||
|  | @@ -389,7 +389,8 @@ extern void common_options(int ch);
 | ||||||
|  |  extern int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen, | ||||||
|  |  			     int cc, uint16_t seq, int hops, | ||||||
|  |  			     int csfailed, struct timeval *tv, char *from, | ||||||
|  | -			     void (*pr_reply)(uint8_t *ptr, int cc), int multicast);
 | ||||||
|  | +			     void (*pr_reply)(uint8_t *ptr, int cc), int multicast,
 | ||||||
|  | +			     int wrong_source);
 | ||||||
|  |  extern void print_timestamp(struct ping_rts *rts); | ||||||
|  |  void fill(struct ping_rts *rts, char *patp, unsigned char *packet, size_t packet_size); | ||||||
|  |   | ||||||
|  | diff --git a/ping/ping6_common.c b/ping/ping6_common.c
 | ||||||
|  | index d0d2d84..4712928 100644
 | ||||||
|  | --- a/ping/ping6_common.c
 | ||||||
|  | +++ b/ping/ping6_common.c
 | ||||||
|  | @@ -802,6 +802,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
 | ||||||
|  |  	struct cmsghdr *c; | ||||||
|  |  	struct icmp6_hdr *icmph; | ||||||
|  |  	int hops = -1; | ||||||
|  | +	int wrong_source = 0;
 | ||||||
|  |   | ||||||
|  |  	for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) { | ||||||
|  |  		if (c->cmsg_level != IPPROTO_IPV6) | ||||||
|  | @@ -828,16 +829,18 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (icmph->icmp6_type == ICMP6_ECHO_REPLY) { | ||||||
|  | -		if (!rts->multicast && !rts->subnet_router_anycast &&
 | ||||||
|  | -		    memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
 | ||||||
|  | -			return 1;
 | ||||||
|  |  		if (!is_ours(rts, sock, icmph->icmp6_id)) | ||||||
|  |  			return 1; | ||||||
|  | +
 | ||||||
|  | +		if (!rts->multicast && !rts->subnet_router_anycast &&
 | ||||||
|  | +		    memcmp(&from->sin6_addr.s6_addr, &rts->whereto6.sin6_addr.s6_addr, 16))
 | ||||||
|  | +			wrong_source = 1;
 | ||||||
|  | +
 | ||||||
|  |  		if (gather_statistics(rts, (uint8_t *)icmph, sizeof(*icmph), cc, | ||||||
|  |  				      ntohs(icmph->icmp6_seq), | ||||||
|  |  				      hops, 0, tv, pr_addr(rts, from, sizeof *from), | ||||||
|  |  				      pr_echo_reply, | ||||||
|  | -				      rts->multicast)) {
 | ||||||
|  | +				      rts->multicast, wrong_source)) {
 | ||||||
|  |  			fflush(stdout); | ||||||
|  |  			return 0; | ||||||
|  |  		} | ||||||
|  | @@ -850,7 +853,7 @@ int ping6_parse_reply(struct ping_rts *rts, socket_st *sock,
 | ||||||
|  |  				      seq, | ||||||
|  |  				      hops, 0, tv, pr_addr(rts, from, sizeof *from), | ||||||
|  |  				      pr_niquery_reply, | ||||||
|  | -				      rts->multicast))
 | ||||||
|  | +				      rts->multicast, 0))
 | ||||||
|  |  			return 0; | ||||||
|  |  	} else { | ||||||
|  |  		int nexthdr; | ||||||
|  | diff --git a/ping/ping_common.c b/ping/ping_common.c
 | ||||||
|  | index 357c39d..0336259 100644
 | ||||||
|  | --- a/ping/ping_common.c
 | ||||||
|  | +++ b/ping/ping_common.c
 | ||||||
|  | @@ -711,7 +711,8 @@ int main_loop(struct ping_rts *rts, ping_func_set_st *fset, socket_st *sock,
 | ||||||
|  |  int gather_statistics(struct ping_rts *rts, uint8_t *icmph, int icmplen, | ||||||
|  |  		      int cc, uint16_t seq, int hops, | ||||||
|  |  		      int csfailed, struct timeval *tv, char *from, | ||||||
|  | -		      void (*pr_reply)(uint8_t *icmph, int cc), int multicast)
 | ||||||
|  | +		      void (*pr_reply)(uint8_t *icmph, int cc), int multicast,
 | ||||||
|  | +		      int wrong_source)
 | ||||||
|  |  { | ||||||
|  |  	int dupflag = 0; | ||||||
|  |  	long triptime = 0; | ||||||
|  | @@ -804,10 +805,13 @@ restamp:
 | ||||||
|  |  				printf(_(" time=%ld.%03ld ms"), triptime / 1000, | ||||||
|  |  				       triptime % 1000); | ||||||
|  |  		} | ||||||
|  | +
 | ||||||
|  |  		if (dupflag && (!multicast || rts->opt_verbose)) | ||||||
|  |  			printf(_(" (DUP!)")); | ||||||
|  |  		if (csfailed) | ||||||
|  |  			printf(_(" (BAD CHECKSUM!)")); | ||||||
|  | +		if (wrong_source)
 | ||||||
|  | +			printf(_(" (DIFFERENT ADDRESS!)"));
 | ||||||
|  |   | ||||||
|  |  		/* check the data */ | ||||||
|  |  		cp = ((unsigned char *)ptr) + sizeof(struct timeval); | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										51
									
								
								SOURCES/010-ping-Fix-socket-error-reporting.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								SOURCES/010-ping-Fix-socket-error-reporting.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | From 42ff1833920e2524b07790243ef9146125f5b2c4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Wed, 10 Aug 2022 21:05:22 +0200 | ||||||
|  | Subject: [PATCH] ping: Fix socket error reporting | ||||||
|  | 
 | ||||||
|  | There is actually no need for errno EAFNOSUPPORT special handling, | ||||||
|  | nor for any other errno. *All* errors needs to be reported on verbose | ||||||
|  | mode or when socket is required. If AF_INET6 socket is used with | ||||||
|  | disabled IPv6, error reporting is done by gai_strerror() (ipv6.disable=1) | ||||||
|  | or by connect() error handling in ping6_run() (EADDRNOTAVAIL on | ||||||
|  | net.ipv6.conf.all.disable_ipv6=1). | ||||||
|  | 
 | ||||||
|  | Bug was hidden because condition "errno == EAFNOSUPPORT && socktype == | ||||||
|  | AF_INET6" introduced in d141cb6 was always false as AF_INET6 is is an address | ||||||
|  | family not a socket type, until otherwise correct fix 904cdb6. Attempt | ||||||
|  | to fix it in 79d713e introduced regression that other errors weren't | ||||||
|  | reported (e.g. EPERM on RAW socket on non-root, see #406). | ||||||
|  | 
 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/418 | ||||||
|  | Fixes: https://github.com/iputils/iputils/issues/406 | ||||||
|  | Fixes: 79d713e ("ping: Remove 'unsupported IPv6' warning on disabled IPv6") | ||||||
|  | Fixes: d141cb6 ("ping: work with older kernels that don't support ping sockets") | ||||||
|  | 
 | ||||||
|  | Reported-by: Benjamin Poirier <benjamin.poirier@gmail.com> | ||||||
|  | Tested-by: Benjamin Poirier <benjamin.poirier@gmail.com> | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit bbe451f91ecc769ac5f70c1269372a6cc28d6814) | ||||||
|  | ---
 | ||||||
|  |  ping/ping.c | 6 +----- | ||||||
|  |  1 file changed, 1 insertion(+), 5 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping.c b/ping/ping.c
 | ||||||
|  | index 81ee7c8..ff7e742 100644
 | ||||||
|  | --- a/ping/ping.c
 | ||||||
|  | +++ b/ping/ping.c
 | ||||||
|  | @@ -147,11 +147,7 @@ static void create_socket(struct ping_rts *rts, socket_st *sock, int family,
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (sock->fd == -1) { | ||||||
|  | -		/* Report error related to disabled IPv6 only when IPv6 also failed or in
 | ||||||
|  | -		 * verbose mode. Report other errors always.
 | ||||||
|  | -		 */
 | ||||||
|  | -		if ((errno == EAFNOSUPPORT && family == AF_INET6 && requisite) ||
 | ||||||
|  | -		    rts->opt_verbose)
 | ||||||
|  | +		if (requisite || rts->opt_verbose)
 | ||||||
|  |  			error(0, errno, "socket"); | ||||||
|  |  		if (requisite) | ||||||
|  |  			exit(2); | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										95
									
								
								SOURCES/011-ping-Fix-ping6-binding-to-VRF-and-address.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								SOURCES/011-ping-Fix-ping6-binding-to-VRF-and-address.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | From 36580e1d539b4bb7c187d4cf9ccc63afad9edbb1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Lahav Schlesinger <lschlesinger@drivenets.com> | ||||||
|  | Date: Wed, 30 Jun 2021 13:06:13 +0300 | ||||||
|  | Subject: [PATCH 1/2] ping: Fix ping6 binding to VRF and address | ||||||
|  | 
 | ||||||
|  | Since Linux kernel commit 1893ff20275b ("net/ipv6: Add l3mdev check to | ||||||
|  | ipv6_chk_addr_and_flags") from v4.17-rc1 ping fails when trying to | ||||||
|  | create IPv6 SOCK_RAW socket (e.g. if net.ipv4.ping_group_range = 1 0) | ||||||
|  | and passing both -I <vrf_interface> and -I <local_ipv6_addr>. | ||||||
|  | It works for IPv4 SOCK_RAW socket. | ||||||
|  | 
 | ||||||
|  |     # ip netns add tmp_ns | ||||||
|  |     # ip -n tmp_ns link add vrf_1 type vrf table 10001 | ||||||
|  |     # ip -n tmp_ns link add lo10 type dummy | ||||||
|  |     # ip -n tmp_ns link set lo10 master vrf_1 | ||||||
|  |     # ip -n tmp_ns link set vrf_1 up | ||||||
|  |     # ip -n tmp_ns link set lo10 up | ||||||
|  |     # ip -n tmp_ns link set lo up | ||||||
|  |     # ip -n tmp_ns addr add 1:2::3:4/128 dev lo10 | ||||||
|  |     # ip -n tmp_ns addr add 1.2.3.4/32 dev lo10 | ||||||
|  | 
 | ||||||
|  |     # ip netns exec tmp_ns ping -6 1:2::3:4 -I vrf_1 -I 1:2::3:4 -c 1 # IPv6 broken | ||||||
|  |     ping: bind icmp socket: Cannot assign requested address | ||||||
|  | 
 | ||||||
|  |     # ping  1.2.3.4 -I vrf_1 -I 1.2.3.4 -c 1 # IPv4 working | ||||||
|  |     PING 1.2.3.4 (1.2.3.4) from 1.2.3.4 vrf_1: 56(84) bytes of data. | ||||||
|  |     64 bytes from 1.2.3.4: icmp_seq=1 ttl=64 time=0.090 ms | ||||||
|  | 
 | ||||||
|  |     --- 1.2.3.4 ping statistics --- | ||||||
|  |     1 packets transmitted, 1 received, 0% packet loss, time 0ms | ||||||
|  |     rtt min/avg/max/mdev = 0.090/0.090/0.090/0.000 ms | ||||||
|  | 
 | ||||||
|  | ping fails because it doesn't actually bind to the VRF interface, while | ||||||
|  | after 1893ff20275b, binding to an IPv6 address searches only on the same | ||||||
|  | l3mdev as the device the function receives. If the socket wasn't | ||||||
|  | SO_BINDTODEVICE-ed, then the kernel will only search for devices that | ||||||
|  | are not ensalved to an l3mdev device (= in the default VRF), which will | ||||||
|  | cause the bind() to fail. | ||||||
|  | 
 | ||||||
|  | Only SOCK_RAW socket is affected. SOCK_DGRAM is not affected because | ||||||
|  | Linux kernel doesn't check the device the socket was SO_BINDTODEVICE-ed | ||||||
|  | to, but only the device from addr->sin6_scope_id (which if none is | ||||||
|  | passed, it will again only search devices in the default VRF). | ||||||
|  | 
 | ||||||
|  | NOTE: creating network namespace to reproduce the issue is needed just | ||||||
|  | on systems with net.ipv4.ping_group_range = 0 2147483647 (e.g. current | ||||||
|  | Fedora, openSUSE, Ubuntu), which causes to use SOCK_DGRAM socket. | ||||||
|  | Alternatively to force SOCK_RAW to it'd be enough just to properly set | ||||||
|  | net.ipv4.ping_group_range: | ||||||
|  | 
 | ||||||
|  |     # echo "1 0" > /proc/sys/net/ipv4/ping_group_range | ||||||
|  | 
 | ||||||
|  | Closes: https://github.com/iputils/iputils/pull/344 | ||||||
|  | 
 | ||||||
|  | Reviewed-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Signed-off-by: Lahav Schlesinger <lschlesinger@drivenets.com> | ||||||
|  | [ pvorel: adjusted commit message ] | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit 7c65999f98bc4a1984594b7fad1af0eaf0b9d34b) | ||||||
|  | ---
 | ||||||
|  |  ping/ping6_common.c | 11 +++++++++++ | ||||||
|  |  1 file changed, 11 insertions(+) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping6_common.c b/ping/ping6_common.c
 | ||||||
|  | index 4712928..98b5adb 100644
 | ||||||
|  | --- a/ping/ping6_common.c
 | ||||||
|  | +++ b/ping/ping6_common.c
 | ||||||
|  | @@ -223,6 +223,8 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
 | ||||||
|  |  	if (rts->device) { | ||||||
|  |  		struct cmsghdr *cmsg; | ||||||
|  |  		struct in6_pktinfo *ipi; | ||||||
|  | +		int rc;
 | ||||||
|  | +		int errno_save;
 | ||||||
|  |   | ||||||
|  |  		cmsg = (struct cmsghdr *)(rts->cmsgbuf + rts->cmsglen); | ||||||
|  |  		rts->cmsglen += CMSG_SPACE(sizeof(*ipi)); | ||||||
|  | @@ -233,6 +235,15 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
 | ||||||
|  |  		ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg); | ||||||
|  |  		memset(ipi, 0, sizeof(*ipi)); | ||||||
|  |  		ipi->ipi6_ifindex = if_name2index(rts->device); | ||||||
|  | +
 | ||||||
|  | +		enable_capability_raw();
 | ||||||
|  | +		rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
 | ||||||
|  | +				rts->device, strlen(rts->device) + 1);
 | ||||||
|  | +		errno_save = errno;
 | ||||||
|  | +		disable_capability_raw();
 | ||||||
|  | +
 | ||||||
|  | +		if (rc == -1)
 | ||||||
|  | +			error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (IN6_IS_ADDR_MULTICAST(&rts->whereto6.sin6_addr)) { | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										54
									
								
								SOURCES/012-ping6-Avoid-binding-to-non-VRF.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								SOURCES/012-ping6-Avoid-binding-to-non-VRF.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | |||||||
|  | From a2d2428c5fa6bf370486f509b18862c5c7b8b47e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Petr Vorel <pvorel@suse.cz> | ||||||
|  | Date: Tue, 9 Nov 2021 02:39:56 +0100 | ||||||
|  | Subject: [PATCH 2/2] ping6: Avoid binding to non-VRF | ||||||
|  | 
 | ||||||
|  | This fixes permission issue when specifying just address (without VRF) | ||||||
|  | unless having CAP_NET_ADMIN (i.e. root) permission: | ||||||
|  | 
 | ||||||
|  |     $ ./builddir/ping/ping -c1 -I lo ::1 | ||||||
|  |     ./builddir/ping/ping: SO_BINDTODEVICE lo: Operation not permitted | ||||||
|  | 
 | ||||||
|  | because setsockopt() SO_BINDTODEVICE (similar to bind()) can be only done on | ||||||
|  | opt_strictsource. | ||||||
|  | 
 | ||||||
|  | Fixes: 7c65999 ("ping: Fix ping6 binding to VRF and address") | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Petr Vorel <pvorel@suse.cz> | ||||||
|  | (cherry picked from commit f52b582248f1f870e870a9973621805d969906b4) | ||||||
|  | ---
 | ||||||
|  |  ping/ping6_common.c | 18 ++++++++++-------- | ||||||
|  |  1 file changed, 10 insertions(+), 8 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/ping/ping6_common.c b/ping/ping6_common.c
 | ||||||
|  | index 98b5adb..a784be0 100644
 | ||||||
|  | --- a/ping/ping6_common.c
 | ||||||
|  | +++ b/ping/ping6_common.c
 | ||||||
|  | @@ -236,14 +236,16 @@ int ping6_run(struct ping_rts *rts, int argc, char **argv, struct addrinfo *ai,
 | ||||||
|  |  		memset(ipi, 0, sizeof(*ipi)); | ||||||
|  |  		ipi->ipi6_ifindex = if_name2index(rts->device); | ||||||
|  |   | ||||||
|  | -		enable_capability_raw();
 | ||||||
|  | -		rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
 | ||||||
|  | -				rts->device, strlen(rts->device) + 1);
 | ||||||
|  | -		errno_save = errno;
 | ||||||
|  | -		disable_capability_raw();
 | ||||||
|  | -
 | ||||||
|  | -		if (rc == -1)
 | ||||||
|  | -			error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
 | ||||||
|  | +		if (rts->opt_strictsource) {
 | ||||||
|  | +			enable_capability_raw();
 | ||||||
|  | +			rc = setsockopt(sock->fd, SOL_SOCKET, SO_BINDTODEVICE,
 | ||||||
|  | +					rts->device, strlen(rts->device) + 1);
 | ||||||
|  | +			errno_save = errno;
 | ||||||
|  | +			disable_capability_raw();
 | ||||||
|  | +
 | ||||||
|  | +			if (rc == -1)
 | ||||||
|  | +				error(2, errno_save, "SO_BINDTODEVICE %s", rts->device);
 | ||||||
|  | +		}
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (IN6_IS_ADDR_MULTICAST(&rts->whereto6.sin6_addr)) { | ||||||
|  | -- 
 | ||||||
|  | 2.46.0 | ||||||
|  | 
 | ||||||
| @ -3,7 +3,7 @@ | |||||||
| Summary: Network monitoring tools including ping | Summary: Network monitoring tools including ping | ||||||
| Name: iputils | Name: iputils | ||||||
| Version: 20210202 | Version: 20210202 | ||||||
| Release: 9%{?dist} | Release: 11%{?dist} | ||||||
| # some parts are under the original BSD (ping.c) | # some parts are under the original BSD (ping.c) | ||||||
| # some are under GPLv2+ (tracepath.c) | # some are under GPLv2+ (tracepath.c) | ||||||
| License: BSD and GPLv2+ | License: BSD and GPLv2+ | ||||||
| @ -20,6 +20,17 @@ Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt | |||||||
| 
 | 
 | ||||||
| # Upstream patches | # Upstream patches | ||||||
| Patch001: 001-ping-remove-unsupported-IPv6-warning-on-disabled-IPv6.patch | Patch001: 001-ping-remove-unsupported-IPv6-warning-on-disabled-IPv6.patch | ||||||
|  | Patch002: 002-arping-Fix-1s-delay-on-exit-for-unsolicited-arpings.patch | ||||||
|  | Patch003: 003-arping-Fix-unsolicited-ARP-regressions-on-c-1.patch | ||||||
|  | Patch004: 004-arping-fix-typo-in-error-checking.patch | ||||||
|  | Patch005: 005-arping-exit-0-if-running-in-deadline-mode-and-we-see.patch | ||||||
|  | Patch006: 006-Revert-Add-strict-pattern-matching-on-response-when-.patch | ||||||
|  | Patch007: 007-ping-Move-ping_rts-multicast.patch | ||||||
|  | Patch008: 008-ping-Print-reply-from-Subnet-Router-anycast-address.patch | ||||||
|  | Patch009: 009-ping-Print-reply-with-wrong-source-with-warning.patch | ||||||
|  | Patch010: 010-ping-Fix-socket-error-reporting.patch | ||||||
|  | Patch011: 011-ping-Fix-ping6-binding-to-VRF-and-address.patch | ||||||
|  | Patch012: 012-ping6-Avoid-binding-to-non-VRF.patch | ||||||
| 
 | 
 | ||||||
| # Downstream-only patches | # Downstream-only patches | ||||||
| Patch100: 100-iputils-ifenslave.patch | Patch100: 100-iputils-ifenslave.patch | ||||||
| @ -130,6 +141,15 @@ install -cp ifenslave.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/ | |||||||
| %attr(644,root,root) %{_mandir}/man8/ninfod.8.gz | %attr(644,root,root) %{_mandir}/man8/ninfod.8.gz | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Fri Sep 06 2024 Jan Macku <jamacku@redhat.com> - 20210202-11 | ||||||
|  | - ping: Fix ping6 binding to VRF and address (RHEL-57734) | ||||||
|  | 
 | ||||||
|  | * Wed Aug 28 2024 Jan Macku <jamacku@redhat.com> - 20210202-10 | ||||||
|  | - arping: Fix 1s delay on exit for unsolicited arpings (RHEL-34110) | ||||||
|  | - arping: exit 0 if running in deadline mode and we see replies (RHEL-27718) | ||||||
|  | - ping: Print reply with wrong source with warning & some follow-up fixes (RHEL-12789, RHEL-13480) | ||||||
|  | - ping: Fix socket error reporting (RHEL-4608) | ||||||
|  | 
 | ||||||
| * Wed May 03 2023 Jan Macku <jamacku@redhat.com> - 20210202-9 | * Wed May 03 2023 Jan Macku <jamacku@redhat.com> - 20210202-9 | ||||||
| - ping: Remove 'unsupported IPv6' warning on disabled IPv6 (rhbz#2152511) | - ping: Remove 'unsupported IPv6' warning on disabled IPv6 (rhbz#2152511) | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user