summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2013-04-22 20:53:38 +0400
committerDmitry Kozlov <xeb@mail.ru>2013-04-22 20:53:38 +0400
commitfc503382df18bf579375ee22d78184d7dcfaea9e (patch)
tree151c4872214c7b328f684da7ff8718eef99e6caa /accel-pppd/ctrl
parent2a2012bec51d58b05f508f0c79819d48392824ea (diff)
downloadaccel-ppp-xebd-fc503382df18bf579375ee22d78184d7dcfaea9e.tar.gz
accel-ppp-xebd-fc503382df18bf579375ee22d78184d7dcfaea9e.zip
ipoe: start dhcp socket on ipoe interfaces for unicast dhcp messages
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c68
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h1
2 files changed, 63 insertions, 6 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 46c5372..8044ad0 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -123,6 +123,7 @@ static void ipoe_session_finished(struct ap_session *s);
static void ipoe_drop_sessions(struct ipoe_serv *serv, struct ipoe_session *skip);
static void ipoe_serv_close(struct triton_context_t *ctx);
static void __ipoe_session_activate(struct ipoe_session *ses);
+static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack);
static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct dhcpv4_packet *pack)
{
@@ -331,8 +332,7 @@ static void ipoe_session_start(struct ipoe_session *ses)
struct unit_cache *uc;
if (!ses->ses.username) {
- if (!ses->serv->opt_shared)
- strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
+ strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
ipoe_session_set_username(ses);
@@ -584,9 +584,12 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
if (ses->ifindex != -1) {
addr = 0;
- if (!ses->ses.ipv4)
- addr = 1;
- else if (ses->ses.ipv4->peer_addr != ses->yiaddr)
+ if (!ses->ses.ipv4) {
+ if (ses->serv->opt_mode == MODE_L3) {
+ addr = 1;
+ ses->ctrl.dont_ifcfg = 1;
+ }
+ } else if (ses->ses.ipv4->peer_addr != ses->yiaddr)
addr = ses->ses.ipv4->peer_addr;
if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, addr, NULL, NULL)) {
@@ -687,6 +690,15 @@ static void ipoe_session_started(struct ap_session *s)
if (ses->timer.tpd)
triton_timer_mod(&ses->timer, 0);
+
+ if (ses->ifindex != -1 && ses->xid) {
+ ses->dhcpv4 = dhcpv4_create(ses->ctrl.ctx, ses->ses.ifname, "");
+ if (!ses->dhcpv4) {
+ //terminate
+ return;
+ }
+ ses->dhcpv4->recv = ipoe_ses_recv_dhcpv4;
+ }
}
static void ipoe_session_free(struct ipoe_session *ses)
@@ -748,6 +760,9 @@ static void ipoe_session_finished(struct ap_session *s)
if (serv_close)
ipoe_serv_close(&ses->serv->ctx);
+
+ if (ses->dhcpv4)
+ dhcpv4_free(ses->dhcpv4);
triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_free, ses);
}
@@ -869,6 +884,48 @@ static void __ipoe_session_terminate(struct ap_session *ses)
ap_session_terminate(ses, TERM_USER_REQUEST, 0);
}
+static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack)
+{
+ struct ipoe_session *ses = container_of(dhcpv4->ctx, typeof(*ses), ctx);
+
+ if (ap_shutdown)
+ return;
+
+ if (conf_verbose) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(pack, 0, log_info2);
+ }
+
+ if (pack->msg_type == DHCPDISCOVER) {
+ if (ses->yiaddr) {
+ if (ses->serv->dhcpv4_relay) {
+ dhcpv4_packet_ref(pack);
+ triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_keepalive, pack);
+ } else
+ dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->router, ses->mask, ses->lease_time, ses->dhcpv4_relay_reply);
+ }
+ } else if (pack->msg_type == DHCPREQUEST) {
+ if (pack->hdr->ciaddr == ses->yiaddr && pack->hdr->xid != ses->xid)
+ 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))) {
+
+ if (pack->server_id == ses->siaddr)
+ dhcpv4_send_nak(dhcpv4, pack);
+ else if (ses->serv->dhcpv4_relay)
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, pack, 0, ses->serv->ifname, conf_agent_remote_id);
+
+ ap_session_terminate(&ses->ses, TERM_USER_REQUEST, 0);
+ } else {
+ dhcpv4_packet_ref(pack);
+ ipoe_session_keepalive(pack);
+ }
+ } else if (pack->msg_type == DHCPDECLINE || pack->msg_type == DHCPRELEASE) {
+ dhcpv4_packet_ref(pack);
+ ipoe_session_decline(pack);
+ }
+}
+
static void ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack)
{
struct ipoe_serv *serv = container_of(dhcpv4->ctx, typeof(*serv), ctx);
@@ -882,7 +939,6 @@ static void ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *p
if (pack->msg_type == DHCPDISCOVER) {
ses = ipoe_session_lookup(serv, pack);
if (!ses) {
-
if (serv->opt_shared == 0)
ipoe_drop_sessions(serv, NULL);
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index bb5841e..96920a3 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -35,6 +35,7 @@ struct ipoe_session
struct triton_context_t ctx;
struct triton_timer_t timer;
struct ipoe_serv *serv;
+ struct dhcpv4_serv *dhcpv4;
struct ap_ctrl ctrl;
struct ap_session ses;
uint8_t hwaddr[6];