Simplify nhop operations in ip_output().

Consistently use `nh` instead of always dereferencing
 ro->ro_nh inside the if block.
Always use nexthop mtu, as it provides guarantee that mtu is accurate.
Pass `nh` pointer to rt_update_ro_flags() to allow upcoming uses
 of updating ro flags based on different nexthop.

Differential Revision: https://reviews.freebsd.org/D31451
Reviewed by:	kp
MFC after: 2 weeks
This commit is contained in:
Alexander V. Chernikov 2021-08-07 11:18:02 +00:00
parent 04389c855e
commit 9748eb7427
2 changed files with 32 additions and 16 deletions

View File

@ -567,6 +567,24 @@ rib_add_route(uint32_t fibnum, struct rt_addrinfo *info,
return (error);
}
/*
* Checks if @dst and @gateway is valid combination.
*
* Returns true if is valid, false otherwise.
*/
static bool
check_gateway(struct rib_head *rnh, struct sockaddr *dst,
struct sockaddr *gateway)
{
if (dst->sa_family == gateway->sa_family)
return (true);
else if (gateway->sa_family == AF_UNSPEC)
return (true);
else if (gateway->sa_family == AF_LINK)
return (true);
return (false);
}
/*
* Creates rtentry and nexthop based on @info data.
* Return 0 and fills in rtentry into @prt on success,
@ -589,8 +607,7 @@ create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info,
if ((flags & RTF_GATEWAY) && !gateway)
return (EINVAL);
if (dst && gateway && (dst->sa_family != gateway->sa_family) &&
(gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK))
if (dst && gateway && !check_gateway(rnh, dst, gateway))
return (EINVAL);
if (dst->sa_len > sizeof(((struct rtentry *)NULL)->rt_dstb))

View File

@ -293,9 +293,9 @@ ip_output_send(struct inpcb *inp, struct ifnet *ifp, struct mbuf *m,
/* rte<>ro_flags translation */
static inline void
rt_update_ro_flags(struct route *ro)
rt_update_ro_flags(struct route *ro, const struct nhop_object *nh)
{
int nh_flags = ro->ro_nh->nh_flags;
int nh_flags = nh->nh_flags;
ro->ro_flags &= ~ (RT_REJECT|RT_BLACKHOLE|RT_HAS_GW);
@ -495,22 +495,21 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
goto bad;
}
}
ia = ifatoia(ro->ro_nh->nh_ifa);
ifp = ro->ro_nh->nh_ifp;
counter_u64_add(ro->ro_nh->nh_pksent, 1);
rt_update_ro_flags(ro);
if (ro->ro_nh->nh_flags & NHF_GATEWAY)
gw = &ro->ro_nh->gw4_sa;
if (ro->ro_nh->nh_flags & NHF_HOST)
isbroadcast = (ro->ro_nh->nh_flags & NHF_BROADCAST);
struct nhop_object *nh = ro->ro_nh;
ia = ifatoia(nh->nh_ifa);
ifp = nh->nh_ifp;
counter_u64_add(nh->nh_pksent, 1);
rt_update_ro_flags(ro, nh);
if (nh->nh_flags & NHF_GATEWAY)
gw = &nh->gw4_sa;
if (nh->nh_flags & NHF_HOST)
isbroadcast = (nh->nh_flags & NHF_BROADCAST);
else if (ifp->if_flags & IFF_BROADCAST)
isbroadcast = in_ifaddr_broadcast(gw->sin_addr, ia);
else
isbroadcast = 0;
if (ro->ro_nh->nh_flags & NHF_HOST)
mtu = ro->ro_nh->nh_mtu;
else
mtu = ifp->if_mtu;
mtu = nh->nh_mtu;
src = IA_SIN(ia)->sin_addr;
} else {
struct nhop_object *nh;