summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclaudio <claudio@openbsd.org>2015-09-12 14:21:04 +0000
committerclaudio <claudio@openbsd.org>2015-09-12 14:21:04 +0000
commit06fd5c86de2f9c1689d7263727ab8e6114fba9bc (patch)
tree85885e2a2ad50d0d6d6a12b26ad7849534147b0d
parentIt is not necessary to reset errno to 0 since we use logerrorx(). (diff)
downloadwireguard-openbsd-06fd5c86de2f9c1689d7263727ab8e6114fba9bc.tar.xz
wireguard-openbsd-06fd5c86de2f9c1689d7263727ab8e6114fba9bc.zip
Use rtfree() instead of playing with the refcount directly. Some care is
needed since rt0 as passed from the upper layer is freed by that layer. Also if_output does not free the rt so handle that as well. With and OK mpi@
-rw-r--r--sys/netmpls/mpls_output.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/netmpls/mpls_output.c b/sys/netmpls/mpls_output.c
index 68c35ee1da7..07bc343afc5 100644
--- a/sys/netmpls/mpls_output.c
+++ b/sys/netmpls/mpls_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_output.c,v 1.21 2015/07/15 22:16:42 deraadt Exp $ */
+/* $OpenBSD: mpls_output.c,v 1.22 2015/09/12 14:21:04 claudio Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
@@ -50,7 +50,7 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
struct sockaddr_mpls *smpls;
struct sockaddr_mpls sa_mpls;
struct shim_hdr *shim;
- struct rtentry *rt = rt0;
+ struct rtentry *rt;
struct rt_mpls *rt_mpls;
int i, error;
u_int8_t ttl;
@@ -58,9 +58,9 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
if (rt0 == NULL || (dst->sa_family != AF_INET &&
dst->sa_family != AF_INET6 && dst->sa_family != AF_MPLS)) {
if (!ISSET(ifp->if_xflags, IFXF_MPLS))
- return (ifp->if_output(ifp, m, dst, rt));
+ return (ifp->if_output(ifp, m, dst, rt0));
else
- return (ifp->if_ll_output(ifp, m, dst, rt));
+ return (ifp->if_ll_output(ifp, m, dst, rt0));
}
/* need to calculate checksums now if necessary */
@@ -74,6 +74,7 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
ttl = mpls_getttl(m, dst->sa_family);
+ rt = rt0;
for (i = 0; i < mpls_inkloop; i++) {
rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
if (rt_mpls == NULL || (rt->rt_flags & RTF_MPLS) == 0) {
@@ -120,6 +121,8 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
break;
smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
+ if (rt != rt0)
+ rtfree(rt);
rt = rtalloc(smplstosa(smpls), RT_REPORT|RT_RESOLVE, 0);
if (rt == NULL) {
/* no entry for this label */
@@ -131,7 +134,6 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
goto bad;
}
rt->rt_use++;
- rt->rt_refcnt--;
}
/* write back TTL */
@@ -157,7 +159,10 @@ mpls_output(struct ifnet *ifp0, struct mbuf *m, struct sockaddr *dst,
m->m_flags &= ~(M_BCAST | M_MCAST);
smpls->smpls_label = shim->shim_label & MPLS_LABEL_MASK;
- return (ifp->if_ll_output(ifp, m, smplstosa(smpls), rt));
+ error = ifp->if_ll_output(ifp, m, smplstosa(smpls), rt);
+ if (rt != rt0)
+ rtfree(rt);
+ return (error);
bad:
m_freem(m);
return (error);