Skip to content

Commit

Permalink
bgpd: Only update peer connection information when needed
Browse files Browse the repository at this point in the history
Currently bgp is repeatedly grabbing peer connection information.
This is a bit overkill.  There are two situations:

a) Opening a connection to the peer
   In this case, we know the remote port/address a priori and can get
   the local information by just asking the OS.
b) Peer opening a connection to us.
   In this case, we know the local port/address a priori and can get
   the remote information by just asking the OS.

Modify the code to just grab this data at the appropriate time.

Signed-off-by: Donald Sharp <[email protected]>
  • Loading branch information
donaldsharp committed Jan 10, 2025
1 parent 78fa9b6 commit 348c2dc
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 16 deletions.
1 change: 0 additions & 1 deletion bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,6 @@ static void bgp_connect_in_progress_update_connection(struct peer_connection *co
{
struct peer *peer = connection->peer;

bgp_updatesockname(connection);
if (!connection->su_remote && !BGP_CONNECTION_SU_UNSPEC(connection)) {
/* if connect initiated, then dest port and dest addresses are well known */
connection->su_remote = sockunion_dup(&connection->su);
Expand Down
36 changes: 22 additions & 14 deletions bgpd/bgp_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,9 @@ static void bgp_accept(struct event *thread)
/* Dynamic neighbor has been created, let it proceed */
connection1->fd = bgp_sock;

connection1->su_local = sockunion_getsockname(connection1->fd);
connection1->su_remote = sockunion_dup(&su);

if (bgp_set_socket_ttl(connection1) < 0) {
peer1->last_reset = PEER_DOWN_SOCKET_ERROR;
zlog_err("%s: Unable to set min/max TTL on peer %s (dynamic), error received: %s(%d)",
Expand Down Expand Up @@ -623,7 +626,10 @@ static void bgp_accept(struct event *thread)

peer->doppelganger = peer1;
peer1->doppelganger = peer;

connection->fd = bgp_sock;
connection->su_local = sockunion_getsockname(connection->fd);
connection->su_remote = sockunion_dup(&su);

if (bgp_set_socket_ttl(connection) < 0)
if (bgp_debug_neighbor_events(peer))
Expand Down Expand Up @@ -857,33 +863,35 @@ enum connect_result bgp_connect(struct peer_connection *connection)
peer->host, connection->fd);

/* Connect to the remote peer. */
return sockunion_connect(connection->fd, &connection->su,
htons(peer->port), ifindex);
}
enum connect_result res;

void bgp_updatesockname(struct peer_connection *connection)
{
if (connection->su_local) {
sockunion_free(connection->su_local);
connection->su_local = NULL;
}
res = sockunion_connect(connection->fd, &connection->su, htons(peer->port), ifindex);

if (connection->su_remote) {
if (connection->su_remote)
sockunion_free(connection->su_remote);
connection->su_remote = NULL;

connection->su_remote = sockunion_dup(&connection->su);
switch (connection->su.sa.sa_family) {
case AF_INET:
connection->su_remote->sin.sin_port = htons(peer->port);
break;
case AF_INET6:
connection->su_remote->sin6.sin6_port = htons(peer->port);
break;
}

if (connection->su_local)
sockunion_free(connection->su_local);
connection->su_local = sockunion_getsockname(connection->fd);
connection->su_remote = sockunion_getpeername(connection->fd);

return res;
}

/* After TCP connection is established. Get local address and port. */
int bgp_getsockname(struct peer_connection *connection)
{
struct peer *peer = connection->peer;

bgp_updatesockname(connection);

if (!bgp_zebra_nexthop_set(connection->su_local, connection->su_remote, &peer->nexthop,
peer)) {
flog_err(EC_BGP_NH_UPD,
Expand Down
1 change: 0 additions & 1 deletion bgpd/bgp_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ extern void bgp_close_vrf_socket(struct bgp *bgp);
extern void bgp_close(void);
extern enum connect_result bgp_connect(struct peer_connection *connection);
extern int bgp_getsockname(struct peer_connection *connection);
extern void bgp_updatesockname(struct peer_connection *connection);

extern int bgp_md5_set_prefix(struct bgp *bgp, struct prefix *p,
const char *password);
Expand Down

0 comments on commit 348c2dc

Please sign in to comment.