diff mbox

ping: ping doesn't work correctly with -m option

Message ID 7E20C7B36969D643A89BC9AE4BF0F3A422D31D95@MX102CL01.corp.emc.com
State Not Applicable, archived
Delegated to: David Miller
Headers show

Commit Message

Kovalev, Sergey May 18, 2015, 12:37 p.m. UTC
The "ping" or "ping6" with parameter "-m" doesn't work when "main" and "default" table are empty (or do not have any route to destination IP).
If we don't specify source IP address for the ping, the ping will try to determine the source IP automatically. To do so it creates the probe UDP socket, and try to connect to dst IP on that socket. The connect should make routing decision based on current Linux routing.  If connection succeeded it takes source IP (however it doesn't use it in future indeed). The issue is that PIGN doesn't specify fwmark for that probe socket as a result connection fails with "Network unreachable" error.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

--- ./ping.c.origin     2015-05-12 09:01:16.000000000 -0400
+++ ./ping.c    		2015-05-13 07:34:06.000000000 -0400
@@ -107,6 +107,7 @@ 
 struct sockaddr_in source;
 char *device;
 int pmtudisc = -1;
+extern int mark;


 int
@@ -305,6 +306,12 @@ 
                                }
                        }
                }
+        if (options & F_MARK) {
+            if (setsockopt(probe_fd, SOL_SOCKET, SO_MARK,
+                        &mark, sizeof(mark)) == -1) {
+                fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
+            }
+        }

                if (settos &&
                    setsockopt(probe_fd, IPPROTO_IP, IP_TOS, (char *)&settos, sizeof(int)) < 0)
--- ./ping6.c.origin    2015-05-12 09:01:16.000000000 -0400
+++ ./ping6.c   		2015-05-13 07:33:39.000000000 -0400
@@ -137,7 +137,7 @@ 
 int pmtudisc=-1;

 static int icmp_sock;
-
+extern int mark;


 static struct in6_addr in6_anyaddr;
@@ -385,6 +385,12 @@ 
 #endif
                        }
                }
+        if (options & F_MARK) {
+            if (setsockopt(probe_fd, SOL_SOCKET, SO_MARK,
+                        &mark, sizeof(mark)) == -1) {
+                fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
+            }
+        }
                firsthop.sin6_port = htons(1025);
                if (connect(probe_fd, (struct sockaddr*)&firsthop, sizeof(firsthop)) == -1) {
                        perror("connect");