summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2015-09-12 14:21:05 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2015-09-12 14:21:05 +0000
commitc837385ad2cf270d192bfa5867103be22a4f7005 (patch)
tree673dca8cb5b572c36bab5b4c6079e627dca5cbe7
parent4e898d9abf63f8f55cb2a706309e95b8cb246094 (diff)
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);