From a5da286a96eeddee654861fd1da18735d26b9bf7 Mon Sep 17 00:00:00 2001 From: Brendan O'Dea Date: Thu, 18 Nov 2004 09:02:29 +0000 Subject: [PATCH] don't route Framed-IP-Address if contained in a Framed-Route --- Changes | 1 + l2tpns.c | 108 ++++++++++++++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Changes b/Changes index 22d302e..6ff4fec 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,6 @@ * Wed Nov 17 2004 Brendan O'Dea 2.0.8 - Ignore gateway address in Framed-Route (from Jonathan McDowell). +- Don't route Framed-IP-Address if contained in a Framed-Route. - Call sessionshutdown() when a tunnel is dropped rather than sessionkill() to ensure that RADIUS stop records are sent. - Cleanup: make a bunch of global functions/variables static. diff --git a/l2tpns.c b/l2tpns.c index 1ecbc5c..b7945f6 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -4,7 +4,7 @@ // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced // vim: sw=8 ts=8 -char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.53 2004-11-18 06:41:03 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.54 2004-11-18 09:02:29 bodea Exp $"; #include #include @@ -1052,15 +1052,20 @@ void sessionshutdown(sessionidt s, char *reason) if (session[s].ip) { // IP allocated, clear and unroute int r; + int routed = 0; for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) { + if ((session[s].ip & session[s].route[r].mask) == + (session[s].route[r].ip & session[s].route[r].mask)) + routed++; + routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 0); session[s].route[r].ip = 0; } if (session[s].ip_pool_index == -1) // static ip { - routeset(s, session[s].ip, 0, 0, 0); // Delete route. + if (!routed) routeset(s, session[s].ip, 0, 0, 0); session[s].ip = 0; } else @@ -3576,18 +3581,30 @@ int sessionsetup(tunnelidt t, sessionidt s) } } + { + int routed = 0; + // Add the route for this session. - // - // Static IPs need to be routed. Anything else - // is part of the IP address pool and is already routed, - // it just needs to be added to the IP cache. - if (session[s].ip_pool_index == -1) // static ip - routeset(s, session[s].ip, 0, 0, 1); - else - cache_ipmap(session[s].ip, s); + for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) + { + if ((session[s].ip & session[s].route[r].mask) == + (session[s].route[r].ip & session[s].route[r].mask)) + routed++; - for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) - routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 1); + routeset(s, session[s].route[r].ip, session[s].route[r].mask, 0, 1); + } + + // Static IPs need to be routed if not already + // convered by a Framed-Route. Anything else is part + // of the IP address pool and is already routed, it + // just needs to be added to the IP cache. + if (session[s].ip_pool_index == -1) // static ip + { + if (!routed) routeset(s, session[s].ip, 0, 0, 1); + } + else + cache_ipmap(session[s].ip, s); + } if (!session[s].unique_id) { @@ -3631,6 +3648,7 @@ int sessionsetup(tunnelidt t, sessionidt s) int load_session(sessionidt s, sessiont *new) { int i; + int newip = 0; // Sanity checks. if (new->ip_pool_index >= MAXIPPOOL || @@ -3648,48 +3666,66 @@ int load_session(sessionidt s, sessiont *new) session[s].tunnel = new->tunnel; // For logging in cache_ipmap + // See if routes/ip cache need updating + if (new->ip != session[s].ip) + newip++; + + for (i = 0; !newip && i < MAXROUTE && (session[s].route[i].ip || new->route[i].ip); i++) + if (new->route[i].ip != session[s].route[i].ip || + new->route[i].mask != session[s].route[i].mask) + newip++; - if (new->ip != session[s].ip) // Changed ip. fix up hash tables. + // needs update + if (newip) { - if (session[s].ip) // If there's an old one, remove it. + int routed = 0; + + // remove old routes... + for (i = 0; i < MAXROUTE && session[s].route[i].ip; i++) { - // Remove any routes if the IP has changed - for (i = 0; i < MAXROUTE && session[s].route[i].ip; i++) - { - routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0); - session[s].route[i].ip = 0; - } + if ((session[s].ip & session[s].route[i].mask) == + (session[s].route[i].ip & session[s].route[i].mask)) + routed++; + + routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0); + } + // ...ip + if (session[s].ip) + { if (session[s].ip_pool_index == -1) // static IP - routeset(s, session[s].ip, 0, 0, 0); + { + if (!routed) routeset(s, session[s].ip, 0, 0, 0); + } else // It's part of the IP pool, remove it manually. uncache_ipmap(session[s].ip); } + routed = 0; + + // add new routes... + for (i = 0; i < MAXROUTE && new->route[i].ip; i++) + { + if ((new->ip & new->route[i].mask) == + (new->route[i].ip & new->route[i].mask)) + routed++; + + routeset(s, new->route[i].ip, new->route[i].mask, 0, 1); + } + + // ...ip if (new->ip) { // If there's a new one, add it. if (new->ip_pool_index == -1) - routeset(s, new->ip, 0, 0, 1); + { + if (!routed) routeset(s, new->ip, 0, 0, 1); + } else cache_ipmap(new->ip, s); } } - // Update routed networks - for (i = 0; i < MAXROUTE && (session[s].route[i].ip || new->route[i].ip); i++) - { - if (new->route[i].ip == session[s].route[i].ip && - new->route[i].mask == session[s].route[i].mask) - continue; - - if (session[s].route[i].ip) // Remove the old one if it exists. - routeset(s, session[s].route[i].ip, session[s].route[i].mask, 0, 0); - - if (new->route[i].ip) // Add the new one if it exists. - routeset(s, new->route[i].ip, new->route[i].mask, 0, 1); - } - if (new->tunnel && s > config->cluster_highest_sessionid) // Maintain this in the slave. It's used // for walking the sessions to forward byte counts to the master. config->cluster_highest_sessionid = s; -- 2.20.1