summaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
authorAndre Oppermann <andre@FreeBSD.org>2003-11-20 20:07:39 +0000
committerAndre Oppermann <andre@FreeBSD.org>2003-11-20 20:07:39 +0000
commit97d8d152c28bb596e1c310d9842db5d0314207b2 (patch)
treef947a08d66395dd498056038f0c360783fa281c7 /sys/netinet6
parent26d02ca7babf8bb8d1e2b9c8cb3e18ec0fcd1317 (diff)
Notes
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/icmp6.c32
-rw-r--r--sys/netinet6/in6_pcb.c44
-rw-r--r--sys/netinet6/in6_rmx.c3
-rw-r--r--sys/netinet6/in6_src.c45
-rw-r--r--sys/netinet6/ip6_output.c27
-rw-r--r--sys/netinet6/udp6_output.c9
6 files changed, 79 insertions, 81 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 997474ef42a9..6baa2db349fe 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -94,6 +94,7 @@
#include <netinet/in_var.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
+#include <netinet/tcp_var.h>
#include <netinet6/in6_ifattach.h>
#include <netinet6/in6_pcb.h>
#include <netinet6/ip6protosw.h>
@@ -1105,8 +1106,7 @@ icmp6_mtudisc_update(ip6cp, validated)
struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
struct mbuf *m = ip6cp->ip6c_m; /* will be necessary for scope issue */
u_int mtu = ntohl(icmp6->icmp6_mtu);
- struct rtentry *rt = NULL;
- struct sockaddr_in6 sin6;
+ struct in_conninfo inc;
#if 0
/*
@@ -1131,31 +1131,19 @@ icmp6_mtudisc_update(ip6cp, validated)
if (!validated)
return;
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = PF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_addr = *dst;
+ bzero(&inc, sizeof(inc));
+ inc.inc_flags = 1; /* IPv6 */
+ inc.inc6_faddr = *dst;
/* XXX normally, this won't happen */
if (IN6_IS_ADDR_LINKLOCAL(dst)) {
- sin6.sin6_addr.s6_addr16[1] =
+ inc.inc6_faddr.s6_addr16[1] =
htons(m->m_pkthdr.rcvif->if_index);
}
- /* sin6.sin6_scope_id = XXX: should be set if DST is a scoped addr */
- rt = rtalloc1((struct sockaddr *)&sin6, 0, RTF_CLONING);
-
- if (rt && (rt->rt_flags & RTF_HOST) &&
- !(rt->rt_rmx.rmx_locks & RTV_MTU)) {
- if (mtu < IPV6_MMTU) {
- /* xxx */
- rt->rt_rmx.rmx_locks |= RTV_MTU;
- } else if (mtu < rt->rt_ifp->if_mtu &&
- rt->rt_rmx.rmx_mtu > mtu) {
- icmp6stat.icp6s_pmtuchg++;
- rt->rt_rmx.rmx_mtu = mtu;
- }
+
+ if (mtu >= IPV6_MMTU) {
+ tcp_hc_updatemtu(&inc, mtu);
+ icmp6stat.icp6s_pmtuchg++;
}
- if (rt)
- rtfree(rt);
}
/*
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index 5c7f1f24b85d..b3d58e8acb27 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -337,8 +337,7 @@ in6_pcbladdr(inp, nam, plocal_addr6)
* Is it the intended behavior?
*/
*plocal_addr6 = in6_selectsrc(sin6, inp->in6p_outputopts,
- inp->in6p_moptions,
- &inp->in6p_route,
+ inp->in6p_moptions, NULL,
&inp->in6p_laddr, &error);
if (*plocal_addr6 == 0) {
if (error == 0)
@@ -351,10 +350,6 @@ in6_pcbladdr(inp, nam, plocal_addr6)
* and exit to caller, that will do the lookup.
*/
}
-
- if (inp->in6p_route.ro_rt)
- ifp = inp->in6p_route.ro_rt->rt_ifp;
-
return (0);
}
@@ -447,8 +442,6 @@ in6_pcbdetach(inp)
ip6_freepcbopts(inp->in6p_outputopts);
ip6_freemoptions(inp->in6p_moptions);
- if (inp->in6p_route.ro_rt)
- RTFREE(inp->in6p_route.ro_rt);
/* Check and free IPv4 related resources in case of mapped addr */
if (inp->inp_options)
(void)m_free(inp->inp_options);
@@ -830,26 +823,10 @@ void
in6_losing(in6p)
struct inpcb *in6p;
{
- struct rtentry *rt;
- struct rt_addrinfo info;
-
- if ((rt = in6p->in6p_route.ro_rt) != NULL) {
- RT_LOCK(rt);
- in6p->in6p_route.ro_rt = NULL;
- bzero((caddr_t)&info, sizeof(info));
- info.rti_flags = rt->rt_flags;
- info.rti_info[RTAX_DST] = rt_key(rt);
- info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
- info.rti_info[RTAX_NETMASK] = rt_mask(rt);
- rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
- if (rt->rt_flags & RTF_DYNAMIC)
- rtexpunge(rt);
- RTFREE_LOCKED(rt);
- /*
- * A new route can be allocated
- * the next time output is attempted.
- */
- }
+ /*
+ * We don't store route pointers in the routing table anymore
+ */
+ return;
}
/*
@@ -861,14 +838,9 @@ in6_rtchange(inp, errno)
struct inpcb *inp;
int errno;
{
- if (inp->in6p_route.ro_rt) {
- RTFREE(inp->in6p_route.ro_rt);
- inp->in6p_route.ro_rt = 0;
- /*
- * A new route can be allocated the next time
- * output is attempted.
- */
- }
+ /*
+ * We don't store route pointers in the routing table anymore
+ */
return inp;
}
diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c
index 09526b262ab0..b68852d01d4b 100644
--- a/sys/netinet6/in6_rmx.c
+++ b/sys/netinet6/in6_rmx.c
@@ -141,8 +141,7 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
}
}
- if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)
- && rt->rt_ifp)
+ if (!rt->rt_rmx.rmx_mtu && rt->rt_ifp)
rt->rt_rmx.rmx_mtu = IN6_LINKMTU(rt->rt_ifp);
ret = rn_addroute(v_arg, n_arg, head, treenodes);
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index d5849569fddd..88ace1cc6cac 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -211,7 +211,6 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp)
!= 0) {
return (NULL);
}
-
/*
* determine the appropriate zone id of the source based on
* the zone of the destination and the outgoing interface.
@@ -449,12 +448,19 @@ in6_selectif(dstsock, opts, mopts, ro, retifp)
struct route_in6 *ro;
struct ifnet **retifp;
{
- int error, clone;
+ int error;
+ struct route_in6 sro;
struct rtentry *rt = NULL;
- clone = IN6_IS_ADDR_MULTICAST(&dstsock->sin6_addr) ? 0 : 1;
+ if (ro == NULL) {
+ bzero(&sro, sizeof(sro));
+ ro = &sro;
+ }
+
if ((error = in6_selectroute(dstsock, opts, mopts, ro, retifp,
- &rt, clone)) != 0) {
+ &rt, 0)) != 0) {
+ if (rt && rt == sro.ro_rt)
+ RTFREE(rt);
return (error);
}
@@ -476,7 +482,11 @@ in6_selectif(dstsock, opts, mopts, ro, retifp)
* We thus reject the case here.
*/
if (rt && (rt->rt_flags & (RTF_REJECT | RTF_BLACKHOLE))) {
- return (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+ int flags = (rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+
+ if (rt && rt == sro.ro_rt)
+ RTFREE(rt);
+ return (flags);
}
/*
@@ -489,6 +499,8 @@ in6_selectif(dstsock, opts, mopts, ro, retifp)
if (rt && rt->rt_ifa && rt->rt_ifa->ifa_ifp)
*retifp = rt->rt_ifa->ifa_ifp;
+ if (rt && rt == sro.ro_rt)
+ RTFREE(rt);
return (0);
}
@@ -623,6 +635,7 @@ in6_selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone)
sa6 = (struct sockaddr_in6 *)&ro->ro_dst;
*sa6 = *dstsock;
sa6->sin6_scope_id = 0;
+
if (clone) {
rtalloc((struct route *)ro);
} else {
@@ -695,7 +708,7 @@ in6_selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone)
* 2. (If the outgoing interface is detected) the current
* hop limit of the interface specified by router advertisement.
* 3. The system default hoplimit.
-*/
+ */
int
in6_selecthlim(in6p, ifp)
struct in6pcb *in6p;
@@ -705,8 +718,24 @@ in6_selecthlim(in6p, ifp)
return (in6p->in6p_hops);
else if (ifp)
return (ND_IFINFO(ifp)->chlim);
- else
- return (ip6_defhlim);
+ else if (in6p && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
+ struct route_in6 ro6;
+ struct ifnet *lifp;
+
+ bzero(&ro6, sizeof(ro6));
+ ro6.ro_dst.sin6_family = AF_INET6;
+ ro6.ro_dst.sin6_len = sizeof(struct sockaddr_in6);
+ ro6.ro_dst.sin6_addr = in6p->in6p_faddr;
+ rtalloc((struct route *)&ro6);
+ if (ro6.ro_rt) {
+ lifp = ro6.ro_rt->rt_ifp;
+ RTFREE(ro6.ro_rt);
+ if (lifp)
+ return (ND_IFINFO(lifp)->chlim);
+ } else
+ return (ip6_defhlim);
+ }
+ return (ip6_defhlim);
}
/*
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index b95b1976bd7a..30728518dddd 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -96,6 +96,7 @@
#include <netinet/icmp6.h>
#include <netinet6/ip6_var.h>
#include <netinet/in_pcb.h>
+#include <netinet/tcp_var.h>
#include <netinet6/nd6.h>
#ifdef IPSEC
@@ -661,7 +662,7 @@ skip_ipsec2:;
/* XXX rt not locked */
ia = ifatoia6(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
- ro->ro_rt->rt_use++;
+ ro->ro_rt->rt_rmx.rmx_pksent++;
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = (struct sockaddr_in6 *)ro->ro_rt->rt_gateway;
m->m_flags &= ~(M_BCAST | M_MCAST); /* just in case */
@@ -757,7 +758,7 @@ skip_ipsec2:;
}
ia = ifatoia6(ro->ro_rt->rt_ifa);
ifp = ro->ro_rt->rt_ifp;
- ro->ro_rt->rt_use++;
+ ro->ro_rt->rt_rmx.rmx_pksent++;
RT_UNLOCK(ro->ro_rt);
}
@@ -1387,11 +1388,20 @@ ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup, alwaysfragp)
}
if (ro_pmtu->ro_rt) {
u_int32_t ifmtu;
+ struct in_conninfo inc;
+
+ bzero(&inc, sizeof(inc));
+ inc.inc_flags = 1; /* IPv6 */
+ inc.inc6_faddr = *dst;
if (ifp == NULL)
ifp = ro_pmtu->ro_rt->rt_ifp;
ifmtu = IN6_LINKMTU(ifp);
- mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
+ mtu = tcp_hc_getmtu(&inc);
+ if (mtu)
+ mtu = min(mtu, ro_pmtu->ro_rt->rt_rmx.rmx_mtu);
+ else
+ mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu;
if (mtu == 0)
mtu = ifmtu;
else if (mtu < IPV6_MMTU) {
@@ -1415,8 +1425,7 @@ ip6_getpmtu(ro_pmtu, ro, ifp, dst, mtup, alwaysfragp)
* field isn't locked).
*/
mtu = ifmtu;
- if (!(ro_pmtu->ro_rt->rt_rmx.rmx_locks & RTV_MTU))
- ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu;
+ ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu;
}
} else if (ifp) {
mtu = IN6_LINKMTU(ifp);
@@ -1993,7 +2002,9 @@ do { \
{
u_long pmtu = 0;
struct ip6_mtuinfo mtuinfo;
- struct route_in6 *ro = (struct route_in6 *)&in6p->in6p_route;
+ struct route_in6 sro;
+
+ bzero(&sro, sizeof(sro));
if (!(so->so_state & SS_ISCONNECTED))
return (ENOTCONN);
@@ -2002,8 +2013,10 @@ do { \
* routing, or optional information to specify
* the outgoing interface.
*/
- error = ip6_getpmtu(ro, NULL, NULL,
+ error = ip6_getpmtu(&sro, NULL, NULL,
&in6p->in6p_faddr, &pmtu, NULL);
+ if (sro.ro_rt)
+ RTFREE(sro.ro_rt);
if (error)
break;
if (pmtu > IPV6_MAXPACKET)
diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c
index 36a7fba38a00..d905e8479205 100644
--- a/sys/netinet6/udp6_output.c
+++ b/sys/netinet6/udp6_output.c
@@ -203,8 +203,7 @@ udp6_output(in6p, m, addr6, control, td)
if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
laddr = in6_selectsrc(sin6, in6p->in6p_outputopts,
- in6p->in6p_moptions,
- &in6p->in6p_route,
+ in6p->in6p_moptions, NULL,
&in6p->in6p_laddr, &error);
} else
laddr = &in6p->in6p_laddr; /* XXX */
@@ -277,9 +276,7 @@ udp6_output(in6p, m, addr6, control, td)
ip6->ip6_plen = htons((u_short)plen);
#endif
ip6->ip6_nxt = IPPROTO_UDP;
- ip6->ip6_hlim = in6_selecthlim(in6p,
- in6p->in6p_route.ro_rt ?
- in6p->in6p_route.ro_rt->rt_ifp : NULL);
+ ip6->ip6_hlim = in6_selecthlim(in6p, NULL);
ip6->ip6_src = *laddr;
ip6->ip6_dst = *faddr;
@@ -297,7 +294,7 @@ udp6_output(in6p, m, addr6, control, td)
goto release;
}
#endif /* IPSEC */
- error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
+ error = ip6_output(m, in6p->in6p_outputopts, NULL,
flags, in6p->in6p_moptions, NULL, in6p);
break;
case AF_INET: