Перейти к содержимому
Калькуляторы
Было-бы неплохо с биллинга для каждого клиента отдать Framed-IP-Netmask , если его нет то /32 .

Тогда каждый клиент будет сетью, хоть из 1 IP, хоть из 255.

Но дело в том что в rfc3576 (CoA) такого атрибута нет. Или я что-то путаю )))

rfc3576 абсолютно пофиг, что ты сунешь в аттрибуты "что менять". Вот mpd-limit народ сунет - и ничего :). Там "Session identification attributes" важнее, т.е. "кому менять".

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Framed-IP-Netmask несколько не для этого. Но боком прикрутить можно.

А зачем он в CoA? Сессия то все равно одна будет для всей подсети. Вот этой сессии и подавать CoA по ID, опираясь на Online в билинге.

А вот те, у кого radius/билинг шлет по умолчанию этот параметр, будут неприятно удивлены поведением.

 

А хотя нет. Не одна сессия будет. Ведь запустить сессию может любой IP, а только потом в ISG придет атрибут Framed-IP-Netmask.

А значит для сети /24 в базе билинга придется держать 254 логина.

Тогда уже логичней будет считать все сессии в отдельности, и держать отдельный счетчик всей подсети в ядре для полисинга.

Или же использовать общий счетчик через указатель. но тогда у всех активных сессий в билинге будут одинаковые счетчики трафика.

 

В общем пока не ясно, как проще.

Предлагайте

Изменено пользователем SNeon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Совершенно верно, в ISG сессию инициирует любой IP , но это же не догма ?

Но я думаю совершенно незачем держать для /24 - 254 логина, вполне достаточно одного, с одним счетчиком для полисинга.

Сессию стартовать всегда с проверкой IP по маске (Framed-IP-Netmask), в результате для любой произвольной подсети будет

соответствовать одна сессия.

По поводу Framed-IP-Netmask - согласен, не из этой оперы, но самое близкое, ближе нет )))

Изменено пользователем kww

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Де дело в том, что от ISG не придет Framed-IP-Netmask с самого начала, ибо ISG не знает как бить сети.

 

Допустим нет ни одной сессии. Допустим надо полисить сеть 1.0.0.0/24

Теперь приходит клиент и включает камп:

Идет auth-request примерно следующего типа

логин: 1.0.0.24

пароль: 1.0.0.24

id: random

port: первый свободный

 

и вот как ему назначить сеть?

а логин и пароль нужен в билинге, иначе как идентифицировать?

 

ISG в запросе не может передать сеть! никак! он же не знает того, что знает билинг!!!

 

дальше: допустим билинг ответил ацептом (по связке IP-пароль). Выдал атрибуты...

....

Framed-IP-Netmask

....

 

и как с атриутом дальше поступить?

 

а теперь допустим, что первым включили камп с IP 1.0.0.21...

 

мысли?

 

а теперь случай - уже зареган 1.0.0.24. А тут запрос от 1.0.0.98 Чо дальше делать?

Как отчитаться radius о клиентах?

Изменено пользователем SNeon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Совершенно верно, в ISG сессию инициирует любой IP , но это же не догма ?

Но я думаю совершенно незачем держать для /24 - 254 логина, вполне достаточно одного, с одним счетчиком для полисинга.

как об этом уведомить ISG? Ведь хочется ж одним правилом в iptables оседлать и /24 и /30 и /32

Проблема в том, что запрос логин-пароль (IP-IP) идут раньше, чем назначения подсетей из билинга

 

Сессию стартовать всегда с проверкой IP по маске (Framed-IP-Netmask), в результате для любой произвольной подсети будет соответствовать одна сессия.

Ну подумайте сами. клиент ломится в инет. что мы о нем можем узнать? IP? Да, только его IP. Сеть он не передает. Как узнать его сеть?

Только спросить у билинга, через IP. А для этого и надо держать 254 IP для /24

Теперь: как опросив логин (а именно IP, а он же может быть любой из диапазона) вычислить нужный шейпер?

 

По поводу Framed-IP-Netmask - согласен, не из этой оперы, но самое близкое, ближе нет )))
юзабельно, только вот вопросы выше...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а что, биллинг не может проверить попадает этот IP в подсеть или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
а что, биллинг не может проверить попадает этот IP в подсеть или нет?
Я вот только что хотел написать, что это можно прямо в SQL-запросе заматчить :). А-ля:

