summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_network.c
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-01-27 22:37:55 +0000
committerChris Hall <GMCH@hestia.halldom.com>2010-01-27 22:37:55 +0000
commite29ed2adec0ef11ca1c84b40b2c98247f162f3df (patch)
treed0a65837f2a544c8e46f8ddda654e70686c531a1 /bgpd/bgp_network.c
parente6d986058f23f350aa6aedac4da5fe9f3afda6e8 (diff)
downloadquagga-e29ed2adec0ef11ca1c84b40b2c98247f162f3df.tar.bz2
quagga-e29ed2adec0ef11ca1c84b40b2c98247f162f3df.tar.xz
Binding to interfaces and counting of messages.
Wired up message counters in bgp_session structure. Added fields to session for neighbor interface and neighbor update-source -- so that these can be set when connect() is done. Peering Engine resolves any interface name to an address, so that BGP Engine doesn't have to. Reinstated as much code as necessary in bgp_network to bind to specific interfaces, as set in the session. Moved setting of bgp_nexthop_set() back into Routeing Engine. Result is that only Peering Engine talks to Zebra or uses the iflist. Wired up setting of TTL. Reworked connections locking of the session mutex so more robust if/when connections are cut loose from the session. Made peer_index entry point at connection, not session. Works better in bgp_network that way. modified: bgpd/bgp_connection.c modified: bgpd/bgp_connection.h modified: bgpd/bgp_fsm.c modified: bgpd/bgp_msg_read.c modified: bgpd/bgp_msg_write.c modified: bgpd/bgp_network.c modified: bgpd/bgp_network.h modified: bgpd/bgp_peer.c modified: bgpd/bgp_peer.h modified: bgpd/bgp_peer_index.c modified: bgpd/bgp_peer_index.h modified: bgpd/bgp_session.c modified: bgpd/bgp_session.h modified: lib/prefix.h modified: lib/sockunion.c modified: lib/sockunion.h
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
*/