diff options
Diffstat (limited to 'lib/vrf.c')
-rw-r--r-- | lib/vrf.c | 51 |
1 files changed, 38 insertions, 13 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; } |