summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2016-11-29 17:41:09 +0300
committerDmitry Kozlov <xeb@mail.ru>2016-11-29 17:41:09 +0300
commit01a985316d5240e7a2ba9ba683493cc015282d8a (patch)
tree18968ccea5ebf22e6de4008433e966bb1c1ea9ef /accel-pppd
parent77fb7e670f32ca8967dc0c33e5c78721b08465ef (diff)
downloadaccel-ppp-01a985316d5240e7a2ba9ba683493cc015282d8a.tar.gz
accel-ppp-01a985316d5240e7a2ba9ba683493cc015282d8a.zip
ipoe: do not start UP session by arp request immediately (wait for IP packet)
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 4ec77e9..5a15008 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -627,9 +627,16 @@ static void ipoe_session_start(struct ipoe_session *ses)
char *username;
const char *pass;
- if (ses->dhcpv4_request && conf_verbose) {
- log_ppp_info2("recv ");
- dhcpv4_print_packet(ses->dhcpv4_request, 0, log_ppp_info2);
+ if (conf_verbose) {
+ if (ses->dhcpv4_request) {
+ log_ppp_info2("recv ");
+ dhcpv4_print_packet(ses->dhcpv4_request, 0, log_ppp_info2);
+ } else if (ses->arph) {
+ char addr1[64], addr2[64];
+ u_inet_ntoa(ses->arph->ar_tpa, addr1);
+ u_inet_ntoa(ses->arph->ar_spa, addr2);
+ log_ppp_info2("recv [ARP Request who-has %s tell %s]\n", addr1, addr2);
+ }
}
__sync_add_and_fetch(&stat_starting, 1);
@@ -705,6 +712,24 @@ static void find_gw_addr(struct ipoe_session *ses)
}
}
+static void send_arp_reply(struct ipoe_serv *serv, struct _arphdr *arph)
+{
+ __be32 tpa = arph->ar_tpa;
+
+ if (conf_verbose) {
+ char addr[64];
+ u_inet_ntoa(arph->ar_tpa, addr);
+ log_ppp_info2("send [ARP Reply %s is-at %02x:%02x:%02x:%02x:%02x:%02x]\n", addr,
+ serv->hwaddr[0], serv->hwaddr[1], serv->hwaddr[2], serv->hwaddr[3], serv->hwaddr[4], serv->hwaddr[5]);
+ }
+
+ memcpy(arph->ar_tha, arph->ar_sha, ETH_ALEN);
+ memcpy(arph->ar_sha, serv->hwaddr, ETH_ALEN);
+ arph->ar_tpa = arph->ar_spa;
+ arph->ar_spa = tpa;
+ arp_send(serv->ifindex, arph);
+}
+
static void __ipoe_session_start(struct ipoe_session *ses)
{
if (!ses->yiaddr && ses->serv->dhcpv4) {
@@ -800,11 +825,6 @@ static void __ipoe_session_start(struct ipoe_session *ses)
dhcpv4_packet_free(ses->dhcpv4_request);
ses->dhcpv4_request = NULL;
-
- ses->timer.expire = ipoe_session_timeout;
- ses->timer.period = 0;
- ses->timer.expire_tv.tv_sec = conf_offer_timeout;
- triton_timer_add(&ses->ctx, &ses->timer, 0);
} else {
if (!ses->router)
find_gw_addr(ses);
@@ -826,8 +846,20 @@ static void __ipoe_session_start(struct ipoe_session *ses)
ses->siaddr = ses->router;
- __ipoe_session_activate(ses);
+ if (ses->arph) {
+ send_arp_reply(ses->serv, ses->arph);
+ _free(ses->arph);
+ ses->arph = NULL;
+ } else {
+ __ipoe_session_activate(ses);
+ return;
+ }
}
+
+ ses->timer.expire = ipoe_session_timeout;
+ ses->timer.period = 0;
+ ses->timer.expire_tv.tv_sec = conf_offer_timeout;
+ triton_timer_add(&ses->ctx, &ses->timer, 0);
}
static void make_ipv6_intfid(uint64_t *intfid, const uint8_t *hwaddr)
@@ -846,9 +878,11 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
uint32_t addr, gw = 0;
struct ipoe_serv *serv = ses->serv;
- if (ses->terminating)
+ if (ses->terminating || ses->started)
return;
+ log_ppp_debug("ipoe: activate session\n");
+
if (ses->ifindex != -1) {
addr = 0;
/*if (!ses->ses.ipv4) {
@@ -892,19 +926,6 @@ static void __ipoe_session_activate(struct ipoe_session *ses)
} else
ses->ctrl.dont_ifcfg = 0;
- if (ses->arph) {
- if (ses->arph->ar_tpa == ses->router) {
- memcpy(ses->arph->ar_tha, ses->arph->ar_sha, ETH_ALEN);
- memcpy(ses->arph->ar_sha, ses->serv->hwaddr, ETH_ALEN);
- ses->arph->ar_tpa = ses->arph->ar_spa;
- ses->arph->ar_spa = ses->router;
- arp_send(ses->serv->ifindex, ses->arph);
- }
-
- _free(ses->arph);
- ses->arph = NULL;
- }
-
if (ses->serv->opt_mode == MODE_L2 && ses->serv->opt_ipv6 && sock6_fd != -1) {
ses->ses.ipv6 = ipdb_get_ipv6(&ses->ses);
if (!ses->ses.ipv6)
@@ -1944,13 +1965,14 @@ void ipoe_recv_up(int ifindex, struct ethhdr *eth, struct iphdr *iph, struct _ar
pthread_mutex_lock(&serv->lock);
- if (!serv->opt_shared && !list_empty(&serv->sessions)) {
- pthread_mutex_unlock(&serv->lock);
- break;
- }
-
list_for_each_entry(ses, &serv->sessions, entry) {
if (ses->yiaddr == saddr) {
+ if (arph) {
+ if (!ses->arph)
+ send_arp_reply(serv, arph);
+ } else if (!ses->started)
+ triton_context_call(&ses->ctx, (triton_event_func)__ipoe_session_activate, ses);
+
pthread_mutex_unlock(&serv->lock);
pthread_mutex_unlock(&serv_lock);
return;