diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/vrf.c | 51 | ||||
| -rw-r--r-- | lib/vrf.h | 11 |
2 files changed, 43 insertions, 19 deletions
@@ -994,25 +994,50 @@ const char *vrf_get_default_name(void) 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; } @@ -251,15 +251,14 @@ extern int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id, 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, |
