[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.145 and 1.146

version 1.145, 2015/06/08 08:21:49 version 1.146, 2015/07/17 02:21:08
Line 355  rtcache(struct route *ro)
Line 355  rtcache(struct route *ro)
 }  }
   
 /*  /*
  * Packet routing routines.   * Packet routing routines. If success, refcnt of a returned rtentry
    * will be incremented. The caller has to rtfree it by itself.
  */   */
 struct rtentry *  struct rtentry *
 rtalloc1(const struct sockaddr *dst, int report)  rtalloc1(const struct sockaddr *dst, int report)
Line 378  rtalloc1(const struct sockaddr *dst, int
Line 379  rtalloc1(const struct sockaddr *dst, int
                         }                          }
                         KASSERT(newrt != NULL);                          KASSERT(newrt != NULL);
                         rt = newrt;                          rt = newrt;
                           rt->rt_refcnt++;
                         if (rt->rt_flags & RTF_XRESOLVE) {                          if (rt->rt_flags & RTF_XRESOLVE) {
                                 msgtype = RTM_RESOLVE;                                  msgtype = RTM_RESOLVE;
                                 goto miss;                                  goto miss;
Line 533  out:
Line 535  out:
 }  }
   
 /*  /*
  * Delete a route and generate a message   * Delete a route and generate a message.
    * It doesn't free a passed rt.
  */   */
 static int  static int
 rtdeletemsg(struct rtentry *rt)  rtdeletemsg(struct rtentry *rt)
 {  {
         int error;          int error;
         struct rt_addrinfo info;          struct rt_addrinfo info;
           struct rtentry *retrt;
   
         /*          /*
          * Request the new route so that the entry is not actually           * Request the new route so that the entry is not actually
Line 551  rtdeletemsg(struct rtentry *rt)
Line 555  rtdeletemsg(struct rtentry *rt)
         info.rti_info[RTAX_NETMASK] = rt_mask(rt);          info.rti_info[RTAX_NETMASK] = rt_mask(rt);
         info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;          info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
         info.rti_flags = rt->rt_flags;          info.rti_flags = rt->rt_flags;
         error = rtrequest1(RTM_DELETE, &info, &rt);          error = rtrequest1(RTM_DELETE, &info, &retrt);
   
         rt_missmsg(RTM_DELETE, &info, info.rti_flags, error);          rt_missmsg(RTM_DELETE, &info, info.rti_flags, error);
   
         /* Adjust the refcount */          if (error == 0)
         if (error == 0 && rt->rt_refcnt <= 0) {                  rtfree(retrt);
                 rt->rt_refcnt++;  
                 rtfree(rt);  
         }  
         return error;          return error;
 }  }
   
