summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_network.c')
-rw-r--r--bgpd/bgp_network.c187
1 files changed, 60 insertions, 127 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index b5d66679..0c1072c9 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -27,13 +27,13 @@
#include "log.h"
#include "if.h"
#include "prefix.h"
-//#include "command.h"
#include "privs.h"
+#include "qpselect.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_network.h"
+#include "bgpd/bgp_peer_index.h"
-#include "bgpd/bgp_engine.h"
#include "bgpd/bgp_session.h"
#include "bgpd/bgp_connection.h"
#include "bgpd/bgp_fsm.h"
@@ -437,7 +437,6 @@ static void
bgp_accept_action(qps_file qf, void* file_info)
{
bgp_connection connection ;
- bgp_session session ;
union sockunion su_remote ;
union sockunion su_local ;
int exists ;
@@ -460,8 +459,8 @@ bgp_accept_action(qps_file qf, void* file_info)
inet_sutop(&su_remote, buf)) ;
/* See if we are ready to accept connections from the connecting party */
- session = bgp_session_index_seek(&su_remote, &exists) ;
- if (session != NULL)
+ connection = bgp_peer_index_seek_accept(&su_remote, &exists) ;
+ if (connection != NULL)
{
if (BGP_DEBUG(events, EVENTS))
zlog_debug(exists
@@ -484,7 +483,7 @@ bgp_accept_action(qps_file qf, void* file_info)
* except under the mutex, and will not destroy the session.
*/
- BGP_SESSION_LOCK(session) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ BGP_CONNECTION_SESSION_LOCK(connection) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
/* Set the common socket options.
* Does not set password -- that is inherited from the listener.
@@ -497,16 +496,15 @@ bgp_accept_action(qps_file qf, void* file_info)
ret = bgp_getsockname(fd, &su_local, &su_remote) ;
if (ret != 0)
- ret = bgp_socket_set_common_options(fd, &su_remote, session->ttl, NULL) ;
-
- connection = session->connections[bgp_connection_secondary] ;
+ ret = bgp_socket_set_common_options(fd, &su_remote,
+ connection->session->ttl, NULL) ;
if (ret == 0)
bgp_connection_open(connection, fd) ;
else
close(fd) ;
- BGP_SESSION_UNLOCK(session) ; /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ BGP_CONNECTION_SESSION_UNLOCK(connection) ; /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
/* Now kick the FSM in an appropriate fashion */
bgp_fsm_connect_completed(connection, ret, &su_local, &su_remote) ;
@@ -516,8 +514,8 @@ bgp_accept_action(qps_file qf, void* file_info)
* Open BGP Connection -- connect() to the other end
*/
-static int bgp_bind(bgp_connection connection) ;
-static int bgp_update_source (bgp_connection connection) ;
+static int bgp_bind_ifname(bgp_connection connection, int fd) ;
+static int bgp_bind_ifaddress(bgp_connection connection, int fd) ;
/*------------------------------------------------------------------------------
* Open BGP Connection -- connect() to the other end
@@ -534,7 +532,6 @@ static int bgp_update_source (bgp_connection connection) ;
extern void
bgp_open_connect(bgp_connection connection)
{
- unsigned int ifindex = 0 ;
int fd ;
int ret ;
union sockunion* su = connection->session->su_peer ;
@@ -550,18 +547,11 @@ bgp_open_connect(bgp_connection connection)
/* Bind socket. */
if (ret == 0)
- ret = bgp_bind(connection) ;
+ ret = bgp_bind_ifname(connection, fd) ;
/* Update source bind. */
if (ret == 0)
- ret = bgp_update_source(connection) ;
-
-#if 0 /* TODO: worry about peer->ifname and sessions ! */
-#ifdef HAVE_IPV6
- if (peer->ifname)
- ifindex = if_nametoindex(peer->ifname);
-#endif /* HAVE_IPV6 */
-#endif
+ ret = bgp_bind_ifaddress(connection, fd) ;
if (BGP_DEBUG(events, EVENTS))
plog_debug(connection->log, "%s [Event] Connect start to %s fd %d",
@@ -569,7 +559,8 @@ bgp_open_connect(bgp_connection connection)
/* Connect to the remote peer. */
if (ret == 0)
- ret = sockunion_connect(fd, su, connection->session->port, ifindex) ;
+ ret = sockunion_connect(fd, su, connection->session->port,
+ connection->session->ifindex) ;
/* does not report EINPROGRESS as an error. */
/* If not OK now, close the fd and signal the error */
@@ -669,6 +660,25 @@ bgp_connect_action(qps_file qf, void* file_info)
} ;
/*==============================================================================
+ * Set the TTL for the given connection (if any), if there is an fd.
+ */
+extern void
+bgp_set_ttl(bgp_connection connection, int ttl)
+{
+ int fd ;
+
+ if (connection == NULL)
+ return ;
+
+ fd = qps_file_fd(&connection->qf) ;
+ if (fd < 0)
+ return ;
+
+ if (ttl != 0)
+ sockopt_ttl(connection->paf, fd, ttl) ;
+} ;
+
+/*==============================================================================
* Get local and remote address and port for connection.
*/
static int
@@ -679,10 +689,6 @@ bgp_getsockname(int fd, union sockunion* su_local, union sockunion* su_remote)
ret_l = sockunion_getsockname(fd, su_local) ;
ret_r = sockunion_getpeername(fd, su_remote) ;
-#if 0 /* TODO: restore setting of peer->nexthop */
- bgp_nexthop_set(peer->su_local, peer->su_remote, &peer->nexthop, peer);
-#endif
-
return (ret_l != 0) ? ret_l : ret_r ;
} ;
@@ -691,9 +697,6 @@ bgp_getsockname(int fd, union sockunion* su_local, union sockunion* su_remote)
*
*/
-static struct in_addr* bgp_update_address (struct interface *ifp) ;
-static int bgp_bind_address (int sock, struct in_addr *addr) ;
-
/*------------------------------------------------------------------------------
* BGP socket bind.
*
@@ -705,34 +708,41 @@ static int bgp_bind_address (int sock, struct in_addr *addr) ;
* != 0 : error number (from errno or otherwise)
*/
static int
-bgp_bind(bgp_connection connection)
+bgp_bind_ifname(bgp_connection connection, int fd)
{
-#if 0 /* TODO: restore binding to specific interfaces */
#ifdef SO_BINDTODEVICE
- int ret;
+ int ret, retp ;
struct ifreq ifreq;
- if (! peer->ifname)
+ if (connection->session->ifname == NULL)
return 0;
- strncpy ((char *)&ifreq.ifr_name, peer->ifname, sizeof (ifreq.ifr_name));
+ strncpy ((char *)&ifreq.ifr_name, connection->session->ifname,
+ sizeof (ifreq.ifr_name));
- if ( bgpd_privs.change (ZPRIVS_RAISE) )
- zlog_err ("bgp_bind: could not raise privs");
+ ret = 0 ;
+ retp = 0 ;
+ if (bgpd_privs.change (ZPRIVS_RAISE))
+ {
+ zlog_err ("bgp_bind: could not raise privs");
+ retp = -1 ;
+ } ;
- ret = setsockopt (peer->fd, SOL_SOCKET, SO_BINDTODEVICE,
- &ifreq, sizeof (ifreq));
+ ret = setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, &ifreq, sizeof (ifreq));
if (bgpd_privs.change (ZPRIVS_LOWER) )
- zlog_err ("bgp_bind: could not lower privs");
+ {
+ zlog_err ("bgp_bind: could not lower privs");
+ retp = -1 ;
+ } ;
- if (ret < 0)
+ if ((ret < 0) || (retp < 0))
{
- zlog (peer->log, LOG_INFO, "bind to interface %s failed", peer->ifname);
- return ret;
+ zlog (connection->log, LOG_INFO, "bind to interface %s failed",
+ connection->session->ifname);
+ return -1 ;
}
#endif /* SO_BINDTODEVICE */
-#endif
return 0;
} ;
@@ -743,93 +753,16 @@ bgp_bind(bgp_connection connection)
* != 0 : error number (from errno or otherwise)
*/
static int
-bgp_update_source (bgp_connection connection)
+bgp_bind_ifaddress(bgp_connection connection, int fd)
{
-#if 0 /* TODO: restore update-source handling */
- struct interface *ifp;
- struct in_addr *addr;
-
- /* Source is specified with interface name. */
- if (peer->update_if)
+ if (connection->session->ifaddress != NULL)
{
- ifp = if_lookup_by_name (peer->update_if);
- if (! ifp)
- return;
-
- addr = bgp_update_address (ifp);
- if (! addr)
- return;
-
- bgp_bind_address (peer->fd, addr);
- }
-
- /* Source is specified with IP address. */
- if (peer->update_source)
- sockunion_bind (peer->fd, peer->update_source, 0, peer->update_source);
-#else
- return bgp_bind_address(0, bgp_update_address (NULL)) ;
- /* returns 0 -- avoid warnings */
-#endif
-} ;
-
-/*------------------------------------------------------------------------------
- * Bind given socket to given address... ???
- *
- */
-static int
-bgp_bind_address (int sock, struct in_addr *addr)
-{
-#if 0 /* TODO: restore update-source handling */
-
- int ret;
- struct sockaddr_in local;
-
- memset (&local, 0, sizeof (struct sockaddr_in));
- local.sin_family = AF_INET;
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
- local.sin_len = sizeof(struct sockaddr_in);
-#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
- memcpy (&local.sin_addr, addr, sizeof (struct in_addr));
-
- if ( bgpd_privs.change (ZPRIVS_RAISE) )
- zlog_err ("bgp_bind_address: could not raise privs");
-
- ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in));
- if (ret < 0)
- ;
-
- if (bgpd_privs.change (ZPRIVS_LOWER) )
- zlog_err ("bgp_bind_address: could not lower privs");
-
-#endif
- return 0;
+ union sockunion su = *(connection->session->ifaddress) ;
+ return sockunion_bind (fd, &su, 0, &su) ;
+ } ;
+ return 0 ;
} ;
-/*------------------------------------------------------------------------------
- * Update address.... ???
- *
- * Returns: address of IPv4 prefix
- * or: NULL
- */
-static struct in_addr *
-bgp_update_address (struct interface *ifp)
-{
-#if 0 /* TODO: restore update-source handling */
- struct prefix_ipv4 *p;
- struct connected *connected;
- struct listnode *node;
-
- for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
- {
- p = (struct prefix_ipv4 *) connected->address;
-
- if (p->family == AF_INET)
- return &p->prefix;
- }
-#endif
- return NULL;
-}
-
/*==============================================================================
* BGP Socket Option handling
*/