summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2015-11-20 20:14:19 +0300
committerDmitry Kozlov <xeb@mail.ru>2015-11-20 20:14:19 +0300
commit5cd2744f424c4228448834076bdad099927b05c7 (patch)
treeeedfebd450058ff032fadb7b51270aebca653d1f
parent2f072eba3d0f045cd540d29ba2f5c195f056793b (diff)
downloadaccel-ppp-5cd2744f424c4228448834076bdad099927b05c7.tar.gz
accel-ppp-5cd2744f424c4228448834076bdad099927b05c7.zip
ipoe: implemented interface renaming by NAS-Port-Id
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c38
-rw-r--r--accel-pppd/ifcfg.c28
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;
}