Line 617  ifa_ifwithroute(int flags, const struct 
Line 618  ifa_ifwithroute(int flags, const struct 
                 struct rtentry *rt = rtalloc1(dst, 0);                  struct rtentry *rt = rtalloc1(dst, 0);
                 if (rt == NULL)                  if (rt == NULL)
                         return NULL;                          return NULL;
                 rt->rt_refcnt--;                  ifa = rt->rt_ifa;
                 if ((ifa = rt->rt_ifa) == NULL)                  rtfree(rt);
                   if (ifa == NULL)
                         return NULL;                          return NULL;
         }          }
         if (ifa->ifa_addr->sa_family != dst->sa_family) {          if (ifa->ifa_addr->sa_family != dst->sa_family) {
Line 630  ifa_ifwithroute(int flags, const struct 
Line 632  ifa_ifwithroute(int flags, const struct 
         return ifa;          return ifa;
 }  }
   
   /*
    * If it suceeds and ret_nrt isn't NULL, refcnt of ret_nrt is incremented.
    * The caller has to rtfree it by itself.
    */
 int  int
 rtrequest(int req, const struct sockaddr *dst, const struct sockaddr *gateway,  rtrequest(int req, const struct sockaddr *dst, const struct sockaddr *gateway,
         const struct sockaddr *netmask, int flags, struct rtentry **ret_nrt)          const struct sockaddr *netmask, int flags, struct rtentry **ret_nrt)
Line 644  rtrequest(int req, const struct sockaddr
Line 650  rtrequest(int req, const struct sockaddr
         return rtrequest1(req, &info, ret_nrt);          return rtrequest1(req, &info, ret_nrt);
 }  }
   
   /*
    * It's a utility function to add/remove a route to/from the routing table
    * and tell user processes the addition/removal on success.
    */
   int
   rtrequest_newmsg(const int req, const struct sockaddr *dst,
           const struct sockaddr *gateway, const struct sockaddr *netmask,
           const int flags)
   {
           int error;
           struct rtentry *ret_nrt = NULL;
   
           KASSERT(req == RTM_ADD || req == RTM_DELETE);
   
           error = rtrequest(req, dst, gateway, netmask, flags, &ret_nrt);
           if (error != 0)
                   return error;
   
           KASSERT(ret_nrt != NULL);
   
           rt_newmsg(req, ret_nrt); /* tell user process */
           rtfree(ret_nrt);
   
           return 0;
   }
   
 int  int
 rt_getifa(struct rt_addrinfo *info)  rt_getifa(struct rt_addrinfo *info)
 {  {
Line 688  rt_getifa(struct rt_addrinfo *info)
Line 720  rt_getifa(struct rt_addrinfo *info)
         return 0;          return 0;
 }  }
   
   /*
    * If it suceeds and ret_nrt isn't NULL, refcnt of ret_nrt is incremented.
    * The caller has to rtfree it by itself.
    */
 int  int
 rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)  rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)
 {  {
Line 743  rtrequest1(int req, struct rt_addrinfo *
Line 779  rtrequest1(int req, struct rt_addrinfo *
                                 ifa->ifa_rtrequest(RTM_DELETE, rt, info);                                  ifa->ifa_rtrequest(RTM_DELETE, rt, info);
                 }                  }
                 rttrash++;                  rttrash++;
                 if (ret_nrt)                  if (ret_nrt) {
                         *ret_nrt = rt;                          *ret_nrt = rt;
                 else if (rt->rt_refcnt <= 0) {                          rt->rt_refcnt++;
                   } else if (rt->rt_refcnt <= 0) {
                           /* Adjust the refcount */
                         rt->rt_refcnt++;                          rt->rt_refcnt++;
                         rtfree(rt);                          rtfree(rt);
                 }                  }
Line 974  rtinit(struct ifaddr *ifa, int cmd, int 
Line 1012  rtinit(struct ifaddr *ifa, int cmd, int 
                         rt_maskedcopy(odst, dst, ifa->ifa_netmask);                          rt_maskedcopy(odst, dst, ifa->ifa_netmask);
                 }                  }
                 if ((rt = rtalloc1(dst, 0)) != NULL) {                  if ((rt = rtalloc1(dst, 0)) != NULL) {
                         rt->rt_refcnt--;                          if (rt->rt_ifa != ifa) {
                         if (rt->rt_ifa != ifa)                                  rtfree(rt);
                                 return (flags & RTF_HOST) ? EHOSTUNREACH                                  return (flags & RTF_HOST) ? EHOSTUNREACH
                                                         : ENETUNREACH;                                                          : ENETUNREACH;
                           }
                           rtfree(rt);
                 }                  }
         }          }
         memset(&info, 0, sizeof(info));          memset(&info, 0, sizeof(info));
