==== //depot/vendor/freebsd/src/sys/netinet/if_ether.c#84 (text+ko) - //depot/projects/ethng/src/sys/netinet/if_ether.c#7 (text+ko) ==== content @@ -224,8 +224,8 @@ RT_ADDREF(rt); la->la_rt = rt; rt->rt_flags |= RTF_LLINFO; - callout_init_mtx(&la->la_timer, &rt->rt_mtx, - CALLOUT_RETURNUNLOCKED); + callout_init_rwlock(&la->la_timer, &rt->rt_lock, + CALLOUT_RETURNUNLOCKED_RW); #ifdef INET /* ==== //depot/vendor/freebsd/src/sys/netinet/in_pcb.c#110 (text+ko) - //depot/projects/ethng/src/sys/netinet/in_pcb.c#8 (text+ko) ==== content @@ -160,6 +160,13 @@ &ipport_randomtime, 0, "Minimum time to keep sequental port " "allocation before switching to a random one"); + +static __inline int +calc_lfsr(int lfsr) +{ + return ((lfsr >> 1) ^ (-(signed int)(lfsr & 1) & 0xd0000001u)); /* taps 32 31 29 1 */ +} + /* * in_pcb.c: manage the Protocol Control Blocks. * @@ -177,7 +184,8 @@ { struct inpcb *inp; int error; - + static int rss_hash = 1; + INP_INFO_WLOCK_ASSERT(pcbinfo); error = 0; inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT); @@ -186,6 +194,7 @@ bzero(inp, inp_zero_size); inp->inp_pcbinfo = pcbinfo; inp->inp_socket = so; + inp->inp_rss_hash = rss_hash = calc_lfsr(rss_hash); #ifdef MAC error = mac_inpcb_init(inp, M_NOWAIT); if (error != 0) @@ -727,6 +736,8 @@ #ifdef MAC mac_inpcb_destroy(inp); #endif + if (inp->inp_route.ro_rt) + RTFREE(inp->inp_route.ro_rt); INP_UNLOCK(inp); uma_zfree(ipi->ipi_zone, inp); } ==== //depot/vendor/freebsd/src/sys/netinet/in_pcb.h#62 (text+ko) - //depot/projects/ethng/src/sys/netinet/in_pcb.h#3 (text+ko) ==== content @@ -169,7 +169,8 @@ #define inp_zero_size offsetof(struct inpcb, inp_gencnt) inp_gen_t inp_gencnt; /* generation count of this instance */ struct mtx inp_mtx; - + uint32_t inp_rss_hash; + struct route inp_route; #define in6p_faddr inp_inc.inc6_faddr #define in6p_laddr inp_inc.inc6_laddr #define in6p_hops inp_depend6.inp6_hops /* default hop limit */ ==== //depot/vendor/freebsd/src/sys/netinet/tcp_input.c#232 (text+ko) - //depot/projects/ethng/src/sys/netinet/tcp_input.c#5 (text+ko) ==== content @@ -634,6 +634,7 @@ INP_UNLOCK(inp); /* listen socket */ inp = sotoinpcb(so); INP_LOCK(inp); /* new connection */ + inp->inp_rss_hash = m->m_pkthdr.rss_hash; tp = intotcpcb(inp); KASSERT(tp->t_state == TCPS_SYN_RECEIVED, ("%s: ", __func__)); @@ -835,8 +836,8 @@ */ INP_INFO_UNLOCK_ASSERT(&tcbinfo); return; - } - + } else if (inp->inp_rss_hash != m->m_pkthdr.rss_hash && m->m_pkthdr.rss_hash) + inp->inp_rss_hash = m->m_pkthdr.rss_hash; /* * Segment belongs to a connection in SYN_SENT, ESTABLISHED or later * state. tcp_do_segment() always consumes the mbuf chain, unlocks ==== //depot/vendor/freebsd/src/sys/netinet/tcp_output.c#91 (text+ko) - //depot/projects/ethng/src/sys/netinet/tcp_output.c#6 (text+ko) ==== content @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -125,7 +126,8 @@ int tcp_output(struct tcpcb *tp) { - struct socket *so = tp->t_inpcb->inp_socket; + struct inpcb *inp = tp->t_inpcb; + struct socket *so = inp->inp_socket; long len, recwin, sendwin; int off, flags, error; #ifdef TCP_SIGNATURE @@ -142,6 +144,7 @@ struct sackhole *p; int tso = 0; struct tcpopt to; + struct rtentry *rt; #if 0 int maxburst = TCP_MAXBURST; #endif @@ -1123,8 +1126,27 @@ */ if (path_mtu_discovery) ip->ip_off |= IP_DF; + /* + * XXX timer wrap? + */ + rt = inp->inp_route.ro_rt; + if (rt == NULL || (rt && rt->rt_rmx.rmx_expire && (rt->rt_rmx.rmx_expire <= time_uptime))) { + struct sockaddr_in *dst = (struct sockaddr_in *)&inp->inp_route.ro_dst; + struct ip *ip = mtod(m, struct ip *); + + bzero(dst, sizeof(*dst)); + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr = ip->ip_dst; + if (rt) { + RTFREE(rt); + inp->inp_route.ro_rt = NULL; + } + rtalloc_ign(&inp->inp_route, 0); + } - error = ip_output(m, tp->t_inpcb->inp_options, NULL, + m->m_pkthdr.rss_hash = tp->t_inpcb->inp_rss_hash; + error = ip_output(m, tp->t_inpcb->inp_options, &inp->inp_route, ((so->so_options & SO_DONTROUTE) ? IP_ROUTETOIF : 0), 0, tp->t_inpcb); } ==== //depot/vendor/freebsd/src/sys/netinet/udp_usrreq.c#127 (text+ko) - //depot/projects/ethng/src/sys/netinet/udp_usrreq.c#7 (text+ko) ==== content @@ -769,7 +769,8 @@ int ipflags; u_short fport, lport; int unlock_udbinfo; - + struct rtentry *rt; + /* * udp_output() may need to temporarily bind or connect the current * inpcb. As such, we don't know up front whether we will need the @@ -969,7 +970,30 @@ if (unlock_udbinfo) INP_INFO_WUNLOCK(&udbinfo); - error = ip_output(m, inp->inp_options, NULL, ipflags, + + /* + * XXX timer wrap? + */ + rt = inp->inp_route.ro_rt; + if (rt == NULL || (rt && rt->rt_rmx.rmx_expire && (rt->rt_rmx.rmx_expire <= time_uptime))) { + struct sockaddr_in *dst = (struct sockaddr_in *)&inp->inp_route.ro_dst; + struct ip *ip = mtod(m, struct ip *); + + bzero(dst, sizeof(*dst)); + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr = ip->ip_dst; + if (rt) { + RTFREE(rt); + inp->inp_route.ro_rt = NULL; + } + rtalloc_ign(&inp->inp_route, 0); + } + + + + m->m_pkthdr.rss_hash = inp->inp_rss_hash; + error = ip_output(m, inp->inp_options, &inp->inp_route, ipflags, inp->inp_moptions, inp); INP_UNLOCK(inp); return (error);