]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Allow learning iroutes with network made up of all 0s (only if netbits < 8)
authorAntonio Quartulli <a@unstable.cc>
Wed, 6 Dec 2017 15:43:56 +0000 (23:43 +0800)
committerDavid Sommerseth <davids@openvpn.net>
Wed, 6 Dec 2017 21:26:00 +0000 (22:26 +0100)
It is plausible for a user to be willing to add a route for a network
made up of all 0s via a VPN client (i.e. 0.0.0.0/1), therefore such
iroute should be supported.

As of now the option parsing code will accept such iroute, but
the learning routine will (silently) reject it after a sanity check.

Such check prevents routes with network made up of all 0s to be
learnt at all..

Change the sanity check so that it will reject iroutes to network
made up of 0s only when netbits is greater than 7.

The reason for choosing 7 is because anything within 0.0.0.0/8 is not
really routable among networks.

While at it, make the sanity check louder so that it can print the
reason why a route is being rejected.

Trac: #726
Signed-off-by: Antonio Quartulli <a@unstable.cc>
Acked-by: David Sommerseth <davids@openvpn.net>
Message-Id: <20171206154356.30764-1-a@unstable.cc>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg16044.html
Signed-off-by: David Sommerseth <davids@openvpn.net>
(cherry picked from commit a19c56db9bd42b7b8c4a8f353f7db92781397cec)

src/openvpn/mroute.c
src/openvpn/mroute.h
src/openvpn/multi.c

index 74ee360c1be4c955606c6d6e3ca849fb10d5c38a..bf174ad461e52ff68c6720c567b19e42ab28c975 100644 (file)
@@ -65,25 +65,49 @@ is_mac_mcast_maddr(const struct mroute_addr *addr)
  * Don't learn certain addresses.
  */
 bool
-mroute_learnable_address(const struct mroute_addr *addr)
+mroute_learnable_address(const struct mroute_addr *addr, struct gc_arena *gc)
 {
     int i;
-    bool not_all_zeros = false;
-    bool not_all_ones = false;
+    bool all_zeros = true;
+    bool all_ones = true;
 
     for (i = 0; i < addr->len; ++i)
     {
         int b = addr->raw_addr[i];
         if (b != 0x00)
         {
-            not_all_zeros = true;
+            all_zeros = false;
         }
         if (b != 0xFF)
         {
-            not_all_ones = true;
+            all_ones = false;
         }
     }
-    return not_all_zeros && not_all_ones && !is_mac_mcast_maddr(addr);
+
+    /* only networkss shorter than 8 bits are allowed to be all 0s. */
+    if (all_zeros
+        && !((addr->type & MR_WITH_NETBITS) && (addr->netbits < 8)))
+    {
+        msg(D_MULTI_LOW, "Can't learn %s: network is all 0s, but netbits >= 8",
+            mroute_addr_print(addr, gc));
+        return false;
+    }
+
+    if (all_ones)
+    {
+        msg(D_MULTI_LOW, "Can't learn %s: network is all 1s",
+            mroute_addr_print(addr, gc));
+        return false;
+    }
+
+    if (is_mac_mcast_maddr(addr))
+    {
+        msg(D_MULTI_LOW, "Can't learn %s: network is a multicast address",
+            mroute_addr_print(addr, gc));
+        return false;
+    }
+
+    return true;
 }
 
 static inline void
index 35361fbd5064e21c16ef40d2054ff5d4d3c46cc8..6a85b0e2027f1b7eb98f8bee582ef5dcd299ec4a 100644 (file)
@@ -141,7 +141,8 @@ bool mroute_extract_openvpn_sockaddr(struct mroute_addr *addr,
                                      const struct openvpn_sockaddr *osaddr,
                                      bool use_port);
 
-bool mroute_learnable_address(const struct mroute_addr *addr);
+bool mroute_learnable_address(const struct mroute_addr *addr,
+                              struct gc_arena *gc);
 
 uint32_t mroute_addr_hash_function(const void *key, uint32_t iv);
 
index c798c438519fc43b1be335603139bf3832824a7b..9136f50741598deb2b875aeaa582a39b7adac3fa 100644 (file)
@@ -1077,6 +1077,7 @@ multi_learn_addr(struct multi_context *m,
     struct hash_bucket *bucket = hash_bucket(m->vhash, hv);
     struct multi_route *oldroute = NULL;
     struct multi_instance *owner = NULL;
+    struct gc_arena gc = gc_new();
 
     /* if route currently exists, get the instance which owns it */
     he = hash_lookup_fast(m->vhash, bucket, addr, hv);
@@ -1090,11 +1091,9 @@ multi_learn_addr(struct multi_context *m,
     }
 
     /* do we need to add address to hash table? */
-    if ((!owner || owner != mi)
-        && mroute_learnable_address(addr)
+    if ((!owner || owner != mi) && mroute_learnable_address(addr, &gc)
         && !mroute_addr_equal(addr, &m->local))
     {
-        struct gc_arena gc = gc_new();
         struct multi_route *newroute;
         bool learn_succeeded = false;
 
@@ -1151,9 +1150,8 @@ multi_learn_addr(struct multi_context *m,
         {
             free(newroute);
         }
-
-        gc_free(&gc);
     }
+    gc_free(&gc);
 
     return owner;
 }