improved load balancing algorithm.
authorfendo <fendo@bi12info.com>
Fri, 2 Aug 2013 09:36:56 +0000 (11:36 +0200)
committerfendo <fendo@bi12info.com>
Fri, 2 Aug 2013 09:36:56 +0000 (11:36 +0200)
debian/changelog
grpsess.c
l2tpns.c
l2tpns.h

index 4a37290..07531e8 100644 (file)
@@ -1,3 +1,9 @@
+l2tpns (2.2.1-2sames3.11) unstable; urgency=low
+
+  * improved load balancing algorithm.
+
+ -- Fernando Alves <fernando.alves@sameswireless.fr>  Fri, 02 Aug 2013 11:32:49 +0200
+
 l2tpns (2.2.1-2sames3.10) unstable; urgency=low
 
   * Fix: authentication success was sent 2 times.
index e710709..f38ab1a 100644 (file)
--- a/grpsess.c
+++ b/grpsess.c
@@ -42,6 +42,14 @@ static groupidt grp_lookup_ipmap(in_addr_t ip)
        return h[*a].grp;
 }
 
+typedef struct
+{
+       sessionidt sid_loaddist[0x10000];
+}
+local_group;
+
+local_group *grp_local = NULL;         // Array of local_group structures.
+
 //
 // Take an IP address in HOST byte order and
 // add it to the grouid by IP cache.
@@ -447,6 +455,14 @@ void grp_initdata()
        {
                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
@@ -498,7 +514,7 @@ static void grp_uncache_ipsession(groupidt g, sessionidt s)
 }
 
 // return the next session can be used on the group
-sessionidt grp_getnextsession(groupidt g, in_addr_t ip)
+sessionidt grp_getnextsession(groupidt g, in_addr_t ip, in_addr_t ip_src)
 {
        sessionidt s = 0, s2 = 0, s3 = 0;
        int i;
@@ -551,15 +567,30 @@ sessionidt grp_getnextsession(groupidt g, in_addr_t ip)
 
        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(2, 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 (s == grpsession[g].smax)
                {
                        s = grpsession[g].smin;
+                       grp_local[g].sid_loaddist[ai] = s;
                        grpsession[g].smax = 0;
                }
                else if ( (session[s].ppp.phase > Establish) &&
@@ -570,6 +601,7 @@ sessionidt grp_getnextsession(groupidt g, in_addr_t ip)
                else
                {
                        s = 0;
+                       grp_local[g].sid_loaddist[ai] = 0;
                }
        }
 
index 9ac6bfd..9861e88 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -1413,7 +1413,7 @@ void processipout(uint8_t *buf, int len)
        groupidt g;
        sessiont *sp;
        tunnelidt t;
-       in_addr_t ip;
+       in_addr_t ip, ip_src;
 
        uint8_t *data = buf;    // Keep a copy of the originals.
        int size = len;
@@ -1446,10 +1446,11 @@ void processipout(uint8_t *buf, int len)
                return;
        }
 
+       ip_src = *(uint32_t *)(buf + 12);
        ip = *(uint32_t *)(buf + 16);
        if ((g = grp_groupbyip(ip)))
        {
-               s = grp_getnextsession(g, ip);
+               s = grp_getnextsession(g, ip, ip_src);
                if (!s)
                {
                        // Is this a packet for a session that doesn't exist?
index 1ce46a3..5dd854f 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1005,7 +1005,7 @@ void lac_send_ICRQ(tunnelidt t, sessionidt s);
 void lac_tunnelshutdown(tunnelidt t, char *reason, int result, int error, char *msg);
 
 // grpsess.c
-sessionidt grp_getnextsession(groupidt g, in_addr_t ip);
+sessionidt grp_getnextsession(groupidt g, in_addr_t ip, in_addr_t ip_src);
 void grp_initdata(void);
 void grp_processvendorspecific(sessionidt s, uint8_t *pvs);
 groupidt grp_groupbysession(sessionidt s);