[Openvpn-devel,v2] do not push route-ipv6 entries that are also in the iroute-ipv6 list

Message ID 20220628082024.19059-1-a@unstable.cc
State New
Headers show
Series
  • [Openvpn-devel,v2] do not push route-ipv6 entries that are also in the iroute-ipv6 list
Related show

Commit Message

Antonio Quartulli June 28, 2022, 8:20 a.m.
A server should push a route to a client only if there is no matching
iroute for the same client.

While this logic works fine for IPv4, there is no IPv6 counterpart.

Implement the same check for IPv6 routes and discard matching ones
from the push list.

Trac: #354
Cc: Gert Doering <gert@greenie.muc.de>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---

Changes from v1:
* add "&& o->iroutes{,_ipv6}" check before attempting to traverse
  iroutes list. This way we avoid executing getaddr or get_ipv6_addr if
  we already know that we have no iroutes to compare to.


 src/openvpn/push.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

Comments

Heiko Hund June 28, 2022, 12:36 p.m. | #1
On Dienstag, 28. Juni 2022 10:20:24 CEST Antonio Quartulli wrote:
> A server should push a route to a client only if there is no matching
> iroute for the same client.
> 
> While this logic works fine for IPv4, there is no IPv6 counterpart.
> 
> Implement the same check for IPv6 routes and discard matching ones
> from the push list.
> 
> Trac: #354
> Cc: Gert Doering <gert@greenie.muc.de>
> Signed-off-by: Antonio Quartulli <a@unstable.cc>

ACK

Patch

diff --git a/src/openvpn/push.c b/src/openvpn/push.c
index 63257348..e5b588bb 100644
--- a/src/openvpn/push.c
+++ b/src/openvpn/push.c
@@ -1002,7 +1002,7 @@  process_incoming_push_msg(struct context *c,
 void
 remove_iroutes_from_push_route_list(struct options *o)
 {
-    if (o && o->push_list.head && o->iroutes)
+    if (o && o->push_list.head && (o->iroutes || o->iroutes_ipv6))
     {
         struct gc_arena gc = gc_new();
         struct push_entry *e = o->push_list.head;
@@ -1019,7 +1019,7 @@  remove_iroutes_from_push_route_list(struct options *o)
                 && parse_line(e->option, p, SIZE(p), "[PUSH_ROUTE_REMOVE]", 1, D_ROUTE_DEBUG, &gc))
             {
                 /* is the push item a route directive? */
-                if (p[0] && !strcmp(p[0], "route") && !p[3])
+                if (p[0] && !strcmp(p[0], "route") && !p[3] && o->iroutes)
                 {
                     /* get route parameters */
                     bool status1, status2;
@@ -1042,6 +1042,30 @@  remove_iroutes_from_push_route_list(struct options *o)
                         }
                     }
                 }
+                else if (p[0] && !strcmp(p[0], "route-ipv6") && !p[2]
+                         && o->iroutes_ipv6)
+                {
+                    /* get route parameters */
+                    struct in6_addr network;
+                    unsigned int netbits;
+
+                    /* parse route-ipv6 arguments */
+                    if (get_ipv6_addr(p[1], &network, &netbits, D_ROUTE_DEBUG))
+                    {
+                        struct iroute_ipv6 *ir;
+
+                        /* does this route-ipv6 match an iroute-ipv6? */
+                        for (ir = o->iroutes_ipv6; ir != NULL; ir = ir->next)
+                        {
+                            if (!memcmp(&network, &ir->network, sizeof(network))
+                                && netbits == ir->netbits)
+                            {
+                                enable = false;
+                                break;
+                            }
+                        }
+                    }
+                }
 
                 /* should we copy the push item? */
                 e->enable = enable;