From 01c7b7c8e9cb16a3ac1d18049e687856b552b57c Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Thu, 25 Jan 2018 12:44:16 +0300 Subject: 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 --- accel-pppd/ctrl/ipoe/ipoe.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 2be0f25d..9e0b9eae 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) { -- cgit v1.2.3