Remove the global one-level rtcache variable and associated
complex locking and rework ip_rtaddr() to do its own rtlookup. Adopt all its callers to this and make ip_output() callable with NULL rt pointer. Reviewed by: sam (mentor)
This commit is contained in:
parent
9365176c26
commit
02c1c7070e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122708
@ -134,13 +134,6 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the new route created successfully, and we are forwarding,
|
||||
* flush any cached routes to avoid using a stale value.
|
||||
*/
|
||||
if (ret != NULL && ipforwarding)
|
||||
ip_forward_cacheinval();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1160,7 +1160,6 @@ send_pkt(struct ipfw_flow_id *id, u_int32_t seq, u_int32_t ack, int flags)
|
||||
struct mbuf *m;
|
||||
struct ip *ip;
|
||||
struct tcphdr *tcp;
|
||||
struct route sro; /* fake route */
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
if (m == 0)
|
||||
@ -1226,12 +1225,8 @@ send_pkt(struct ipfw_flow_id *id, u_int32_t seq, u_int32_t ack, int flags)
|
||||
*/
|
||||
ip->ip_ttl = ip_defttl;
|
||||
ip->ip_len = m->m_pkthdr.len;
|
||||
bzero (&sro, sizeof (sro));
|
||||
ip_rtaddr(ip->ip_dst, &sro);
|
||||
m->m_flags |= M_SKIP_FIREWALL;
|
||||
ip_output(m, NULL, &sro, 0, NULL, NULL);
|
||||
if (sro.ro_rt)
|
||||
RTFREE(sro.ro_rt);
|
||||
ip_output(m, NULL, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,7 +120,7 @@ int icmpprintfs = 0;
|
||||
#endif
|
||||
|
||||
static void icmp_reflect(struct mbuf *);
|
||||
static void icmp_send(struct mbuf *, struct mbuf *, struct route *);
|
||||
static void icmp_send(struct mbuf *, struct mbuf *);
|
||||
static int ip_next_mtu(int, int);
|
||||
|
||||
extern struct protosw inetsw[];
|
||||
@ -615,7 +615,6 @@ icmp_reflect(m)
|
||||
struct in_addr t;
|
||||
struct mbuf *opts = 0;
|
||||
int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
|
||||
struct route *ro = NULL, rt;
|
||||
|
||||
if (!in_canforward(ip->ip_src) &&
|
||||
((ntohl(ip->ip_src.s_addr) & IN_CLASSA_NET) !=
|
||||
@ -626,8 +625,6 @@ icmp_reflect(m)
|
||||
}
|
||||
t = ip->ip_dst;
|
||||
ip->ip_dst = ip->ip_src;
|
||||
ro = &rt;
|
||||
bzero(ro, sizeof(*ro));
|
||||
/*
|
||||
* If the incoming packet was addressed directly to us,
|
||||
* use dst as the src for the reply. Otherwise (broadcast
|
||||
@ -648,7 +645,7 @@ icmp_reflect(m)
|
||||
goto match;
|
||||
}
|
||||
}
|
||||
ia = ip_rtaddr(ip->ip_dst, ro);
|
||||
ia = ip_rtaddr(ip->ip_dst);
|
||||
/* We need a route to do anything useful. */
|
||||
if (ia == NULL) {
|
||||
m_freem(m);
|
||||
@ -738,12 +735,10 @@ icmp_reflect(m)
|
||||
}
|
||||
m_tag_delete_nonpersistent(m);
|
||||
m->m_flags &= ~(M_BCAST|M_MCAST);
|
||||
icmp_send(m, opts, ro);
|
||||
icmp_send(m, opts);
|
||||
done:
|
||||
if (opts)
|
||||
(void)m_free(opts);
|
||||
if (ro && ro->ro_rt)
|
||||
RTFREE(ro->ro_rt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -751,10 +746,9 @@ icmp_reflect(m)
|
||||
* after supplying a checksum.
|
||||
*/
|
||||
static void
|
||||
icmp_send(m, opts, rt)
|
||||
icmp_send(m, opts)
|
||||
register struct mbuf *m;
|
||||
struct mbuf *opts;
|
||||
struct route *rt;
|
||||
{
|
||||
register struct ip *ip = mtod(m, struct ip *);
|
||||
register int hlen;
|
||||
@ -777,7 +771,7 @@ icmp_send(m, opts, rt)
|
||||
buf, inet_ntoa(ip->ip_src));
|
||||
}
|
||||
#endif
|
||||
(void) ip_output(m, opts, rt, 0, NULL, NULL);
|
||||
(void) ip_output(m, opts, NULL, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
n_time
|
||||
|
@ -212,52 +212,6 @@ int fw_one_pass = 1;
|
||||
/* Dummynet hooks */
|
||||
ip_dn_io_t *ip_dn_io_ptr;
|
||||
|
||||
/*
|
||||
* One deep route cache for ip forwarding. This is done
|
||||
* very inefficiently. We don't care as it's about to be
|
||||
* replaced by something better.
|
||||
*/
|
||||
static struct rtcache {
|
||||
struct route rc_ro; /* most recently used route */
|
||||
struct mtx rc_mtx; /* update lock for cache */
|
||||
} ip_fwdcache;
|
||||
|
||||
#define RTCACHE_LOCK() mtx_lock(&ip_fwdcache.rc_mtx)
|
||||
#define RTCACHE_UNLOCK() mtx_unlock(&ip_fwdcache.rc_mtx)
|
||||
#define RTCACHE_LOCK_INIT() \
|
||||
mtx_init(&ip_fwdcache.rc_mtx, "route cache", NULL, MTX_DEF)
|
||||
#define RTCACHE_LOCK_ASSERT() mtx_assert(&ip_fwdcache.rc_mtx, MA_OWNED)
|
||||
|
||||
/*
|
||||
* Get a copy of the current route cache contents.
|
||||
*/
|
||||
#define RTCACHE_GET(_ro) do { \
|
||||
struct rtentry *rt; \
|
||||
RTCACHE_LOCK(); \
|
||||
*(_ro) = ip_fwdcache.rc_ro; \
|
||||
if ((rt = (_ro)->ro_rt) != NULL) { \
|
||||
RT_LOCK(rt); \
|
||||
RT_ADDREF(rt); \
|
||||
RT_UNLOCK(rt); \
|
||||
} \
|
||||
RTCACHE_UNLOCK(); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Update the cache contents.
|
||||
*/
|
||||
#define RTCACHE_UPDATE(_ro) do { \
|
||||
struct rtentry *rt; \
|
||||
RTCACHE_LOCK(); \
|
||||
rt = ip_fwdcache.rc_ro.ro_rt; \
|
||||
if ((_ro)->ro_rt != rt) { \
|
||||
ip_fwdcache.rc_ro = *(_ro); \
|
||||
if (rt) \
|
||||
RTFREE(rt); \
|
||||
} \
|
||||
RTCACHE_UNLOCK(); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* XXX this is ugly -- the following two global variables are
|
||||
* used to store packet state while it travels through the stack.
|
||||
@ -282,7 +236,7 @@ static struct ip_srcrt {
|
||||
static void save_rte(u_char *, struct in_addr);
|
||||
static int ip_dooptions(struct mbuf *m, int,
|
||||
struct sockaddr_in *next_hop);
|
||||
static void ip_forward(struct mbuf *m, struct route *, int srcrt,
|
||||
static void ip_forward(struct mbuf *m, int srcrt,
|
||||
struct sockaddr_in *next_hop);
|
||||
static void ip_freef(struct ipqhead *, struct ipq *);
|
||||
static struct mbuf *ip_reass(struct mbuf *, struct ipqhead *,
|
||||
@ -323,9 +277,6 @@ ip_init()
|
||||
for (i = 0; i < IPREASS_NHASH; i++)
|
||||
TAILQ_INIT(&ipq[i]);
|
||||
|
||||
bzero(&ip_fwdcache, sizeof(ip_fwdcache));
|
||||
RTCACHE_LOCK_INIT();
|
||||
|
||||
maxnipq = nmbclusters / 32;
|
||||
maxfragsperpacket = 16;
|
||||
|
||||
@ -337,22 +288,6 @@ ip_init()
|
||||
netisr_register(NETISR_IP, ip_input, &ipintrq, NETISR_MPSAFE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate any cached route used for forwarding.
|
||||
*/
|
||||
void
|
||||
ip_forward_cacheinval(void)
|
||||
{
|
||||
struct rtentry *rt;
|
||||
|
||||
RTCACHE_LOCK();
|
||||
rt = ip_fwdcache.rc_ro.ro_rt;
|
||||
ip_fwdcache.rc_ro.ro_rt = 0;
|
||||
if (rt != NULL)
|
||||
RTFREE(rt);
|
||||
RTCACHE_UNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
* Ip input routine. Checksum and byte swap header. If fragmented
|
||||
* try to reassemble. Process options. Pass to next level.
|
||||
@ -370,8 +305,7 @@ ip_input(struct mbuf *m)
|
||||
struct in_addr pkt_dst;
|
||||
u_int32_t divert_info = 0; /* packet divert/tee info */
|
||||
struct ip_fw_args args;
|
||||
struct route cro; /* copy of cached route */
|
||||
int srcrt = 0; /* forward by ``src routing'' */
|
||||
int dchg = 0; /* dest changed after fw */
|
||||
#ifdef PFIL_HOOKS
|
||||
struct in_addr odst; /* original dst address */
|
||||
#endif
|
||||
@ -566,7 +500,7 @@ ip_input(struct mbuf *m)
|
||||
if (m == NULL) /* consumed by filter */
|
||||
return;
|
||||
ip = mtod(m, struct ip *);
|
||||
srcrt = (odst.s_addr != ip->ip_dst.s_addr);
|
||||
dchg = (odst.s_addr != ip->ip_dst.s_addr);
|
||||
#endif /* PFIL_HOOKS */
|
||||
|
||||
if (fw_enable && IPFW_LOADED) {
|
||||
@ -802,8 +736,7 @@ ip_input(struct mbuf *m)
|
||||
goto bad;
|
||||
}
|
||||
#endif /* FAST_IPSEC */
|
||||
RTCACHE_GET(&cro);
|
||||
ip_forward(m, &cro, srcrt, args.next_hop);
|
||||
ip_forward(m, dchg, args.next_hop);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -1419,14 +1352,6 @@ ip_dooptions(struct mbuf *m, int pass, struct sockaddr_in *next_hop)
|
||||
struct in_addr *sin, dst;
|
||||
n_time ntime;
|
||||
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
|
||||
struct route cro; /* copy of cached route */
|
||||
|
||||
/*
|
||||
* Grab a copy of the route cache in case we need
|
||||
* to update to reflect source routing or the like.
|
||||
* Could optimize this to do it later...
|
||||
*/
|
||||
RTCACHE_GET(&cro);
|
||||
|
||||
dst = ip->ip_dst;
|
||||
cp = (u_char *)(ip + 1);
|
||||
@ -1546,7 +1471,7 @@ ip_dooptions(struct mbuf *m, int pass, struct sockaddr_in *next_hop)
|
||||
if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == 0)
|
||||
ia = (INA)ifa_ifwithnet((SA)&ipaddr);
|
||||
} else
|
||||
ia = ip_rtaddr(ipaddr.sin_addr, &cro);
|
||||
ia = ip_rtaddr(ipaddr.sin_addr);
|
||||
if (ia == 0) {
|
||||
type = ICMP_UNREACH;
|
||||
code = ICMP_UNREACH_SRCFAIL;
|
||||
@ -1588,7 +1513,7 @@ ip_dooptions(struct mbuf *m, int pass, struct sockaddr_in *next_hop)
|
||||
* use the incoming interface (should be same).
|
||||
*/
|
||||
if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) == 0 &&
|
||||
(ia = ip_rtaddr(ipaddr.sin_addr, &cro)) == 0) {
|
||||
(ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
|
||||
type = ICMP_UNREACH;
|
||||
code = ICMP_UNREACH_HOST;
|
||||
goto bad;
|
||||
@ -1668,7 +1593,7 @@ ip_dooptions(struct mbuf *m, int pass, struct sockaddr_in *next_hop)
|
||||
}
|
||||
}
|
||||
if (forward && ipforwarding) {
|
||||
ip_forward(m, &cro, 1, next_hop);
|
||||
ip_forward(m, 1, next_hop);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
@ -1683,30 +1608,26 @@ ip_dooptions(struct mbuf *m, int pass, struct sockaddr_in *next_hop)
|
||||
* return internet address info of interface to be used to get there.
|
||||
*/
|
||||
struct in_ifaddr *
|
||||
ip_rtaddr(dst, rt)
|
||||
ip_rtaddr(dst)
|
||||
struct in_addr dst;
|
||||
struct route *rt;
|
||||
{
|
||||
register struct sockaddr_in *sin;
|
||||
struct sockaddr_in *sin;
|
||||
struct in_ifaddr *ifa;
|
||||
struct route ro;
|
||||
|
||||
sin = (struct sockaddr_in *)&rt->ro_dst;
|
||||
bzero(&ro, sizeof(ro));
|
||||
sin = (struct sockaddr_in *)&ro.ro_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_addr = dst;
|
||||
rtalloc_ign(&ro, (RTF_PRCLONING | RTF_CLONING));
|
||||
|
||||
if (rt->ro_rt == 0 ||
|
||||
!(rt->ro_rt->rt_flags & RTF_UP) ||
|
||||
dst.s_addr != sin->sin_addr.s_addr) {
|
||||
if (rt->ro_rt) {
|
||||
RTFREE(rt->ro_rt);
|
||||
rt->ro_rt = 0;
|
||||
}
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_addr = dst;
|
||||
|
||||
rtalloc_ign(rt, RTF_PRCLONING);
|
||||
}
|
||||
if (rt->ro_rt == 0)
|
||||
if (ro.ro_rt == 0)
|
||||
return ((struct in_ifaddr *)0);
|
||||
return (ifatoia(rt->ro_rt->rt_ifa));
|
||||
|
||||
ifa = ifatoia(ro.ro_rt->rt_ifa);
|
||||
RTFREE(ro.ro_rt);
|
||||
return ifa;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1853,11 +1774,10 @@ u_char inetctlerrmap[PRC_NCMDS] = {
|
||||
* via a source route.
|
||||
*/
|
||||
static void
|
||||
ip_forward(struct mbuf *m, struct route *ro,
|
||||
int srcrt, struct sockaddr_in *next_hop)
|
||||
ip_forward(struct mbuf *m, int srcrt, struct sockaddr_in *next_hop)
|
||||
{
|
||||
struct ip *ip = mtod(m, struct ip *);
|
||||
struct rtentry *rt;
|
||||
struct in_ifaddr *ia;
|
||||
int error, type = 0, code = 0;
|
||||
struct mbuf *mcopy;
|
||||
n_long dest;
|
||||
@ -1867,7 +1787,6 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
struct ifnet dummyifp;
|
||||
#endif
|
||||
|
||||
dest = 0;
|
||||
/*
|
||||
* Cache the destination address of the packet; this may be
|
||||
* changed by use of 'ipfw fwd'.
|
||||
@ -1892,18 +1811,17 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
#endif
|
||||
if (ip->ip_ttl <= IPTTLDEC) {
|
||||
icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS,
|
||||
dest, 0);
|
||||
0, 0);
|
||||
return;
|
||||
}
|
||||
#ifdef IPSTEALTH
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ip_rtaddr(pkt_dst, ro) == 0) {
|
||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
|
||||
if ((ia = ip_rtaddr(pkt_dst)) == 0) {
|
||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
|
||||
return;
|
||||
} else
|
||||
rt = ro->ro_rt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Save the IP header and at most 8 bytes of the payload,
|
||||
@ -1954,27 +1872,44 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
* Also, don't send redirect if forwarding using a default route
|
||||
* or a route modified by a redirect.
|
||||
*/
|
||||
if (rt->rt_ifp == m->m_pkthdr.rcvif &&
|
||||
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
|
||||
satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
|
||||
ipsendredirects && !srcrt && !next_hop) {
|
||||
#define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa))
|
||||
u_long src = ntohl(ip->ip_src.s_addr);
|
||||
dest = 0;
|
||||
if (ipsendredirects && ia->ia_ifp == m->m_pkthdr.rcvif) {
|
||||
struct sockaddr_in *sin;
|
||||
struct route ro;
|
||||
struct rtentry *rt;
|
||||
|
||||
if (RTA(rt) &&
|
||||
(src & RTA(rt)->ia_subnetmask) == RTA(rt)->ia_subnet) {
|
||||
if (rt->rt_flags & RTF_GATEWAY)
|
||||
dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
|
||||
else
|
||||
dest = pkt_dst.s_addr;
|
||||
/* Router requirements says to only send host redirects */
|
||||
type = ICMP_REDIRECT;
|
||||
code = ICMP_REDIRECT_HOST;
|
||||
bzero(&ro, sizeof(ro));
|
||||
sin = (struct sockaddr_in *)&ro.ro_dst;
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_len = sizeof(*sin);
|
||||
sin->sin_addr = pkt_dst;
|
||||
rtalloc_ign(&ro, (RTF_PRCLONING | RTF_CLONING));
|
||||
|
||||
rt = ro.ro_rt;
|
||||
|
||||
if (rt && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 &&
|
||||
satosin(rt_key(rt))->sin_addr.s_addr != 0 &&
|
||||
ipsendredirects && !srcrt && !next_hop) {
|
||||
#define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa))
|
||||
u_long src = ntohl(ip->ip_src.s_addr);
|
||||
|
||||
if (RTA(rt) &&
|
||||
(src & RTA(rt)->ia_subnetmask) == RTA(rt)->ia_subnet) {
|
||||
if (rt->rt_flags & RTF_GATEWAY)
|
||||
dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
|
||||
else
|
||||
dest = pkt_dst.s_addr;
|
||||
/* Router requirements says to only send host redirects */
|
||||
type = ICMP_REDIRECT;
|
||||
code = ICMP_REDIRECT_HOST;
|
||||
#ifdef DIAGNOSTIC
|
||||
if (ipprintfs)
|
||||
printf("redirect (%d) to %lx\n", code, (u_long)dest);
|
||||
if (ipprintfs)
|
||||
printf("redirect (%d) to %lx\n", code, (u_long)dest);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (rt)
|
||||
RTFREE(rt);
|
||||
}
|
||||
|
||||
{
|
||||
@ -1989,13 +1924,8 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
tag.mh_next = m;
|
||||
m = (struct mbuf *)&tag;
|
||||
}
|
||||
error = ip_output(m, (struct mbuf *)0, ro, IP_FORWARDING, 0, NULL);
|
||||
error = ip_output(m, (struct mbuf *)0, NULL, IP_FORWARDING, 0, NULL);
|
||||
}
|
||||
/*
|
||||
* Update the ip forwarding cache with the route we used.
|
||||
* We may want to do this more selectively; not sure.
|
||||
*/
|
||||
RTCACHE_UPDATE(ro);
|
||||
if (error)
|
||||
ipstat.ips_cantforward++;
|
||||
else {
|
||||
@ -2030,77 +1960,31 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
case EMSGSIZE:
|
||||
type = ICMP_UNREACH;
|
||||
code = ICMP_UNREACH_NEEDFRAG;
|
||||
#ifdef IPSEC
|
||||
#if defined(IPSEC) || defined(FAST_IPSEC)
|
||||
/*
|
||||
* If the packet is routed over IPsec tunnel, tell the
|
||||
* originator the tunnel MTU.
|
||||
* tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
|
||||
* XXX quickhack!!!
|
||||
*/
|
||||
if (ro->ro_rt) {
|
||||
{
|
||||
struct secpolicy *sp = NULL;
|
||||
int ipsecerror;
|
||||
int ipsechdr;
|
||||
struct route *ro;
|
||||
|
||||
#ifdef IPSEC
|
||||
sp = ipsec4_getpolicybyaddr(mcopy,
|
||||
IPSEC_DIR_OUTBOUND,
|
||||
IP_FORWARDING,
|
||||
&ipsecerror);
|
||||
|
||||
if (sp == NULL)
|
||||
destifp = ro->ro_rt->rt_ifp;
|
||||
else {
|
||||
/* count IPsec header size */
|
||||
ipsechdr = ipsec4_hdrsiz(mcopy,
|
||||
IPSEC_DIR_OUTBOUND,
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* find the correct route for outer IPv4
|
||||
* header, compute tunnel MTU.
|
||||
*
|
||||
* XXX BUG ALERT
|
||||
* The "dummyifp" code relies upon the fact
|
||||
* that icmp_error() touches only ifp->if_mtu.
|
||||
*/
|
||||
/*XXX*/
|
||||
destifp = NULL;
|
||||
if (sp->req != NULL
|
||||
&& sp->req->sav != NULL
|
||||
&& sp->req->sav->sah != NULL) {
|
||||
struct route *saro;
|
||||
saro = &sp->req->sav->sah->sa_route;
|
||||
if (saro->ro_rt && saro->ro_rt->rt_ifp) {
|
||||
dummyifp.if_mtu =
|
||||
saro->ro_rt->rt_ifp->if_mtu;
|
||||
dummyifp.if_mtu -= ipsechdr;
|
||||
destifp = &dummyifp;
|
||||
}
|
||||
}
|
||||
|
||||
key_freesp(sp);
|
||||
}
|
||||
}
|
||||
#elif FAST_IPSEC
|
||||
/*
|
||||
* If the packet is routed over IPsec tunnel, tell the
|
||||
* originator the tunnel MTU.
|
||||
* tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz
|
||||
* XXX quickhack!!!
|
||||
*/
|
||||
if (ro->ro_rt) {
|
||||
struct secpolicy *sp = NULL;
|
||||
int ipsecerror;
|
||||
int ipsechdr;
|
||||
|
||||
IP_FORWARDING,
|
||||
&ipsecerror);
|
||||
#else /* FAST_IPSEC */
|
||||
sp = ipsec_getpolicybyaddr(mcopy,
|
||||
IPSEC_DIR_OUTBOUND,
|
||||
IP_FORWARDING,
|
||||
&ipsecerror);
|
||||
|
||||
if (sp == NULL)
|
||||
destifp = ro->ro_rt->rt_ifp;
|
||||
else {
|
||||
IP_FORWARDING,
|
||||
&ipsecerror);
|
||||
#endif
|
||||
if (sp != NULL) {
|
||||
/* count IPsec header size */
|
||||
ipsechdr = ipsec4_hdrsiz(mcopy,
|
||||
IPSEC_DIR_OUTBOUND,
|
||||
@ -2119,23 +2003,28 @@ ip_forward(struct mbuf *m, struct route *ro,
|
||||
if (sp->req != NULL
|
||||
&& sp->req->sav != NULL
|
||||
&& sp->req->sav->sah != NULL) {
|
||||
struct route *saro;
|
||||
saro = &sp->req->sav->sah->sa_route;
|
||||
if (saro->ro_rt && saro->ro_rt->rt_ifp) {
|
||||
ro = &sp->req->sav->sah->sa_route;
|
||||
if (ro->ro_rt && ro->ro_rt->rt_ifp) {
|
||||
dummyifp.if_mtu =
|
||||
saro->ro_rt->rt_ifp->if_mtu;
|
||||
ro->ro_rt->rt_ifp->if_mtu;
|
||||
dummyifp.if_mtu -= ipsechdr;
|
||||
destifp = &dummyifp;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IPSEC
|
||||
key_freesp(sp);
|
||||
#else /* FAST_IPSEC */
|
||||
KEY_FREESP(&sp);
|
||||
}
|
||||
#endif
|
||||
ipstat.ips_cantfrag++;
|
||||
break;
|
||||
} else
|
||||
#endif /*IPSEC || FAST_IPSEC*/
|
||||
destifp = ia->ia_ifp;
|
||||
#if defined(IPSEC) || defined(FAST_IPSEC)
|
||||
}
|
||||
#else /* !IPSEC && !FAST_IPSEC */
|
||||
if (ro->ro_rt)
|
||||
destifp = ro->ro_rt->rt_ifp;
|
||||
#endif /*IPSEC*/
|
||||
#endif /*IPSEC || FAST_IPSEC*/
|
||||
ipstat.ips_cantfrag++;
|
||||
break;
|
||||
|
||||
|
@ -142,13 +142,12 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
|
||||
struct in_ifaddr *ia = NULL;
|
||||
int isbroadcast, sw_csum;
|
||||
struct in_addr pkt_dst;
|
||||
#ifdef IPSEC
|
||||
struct route iproute;
|
||||
#ifdef IPSEC
|
||||
struct socket *so;
|
||||
struct secpolicy *sp = NULL;
|
||||
#endif
|
||||
#ifdef FAST_IPSEC
|
||||
struct route iproute;
|
||||
struct m_tag *mtag;
|
||||
struct secpolicy *sp = NULL;
|
||||
struct tdb_ident *tdbi;
|
||||
@ -202,10 +201,12 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
|
||||
#endif /*IPSEC*/
|
||||
|
||||
M_ASSERTPKTHDR(m);
|
||||
#ifndef FAST_IPSEC
|
||||
KASSERT(ro != NULL, ("ip_output: no route, proto %d",
|
||||
mtod(m, struct ip *)->ip_p));
|
||||
#endif
|
||||
|
||||
if (ro == NULL) {
|
||||
ro = &iproute;
|
||||
bzero(ro, sizeof (*ro));
|
||||
}
|
||||
|
||||
if (inp != NULL)
|
||||
INP_LOCK_ASSERT(inp);
|
||||
|
||||
@ -256,12 +257,6 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
|
||||
hlen = ip->ip_hl << 2;
|
||||
}
|
||||
|
||||
#ifdef FAST_IPSEC
|
||||
if (ro == NULL) {
|
||||
ro = &iproute;
|
||||
bzero(ro, sizeof (*ro));
|
||||
}
|
||||
#endif /* FAST_IPSEC */
|
||||
dst = (struct sockaddr_in *)&ro->ro_dst;
|
||||
/*
|
||||
* If there is a cached route,
|
||||
@ -1089,11 +1084,11 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
|
||||
ipstat.ips_fragmented++;
|
||||
|
||||
done:
|
||||
#ifdef IPSEC
|
||||
if (ro == &iproute && ro->ro_rt) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
#ifdef IPSEC
|
||||
if (sp != NULL) {
|
||||
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
|
||||
printf("DP ip_output call free SP:%p\n", sp));
|
||||
@ -1101,10 +1096,6 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro,
|
||||
}
|
||||
#endif
|
||||
#ifdef FAST_IPSEC
|
||||
if (ro == &iproute && ro->ro_rt) {
|
||||
RTFREE(ro->ro_rt);
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
if (sp != NULL)
|
||||
KEY_FREESP(&sp);
|
||||
#endif
|
||||
|
@ -162,7 +162,6 @@ int ip_ctloutput(struct socket *, struct sockopt *sopt);
|
||||
void ip_drain(void);
|
||||
int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
u_long if_hwassist_flags, int sw_csum);
|
||||
void ip_forward_cacheinval(void);
|
||||
void ip_freemoptions(struct ip_moptions *);
|
||||
void ip_init(void);
|
||||
extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
|
||||
@ -171,7 +170,7 @@ int ip_output(struct mbuf *,
|
||||
struct mbuf *, struct route *, int, struct ip_moptions *,
|
||||
struct inpcb *);
|
||||
struct in_ifaddr *
|
||||
ip_rtaddr(struct in_addr, struct route *);
|
||||
ip_rtaddr(struct in_addr);
|
||||
void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
|
||||
struct mbuf *);
|
||||
void ip_slowtimo(void);
|
||||
|
Loading…
Reference in New Issue
Block a user