From bf5340291badcc631bd855bb924593cd445ecd26 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Fri, 11 Apr 2014 11:08:29 +0400 Subject: net-snmp: run snmp in "special" thread NET-SNMP is built on top of stale file descriptor multiplexing mechanism (select) which prevents to use descriptors with number >= 1024. Due to accel-ppp uses a lots of descriptors NET-SNMP easy overflows this limit and fails and even may crash whole accel-ppp process. This patch runs snmp in special thread which does not share file descritor table with main process, so it can use less descriptors and live in __FD_SETSIZE limit. Signed-off-by: Dmitry Kozlov --- accel-pppd/extra/net-snmp/agent.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'accel-pppd') diff --git a/accel-pppd/extra/net-snmp/agent.c b/accel-pppd/extra/net-snmp/agent.c index cfeb763..2acc6d7 100644 --- a/accel-pppd/extra/net-snmp/agent.c +++ b/accel-pppd/extra/net-snmp/agent.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -26,8 +27,8 @@ static int conf_master = 0; static oid* oid_prefix; static size_t oid_prefix_size;*/ -static pthread_t snmp_thr; static int snmp_term = 0; +static int snmp_pid; /*int accel_ppp_alloc_oid(oid tail, size_t size, oid **oid) { @@ -70,7 +71,7 @@ static int agent_log(int major, int minor, void *serv_arg, void *cl_arg) return 0; } -static void *snmp_thread(void *a) +static int snmp_thread(void *a) { sigset_t set; @@ -107,22 +108,22 @@ static void *snmp_thread(void *a) if (conf_master) init_master_agent(); - while (!snmp_term) { + while (!snmp_term) agent_check_and_process(1); - } snmp_shutdown(conf_agent_name); SOCK_CLEANUP; - return NULL; + return 0; } static void snmp_ctx_close(struct triton_context_t *ctx) { + int status; snmp_term = 1; - pthread_cancel(snmp_thr); - pthread_join(snmp_thr, NULL); + kill(snmp_pid, 32); + waitpid(snmp_pid, &status, 0); triton_context_unregister(ctx); } @@ -146,7 +147,8 @@ static void init(void) if (opt) conf_oid_prefix = opt;*/ - pthread_create(&snmp_thr, NULL, snmp_thread, NULL); + snmp_pid = clone(snmp_thread, malloc(1024*1024) + 1024*1024, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_THREAD, NULL); + triton_context_register(&ctx, NULL); triton_context_wakeup(&ctx); triton_collect_cpu_usage(); -- cgit v1.2.3 From 89917df20ebd975738501b5cfe83e007f71564b0 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Fri, 11 Apr 2014 12:36:09 +0400 Subject: ipoe:lua: update thread-specific value when updating L (fixes segfault) Signed-off-by: Dmitry Kozlov --- accel-pppd/ctrl/ipoe/lua.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'accel-pppd') diff --git a/accel-pppd/ctrl/ipoe/lua.c b/accel-pppd/ctrl/ipoe/lua.c index ab95e41..4fb6380 100644 --- a/accel-pppd/ctrl/ipoe/lua.c +++ b/accel-pppd/ctrl/ipoe/lua.c @@ -204,6 +204,7 @@ out_err: log_ppp_error("ipoe: lua: %s\n", lua_tostring(L, -1)); lua_close(L); L = NULL; + pthread_setspecific(__key, L); } /*static void stackDump (lua_State *L) { @@ -266,6 +267,7 @@ out_err: file_error = 1; lua_close(L); L = NULL; + pthread_setspecific(__key, L); return -1; } -- cgit v1.2.3 From 33bdf4071ab9db915aa069ef69176f3e4b57484e Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Fri, 11 Apr 2014 13:04:54 +0400 Subject: ipoe: early allocate interface for shared vlans (prevents different values of NAS-Port in Access-Request and Account-Request) Signed-off-by: Dmitry Kozlov --- accel-pppd/ctrl/ipoe/ipoe.c | 78 ++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'accel-pppd') diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index ad603f6..50e5932 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -163,6 +163,7 @@ static void __ipoe_recv_dhcpv4(struct dhcpv4_serv *dhcpv4, struct dhcpv4_packet static void ipoe_session_keepalive(struct dhcpv4_packet *pack); static void add_interface(const char *ifname, int ifindex, const char *opt, int parent_ifindex, int vid); static int get_offer_delay(); +static void __ipoe_session_start(struct ipoe_session *ses); static struct ipoe_session *ipoe_session_lookup(struct ipoe_serv *serv, struct dhcpv4_packet *pack, struct ipoe_session **opt82_ses) { @@ -447,13 +448,50 @@ static void ipoe_change_addr(struct ipoe_session *ses, in_addr_t newaddr) } -static void __ipoe_session_start(struct ipoe_session *ses); +static int ipoe_create_interface(struct ipoe_session *ses) +{ + struct unit_cache *uc; + struct ifreq ifr; + + pthread_mutex_lock(&uc_lock); + if (!list_empty(&uc_list)) { + uc = list_entry(uc_list.next, typeof(*uc), entry); + ses->ifindex = uc->ifindex; + list_del(&uc->entry); + --uc_size; + pthread_mutex_unlock(&uc_lock); + mempool_free(uc); + } else { + pthread_mutex_unlock(&uc_lock); + ses->ifindex = ipoe_nl_create(0, 0, ses->serv->opt_mode == MODE_L2 ? ses->serv->ifname : NULL, ses->hwaddr); + if (ses->ifindex == -1) { + log_ppp_error("ipoe: failed to create interface\n"); + ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); + return -1; + } + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = ses->ifindex; + if (ioctl(sock_fd, SIOCGIFNAME, &ifr, sizeof(ifr))) { + log_ppp_error("ipoe: failed to get interface name\n"); + ses->ifindex = -1; + ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); + return -1; + } + + strncpy(ses->ses.ifname, ifr.ifr_name, AP_IFNAME_LEN); + ses->ses.ifindex = ses->ifindex; + ses->ses.unit_idx = ses->ifindex; + ses->ctrl.dont_ifcfg = 0; + + return 0; +} + static void ipoe_session_start(struct ipoe_session *ses) { int r; char *passwd; - struct ifreq ifr; - struct unit_cache *uc; __sync_add_and_fetch(&stat_starting, 1); @@ -476,6 +514,9 @@ static void ipoe_session_start(struct ipoe_session *ses) ap_session_starting(&ses->ses); if (!conf_noauth) { + if (ses->serv->opt_shared && ipoe_create_interface(ses)) + return; + r = pwdb_check(&ses->ses, ses->ses.username, PPP_PAP, conf_password ? conf_password : ses->ses.username); if (r == PWDB_NO_IMPL) { passwd = pwdb_get_passwd(&ses->ses, ses->ses.username); @@ -509,37 +550,8 @@ static void ipoe_session_start(struct ipoe_session *ses) strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN); ses->ses.ifindex = ses->serv->ifindex; } else if (ses->ifindex == -1) { - pthread_mutex_lock(&uc_lock); - if (!list_empty(&uc_list)) { - uc = list_entry(uc_list.next, typeof(*uc), entry); - ses->ifindex = uc->ifindex; - list_del(&uc->entry); - --uc_size; - pthread_mutex_unlock(&uc_lock); - mempool_free(uc); - } else { - pthread_mutex_unlock(&uc_lock); - ses->ifindex = ipoe_nl_create(0, 0, ses->serv->opt_mode == MODE_L2 ? ses->serv->ifname : NULL, ses->hwaddr); - if (ses->ifindex == -1) { - log_ppp_error("ipoe: failed to create interface\n"); - ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); - return; - } - } - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = ses->ifindex; - if (ioctl(sock_fd, SIOCGIFNAME, &ifr, sizeof(ifr))) { - log_ppp_error("ipoe: failed to get interface name\n"); - ses->ifindex = -1; - ap_session_terminate(&ses->ses, TERM_NAS_ERROR, 1); + if (ipoe_create_interface(ses)) return; - } - - strncpy(ses->ses.ifname, ifr.ifr_name, AP_IFNAME_LEN); - ses->ses.ifindex = ses->ifindex; - ses->ses.unit_idx = ses->ifindex; - ses->ctrl.dont_ifcfg = 0; } ap_session_set_ifindex(&ses->ses); -- cgit v1.2.3