From: Roy Marples Date: Thu, 11 Sep 2008 09:38:02 +0000 (+0000) Subject: Add allowinterfaces and denyinterfaces options to dhcpcd.conf for better multiple... X-Git-Tag: v5.0.0~265 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba97e49417ba7463405abdb7d62e834349f0d329;p=thirdparty%2Fdhcpcd.git Add allowinterfaces and denyinterfaces options to dhcpcd.conf for better multiple interface support. --- diff --git a/dhcpcd.8.in b/dhcpcd.8.in index aba3b866..f0ae80a5 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 3, 2008 +.Dd September 11, 2008 .Dt DHCPCD 8 SMM .Sh NAME .Nm dhcpcd @@ -42,12 +42,14 @@ .Op Fl t , -timeout Ar seconds .Op Fl u , -userclass Ar class .Op Fl v , -vendor Ar code , Ar value +.Op Fl z , -allowinterfaces Ar pattern .Op Fl C , -nohook Ar hook .Op Fl F , -fqdn Ar FQDN .Op Fl I , -clientid Ar clientid .Op Fl O , -nooption Ar option .Op Fl Q , -require Ar option .Op Fl X , -blacklist Ar address +.Op Fl Z , -denyinterfaces Ar pattern .Op interface .Op ... .Nm @@ -104,8 +106,10 @@ can be run per interface or as a single instance to manage all interfaces. If a list of interfaces are given on the command line, then .Nm only works with those interfaces. -If no interfaces are given then we detect all available interfaces and +If no interfaces are given then we discover available interfaces and attempt to configure all of them. +See options below for controlling what interfaces we allow and deny through +the use of patterns. .Ss Hooking into DHCP events .Nm runs @@ -349,6 +353,14 @@ Quiet .Nm on the command line, only warnings and errors will be displayed. The messages are still logged though. +.It Fl z , -allowinterfaces Ar pattern +When discovering interfaces, the interface name must match +.Ar pattern +which is a space or comma separated list of patterns passed to +.Xr fnmatch 3 . +If the same interface is matched in +.Fl Z , -denyinterfaces +then it is still denied. .It Fl A , -noarp Don't request or claim the address by ARP. This also disables IPv4LL. @@ -397,6 +409,11 @@ as the server ID. This may be expanded in future releases to ignore all packets matching either the IP or hardware .Ar address . +.It Fl Z , -denyinterfaces Ar pattern +When discovering interfaces, the interface name must not match +.Ar pattern +which is a space or comma separated list of patterns passed to +.Xr fnmatch 3 . .El .Sh NOTES .Nm @@ -430,6 +447,7 @@ running on the .Xr dhcpcd-run-hooks 8 , .Xr resolv.conf 5 , .Xr resolvconf 8 , +.Xr fnmatch 3 .Sh STANDARDS RFC 2131, RFC 2132, RFC 2855, RFC 3004, RFC 3361, RFC 3396, RFC 3397, RFC 3442, RFC 3927, RFC 4361, RFC 4390, RFC 4702. diff --git a/dhcpcd.c b/dhcpcd.c index 9992b41e..d7111117 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -68,6 +68,10 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples"; int options = 0; int pidfd = -1; struct interface *ifaces = NULL; +int ifac = 0; +char **ifav = NULL; +int ifdc = 0; +char **ifdv = NULL; static char **ifv = NULL; static int ifc = 0; @@ -134,12 +138,20 @@ cleanup(void) { #ifdef DEBUG_MEMORY struct interface *iface; + int i; while (ifaces) { iface = ifaces; ifaces = iface->next; free_interface(iface); } + + for (i = 0; i < ifac; i++) + free(ifav[i]); + free(ifav); + for (i = 0; i < ifdc; i++) + free(ifdv[i]); + free(ifdv); #endif if (linkfd != -1) @@ -986,7 +998,6 @@ main(int argc, char **argv) closefrom(3); openlog(PACKAGE, LOG_PERROR, LOG_DAEMON); setlogmask(LOG_UPTO(LOG_INFO)); - options = DHCPCD_DAEMONISE; /* Test for --help and --version */ if (argc > 1) { @@ -999,6 +1010,7 @@ main(int argc, char **argv) } } + i = 0; while ((opt = getopt_long(argc, argv, IF_OPTS, cf_options, &oi)) != -1) { switch (opt) { @@ -1018,7 +1030,7 @@ main(int argc, char **argv) sig = SIGTERM; break; case 'T': - options |= DHCPCD_TEST | DHCPCD_PERSISTENT; + i = 1; break; case 'V': print_options(); @@ -1036,12 +1048,15 @@ main(int argc, char **argv) usage(); exit(EXIT_FAILURE); } + options = ifo->options; + if (i) + options |= DHCPCD_TEST | DHCPCD_PERSISTENT; #ifdef THERE_IS_NO_FORK options &= ~DHCPCD_DAEMONISE; #endif - if (ifo->options & DHCPCD_QUIET) + if (options & DHCPCD_QUIET) setlogmask(LOG_UPTO(LOG_WARNING)); /* If we have any other args, we should run as a single dhcpcd instance diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 899aea35..a492855d 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 18, 2008 +.Dd September 11, 2008 .Dt DHCPCD.CONF 5 SMM .Sh NAME .Nm dhcpcd.conf @@ -43,6 +43,19 @@ Blank lines and lines starting with # are ignored. .Pp Here's a list of available options: .Bl -tag -width indent +.It Ic allowinterfaces Ar pattern +When discovering interfaces, the interface name must match +.Ar pattern +which is a space or comma separated list of patterns passed to +.Xr fnmatch 3 . +If the same interface is matched in +.Ic denyinterfaces +then it is still denied. +.It Ic denyinterfaces Ar pattern +When discovering interfaces, the interface name must not match +.Ar pattern +which is a space or comma separated list of patterns passed to +.Xr fnmatch 3 . .It Ic background Background immediately. This is useful for startup scripts which don't disable link messages for @@ -148,7 +161,8 @@ If not set then none is sent. .El .Sh SEE ALSO .Xr dhcpcd-run-hooks 8 , -.Xr dhcpcd 8 +.Xr dhcpcd 8 , +.Xr fnmatch 3 .Sh AUTHORS .An Roy Marples .Sh BUGS diff --git a/dhcpcd.h b/dhcpcd.h index 2251febd..19ca613f 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -106,6 +106,10 @@ struct interface extern int pidfd; extern int options; +extern int ifac; +extern char **ifav; +extern int ifdc; +extern char **ifdv; extern struct interface *ifaces; int handle_args(int, char **); diff --git a/if-linux.c b/if-linux.c index 9a20abc2..8419b5ec 100644 --- a/if-linux.c +++ b/if-linux.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -397,7 +398,6 @@ discover_interfaces(int argc, char * const *argv) FILE *f; char *buffer = NULL, *p; size_t len = 0, ln = 0, n; - int i; struct interface *ifs = NULL, *ifp, *ifl; if ((f = fopen("/proc/net/dev", "r"))) { @@ -418,10 +418,21 @@ discover_interfaces(int argc, char * const *argv) if (ifp) continue; if (argc > 0) { - for (i = 0; i < argc; i++) - if (strcmp(argv[i], p) == 0) + for (n = 0; n < argc; n++) + if (strcmp(argv[n], p) == 0) break; - if (i == argc) + if (n == argc) + continue; + } else { + for (n = 0; n < ifdc; n++) + if (!fnmatch(ifdv[n], ifr->ifr_name, 0)) + break; + if (n < ifdc) + continue; + for (n = 0; n < ifac; n++) + if (!fnmatch(ifav[n], ifr->ifr_name, 0)) + break; + if (ifac && n == ifac) continue; } if ((ifp = init_interface(p))) { diff --git a/if-options.c b/if-options.c index 3c45b0de..e51a09f6 100644 --- a/if-options.c +++ b/if-options.c @@ -51,41 +51,43 @@ #define OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:" const struct option cf_options[] = { - {"background", no_argument, NULL, 'b'}, - {"script", required_argument, NULL, 'c'}, - {"debug", no_argument, NULL, 'd'}, - {"config", required_argument, NULL, 'f'}, - {"hostname", optional_argument, NULL, 'h'}, - {"vendorclassid", optional_argument, NULL, 'i'}, - {"release", no_argument, NULL, 'k'}, - {"leasetime", required_argument, NULL, 'l'}, - {"metric", required_argument, NULL, 'm'}, - {"rebind", no_argument, NULL, 'n'}, - {"option", required_argument, NULL, 'o'}, - {"persistent", no_argument, NULL, 'p'}, - {"quiet", no_argument, NULL, 'q'}, - {"request", optional_argument, NULL, 'r'}, - {"inform", optional_argument, NULL, 's'}, - {"timeout", required_argument, NULL, 't'}, - {"userclass", required_argument, NULL, 'u'}, - {"vendor", required_argument, NULL, 'v'}, - {"exit", no_argument, NULL, 'x'}, - {"noarp", no_argument, NULL, 'A'}, - {"nobackground", no_argument, NULL, 'B'}, - {"nohook", required_argument, NULL, 'C'}, - {"duid", no_argument, NULL, 'D'}, - {"lastlease", no_argument, NULL, 'E'}, - {"fqdn", optional_argument, NULL, 'F'}, - {"nogateway", no_argument, NULL, 'G'}, - {"clientid", optional_argument, NULL, 'I'}, - {"nolink", no_argument, NULL, 'K'}, - {"noipv4ll", no_argument, NULL, 'L'}, - {"nooption", optional_argument, NULL, 'O'}, - {"require", required_argument, NULL, 'Q'}, - {"test", no_argument, NULL, 'T'}, - {"variables", no_argument, NULL, 'V'}, - {"blacklist", required_argument, NULL, 'X'}, - {NULL, 0, NULL, '\0'} + {"background", no_argument, NULL, 'b'}, + {"script", required_argument, NULL, 'c'}, + {"debug", no_argument, NULL, 'd'}, + {"config", required_argument, NULL, 'f'}, + {"hostname", optional_argument, NULL, 'h'}, + {"vendorclassid", optional_argument, NULL, 'i'}, + {"release", no_argument, NULL, 'k'}, + {"leasetime", required_argument, NULL, 'l'}, + {"metric", required_argument, NULL, 'm'}, + {"rebind", no_argument, NULL, 'n'}, + {"option", required_argument, NULL, 'o'}, + {"persistent", no_argument, NULL, 'p'}, + {"quiet", no_argument, NULL, 'q'}, + {"request", optional_argument, NULL, 'r'}, + {"inform", optional_argument, NULL, 's'}, + {"timeout", required_argument, NULL, 't'}, + {"userclass", required_argument, NULL, 'u'}, + {"vendor", required_argument, NULL, 'v'}, + {"exit", no_argument, NULL, 'x'}, + {"allowinterfaces", required_argument, NULL, 'z'}, + {"noarp", no_argument, NULL, 'A'}, + {"nobackground", no_argument, NULL, 'B'}, + {"nohook", required_argument, NULL, 'C'}, + {"duid", no_argument, NULL, 'D'}, + {"lastlease", no_argument, NULL, 'E'}, + {"fqdn", optional_argument, NULL, 'F'}, + {"nogateway", no_argument, NULL, 'G'}, + {"clientid", optional_argument, NULL, 'I'}, + {"nolink", no_argument, NULL, 'K'}, + {"noipv4ll", no_argument, NULL, 'L'}, + {"nooption", optional_argument, NULL, 'O'}, + {"require", required_argument, NULL, 'Q'}, + {"test", no_argument, NULL, 'T'}, + {"variables", no_argument, NULL, 'V'}, + {"blacklist", required_argument, NULL, 'X'}, + {"denyinterfaces", required_argument, NULL, 'Z'}, + {NULL, 0, NULL, '\0'} }; static int @@ -248,6 +250,22 @@ parse_string_hwaddr(char *sbuf, ssize_t slen, const char *str, int clid) return l; } +static char ** +splitv(int *argc, char **argv, const char *arg) +{ + char **v = argv; + char *o = xstrdup(arg), *p, *t; + + p = o; + while ((t = strsep(&p, ", "))) { + (*argc)++; + v = xrealloc(v, *argc); + v[(*argc) - 1] = xstrdup(t); + } + free(o); + return v; +} + static int parse_option(struct if_options *ifo, int opt, const char *arg) { @@ -417,6 +435,11 @@ parse_option(struct if_options *ifo, int opt, const char *arg) ifo->vendor[0] += s + 2; } break; + case 'z': + /* We only set this if we haven't got any interfaces */ + if (!ifaces) + ifav = splitv(&ifac, ifav, arg); + break; case 'A': ifo->options &= ~DHCPCD_ARP; /* IPv4LL requires ARP */ @@ -514,6 +537,11 @@ parse_option(struct if_options *ifo, int opt, const char *arg) ifo->blacklist[ifo->blacklist_len] = addr.s_addr; ifo->blacklist_len++; break; + case 'Z': + /* We only set this if we haven't got any interfaces */ + if (!ifaces) + ifdv = splitv(&ifdc, ifdv, arg); + break; default: return 0; } diff --git a/if-options.h b/if-options.h index 7358bd64..0559eec0 100644 --- a/if-options.h +++ b/if-options.h @@ -36,8 +36,8 @@ #include /* Don't set any optional arguments here so we retain POSIX - * * compatibility with getopt */ -#define IF_OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xABC:DEF:GI:KLO:Q:TVX:" + * compatibility with getopt */ +#define IF_OPTS "bc:df:h:i:kl:m:no:pqr:s:t:u:v:xz:ABC:DEF:GI:KLO:Q:TVX:Z:" #define DEFAULT_TIMEOUT 30 #define DEFAULT_LEASETIME 3600 /* 1 hour */ diff --git a/net.c b/net.c index 1f015be7..15b80075 100644 --- a/net.c +++ b/net.c @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -398,6 +399,17 @@ do_interface(const char *ifname, break; if (n == argc) continue; + } else { + for (n = 0; n < ifdc; n++) + if (!fnmatch(ifdv[n], ifr->ifr_name, 0)) + break; + if (n < ifdc) + continue; + for (n = 0; n < ifac; n++) + if (!fnmatch(ifav[n], ifr->ifr_name, 0)) + break; + if (ifac && n == ifac) + continue; } ifn = init_interface(ifr->ifr_name); if (!ifn)