Skip to content

Commit

Permalink
bgpd: make bgpd rely on vrf_bind() API usage
Browse files Browse the repository at this point in the history
Instead of relying on local usage of vrf bind operation, the vrf API for
that usage is done.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>

fixup bgp
  • Loading branch information
pguibert6WIND committed Feb 27, 2018
1 parent 0f4977c commit 97896a9
Showing 1 changed file with 13 additions and 40 deletions.
53 changes: 13 additions & 40 deletions bgpd/bgp_network.c
Expand Up @@ -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 {
Expand Down Expand Up @@ -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() */

Expand Down Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 97896a9

Please sign in to comment.