summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2018-01-25 12:44:16 +0300
committerDmitry Kozlov <xeb@mail.ru>2018-01-25 12:44:26 +0300
commit01c7b7c8e9cb16a3ac1d18049e687856b552b57c (patch)
treef305a6cd5b416bd70d111ae1928f282220ab4c0e
parent8b265c99a14ad6c7f3eeb59a8cff56870eb5f592 (diff)
downloadaccel-ppp-xebd-01c7b7c8e9cb16a3ac1d18049e687856b552b57c.tar.gz
accel-ppp-xebd-01c7b7c8e9cb16a3ac1d18049e687856b552b57c.zip
ipoe: improved handling of DHCP Request for nonexistent sessions
Send NAK only to unicast requests or if requested Server-ID matches one of gw-ip-address
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 2be0f25..9e0b9ea 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -731,6 +731,18 @@ static void find_gw_addr(struct ipoe_session *ses)
}
}
+static int check_server_id(in_addr_t addr)
+{
+ struct gw_addr *a;
+
+ list_for_each_entry(a, &conf_gw_addr, entry) {
+ if (a->addr == addr)
+ return 1;
+ }
+
+ return 0;
+}
+
static void send_arp_reply(struct ipoe_serv *serv, struct _arphdr *arph)
{
__be32 tpa = arph->ar_tpa;
@@ -1589,7 +1601,7 @@ static void ipoe_serv_add_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pac
}
}
-static void ipoe_serv_check_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pack)
+static int ipoe_serv_check_disc(struct ipoe_serv *serv, struct dhcpv4_packet *pack)
{
struct disc_item *d;
@@ -1606,8 +1618,10 @@ static void ipoe_serv_check_disc(struct ipoe_serv *serv, struct dhcpv4_packet *p
__sync_sub_and_fetch(&stat_delayed_offer, 1);
- break;
+ return 1;
}
+
+ return 0;
}
static int ipoe_serv_request_check(struct ipoe_serv *serv, uint32_t xid)
@@ -1620,7 +1634,10 @@ static int ipoe_serv_request_check(struct ipoe_serv *serv, uint32_t xid)
list_for_each_safe(pos, n, &serv->req_list) {
r = list_entry(pos, typeof(*r), entry);
- if (r->xid == xid) {
+ if (ts.tv_sec > r->expire) {
+ list_del(&r->entry);
+ mempool_free(r);
+ } else if (r->xid == xid) {
if (++r->cnt == conf_max_request) {
list_del(&r->entry);
mempool_free(r);
@@ -1630,11 +1647,6 @@ static int ipoe_serv_request_check(struct ipoe_serv *serv, uint32_t xid)
r->expire = ts.tv_sec + 30;
return 0;
}
-
- if (ts.tv_sec > r->expire) {
- list_del(&r->entry);
- mempool_free(r);
- }
}
r = mempool_alloc(req_item_pool);
@@ -1769,7 +1781,8 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
triton_context_call(&ses->ctx, (triton_event_func)ipoe_ses_recv_dhcpv4_discover, pack);
}
} else if (pack->msg_type == DHCPREQUEST) {
- ipoe_serv_check_disc(serv, pack);
+ if (ipoe_serv_check_disc(serv, pack))
+ goto out;
ses = ipoe_session_lookup(serv, pack, &opt82_ses);
@@ -1779,15 +1792,24 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
dhcpv4_print_packet(pack, 0, log_debug);
}
- if (!pack->server_id)
+ if (pack->src_addr) {
dhcpv4_send_nak(dhcpv4, pack);
+ goto out;
+ }
+
+ if (pack->server_id) {
+ if (check_server_id(pack->server_id)) {
+ dhcpv4_send_nak(dhcpv4, pack);
+ goto out;
+ }
+ }
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))
+ } else if (ipoe_serv_request_check(serv, pack->hdr->xid))
dhcpv4_send_nak(dhcpv4, pack);
} else {
if (ses->terminate) {