]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
interfaces: allow whitelisting an interface
authorVincent Bernat <vbe@deezer.com>
Thu, 6 Mar 2014 17:09:27 +0000 (18:09 +0100)
committerVincent Bernat <vbe@deezer.com>
Thu, 6 Mar 2014 17:09:27 +0000 (18:09 +0100)
Currently, this means that an interface can be both blacklisted and
whitelisted and in this case, it is accepted as valid.

NEWS
src/daemon/lldpd.8
src/daemon/pattern.c
tests/check_pattern.c

diff --git a/NEWS b/NEWS
index 30537444a1361fc1baacb7bb69bccde3ff4bb9e1..e77168aa6a7ba363a725a74074e87e0af9f0df28 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ lldpd (0.7.8)
     + Android support
     + Add the possibility to disable privilege separation (lower
       memory consumption, lower security, don't do it).
+    + Interfaces can now be whitelisted. For example, *,!eth*,!!eth1
+      is a valid pattern for all interfaces except eth ones, except
+      eth1.
 
 lldpd (0.7.7)
   * Features:
index cfb0191fb5a238fe76165faadf6b767c0726db03..da10a6eb7c560d3737d09b28e982b9c98b84d20c 100644 (file)
@@ -194,8 +194,10 @@ Specify which interface to listen to. Without this option,
 will listen on all available interfaces. This option can use
 wildcards. Several interfaces can be specified separated by commas.
 It is also possible to blacklist an interface by suffixing it with an
-exclamation mark. When an interface is both specified with and without
-an exclamation mark, it is blacklisted. For example, with
+exclamation mark. It is possible to whitelist an interface by
+suffixing it with two exclamation marks. A whitelisted interface beats
+a blacklisted interfaces which beats a simple matched interface. For
+example, with
 .Em eth*,!eth1,!eth2
 .Nm
 will only listen to interfaces starting by
@@ -204,6 +206,13 @@ with the exception of
 .Em eth1
 and
 .Em eth2 .
+While with
+.Em *,!eth*,!!eth1
+.Nm
+will listen to all interfaces, except interfaces starting by
+.Em eth
+with the exception of
+.Em eth1 .
 .It Fl C Ar interfaces
 Specify which interfaces to use for computing chassis ID. Without this
 option, all interfaces are considered.
index 10aa770ed0a40bd25e69bb681a87b9055daf5948..059effdd5c0407f10dc45584e33395b6fec4aace 100644 (file)
  * @param string   String to match against the list of patterns
  * @param patterns List of comma separated patterns. A pattern may
  *                 begin by `!` to negate it. In this case, it is
- *                 blacklisted. Each pattern will then be matched
- *                 against `fnmatch()` function.
+ *                 blacklisted. A pattern may begin with `!!`. In this
+ *                 case, it is whitelisted. Each pattern will then be
+ *                 matched against `fnmatch()` function.
  * @param found    Value to return if the pattern isn't found.
  *
  * If a pattern is found matching and blacklisted at the same time, it
- * will be blacklisted.
+ * will be blacklisted. If it is both whitelisted and blacklisted, it
+ * will be whitelisted.
  *
- * @return 0 if the string matches a blacklisted pattern or if the
- *         pattern wasn't found and `found` was set to 0. Otherwise,
- *         return 1.
+ * @return 0 if the string matches a blacklisted pattern which is not
+ *         whitelisted or if the pattern wasn't found and `found` was
+ *         set to 0. Otherwise, return 1.
  */
 int
 pattern_match(char *string, char *patterns, int found)
 {
        char *pattern;
+       int blacklisted = 0;
 
        if ((patterns = strdup(patterns)) == NULL) {
                log_warnx("interfaces", "unable to allocate memory");
@@ -50,13 +53,17 @@ pattern_match(char *string, char *patterns, int found)
        for (pattern = strtok(patterns, ",");
             pattern != NULL;
             pattern = strtok(NULL, ",")) {
-               if ((pattern[0] == '!') &&
-                   ((fnmatch(pattern + 1, string, 0) == 0))) {
-                       /* Blacklisted. No need to search further. */
-                       found = 0;
+               if ((pattern[0] == '!') && (pattern[1] == '!') &&
+                   (fnmatch(pattern + 2, string, 0) == 0)) {
+                       /* Whitelisted. No need to search further. */
+                       found = 1;
                        break;
                }
-               if (fnmatch(pattern, string, 0) == 0)
+               if ((pattern[0] == '!') &&
+                   (fnmatch(pattern + 1, string, 0) == 0)) {
+                       blacklisted = 1;
+                       found = 0;
+               } else if (!blacklisted && fnmatch(pattern, string, 0) == 0)
                        found = 1;
        }
 
index 58e63a3371d31905792d02efd4e1805bc9d610b8..939b1f99989b9fc39e680a855bb7ae9b9033e554 100644 (file)
@@ -86,6 +86,24 @@ START_TEST(test_blacklist_wildcard) {
 }
 END_TEST
 
+START_TEST(test_whitelist) {
+       ck_assert_int_eq(pattern_match("eth0", "!!eth0", 0), 1);
+       ck_assert_int_eq(pattern_match("eth0", "!!eth0", 1), 1);
+       ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 0), 1);
+       ck_assert_int_eq(pattern_match("eth0", "!eth*,!!eth0", 1), 1);
+       ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 0), 0);
+       ck_assert_int_eq(pattern_match("eth1", "!eth*,!!eth0", 1), 0);
+       ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 0), 1);
+       ck_assert_int_eq(pattern_match("vlan0", "*,!eth*,!!eth0", 1), 1);
+       ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 0), 1);
+       ck_assert_int_eq(pattern_match("eth0", "*,!eth*,!!eth0", 1), 1);
+       ck_assert_int_eq(pattern_match("eth1", "*,!eth*,!!eth0", 0), 0);
+       ck_assert_int_eq(pattern_match("eth1", "*,!!eth0,!eth*", 1), 0);
+       ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 0), 1);
+       ck_assert_int_eq(pattern_match("eth0", "*,!!eth0,!eth*", 1), 1);
+}
+END_TEST
+
 Suite *
 pattern_suite(void)
 {
@@ -100,6 +118,7 @@ pattern_suite(void)
        tcase_add_test(tc_pattern, test_simple_blacklist);
        tcase_add_test(tc_pattern, test_match_and_blacklist);
        tcase_add_test(tc_pattern, test_blacklist_wildcard);
+       tcase_add_test(tc_pattern, test_whitelist);
        suite_add_tcase(s, tc_pattern);
 
        return s;