return vrf_default_name;
}
-int vrf_bind(vrf_id_t vrf_id, int fd, const char *name)
+int vrf_bind(vrf_id_t vrf_id, int fd, const char *ifname)
{
int ret = 0;
struct interface *ifp;
+ struct vrf *vrf;
+
+ if (fd < 0)
+ return -1;
+
+ if (vrf_id == VRF_UNKNOWN)
+ return -1;
+
+ /* can't bind to a VRF that doesn't exist */
+ vrf = vrf_lookup_by_id(vrf_id);
+ if (!vrf_is_enabled(vrf))
+ return -1;
+
+ if (ifname && strcmp(ifname, vrf->name)) {
+ /* binding to a regular interface */
+
+ /* can't bind to an interface that doesn't exist */
+ ifp = if_lookup_by_name(ifname, vrf_id);
+ if (!ifp)
+ return -1;
+ } else {
+ /* binding to a VRF device */
+
+ /* nothing to do for netns */
+ if (vrf_is_backend_netns())
+ return 0;
+
+ /* nothing to do for default vrf */
+ if (vrf_id == VRF_DEFAULT)
+ return 0;
+
+ ifname = vrf->name;
+ }
- if (fd < 0 || name == NULL)
- return fd;
- /* the device should exist
- * otherwise we should return
- * case ifname = vrf in netns mode => return
- */
- ifp = if_lookup_by_name(name, vrf_id);
- if (!ifp)
- return fd;
#ifdef SO_BINDTODEVICE
- ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)+1);
+ ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, ifname,
+ strlen(ifname) + 1);
if (ret < 0)
- zlog_debug("bind to interface %s failed, errno=%d", name,
- errno);
+ zlog_err("bind to interface %s failed, errno=%d", ifname,
+ errno);
#endif /* SO_BINDTODEVICE */
return ret;
}
const char *name);
/*
- * Binds a socket to a VRF device.
+ * Binds a socket to an interface (ifname) in a VRF (vrf_id).
*
- * If name is null, the socket is not bound, irrespective of any other
- * arguments.
+ * If ifname is NULL or is equal to the VRF name then bind to a VRF device.
+ * Otherwise, bind to the specified interface in the specified VRF.
*
- * name should be the name of the VRF device. vrf_id should be the
- * corresponding vrf_id (the ifindex of the device).
+ * Returns 0 on success and -1 on failure.
*/
-extern int vrf_bind(vrf_id_t vrf_id, int fd, const char *name);
+extern int vrf_bind(vrf_id_t vrf_id, int fd, const char *ifname);
/* VRF ioctl operations */
extern int vrf_getaddrinfo(const char *node, const char *service,
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
-from lib.common_config import adjust_router_l3mdev
+from lib.common_config import required_linux_kernel_version
# Required to instantiate the topology builder class.
from mininet.topo import Topo
def setup_module(mod):
"Sets up the pytest environment"
+
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("5.0")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
tgen = Topogen(BGPIPV6RTADVVRFTopo, mod.__name__)
tgen.start_topology()
for cmd in cmds:
output = tgen.net[rname].cmd(cmd.format(rname))
- # adjust handling of vrf traffic
- adjust_router_l3mdev(tgen, rname)
-
for rname, router in router_list.items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from lib.topotest import iproute2_is_vrf_capable
-from lib.common_config import (
- required_linux_kernel_version,
- adjust_router_l3mdev,
-)
+from lib.common_config import required_linux_kernel_version
#####################################################
##
def setup_module(mod):
"Sets up the pytest environment"
+ # Required linux kernel version for this suite to run.
+ result = required_linux_kernel_version("5.0")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
tgen = Topogen(NetworkTopo, mod.__name__)
tgen.start_topology()
for cmd in cmds2:
output = tgen.net[rname].cmd(cmd.format(rname))
- # adjust handling of vrf traffic
- adjust_router_l3mdev(tgen, rname)
-
for rname, router in tgen.routers().items():
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))