Diff for /embedaddon/dnsmasq/src/netlink.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2014/06/15 16:31:38 version 1.1.1.3, 2016/11/02 09:57:01
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
   
    This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
Line 38 Line 38
 static struct iovec iov;  static struct iovec iov;
 static u32 netlink_pid;  static u32 netlink_pid;
   
static int nl_async(struct nlmsghdr *h);static void nl_async(struct nlmsghdr *h);
   
 void netlink_init(void)  void netlink_init(void)
 {  {
Line 142  int iface_enumerate(int family, void *parm, int (*call Line 142  int iface_enumerate(int family, void *parm, int (*call
   struct nlmsghdr *h;    struct nlmsghdr *h;
   ssize_t len;    ssize_t len;
   static unsigned int seq = 0;    static unsigned int seq = 0;
  int callback_ok = 1, newaddr = 0;  int callback_ok = 1;
   
   struct {    struct {
     struct nlmsghdr nlh;      struct nlmsghdr nlh;
Line 169  int iface_enumerate(int family, void *parm, int (*call Line 169  int iface_enumerate(int family, void *parm, int (*call
   req.g.rtgen_family = family;     req.g.rtgen_family = family; 
   
   /* Don't block in recvfrom if send fails */    /* Don't block in recvfrom if send fails */
  while((len = sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0,   while(retry_send(sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0, 
                      (struct sockaddr *)&addr, sizeof(addr))) == -1 && retry_send());                          (struct sockaddr *)&addr, sizeof(addr))));
  
  if (len == -1)  if (errno != 0)
     return 0;      return 0;
           
   while (1)    while (1)
Line 191  int iface_enumerate(int family, void *parm, int (*call Line 191  int iface_enumerate(int family, void *parm, int (*call
         if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)          if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
           {            {
             /* May be multicast arriving async */              /* May be multicast arriving async */
            if (nl_async(h))            nl_async(h);
              { 
                newaddr = 1;  
                enumerate_interfaces(1); /* reset */ 
              } 
           }            }
         else if (h->nlmsg_type == NLMSG_DONE)          else if (h->nlmsg_type == NLMSG_DONE)
          {          return callback_ok;
            /* handle async new interface address arrivals, these have to be done 
               after we complete as we're not re-entrant */ 
            if (newaddr)  
              newaddress(dnsmasq_time()); 
                 
            return callback_ok; 
          } 
         else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)          else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
           {            {
             struct ifaddrmsg *ifa = NLMSG_DATA(h);                struct ifaddrmsg *ifa = NLMSG_DATA(h);  
Line 219  int iface_enumerate(int family, void *parm, int (*call Line 208  int iface_enumerate(int family, void *parm, int (*call
                     struct in_addr netmask, addr, broadcast;                      struct in_addr netmask, addr, broadcast;
                     char *label = NULL;                      char *label = NULL;
   
                    netmask.s_addr = htonl(0xffffffff << (32 - ifa->ifa_prefixlen));                    netmask.s_addr = htonl(~(in_addr_t)0 << (32 - ifa->ifa_prefixlen));
 
                     addr.s_addr = 0;                      addr.s_addr = 0;
                     broadcast.s_addr = 0;                      broadcast.s_addr = 0;
                                           
Line 298  int iface_enumerate(int family, void *parm, int (*call Line 288  int iface_enumerate(int family, void *parm, int (*call
                 rta = RTA_NEXT(rta, len1);                  rta = RTA_NEXT(rta, len1);
               }                }
   
            if (inaddr && mac && callback_ok)            if (!(neigh->ndm_state & (NUD_NOARP | NUD_INCOMPLETE | NUD_FAILED)) &&
                 inaddr && mac && callback_ok)
               if (!((*callback)(neigh->ndm_family, inaddr, mac, maclen, parm)))                if (!((*callback)(neigh->ndm_family, inaddr, mac, maclen, parm)))
                 callback_ok = 0;                  callback_ok = 0;
           }            }
Line 330  int iface_enumerate(int family, void *parm, int (*call Line 321  int iface_enumerate(int family, void *parm, int (*call
     }      }
 }  }
   
void netlink_multicast(time_t now)void netlink_multicast(void)
 {  {
   ssize_t len;    ssize_t len;
   struct nlmsghdr *h;    struct nlmsghdr *h;
  int flags, newaddr = 0;  int flags;
       
   /* don't risk blocking reading netlink messages here. */    /* don't risk blocking reading netlink messages here. */
   if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||    if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
Line 343  void netlink_multicast(time_t now) Line 334  void netlink_multicast(time_t now)
       
   if ((len = netlink_recv()) != -1)    if ((len = netlink_recv()) != -1)
     for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))      for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
      if (nl_async(h))      nl_async(h);
        newaddr = 1; 
       
   /* restore non-blocking status */    /* restore non-blocking status */
   fcntl(daemon->netlinkfd, F_SETFL, flags);    fcntl(daemon->netlinkfd, F_SETFL, flags);
     
   if (newaddr)   
     newaddress(now);  
 }  }
   
static int nl_async(struct nlmsghdr *h)static void nl_async(struct nlmsghdr *h)
 {  {
   if (h->nlmsg_type == NLMSG_ERROR)    if (h->nlmsg_type == NLMSG_ERROR)
     {      {
       struct nlmsgerr *err = NLMSG_DATA(h);        struct nlmsgerr *err = NLMSG_DATA(h);
       if (err->error != 0)        if (err->error != 0)
         my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));          my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
       return 0;  
     }      }
   else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)     else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE) 
     {      {
Line 372  static int nl_async(struct nlmsghdr *h) Line 358  static int nl_async(struct nlmsghdr *h)
       struct rtmsg *rtm = NLMSG_DATA(h);        struct rtmsg *rtm = NLMSG_DATA(h);
               
       if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)        if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
        {        queue_event(EVENT_NEWROUTE);
          /* Force re-reading resolv file right now, for luck. */ 
          daemon->last_resolv = 0; 
           
          if (daemon->srv_save) 
            { 
              int fd; 
 
              if (daemon->srv_save->sfd) 
                fd = daemon->srv_save->sfd->fd; 
              else if (daemon->rfd_save && daemon->rfd_save->refcount != 0) 
                fd = daemon->rfd_save->fd; 
              else 
                return 0; 
               
              while(sendto(fd, daemon->packet, daemon->packet_len, 0, 
                           &daemon->srv_save->addr.sa, sa_len(&daemon->srv_save->addr)) == -1 && retry_send());  
            } 
        } 
      return 0; 
     }      }
   else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)     else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) 
    return 1; /* clever bind mode - rescan */    queue_event(EVENT_NEWADDR);
   
  return 0; 
 }  }
 #endif  #endif
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>