diff options
| author | ozaki-r <ozaki-r@NetBSD.org> | 2016-12-08 05:16:33 +0000 |
|---|---|---|
| committer | ozaki-r <ozaki-r@NetBSD.org> | 2016-12-08 05:16:33 +0000 |
| commit | 9de8a52bfeed29dabf6008217920339dbdf03491 (patch) | |
| tree | 56ca9bb4e936c59b20253c57f0ad1b39065e6c38 /sys/netinet/ip_input.c | |
| parent | 8ed2b65eee837916c0187b1f5f0e1b67801965d9 (diff) | |
Add rtcache_unref to release points of rtentry stemming from rtcache
In the MP-safe world, a rtentry stemming from a rtcache can be freed at any
points. So we need to protect rtentries somehow say by reference couting or
passive references. Regardless of the method, we need to call some release
function of a rtentry after using it.
The change adds a new function rtcache_unref to release a rtentry. At this
point, this function does nothing because for now we don't add a reference
to a rtentry when we get one from a rtcache. We will add something useful
in a further commit.
This change is a part of changes for MP-safe routing table. It is separated
to avoid one big change that makes difficult to debug by bisecting.
Diffstat (limited to 'sys/netinet/ip_input.c')
| -rw-r--r-- | sys/netinet/ip_input.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index bc5619ffecd..e13772cc0f1 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.344 2016/10/18 07:30:31 ozaki-r Exp $ */ +/* $NetBSD: ip_input.c,v 1.345 2016/12/08 05:16:33 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.344 2016/10/18 07:30:31 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.345 2016/12/08 05:16:33 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1183,13 +1183,15 @@ ip_rtaddr(struct in_addr dst) sockaddr_in_init(&u.dst4, &dst, 0); - SOFTNET_LOCK(); ro = percpu_getref(ipforward_rt_percpu); rt = rtcache_lookup(ro, &u.dst); - percpu_putref(ipforward_rt_percpu); - SOFTNET_UNLOCK(); - if (rt == NULL) + if (rt == NULL) { + percpu_putref(ipforward_rt_percpu); return NULL; + } + + rtcache_unref(rt, ro); + percpu_putref(ipforward_rt_percpu); return ifatoia(rt->rt_ifa); } @@ -1349,7 +1351,8 @@ ip_forward(struct mbuf *m, int srcrt, struct ifnet *rcvif) sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); ro = percpu_getref(ipforward_rt_percpu); - if ((rt = rtcache_lookup(ro, &u.dst)) == NULL) { + rt = rtcache_lookup(ro, &u.dst); + if (rt == NULL) { percpu_putref(ipforward_rt_percpu); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, dest, 0); return; @@ -1393,6 +1396,7 @@ ip_forward(struct mbuf *m, int srcrt, struct ifnet *rcvif) code = ICMP_REDIRECT_HOST; } } + rtcache_unref(rt, ro); error = ip_output(m, NULL, ro, (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), @@ -1450,8 +1454,10 @@ error: type = ICMP_UNREACH; code = ICMP_UNREACH_NEEDFRAG; - if ((rt = rtcache_validate(ro)) != NULL) + if ((rt = rtcache_validate(ro)) != NULL) { destmtu = rt->rt_ifp->if_mtu; + rtcache_unref(rt, ro); + } #ifdef IPSEC if (ipsec_used) (void)ipsec4_forward(mcopy, &destmtu); |
