[BACK]Return to route.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / net

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/net/route.c between version 1.121.4.4 and 1.122

version 1.121.4.4, 2011/04/21 01:42:13 version 1.122, 2010/05/02 19:17:56
Line 96 
Line 96 
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/kmem.h>  
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/callout.h>  #include <sys/callout.h>
Line 125  __KERNEL_RCSID(0, "$NetBSD$");
Line 124  __KERNEL_RCSID(0, "$NetBSD$");
 #define rtcache_debug() 0  #define rtcache_debug() 0
 #endif /* RTFLUSH_DEBUG */  #endif /* RTFLUSH_DEBUG */
   
   struct  route_cb route_cb;
 struct  rtstat  rtstat;  struct  rtstat  rtstat;
   struct  radix_node_head *rt_tables[AF_MAX+1];
   
 int     rttrash;                /* routes not in table but not freed */  int     rttrash;                /* routes not in table but not freed */
   
Line 252  rt_set_ifa(struct rtentry *rt, struct if
Line 253  rt_set_ifa(struct rtentry *rt, struct if
         rt_set_ifa1(rt, ifa);          rt_set_ifa1(rt, ifa);
 }  }
   
   void
   rtable_init(void **table)
   {
           struct domain *dom;
           DOMAIN_FOREACH(dom)
                   if (dom->dom_rtattach)
                           dom->dom_rtattach(&table[dom->dom_family],
                               dom->dom_rtoffset);
   }
   
 static int  static int
 route_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,  route_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
     void *arg0, void *arg1, void *arg2, void *arg3)      void *arg0, void *arg1, void *arg2, void *arg3)
Line 272  route_listener_cb(kauth_cred_t cred, kau
Line 283  route_listener_cb(kauth_cred_t cred, kau
 }  }
   
 void  void
 rt_init(void)  route_init(void)
 {  {
   
 #ifdef RTFLUSH_DEBUG  #ifdef RTFLUSH_DEBUG
Line 284  rt_init(void)
Line 295  rt_init(void)
         pool_init(&rttimer_pool, sizeof(struct rttimer), 0, 0, 0, "rttmrpl",          pool_init(&rttimer_pool, sizeof(struct rttimer), 0, 0, 0, "rttmrpl",
             NULL, IPL_SOFTNET);              NULL, IPL_SOFTNET);
   
           rt_init();
         rn_init();      /* initialize all zeroes, all ones, mask table */          rn_init();      /* initialize all zeroes, all ones, mask table */
         rtbl_init();          rtable_init((void **)rt_tables);
   
         route_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,          route_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
             route_listener_cb, NULL);              route_listener_cb, NULL);
