diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2013-09-05 10:29:40 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-09-05 10:29:40 +0400 |
commit | 3f1680f8c6a27b942796f2f558f700abe93d12ca (patch) | |
tree | c8df688c1b550d57594503b1607d978d5046c746 /accel-pppd/ctrl/ipoe | |
parent | 61d2782551b0f90cd8c3611a0781f029e7fcd2a7 (diff) | |
download | accel-ppp-3f1680f8c6a27b942796f2f558f700abe93d12ca.tar.gz accel-ppp-3f1680f8c6a27b942796f2f558f700abe93d12ca.zip |
ipoe: delay vlan removing
Diffstat (limited to 'accel-pppd/ctrl/ipoe')
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index c6e9757..4edafcb 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -112,7 +112,7 @@ static int conf_attr_l4_redirect; static int conf_l4_redirect_table; static int conf_l4_redirect_on_reject; static const char *conf_l4_redirect_ipset; -static int conf_vlan_timeout = 10; +static int conf_vlan_timeout = 30; static const char *conf_relay; @@ -152,7 +152,7 @@ static struct triton_context_t l4_redirect_ctx; 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_serv_release(struct ipoe_serv *serv); static void __ipoe_session_activate(struct ipoe_session *ses); static void ipoe_ses_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack); static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet *pack, int force); @@ -877,14 +877,14 @@ static void ipoe_session_free(struct ipoe_session *ses) static void ipoe_session_finished(struct ap_session *s) { struct ipoe_session *ses = container_of(s, typeof(*ses), ses); - int serv_close; struct unit_cache *uc; log_ppp_info1("ipoe: session finished\n"); pthread_mutex_lock(&ses->serv->lock); list_del(&ses->entry); - serv_close = (ses->serv->vid || ses->serv->need_close) && list_empty(&ses->serv->sessions); + if ((ses->serv->vid || ses->serv->need_close) && list_empty(&ses->serv->sessions)) + triton_context_call(&ses->serv->ctx, (triton_event_func)ipoe_serv_release, ses->serv); pthread_mutex_unlock(&ses->serv->lock); if (ses->ifindex != -1) { @@ -907,9 +907,6 @@ static void ipoe_session_finished(struct ap_session *s) if (ses->ifcfg) ipoe_ifcfg_del(ses); - - if (serv_close) - ipoe_serv_close(&ses->serv->ctx); if (ses->dhcpv4) dhcpv4_free(ses->dhcpv4); @@ -1212,6 +1209,9 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet int offer_delay; //struct dhcpv4_packet *reply; + if (serv->timer.tpd) + triton_timer_mod(&serv->timer, 0); + if (ap_shutdown) return; @@ -1644,18 +1644,24 @@ static void ev_radius_coa(struct ev_radius_t *ev) } #endif -static void ipoe_serv_close(struct triton_context_t *ctx) +static void ipoe_serv_release(struct ipoe_serv *serv) { - struct ipoe_serv *serv = container_of(ctx, typeof(*serv), ctx); - pthread_mutex_lock(&serv->lock); if (!list_empty(&serv->sessions)) { - serv->need_close = 1; pthread_mutex_unlock(&serv->lock); return; } pthread_mutex_unlock(&serv->lock); - + + if (serv->vid && !serv->need_close) { + if (serv->timer.tpd) + triton_timer_mod(&serv->timer, 0); + else + triton_timer_add(&serv->ctx, &serv->timer, 0); + + return; + } + log_info2("ipoe: stop interface %s\n", serv->ifname); pthread_mutex_lock(&serv_lock); @@ -1693,12 +1699,27 @@ static void ipoe_serv_close(struct triton_context_t *ctx) ipoe_nl_add_vlan_mon_vid(serv->parent_ifindex, serv->vid); } - triton_context_unregister(ctx); + triton_context_unregister(&serv->ctx); _free(serv->ifname); _free(serv); } +static void ipoe_serv_close(struct triton_context_t *ctx) +{ + struct ipoe_serv *serv = container_of(ctx, typeof(*serv), ctx); + + pthread_mutex_lock(&serv->lock); + if (!list_empty(&serv->sessions)) { + serv->need_close = 1; + pthread_mutex_unlock(&serv->lock); + return; + } + pthread_mutex_unlock(&serv->lock); + + ipoe_serv_release(serv); +} + static void l4_redirect_ctx_close(struct triton_context_t *ctx) { struct l4_redirect *n; @@ -1876,7 +1897,9 @@ static void ipoe_serv_timeout(struct triton_timer_t *t) { struct ipoe_serv *serv = container_of(t, typeof(*serv), timer); - ipoe_serv_close(&serv->ctx); + serv->need_close = 1; + + ipoe_serv_release(serv); } static void add_interface(const char *ifname, int ifindex, const char *opt, int parent_ifindex, int vid) @@ -2189,9 +2212,9 @@ static void load_interfaces(struct conf_sect_t *sect) } list_for_each_entry(serv, &serv_list, entry) { - if (!serv->active) { + if (!serv->active && !serv->vid) { ipoe_drop_sessions(serv, NULL); - triton_context_call(&serv->ctx, (triton_event_func)ipoe_serv_close, &serv->ctx); + triton_context_call(&serv->ctx, (triton_event_func)ipoe_serv_release, serv); } } } @@ -2726,6 +2749,12 @@ static void load_config(void) else conf_proto = 3; + opt = conf_get_opt("ipoe", "vlan-timeout"); + if (opt && atoi(opt) > 0) + conf_vlan_timeout = atoi(opt); + else + conf_vlan_timeout = 60; + #ifdef RADIUS if (triton_module_loaded("radius")) load_radius_attrs(); |