diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2015-11-20 20:14:19 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2015-11-20 20:14:19 +0300 |
commit | 5cd2744f424c4228448834076bdad099927b05c7 (patch) | |
tree | eedfebd450058ff032fadb7b51270aebca653d1f | |
parent | 2f072eba3d0f045cd540d29ba2f5c195f056793b (diff) | |
download | accel-ppp-5cd2744f424c4228448834076bdad099927b05c7.tar.gz accel-ppp-5cd2744f424c4228448834076bdad099927b05c7.zip |
ipoe: implemented interface renaming by NAS-Port-Id
-rw-r--r-- | accel-pppd/ctrl/ipoe/ipoe.c | 38 | ||||
-rw-r--r-- | accel-pppd/ifcfg.c | 28 |
2 files changed, 49 insertions, 17 deletions
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c index 594df29..ef729f5 100644 --- a/accel-pppd/ctrl/ipoe/ipoe.c +++ b/accel-pppd/ctrl/ipoe/ipoe.c @@ -576,15 +576,12 @@ cont: if (ses->serv->opt_nat) ses->ses.ipv4 = ipdb_get_ipv4(&ses->ses); - if (ses->serv->opt_shared == 0 && (!ses->ses.ipv4 || ses->ses.ipv4->peer_addr == ses->yiaddr)) { - strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN); - ses->ses.ifindex = ses->serv->ifindex; - } else if (ses->ifindex == -1) { + if (ses->serv->opt_shared == 0 && ses->ses.ipv4 && ses->ses.ipv4->peer_addr != ses->yiaddr) { if (ipoe_create_interface(ses)) return; - } - ap_session_set_ifindex(&ses->ses); + ap_session_set_ifindex(&ses->ses); + } if (ses->dhcpv4_request && ses->serv->dhcpv4_relay) { dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id); @@ -1092,12 +1089,6 @@ static void ipoe_session_finished(struct ap_session *s) log_ppp_info1("ipoe: session finished\n"); - pthread_mutex_lock(&ses->serv->lock); - list_del(&ses->entry); - 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) { if (uc_size < conf_unit_cache && ipoe_nl_modify(ses->ifindex, 0, 0, "", NULL)) { uc = mempool_alloc(uc_pool); @@ -1125,6 +1116,29 @@ static void ipoe_session_finished(struct ap_session *s) triton_event_fire(EV_CTRL_FINISHED, s); + if (s->ifindex == ses->serv->ifindex && strcmp(s->ifname, ses->serv->ifname)) { + struct ifreq ifr; + + strcpy(ifr.ifr_name, s->ifname); + + ioctl(sock_fd, SIOCGIFFLAGS, &ifr); + ifr.ifr_flags &= ~IFF_UP; + ioctl(sock_fd, SIOCSIFFLAGS, &ifr); + + strcpy(ifr.ifr_newname, ses->serv->ifname); + ioctl(sock_fd, SIOCSIFNAME, &ifr); + + strcpy(ifr.ifr_name, ses->serv->ifname); + ifr.ifr_flags |= IFF_UP; + ioctl(sock_fd, SIOCSIFFLAGS, &ifr); + } + + pthread_mutex_lock(&ses->serv->lock); + list_del(&ses->entry); + 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); + triton_context_call(&ses->ctx, (triton_event_func)ipoe_session_free, ses); } diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c index 77a3732..69b77e7 100644 --- a/accel-pppd/ifcfg.c +++ b/accel-pppd/ifcfg.c @@ -261,6 +261,7 @@ void __export ap_session_ifdown(struct ap_session *ses) int __export ap_session_rename(struct ap_session *ses, const char *ifname, int len) { struct ifreq ifr; + int r, up = 0; if (len == -1) len = strlen(ifname); @@ -274,19 +275,36 @@ int __export ap_session_rename(struct ap_session *ses, const char *ifname, int l memcpy(ifr.ifr_newname, ifname, len); ifr.ifr_newname[len] = 0; - if (ioctl(sock_fd, SIOCSIFNAME, &ifr)) { + r = ioctl(sock_fd, SIOCSIFNAME, &ifr); + if (r && errno == EBUSY) { + ioctl(sock_fd, SIOCGIFFLAGS, &ifr); + ifr.ifr_flags &= ~IFF_UP; + ioctl(sock_fd, SIOCSIFFLAGS, &ifr); + + memcpy(ifr.ifr_newname, ifname, len); + ifr.ifr_newname[len] = 0; + r = ioctl(sock_fd, SIOCSIFNAME, &ifr); + + up = 1; + } + + if (r) { if (!ses->ifname_rename) ses->ifname_rename = _strdup(ifr.ifr_newname); - else { + else log_ppp_warn("interface rename failed: %s\n", strerror(errno)); - return -1; - } } else { log_ppp_info2("rename interface to '%s'\n", ifr.ifr_newname); memcpy(ses->ifname, ifname, len); ses->ifname[len] = 0; } - return 0; + if (up) { + strcpy(ifr.ifr_name, ses->ifname); + ifr.ifr_flags |= IFF_UP; + ioctl(sock_fd, SIOCSIFFLAGS, &ifr); + } + + return r; } |