Fix bug 5681: Do not limit the number of network interfaces
authorVolker Lendecke <vl@samba.org>
Mon, 18 May 2009 08:32:27 +0000 (10:32 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 18 May 2009 11:38:55 +0000 (13:38 +0200)
Jeremy as far as I can see there is no real technical reason to limit the
number of interfaces. If you like this patch, can you please merge it to 3.4?
If you don't please tell me :-)

Thanks,

Volker

source3/include/interfaces.h
source3/lib/interface.c
source3/lib/interfaces.c
source3/lib/util_sock.c

index 9a19c33b57062f5a0ddb64c0cfccc1f4f006dc4c..6ba0e21f6dd1fbe9870b192c18ed4288b3d348cb 100644 (file)
@@ -27,8 +27,6 @@
 #include "../replace/replace.h"
 #include "../replace/system/network.h"
 
-#define MAX_INTERFACES 128
-
 struct iface_struct {
        char name[16];
        int flags;
@@ -46,6 +44,6 @@ void make_bcast(struct sockaddr_storage *pss_out,
 void make_net(struct sockaddr_storage *pss_out,
              const struct sockaddr_storage *pss_in,
              const struct sockaddr_storage *nmask);
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
+int get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces);
 
 #endif
index b32ccb9c56851d5f80b9bfbe9a03ed3ec17783b5..4a8a154edbc956f6f784ed9e6e60f6cd65210997 100644 (file)
@@ -492,7 +492,7 @@ static void interpret_interface(char *token)
 
 void load_interfaces(void)
 {
-       struct iface_struct ifaces[MAX_INTERFACES];
+       struct iface_struct *ifaces = NULL;
        const char **ptr = lp_interfaces();
        int i;
 
@@ -507,7 +507,7 @@ void load_interfaces(void)
        }
 
        /* Probe the kernel for interfaces */
-       total_probed = get_interfaces(ifaces, MAX_INTERFACES);
+       total_probed = get_interfaces(talloc_tos(), &ifaces);
 
        if (total_probed > 0) {
                probed_ifaces = (struct iface_struct *)memdup(ifaces,
@@ -517,6 +517,7 @@ void load_interfaces(void)
                        exit(1);
                }
        }
+       TALLOC_FREE(ifaces);
 
        /* if we don't have a interfaces line then use all broadcast capable
           interfaces except loopback */
@@ -569,15 +570,17 @@ void gfree_interfaces(void)
 
 bool interfaces_changed(void)
 {
+       bool ret = false;
        int n;
-       struct iface_struct ifaces[MAX_INTERFACES];
+       struct iface_struct *ifaces = NULL;
 
-       n = get_interfaces(ifaces, MAX_INTERFACES);
+       n = get_interfaces(talloc_tos(), &ifaces);
 
        if ((n > 0 )&& (n != total_probed ||
                        memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n))) {
-               return true;
+               ret = true;
        }
 
-       return false;
+       TALLOC_FREE(ifaces);
+       return ret;
 }
index 2535418d99a08a62351cc488dd69cacfdf3f54ec..bc6c991f6f80fffc45941c95ba050cc1d75341b9 100644 (file)
@@ -123,10 +123,12 @@ void make_net(struct sockaddr_storage *pss_out,
  Get the netmask address for a local interface.
 ****************************************************************************/
 
-static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+static int _get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
 {
+       struct iface_struct *ifaces;
        struct ifaddrs *iflist = NULL;
        struct ifaddrs *ifptr = NULL;
+       int count;
        int total = 0;
        size_t copy_size;
 
@@ -134,10 +136,25 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                return -1;
        }
 
+       count = 0;
+       for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
+               if (!ifptr->ifa_addr || !ifptr->ifa_netmask) {
+                       continue;
+               }
+               if (!(ifptr->ifa_flags & IFF_UP)) {
+                       continue;
+               }
+               count += 1;
+       }
+
+       ifaces = talloc_array(mem_ctx, struct iface_struct, count);
+       if (ifaces == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
        /* Loop through interfaces, looking for given IP address */
-       for (ifptr = iflist, total = 0;
-                       ifptr != NULL && total < max_interfaces;
-                       ifptr = ifptr->ifa_next) {
+       for (ifptr = iflist; ifptr != NULL; ifptr = ifptr->ifa_next) {
 
                memset(&ifaces[total], '\0', sizeof(ifaces[total]));
 
@@ -147,13 +164,13 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                        continue;
                }
 
-               ifaces[total].flags = ifptr->ifa_flags;
-
                /* Check the interface is up. */
-               if (!(ifaces[total].flags & IFF_UP)) {
+               if (!(ifptr->ifa_flags & IFF_UP)) {
                        continue;
                }
 
+               ifaces[total].flags = ifptr->ifa_flags;
+
 #if defined(HAVE_IPV6)
                if (ifptr->ifa_addr->sa_family == AF_INET6) {
                        copy_size = sizeof(struct sockaddr_in6);
@@ -183,6 +200,7 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
 
        freeifaddrs(iflist);
 
+       *pifaces = ifaces;
        return total;
 }
 
@@ -250,14 +268,14 @@ static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
        return 0;
 }
 
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
 /* this wrapper is used to remove duplicates from the interface list generated
    above */
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
+int get_interfaces(TALLOC_CTX *mem_ctx, struct iface_struct **pifaces)
 {
+       struct iface_struct *ifaces;
        int total, i, j;
 
-       total = _get_interfaces(ifaces, max_interfaces);
+       total = _get_interfaces(mem_ctx, &ifaces);
        if (total <= 0) return total;
 
        /* now we need to remove duplicates */
@@ -274,6 +292,7 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
                }
        }
 
+       *pifaces = ifaces;
        return total;
 }
 
index 1d7a82d7a5797ccc7303ff4153dce43cfaa59a48..40e2887440f8f48f1d153990d0daf1f1eec4468f 100644 (file)
@@ -1948,12 +1948,7 @@ bool is_myname_or_ipaddr(const char *s)
                        return false;
                }
 
-               nics = TALLOC_ARRAY(ctx, struct iface_struct,
-                                       MAX_INTERFACES);
-               if (!nics) {
-                       return false;
-               }
-               n = get_interfaces(nics, MAX_INTERFACES);
+               n = get_interfaces(talloc_tos(), &nics);
                for (i=0; i<n; i++) {
                        if (sockaddr_equal((struct sockaddr *)&nics[i].ip, (struct sockaddr *)&ss)) {
                                TALLOC_FREE(nics);