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