Date: Thu, 1 Oct 2009 18:32:39 -0700 From: Qing Li <qingli@freebsd.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r197687 - head/sys/net Message-ID: <9ace436c0910011832q3fe6d273nbfd3c9a5d8d348ed@mail.gmail.com> In-Reply-To: <200910012032.n91KWTOa064111@svn.freebsd.org> References: <200910012032.n91KWTOa064111@svn.freebsd.org>
index | next in thread | previous in thread | raw e-mail
I misinterpreted the "Submitted by:" field. I thought I put in the names of persons who reported the bug. Disregard the "Submitted by" field for this checkin. It's my code. Something breaks, my fault, email me ... -- Qing On Thu, Oct 1, 2009 at 1:32 PM, Qing Li <qingli@freebsd.org> wrote: > Author: qingli > Date: Thu Oct 1 20:32:29 2009 > New Revision: 197687 > URL: http://svn.freebsd.org/changeset/base/197687 > > Log: > The flow-table associates TCP/UDP flows and IP destinations with > specific routes. When the routing table changes, for example, > when a new route with a more specific prefix is inserted into the > routing table, the flow-table is not updated to reflect that change. > As such existing connections cannot take advantage of the new path. > In some cases the path is broken. This patch will update the affected > flow-table entries when a more specific route is added. The route > entry is properly marked when a route is deleted from the table. > In this case, when the flow-table performs a search, the stale > entry is updated automatically. Therefore this patch is not > necessary for route deletion. > > Submitted by: simon, phk > Reviewed by: bz, kmacy > MFC after: 3 days > > Modified: > head/sys/net/flowtable.c > head/sys/net/flowtable.h > head/sys/net/route.c > > Modified: head/sys/net/flowtable.c > ============================================================================== > --- head/sys/net/flowtable.c Thu Oct 1 20:11:42 2009 (r197686) > +++ head/sys/net/flowtable.c Thu Oct 1 20:32:29 2009 (r197687) > @@ -830,7 +830,7 @@ fle_free(struct flentry *fle) > } > > static void > -flowtable_free_stale(struct flowtable *ft) > +flowtable_free_stale(struct flowtable *ft, struct rtentry *rt) > { > int curbit = 0, count; > struct flentry *fle, **flehead, *fleprev; > @@ -866,8 +866,14 @@ flowtable_free_stale(struct flowtable *f > curbit); > } > #endif > - while (fle != NULL) { > - if (!flow_stale(ft, fle)) { > + while (fle != NULL) { > + if (rt != NULL) { > + if (__DEVOLATILE(struct rtentry *, fle->f_rt) != rt) { > + fleprev = fle; > + fle = fle->f_next; > + continue; > + } > + } else if (!flow_stale(ft, fle)) { > fleprev = fle; > fle = fle->f_next; > continue; > @@ -916,6 +922,30 @@ flowtable_free_stale(struct flowtable *f > log(LOG_DEBUG, "freed %d flow entries\n", count); > } > > +void > +flowtable_route_flush(struct flowtable *ft, struct rtentry *rt) > +{ > + int i; > + if (ft->ft_flags & FL_PCPU) { > + for (i = 0; i <= mp_maxid; i++) { > + if (CPU_ABSENT(i)) > + continue; > + > + thread_lock(curthread); > + sched_bind(curthread, i); > + thread_unlock(curthread); > + > + flowtable_free_stale(ft, rt); > + > + thread_lock(curthread); > + sched_unbind(curthread); > + thread_unlock(curthread); > + } > + } else { > + flowtable_free_stale(ft, rt); > + } > +} > + > static void > flowtable_clean_vnet(void) > { > @@ -933,14 +963,14 @@ flowtable_clean_vnet(void) > sched_bind(curthread, i); > thread_unlock(curthread); > > - flowtable_free_stale(ft); > + flowtable_free_stale(ft, NULL); > > thread_lock(curthread); > sched_unbind(curthread); > thread_unlock(curthread); > } > } else { > - flowtable_free_stale(ft); > + flowtable_free_stale(ft, NULL); > } > ft = ft->ft_next; > } > > Modified: head/sys/net/flowtable.h > ============================================================================== > --- head/sys/net/flowtable.h Thu Oct 1 20:11:42 2009 (r197686) > +++ head/sys/net/flowtable.h Thu Oct 1 20:32:29 2009 (r197687) > @@ -51,5 +51,7 @@ struct flowtable *flowtable_alloc(int ne > int flowtable_lookup(struct flowtable *ft, struct mbuf *m, > struct route *ro, uint32_t fibnum); > > +void flowtable_route_flush(struct flowtable *ft, struct rtentry *rt); > + > #endif /* _KERNEL */ > #endif > > Modified: head/sys/net/route.c > ============================================================================== > --- head/sys/net/route.c Thu Oct 1 20:11:42 2009 (r197686) > +++ head/sys/net/route.c Thu Oct 1 20:32:29 2009 (r197687) > @@ -56,6 +56,7 @@ > #include <net/if_dl.h> > #include <net/route.h> > #include <net/vnet.h> > +#include <net/flowtable.h> > > #ifdef RADIX_MPATH > #include <net/radix_mpath.h> > @@ -996,6 +997,9 @@ rtrequest1_fib(int req, struct rt_addrin > { > int error = 0, needlock = 0; > register struct rtentry *rt; > +#ifdef FLOWTABLE > + register struct rtentry *rt0; > +#endif > register struct radix_node *rn; > register struct radix_node_head *rnh; > struct ifaddr *ifa; > @@ -1153,6 +1157,53 @@ rtrequest1_fib(int req, struct rt_addrin > } > #endif > > +#ifdef FLOWTABLE > + rt0 = NULL; > + /* XXX > + * "flow-table" only support IPv4 at the moment. > + */ > + if (dst->sa_family == AF_INET) { > + rn = rnh->rnh_matchaddr(dst, rnh); > + if (rn && ((rn->rn_flags & RNF_ROOT) == 0)) { > + struct sockaddr *mask; > + u_char *m, *n; > + int len; > + > + /* > + * compare mask to see if the new route is > + * more specific than the existing one > + */ > + rt0 = RNTORT(rn); > + RT_LOCK(rt0); > + RT_ADDREF(rt0); > + RT_UNLOCK(rt0); > + /* > + * A host route is already present, so > + * leave the flow-table entries as is. > + */ > + if (rt0->rt_flags & RTF_HOST) { > + RTFREE(rt0); > + rt0 = NULL; > + } else if (!(flags & RTF_HOST) && netmask) { > + mask = rt_mask(rt0); > + len = mask->sa_len; > + m = (u_char *)mask; > + n = (u_char *)netmask; > + while (len-- > 0) { > + if (*n != *m) > + break; > + n++; > + m++; > + } > + if (len == 0 || (*n < *m)) { > + RTFREE(rt0); > + rt0 = NULL; > + } > + } > + } > + } > +#endif > + > /* XXX mtu manipulation will be done in rnh_addaddr -- itojun */ > rn = rnh->rnh_addaddr(ndst, netmask, rnh, rt->rt_nodes); > /* > @@ -1165,8 +1216,18 @@ rtrequest1_fib(int req, struct rt_addrin > Free(rt_key(rt)); > RT_LOCK_DESTROY(rt); > uma_zfree(V_rtzone, rt); > +#ifdef FLOWTABLE > + if (rt0 != NULL) > + RTFREE(rt0); > +#endif > senderr(EEXIST); > + } > +#ifdef FLOWTABLE > + else if (rt0 != NULL) { > + flowtable_route_flush(V_ip_ft, rt0); > + RTFREE(rt0); > } > +#endif > > /* > * If this protocol has something to add to this then >help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9ace436c0910011832q3fe6d273nbfd3c9a5d8d348ed>
