Add an additional routing table lookup when m->m_pkthdr.fibnum is changed
at a PFIL hook in ip{,6}_output(). IPFW setfib rule did not perform a routing table lookup when the destination address was not changed. CR: D805
This commit is contained in:
parent
394c813d06
commit
9c57a5b630
@ -136,7 +136,9 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
struct rtentry *rte; /* cache for ro->ro_rt */
|
||||
struct in_addr odst;
|
||||
struct m_tag *fwd_tag = NULL;
|
||||
uint32_t fibnum;
|
||||
int have_ia_ref;
|
||||
int needfiblookup;
|
||||
#ifdef IPSEC
|
||||
int no_route_but_check_spd = 0;
|
||||
#endif
|
||||
@ -202,6 +204,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
* therefore we need restore gw if we're redoing lookup.
|
||||
*/
|
||||
gw = dst = (struct sockaddr_in *)&ro->ro_dst;
|
||||
fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m);
|
||||
again:
|
||||
ia = NULL;
|
||||
have_ia_ref = 0;
|
||||
@ -283,10 +286,9 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
#ifdef RADIX_MPATH
|
||||
rtalloc_mpath_fib(ro,
|
||||
ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr),
|
||||
inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
|
||||
fibnum);
|
||||
#else
|
||||
in_rtalloc_ign(ro, 0,
|
||||
inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
|
||||
in_rtalloc_ign(ro, 0, fibnum);
|
||||
#endif
|
||||
rte = ro->ro_rt;
|
||||
}
|
||||
@ -504,6 +506,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
goto done;
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
needfiblookup = 0;
|
||||
|
||||
/* See if destination IP address was changed by packet filter. */
|
||||
if (odst.s_addr != ip->ip_dst.s_addr) {
|
||||
@ -529,9 +532,18 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
} else {
|
||||
if (have_ia_ref)
|
||||
ifa_free(&ia->ia_ifa);
|
||||
goto again; /* Redo the routing table lookup. */
|
||||
needfiblookup = 1; /* Redo the routing table lookup. */
|
||||
}
|
||||
}
|
||||
/* See if fib was changed by packet filter. */
|
||||
if (fibnum != M_GETFIB(m)) {
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
fibnum = M_GETFIB(m);
|
||||
RO_RTFREE(ro);
|
||||
needfiblookup = 1;
|
||||
}
|
||||
if (needfiblookup)
|
||||
goto again;
|
||||
|
||||
/* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */
|
||||
if (m->m_flags & M_FASTFWD_OURS) {
|
||||
|
@ -255,6 +255,8 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
struct route_in6 *ro_pmtu = NULL;
|
||||
int hdrsplit = 0;
|
||||
int sw_csum, tso;
|
||||
int needfiblookup;
|
||||
uint32_t fibnum;
|
||||
struct m_tag *fwd_tag = NULL;
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
@ -448,6 +450,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
if (ro->ro_rt == NULL)
|
||||
(void )flowtable_lookup(AF_INET6, m, (struct route *)ro);
|
||||
#endif
|
||||
fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m);
|
||||
again:
|
||||
/*
|
||||
* if specified, try to fill in the traffic class field.
|
||||
@ -489,7 +492,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
dst_sa.sin6_addr = ip6->ip6_dst;
|
||||
}
|
||||
error = in6_selectroute_fib(&dst_sa, opt, im6o, ro, &ifp,
|
||||
&rt, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m));
|
||||
&rt, fibnum);
|
||||
if (error != 0) {
|
||||
if (ifp != NULL)
|
||||
in6_ifstat_inc(ifp, ifs6_out_discard);
|
||||
@ -649,7 +652,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
|
||||
/* Determine path MTU. */
|
||||
if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu,
|
||||
&alwaysfrag, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m))) != 0)
|
||||
&alwaysfrag, fibnum)) != 0)
|
||||
goto bad;
|
||||
|
||||
/*
|
||||
@ -727,6 +730,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
goto done;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
needfiblookup = 0;
|
||||
/* See if destination IP address was changed by packet filter. */
|
||||
if (!IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst)) {
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
@ -747,8 +751,17 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
error = netisr_queue(NETISR_IPV6, m);
|
||||
goto done;
|
||||
} else
|
||||
goto again; /* Redo the routing table lookup. */
|
||||
needfiblookup = 1; /* Redo the routing table lookup. */
|
||||
}
|
||||
/* See if fib was changed by packet filter. */
|
||||
if (fibnum != M_GETFIB(m)) {
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
fibnum = M_GETFIB(m);
|
||||
RO_RTFREE(ro);
|
||||
needfiblookup = 1;
|
||||
}
|
||||
if (needfiblookup)
|
||||
goto again;
|
||||
|
||||
/* See if local, if yes, send it to netisr. */
|
||||
if (m->m_flags & M_FASTFWD_OURS) {
|
||||
|
Loading…
Reference in New Issue
Block a user