From 053154e5c3deb40890fc20a50de434f3811f6ffc Mon Sep 17 00:00:00 2001 From: david Date: Tue, 30 Aug 2011 04:18:58 +0000 Subject: [PATCH] Honor sin6_scope_id in route_dst_generic. This is set nonzero when there is a scope identifier at the end of an IPv6 address, like fe80::a8bb:ccff:fedd:eeff%eth0. When this happens, we look up the interface by index and then act as if it was the interface given by -e. (But -e always has precedence over this.) --- libnetutil/netutil.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index d0aae504f..d85929c18 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -3094,6 +3094,7 @@ static int route_dst_generic(const struct sockaddr_storage *dst, struct sys_route *routes; int numroutes = 0; int i; + char namebuf[IFNAMSIZ]; char errstr[256]; errstr[0]='\0'; @@ -3107,10 +3108,21 @@ static int route_dst_generic(const struct sockaddr_storage *dst, assert(device!=NULL && device[0]!='\0'); } + /* Check if there is an interface scope on the address. */ + if (device == NULL || device[0] == '\0') { + if (dst->ss_family == AF_INET6) { + const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) dst; + if (sin6->sin6_scope_id > 0) { + device = if_indextoname(sin6->sin6_scope_id, namebuf); + assert(device != NULL); + } + } + } + if (device!=NULL && device[0]!='\0'){ iface = getInterfaceByName(device, dst->ss_family); if (!iface) - netutil_fatal("Could not find interface %s which was specified by -e", device); + netutil_fatal("Could not find interface %s", device); } else { iface = NULL; }