SELECT x,y,z FROM aaa WHERE (aaa.ip | aaa.netmask) = (inet_aton("1.2.3.4") | inet_aton("255.255.255.0"));

Это при условии, что ip и netmask в aaa хранятся как int.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Каким запросом, зная только IP, получить из базы маску?

Многие ли билинги это умеют?

допустим в базе есть запись с логином 10.0.0.0. для этого логина я хочу сеть /29. Т.е. будет еще поле для Framed-Netmask = 255.255.255.248

 

как теперь это всё провернуть, если подключается клиент с IP 10.0.0.5 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Если Postgres то можно проверить принадлежность к сети так:

 

SELECT ip FROM users WHERE ip << '10.10.10.0/24'::inet

 

Вернет IP пи условии что оно попадет под маску, в противном случае нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

но мы же не знаем какая маска. у нас всё с точностью до наоборот! известен IP а надо подобрать ему в базе соответствующую маску же!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
но мы же не знаем какая маска. у нас всё с точностью до наоборот! известен IP а надо подобрать ему в базе соответствующую маску же!
Модификация кода, написанного выше:

SELECT x,y,z FROM aaa WHERE (aaa.ip | aaa.netmask) = (inet_aton("1.2.3.4") | aaa.netmask);

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

уговорили )

сделаю под Framed-Netmask =) Не обещаю, что скоро. Пока продумываю алгоритм

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Давайте промоделируем ситуацию.

В ISG шлюз прилетел пакет с адресом допустим 10.10.10.5, в текушем состоянии ISG

запросит у радиуса данные по этому IP (который спросит у биллинга) и получив ACCEPT создаст

сессию для этого IP с параметрами которые отдал радиус.

Нам нужно немного модифицировать поведение.

При приходе пакета ISG запросит у радиуса данные по IP

радиус из биллинга должен отдать (не суть важно как, каждый это реализует по своему) пару атрибутов

допустим ACCEPT для данного пользователя (IP) и принадлежащую ему сеть.

Задача ISG в данном случае создать одну сессию для этой сети.

Похоже для каждой авторизованной IP в ядре придется держать адрес сети к которой она принадлежит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Именно! Уже заканчиваю реализацию. Днем поставлю на тест.

Для каждой авторизованной сессии будет держаться связка сеть/маска. пакеты будут сравниваться так: сеть == IP & маска. на всю подсеть 1 сессия. Но инициализированная по любому IP. Билинг уже перековырял =)

