summaryrefslogtreecommitdiff
path: root/accel-pppd/ifcfg.c
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2016-07-11 09:47:04 +0300
committerDmitry Kozlov <xeb@mail.ru>2016-07-11 09:47:04 +0300
commite0cca4344f70b9c9e23e3c6a7e17c8e93c765184 (patch)
tree1068654b025b2e24c983d99776696ad889a0c138 /accel-pppd/ifcfg.c
parent6fb04941ca41312909208938bfac4f753d3c277c (diff)
downloadaccel-ppp-e0cca4344f70b9c9e23e3c6a7e17c8e93c765184.tar.gz
accel-ppp-e0cca4344f70b9c9e23e3c6a7e17c8e93c765184.zip
implemented support for network namespace
This is done using radius attribute NAS-Port-Id. The new format of this attribute is NAS-Port-Id=[ns/][name]. Namespaces must be created malually by "ip netns add ..." command
Diffstat (limited to 'accel-pppd/ifcfg.c')
-rw-r--r--accel-pppd/ifcfg.c82
1 files changed, 57 insertions, 25 deletions
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index 246aa643..5e7c790a 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -149,9 +149,11 @@ void __export ap_session_accounting_started(struct ap_session *ses)
}
if (ses->ipv6) {
+ net->enter_ns();
devconf(ses, "accept_ra", "0");
devconf(ses, "autoconf", "0");
devconf(ses, "forwarding", "1");
+ net->exit_ns();
memset(&ifr6, 0, sizeof(ifr6));
@@ -161,7 +163,7 @@ void __export ap_session_accounting_started(struct ap_session *ses)
ifr6.ifr6_prefixlen = 64;
ifr6.ifr6_ifindex = ses->ifindex;
- if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6))
+ if (net->sock6_ioctl(SIOCSIFADDR, &ifr6))
log_ppp_error("faild to set LL IPv6 address: %s\n", strerror(errno));
}
@@ -246,7 +248,7 @@ void __export ap_session_ifdown(struct ap_session *ses)
ifr6.ifr6_addr.s6_addr32[0] = htonl(0xfe800000);
*(uint64_t *)(ifr6.ifr6_addr.s6_addr + 8) = ses->ipv6->intf_id;
ifr6.ifr6_prefixlen = 64;
- ioctl(sock6_fd, SIOCDIFADDR, &ifr6);
+ net->sock6_ioctl(SIOCDIFADDR, &ifr6);
}
list_for_each_entry(a, &ses->ipv6->addr_list, entry) {
@@ -267,42 +269,72 @@ 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;
+ int i, r, up = 0;
+ struct ap_net *ns = NULL;
+ char ns_name[256];
if (len == -1)
len = strlen(ifname);
+ for (i = 0; i < len; i++) {
+ if (ifname[i] == '/') {
+ memcpy(ns_name, ifname, i);
+ ns_name[i] = 0;
+
+ ns = ap_net_open_ns(ns_name);
+ if (!ns)
+ return -1;
+
+ ifname += i + 1;
+ len -= i + 1;
+ break;
+ }
+ }
+
if (len >= IFNAMSIZ) {
- log_ppp_warn("cannot rename interface (name is too long)\n");
+ log_ppp_error("cannot rename interface (name is too long)\n");
return -1;
}
- strcpy(ifr.ifr_name, ses->ifname);
- memcpy(ifr.ifr_newname, ifname, len);
- ifr.ifr_newname[len] = 0;
-
- r = net->sock_ioctl(SIOCSIFNAME, &ifr);
- if (r && errno == EBUSY) {
- net->sock_ioctl(SIOCGIFFLAGS, &ifr);
- ifr.ifr_flags &= ~IFF_UP;
- net->sock_ioctl(SIOCSIFFLAGS, &ifr);
-
+ if (len) {
+ strcpy(ifr.ifr_name, ses->ifname);
memcpy(ifr.ifr_newname, ifname, len);
ifr.ifr_newname[len] = 0;
+
r = net->sock_ioctl(SIOCSIFNAME, &ifr);
+ if (r && errno == EBUSY) {
+ net->sock_ioctl(SIOCGIFFLAGS, &ifr);
+ ifr.ifr_flags &= ~IFF_UP;
+ net->sock_ioctl(SIOCSIFFLAGS, &ifr);
+
+ memcpy(ifr.ifr_newname, ifname, len);
+ ifr.ifr_newname[len] = 0;
+ r = net->sock_ioctl(SIOCSIFNAME, &ifr);
+
+ up = 1;
+ }
- up = 1;
+ if (r) {
+ if (!ses->ifname_rename)
+ ses->ifname_rename = _strdup(ifr.ifr_newname);
+ else
+ log_ppp_warn("interface rename to %s failed: %s\n", ifr.ifr_newname, strerror(errno));
+ } else {
+ log_ppp_info2("rename interface to '%s'\n", ifr.ifr_newname);
+ memcpy(ses->ifname, ifname, len);
+ ses->ifname[len] = 0;
+ }
}
- if (r) {
- if (!ses->ifname_rename)
- ses->ifname_rename = _strdup(ifr.ifr_newname);
- else
- log_ppp_warn("interface rename to %s failed: %s\n", ifr.ifr_newname, strerror(errno));
- } else {
- log_ppp_info2("rename interface to '%s'\n", ifr.ifr_newname);
- memcpy(ses->ifname, ifname, len);
- ses->ifname[len] = 0;
+ if (ns) {
+ if (net->move_link(ns, ses->ifindex)) {
+ log_ppp_error("failed to attach namespace\n");
+ ns->release(ns);
+ return -1;
+ }
+ ses->net = ns;
+ net = ns;
+ log_ppp_info2("move to namespace %s\n", ns->name);
}
if (up) {
@@ -311,6 +343,6 @@ int __export ap_session_rename(struct ap_session *ses, const char *ifname, int l
net->sock_ioctl(SIOCSIFFLAGS, &ifr);
}
- return r;
+ return 0;
}