summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authorozaki-r <ozaki-r@NetBSD.org>2016-12-08 05:16:33 +0000
committerozaki-r <ozaki-r@NetBSD.org>2016-12-08 05:16:33 +0000
commit9de8a52bfeed29dabf6008217920339dbdf03491 (patch)
tree56ca9bb4e936c59b20253c57f0ad1b39065e6c38 /sys/netinet/ip_input.c
parent8ed2b65eee837916c0187b1f5f0e1b67801965d9 (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.c22
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);