summaryrefslogtreecommitdiff
path: root/zebra/ioctl.c
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2018-03-01 11:10:01 -0500
committerQuentin Young <qlyoung@cumulusnetworks.com>2018-03-01 11:10:01 -0500
commita975744835bb87e3cf62701e13248d66f1dac1df (patch)
treebca5ab1f29594688c43e0c36c9eb2f0c5c8e66c6 /zebra/ioctl.c
parent351c56649bfd8487676704a10995d736d1d893cc (diff)
parentc98f4d81aa5d4113ceea58ce6db4bebab5c99735 (diff)
Merge branch 'master' into docuser
* New manpage: mtracebis.rst * Makefile.am includes mtracebis.rst * configure.ac lines removed * Debian packaging files updated * Fixed up manpage |seealso-programs| in the process * Centos7 build package list updated to include systemd-devel * New paragraph on netns vrf support in zebra manpage Conflicts: configure.ac debianpkg/backports/ubuntu14.04/debian/frr.install debianpkg/frr.install doc/Makefile.am doc/developer/Building_FRR_on_CentOS7.rst doc/zebra.8.in Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'zebra/ioctl.c')
-rw-r--r--zebra/ioctl.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/zebra/ioctl.c b/zebra/ioctl.c
index 8e3a1d1a03..d07d37056e 100644
--- a/zebra/ioctl.c
+++ b/zebra/ioctl.c
@@ -59,6 +59,7 @@ int if_ioctl(u_long request, caddr_t buffer)
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
int save_errno = errno;
+
if (zserv_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges");
zlog_err("Cannot create UDP socket: %s",
@@ -78,6 +79,39 @@ int if_ioctl(u_long request, caddr_t buffer)
return 0;
}
+/* call ioctl system call */
+int vrf_if_ioctl(u_long request, caddr_t buffer, vrf_id_t vrf_id)
+{
+ int sock;
+ int ret;
+ int err = 0;
+
+ if (zserv_privs.change(ZPRIVS_RAISE))
+ zlog_err("Can't raise privileges");
+ sock = vrf_socket(AF_INET, SOCK_DGRAM, 0, vrf_id, NULL);
+ if (sock < 0) {
+ int save_errno = errno;
+
+ if (zserv_privs.change(ZPRIVS_LOWER))
+ zlog_err("Can't lower privileges");
+ zlog_err("Cannot create UDP socket: %s",
+ safe_strerror(save_errno));
+ exit(1);
+ }
+ ret = vrf_ioctl(vrf_id, sock, request, buffer);
+ if (ret < 0)
+ err = errno;
+ if (zserv_privs.change(ZPRIVS_LOWER))
+ zlog_err("Can't lower privileges");
+ close(sock);
+
+ if (ret < 0) {
+ errno = err;
+ return ret;
+ }
+ return 0;
+}
+
#ifndef HAVE_NETLINK
static int if_ioctl_ipv6(u_long request, caddr_t buffer)
{
@@ -90,6 +124,7 @@ static int if_ioctl_ipv6(u_long request, caddr_t buffer)
sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
int save_errno = errno;
+
if (zserv_privs.change(ZPRIVS_LOWER))
zlog_err("Can't lower privileges");
zlog_err("Cannot create IPv6 datagram socket: %s",
@@ -122,7 +157,7 @@ void if_get_metric(struct interface *ifp)
ifreq_set_name(&ifreq, ifp);
- if (if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq) < 0)
+ if (vrf_if_ioctl(SIOCGIFMETRIC, (caddr_t)&ifreq, ifp->vrf_id) < 0)
return;
ifp->metric = ifreq.ifr_metric;
if (ifp->metric == 0)
@@ -140,7 +175,7 @@ void if_get_mtu(struct interface *ifp)
ifreq_set_name(&ifreq, ifp);
#if defined(SIOCGIFMTU)
- if (if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq) < 0) {
+ if (vrf_if_ioctl(SIOCGIFMTU, (caddr_t)&ifreq, ifp->vrf_id) < 0) {
zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)");
ifp->mtu6 = ifp->mtu = -1;
return;
@@ -376,9 +411,9 @@ void if_get_flags(struct interface *ifp)
ifreq_set_name(&ifreq, ifp);
- ret = if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq);
+ ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
- zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s",
+ zlog_err("vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
safe_strerror(errno));
return;
}
@@ -423,7 +458,7 @@ int if_set_flags(struct interface *ifp, uint64_t flags)
ifreq.ifr_flags = ifp->flags;
ifreq.ifr_flags |= flags;
- ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq);
+ ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
zlog_info("can't set interface flags");
@@ -444,7 +479,7 @@ int if_unset_flags(struct interface *ifp, uint64_t flags)
ifreq.ifr_flags = ifp->flags;
ifreq.ifr_flags &= ~flags;
- ret = if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq);
+ ret = vrf_if_ioctl(SIOCSIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
if (ret < 0) {
zlog_info("can't unset interface flags");