Date: Sun, 1 Mar 2009 03:32:28 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r189199 - user/kmacy/releng_7_fast_net/sys/netinet Message-ID: <200903010332.n213WSha029225@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Sun Mar 1 03:32:28 2009 New Revision: 189199 URL: http://svn.freebsd.org/changeset/base/189199 Log: IFC HEAD_fast_net 186573: cache rtentry in inpcb for connected sockets Modified: user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.c user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.h user/kmacy/releng_7_fast_net/sys/netinet/ip_output.c user/kmacy/releng_7_fast_net/sys/netinet/tcp_usrreq.c Modified: user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.c ============================================================================== --- user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.c Sun Mar 1 03:07:07 2009 (r189198) +++ user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.c Sun Mar 1 03:32:28 2009 (r189199) @@ -489,6 +489,39 @@ in_pcbbind_setup(struct inpcb *inp, stru return (0); } +void +in_pcbrtalloc(struct inpcb *inp, in_addr_t faddr, struct route *sro) +{ + struct sockaddr_in *sin; + + INP_WLOCK_ASSERT(inp); + bzero(sro, sizeof(*sro)); + sin = (struct sockaddr_in *)&sro->ro_dst; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_addr.s_addr = faddr; + /* + * If route is known our src addr is taken from the i/f, + * else punt. + * + * Find out route to destination. + */ + if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0) { +#ifdef RADIX_MPATH + rtalloc_mpath_fib(sro, ntohl(faddr->s_addr), + inp->inp_inc.inc_fibnum); +#else + in_rtalloc_ign(sro, 0, inp->inp_inc.inc_fibnum); +#endif + } + + if (sro->ro_rt != NULL) { + inp->inp_rt = sro->ro_rt; + inp->inp_vflag |= INP_RT_VALID; + + } +} + /* * Connect from a socket to a specified address. * Both address and port must be specified in argument sin. @@ -501,6 +534,7 @@ in_pcbconnect(struct inpcb *inp, struct u_short lport, fport; in_addr_t laddr, faddr; int anonport, error; + struct route sro; INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); INP_WLOCK_ASSERT(inp); @@ -524,6 +558,7 @@ in_pcbconnect(struct inpcb *inp, struct } } + in_pcbrtalloc(inp, faddr, &sro); /* Commit the remaining changes. */ inp->inp_lport = lport; inp->inp_laddr.s_addr = laddr; @@ -861,6 +896,12 @@ in_pcbdisconnect(struct inpcb *inp) INP_INFO_WLOCK_ASSERT(inp->inp_pcbinfo); INP_WLOCK_ASSERT(inp); + if (inp->inp_vflag & INP_RT_VALID) { + RTFREE(inp->inp_rt); + inp->inp_rt = NULL; + inp->inp_vflag &= ~INP_RT_VALID; + } + inp->inp_faddr.s_addr = INADDR_ANY; inp->inp_fport = 0; in_pcbrehash(inp); @@ -900,6 +941,12 @@ in_pcbfree(struct inpcb *inp) INP_INFO_WLOCK_ASSERT(ipi); INP_WLOCK_ASSERT(inp); + if (inp->inp_vflag & INP_RT_VALID) { + RTFREE(inp->inp_rt); + inp->inp_rt = NULL; + inp->inp_vflag &= ~INP_RT_VALID; + } + #ifdef IPSEC ipsec4_delete_pcbpolicy(inp); #endif /*IPSEC*/ Modified: user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.h ============================================================================== --- user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.h Sun Mar 1 03:07:07 2009 (r189198) +++ user/kmacy/releng_7_fast_net/sys/netinet/in_pcb.h Sun Mar 1 03:32:28 2009 (r189199) @@ -160,9 +160,9 @@ struct inpcb { u_char inp_ip_ttl; /* (i) time to live proto */ u_char inp_ip_p; /* (c) protocol proto */ u_char inp_ip_minttl; /* (i) minimum TTL or drop */ - uint32_t inp_ispare1; /* (x) connection id / queue id */ - void *inp_pspare; /* (x) rtentry / general use */ - struct ucred *inp_cred; /* (c) cache of socket cred */ + u_int inp_refcount; /* (i) refcount */ + void *inp_pspare[1]; /* L2 information */ + struct rtentry *inp_rt; /* L3 information */ /* Local and foreign ports, local and foreign addr. */ struct in_conninfo inp_inc; /* (i/p) list for PCB's local port */ @@ -317,6 +317,9 @@ struct inpcbinfo { #define INP_RLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_RLOCKED) #define INP_WLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_WLOCKED) #define INP_UNLOCK_ASSERT(inp) rw_assert(&(inp)->inp_lock, RA_UNLOCKED) +#define INP_TRY_UPGRADE(inp) rw_try_upgrade(&(inp)->inp_lock) +#define INP_DOWNGRADE(inp) rw_downgrade(&(inp)->inp_lock) +#define INP_WLOCKED(inp) rw_wowned(&(inp)->inp_lock) #ifdef _KERNEL /* @@ -414,6 +417,7 @@ void inp_4tuple_get(struct inpcb *inp, #define INP_ONESBCAST 0x10 /* send all-ones broadcast */ #define INP_DROPPED 0x20 /* protocol drop flag */ #define INP_SOCKREF 0x40 /* strong socket reference */ +#define INP_RT_VALID 0x80 /* rtentry is set */ /* * Flags for inp_flag. @@ -499,6 +503,7 @@ void in_pcbdisconnect(struct inpcb *); void in_pcbdrop(struct inpcb *); void in_pcbfree(struct inpcb *); int in_pcbinshash(struct inpcb *); +void in_pcbrtalloc(struct inpcb *inp, in_addr_t faddr, struct route *sro); struct inpcb * in_pcblookup_local(struct inpcbinfo *, struct in_addr, u_short, int, struct ucred *); Modified: user/kmacy/releng_7_fast_net/sys/netinet/ip_output.c ============================================================================== --- user/kmacy/releng_7_fast_net/sys/netinet/ip_output.c Sun Mar 1 03:07:07 2009 (r189198) +++ user/kmacy/releng_7_fast_net/sys/netinet/ip_output.c Sun Mar 1 03:32:28 2009 (r189199) @@ -110,11 +110,13 @@ ip_output(struct mbuf *m, struct mbuf *o int hlen = sizeof (struct ip); int mtu; int len, error = 0; + int neednewroute = 0; struct sockaddr_in *dst = NULL; /* keep compiler happy */ struct in_ifaddr *ia = NULL; int isbroadcast, sw_csum; struct route iproute; struct in_addr odst; + struct sockaddr_in *sin; #ifdef IPFIREWALL_FORWARD struct m_tag *fwd_tag = NULL; #endif @@ -128,6 +130,16 @@ ip_output(struct mbuf *m, struct mbuf *o if (inp != NULL) { M_SETFIB(m, inp->inp_inc.inc_fibnum); INP_LOCK_ASSERT(inp); + if ((ro == &iproute) && (inp->inp_vflag & INP_RT_VALID)) { + if (inp->inp_rt->rt_flags & RTF_UP) { + sin = (struct sockaddr_in *)&ro->ro_dst; + sin->sin_family = AF_INET; + sin->sin_len = sizeof(struct sockaddr_in); + sin->sin_addr.s_addr = inp->inp_faddr.s_addr; + ro->ro_rt = inp->inp_rt; + } else + neednewroute = 1; + } } if (opt) { @@ -170,7 +182,8 @@ again: if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || dst->sin_family != AF_INET || dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { - RTFREE(ro->ro_rt); + if (inp == NULL || (ro->ro_rt != inp->inp_rt)) + RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)NULL; } #ifdef IPFIREWALL_FORWARD @@ -595,8 +608,20 @@ passout: ipstat.ips_fragmented++; done: - if (ro == &iproute && ro->ro_rt) { - RTFREE(ro->ro_rt); + if (ro == &iproute && ro->ro_rt != NULL) { + int wlocked; + + if (inp == NULL || (inp->inp_vflag & INP_RT_VALID) == 0) + RTFREE(ro->ro_rt); + else if (neednewroute && ro->ro_rt != inp->inp_rt) { + wlocked = INP_WLOCKED(inp); + if (!wlocked && INP_TRY_UPGRADE(inp) == 0) + return (error); + RTFREE(inp->inp_rt); + inp->inp_rt = ro->ro_rt; + if (!wlocked) + INP_DOWNGRADE(inp); + } } return (error); bad: Modified: user/kmacy/releng_7_fast_net/sys/netinet/tcp_usrreq.c ============================================================================== --- user/kmacy/releng_7_fast_net/sys/netinet/tcp_usrreq.c Sun Mar 1 03:07:07 2009 (r189198) +++ user/kmacy/releng_7_fast_net/sys/netinet/tcp_usrreq.c Sun Mar 1 03:32:28 2009 (r189199) @@ -1087,6 +1087,7 @@ tcp_connect(struct tcpcb *tp, struct soc struct inpcb *inp = tp->t_inpcb, *oinp; struct socket *so = inp->inp_socket; struct in_addr laddr; + struct route sro; u_short lport; int error; @@ -1115,6 +1116,7 @@ tcp_connect(struct tcpcb *tp, struct soc inp->inp_laddr = laddr; in_pcbrehash(inp); + in_pcbrtalloc(inp, inp->inp_faddr.s_addr, &sro); /* * Compute window scaling to request: * Scale to fit into sweet spot. See tcp_syncache.c.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903010332.n213WSha029225>