Изменено пользователем SNeon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Патч на динамическое распределение на подсети по атрибуту Framed-IP-Netmask (атрибут можно изменить в конфиге, опция $cfg{network_ident}. Атрибут должен быть типа ipaddr (см. в файле dictionary)

 

Сессию запускает первый обратившийся IP из подсети. С-но логин/пароль будет этот же IP. Вся статистика будет также идти от этого IP.

Но полиситься и учитываться будет вся подсеть. Если Framed-IP-Netmask не указан, то считается что маска 255.255.255.255 (то есть 1 IP)

 

Это АЛЬФА версия патча на голую версию http://bitbucket.org/sysoleg/lisg/get/tip.tar.gz

Альфа, потому как не тестировал сервисы и классы. Есть мнение, работать будет, но тестировать негде т.к. у меня не используется.

 

Эта версия уже трудится 4 часа. Мин нет. Кому не страшно - тестируйте и отписывайте.

в iptables ничего не изменилось

в конфиг добавлена опция $cfg{network_ident} = "Framed-IP-Netmask";

изменены файлы:

./ISG/bin/ISG.pl

./ISG/bin/ISGd.pl

./lib/ISG.pm

./kernel/isg_main.c

./kernel/isg_main.h

 

так что потребуется пересборка модуля ядра, перезапись поверх библиотеки, демона и управляющей программы. перезагрузка модуля, перезапуск демона

 

diff -ruN lisg/ISG/bin/ISGd.pl lisg-framed-net/ISG/bin/ISGd.pl
--- lisg/ISG/bin/ISGd.pl	2010-10-02 22:10:08.000000000 +0300
+++ lisg-framed-net/ISG/bin/ISGd.pl	2011-01-16 15:05:58.957575888 +0200
@@ -287,6 +287,7 @@
			$oev->{'alive_interval'} = defined($alive_interval) ? $alive_interval : $cfg{session_alive_interval};
			$oev->{'max_duration'} = defined($max_duration) ? $max_duration : $cfg{session_max_duration};
			$oev->{'idle_timeout'} = defined($idle_timeout) ? $idle_timeout : $cfg{idle_timeout};
+			$oev->{'ipnetmask'} = ISG::ip2long($rp->attr(defined($cfg{network_ident}) ? $cfg{network_ident} : 'Framed-IP-Netmask'));

			if (defined($speed_info) && $speed_info =~ /^(\d{1,})\/(\d{1,})$/) {
			    $oev->{'in_rate'}  = $2 * 1000;
diff -ruN lisg/ISG/etc/config.pl lisg-framed-net/ISG/etc/config.pl
--- lisg/ISG/etc/config.pl	2010-10-02 22:10:08.000000000 +0300
+++ lisg-framed-net/ISG/etc/config.pl	2011-01-16 15:05:58.972575673 +0200
@@ -35,6 +35,9 @@
### Check traffic classification file MD5 sum every N seconds. If sum was changed re-read this file.
$cfg{tc_check_interval} = 300; ## Every 5 minutes

+### Network identifier. Param from dictionary. Type is ipaddr. Default - Framed-IP-Netmask
+$cfg{network_ident} = "Framed-IP-Netmask";
+
####################### Services description #######################

### Begin ``TESTSERV'' service ###
diff -ruN lisg/ISG/lib/ISG.pm lisg-framed-net/ISG/lib/ISG.pm
--- lisg/ISG/lib/ISG.pm	2010-10-02 22:10:08.000000000 +0300
+++ lisg-framed-net/ISG/lib/ISG.pm	2011-01-16 15:05:58.981575546 +0200
@@ -22,7 +22,7 @@
use constant NLMSG_ALIGNTO	=> 4;
use constant NLMSG_DONE		=> 0x3;
use constant NLM_F_MULTI	=> 0x2;
-use constant IN_EVENT_MSG_LEN 	=> 140;
+use constant IN_EVENT_MSG_LEN 	=> 148;

use constant EVENT_LISTENER_REG  => 0x01;
use constant EVENT_SESS_APPROVE  => 0x04;
@@ -178,6 +178,8 @@

    $pars->{'session_id'}	= "";
    $pars->{'ipaddr'}		= 0;
+    $pars->{'ipnetwork'}	= 0;
+    $pars->{'ipnetmask'}	= 4294967295;
    $pars->{'nat_ipaddr'}	= 0;
    $pars->{'port_number'}	= 0;
    $pars->{'flags'}		= 0;
@@ -220,10 +222,12 @@

    } else {

-	return pack("I a8 N2 H12 v I8 a32 C",
+	return pack("I a8 N4 H12 v I8 a32 C",
	    $pars->{'type'},
	    $pars->{'session_id'},
	    $pars->{'ipaddr'},
+	    $pars->{'ipnetwork'},
+	    $pars->{'ipnetmask'},
	    $pars->{'nat_ipaddr'},
	    0, # MAC-Address is read-only
	    $pars->{'flags'},
@@ -255,6 +259,8 @@
	$session_id_hi,
	$session_id_lo,
	$pars->{'ipaddr'},
+	$pars->{'ipnetwork'},
+	$pars->{'ipnetmask'},
	$pars->{'nat_ipaddr'},
	$pars->{'macaddr'},
	$pars->{'flags'},
@@ -279,7 +285,7 @@
	$p_session_id_hi,
	$p_session_id_lo,
	$pars->{'service_name'}
-    ) = unpack("I I2 N2 H12 v I8 I i I10 a32", shift);
+    ) = unpack("I I2 N4 H12 v I8 I i I10 a32", shift);

    $pars->{'service_name'} =~ s/\000//g;
    if (!length($pars->{'service_name'})) {
diff -ruN lisg/kernel/isg_main.c lisg-framed-net/kernel/isg_main.c
--- lisg/kernel/isg_main.c	2010-10-02 22:10:08.000000000 +0300
+++ lisg-framed-net/kernel/isg_main.c	2011-01-16 15:05:58.982575531 +0200
@@ -491,6 +491,8 @@
    }

    is->info.ipaddr = ipaddr;
+    is->info.ipnetwork = ipaddr;
+    is->info.ipnetmask = 0xFFFFFFFFL;
    is->start_ktime = ts_now.tv_sec;
    is->isg_net = isg_net;

@@ -556,6 +558,9 @@
	is->info.out_rate = ev->si.sinfo.out_rate;
	is->info.out_burst = ev->si.sinfo.out_burst;

+	is->info.ipnetmask = ev->si.sinfo.ipnetmask;
+	is->info.ipnetwork = (is->info.ipnetmask & is->info.ipaddr);
+
	if (ev->si.sinfo.nat_ipaddr) {
	    is->info.nat_ipaddr = ev->si.sinfo.nat_ipaddr;
	}
@@ -674,14 +679,17 @@
}

static inline struct isg_session *isg_lookup_session(struct isg_net *isg_net, u_int32_t ipaddr) {
+    unsigned int i;
    struct isg_session *is;
    struct hlist_node *n;
-    unsigned int h = get_isg_hash(ipaddr);
+//    unsigned int h = get_isg_hash(ipaddr);

-    hlist_for_each_entry(is, n, &isg_net->hash[h], list) {
-	if (is->info.ipaddr == ipaddr) {
-            return is;
-        }
+    for (i = 0; i < nr_buckets; i++) {
+	hlist_for_each_entry(is, n, &isg_net->hash[i], list) {
+	    if (is->info.ipnetwork == (ipaddr & is->info.ipnetmask)) {
+		return is;
+	    }
+	}
    }

    return NULL;
@@ -690,7 +698,7 @@
static inline int isg_equal(struct isg_in_event *ev, struct isg_session *is) {
    if ((ev->si.sinfo.id && ev->si.sinfo.id == is->info.id) ||
	(is->info.port_number == ev->si.sinfo.port_number) ||
-	(is->info.ipaddr == ev->si.sinfo.ipaddr)) {
+	(is->info.ipnetwork == (is->info.ipnetmask & ev->si.sinfo.ipaddr))) {
	return 1;
    } else {
	return 0;
diff -ruN lisg/kernel/isg_main.h lisg-framed-net/kernel/isg_main.h
--- lisg/kernel/isg_main.h	2010-10-02 22:10:08.000000000 +0300
+++ lisg-framed-net/kernel/isg_main.h	2011-01-16 15:05:58.983575515 +0200
@@ -83,6 +83,8 @@
    u_int64_t id;

    u_int32_t ipaddr;		/* User's IP-address */
+    u_int32_t ipnetwork;	/* User's NetWork */
+    u_int32_t ipnetmask;	/* User's NetMask */
    u_int32_t nat_ipaddr;	/* User's 1-to-1 NAT IP-address */
    u_int8_t macaddr[ETH_ALEN];	/* User's MAC-address */

Изменено пользователем SNeon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А есть идеи как реялизовать L4 Redirect ? Ведь вся работа lISG происходит в таблице filter где пакеты только фильтруются, а подмена IP адресов и портов происходит в таблице nat ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Думаю можно реализовать так-же как и 1-to-1 NAT. При помощи добавления правил в -t nat из perl скрипта

Попробую вечерком поколдовать на эту тему

Изменено пользователем SNeon

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

надо сделать следующим образом:

 

модифицировать isg_session_info и добавить в неё список айпишников, при этом поле ipaddr оставить в качестве имени.

при приходе пакета от адреса, которого еще нет в активных сессиях, отправлять в радиус аус рек с именем пользователя, равным этому пришедшему адресу.

радиус при отправке акцепта во Framed-IP-Address ставит первый (по какому нравится алгоритму) или единственный адрес клиента из своей имеющейся базы.

исг при получении акцепта от радиуса либо заводит новую сессию, либо пополняет список в одной из существующих сессий.

у сессий с единственным адресом (большинство) список пустой, есть только имя-адрес.

при этом isg_find_session должен искать сессию не только по имени-адресу из isg_session_info, но и по списку.

 

таким образом решается проблема с полисингом не только подсетей, как предлагается выше, но и с адресами, выданными в разное время и, возможно, совершенно из разных блоков.

 

есть добровольцы? :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Поделюсь своим решением поддержки нескольких IP адресов. Работает уже пару месяцев, все ок.

 

У каждой сессии может быть родительская:

 

struct isg_session_info {
      u_int32_t ipaddr;       /* User's IP-address */
      u_int32_t pipaddr;      /* Parent's IP Address (Only for additional sessions) */
.......
}

 

Если у клиента всего лишь один IP адрес, то все происходит как обычно. Если у него несколько IP адресов (может быть даже из разных сетей) то выделяется один главный айпи для которого будет создана родительская сессия, для остальных айпи будут созданы дочерние сессии у которых pipaddr будет равен IP родительской.

 

Теперь покажу как происходит авторизация дочерней сессии. У меня есть модуль в радиусе который тянет из биллинга клиентов, и если у клиента есть главный IP, а сессия открывается для дополнительного, то он отвечает так:

 

[root@ex2 /]# radtest 192.168.10.11 192.168.10.11 localhost 0 test
Sending Access-Request of id 207 to 127.0.0.1 port 1812
    User-Name = "192.168.10.11"
    User-Password = "192.168.10.11"
    NAS-IP-Address = 127.0.0.1
    NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1 port 1812, id=207, length=51
    Idle-Timeout = 1800
    Acct-Interim-Interval = 0
    Session-Timeout = 39604
    Class = 0x31302f3130
    Framed-IPX-Network = 192.168.10.10

 

Где Framed-IPX-Network это IP адрес родительской сессии (атрибут выбрал от балды).

 

Счетчики обновляются для каждой сессии отдельно, но когда дело доходит до полосы пропускания, то она режется на основе счетчиков родительской сессии.

 

Список клиентов выдлядит так:

 

[root@ex2 /]# /usr/local/ISG/bin/ISG.pl
User IP-address Parent IP       Port number   Uniq. Identifier Duration   Bytes-in   Bytes-out  Rate-in    Rate-out   Status
.........
192.168.35.104   0.0.0.0         Virtual83     69C905438CD864C5 02:06:31   357.01 MB  6.07 MB    4 Mbit/s   2 Mbit/s   On   
192.168.22.149  0.0.0.0         Virtual392    72E352E634A71956 02:10:52   145.23 MB  10.85 MB   2 Mbit/s   1 Mbit/s   On   
192.168.42.80    0.0.0.0         Virtual654    1B207950199C66A7 02:09:18   10.91 MB   16.39 MB   4 Mbit/s   2 Mbit/s   On   
192.168.25.120  192.168.25.90   Virtual401    55FADF71734B0E79 02:10:33   8.65 MB    15.09 MB   10 Kbit/s  10 Kbit/s  On   
192.168.20.2    192.168.20.50   Virtual201    0E223E9BE5F27FB8 02:13:01   189.97 MB  7.86 MB    10 Kbit/s  10 Kbit/s  On
..........

 

Главный минус в моем подходе это куча дочерних сессий если клиенту выделен /28. За то видна статистика по каждому айпи адресу.

 

Если что могу показать более детально код где происходит вся магия.

 

PS. У меня нет NATа. Все IP адреса придуманы. Также нету классов направления, при разработке я их вообще не брал во внимание, так что с ними работать думаю не будет.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а у парента рейты считаются суммой себя плюс детей? в общем, код в студию!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

ОК, освобожусь немножко и покажу куски кода чтобы идея была понятна.

 

а у парента рейты считаются суммой себя плюс детей? в общем, код в студию!

Полоса одна на всех.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И так, как и обещал, покажу куски кода более детально. Я могу конечно выложить полностью исходники, но поддержка нескольких айпи на клиента это не единственная вещь которую я реализовал, поэтому приведу код который занимается именно этим.

 

Код написанный мною снабжен комментариями.

 

После того как демон получил ответ "Access-Accept" от радиуса с атрибутом "Framed-IPX-Network", то он просто вместе с остальными параметрами шлет и этот параметр модулю:

 

if ($rp->code eq "Access-Accept") {
    my $oev;
    ....................
    my $alive_interval = $rp->attr('Acct-Interim-Interval');
    my $max_duration   = $rp->attr('Session-Timeout');
    my $idle_timeout   = $rp->attr('Idle-Timeout');
    my $pipaddr        = $rp->attr('Framed-IPX-Network'); // Этим параметром демон указывает что это дочерния сессия

    $oev->{'type'} = ISG::EVENT_SESS_APPROVE;
    $oev->{'port_number'} = $exp_ev->{'port_number'};

    .........................

    if (defined($pipaddr)) {
        $oev->{'pipaddr'} = ISG::ip2long($pipaddr); // Тоже самое
    }

    if (isg_send_event($sk, $oev) < 0) {
        do_log("err", "Error sending reply for SESS_CREATE: $!");
    }

    .........................

 

Получив эти данные, модуль вызывает функцию isg_update_session:

 

static int isg_update_session(struct isg_net *isg_net, struct isg_in_event *ev) {
    struct isg_session *is;
    ...............................
    
if (is) {
        is->info.in_rate = ev->si.sinfo.in_rate;
        is->info.in_burst = ev->si.sinfo.in_burst;

        is->info.pipaddr = ev->si.sinfo.pipaddr; // Указываем что у сессии есть родительская

    ...............................

 

А теперь листинг где происходят главные действия:

 

#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) // У меня Centos 5.5 2.6.18-194.32.1.el5
isg_tg(struct sk_buff **pskb,
        const struct net_device *in,
        const struct net_device *out,
        unsigned int hooknum,
        const struct xt_target *target,
        const void *targinfo,
        void *userinfo)
    ..................................

    struct isg_session *is, *isrv, *classic_is = NULL;
    struct isg_session *pis = NULL;         // Если пакет будет от дочерней сессии то эта переменная будет хранить родительскую
    struct isg_session *cis = NULL;         // А в этой будем хранить дочернюю

    ..................................

    is = isg_lookup_session(isg_net, laddr); // Здесь ищем сессию от которой пришел пакет

    if (is == NULL) { // Если сессии нету то далее идет ее создание и отброс пакета

    ..................................
    /*
     * Смотрим если у этой сессии есть родительская
    */

    if (is->info.pipaddr) {
                pis     = isg_lookup_session(isg_net, is->info.pipaddr); // Если она есть то находим ее

                /*
                * Если находим то инициализируем переменные
                */
                if (pis) {
                        cis = is;       // Сохраняем дочернюю
                        is = pis;       // Далее будем работать уже с родительской
                } else {

                        /*
                        * Если у родителя нету открытой сессии то создаем ее
                        */
                        u_int8_t *src_mac = NULL;               

                        if (skb_mac_header(skb) >= skb->head && skb_mac_header(skb) + ETH_HLEN <= skb->data) {
                                if (iinfo->flags & INIT_BY_SRC) {
                                        src_mac = eth_hdr(skb)->h_source;
                                }
                        }

                        isg_create_session(isg_net, is->info.pipaddr, src_mac);
                        goto DROP;
                }
        }

    ..........................

found:
    ..........................
    /*
    * В is мы храним родительскую сессию, а в cis дочернюю.
    */

    if (iinfo->flags & INIT_BY_SRC) {
                isg_update_tokens(is, now, ISG_DIR_IN);
                
                if (cis) {
                        cis->in_last_seen = now; // Обновляем счетчик
                }

                if (pkt_len_bits <= is->in_tokens || !is->info.in_rate) {
                    is->in_tokens -= pkt_len_bits;

                        /* Если это дочерняя то обновляем ее счетчики */
                        if (cis) {
                                cis->stat.in_bytes += pkt_len;
                                cis->stat.in_packets++;
                        } else {
                                is->stat.in_bytes += pkt_len;
                                is->stat.in_packets++;
                        }
    ......................

 

Вот и все. Если есть вопросы, задавайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Вы бы ребята усилия объединили и выложили это в каком то "официальном виде".

Чтобы не приходилось нам делать diffы и собирать всё это по кусочкам =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Выложите, если можно, скрипты для привязки сего чуда к Abills. Буду очень благодарен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Выложите, если можно, скрипты для привязки сего чуда к Abills. Буду очень благодарен.

Выкладывал на форуме Abills. Там, правда, кое-чего нету, но при желании дописывается за полчаса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас