diff options
Diffstat (limited to 'accel-pppd/ctrl/ipoe/ipoe.c')
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index bfe65fb..b961ef8 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -102,18 +102,12 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d if (pack->agent_remote_id && !ses->agent_remote_id) continue; - if (pack->client_id && !ses->client_id) - continue; - if (!pack->agent_circuit_id && ses->agent_circuit_id) continue; if (!pack->agent_remote_id && ses->agent_remote_id) continue; - if (!pack->client_id && ses->client_id) - continue; - if (pack->agent_circuit_id) { if (pack->agent_circuit_id->len != ses->agent_circuit_id->len) continue; @@ -126,8 +120,17 @@ static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct d continue; if (memcmp(pack->agent_remote_id->data, ses->agent_remote_id->data, pack->agent_remote_id->len)) continue; + + return ses; } + if (pack->client_id && !ses->client_id) + continue; + + if (!pack->client_id && ses->client_id) + continue; + + if (pack->client_id) { if (pack->client_id->len != ses->client_id->len) continue; @@ -258,8 +261,17 @@ static void ipoe_session_start(struct ipoe_session *ses) else if (!ses->ses.ipv4->mask) ses->ses.ipv4->mask = 24; + if (!ses->yiaddr) + ses->yiaddr = ses->ses.ipv4->peer_addr; + + if (!ses->siaddr) + ses->siaddr = ses->ses.ipv4->addr; + + if (!ses->mask) + ses->mask = 24; + if (ses->dhcpv4_request) { - dhcpv4_send_reply(DHCPOFFER, ses->serv->dhcpv4, ses->dhcpv4_request, &ses->ses, conf_lease_time); + dhcpv4_send_reply(DHCPOFFER, ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->mask, conf_lease_time); dhcpv4_packet_free(ses->dhcpv4_request); ses->dhcpv4_request = NULL; @@ -268,7 +280,7 @@ static void ipoe_session_start(struct ipoe_session *ses) ses->timer.expire_tv.tv_sec = conf_offer_timeout; triton_timer_add(&ses->ctx, &ses->timer, 0); } else { - if (ipoe_nl_modify(ses->ifindex, ses->giaddr, ses->ses.ipv4->peer_addr, NULL, NULL)) + if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, ses->ses.ipv4->peer_addr, NULL, NULL)) ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 0); else ap_session_activate(&ses->ses); @@ -277,11 +289,18 @@ static void ipoe_session_start(struct ipoe_session *ses) static void ipoe_session_activate(struct ipoe_session *ses) { + if (ses->ifindex != -1) { + if (ipoe_nl_modify(ses->ifindex, ses->yiaddr, ses->ses.ipv4->peer_addr, NULL, NULL)) { + ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 0); + return; + } + } + ap_session_activate(&ses->ses); if (ses->dhcpv4_request) { if (ses->ses.state == AP_STATE_ACTIVE) - dhcpv4_send_reply(DHCPACK, ses->serv->dhcpv4, ses->dhcpv4_request, &ses->ses, conf_lease_time); + dhcpv4_send_reply(DHCPACK, ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->mask, conf_lease_time); else dhcpv4_send_nak(ses->serv->dhcpv4, ses->dhcpv4_request); @@ -298,7 +317,7 @@ static void ipoe_session_keepalive(struct ipoe_session *ses) ses->xid = ses->dhcpv4_request->hdr->xid; if (ses->ses.state == AP_STATE_ACTIVE) - dhcpv4_send_reply(DHCPACK, ses->serv->dhcpv4, ses->dhcpv4_request, &ses->ses, conf_lease_time); + dhcpv4_send_reply(DHCPACK, ses->serv->dhcpv4, ses->dhcpv4_request, ses->yiaddr, ses->siaddr, ses->mask, conf_lease_time); else dhcpv4_send_nak(ses->serv->dhcpv4, ses->dhcpv4_request); @@ -366,6 +385,9 @@ static void ipoe_session_finished(struct ap_session *s) serv_close = ses->serv->need_close && list_empty(&ses->serv->sessions); pthread_mutex_unlock(&ses->serv->lock); + if (ses->yiaddr && ses->serv->dhcpv4 && ses->serv->dhcpv4->range) + dhcpv4_put_ip(ses->serv->dhcpv4, ses->yiaddr); + if (serv_close) ipoe_serv_close(&ses->serv->ctx); @@ -412,6 +434,8 @@ static struct ipoe_session *ipoe_session_create_dhcpv4(struct ipoe_serv *serv, s memcpy(ses->hwaddr, pack->hdr->chaddr, 6); ses->giaddr = pack->hdr->giaddr; + dhcpv4_get_ip(serv->dhcpv4, &ses->yiaddr, &ses->siaddr, &ses->mask); + if (pack->agent_circuit_id) dlen += sizeof(struct dhcp_opt) + pack->agent_circuit_id->len; @@ -513,7 +537,7 @@ static void ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *p } if (ses->ses.ipv4 && ses->ses.state == AP_STATE_ACTIVE && pack->request_ip == ses->ses.ipv4->peer_addr) - dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, &ses->ses, conf_lease_time); + dhcpv4_send_reply(DHCPOFFER, dhcpv4, pack, ses->yiaddr, ses->siaddr, ses->mask, conf_lease_time); dhcpv4_packet_free(pack); } @@ -528,16 +552,15 @@ static void ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *p dhcpv4_send_nak(dhcpv4, pack); } else { - if (!ses->ses.ipv4 || - (pack->server_id && (pack->server_id != ses->ses.ipv4->addr || pack->request_ip != ses->ses.ipv4->peer_addr)) || - (pack->hdr->ciaddr && (pack->hdr->xid != ses->xid || pack->hdr->ciaddr != ses->ses.ipv4->peer_addr))) { + 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 (conf_verbose) { log_info2("recv "); dhcpv4_print_packet(pack, log_info2); } - if (ses->ses.ipv4 && pack->server_id == ses->ses.ipv4->addr && pack->request_ip && pack->request_ip != ses->ses.ipv4->peer_addr) + if (pack->server_id == ses->siaddr && pack->request_ip && pack->request_ip != ses->yiaddr) dhcpv4_send_nak(dhcpv4, pack); ap_session_terminate(&ses->ses, TERM_USER_REQUEST, 0); @@ -611,7 +634,7 @@ static struct ipoe_session *ipoe_session_create_up(struct ipoe_serv *serv, struc ses->ctrl.type = CTRL_TYPE_IPOE; ses->ctrl.name = "ipoe"; - ses->giaddr = iph->saddr; + ses->yiaddr = iph->saddr; ses->ctrl.calling_station_id = _malloc(17); ses->ctrl.called_station_id = _malloc(17); @@ -682,7 +705,7 @@ void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph) pthread_mutex_lock(&serv->lock); list_for_each_entry(ses, &serv->sessions, entry) { - if (ses->giaddr == iph->saddr) { + if (ses->yiaddr == iph->saddr) { pthread_mutex_unlock(&serv->lock); return; } @@ -812,8 +835,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) opt_mode = MODE_L3; else goto parse_err; - } else - goto parse_err; + } if (end) break; @@ -842,7 +864,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) } if (opt_dhcpv4 && !serv->dhcpv4) { - serv->dhcpv4 = dhcpv4_create(&serv->ctx, serv->ifname); + serv->dhcpv4 = dhcpv4_create(&serv->ctx, serv->ifname, opt); if (serv->dhcpv4) serv->dhcpv4->recv = ipoe_recv_dhcpv4; } else if (!opt_dhcpv4 && serv->dhcpv4) { @@ -872,7 +894,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt) triton_context_register(&serv->ctx, NULL); if (serv->opt_dhcpv4) { - serv->dhcpv4 = dhcpv4_create(&serv->ctx, serv->ifname); + serv->dhcpv4 = dhcpv4_create(&serv->ctx, serv->ifname, opt); if (serv->dhcpv4) serv->dhcpv4->recv = ipoe_recv_dhcpv4; } |