diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-03-01 11:10:01 -0500 |
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-03-01 11:10:01 -0500 |
| commit | a975744835bb87e3cf62701e13248d66f1dac1df (patch) | |
| tree | bca5ab1f29594688c43e0c36c9eb2f0c5c8e66c6 /zebra/ioctl.c | |
| parent | 351c56649bfd8487676704a10995d736d1d893cc (diff) | |
| parent | c98f4d81aa5d4113ceea58ce6db4bebab5c99735 (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.c | 47 |
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"); |
