From: fendo Date: Sun, 14 Sep 2014 17:00:57 +0000 (+0200) Subject: Merge from Master X-Git-Tag: 2.2.1-2sames3.14 X-Git-Url: http://git.sameswireless.fr/l2tpns.git/commitdiff_plain/ba1c3362c6dc0d65eb3d06368c47b75aa135456b Merge from Master --- ba1c3362c6dc0d65eb3d06368c47b75aa135456b diff --cc Makefile index 7280139,36789e3..abab4e0 --- a/Makefile +++ b/Makefile @@@ -26,7 -26,7 +26,7 @@@ INSTALL = install -c -D -o root -g roo l2tpns.LIBS = -lcli -ldl OBJS = arp.o cli.o cluster.o constants.o control.o icmp.o l2tpns.o \ - ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o l2tplac.o grpsess.o - ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o l2tplac.o dhcp6.o ipv6_u.o ++ ll.o md5.o ppp.o radius.o tbf.o util.o pppoe.o l2tplac.o grpsess.o dhcp6.o ipv6_u.o PROGRAMS = l2tpns nsctl PLUGINS = autosnoop.so autothrottle.so garden.so sessionctl.so \ @@@ -108,32 -108,35 +108,36 @@@ install: al .PHONY: all clean depend install ## Dependencies: (autogenerated) ## - arp.o: arp.c l2tpns.h - cli.o: cli.c l2tpns.h constants.h util.h cluster.h tbf.h ll.h bgp.h \ - l2tplac.h - cluster.o: cluster.c l2tpns.h cluster.h util.h tbf.h pppoe.h bgp.h + arp.o: arp.c dhcp6.h l2tpns.h + cli.o: cli.c dhcp6.h l2tpns.h constants.h util.h cluster.h tbf.h ll.h \ + bgp.h l2tplac.h + cluster.o: cluster.c dhcp6.h l2tpns.h cluster.h util.h tbf.h pppoe.h \ + bgp.h constants.o: constants.c constants.h - control.o: control.c l2tpns.h control.h - icmp.o: icmp.c l2tpns.h pppoe.h - l2tpns.o: l2tpns.c md5.h l2tpns.h cluster.h plugin.h ll.h constants.h \ - control.h util.h tbf.h bgp.h l2tplac.h pppoe.h + control.o: control.c dhcp6.h l2tpns.h control.h + icmp.o: icmp.c dhcp6.h l2tpns.h ipv6_u.h + l2tpns.o: l2tpns.c md5.h dhcp6.h l2tpns.h cluster.h plugin.h ll.h \ + constants.h control.h util.h tbf.h bgp.h l2tplac.h pppoe.h ll.o: ll.c ll.h md5.o: md5.c md5.h - ppp.o: ppp.c l2tpns.h constants.h plugin.h util.h tbf.h cluster.h \ + ppp.o: ppp.c dhcp6.h l2tpns.h constants.h plugin.h util.h tbf.h cluster.h \ l2tplac.h pppoe.h - radius.o: radius.c md5.h constants.h l2tpns.h plugin.h util.h cluster.h \ - l2tplac.h pppoe.h - tbf.o: tbf.c l2tpns.h util.h tbf.h - util.o: util.c l2tpns.h bgp.h - pppoe.o: pppoe.c l2tpns.h cluster.h constants.h md5.h util.h - l2tplac.o: l2tplac.c md5.h l2tpns.h util.h cluster.h l2tplac.h pppoe.h + radius.o: radius.c md5.h constants.h dhcp6.h l2tpns.h plugin.h util.h \ + cluster.h l2tplac.h pppoe.h + tbf.o: tbf.c dhcp6.h l2tpns.h util.h tbf.h + util.o: util.c dhcp6.h l2tpns.h bgp.h + pppoe.o: pppoe.c dhcp6.h l2tpns.h cluster.h constants.h md5.h util.h + l2tplac.o: l2tplac.c md5.h dhcp6.h l2tpns.h util.h cluster.h l2tplac.h \ + pppoe.h +grpsess.o: grpsess.c l2tpns.h util.h cluster.h bgp.h - bgp.o: bgp.c l2tpns.h bgp.h util.h - autosnoop.so: autosnoop.c l2tpns.h plugin.h - autothrottle.so: autothrottle.c l2tpns.h plugin.h - garden.so: garden.c l2tpns.h plugin.h control.h - sessionctl.so: sessionctl.c l2tpns.h plugin.h control.h - setrxspeed.so: setrxspeed.c l2tpns.h plugin.h - snoopctl.so: snoopctl.c l2tpns.h plugin.h control.h - stripdomain.so: stripdomain.c l2tpns.h plugin.h - throttlectl.so: throttlectl.c l2tpns.h plugin.h control.h + dhcp6.o: dhcp6.c dhcp6.h l2tpns.h ipv6_u.h + ipv6_u.o: ipv6_u.c ipv6_u.h + bgp.o: bgp.c dhcp6.h l2tpns.h bgp.h util.h + autosnoop.so: autosnoop.c dhcp6.h l2tpns.h plugin.h + autothrottle.so: autothrottle.c dhcp6.h l2tpns.h plugin.h + garden.so: garden.c dhcp6.h l2tpns.h plugin.h control.h + sessionctl.so: sessionctl.c dhcp6.h l2tpns.h plugin.h control.h + setrxspeed.so: setrxspeed.c dhcp6.h l2tpns.h plugin.h + snoopctl.so: snoopctl.c dhcp6.h l2tpns.h plugin.h control.h + stripdomain.so: stripdomain.c dhcp6.h l2tpns.h plugin.h + throttlectl.so: throttlectl.c dhcp6.h l2tpns.h plugin.h control.h diff --cc arp.c index e9c7584,0aae069..111f973 --- a/arp.c +++ b/arp.c @@@ -5,9 -5,9 +5,10 @@@ #include #include #include - #include +#include + #include + #include "dhcp6.h" #include "l2tpns.h" /* Most of this code is based on keepalived:vrrp_arp.c */ diff --cc autosnoop.c index 5633824,c520aaf..ed91a88 --- a/autosnoop.c +++ b/autosnoop.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + #include "dhcp6.h" + #include "l2tpns.h" #include "plugin.h" diff --cc autothrottle.c index 007f926,9d55456..25dd647 --- a/autothrottle.c +++ b/autothrottle.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + #include "dhcp6.h" + #include "l2tpns.h" #include "plugin.h" diff --cc bgp.c index 36894be,2791ca3..c44f05d --- a/bgp.c +++ b/bgp.c @@@ -20,8 -20,8 +20,9 @@@ #include #include #include +#include + #include "dhcp6.h" #include "l2tpns.h" #include "bgp.h" #include "util.h" diff --cc cli.c index 876ad06,e63d73e..fee9319 --- a/cli.c +++ b/cli.c @@@ -21,8 -21,8 +21,9 @@@ #include #include #include +#include + #include "dhcp6.h" #include "l2tpns.h" #include "constants.h" #include "util.h" diff --cc cluster.c index 7768bf2,5d2b5b8..8e604db --- a/cluster.c +++ b/cluster.c @@@ -16,8 -16,8 +16,9 @@@ #include #include #include +#include + #include "dhcp6.h" #include "l2tpns.h" #include "cluster.h" #include "util.h" diff --cc cluster.h index b1aebaf,b7a91f1..290c589 --- a/cluster.h +++ b/cluster.h @@@ -25,11 -25,8 +25,11 @@@ #define C_CBUNDLE 18 // Compressed bundle structure. #define C_MPPP_FORWARD 19 // MPPP Forwarded packet.. #define C_PPPOE_FORWARD 20 // PPPOE Forwarded packet.. +#define C_GROUPE 21 // Groupe structure. +#define C_CGROUPE 22 // Compressed groupe structure. + - #define HB_VERSION 7 // Protocol version number.. + #define HB_VERSION 8 // Protocol version number.. #define HB_MAX_SEQ (1<<30) // Maximum sequence number. (MUST BE A POWER OF 2!) #define HB_HISTORY_SIZE 64 // How many old heartbeats we remember?? (Must be a factor of HB_MAX_SEQ) diff --cc control.c index 092ab8e,1ccd07a..8aeb48c --- a/control.c +++ b/control.c @@@ -1,9 -1,8 +1,10 @@@ // L2TPNS: control #include - #include +#include + #include + #include "dhcp6.h" + #include "l2tpns.h" #include "control.h" diff --cc debian/changelog index 61a117a,6b7ff2e..1c96e14 --- a/debian/changelog +++ b/debian/changelog @@@ -1,4 -1,23 +1,13 @@@ -l2tpns (2.2.1-2fdn3.14) unstable; urgency=low ++l2tpns (2.2.1-2sames3.14) unstable; urgency=low + + * Fix cluster slave; reset to 0, the end of the session when the master version < slave version. + * Fix cluster slave; no add the ipv6 route address (/128) if included in the delegated prefix. - - -- Fernando Alves Fri, 12 Sep 2014 18:21:53 +0200 - -l2tpns (2.2.1-2fdn3.13) unstable; urgency=low - + * Add DHCPv6 functionality - - -- Fernando Alves Thu, 11 Sep 2014 16:10:38 +0200 - -l2tpns (2.2.1-2fdn3.12) unstable; urgency=low - + * Fix: remove old IPV6 routes on master + - -- Fernando Alves Tue, 10 Dec 2013 23:13:20 +0100 ++ -- Fernando Alves Sun, 14 Sep 2014 18:27:09 +0200 + -l2tpns (2.2.1-2fdn3.11) unstable; urgency=low +l2tpns (2.2.1-2sames3.12) UNRELEASED; urgency=low * Fix: throttle ipv6 out. * Fix: remove old IPV6 routes on slave diff --cc garden.c index 863114e,0e6880c..da4a7d6 --- a/garden.c +++ b/garden.c @@@ -3,9 -3,8 +3,10 @@@ #include #include #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" #include "control.h" diff --cc grpsess.c index d3fae30,0000000..5528453 mode 100644,000000..100644 --- a/grpsess.c +++ b/grpsess.c @@@ -1,709 -1,0 +1,711 @@@ +/* + * Fernando ALVES 2013 + * Grouped session for load balancing and fail-over + * GPL licenced + */ + +#include +#include +#include +#include +#include ++#include + ++#include "dhcp6.h" +#include "l2tpns.h" +#include "util.h" +#include "cluster.h" + +#ifdef BGP +#include "bgp.h" +#endif + +union grp_iphash { + groupidt grp; + union grp_iphash *idx; +} grp_ip_hash[256]; // Mapping from IP address to group structures. + +groupidt gnextgrpid = 0; + +typedef struct +{ + sessionidt sid_loaddist[0x10000]; +} +local_group; + +local_group *grp_local = NULL; // Array of local_group structures. + +// Find gruop by IP, < 1 for not found +// +// Confusingly enough, this 'ip' must be +// in _network_ order. This being the common +// case when looking it up from IP packet headers. +static groupidt grp_lookup_ipmap(in_addr_t ip) +{ + uint8_t *a = (uint8_t *) &ip; + union grp_iphash *h = grp_ip_hash; + + if (!(h = h[*a++].idx)) return 0; + if (!(h = h[*a++].idx)) return 0; + if (!(h = h[*a++].idx)) return 0; + + return h[*a].grp; +} + +// +// Take an IP address in HOST byte order and +// add it to the grouid by IP cache. +// +// (It's actually cached in network order) +// +static void grp_cache_ipmap(in_addr_t ip, groupidt g) +{ + in_addr_t nip = htonl(ip); // MUST be in network order. I.e. MSB must in be ((char *) (&ip))[0] + uint8_t *a = (uint8_t *) &nip; + union grp_iphash *h = grp_ip_hash; + int i; + + for (i = 0; i < 3; i++) + { + if (!(h[a[i]].idx || (h[a[i]].idx = calloc(256, sizeof(union grp_iphash))))) + return; + + h = h[a[i]].idx; + } + + h[a[3]].grp = g; + + if (g > 0) + LOG(4, 0, 0, "Caching Group:%d ip address %s\n", g, fmtaddr(nip, 0)); + else if (g == 0) + LOG(4, 0, 0, "Un-caching Group ip address %s\n", fmtaddr(nip, 0)); +} + +groupidt grp_groupbyip(in_addr_t ip) +{ + groupidt g = grp_lookup_ipmap(ip); + + if (g > 0 && g < MAXGROUPE) + return g; + + return 0; +} + +// Add a route +// +// This adds it to the routing table, advertises it +// via BGP if enabled, and stuffs it into the +// 'groupbyip' cache. +// +// 'ip' must be in _host_ order. +// +static void grp_routeset(groupidt g, in_addr_t ip, int prefixlen, int add) +{ + struct { + struct nlmsghdr nh; + struct rtmsg rt; + char buf[32]; + } req; + int i; + in_addr_t n_ip; + + if (!prefixlen) prefixlen = 32; + + ip &= 0xffffffff << (32 - prefixlen);; // Force the ip to be the first one in the route. + + memset(&req, 0, sizeof(req)); + + if (add) + { + req.nh.nlmsg_type = RTM_NEWROUTE; + req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE; + } + else + { + req.nh.nlmsg_type = RTM_DELROUTE; + req.nh.nlmsg_flags = NLM_F_REQUEST; + } + + req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.rt)); + + req.rt.rtm_family = AF_INET; + req.rt.rtm_dst_len = prefixlen; + req.rt.rtm_table = RT_TABLE_MAIN; + req.rt.rtm_protocol = 42; + req.rt.rtm_scope = RT_SCOPE_LINK; + req.rt.rtm_type = RTN_UNICAST; + + netlink_addattr(&req.nh, RTA_OIF, &tunidx, sizeof(int)); + n_ip = htonl(ip); + netlink_addattr(&req.nh, RTA_DST, &n_ip, sizeof(n_ip)); + + LOG(3, 0, 0, "Route (Group) %s %s/%d\n", add ? "add" : "del", fmtaddr(htonl(ip), 0), prefixlen); + + if (netlink_send(&req.nh) < 0) + LOG(0, 0, 0, "grp_routeset() error in sending netlink message: %s\n", strerror(errno)); + +#ifdef BGP + if (add) + bgp_add_route(htonl(ip), prefixlen); + else + bgp_del_route(htonl(ip), prefixlen); +#endif /* BGP */ + + // Add/Remove the IPs to the 'groupbyip' cache. + // Note that we add the zero address in the case of + // a network route. Roll on CIDR. + + // Note that 'g == 0' implies this is the address pool. + // We still cache it here, because it will pre-fill + // the malloc'ed tree. + if (g) + { + if (!add) // Are we deleting a route? + g = 0; // Caching the session as '0' is the same as uncaching. + + for (i = ip; i < ip+(1<<(32-prefixlen)) ; ++i) + { + grp_cache_ipmap(i, g); + if (!g) cache_ipmap(i, 0); + } + } +} + +// Set all route of a group +void grp_setgrouproute(groupidt g, int add) +{ + int i; + for (i = 0; i < grpsession[g].nbroutesgrp; i++) + { + if (grpsession[g].route[i].ip != 0) + { + grp_routeset(g, grpsession[g].route[i].ip, grpsession[g].route[i].prefixlen, add); + } + } +} + +// return group id by session +groupidt grp_groupbysession(sessionidt s) +{ + groupidt g = 0; + int i; + for (g = gnextgrpid; g != 0; g = grpsession[g].prev) + { + for (i = 0; i < grpsession[g].nbsession; i++) + { + if (grpsession[g].sesslist[i].sid == s) + { // session found in group + return g; + } + } + } + + return 0; +} + +// Remove a session to a group +// return 1 if OK +void grp_removesession(groupidt g, sessionidt s) +{ + int i; + + if (grpsession[g].nbsession <= 0) + return; + + for (i = 0; i < grpsession[g].nbsession; i++) + { + if (grpsession[g].sesslist[i].sid == s) + { // session found on group + --grpsession[g].nbsession; + if (grpsession[g].nbsession == 0) + { + // Group is empty, remove it + + // Del all routes + grp_setgrouproute(g, 0); + + if (gnextgrpid == g) + { + gnextgrpid = grpsession[g].prev; + } + else + { + groupidt g2; + for (g2 = gnextgrpid; g2 != 0; g2 = grpsession[g2].prev) + { + if (grpsession[g2].prev == g) + { + grpsession[g2].prev = grpsession[g].prev; + break; + } + } + } + + memset(&grpsession[g], 0, sizeof(grpsession[0])); + grpsession[g].state = GROUPEFREE; + } + else + { + // remove the session + memmove(&grpsession[g].sesslist[i], + &grpsession[g].sesslist[i+1], + (grpsession[g].nbsession - i) * sizeof(grpsession[g].sesslist[i])); + } + + cluster_send_groupe(g); + return; + } + } +} + +// Add a session to a group +// return 1 if OK +static int grp_addsession(groupidt g, sessionidt s, uint8_t weight) +{ + int i; + + for (i = 0; i < grpsession[g].nbsession; i++) + { + if (grpsession[g].sesslist[i].sid == s) + { // already in group + if ((!grpsession[g].sesslist[i].weight) || (weight > 1)) + grpsession[g].sesslist[i].weight = weight; // update Weight session (for load-balancing) + + return 1; + } + } + + if (i >= MAXSESSINGRP) + { + LOG(1, s, session[s].tunnel, " Too many session for Group %d\n", g); + return 0; + } + else + { // add session id to group + if (i == 0) + { + // it's the first session of the group, set to next group + grpsession[g].prev = gnextgrpid; + gnextgrpid = g; + grpsession[g].state = GROUPEOPEN; + } + grpsession[g].sesslist[i].sid = s; + grpsession[g].sesslist[i].weight = weight; + grpsession[g].nbsession++; + + return 1; + } + return 0; +} + +// Add a route to a group +// return 1 if OK +static int grp_addroute(groupidt g, sessionidt s, in_addr_t ip, int prefixlen) +{ + int i; + + for (i = 0; i < MAXROUTEINGRP; i++) + { + if ((i >= grpsession[g].nbroutesgrp)) + { + LOG(3, s, session[s].tunnel, " Radius reply Group %d contains route for %s/%d\n", + g, fmtaddr(htonl(ip), 0), prefixlen); + + grpsession[g].route[i].ip = ip; + grpsession[g].route[i].prefixlen = prefixlen; + grpsession[g].nbroutesgrp++; + return 1; + } + else if ((grpsession[g].route[i].ip == ip) && (grpsession[g].route[i].prefixlen == prefixlen)) + { + // route already defined in group + LOG(3, s, session[s].tunnel, + " Radius reply Group %d contains route for %s/%d (this already defined)\n", + g, fmtaddr(htonl(ip), 0), prefixlen); + + return 1; + } + else if (grpsession[g].route[i].ip == 0) + { + LOG(3, s, session[s].tunnel, " Radius reply Group %d contains route for %s/%d (find empty on list!!!)\n", + g, fmtaddr(htonl(ip), 0), prefixlen); + + grpsession[g].route[i].ip = ip; + grpsession[g].route[i].prefixlen = prefixlen; + return 1; + } + } + + if (i >= MAXROUTEINGRP) + { + LOG(1, s, session[s].tunnel, " Too many routes for Group %d\n", g); + } + return 0; +} + +// Process Sames vendor specific attribut radius +void grp_processvendorspecific(sessionidt s, uint8_t *pvs) +{ + uint8_t attrib = *pvs; + groupidt grpid = 0; + uint8_t *n = pvs + 2; + uint8_t *e = pvs + pvs[1]; + + if ((attrib >= 22) && (attrib <= 23)) + { + while (n < e && isdigit(*n)) + { + grpid = grpid * 10 + *n - '0'; + n++; + } + if ((grpid == 0) || (grpid >= MAXGROUPE)) + { + LOG(1, s, session[s].tunnel, " Group Attribute Id %d not allowed\n", grpid); + return; + } + else if (*n != ',') + { + LOG(1, s, session[s].tunnel, " Group Attribute Id not defined\n"); + return; + } + + if (!grp_addsession(grpid, s, 1)) + { + return; + } + + if (grpid > config->cluster_highest_groupeid) + config->cluster_highest_groupeid = grpid; + + n++; + } + + //process, Sames vendor-specific 64520 + if (attrib == 22) //SAMES-Group-Framed-Route + { + in_addr_t ip = 0; + uint8_t u = 0; + uint8_t bits = 0; + + while (n < e && (isdigit(*n) || *n == '.')) + { + if (*n == '.') + { + ip = (ip << 8) + u; + u = 0; + } + else + u = u * 10 + *n - '0'; + n++; + } + ip = (ip << 8) + u; + if (*n == '/') + { + n++; + while (n < e && isdigit(*n)) + bits = bits * 10 + *n++ - '0'; + } + else if ((ip >> 24) < 128) + bits = 8; + else if ((ip >> 24) < 192) + bits = 16; + else + bits = 24; + + if (!grp_addroute(grpid, s, ip, bits)) + return; + } + else if (attrib == 23) //SAMES-Group-Session-Weight + { + uint8_t weight = 0; + + while (n < e && isdigit(*n)) + weight = weight * 10 + *n++ - '0'; + + if (!weight) + { + LOG(1, s, session[s].tunnel, " Group-Session-Weight 0 GroupId %d not allowed\n", grpid); + return; + } + if (!grp_addsession(grpid, s, weight)) + { + return; + } + } + else + { + LOG(3, s, session[s].tunnel, " Unknown vendor-specific: 64520, Attrib: %d\n", attrib); + } +} + +// Init data structures +void grp_initdata() +{ + int i; + + // Set default value (10s) + config->grp_txrate_average_time = 10; + + if (!(grpsession = shared_malloc(sizeof(groupsesst) * MAXGROUPE))) + { + LOG(0, 0, 0, "Error doing malloc for grouped session: %s\n", strerror(errno)); + exit(1); + } + + memset(grpsession, 0, sizeof(grpsession[0]) * MAXGROUPE); + for (i = 1; i < MAXGROUPE; i++) + { + grpsession[i].state = GROUPEUNDEF; + } + + if (!(grp_local = shared_malloc(sizeof(local_group) * MAXGROUPE))) + { + LOG(0, 0, 0, "Error doing malloc for grp_local: %s\n", strerror(errno)); + exit(1); + } + memset(grp_local, 0, sizeof(grp_local[0]) * MAXGROUPE); + +} + +// Update time_changed of the group +void grp_time_changed() +{ + groupidt g; + + for (g = gnextgrpid; g != 0; g = grpsession[g].prev) + { + grpsession[g].time_changed++; + } +} + +// Uncache all IP of a session +static void grp_uncache_ipsession(groupidt g, sessionidt s) +{ + int i; + uint8_t *a; + in_addr_t ip; + in_addr_t n_ip, j; + int prefixlen; + union iphash *h; + + for (i = 0; i < grpsession[g].nbroutesgrp; i++) + { + if (grpsession[g].route[i].ip != 0) + { + prefixlen = grpsession[g].route[i].prefixlen; + ip = grpsession[g].route[i].ip & (0xffffffff << (32 - prefixlen)); // Force the ip to be the first one in the route. + + for (j = ip; j < ip+(1<<(32-prefixlen)) ; ++j) + { + n_ip = htonl(j); // To network order + a = (uint8_t *) &n_ip; + h = ip_hash; + + if (!(h = h[*a++].idx)) continue; + if (!(h = h[*a++].idx)) continue; + if (!(h = h[*a++].idx)) continue; + + if (s == h[*a].sess) + { + h[*a].sess = 0; + //LOG(3, s, session[s].tunnel, "UnCaching ip address %s\n", fmtaddr(n_ip, 0)); + } + } + } + } +} + +uint16_t guint16_index_loadlist; +// return the next session can be used on the group +sessionidt grp_getnextsession(groupidt g, in_addr_t ip, in_addr_t ip_src) +{ + sessionidt s = 0, s2 = 0, s3 = 0; + int i; + uint32_t ltime_changed = 0, mintxrate = 0xFFFFFFFF, maxtxrate = 0; + uint32_t txrate = 0; + + if (g >= MAXGROUPE) + return 0; + + if (grpsession[g].time_changed >= config->grp_txrate_average_time) + { + // recalculation txrate + ltime_changed = grpsession[g].time_changed; + grpsession[g].time_changed = 0; + for (i = 0; i < grpsession[g].nbsession; i++) + { + if ((s2 = grpsession[g].sesslist[i].sid)) + { + uint32_t coutgrp_delta = 0; + + if (session[s2].cout >= grpsession[g].sesslist[i].prev_coutgrp) + coutgrp_delta = session[s2].cout - grpsession[g].sesslist[i].prev_coutgrp; + grpsession[g].sesslist[i].prev_coutgrp = session[s2].cout; + + txrate = (txrate + (coutgrp_delta/ltime_changed)) >> 1; + grpsession[g].sesslist[i].tx_rate = txrate; + + txrate = grpsession[g].sesslist[i].tx_rate/grpsession[g].sesslist[i].weight; + if (txrate < mintxrate) + { + if ( session[s2].ppp.phase > Establish && + (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) ) + { + grpsession[g].smin = s2; + mintxrate = txrate; + } + } + + if (txrate > maxtxrate) + { + if ( session[s2].ppp.phase > Establish && + (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) ) + { + grpsession[g].smax = s2; + maxtxrate = txrate; + } + } + } + } + } + + if ((s = sessionbyip(ip))) + { + uint8_t *as = (uint8_t *) &ip_src; + uint8_t *ad = (uint8_t *) &ip; + uint16_t ai = ad[3]; + ai <<= 8; + ai |= as[3]; + + s = grp_local[g].sid_loaddist[ai]; + if (!s) + { + s = grpsession[g].smin; + grp_local[g].sid_loaddist[ai] = s; + } + + if (g != grp_groupbysession(s)) + { + // This session does not belong to this group + LOG(3, s, session[s].tunnel, "Warning, the session does not belong to group %d\n", g); + s = 0; + grp_local[g].sid_loaddist[ai] = 0; + } + else if ( (session[s].ppp.phase > Establish) && + (time_now - session[s].last_packet <= (config->echo_timeout + 1)) ) + { + grp_local[g].sid_loaddist[guint16_index_loadlist++] = 0; + return s; + } + else + { + s = 0; + grp_local[g].sid_loaddist[ai] = 0; + } + } + + if (!s) + { + // random between 0 and nbsession-1 + uint indexsess = (rand() % grpsession[g].nbsession); + + if (indexsess >= grpsession[g].nbsession) + indexsess = 0; //Sanity checks. + + s2 = grpsession[g].sesslist[indexsess].sid; + if (s2 && + (session[s2].ppp.phase > Establish) && + (time_now - session[s2].last_packet <= (config->echo_timeout + 1))) + { + s = s2; + } + else + { + for (i = 0; i < grpsession[g].nbsession; i++) + { + if ((s2 = grpsession[g].sesslist[i].sid)) + { + s3 = s2; + + if ( session[s2].ppp.phase > Establish && + (time_now - session[s2].last_packet <= (config->echo_timeout + 1)) ) + { + s = s2; + break; + } + } + } + } + } + + if (!s) + s = s3; + + if (s) + cache_ipmap(ntohl(ip), s); + + return s; +} + +// load a groupe receive from master +int grp_cluster_load_groupe(groupidt g, groupsesst *new) +{ + int i; + int updategroup = 0; + + if (g >= MAXGROUPE) + { + LOG(0, 0, 0, "ERROR: Received a group id > MAXGROUPE!\n"); + return 0; + } + + if ((grpsession[g].nbroutesgrp != new->nbroutesgrp) || + (grpsession[g].nbsession != new->nbsession)) + { + updategroup = 1; + } + + if (!updategroup) + { + // Check session list + for (i = 0; i < grpsession[g].nbsession; i++) + { + if (grpsession[g].sesslist[i].sid != new->sesslist[i].sid) + { + updategroup = 1; + break; + } + } + } + + if (!updategroup) + { + // Check routes list + for (i = 0; i < grpsession[g].nbroutesgrp; i++) + { + if (grpsession[g].route[i].ip != new->route[i].ip) + { + updategroup = 1; + break; + } + } + } + + // needs update + if (updategroup) + { + // Del all routes + grp_setgrouproute(g, 0); + } + + memcpy(&grpsession[g], new, sizeof(grpsession[g])); // Copy over.. + + // needs update + if (updategroup) + { + // Add all routes + grp_setgrouproute(g, 1); + } + + return 1; +} diff --cc icmp.c index 5f05127,0d6c65e..e458741 --- a/icmp.c +++ b/icmp.c @@@ -4,19 -4,12 +4,13 @@@ #include #include #include - #include - #include #include - #include - #include - #include +#include + #include + #include "dhcp6.h" #include "l2tpns.h" - #include "pppoe.h" + #include "ipv6_u.h" static uint16_t _checksum(uint8_t *addr, int count); diff --cc l2tplac.c index fd3a7e0,4140258..5fb361e --- a/l2tplac.c +++ b/l2tplac.c @@@ -7,10 -7,10 +7,11 @@@ #include #include - #include +#include + #include #include "md5.h" + #include "dhcp6.h" #include "l2tpns.h" #include "util.h" #include "cluster.h" diff --cc l2tpns.h index 7dbf5b4,d92c274..94784d2 --- a/l2tpns.h +++ b/l2tpns.h @@@ -15,7 -15,7 +15,7 @@@ #include #include - #define VERSION "2.2.1" -#define VERSION "2.2.1-2fdn3.13" ++#define VERSION "2.2.1-2sames3.14" // Limits #define MAXTUNNEL 500 // could be up to 65535 diff --cc nsctl.c index 98785cd,4e19468..bfe3a69 --- a/nsctl.c +++ b/nsctl.c @@@ -7,9 -7,8 +7,10 @@@ #include #include #include +#include +#include + #include "dhcp6.h" #include "l2tpns.h" #include "control.h" diff --cc ppp.c index 0ffacd3,3a045ce..0259ab7 --- a/ppp.c +++ b/ppp.c @@@ -5,9 -5,8 +5,10 @@@ #include #include #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "constants.h" #include "plugin.h" diff --cc pppoe.c index 40e898e,c6bc12d..25ab798 --- a/pppoe.c +++ b/pppoe.c @@@ -21,8 -21,8 +21,9 @@@ #include #include #include +#include + #include "dhcp6.h" #include "l2tpns.h" #include "cluster.h" #include "constants.h" diff --cc sessionctl.c index a8c11bd,97e6111..9bf385d --- a/sessionctl.c +++ b/sessionctl.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" #include "control.h" diff --cc setrxspeed.c index f987378,a808c85..aef4a57 --- a/setrxspeed.c +++ b/setrxspeed.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" diff --cc snoopctl.c index 97d4bd0,ab850f0..4ec9b52 --- a/snoopctl.c +++ b/snoopctl.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" #include "control.h" diff --cc stripdomain.c index c251dba,d14e5d3..b536339 --- a/stripdomain.c +++ b/stripdomain.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" diff --cc tbf.c index aa9810e,4835ecc..9dba63e --- a/tbf.c +++ b/tbf.c @@@ -1,9 -1,8 +1,10 @@@ // L2TPNS: token bucket filters #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "util.h" #include "tbf.h" diff --cc throttlectl.c index bcc0478,ef194f4..5d73a01 --- a/throttlectl.c +++ b/throttlectl.c @@@ -1,7 -1,6 +1,8 @@@ #include - #include +#include + #include + + #include "dhcp6.h" #include "l2tpns.h" #include "plugin.h" #include "control.h" diff --cc util.c index e412fc1,ff6bf1e..2cd9a9e --- a/util.c +++ b/util.c @@@ -8,8 -8,8 +8,9 @@@ #include #include #include +#include + #include "dhcp6.h" #include "l2tpns.h" #ifdef BGP #include "bgp.h"