summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/ip_icmp.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 340efd4..a157dd5 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -110,6 +110,10 @@ static int icmplim_output = 1;
SYSCTL_INT(_net_inet_icmp, OID_AUTO, icmplim_output, CTLFLAG_RW,
&icmplim_output, 0, "");
+static char reply_src[IFNAMSIZ+1];
+SYSCTL_STRING(_net_inet_icmp, OID_AUTO, reply_src, CTLFLAG_RW,
+ &reply_src, IFNAMSIZ, "icmp reply source for non-local packets.");
+
/*
* ICMP broadcast echo sysctl
*/
@@ -618,6 +622,7 @@ icmp_reflect(m)
{
struct ip *ip = mtod(m, struct ip *);
struct ifaddr *ifa;
+ struct ifnet *ifn;
struct in_ifaddr *ia;
struct in_addr t;
struct mbuf *opts = 0;
@@ -658,6 +663,20 @@ icmp_reflect(m)
goto match;
}
}
+ /*
+ * If the incoming packet was not addressed directly to us, use
+ * designated interface for icmp replies specified by sysctl
+ * net.inet.icmp.reply_src (default not set). Otherwise continue
+ * with normal source selection.
+ */
+ if (reply_src[0] != '\0' && (ifn = ifunit(reply_src))) {
+ TAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
+ if (ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+ ia = ifatoia(ifa);
+ goto match;
+ }
+ }
/*
* If the packet was transiting through us, use the address of
* the interface that is the closest to the packet source.
OpenPOWER on IntegriCloud