diff options
| author | Andre Oppermann <andre@FreeBSD.org> | 2003-11-20 20:07:39 +0000 |
|---|---|---|
| committer | Andre Oppermann <andre@FreeBSD.org> | 2003-11-20 20:07:39 +0000 |
| commit | 97d8d152c28bb596e1c310d9842db5d0314207b2 (patch) | |
| tree | f947a08d66395dd498056038f0c360783fa281c7 /sys/netinet6 | |
| parent | 26d02ca7babf8bb8d1e2b9c8cb3e18ec0fcd1317 (diff) | |
Notes
Diffstat (limited to 'sys/netinet6')
| -rw-r--r-- | sys/netinet6/icmp6.c | 32 | ||||
| -rw-r--r-- | sys/netinet6/in6_pcb.c | 44 | ||||
| -rw-r--r-- | sys/netinet6/in6_rmx.c | 3 | ||||
| -rw-r--r-- | sys/netinet6/in6_src.c | 45 | ||||
| -rw-r--r-- | sys/netinet6/ip6_output.c | 27 | ||||
| -rw-r--r-- | sys/netinet6/udp6_output.c | 9 |
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: |
