diff --git a/l2tpns.c b/l2tpns.c index 3e6d846..eb18f4f 100644 --- a/l2tpns.c +++ b/l2tpns.c @@ -263,6 +263,7 @@ static int netlink_handle_ack(struct nlmsghdr *nh, int gen, int min_initok_nlseq static void rtnetlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen); static void genetlink_addattr(struct nlmsghdr *nh, int type, const void *data, int alen); static int genetlink_getattr(struct nlmsghdr *nh, int type, void *data, int alen); +static void routesset(sessionidt s, sessiont *sp, int add); static void cache_ipmap(in_addr_t ip, sessionidt s); static void uncache_ipmap(in_addr_t ip); static void cache_ipv6map(struct in6_addr ip, int prefixlen, sessionidt s); @@ -1115,6 +1116,51 @@ static void routeset(sessionidt s, in_addr_t ip, int prefixlen, in_addr_t gw, in } } +// +// Add or remove the routes for a session +static void routesset(sessionidt s, sessiont *sp, int add) +{ + int r; + int routed = 0; + + // add/remove routes... + for (r = 0; r < MAXROUTE && sp->route[r].ip; r++) + { + if ((sp->ip >> (32-sp->route[r].prefixlen)) == + (sp->route[r].ip >> (32-sp->route[r].prefixlen))) + routed++; + + routeset(s, sp->route[r].ip, sp->route[r].prefixlen, 0, add); + } + + // ...ip + if (sp->ip) + { + // 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. + // IPv6 route setup is done in ppp.c, when IPV6CP is acked. + if (sp->ip_pool_index == -1) // static ip + { + if (!routed) routeset(s, sp->ip, 0, 0, add); + } + else // It's part of the IP pool, add/remove it manually. + { + if (add) + cache_ipmap(sp->ip, s); + else + uncache_ipmap(sp->ip); + } + } +} + +// Add an IPv6 route +// +// This adds it to the routing table, advertises it +// via BGP if enabled, and stuffs it into the +// 'sessionbyip' cache. +// void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add) { struct { @@ -1184,6 +1230,25 @@ void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add) return; } +// +// Add or remove the IPv6 routes for a session +void routes6set(sessionidt s, sessiont *sp, int add) +{ + int r; + + for (r = 0; r < MAXROUTE6 && sp->route6[r].ipv6prefixlen; r++) + { + route6set(s, sp->route6[r].ipv6route, sp->route6[r].ipv6prefixlen, add); + } + + if (sp->ipv6address.s6_addr[0]) + { + // Check if included in prefix + if (!add || sessionbyipv6(sp->ipv6address) != s) + route6set(s, sp->ipv6address, 128, add); + } +} + // // Get L2TP netlink id static int16_t netlink_get_l2tp_id(void) @@ -3001,38 +3066,27 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e 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 >> (32-session[s].route[r].prefixlen)) == - (session[s].route[r].ip >> (32-session[s].route[r].prefixlen))) - routed++; + if (del_routes) + routesset(s, &session[s], 0); - if (del_routes) routeset(s, session[s].route[r].ip, session[s].route[r].prefixlen, 0, 0); + int r; + for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) session[s].route[r].ip = 0; - } if (session[s].ip_pool_index == -1) // static ip - { - if (!routed && del_routes) routeset(s, session[s].ip, 0, 0, 0); session[s].ip = 0; - } else free_ip_address(s); + if (del_routes) + routes6set(s, &session[s], 0); + // unroute IPv6, if setup for (r = 0; r < MAXROUTE6 && session[s].route6[r].ipv6route.s6_addr[0] && session[s].route6[r].ipv6prefixlen; r++) { - if (del_routes) route6set(s, session[s].route6[r].ipv6route, session[s].route6[r].ipv6prefixlen, 0); memset(&session[s].route6[r], 0, sizeof(session[s].route6[r])); } - if (session[s].ipv6address.s6_addr[0] && del_routes) - { - route6set(s, session[s].ipv6address, 128, 0); - } - if (b) { // This session was part of a bundle @@ -3067,7 +3121,6 @@ void sessionshutdown(sessionidt s, char const *reason, int cdn_result, int cdn_e { sessionidt new_s = bundle[b].members[0]; - routed = 0; // Add the route for this session. for (r = 0; r < MAXROUTE && session[new_s].route[r].ip; r++) { @@ -6602,7 +6655,6 @@ int sessionsetup(sessionidt s, tunnelidt t) in_addr_t ip; char *user; sessionidt i; - int r; CSTAT(sessionsetup); @@ -6680,31 +6732,8 @@ int sessionsetup(sessionidt s, tunnelidt t) // no need to set a route for the same IP address of the bundle if (!session[s].bundle || (bundle[session[s].bundle].num_of_links == 1)) - { - int routed = 0; - // Add the route for this session. - for (r = 0; r < MAXROUTE && session[s].route[r].ip; r++) - { - if ((session[s].ip >> (32-session[s].route[r].prefixlen)) == - (session[s].route[r].ip >> (32-session[s].route[r].prefixlen))) - routed++; - - routeset(s, session[s].route[r].ip, session[s].route[r].prefixlen, 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. - // IPv6 route setup is done in ppp.c, when IPV6CP is acked. - 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); - } + routesset(s, &session[s], 1); sess_local[s].lcp_authtype = 0; // RADIUS authentication complete lcp_open(s, t); // transition to Network phase and send initial IPCP @@ -6767,80 +6796,19 @@ int load_session(sessionidt s, sessiont *new) // needs update if (newip) { - int routed = 0; - // remove old routes... - for (i = 0; i < MAXROUTE && session[s].route[i].ip; i++) - { - if ((session[s].ip >> (32-session[s].route[i].prefixlen)) == - (session[s].route[i].ip >> (32-session[s].route[i].prefixlen))) - routed++; - - routeset(s, session[s].route[i].ip, session[s].route[i].prefixlen, 0, 0); - } - - // ...ip - if (session[s].ip) - { - if (session[s].ip_pool_index == -1) // static IP - { - 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); - } + routesset(s, &session[s], 0); // remove old IPV6 routes... - for (i = 0; i < MAXROUTE6 && session[s].route6[i].ipv6route.s6_addr[0] && session[s].route6[i].ipv6prefixlen; i++) - { - route6set(s, session[s].route6[i].ipv6route, session[s].route6[i].ipv6prefixlen, 0); - } - - if (session[s].ipv6address.s6_addr[0]) - { - route6set(s, session[s].ipv6address, 128, 0); - } - - routed = 0; + routes6set(s, &session[s], 0); // add new routes... - for (i = 0; i < MAXROUTE && new->route[i].ip; i++) - { - if ((new->ip >> (32-new->route[i].prefixlen)) == - (new->route[i].ip >> (32-new->route[i].prefixlen))) - routed++; - - routeset(s, new->route[i].ip, new->route[i].prefixlen, 0, 1); - } - - // ...ip - if (new->ip) - { - // If there's a new one, add it. - if (new->ip_pool_index == -1) - { - if (!routed) routeset(s, new->ip, 0, 0, 1); - } - else - cache_ipmap(new->ip, s); - } + routesset(s, new, 1); } // check v6 routing if (new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened) - { - for (i = 0; i < MAXROUTE6 && new->route6[i].ipv6prefixlen; i++) - { - route6set(s, new->route6[i].ipv6route, new->route6[i].ipv6prefixlen, 1); - } - } - - if (new->ipv6address.s6_addr[0] && new->ppp.ipv6cp == Opened && session[s].ppp.ipv6cp != Opened) - { - // Check if included in prefix - if (sessionbyipv6(new->ipv6address) != s) - route6set(s, new->ipv6address, 128, 1); - } + routes6set(s, new, 1); // check filters if (new->filter_in && (new->filter_in > MAXFILTER || !ip_filters[new->filter_in - 1].name[0])) diff --git a/l2tpns.h b/l2tpns.h index c28eccc..9220b9e 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -962,6 +962,7 @@ int rad_tunnel_pwdecode(uint8_t *pl2tpsecret, size_t *pl2tpsecretlen, const char clockt backoff(uint8_t try); void send_ipv6_ra(sessionidt s, tunnelidt t, struct in6_addr *ip); void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add); +void routes6set(sessionidt s, sessiont *sp, int add); sessionidt sessionbyip(in_addr_t ip); sessionidt sessionbyipv6(struct in6_addr ip); sessionidt sessionbyipv6new(struct in6_addr ip); diff --git a/ppp.c b/ppp.c index 36645e0..43c4213 100644 --- a/ppp.c +++ b/ppp.c @@ -1479,21 +1479,10 @@ void processipcp(sessionidt s, tunnelidt t, uint8_t *p, uint16_t l) static void ipv6cp_open(sessionidt s, tunnelidt t) { - int i; LOG(3, s, t, "IPV6CP: Opened\n"); change_state(s, ipv6cp, Opened); - for (i = 0; i < MAXROUTE6 && session[s].route6[i].ipv6prefixlen; i++) - { - route6set(s, session[s].route6[i].ipv6route, session[s].route6[i].ipv6prefixlen, 1); - } - - if (session[s].ipv6address.s6_addr[0]) - { - // Check if included in prefix - if (sessionbyipv6(session[s].ipv6address) != s) - route6set(s, session[s].ipv6address, 128, 1); - } + routes6set(s, &session[s], 1); // Send an initial RA send_ipv6_ra(s, t, NULL);