Неправильная отправка DHCP NAK
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Неправильная отправка DHCP NAK
Есть следующая ситуация: QinQ, два сервера с accel-ppp.
Есть некоторые клиенты, которые отправляют DHCP Request-ы broadcast-ом.
Возникает следующее: клиент подключается к серверу (1), через некоторое время приходит за обновлением лизы. Запрос на обновление лизы отправляет broadcast-ом. Ему отвечают оба сервера: (1) - ACK-ом, (2) - NAK-ом.
В результате клиент, получив NAK, заново начинает Discover. В это время у абонента на 1-2 секунды пропадает связь.
Получается, что сервер (2) не должен отвечать NAK-ом на broadcast REQUEST-ы?
Есть некоторые клиенты, которые отправляют DHCP Request-ы broadcast-ом.
Возникает следующее: клиент подключается к серверу (1), через некоторое время приходит за обновлением лизы. Запрос на обновление лизы отправляет broadcast-ом. Ему отвечают оба сервера: (1) - ACK-ом, (2) - NAK-ом.
В результате клиент, получив NAK, заново начинает Discover. В это время у абонента на 1-2 секунды пропадает связь.
Получается, что сервер (2) не должен отвечать NAK-ом на broadcast REQUEST-ы?
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Сунул вот такой костыль:
Получаю по несколько записей в лог в секунду.
Посмотрю, поможет ли это клиенту и не будет ли побочных эффектов.
Хотя виноват, конечно, клиент, который чужой NAK ставит выше ACK-а от своего сервера.
Может, стоит делать задержку перед NAK, чтобы другие сервера успели ACK-нуть?
Code: Select all
--- accel-pppd/ctrl/ipoe/dhcpv4.c (revision 5a7474b41970e8cdf5ad98f7daa74814f5667a5e)
+++ accel-pppd/ctrl/ipoe/dhcpv4.c (revision )
@@ -781,6 +781,12 @@
int dhcpv4_send_nak(struct dhcpv4_serv *serv, struct dhcpv4_packet *req)
{
+
+ if (req->src_addr == 0 && req->msg_type == DHCPREQUEST) {
+ log_info2("not NAKing broadcast REQUEST\n");
+ return 0;
+ }
+
struct dhcpv4_packet *pack;
int val, r;
Посмотрю, поможет ли это клиенту и не будет ли побочных эффектов.
Хотя виноват, конечно, клиент, который чужой NAK ставит выше ACK-а от своего сервера.
Может, стоит делать задержку перед NAK, чтобы другие сервера успели ACK-нуть?
Re: Неправильная отправка DHCP NAK
решается offer-delay'ем
Re: Неправильная отправка DHCP NAK
если не указан offer-delay accel считает себя единственным сервером и отвечает на все DHCPREQUEST
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Так это не OFFER, это ответ на REQUEST. При чём вообще левый REQUEST, который к конкретно этому серверу даже отношения не имеет - это чужая сессия.
В любом случае, offer-delay указан на обеих серверах (reload-ом обновляется же?).
Я тут ещё другое заметил. Я запретил на одном сервере отправлять NAK-и, но клиент всё равно начинает заново DISCOVER.
Я сделал дамп и увидел: у меня в двух ACK-ах на одном интерфейсе получился разный siaddr . Видимо, поэтому клиент и начинает заново DISCOVER.
При этом в option 54 адрес сервера правильный. Как такое вообще может быть?
Дамп: https://dl.dropboxusercontent.com/u/124 ... iaddr.pcap
Смотреть на 4 и 6 пакеты (два ACK-а).
Адрес, который там вылез (31.41.71.128) есть в таблице маршрутизации (blackhole 31.41.71.128/26 proto zebra), но в accel-ppp (вроде) нигде не фигурирует.
В любом случае, offer-delay указан на обеих серверах (reload-ом обновляется же?).
Я тут ещё другое заметил. Я запретил на одном сервере отправлять NAK-и, но клиент всё равно начинает заново DISCOVER.
Я сделал дамп и увидел: у меня в двух ACK-ах на одном интерфейсе получился разный siaddr . Видимо, поэтому клиент и начинает заново DISCOVER.
При этом в option 54 адрес сервера правильный. Как такое вообще может быть?
Дамп: https://dl.dropboxusercontent.com/u/124 ... iaddr.pcap
Смотреть на 4 и 6 пакеты (два ACK-а).
Адрес, который там вылез (31.41.71.128) есть в таблице маршрутизации (blackhole 31.41.71.128/26 proto zebra), но в accel-ppp (вроде) нигде не фигурирует.
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Во я идиот - это у меня DHCP под NAT попал. Посыпаю голову пеплом, правлю iptables и буду дальше смотреть.
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Нет, всё-таки дело не в NAT-е и не в моих умственных способностях. Есть всё-таки багованные клиенты, которые DHCPREQUEST-ы (на обновление лизы) отправляют броадкастом, а потом обижаются на NAK от второго сервера.
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Сегодня ночью попробую вот такой патч:
Code: Select all
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 197c1a5..64e83df 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -132,6 +132,7 @@ start=dhcpv4
#vlan-name=%I.%N
#ip-pool=ipoe
interface=eth0
+#nak_quirk=1
[dns]
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c
index 936b50e..06a7b24 100644
--- a/accel-pppd/ctrl/ipoe/dhcpv4.c
+++ b/accel-pppd/ctrl/ipoe/dhcpv4.c
@@ -36,6 +36,7 @@ struct dhcpv4_relay_ctx {
static int conf_verbose;
static in_addr_t conf_dns1;
static in_addr_t conf_dns2;
+static int conf_nak_quirk;
static mempool_t pack_pool;
static mempool_t opt_pool;
@@ -781,6 +782,12 @@ out_err:
int dhcpv4_send_nak(struct dhcpv4_serv *serv, struct dhcpv4_packet *req)
{
+
+ if (conf_nak_quirk && req->src_addr == 0 && req->msg_type == DHCPREQUEST) {
+ log_info2("not NAKing broadcast REQUEST\n");
+ return 0;
+ }
+
struct dhcpv4_packet *pack;
int val, r;
@@ -1121,6 +1128,10 @@ static void load_config()
opt = conf_get_opt("dns", "dns2");
if (opt)
conf_dns2 = inet_addr(opt);
+
+ opt = conf_get_opt("ipoe", "nak_quirk");
+ if (opt)
+ conf_nak_quirk = atoi(opt);
}
static void init()
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Dmitry,
А можно ли как-то отсрочить отправку NAK-ов?
Получается такая ситуация: клиент отправляет REQUEST броадкастом (судя по времени - это REBIND request, т.к. RENEW почему-то не доходит), если есть два сервера, то 50 на 50: если первый ответит NAK-ом, то клиент (в моём случае SOHO-роутер) начинает заново DISCOVER.
Насчет логики offer-delay, есть вот такой кусок в ipoe.c:
Вот это как раз мой случай. Сессии на сервере нет, server_id не установлен (прилетает почему-то сразу REBIND; RENEW клиент не присылает), accel-ppp отправляет NAK. До проверки offer-delay дело не доходит.
А можно ли как-то отсрочить отправку NAK-ов?
Получается такая ситуация: клиент отправляет REQUEST броадкастом (судя по времени - это REBIND request, т.к. RENEW почему-то не доходит), если есть два сервера, то 50 на 50: если первый ответит NAK-ом, то клиент (в моём случае SOHO-роутер) начинает заново DISCOVER.
Насчет логики offer-delay, есть вот такой кусок в ipoe.c:
Code: Select all
if (!ses) {
if (conf_verbose) {
log_debug("%s: recv ", serv->ifname);
dhcpv4_print_packet(pack, 0, log_debug);
}
if (!pack->server_id)
dhcpv4_send_nak(dhcpv4, pack);
if (serv->opt_shared == 0)
ipoe_drop_sessions(serv, NULL);
else if (opt82_ses) {
dhcpv4_packet_ref(pack);
triton_context_call(&opt82_ses->ctx, (triton_event_func)mac_change_detected, pack);
} else if (list_empty(&conf_offer_delay) || ipoe_serv_request_check(serv, pack->hdr->xid))
dhcpv4_send_nak(dhcpv4, pack);
- Абрамчук Вадим
- Posts: 75
- Joined: 21 Oct 2014, 20:15
Re: Неправильная отправка DHCP NAK
Хотя это ещё вопрос - а почему не прилетает renew.