routing: Bring back the ability to specify transmit interface via its name.
Some software references outgoing interfaces by specifying name instead of index. Use rti_ifp from rt_addrinfo if provided instead of always using address interface when constructing nexthop. PR: 255678 Reported by: martin.larsson2 at gmail.com MFC after: 1 week
This commit is contained in:
parent
0939f965d8
commit
d98954e229
@ -502,6 +502,38 @@ rt_flushifroutes(struct ifnet *ifp)
|
||||
rib_foreach_table_walk_del(AF_UNSPEC, rt_ifdelroute, ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tries to extract interface from RTAX_IFP passed in rt_addrinfo.
|
||||
* Interface can be specified ether as interface index (sdl_index) or
|
||||
* the interface name (sdl_data).
|
||||
*
|
||||
* Returns found ifp or NULL
|
||||
*/
|
||||
static struct ifnet *
|
||||
info_get_ifp(struct rt_addrinfo *info)
|
||||
{
|
||||
const struct sockaddr_dl *sdl;
|
||||
|
||||
sdl = (const struct sockaddr_dl *)info->rti_info[RTAX_IFP];
|
||||
if (sdl->sdl_family != AF_LINK)
|
||||
return (NULL);
|
||||
|
||||
if (sdl->sdl_index != 0)
|
||||
return (ifnet_byindex(sdl->sdl_index));
|
||||
if (sdl->sdl_nlen > 0) {
|
||||
char if_name[IF_NAMESIZE];
|
||||
if (sdl->sdl_nlen + offsetof(struct sockaddr_dl, sdl_data) > sdl->sdl_len)
|
||||
return (NULL);
|
||||
if (sdl->sdl_nlen >= IF_NAMESIZE)
|
||||
return (NULL);
|
||||
bzero(if_name, sizeof(if_name));
|
||||
memcpy(if_name, sdl->sdl_data, sdl->sdl_nlen);
|
||||
return (ifunit(if_name));
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up rt_addrinfo for a specific fib.
|
||||
*
|
||||
@ -511,12 +543,11 @@ rt_flushifroutes(struct ifnet *ifp)
|
||||
int
|
||||
rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
|
||||
{
|
||||
const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr;
|
||||
const struct sockaddr *dst, *gateway, *ifaaddr;
|
||||
int error, flags;
|
||||
|
||||
dst = info->rti_info[RTAX_DST];
|
||||
gateway = info->rti_info[RTAX_GATEWAY];
|
||||
ifpaddr = info->rti_info[RTAX_IFP];
|
||||
ifaaddr = info->rti_info[RTAX_IFA];
|
||||
flags = info->rti_flags;
|
||||
|
||||
@ -526,13 +557,9 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
|
||||
*/
|
||||
error = 0;
|
||||
|
||||
/* If we have interface specified by the ifindex in the address, use it */
|
||||
if (info->rti_ifp == NULL && ifpaddr != NULL &&
|
||||
ifpaddr->sa_family == AF_LINK) {
|
||||
const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr;
|
||||
if (sdl->sdl_index != 0)
|
||||
info->rti_ifp = ifnet_byindex(sdl->sdl_index);
|
||||
}
|
||||
/* If we have interface specified by RTAX_IFP address, try to use it */
|
||||
if ((info->rti_ifp == NULL) && (info->rti_info[RTAX_IFP] != NULL))
|
||||
info->rti_ifp = info_get_ifp(info);
|
||||
/*
|
||||
* If we have source address specified, try to find it
|
||||
* TODO: avoid enumerating all ifas on all interfaces.
|
||||
|
@ -286,7 +286,7 @@ fill_nhop_from_info(struct nhop_priv *nh_priv, struct rt_addrinfo *info)
|
||||
if ((error = set_nhop_gw_from_info(nh, info)) != 0)
|
||||
return (error);
|
||||
|
||||
nh->nh_ifp = info->rti_ifa->ifa_ifp;
|
||||
nh->nh_ifp = (info->rti_ifp != NULL) ? info->rti_ifp : info->rti_ifa->ifa_ifp;
|
||||
nh->nh_ifa = info->rti_ifa;
|
||||
/* depends on the gateway */
|
||||
nh->nh_aifp = get_aifp(nh);
|
||||
|
Loading…
Reference in New Issue
Block a user