]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Enable net.ipv4.conf.$iface.promote_secondaries on Linux so that
authorRoy Marples <roy@marples.name>
Fri, 26 Feb 2010 20:37:30 +0000 (20:37 +0000)
committerRoy Marples <roy@marples.name>
Fri, 26 Feb 2010 20:37:30 +0000 (20:37 +0000)
we keep the subnet when changing addresses on the same subnet.

if-bsd.c
if-linux.c
net.c
net.h
platform-linux.c

index 58c405f83d8b33f35e1c3beeb0d1bc6ac46908c1..05a2d5157aa89e87425132db5a188494e356afb9 100644 (file)
--- a/if-bsd.c
+++ b/if-bsd.c
 
 static int r_fd = -1;
 
+int
+if_init(_unused struct interface *iface)
+{
+       /* BSD promotes secondary address by default */
+       return 0;
+}
+
 int
 init_sockets(void)
 {
index d24b956e33be01ef6f3a43c59526926a0fa05f00..705f775383b242a19563cc56939a3c526d8c8870 100644 (file)
 static int sock_fd;
 static struct sockaddr_nl sock_nl;
 
+int
+if_init(struct interface *iface)
+{
+       char path[PATH_MAX];
+       FILE *fp;
+       int n;
+
+       /* We enable promote_secondaries so that we can do this
+        * add 192.168.1.2/24
+        * add 192.168.1.3/24
+        * del 192.168.1.2/24
+        * and the subnet mask moves onto 192.168.1.3/24
+        * This matches the behaviour of BSD which makes coding dhcpcd
+        * a little easier as there's just one behaviour. */
+       snprintf(path, sizeof(path),
+           "/proc/sys/net/ipv4/conf/%s/promote_secondaries",
+           iface->name);
+
+       fp = fopen(path, "w");
+       if (fp == NULL)
+               return errno == ENOENT ? 0 : -1;
+       n = fprintf(fp, "1");
+       fclose(fp);
+       return n == -1 ? -1 : 0;
+}
+
 static int
 _open_link_socket(struct sockaddr_nl *nl)
 {
diff --git a/net.c b/net.c
index b55a7108fc877db38b14cfa132eaa7620a2f0f8d..20edd0e7358ed3a786d7ef7f87235cced0d09705 100644 (file)
--- a/net.c
+++ b/net.c
@@ -449,6 +449,14 @@ discover_interfaces(int argc, char * const *argv)
                                    "%s: unknown hardware family", p);
                        }
                }
+
+               /* Handle any platform init for the interface */
+               if (if_init(ifp) == -1) {
+                       syslog(LOG_ERR, "%s: if_init: %m", p);
+                       free_interface(ifp);
+                       continue;
+               }
+
                if (ifl)
                        ifl->next = ifp; 
                else
diff --git a/net.h b/net.h
index d1e9c066288766d34500438a54f3c3b731816d20..4f92f0a7c85a5af36cae927916de23f9e4b630ec 100644 (file)
--- a/net.h
+++ b/net.h
@@ -105,6 +105,8 @@ int inet_ntocidr(struct in_addr);
 int inet_cidrtoaddr(int, struct in_addr *);
 
 int up_interface(struct interface *);
+int if_init(struct interface *);
+
 int do_address(const char *,
     struct in_addr *, struct in_addr *, struct in_addr *, int);
 int if_address(const struct interface *,
index c0bc59941da57cadbab462747f3f68313f5b7f83..99cb4a35ab9ac09a5566774b3676900455ce8553 100644 (file)
@@ -25,9 +25,6 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/param.h>
-#include <sys/sysctl.h>
-
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>