Add an option to have ICMP replies to non-local packets generated with

the IP address the packet came through in.  This is useful for routers
to show in traceroutes the actual path a packet has taken instead of
the possibly different return path.

The new sysctl is named net.inet.icmp.reply_from_interface and defaults
to off.

MFC after:	2 weeks
This commit is contained in:
andre 2005-08-21 12:29:39 +00:00
parent ea31044737
commit cd4fd9f0b7
2 changed files with 29 additions and 1 deletions

View File

@ -32,7 +32,7 @@
.\" @(#)icmp.4 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd March 21, 2003
.Dd August 21, 2005
.Dt ICMP 4
.Os
.Sh NAME
@ -137,6 +137,15 @@ Defaults to false.
An interface name used for the ICMP reply source in response to packets
which are not directly addressed to us.
By default continue with normal source selection.
.It Va reply_from_interface
.Pq Vt boolean
Use the IP address of the interface the packet came through in for
responses to packets which are not directly addressed to us.
If enabled this rule is processed before all others.
By default continue with normal source selection.
Enabling this option is particularly useful on routers because it
makes external traceroutes show the actual path a packet has taken
instead of the possibly different return path.
.El
.Sh ERRORS
A socket operation may fail with one of the following errors returned:

View File

@ -110,6 +110,11 @@ static char reply_src[IFNAMSIZ];
SYSCTL_STRING(_net_inet_icmp, OID_AUTO, reply_src, CTLFLAG_RW,
&reply_src, IFNAMSIZ, "icmp reply source for non-local packets.");
static int icmp_rfi = 0;
SYSCTL_INT(_net_inet_icmp, OID_AUTO, reply_from_interface, CTLFLAG_RW,
&icmp_rfi, 0, "ICMP reply from incoming interface for "
"non-local packets");
/*
* ICMP broadcast echo sysctl
*/
@ -623,6 +628,20 @@ icmp_reflect(m)
goto match;
}
}
/*
* If the packet was transiting through us, use the address of
* the interface the packet came through in. If that interface
* doesn't have a suitable IP address, the normal selection
* criteria apply.
*/
if (icmp_rfi && m->m_pkthdr.rcvif != NULL) {
TAILQ_FOREACH(ifa, &m->m_pkthdr.rcvif->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = ifatoia(ifa);
goto match;
}
}
/*
* If the incoming packet was not addressed directly to us, use
* designated interface for icmp replies specified by sysctl