summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UPDATING4
-rw-r--r--sys/netinet6/frag6.c12
-rw-r--r--sys/netinet6/ip6_forward.c107
-rw-r--r--sys/netinet6/ip6_input.c80
-rw-r--r--sys/netinet6/ip6_var.h3
-rw-r--r--sys/netinet6/vinet6.h3
-rw-r--r--usr.bin/netstat/inet6.c2
7 files changed, 75 insertions, 136 deletions
diff --git a/UPDATING b/UPDATING
index 04d0c17..d8d0b0e 100644
--- a/UPDATING
+++ b/UPDATING
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW:
to maximize performance. (To disable malloc debugging, run
ln -s aj /etc/malloc.conf.)
+20090201:
+ INET6 statistics (struct ip6stat) was updated.
+ netstat(1) needs to be recompiled.
+
20090119:
NTFS has been removed from GENERIC kernel on amd64 to match
GENERIC on i386. Should not cause any issues since mount_ntfs(8)
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index b63e23c..e2eda6f 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -751,18 +751,6 @@ frag6_slowtimo(void)
}
VNET_LIST_RUNLOCK();
IP6Q_UNLOCK();
-
-#if 0
- /*
- * Routing changes might produce a better route than we last used;
- * make sure we notice eventually, even if forwarding only for one
- * destination and the cache is never replaced.
- */
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
-#endif
}
/*
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index 0ce591f..ca5101f 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -77,10 +77,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6protosw.h>
-#ifdef VIMAGE_GLOBALS
-struct route_in6 ip6_forward_rt;
-#endif
-
/*
* Forward a packet. If some error occurs return the sender
* an icmp packet. Note we can't always generate a meaningful
@@ -100,6 +96,7 @@ ip6_forward(struct mbuf *m, int srcrt)
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct sockaddr_in6 *dst = NULL;
struct rtentry *rt = NULL;
+ struct route_in6 rin6;
int error, type = 0, code = 0;
struct mbuf *mcopy = NULL;
struct ifnet *origifp; /* maybe unnecessary */
@@ -112,8 +109,6 @@ ip6_forward(struct mbuf *m, int srcrt)
#endif
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
- /* GIANT_REQUIRED; */ /* XXX bz: ip6_forward_rt */
-
#ifdef IPSEC
/*
* Check AH/ESP integrity.
@@ -355,56 +350,27 @@ ip6_forward(struct mbuf *m, int srcrt)
skip_ipsec:
#endif
- dst = (struct sockaddr_in6 *)&V_ip6_forward_rt.ro_dst;
- if (!srcrt) {
- /* ip6_forward_rt.ro_dst.sin6_addr is equal to ip6->ip6_dst */
- if (V_ip6_forward_rt.ro_rt == 0 ||
- (V_ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0) {
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
-
- /* this probably fails but give it a try again */
- rtalloc((struct route *)&V_ip6_forward_rt);
- }
-
- if (V_ip6_forward_rt.ro_rt == 0) {
- V_ip6stat.ip6s_noroute++;
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
- if (mcopy) {
- icmp6_error(mcopy, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0);
- }
- m_freem(m);
- return;
- }
- } else if ((rt = V_ip6_forward_rt.ro_rt) == 0 ||
- !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) {
- if (V_ip6_forward_rt.ro_rt) {
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
- bzero(dst, sizeof(*dst));
- dst->sin6_len = sizeof(struct sockaddr_in6);
- dst->sin6_family = AF_INET6;
- dst->sin6_addr = ip6->ip6_dst;
-
- rtalloc((struct route *)&V_ip6_forward_rt);
- if (V_ip6_forward_rt.ro_rt == 0) {
- V_ip6stat.ip6s_noroute++;
- in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
- if (mcopy) {
- icmp6_error(mcopy, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_NOROUTE, 0);
- }
- m_freem(m);
- return;
+ bzero(&rin6, sizeof(struct route_in6));
+ dst = (struct sockaddr_in6 *)&rin6.ro_dst;
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = ip6->ip6_dst;
+
+ rin6.ro_rt = rtalloc1((struct sockaddr *)dst, 0, 0);
+ if (rin6.ro_rt != NULL)
+ RT_UNLOCK(rin6.ro_rt);
+ else {
+ V_ip6stat.ip6s_noroute++;
+ in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_noroute);
+ if (mcopy) {
+ icmp6_error(mcopy, ICMP6_DST_UNREACH,
+ ICMP6_DST_UNREACH_NOROUTE, 0);
}
+ goto bad;
}
- rt = V_ip6_forward_rt.ro_rt;
+ rt = rin6.ro_rt;
#ifdef IPSEC
- skip_routing:;
+skip_routing:
#endif
/*
@@ -421,14 +387,12 @@ skip_ipsec:
/* XXX: this should not happen */
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (in6_setscope(&src_in6, m->m_pkthdr.rcvif, &inzone)) {
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (inzone != outzone
#ifdef IPSEC
@@ -452,8 +416,7 @@ skip_ipsec:
if (mcopy)
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_BEYONDSCOPE, 0);
- m_freem(m);
- return;
+ goto bad;
}
/*
@@ -469,8 +432,7 @@ skip_ipsec:
inzone != outzone) {
V_ip6stat.ip6s_cantforward++;
V_ip6stat.ip6s_badscope++;
- m_freem(m);
- return;
+ goto bad;
}
if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
@@ -510,8 +472,7 @@ skip_ipsec:
#endif /* IPSEC */
icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
}
- m_freem(m);
- return;
+ goto bad;
}
if (rt->rt_flags & RTF_GATEWAY)
@@ -544,8 +505,7 @@ skip_ipsec:
*/
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_ADDR, 0);
- m_freem(m);
- return;
+ goto bad;
}
type = ND_REDIRECT;
}
@@ -624,12 +584,12 @@ pass:
senderr:
if (mcopy == NULL)
- return;
+ goto out;
switch (error) {
case 0:
if (type == ND_REDIRECT) {
icmp6_redirect_output(mcopy, rt);
- return;
+ goto out;
}
goto freecopy;
@@ -651,9 +611,18 @@ senderr:
break;
}
icmp6_error(mcopy, type, code, 0);
- return;
+ goto out;
freecopy:
m_freem(mcopy);
- return;
+ goto out;
+bad:
+ m_freem(m);
+out:
+ if (rt != NULL
+#ifdef IPSEC
+ && !ipsecrt
+#endif
+ )
+ RTFREE(rt);
}
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 1aaf0b2..f120ec5 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -143,8 +143,6 @@ extern int icmp6errppslim;
extern int icmp6_nodeinfo;
extern int udp6_sendspace;
extern int udp6_recvspace;
-
-extern struct route_in6 ip6_forward_rt;
#endif
struct pfil_head inet6_pfil_hook;
@@ -309,10 +307,12 @@ ip6_input(struct mbuf *m)
int nxt, ours = 0;
struct ifnet *deliverifp = NULL, *ifp = NULL;
struct in6_addr odst;
+ struct route_in6 rin6;
int srcrt = 0;
struct llentry *lle = NULL;
- struct sockaddr_in6 dst6;
+ struct sockaddr_in6 dst6, *dst;
+ bzero(&rin6, sizeof(struct route_in6));
#ifdef IPSEC
/*
* should the inner packet be considered authentic?
@@ -565,29 +565,13 @@ passin:
if (lle != NULL)
LLE_RUNLOCK(lle);
- if (V_ip6_forward_rt.ro_rt != NULL &&
- (V_ip6_forward_rt.ro_rt->rt_flags & RTF_UP) != 0 &&
- IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
- &((struct sockaddr_in6 *)(&V_ip6_forward_rt.ro_dst))->sin6_addr))
- V_ip6stat.ip6s_forward_cachehit++;
- else {
- struct sockaddr_in6 *dst6;
-
- if (V_ip6_forward_rt.ro_rt) {
- /* route is down or destination is different */
- V_ip6stat.ip6s_forward_cachemiss++;
- RTFREE(V_ip6_forward_rt.ro_rt);
- V_ip6_forward_rt.ro_rt = 0;
- }
-
- bzero(&V_ip6_forward_rt.ro_dst, sizeof(struct sockaddr_in6));
- dst6 = (struct sockaddr_in6 *)&V_ip6_forward_rt.ro_dst;
- dst6->sin6_len = sizeof(struct sockaddr_in6);
- dst6->sin6_family = AF_INET6;
- dst6->sin6_addr = ip6->ip6_dst;
-
- rtalloc((struct route *)&V_ip6_forward_rt);
- }
+ dst = &rin6.ro_dst;
+ dst->sin6_len = sizeof(struct sockaddr_in6);
+ dst->sin6_family = AF_INET6;
+ dst->sin6_addr = ip6->ip6_dst;
+ rin6.ro_rt = rtalloc1((struct sockaddr *)dst, 0, 0);
+ if (rin6.ro_rt)
+ RT_UNLOCK(rin6.ro_rt);
#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key))
@@ -611,14 +595,14 @@ passin:
* while it would be less efficient. Or, should we rather install a
* reject route for such a case?
*/
- if (V_ip6_forward_rt.ro_rt &&
- (V_ip6_forward_rt.ro_rt->rt_flags &
+ if (rin6.ro_rt &&
+ (rin6.ro_rt->rt_flags &
(RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
#ifdef RTF_WASCLONED
- !(V_ip6_forward_rt.ro_rt->rt_flags & RTF_WASCLONED) &&
+ !(rin6.ro_rt->rt_flags & RTF_WASCLONED) &&
#endif
#ifdef RTF_CLONED
- !(V_ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) &&
+ !(rin6.ro_rt->rt_flags & RTF_CLONED) &&
#endif
#if 0
/*
@@ -627,11 +611,11 @@ passin:
* already done through looking up the routing table.
*/
IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst,
- &rt6_key(V_ip6_forward_rt.ro_rt)->sin6_addr)
+ &rt6_key(rin6.ro_rt)->sin6_addr)
#endif
- V_ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
+ rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) {
struct in6_ifaddr *ia6 =
- (struct in6_ifaddr *)V_ip6_forward_rt.ro_rt->rt_ifa;
+ (struct in6_ifaddr *)rin6.ro_rt->rt_ifa;
/*
* record address information into m_tag.
@@ -667,11 +651,11 @@ passin:
* FAITH (Firewall Aided Internet Translator)
*/
if (V_ip6_keepfaith) {
- if (V_ip6_forward_rt.ro_rt && V_ip6_forward_rt.ro_rt->rt_ifp
- && V_ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_FAITH) {
+ if (rin6.ro_rt && rin6.ro_rt->rt_ifp &&
+ rin6.ro_rt->rt_ifp->if_type == IFT_FAITH) {
/* XXX do we need more sanity checks? */
ours = 1;
- deliverifp = V_ip6_forward_rt.ro_rt->rt_ifp; /* faith */
+ deliverifp = rin6.ro_rt->rt_ifp; /* faith */
goto hbhcheck;
}
}
@@ -721,7 +705,7 @@ passin:
#if 0 /*touches NULL pointer*/
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
#endif
- return; /* m have already been freed */
+ goto out; /* m have already been freed */
}
/* adjust pointer */
@@ -744,7 +728,7 @@ passin:
icmp6_error(m, ICMP6_PARAM_PROB,
ICMP6_PARAMPROB_HEADER,
(caddr_t)&ip6->ip6_plen - (caddr_t)ip6);
- return;
+ goto out;
}
#ifndef PULLDOWN_TEST
/* ip6_hopopts_input() ensures that mbuf is contiguous */
@@ -754,7 +738,7 @@ passin:
sizeof(struct ip6_hbh));
if (hbh == NULL) {
V_ip6stat.ip6s_tooshort++;
- return;
+ goto out;
}
#endif
nxt = hbh->ip6h_nxt;
@@ -816,16 +800,13 @@ passin:
if (ip6_mrouter && ip6_mforward &&
ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {
V_ip6stat.ip6s_cantforward++;
- m_freem(m);
- return;
- }
- if (!ours) {
- m_freem(m);
- return;
+ goto bad;
}
+ if (!ours)
+ goto bad;
} else if (!ours) {
ip6_forward(m, srcrt);
- return;
+ goto out;
}
ip6 = mtod(m, struct ip6_hdr *);
@@ -880,9 +861,12 @@ passin:
#endif /* IPSEC */
nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt);
}
- return;
- bad:
+ goto out;
+bad:
m_freem(m);
+out:
+ if (rin6.ro_rt)
+ RTFREE(rin6.ro_rt);
}
/*
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 00b19a7..9e8476c 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -229,9 +229,6 @@ struct ip6stat {
/* number of times that a deprecated address is chosen */
u_quad_t ip6s_sources_deprecated[16];
- u_quad_t ip6s_forward_cachehit;
- u_quad_t ip6s_forward_cachemiss;
-
/* number of times that each rule of source selection is applied. */
u_quad_t ip6s_sources_rule[16];
};
diff --git a/sys/netinet6/vinet6.h b/sys/netinet6/vinet6.h
index e67f731..e0a1fa0 100644
--- a/sys/netinet6/vinet6.h
+++ b/sys/netinet6/vinet6.h
@@ -54,7 +54,7 @@ struct vnet_inet6 {
u_int _frag6_nfrags;
struct ip6q _ip6q;
- struct route_in6 _ip6_forward_rt;
+ struct route_in6 _ip6_forward_rt; /* XXX remove */
struct in6_addrpolicy _defaultaddrpolicy;
TAILQ_HEAD(, addrsel_policyent) _addrsel_policytab;
@@ -194,7 +194,6 @@ extern struct vnet_inet6 vnet_inet6_0;
#define V_ip6_defhlim VNET_INET6(ip6_defhlim)
#define V_ip6_defmcasthlim VNET_INET6(ip6_defmcasthlim)
#define V_ip6_desync_factor VNET_INET6(ip6_desync_factor)
-#define V_ip6_forward_rt VNET_INET6(ip6_forward_rt)
#define V_ip6_forwarding VNET_INET6(ip6_forwarding)
#define V_ip6_hdrnestlimit VNET_INET6(ip6_hdrnestlimit)
#define V_ip6_keepfaith VNET_INET6(ip6_keepfaith)
diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c
index b4aeb1a0..83a31c7f 100644
--- a/usr.bin/netstat/inet6.c
+++ b/usr.bin/netstat/inet6.c
@@ -512,8 +512,6 @@ ip6_stats(u_long off, const char *name, int af1 __unused, int proto __unused)
}
}
- p1a(ip6s_forward_cachehit, "\t%ju forward cache hit\n");
- p1a(ip6s_forward_cachemiss, "\t%ju forward cache miss\n");
printf("\tSource addresses selection rule applied:\n");
for (i = 0; i < 16; i++) {
if (ip6stat.ip6s_sources_rule[i])
OpenPOWER on IntegriCloud