Skip to content

Commit

Permalink
bgpd: fix addressing information of non established outgoing sessions
Browse files Browse the repository at this point in the history
When trying to connect to a BGP peer that does not respons, the 'show
bgp neighbors' command does not give any indication on the local and
remote addresses used:

> # show bgp neighbors
>  BGP neighbor is 192.0.2.150, remote AS 65500, local AS 65500, internal link
>   Local Role: undefined
>   Remote Role: undefined
>   BGP version 4, remote router ID 0.0.0.0, local router ID 192.0.2.1
>   BGP state = Connect
> [..]
>   Connections established 0; dropped 0
>   Last reset 00:00:04,   Waiting for peer OPEN (n/a)
>   Internal BGP neighbor may be up to 255 hops away.
> BGP Connect Retry Timer in Seconds: 120
> Next connect timer due in 117 seconds
> Read thread: off  Write thread: off  FD used: 27

The addressing information (address and port) are only available
when TCP session is established, whereas this information is present
at the system level:

> root@ubuntu2204:~# netstat -pan | grep 192.0.2.1
> tcp        0      0 192.0.2.1:179           192.0.2.150:38060       SYN_RECV    -
> tcp        0      1 192.0.2.1:46526         192.0.2.150:179         SYN_SENT    488310/bgpd

Add the display for outgoing BGP session, as the information in
the getsockname() API provides information for connected streams.
When getpeername() API does not give any information, use the peer
configuration (destination port is encoded in peer->port).

> # show bgp neighbors
> BGP neighbor is 192.0.2.150, remote AS 65500, local AS 65500, internal link
>   Local Role: undefined
>   Remote Role: undefined
>   BGP version 4, remote router ID 0.0.0.0, local router ID 192.0.2.1
>   BGP state = Connect
> [..]
>   Connections established 0; dropped 0
>   Last reset 00:00:16,   Waiting for peer OPEN (n/a)
> Local host: 192.0.2.1, Local port: 46084
> Foreign host: 192.0.2.150, Foreign port: 179

Signed-off-by: Philippe Guibert <[email protected]>
  • Loading branch information
pguibert6WIND committed Apr 5, 2024
1 parent 925d780 commit d0b1b2f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
4 changes: 4 additions & 0 deletions bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1892,6 +1892,10 @@ static enum bgp_fsm_state_progress bgp_start(struct peer_connection *connection)
__func__, peer->connection->fd);
return BGP_FSM_FAILURE;
}
/* after connect is called(), getpeername is able to return
* port and address on non established streams
*/
bgp_updatesockname(peer);
/*
* - when the socket becomes ready, poll() will signify POLLOUT
* - if it fails to connect, poll() will signify POLLHUP
Expand Down
28 changes: 28 additions & 0 deletions bgpd/bgp_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,34 @@ int bgp_connect(struct peer_connection *connection)
htons(peer->port), ifindex);
}

void bgp_updatesockname(struct peer *peer)
{
union sockunion *su_local; /* Sockunion of local address. */
union sockunion *su_remote; /* Sockunion of remote address. */

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

if (su_local) {
if (peer->su_local)
sockunion_free(peer->su_local);
peer->su_local = su_local;
}
if (su_remote) {
if (peer->su_remote)
sockunion_free(peer->su_remote);
peer->su_remote = su_remote;
} else if (!peer->su_remote &&
!BGP_CONNECTION_SU_UNSPEC(peer->connection)) {
/* if connect initiated, then dest port and dest addresses are well known */
peer->su_remote = sockunion_dup(&peer->connection->su);
if (sockunion_family(peer->su_remote) == AF_INET)
peer->su_remote->sin.sin_port = htons(peer->port);
else if (sockunion_family(peer->su_remote) == AF_INET6)
peer->su_remote->sin6.sin6_port = htons(peer->port);
}
}

/* After TCP connection is established. Get local address and port. */
int bgp_getsockname(struct peer *peer)
{
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extern void bgp_close_vrf_socket(struct bgp *bgp);
extern void bgp_close(void);
extern int bgp_connect(struct peer_connection *connection);
extern int bgp_getsockname(struct peer *peer);
extern void bgp_updatesockname(struct peer *peer);

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

0 comments on commit d0b1b2f

Please sign in to comment.