--- src/pppoe.h.orig 2013-06-11 16:00:00.000000000 +0700 +++ src/pppoe.h 2013-06-25 17:46:26.000000000 +0700 @@ -10,15 +10,23 @@ #ifndef _PPPOE_H_ #define _PPPOE_H_ +#include #include "command.h" #include "phys.h" + struct PppoeSoftLimitType { + int limit; + struct timespec pado_delay; + }; + /* * VARIABLES */ extern const struct cmdtab PppoeSetCmds[]; extern const struct phystype gPppoePhysType; + extern int gPppoeSessions; + extern struct PppoeSoftLimitType gPppoeSoftLimit; #endif --- src/pppoe.c.orig 2013-06-25 17:45:22.000000000 +0700 +++ src/pppoe.c 2013-06-25 17:46:26.000000000 +0700 @@ -1065,6 +1065,10 @@ PppoeListenEvent(int type, void *arg) goto shutdown_tee; } + if (gPppoeSessions >= gPppoeSoftLimit.limit && + (gPppoeSoftLimit.pado_delay.tv_sec || gPppoeSoftLimit.pado_delay.tv_nsec)) + nanosleep(&gPppoeSoftLimit.pado_delay, NULL); + /* Put the PPPoE node into OFFER mode. */ memset(idata, 0, sizeof(*idata)); strlcpy(idata->hook, session_hook, sizeof(idata->hook)); --- src/main.c.orig 2013-06-11 16:00:00.000000000 +0700 +++ src/main.c 2013-06-25 17:46:26.000000000 +0700 @@ -25,6 +25,7 @@ #ifdef CCP_MPPC #include "ccp_mppc.h" #endif +#include "pppoe.h" #include @@ -115,6 +116,8 @@ #endif int gChildren = 0; /* Current number of children links */ int gMaxChildren = 10000; /* Maximal number of children links */ + struct PppoeSoftLimitType gPppoeSoftLimit = { 65536, {0, 0} }; + int gPppoeSessions = 0; #ifdef USE_NG_BPF struct acl *acl_filters[ACL_FILTERS]; /* mpd's global internal bpf filters */ --- src/command.c.orig 2013-06-11 16:00:00.000000000 +0700 +++ src/command.c 2013-06-25 17:46:26.000000000 +0700 @@ -44,6 +44,7 @@ #ifdef USE_NG_NETFLOW #include #endif +#include /* * DEFINITIONS @@ -78,6 +79,7 @@ SET_L2TPTO, SET_L2TPLIMIT, #endif + SET_PPPOE_SOFTLIMIT, SET_MAX_CHILDREN, SET_QTHRESHOLD, #ifdef USE_NG_BPF @@ -151,6 +153,9 @@ { "pptplimit {num}", "Calls per PPTP tunnel limit" , GlobalSetCommand, NULL, 2, (void *) SET_PPTPLIMIT }, #endif + { "pppoesoftlimit {num} {sec} {nsec}", + "Soft limit for PPPoE sessions total count" , + GlobalSetCommand, NULL, 2, (void *) SET_PPPOE_SOFTLIMIT }, { "max-children {num}", "Max number of children", GlobalSetCommand, NULL, 2, (void *) SET_MAX_CHILDREN }, { "qthreshold {min} {max}", "Message queue limit thresholds", @@ -697,6 +702,26 @@ GlobalSetCommand(Context ctx, int ac, ch break; #endif + case SET_PPPOE_SOFTLIMIT: + if (ac == 3) { + long lval; + + val = atoi(av[0]); + if (val < 0 || val > 65536) + Error("Incorrect PPPoE soft limit"); + else + gPppoeSoftLimit.limit = val; + lval = atol(av[1]); + if (lval < 0) lval = 0; + gPppoeSoftLimit.pado_delay.tv_sec = (time_t)lval; + lval = atol(av[2]); + if (lval < 0) lval = 0; + gPppoeSoftLimit.pado_delay.tv_nsec = lval; + } + else + return (-1); + break; + case SET_MAX_CHILDREN: val = atoi(*av); if (val < 0 || val > 65536) @@ -984,6 +1009,8 @@ ShowGlobal(Context ctx, int ac, char *av Printf(" pptptimeout : %d\r\n", gPPTPto); Printf(" pptplimit : %d\r\n", gPPTPtunlimit); #endif + Printf(" pppoesoftlimit : %d %ld %ld\r\n", gPppoeSoftLimit.limit, + gPppoeSoftLimit.pado_delay.tv_sec, gPppoeSoftLimit.pado_delay.tv_nsec); Printf(" max-children : %d\r\n", gMaxChildren); Printf(" qthreshold : %d %d\r\n", gQThresMin, gQThresMax); Printf("Global options:\r\n"); --- src/bund.c.orig 2013-06-11 16:00:00.000000000 +0700 +++ src/bund.c 2013-06-25 17:46:26.000000000 +0700 @@ -21,6 +21,7 @@ #include "log.h" #include "util.h" #include "input.h" +#include "pppoe.h" #include #include @@ -377,6 +378,9 @@ BundJoin(Link l) #endif } + if (!strcmp(b->links[0]->type->name, gPppoePhysType.name)) + gPppoeSessions++; + AuthAccountStart(l, AUTH_ACCT_START); return(b->n_up); @@ -400,6 +404,9 @@ BundLeave(Link l) AuthAccountStart(l, AUTH_ACCT_STOP); + if (b->links[0] && !strcmp(b->links[0]->type->name, gPppoePhysType.name)) + gPppoeSessions--; + /* Disable link */ b->pppConfig.links[l->bundleIndex].enableLink = 0; b->pppConfig.links[l->bundleIndex].mru = LCP_DEFAULT_MRU;