Line 996  rtinit(struct ifaddr *ifa, int cmd, int 
Line 1036  rtinit(struct ifaddr *ifa, int cmd, int 
         error = rtrequest1((cmd == RTM_LLINFO_UPD) ? RTM_GET : cmd, &info,          error = rtrequest1((cmd == RTM_LLINFO_UPD) ? RTM_GET : cmd, &info,
             &nrt);              &nrt);
         if (error != 0 || (rt = nrt) == NULL)          if (error != 0 || (rt = nrt) == NULL)
                 ;                  return error;
         else switch (cmd) {  
           switch (cmd) {
         case RTM_DELETE:          case RTM_DELETE:
                 rt_newmsg(cmd, nrt);                  rt_newmsg(cmd, rt);
                 if (rt->rt_refcnt <= 0) {                  rtfree(rt);
                         rt->rt_refcnt++;  
                         rtfree(rt);  
                 }  
                 break;                  break;
         case RTM_LLINFO_UPD:          case RTM_LLINFO_UPD:
                 rt->rt_refcnt--;  
                 RT_DPRINTF("%s: updating%s\n", __func__,                  RT_DPRINTF("%s: updating%s\n", __func__,
                     ((rt->rt_flags & RTF_LLINFO) == 0) ? " (no llinfo)" : "");                      ((rt->rt_flags & RTF_LLINFO) == 0) ? " (no llinfo)" : "");
   
Line 1023  rtinit(struct ifaddr *ifa, int cmd, int 
Line 1060  rtinit(struct ifaddr *ifa, int cmd, int 
   
                 if (cmd == RTM_LLINFO_UPD && ifa->ifa_rtrequest != NULL)                  if (cmd == RTM_LLINFO_UPD && ifa->ifa_rtrequest != NULL)
                         ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);                          ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);
                 rt_newmsg(RTM_CHANGE, nrt);                  rt_newmsg(RTM_CHANGE, rt);
                   rtfree(rt);
                 break;                  break;
         case RTM_ADD:          case RTM_ADD:
                 rt->rt_refcnt--;  
                 if (rt->rt_ifa != ifa) {                  if (rt->rt_ifa != ifa) {
                         printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,                          printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
                                 rt->rt_ifa);                                  rt->rt_ifa);
Line 1039  rtinit(struct ifaddr *ifa, int cmd, int 
Line 1076  rtinit(struct ifaddr *ifa, int cmd, int 
                         if (ifa->ifa_rtrequest != NULL)                          if (ifa->ifa_rtrequest != NULL)
                                 ifa->ifa_rtrequest(RTM_ADD, rt, &info);                                  ifa->ifa_rtrequest(RTM_ADD, rt, &info);
                 }                  }
                 rt_newmsg(cmd, nrt);                  rt_newmsg(cmd, rt);
                   rtfree(rt);
                 break;                  break;
         }          }
         return error;          return error;
Line 1085  rt_ifa_localrequest(int cmd, struct ifad
Line 1123  rt_ifa_localrequest(int cmd, struct ifad
                 rt_replace_ifa(nrt, ifa);                  rt_replace_ifa(nrt, ifa);
   
         rt_newaddrmsg(cmd, ifa, e, nrt);          rt_newaddrmsg(cmd, ifa, e, nrt);
         if (nrt) {          if (nrt != NULL)
                 if (cmd == RTM_DELETE) {                  rtfree(nrt);
                         if (nrt->rt_refcnt <= 0) {  
                                 /* XXX: we should free the entry ourselves. */  
                                 nrt->rt_refcnt++;  
                                 rtfree(nrt);  
                         }  
                 } else {  
                         /* the cmd must be RTM_ADD here */  
                         nrt->rt_refcnt--;  
                 }  
         }  
         return e;          return e;
 }  }
   
Line 1120  rt_ifa_addlocal(struct ifaddr *ifa)
Line 1149  rt_ifa_addlocal(struct ifaddr *ifa)
                 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);                  rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
         }          }
         if (rt != NULL)          if (rt != NULL)
                 rt->rt_refcnt--;                  rtfree(rt);
         return e;          return e;
 }  }
   
Line 1161  rt_ifa_remlocal(struct ifaddr *ifa, stru
Line 1190  rt_ifa_remlocal(struct ifaddr *ifa, stru
         } else          } else
                 rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);                  rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);
         if (rt != NULL)          if (rt != NULL)
                 rt->rt_refcnt--;                  rtfree(rt);
         return e;          return e;
 }  }
   

Legend:
Removed from v.1.145  
changed lines
  Added in v.1.146

CVSweb <webmaster@jp.NetBSD.org>