From 97896a91c2a7c8d856a1326cd4017f458e4a5493 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 5 Feb 2018 17:39:37 +0100 Subject: [PATCH] bgpd: make bgpd rely on vrf_bind() API usage Instead of relying on local usage of vrf bind operation, the vrf API for that usage is done. Signed-off-by: Philippe Guibert fixup bgp --- bgpd/bgp_network.c | 53 ++++++++++++---------------------------------- 1 file changed, 13 insertions(+), 40 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 240a23d198..0ab583f444 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -45,7 +45,7 @@ extern struct zebra_privs_t bgpd_privs; -static int bgp_bind(struct peer *); +static char *bgp_get_bound_name(struct peer *peer); /* BGP listening socket. */ struct bgp_listener { @@ -415,7 +415,7 @@ static int bgp_accept(struct thread *thread) peer->doppelganger = peer1; peer1->doppelganger = peer; peer->fd = bgp_sock; - bgp_bind(peer); + vrf_bind(peer->bgp->vrf_id, bgp_sock, bgp_get_bound_name(peer)); bgp_fsm_change_status(peer, Active); BGP_TIMER_OFF(peer->t_start); /* created in peer_create() */ @@ -443,23 +443,20 @@ static int bgp_accept(struct thread *thread) } /* BGP socket bind. */ -static int bgp_bind(struct peer *peer) +static char *bgp_get_bound_name(struct peer *peer) { -#ifdef SO_BINDTODEVICE - int ret; - int myerrno; char *name = NULL; - /* If not bound to an interface or part of a VRF lite, we don't care. */ if ((peer->bgp->vrf_id == VRF_DEFAULT) && !peer->ifname && !peer->conf_if) - return 0; - if (vrf_is_mapped_on_netns(peer->bgp->vrf_id)) - return 0; + return NULL; + if (peer->su.sa.sa_family != AF_INET && peer->su.sa.sa_family != AF_INET6) - return 0; // unexpected + return NULL; // unexpected + if (!peer) + return name; /* For IPv6 peering, interface (unnumbered or link-local with interface) * takes precedence over VRF. For IPv4 peering, explicit interface or * VRF are the situations to bind. @@ -471,30 +468,7 @@ static int bgp_bind(struct peer *peer) else name = peer->ifname ? peer->ifname : peer->bgp->name; - if (!name) - return 0; - - if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s Binding to interface %s", peer->host, name); - - if (bgpd_privs.change(ZPRIVS_RAISE)) - zlog_err("bgp_bind: could not raise privs"); - - ret = setsockopt(peer->fd, SOL_SOCKET, SO_BINDTODEVICE, name, - strlen(name)); - myerrno = errno; - - if (bgpd_privs.change(ZPRIVS_LOWER)) - zlog_err("bgp_bind: could not lower privs"); - - if (ret < 0) { - if (bgp_debug_neighbor_events(peer)) - zlog_debug("bind to interface %s failed, errno=%d", - name, myerrno); - return ret; - } -#endif /* SO_BINDTODEVICE */ - return 0; + return name; } static int bgp_update_address(struct interface *ifp, const union sockunion *dst, @@ -571,7 +545,8 @@ int bgp_connect(struct peer *peer) if (bgpd_privs.change(ZPRIVS_RAISE)) zlog_err("Can't raise privileges"); /* Make socket for the peer. */ - peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, NULL); + peer->fd = vrf_sockunion_socket(&peer->su, peer->bgp->vrf_id, + bgp_get_bound_name(peer)); if (bgpd_privs.change(ZPRIVS_LOWER)) zlog_err("Can't lower privileges"); if (peer->fd < 0) @@ -605,9 +580,6 @@ int bgp_connect(struct peer *peer) if (peer->password) bgp_md5_set_connect(peer->fd, &peer->su, peer->password); - /* Bind socket. */ - bgp_bind(peer); - /* Update source bind. */ if (bgp_update_source(peer) < 0) { return connect_error; @@ -751,7 +723,8 @@ int bgp_socket(struct bgp *bgp, unsigned short port, const char *address) if (bgpd_privs.change(ZPRIVS_RAISE)) zlog_err("Can't raise privileges"); sock = vrf_socket(ainfo->ai_family, ainfo->ai_socktype, - ainfo->ai_protocol, bgp->vrf_id, NULL); + ainfo->ai_protocol, bgp->vrf_id, + NULL); if (bgpd_privs.change(ZPRIVS_LOWER)) zlog_err("Can't lower privileges"); if (sock < 0) { -- 2.39.5