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

version 1.1.1.3, 2016/11/02 09:57:01 version 1.1.1.4, 2021/03/17 00:56:46
Line 1 Line 1
/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley/* dnsmasq is Copyright (c) 2000-2021 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 22 Line 22
 #include <linux/netlink.h>  #include <linux/netlink.h>
 #include <linux/rtnetlink.h>  #include <linux/rtnetlink.h>
   
   /* Blergh. Radv does this, so that's our excuse. */
   #ifndef SOL_NETLINK
   #define SOL_NETLINK 270
   #endif
   
   #ifndef NETLINK_NO_ENOBUFS
   #define NETLINK_NO_ENOBUFS 5
   #endif
   
 /* linux 2.6.19 buggers up the headers, patch it up here. */   /* linux 2.6.19 buggers up the headers, patch it up here. */ 
 #ifndef IFA_RTA  #ifndef IFA_RTA
 #  define IFA_RTA(r)  \  #  define IFA_RTA(r)  \
Line 40  static u32 netlink_pid; Line 49  static u32 netlink_pid;
   
 static void nl_async(struct nlmsghdr *h);  static void nl_async(struct nlmsghdr *h);
   
void netlink_init(void)char *netlink_init(void)
 {  {
   struct sockaddr_nl addr;    struct sockaddr_nl addr;
   socklen_t slen = sizeof(addr);    socklen_t slen = sizeof(addr);
     int opt = 1;
   
   addr.nl_family = AF_NETLINK;    addr.nl_family = AF_NETLINK;
   addr.nl_pad = 0;    addr.nl_pad = 0;
Line 51  void netlink_init(void) Line 61  void netlink_init(void)
   addr.nl_groups = RTMGRP_IPV4_ROUTE;    addr.nl_groups = RTMGRP_IPV4_ROUTE;
   if (option_bool(OPT_CLEVERBIND))    if (option_bool(OPT_CLEVERBIND))
     addr.nl_groups |= RTMGRP_IPV4_IFADDR;        addr.nl_groups |= RTMGRP_IPV4_IFADDR;  
 #ifdef HAVE_IPV6  
   addr.nl_groups |= RTMGRP_IPV6_ROUTE;    addr.nl_groups |= RTMGRP_IPV6_ROUTE;
   if (option_bool(OPT_CLEVERBIND))    if (option_bool(OPT_CLEVERBIND))
     addr.nl_groups |= RTMGRP_IPV6_IFADDR;      addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif
 #ifdef HAVE_DHCP6  #ifdef HAVE_DHCP6
   if (daemon->doing_ra || daemon->doing_dhcp6)    if (daemon->doing_ra || daemon->doing_dhcp6)
     addr.nl_groups |= RTMGRP_IPV6_IFADDR;      addr.nl_groups |= RTMGRP_IPV6_IFADDR;
Line 73  void netlink_init(void) Line 82  void netlink_init(void)
     }      }
       
   if (daemon->netlinkfd == -1 ||     if (daemon->netlinkfd == -1 || 
      getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == 1)      getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
     die(_("cannot create netlink socket: %s"), NULL, EC_MISC);      die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
     
   
   /* save pid assigned by bind() and retrieved by getsockname() */     /* save pid assigned by bind() and retrieved by getsockname() */ 
   netlink_pid = addr.nl_pid;    netlink_pid = addr.nl_pid;
       
   iov.iov_len = 100;    iov.iov_len = 100;
   iov.iov_base = safe_malloc(iov.iov_len);    iov.iov_base = safe_malloc(iov.iov_len);
     
     if (daemon->kernel_version >= KERNEL_VERSION(2,6,30) &&
         setsockopt(daemon->netlinkfd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(opt)) == -1)
       return _("warning: failed to set NETLINK_NO_ENOBUFS on netlink socket");
     
     return NULL;
 }  }
   
 static ssize_t netlink_recv(void)  static ssize_t netlink_recv(void)
Line 149  int iface_enumerate(int family, void *parm, int (*call Line 165  int iface_enumerate(int family, void *parm, int (*call
     struct rtgenmsg g;       struct rtgenmsg g; 
   } req;    } req;
   
     memset(&req, 0, sizeof(req));
     memset(&addr, 0, sizeof(addr));
   
   addr.nl_family = AF_NETLINK;    addr.nl_family = AF_NETLINK;
   addr.nl_pad = 0;  
   addr.nl_groups = 0;  
   addr.nl_pid = 0; /* address to kernel */  
     
  again:    again: 
   if (family == AF_UNSPEC)    if (family == AF_UNSPEC)
Line 188  int iface_enumerate(int family, void *parm, int (*call Line 204  int iface_enumerate(int family, void *parm, int (*call
         }          }
   
       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 (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)        if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
           {            {
             /* May be multicast arriving async */              /* May be multicast arriving async */
             nl_async(h);              nl_async(h);
           }            }
           else if (h->nlmsg_seq != seq)
             {
               /* May be part of incomplete response to previous request after
                  ENOBUFS. Drop it. */
               continue;
             }
         else if (h->nlmsg_type == NLMSG_DONE)          else if (h->nlmsg_type == NLMSG_DONE)
           return callback_ok;            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)
Line 229  int iface_enumerate(int family, void *parm, int (*call Line 251  int iface_enumerate(int family, void *parm, int (*call
                       if (!((*callback)(addr, ifa->ifa_index, label,  netmask, broadcast, parm)))                        if (!((*callback)(addr, ifa->ifa_index, label,  netmask, broadcast, parm)))
                         callback_ok = 0;                          callback_ok = 0;
                   }                    }
 #ifdef HAVE_IPV6  
                 else if (ifa->ifa_family == AF_INET6)                  else if (ifa->ifa_family == AF_INET6)
                   {                    {
                     struct in6_addr *addrp = NULL;                      struct in6_addr *addrp = NULL;
Line 264  int iface_enumerate(int family, void *parm, int (*call Line 285  int iface_enumerate(int family, void *parm, int (*call
                                         (int) preferred, (int)valid, parm)))                                          (int) preferred, (int)valid, parm)))
                         callback_ok = 0;                          callback_ok = 0;
                   }                    }
 #endif  
               }                }
           }            }
         else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC)          else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC)
Line 357  static void nl_async(struct nlmsghdr *h) Line 377  static void nl_async(struct nlmsghdr *h)
          failing. */            failing. */ 
       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 &&
           (rtm->rtm_table == RT_TABLE_MAIN ||
            rtm->rtm_table == RT_TABLE_LOCAL))
         queue_event(EVENT_NEWROUTE);          queue_event(EVENT_NEWROUTE);
     }      }
   else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)     else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR) 

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


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