Stop rejecting leases with a subnet that overlaps a subnet already
authorkrw <krw@openbsd.org>
Mon, 18 May 2015 14:59:42 +0000 (14:59 +0000)
committerkrw <krw@openbsd.org>
Mon, 18 May 2015 14:59:42 +0000 (14:59 +0000)
present. The latest routing stack code can now handle these situations.

Much requested by beck@ and others. Detailed discussion at s2k15
identified required routing changes.

ok claudio@

sbin/dhclient/dhclient.c
sbin/dhclient/dhcpd.h
sbin/dhclient/dispatch.c

index d280bac..9c74c77 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhclient.c,v 1.360 2015/04/16 15:14:30 gsoares Exp $  */
+/*     $OpenBSD: dhclient.c,v 1.361 2015/05/18 14:59:42 krw Exp $      */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -1060,13 +1060,6 @@ dhcpoffer(struct in_addr client_addr, struct option_data *options, char *info)
                return;
        }
 
-       /*
-        * Reject offers whose subnet is already configured on another
-        * interface.
-        */
-       if (subnet_exists(lease))
-               return;
-
        /*
         * If this lease was acquired through a BOOTREPLY, record that
         * fact.
index c773eef..945aa00 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.149 2015/02/10 04:20:26 krw Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.150 2015/05/18 14:59:42 krw Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -261,7 +261,6 @@ void interface_link_forceup(char *);
 int interface_status(char *);
 int get_rdomain(char *);
 void get_hw_address(void);
-int subnet_exists(struct client_lease *);
 
 /* tables.c */
 extern const struct option dhcp_options[256];
index 2cb7cc9..11e3347 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dispatch.c,v 1.101 2015/04/16 15:14:31 gsoares Exp $  */
+/*     $OpenBSD: dispatch.c,v 1.102 2015/05/18 14:59:42 krw Exp $      */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -343,70 +343,3 @@ get_rdomain(char *name)
        close(s);
        return rv;
 }
-
-int
-subnet_exists(struct client_lease *l)
-{
-       struct option_data *opt;
-       struct ifaddrs *ifap, *ifa;
-       struct in_addr mymask, myaddr, mynet, hismask, hisaddr, hisnet;
-       int myrdomain, hisrdomain;
-
-       opt = &l->options[DHO_SUBNET_MASK];
-       if (opt->len == sizeof(mymask))
-               mymask.s_addr = ((struct in_addr *)opt->data)->s_addr;
-       else
-               mymask.s_addr = INADDR_ANY;
-       myaddr.s_addr = l->address.s_addr;
-       mynet.s_addr = mymask.s_addr & myaddr.s_addr;
-
-       myrdomain = get_rdomain(ifi->name);
-
-       if (getifaddrs(&ifap) != 0)
-               error("getifaddrs failed");
-
-       for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
-               if (strcmp(ifi->name, ifa->ifa_name) == 0)
-                       continue;
-
-               if (ifa->ifa_addr->sa_family != AF_INET)
-                       continue;
-
-               hisrdomain = get_rdomain(ifa->ifa_name);
-               if (hisrdomain != myrdomain)
-                       continue;
-
-               memcpy(&hismask,
-                   &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr,
-                   sizeof(hismask));
-               memcpy(&hisaddr,
-                   &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr,
-                   sizeof(hisaddr));
-               hisnet.s_addr = hisaddr.s_addr & hismask.s_addr;
-
-               if (hisnet.s_addr == INADDR_ANY)
-                       continue;
-
-               /* Would his packets go out *my* interface? */
-               if (mynet.s_addr == (hisaddr.s_addr & mymask.s_addr)) {
-                       note("interface %s already has the offered subnet!",
-                           ifa->ifa_name);
-                       break;
-               }
-
-               /* Would my packets go out *his* interface? */
-               if (hisnet.s_addr == (myaddr.s_addr & hismask.s_addr)) {
-                       note("interface %s already has the offered subnet!",
-                           ifa->ifa_name);
-                       break;
-               }
-       }
-
-       freeifaddrs(ifap);
-
-       /* If ifa == NULL we scanned the list without finding a problem. */
-       if (ifa == NULL)
-               return (0);
-       else
-               return (1);
-}