summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-10-20 16:48:12 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-10-20 16:48:12 +0400
commitbaae559b6234f30fdb93697ae74833b678c94b5b (patch)
treebe1544fd56918ab1c85d8855d6ed3f4f02c46b3b
parent62a3372e720615b25512b0a05b67e078532507ec (diff)
downloadaccel-ppp-baae559b6234f30fdb93697ae74833b678c94b5b.tar.gz
accel-ppp-baae559b6234f30fdb93697ae74833b678c94b5b.zip
ipoe: handle dhcp requests in session context if exists
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c183
1 files changed, 108 insertions, 75 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 483ea7f..ac26b41 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -549,6 +549,11 @@ static void ipoe_session_start(struct ipoe_session *ses)
int r;
char *passwd;
char *username;
+
+ if (ses->dhcpv4_request && conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(ses->dhcpv4_request, 0, log_ppp_info2);
+ }
__sync_add_and_fetch(&stat_starting, 1);
@@ -1133,6 +1138,8 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s
if (serv->timer.tpd)
triton_timer_del(&serv->timer);
+
+ dhcpv4_packet_ref(pack);
triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_start, ses);
@@ -1233,6 +1240,52 @@ static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packe
}
}
+static void ipoe_ses_recv_dhcpv4_discover(struct dhcpv4_packet *pack)
+{
+ struct ipoe_session *ses = container_of(triton_context_self(), typeof(*ses), ctx);
+
+ if (conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(pack, 0, log_ppp_info2);
+ }
+
+ if (ses->yiaddr)
+ dhcpv4_send_reply(DHCPOFFER, ses->serv->dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->dhcpv4_relay_reply);
+
+ dhcpv4_packet_free(pack);
+}
+
+static void ipoe_ses_recv_dhcpv4_request(struct dhcpv4_packet *pack)
+{
+ struct ipoe_session *ses = container_of(triton_context_self(), typeof(*ses), ctx);
+
+ ses->xid = pack->hdr->xid;
+
+ if (conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(pack, 0, log_ppp_info2);
+ }
+
+ if ((pack->server_id && (pack->server_id != ses->siaddr || pack->request_ip != ses->yiaddr)) ||
+ (pack->hdr->ciaddr && (pack->hdr->ciaddr != ses->yiaddr))) {
+
+ if (pack->server_id == ses->siaddr)
+ dhcpv4_send_nak(ses->serv->dhcpv4, pack);
+
+ ap_session_terminate(&ses->ses, TERM_USER_REQUEST, 0);
+
+ dhcpv4_packet_free(pack);
+ return;
+ }
+
+ if (ses->ses.state == AP_STATE_STARTING && ses->yiaddr)
+ ipoe_session_activate(pack);
+ else if (ses->ses.state == AP_STATE_ACTIVE)
+ ipoe_session_keepalive(pack);
+ else
+ dhcpv4_packet_free(pack);
+}
+
static void ipoe_serv_disc_timer(struct triton_timer_t *t)
{
struct ipoe_serv *serv = container_of(t, typeof(*serv), disc_timer);
@@ -1346,6 +1399,38 @@ static int ipoe_serv_request_check(struct ipoe_serv *serv, uint32_t xid)
return 0;
}
+static void port_change_detected(struct dhcpv4_packet *pack)
+{
+ struct ipoe_session *ses = container_of(triton_context_self(), typeof(*ses), ctx);
+
+ if (conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(pack, 0, log_ppp_info2);
+ }
+
+ dhcpv4_packet_free(pack);
+
+ log_ppp_warn("port change detected\n");
+
+ ap_session_terminate(&ses->ses, TERM_USER_REQUEST, 0);
+}
+
+static void mac_change_detected(struct dhcpv4_packet *pack)
+{
+ struct ipoe_session *ses = container_of(triton_context_self(), typeof(*ses), ctx);
+
+ if (conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(pack, 0, log_ppp_info2);
+ }
+
+ dhcpv4_packet_free(pack);
+
+ log_ppp_warn("mac change detected\n");
+
+ ap_session_terminate(&ses->ses, TERM_USER_REQUEST, 0);
+}
+
static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack, int force)
{
struct ipoe_serv *serv = container_of(dhcpv4->ctx, typeof(*serv), ctx);
@@ -1369,10 +1454,8 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
if (serv->opt_shared == 0)
ipoe_drop_sessions(serv, NULL);
else if (opt82_ses) {
- if (conf_verbose)
- log_ppp_warn("mac change detected\n");
-
- triton_context_call(&opt82_ses->ctx, (triton_event_func)__ipoe_session_terminate, &opt82_ses->ses);
+ dhcpv4_packet_ref(pack);
+ triton_context_call(&opt82_ses->ctx, (triton_event_func)mac_change_detected, pack);
}
offer_delay = get_offer_delay();
@@ -1385,37 +1468,17 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
}
ses = ipoe_session_create_dhcpv4(serv, pack);
- if (ses) {
- dhcpv4_packet_ref(pack);
-
- if (conf_verbose) {
- log_switch(dhcpv4->ctx, &ses->ses);
- log_ppp_info2("recv ");
- dhcpv4_print_packet(pack, 0, log_ppp_info2);
- }
- }
} else {
if ((opt82_ses && ses != opt82_ses) || (!opt82_ses && pack->relay_agent)) {
- if (conf_verbose) {
- log_switch(dhcpv4->ctx, &ses->ses);
- log_ppp_info2("recv ");
- dhcpv4_print_packet(pack, 0, log_ppp_info2);
- log_ppp_warn("port change detected\n");
- }
-
- triton_context_call(&ses->ctx, (triton_event_func)__ipoe_session_terminate, &ses->ses);
+ dhcpv4_packet_ref(pack);
+ triton_context_call(&ses->ctx, (triton_event_func)port_change_detected, pack);
+ if (opt82_ses)
+ triton_context_call(&opt82_ses->ctx, (triton_event_func)__ipoe_session_terminate, &opt82_ses->ses);
goto out;
}
-
- log_switch(dhcpv4->ctx, &ses->ses);
-
- if (conf_verbose) {
- log_ppp_info2("recv ");
- dhcpv4_print_packet(pack, 0, log_ppp_info2);
- }
-
- if (ses->yiaddr)
- dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->dhcpv4_relay_reply);
+
+ dhcpv4_packet_ref(pack);
+ 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);
@@ -1434,54 +1497,24 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet
if (serv->opt_shared == 0)
ipoe_drop_sessions(serv, NULL);
else if (opt82_ses) {
- if (conf_verbose) {
- log_switch(dhcpv4->ctx, &opt82_ses->ses);
- log_ppp_warn("mac change detected\n");
- }
-
- triton_context_call(&opt82_ses->ctx, (triton_event_func)__ipoe_session_terminate, &opt82_ses->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);
} else {
- ses->xid = pack->hdr->xid;
-
- if ((pack->server_id && (pack->server_id != ses->siaddr || pack->request_ip != ses->yiaddr)) ||
- (pack->hdr->ciaddr && (pack->hdr->xid != ses->xid || pack->hdr->ciaddr != ses->yiaddr)) ||
- (opt82_ses && ses != opt82_ses) || (!opt82_ses && pack->relay_agent)) {
-
- if (conf_verbose) {
- log_switch(dhcpv4->ctx, &ses->ses);
- log_ppp_info2("recv ");
- dhcpv4_print_packet(pack, 0, log_ppp_info2);
- if ((opt82_ses && ses != opt82_ses) || (!opt82_ses && pack->relay_agent))
- log_ppp_warn("port change detected\n");
- }
-
- if (pack->server_id == ses->siaddr)
- dhcpv4_send_nak(dhcpv4, pack);
-
- if (ses->serv->dhcpv4_relay)
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id);
-
- triton_context_call(&ses->ctx, (triton_event_func)__ipoe_session_terminate, &ses->ses);
- } else {
- if (conf_verbose) {
- log_switch(dhcpv4->ctx, &ses->ses);
- log_ppp_info2("recv ");
- dhcpv4_print_packet(pack, 0, log_ppp_info2);
- }
-
- if (serv->opt_shared == 0)
- ipoe_drop_sessions(serv, ses);
-
- if (ses->ses.state == AP_STATE_STARTING && ses->yiaddr) {
- dhcpv4_packet_ref(pack);
- triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_activate, pack);
- } else if (ses->ses.state == AP_STATE_ACTIVE) {
- dhcpv4_packet_ref(pack);
- triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_keepalive, pack);
- }
+ if ((opt82_ses && ses != opt82_ses) || (!opt82_ses && pack->relay_agent)) {
+ dhcpv4_packet_ref(pack);
+ triton_context_call(&ses->ctx, (triton_event_func)port_change_detected, pack);
+ if (opt82_ses)
+ triton_context_call(&opt82_ses->ctx, (triton_event_func)__ipoe_session_terminate, &opt82_ses->ses);
+ goto out;
}
+
+ if (serv->opt_shared == 0)
+ ipoe_drop_sessions(serv, ses);
+
+ dhcpv4_packet_ref(pack);
+ triton_context_call(&ses->ctx, (triton_event_func)ipoe_ses_recv_dhcpv4_request, pack);
}
} else if (pack->msg_type == DHCPDECLINE || pack->msg_type == DHCPRELEASE) {
ses = ipoe_session_lookup(serv, pack, &opt82_ses);