diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2013-09-05 17:09:20 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2013-09-05 17:09:20 +0400 |
commit | 5f8334da2d874e0be028ad03376574de1598f0cd (patch) | |
tree | d0fd8cc67721edb11514e8b93449620df478c00b /accel-pppd/ctrl | |
parent | b7f3774031f043bc0c16bc0f5d030a6b7fe4e611 (diff) | |
download | accel-ppp-5f8334da2d874e0be028ad03376574de1598f0cd.tar.gz accel-ppp-5f8334da2d874e0be028ad03376574de1598f0cd.zip |
ipoe: various bug fixes
Diffstat (limited to 'accel-pppd/ctrl')
-rw-r--r-- | accel-pppd/ctrl/ipoe/dhcpv4.c | 17 | ||||
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 64 |
2 files changed, 57 insertions, 24 deletions
diff --git a/accel-pppd/ctrl/ipoe/dhcpv4.c b/accel-pppd/ctrl/ipoe/dhcpv4.c index f5408b08..fa763445 100644 --- a/accel-pppd/ctrl/ipoe/dhcpv4.c +++ b/accel-pppd/ctrl/ipoe/dhcpv4.c @@ -41,6 +41,7 @@ static mempool_t pack_pool; static mempool_t opt_pool; static LIST_HEAD(relay_list); +static pthread_mutex_t relay_lock = PTHREAD_MUTEX_INITIALIZER; static int dhcpv4_read(struct triton_md_handler_t *h); int dhcpv4_packet_add_opt(struct dhcpv4_packet *pack, int type, const void *data, int len); @@ -838,6 +839,7 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, laddr.sin_addr.s_addr = giaddr; laddr.sin_port = htons(DHCP_SERV_PORT); + pthread_mutex_lock(&relay_lock); list_for_each_entry(r, &relay_list, entry) { if (r->addr == addr && r->giaddr == giaddr) goto found; @@ -852,7 +854,7 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!sock) { log_error("socket: %s\n", strerror(errno)); - goto out_err; + goto out_err_unlock; } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &f, sizeof(f))) @@ -860,12 +862,12 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, if (bind(sock, &laddr, sizeof(laddr))) { log_error("dhcpv4: relay: %s: bind: %s\n", _addr, strerror(errno)); - goto out_err; + goto out_err_unlock; } if (connect(sock, &raddr, sizeof(raddr))) { log_error("dhcpv4: relay: %s: connect: %s\n", _addr, strerror(errno)); - goto out_err; + goto out_err_unlock; } fcntl(sock, F_SETFL, O_NONBLOCK); @@ -875,7 +877,7 @@ struct dhcpv4_relay *dhcpv4_relay_create(const char *_addr, const char *_giaddr, r->hnd.read = dhcpv4_relay_read; triton_context_register(&r->ctx, NULL); - triton_md_register_handler(ctx, &r->hnd); + triton_md_register_handler(&r->ctx, &r->hnd); triton_md_enable_handler(&r->hnd, MD_MODE_READ); triton_context_wakeup(&r->ctx); @@ -886,9 +888,14 @@ found: c->ctx = ctx; c->recv = recv; list_add_tail(&c->entry, &r->ctx_list); + + pthread_mutex_unlock(&relay_lock); return r; +out_err_unlock: + pthread_mutex_unlock(&relay_lock); + out_err: if (sock != -1) close(sock); @@ -900,6 +907,7 @@ void dhcpv4_relay_free(struct dhcpv4_relay *r, struct triton_context_t *ctx) { struct dhcpv4_relay_ctx *c; + pthread_mutex_lock(&relay_lock); list_for_each_entry(c, &r->ctx_list, entry) { if (c->ctx == ctx) { list_del(&c->entry); @@ -916,6 +924,7 @@ void dhcpv4_relay_free(struct dhcpv4_relay *r, struct triton_context_t *ctx) triton_context_unregister(&r->ctx); _free(r); } + pthread_mutex_unlock(&relay_lock); } int dhcpv4_relay_send(struct dhcpv4_relay *relay, struct dhcpv4_packet *request, uint32_t server_id, const char *agent_circuit_id, const char *agent_remote_id) diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index f792e1bc..5e88f5d9 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -56,7 +56,6 @@ struct iplink_arg { pcre *re; const char *opt; long *arg1; - int arg2; }; struct unit_cache { @@ -685,7 +684,7 @@ static void ipoe_ifcfg_add(struct ipoe_session *ses) ses->ifcfg = 1; } -static void ipoe_ifcfg_del(struct ipoe_session *ses) +static void ipoe_ifcfg_del(struct ipoe_session *ses, int lock) { struct ipoe_serv *serv = ses->serv; @@ -696,10 +695,14 @@ static void ipoe_ifcfg_del(struct ipoe_session *ses) if (ses->serv->opt_shared) { ipoe_serv_del_addr(ses->serv, ses->siaddr); } else { - pthread_mutex_lock(&serv->lock); - if (ipaddr_del(serv->ifindex, ses->siaddr)) - log_ppp_warn("ipoe: failed to remove addess from interface '%s'\n", serv->ifname); - pthread_mutex_unlock(&serv->lock); + if (lock) + pthread_mutex_lock(&serv->lock); + if (ipaddr_del(serv->ifindex, ses->siaddr)) { + if (lock) + log_ppp_warn("ipoe: failed to remove addess from interface '%s'\n", serv->ifname); + } + if (lock) + pthread_mutex_unlock(&serv->lock); } } } @@ -848,7 +851,6 @@ static void ipoe_session_started(struct ap_session *s) static void ipoe_session_free(struct ipoe_session *ses) { - if (ses->started) __sync_sub_and_fetch(&stat_active, 1); else @@ -906,7 +908,7 @@ static void ipoe_session_finished(struct ap_session *s) dhcpv4_relay_send_release(ses->serv->dhcpv4_relay, ses->hwaddr, ses->xid, ses->yiaddr, ses->client_id, ses->relay_agent, ses->serv->ifname, conf_agent_remote_id); if (ses->ifcfg) - ipoe_ifcfg_del(ses); + ipoe_ifcfg_del(ses, 1); if (ses->dhcpv4) dhcpv4_free(ses->dhcpv4); @@ -1655,7 +1657,7 @@ static void ipoe_serv_release(struct ipoe_serv *serv) } pthread_mutex_unlock(&serv->lock); - if (serv->vid && !serv->need_close) { + if (serv->vid && !serv->need_close && !ap_shutdown) { if (serv->timer.tpd) triton_timer_mod(&serv->timer, 0); else @@ -1780,7 +1782,7 @@ static void ipoe_drop_sessions(struct ipoe_serv *serv, struct ipoe_session *skip ses->terminating = 1; if (ses->ifcfg) { - ipoe_ifcfg_del(ses); + ipoe_ifcfg_del(ses, 0); ses->ifcfg = 0; } @@ -1853,8 +1855,10 @@ void ipoe_vlan_notify(int ifindex, int vid) log_info2("ipoe: create vlan %s\n", ifr.ifr_name); - if (iplink_vlan_add(ifr.ifr_name, ifindex, vid)) + if (iplink_vlan_add(ifr.ifr_name, ifindex, vid)) { log_warn("ipoe: vlan-mon: %s: failed to add vlan\n", ifr.ifr_name); + return; + } if (ioctl(sock_fd, SIOCGIFINDEX, &ifr, sizeof(ifr))) { log_error("ipoe: vlan-mon: %s: failed to get interface index\n", ifr.ifr_name); @@ -1993,6 +1997,7 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int if (opt_up) ipoe_nl_add_interface(ifindex); + pthread_mutex_lock(&serv_lock); list_for_each_entry(serv, &serv_list, entry) { if (strcmp(ifname, serv->ifname)) continue; @@ -2044,8 +2049,10 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int if (str0) _free(str0); + pthread_mutex_unlock(&serv_lock); return; } + pthread_mutex_unlock(&serv_lock); opt = strchr(opt, ','); if (opt) @@ -2117,7 +2124,9 @@ static void add_interface(const char *ifname, int ifindex, const char *opt, int triton_context_wakeup(&serv->ctx); + pthread_mutex_lock(&serv_lock); list_add_tail(&serv->entry, &serv_list); + pthread_mutex_unlock(&serv_lock); if (str0) _free(str0); @@ -2436,9 +2445,9 @@ static int parse_vlan_mon(const char *opt, long *mask) ptr = strchr(opt, 0); if (*ptr == ',') - memset(mask, 0xff, 4096/8/sizeof(long)); + memset(mask, 0xff, 4096/8); else if (*ptr == 0) { - memset(mask, 0, 4096/8/sizeof(long)); + memset(mask, 0, 4096/8); return 0; } else goto out_err; @@ -2458,10 +2467,10 @@ static int parse_vlan_mon(const char *opt, long *mask) } for (; vid < vid2; vid++) - mask[vid / (8*sizeof(long))] &= ~(1 << (vid % (8*sizeof(long)))); + mask[vid / (8*sizeof(long))] &= ~(1lu << (vid % (8*sizeof(long)))); } - mask[vid / (8*sizeof(long))] &= ~(1 << (vid % (8*sizeof(long)))); + mask[vid / (8*sizeof(long))] &= ~(1lu << (vid % (8*sizeof(long)))); if (*ptr2 == 0) break; @@ -2479,11 +2488,13 @@ out_err: return -1; } -static void add_vlan_mon(const char *opt, long *mask, int len) +static void add_vlan_mon(const char *opt, long *mask) { const char *ptr; struct ifreq ifr; int ifindex; + long mask1[4096/8/sizeof(long)]; + struct ipoe_serv *serv; for (ptr = opt; *ptr && *ptr != ','; ptr++); @@ -2512,12 +2523,20 @@ static void add_vlan_mon(const char *opt, long *mask, int len) ioctl(sock_fd, SIOCSIFFLAGS, &ifr); } - ipoe_nl_add_vlan_mon(ifindex, mask, len); + memcpy(mask1, mask, sizeof(mask1)); + list_for_each_entry(serv, &serv_list, entry) { + if (serv->vid && serv->parent_ifindex == ifindex) + mask1[serv->vid / (8*sizeof(long))] |= 1lu << (serv->vid % (8*sizeof(long))); + } + + ipoe_nl_add_vlan_mon(ifindex, mask1, sizeof(mask1)); } static int __load_vlan_mon_re(int index, int flags, const char *name, struct iplink_arg *arg) { struct ifreq ifr; + long mask1[4096/8/sizeof(long)]; + struct ipoe_serv *serv; if (pcre_exec(arg->re, NULL, name, strlen(name), 0, 0, NULL, 0) < 0) return 0; @@ -2532,8 +2551,14 @@ static int __load_vlan_mon_re(int index, int flags, const char *name, struct ipl ioctl(sock_fd, SIOCSIFFLAGS, &ifr); } + + memcpy(mask1, arg->arg1, sizeof(mask1)); + list_for_each_entry(serv, &serv_list, entry) { + if (serv->vid && serv->parent_ifindex == index) + mask1[serv->vid / (8*sizeof(long))] |= 1lu << (serv->vid % (8*sizeof(long))); + } - ipoe_nl_add_vlan_mon(index, arg->arg1, arg->arg2); + ipoe_nl_add_vlan_mon(index, mask1, sizeof(mask1)); return 0; } @@ -2563,7 +2588,6 @@ static void load_vlan_mon_re(const char *opt, long *mask, int len) arg.re = re; arg.opt = opt; arg.arg1 = mask; - arg.arg2 = len; iplink_list((iplink_list_func)__load_vlan_mon_re, &arg); @@ -2592,7 +2616,7 @@ static void load_vlan_mon(struct conf_sect_t *sect) if (strlen(opt->val) > 3 && !memcmp(opt->val, "re:", 3)) load_vlan_mon_re(opt->val, mask, sizeof(mask)); else - add_vlan_mon(opt->val, mask, sizeof(mask)); + add_vlan_mon(opt->val, mask); } } |