Line 328  rtcache(struct route *ro)
Line 340  rtcache(struct route *ro)
 struct rtentry *  struct rtentry *
 rtalloc1(const struct sockaddr *dst, int report)  rtalloc1(const struct sockaddr *dst, int report)
 {  {
         rtbl_t *rtbl = rt_gettable(dst->sa_family);          struct radix_node_head *rnh = rt_tables[dst->sa_family];
         struct rtentry *rt;          struct rtentry *rt;
           struct radix_node *rn;
         struct rtentry *newrt = NULL;          struct rtentry *newrt = NULL;
         struct rt_addrinfo info;          struct rt_addrinfo info;
         int  s = splsoftnet(), err = 0, msgtype = RTM_MISS;          int  s = splsoftnet(), err = 0, msgtype = RTM_MISS;
   
         if (rtbl != NULL && (rt = rt_matchaddr(rtbl, dst)) != NULL) {          if (rnh && (rn = rnh->rnh_matchaddr(dst, rnh)) &&
                 newrt = rt;              ((rn->rn_flags & RNF_ROOT) == 0)) {
                   newrt = rt = (struct rtentry *)rn;
                 if (report && (rt->rt_flags & RTF_CLONING)) {                  if (report && (rt->rt_flags & RTF_CLONING)) {
                         err = rtrequest(RTM_RESOLVE, dst, NULL, NULL, 0,                          err = rtrequest(RTM_RESOLVE, dst, NULL, NULL, 0,
                             &newrt);                              &newrt);
Line 383  rtfree(struct rtentry *rt)
Line 397  rtfree(struct rtentry *rt)
                 panic("rtfree");                  panic("rtfree");
         rt->rt_refcnt--;          rt->rt_refcnt--;
         if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {          if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
                 rt_assert_inactive(rt);                  if (rt->rt_nodes->rn_flags & (RNF_ACTIVE | RNF_ROOT))
                           panic ("rtfree 2");
                 rttrash--;                  rttrash--;
                 if (rt->rt_refcnt < 0) {                  if (rt->rt_refcnt < 0) {
                         printf("rtfree: %p not freed (neg refs)\n", rt);                          printf("rtfree: %p not freed (neg refs)\n", rt);
Line 684  int
Line 699  int
 rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)  rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)
 {  {
         int s = splsoftnet();          int s = splsoftnet();
         int error = 0, rc;          int error = 0;
         struct rtentry *rt, *crt;          struct rtentry *rt, *crt;
         rtbl_t *rtbl;          struct radix_node *rn;
           struct radix_node_head *rnh;
         struct ifaddr *ifa, *ifa2;          struct ifaddr *ifa, *ifa2;
         struct sockaddr_storage maskeddst;          struct sockaddr_storage maskeddst;
         const struct sockaddr *dst = info->rti_info[RTAX_DST];          const struct sockaddr *dst = info->rti_info[RTAX_DST];
Line 695  rtrequest1(int req, struct rt_addrinfo *
Line 711  rtrequest1(int req, struct rt_addrinfo *
         int flags = info->rti_flags;          int flags = info->rti_flags;
 #define senderr(x) { error = x ; goto bad; }  #define senderr(x) { error = x ; goto bad; }
   
         if ((rtbl = rt_gettable(dst->sa_family)) == NULL)          if ((rnh = rt_tables[dst->sa_family]) == NULL)
                 senderr(ESRCH);                  senderr(ESRCH);
         if (flags & RTF_HOST)          if (flags & RTF_HOST)
                 netmask = NULL;                  netmask = NULL;
Line 706  rtrequest1(int req, struct rt_addrinfo *
Line 722  rtrequest1(int req, struct rt_addrinfo *
                             netmask);                              netmask);
                         dst = (struct sockaddr *)&maskeddst;                          dst = (struct sockaddr *)&maskeddst;
                 }                  }
                 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)                  if ((rn = rnh->rnh_lookup(dst, netmask, rnh)) == NULL)
                         senderr(ESRCH);                          senderr(ESRCH);
                   rt = (struct rtentry *)rn;
                 if ((rt->rt_flags & RTF_CLONING) != 0) {                  if ((rt->rt_flags & RTF_CLONING) != 0) {
                         /* clean up any cloned children */                          /* clean up any cloned children */
                         rtflushclone(dst->sa_family, rt);                          rtflushclone(dst->sa_family, rt);
                 }                  }
                 if ((rt = rt_deladdr(rtbl, dst, netmask)) == NULL)                  if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)
                         senderr(ESRCH);                          senderr(ESRCH);
                   if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))
                           panic ("rtrequest delete");
                   rt = (struct rtentry *)rn;
                 if (rt->rt_gwroute) {                  if (rt->rt_gwroute) {
                         RTFREE(rt->rt_gwroute);                          RTFREE(rt->rt_gwroute);
                         rt->rt_gwroute = NULL;                          rt->rt_gwroute = NULL;
Line 784  rtrequest1(int req, struct rt_addrinfo *
Line 804  rtrequest1(int req, struct rt_addrinfo *
                         RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                          RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 }                  }
                 rt_set_ifa(rt, ifa);                  rt_set_ifa(rt, ifa);
                 if (info->rti_info[RTAX_TAG] != NULL)  
                         rt_settag(rt, info->rti_info[RTAX_TAG]);  
                 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                  RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 if (info->rti_info[RTAX_IFP] != NULL &&                  if (info->rti_info[RTAX_IFP] != NULL &&
                     (ifa2 = ifa_ifwithnet(info->rti_info[RTAX_IFP])) != NULL &&                      (ifa2 = ifa_ifwithnet(info->rti_info[RTAX_IFP])) != NULL &&
Line 799  rtrequest1(int req, struct rt_addrinfo *
Line 817  rtrequest1(int req, struct rt_addrinfo *
                         rt->rt_parent->rt_refcnt++;                          rt->rt_parent->rt_refcnt++;
                 }                  }
                 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                  RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 rc = rt_addaddr(rtbl, rt, netmask);                  rn = rnh->rnh_addaddr(rt_getkey(rt), netmask, rnh,
                       rt->rt_nodes);
                 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                  RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 if (rc != 0 && (crt = rtalloc1(rt_getkey(rt), 0)) != NULL) {                  if (rn == NULL && (crt = rtalloc1(rt_getkey(rt), 0)) != NULL) {
                         /* overwrite cloned route */                          /* overwrite cloned route */
                         if ((crt->rt_flags & RTF_CLONED) != 0) {                          if ((crt->rt_flags & RTF_CLONED) != 0) {
                                 rtdeletemsg(crt);                                  rtdeletemsg(crt);
                                 rc = rt_addaddr(rtbl, rt, netmask);                                  rn = rnh->rnh_addaddr(rt_getkey(rt),
                                       netmask, rnh, rt->rt_nodes);
                         }                          }
                         RTFREE(crt);                          RTFREE(crt);
                         RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                          RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 }                  }
                 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                  RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 if (rc != 0) {                  if (rn == NULL) {
                         IFAFREE(ifa);                          IFAFREE(ifa);
                         if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent)                          if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent)
                                 rtfree(rt->rt_parent);                                  rtfree(rt->rt_parent);
Line 819  rtrequest1(int req, struct rt_addrinfo *
Line 839  rtrequest1(int req, struct rt_addrinfo *
                                 rtfree(rt->rt_gwroute);                                  rtfree(rt->rt_gwroute);
                         rt_destroy(rt);                          rt_destroy(rt);
                         pool_put(&rtentry_pool, rt);                          pool_put(&rtentry_pool, rt);
                         senderr(rc);                          senderr(EEXIST);
                 }                  }
                 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);                  RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
                 if (ifa->ifa_rtrequest)                  if (ifa->ifa_rtrequest)
Line 841  rtrequest1(int req, struct rt_addrinfo *
Line 861  rtrequest1(int req, struct rt_addrinfo *
                             netmask);                              netmask);
                         dst = (struct sockaddr *)&maskeddst;                          dst = (struct sockaddr *)&maskeddst;
                 }                  }
                 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)                  rn = rnh->rnh_lookup(dst, netmask, rnh);
                   if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0)
                         senderr(ESRCH);                          senderr(ESRCH);
                 if (ret_nrt != NULL) {                  if (ret_nrt != NULL) {
                           rt = (struct rtentry *)rn;
                         *ret_nrt = rt;                          *ret_nrt = rt;
                         rt->rt_refcnt++;                          rt->rt_refcnt++;
                 }                  }
Line 1369  rtcache_setdst(struct route *ro, const s
Line 1391  rtcache_setdst(struct route *ro, const s
         return 0;          return 0;
 }  }
   
 const struct sockaddr *  static int
 rt_settag(struct rtentry *rt, const struct sockaddr *tag)  rt_walktree_visitor(struct radix_node *rn, void *v)
 {  {
         if (rt->rt_tag != tag) {          struct rtwalk *rw = (struct rtwalk *)v;
                 if (rt->rt_tag != NULL)  
                         sockaddr_free(rt->rt_tag);          return (*rw->rw_f)((struct rtentry *)rn, rw->rw_v);
                 rt->rt_tag = sockaddr_dup(tag, M_NOWAIT);  
         }  
         return rt->rt_tag;  
 }  }
   
 struct sockaddr *  int
 rt_gettag(struct rtentry *rt)  rt_walktree(sa_family_t family, int (*f)(struct rtentry *, void *), void *v)
 {  {
         return rt->rt_tag;          struct radix_node_head *rnh = rt_tables[family];
           struct rtwalk rw;
   
           if (rnh == NULL)
                   return 0;
   
           rw.rw_f = f;
           rw.rw_v = v;
   
           return rn_walktree(rnh, rt_walktree_visitor, &rw);
 }  }

Legend:
Removed from v.1.121.4.4  
changed lines
  Added in v.1.122

CVSweb <webmaster@jp.NetBSD.org>