svn commit: r197687 - head/sys/net
Qing Li
qingli at freebsd.org
Fri Oct 2 01:32:41 UTC 2009
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 at 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
>
More information about the svn-src-all
mailing list