mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 15:17:15 +00:00
zebra: handle some ioctl operations for VRF
A new API is available for interface ioctl operations on Linux: vrf_if_ioctl. This is the unified API that permits doing ioctl operations on a per interface basis. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
0268f30e3c
commit
4db2161955
@ -146,7 +146,7 @@ static int if_get_hwaddr(struct interface *ifp)
|
|||||||
ifreq.ifr_addr.sa_family = AF_INET;
|
ifreq.ifr_addr.sa_family = AF_INET;
|
||||||
|
|
||||||
/* Fetch Hardware address if available. */
|
/* Fetch Hardware address if available. */
|
||||||
ret = if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq);
|
ret = vrf_if_ioctl(SIOCGIFHWADDR, (caddr_t)&ifreq, ifp->vrf_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
ifp->hw_addr_len = 0;
|
ifp->hw_addr_len = 0;
|
||||||
else {
|
else {
|
||||||
|
@ -59,6 +59,7 @@ int if_ioctl(u_long request, caddr_t buffer)
|
|||||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
|
||||||
if (zserv_privs.change(ZPRIVS_LOWER))
|
if (zserv_privs.change(ZPRIVS_LOWER))
|
||||||
zlog_err("Can't lower privileges");
|
zlog_err("Can't lower privileges");
|
||||||
zlog_err("Cannot create UDP socket: %s",
|
zlog_err("Cannot create UDP socket: %s",
|
||||||
@ -78,6 +79,39 @@ int if_ioctl(u_long request, caddr_t buffer)
|
|||||||
return 0;
|
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
|
#ifndef HAVE_NETLINK
|
||||||
static int if_ioctl_ipv6(u_long request, caddr_t buffer)
|
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);
|
sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
|
|
||||||
if (zserv_privs.change(ZPRIVS_LOWER))
|
if (zserv_privs.change(ZPRIVS_LOWER))
|
||||||
zlog_err("Can't lower privileges");
|
zlog_err("Can't lower privileges");
|
||||||
zlog_err("Cannot create IPv6 datagram socket: %s",
|
zlog_err("Cannot create IPv6 datagram socket: %s",
|
||||||
@ -122,7 +157,7 @@ void if_get_metric(struct interface *ifp)
|
|||||||
|
|
||||||
ifreq_set_name(&ifreq, 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;
|
return;
|
||||||
ifp->metric = ifreq.ifr_metric;
|
ifp->metric = ifreq.ifr_metric;
|
||||||
if (ifp->metric == 0)
|
if (ifp->metric == 0)
|
||||||
@ -140,7 +175,7 @@ void if_get_mtu(struct interface *ifp)
|
|||||||
ifreq_set_name(&ifreq, ifp);
|
ifreq_set_name(&ifreq, ifp);
|
||||||
|
|
||||||
#if defined(SIOCGIFMTU)
|
#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)");
|
zlog_info("Can't lookup mtu by ioctl(SIOCGIFMTU)");
|
||||||
ifp->mtu6 = ifp->mtu = -1;
|
ifp->mtu6 = ifp->mtu = -1;
|
||||||
return;
|
return;
|
||||||
@ -376,9 +411,9 @@ void if_get_flags(struct interface *ifp)
|
|||||||
|
|
||||||
ifreq_set_name(&ifreq, 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) {
|
if (ret < 0) {
|
||||||
zlog_err("if_ioctl(SIOCGIFFLAGS) failed: %s",
|
zlog_err("vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
|
||||||
safe_strerror(errno));
|
safe_strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -423,7 +458,7 @@ int if_set_flags(struct interface *ifp, uint64_t flags)
|
|||||||
ifreq.ifr_flags = ifp->flags;
|
ifreq.ifr_flags = ifp->flags;
|
||||||
ifreq.ifr_flags |= 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) {
|
if (ret < 0) {
|
||||||
zlog_info("can't set interface flags");
|
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 = ifp->flags;
|
||||||
ifreq.ifr_flags &= ~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) {
|
if (ret < 0) {
|
||||||
zlog_info("can't unset interface flags");
|
zlog_info("can't unset interface flags");
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
extern void ifreq_set_name(struct ifreq *, struct interface *);
|
extern void ifreq_set_name(struct ifreq *, struct interface *);
|
||||||
extern int if_ioctl(u_long, caddr_t);
|
extern int if_ioctl(u_long, caddr_t);
|
||||||
|
extern int vrf_if_ioctl(u_long request, caddr_t buffer, vrf_id_t vrf_id);
|
||||||
|
|
||||||
extern int if_set_flags(struct interface *, uint64_t);
|
extern int if_set_flags(struct interface *, uint64_t);
|
||||||
extern int if_unset_flags(struct interface *, uint64_t);
|
extern int if_unset_flags(struct interface *, uint64_t);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "privs.h"
|
#include "privs.h"
|
||||||
#include "vty.h"
|
#include "vty.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
#include "zebra/rt.h"
|
#include "zebra/rt.h"
|
||||||
@ -44,6 +45,11 @@ void lifreq_set_name(struct lifreq *lifreq, const char *ifname)
|
|||||||
strncpy(lifreq->lifr_name, ifname, IFNAMSIZ);
|
strncpy(lifreq->lifr_name, ifname, IFNAMSIZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int vrf_if_ioctl(u_long request, caddr_t buffer, vrf_id_t vrf_id)
|
||||||
|
{
|
||||||
|
return if_ioctl(request, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
/* call ioctl system call */
|
/* call ioctl system call */
|
||||||
int if_ioctl(u_long request, caddr_t buffer)
|
int if_ioctl(u_long request, caddr_t buffer)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user