summaryrefslogtreecommitdiffstats
path: root/bgpd/bgpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgpd.c')
-rw-r--r--bgpd/bgpd.c221
1 files changed, 108 insertions, 113 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 539996f8..8eb0d2e4 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -684,7 +684,7 @@ peer_sort (struct peer *peer)
}
}
-void
+static inline void
peer_free (struct peer *peer)
{
assert (peer->status == Deleted);
@@ -697,8 +697,6 @@ peer_free (struct peer *peer)
BGP_WRITE_OFF (peer->t_write);
BGP_EVENT_FLUSH (peer);
- bgp_unlock (peer->bgp);
-
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);
@@ -722,6 +720,48 @@ peer_free (struct peer *peer)
XFREE (MTYPE_BGP_PEER, peer);
}
+/* increase reference count on a struct peer */
+struct peer *
+peer_lock (struct peer *peer)
+{
+ assert (peer && (peer->lock >= 0));
+ assert (peer->status != Deleted);
+
+ peer->lock++;
+
+ return peer;
+}
+
+/* decrease reference count on a struct peer
+ * struct peer is freed and NULL returned if last reference
+ */
+struct peer *
+peer_unlock (struct peer *peer)
+{
+ assert (peer && (peer->lock > 0));
+
+ peer->lock--;
+
+ if (peer->lock == 0)
+ {
+#if 0
+ zlog_debug ("unlocked and freeing");
+ zlog_backtrace (LOG_DEBUG);
+#endif
+ peer_free (peer);
+ return NULL;
+ }
+
+#if 0
+ if (peer->lock == 1)
+ {
+ zlog_debug ("unlocked to 1");
+ zlog_backtrace (LOG_DEBUG);
+ }
+#endif
+
+ return peer;
+}
/* Allocate new peer object, implicitely locked. */
static struct peer *
@@ -749,7 +789,7 @@ peer_new (struct bgp *bgp)
peer->ostatus = Idle;
peer->weight = 0;
peer->password = NULL;
- peer->bgp = bgp_lock (bgp);
+ peer->bgp = bgp;
peer = peer_lock (peer); /* initial reference */
/* Set default flags. */
@@ -1150,7 +1190,7 @@ peer_delete (struct peer *peer)
if ((pn = listnode_lookup (peer->group->peer, peer)))
{
- peer_unlock (peer); /* group->peer list reference */
+ peer = peer_unlock (peer); /* group->peer list reference */
list_delete_node (peer->group->peer, pn);
}
peer->group = NULL;
@@ -1164,19 +1204,16 @@ peer_delete (struct peer *peer)
bgp_stop (peer);
bgp_fsm_change_status (peer, Deleted);
-#ifdef HAVE_TCP_MD5SIG
/* Password configuration */
if (peer->password)
{
- free (peer->password);
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
- && sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, NULL);
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ bgp_md5_set (peer);
}
-#endif /* HAVE_TCP_MD5SIG */
-
+
bgp_timer_set (peer); /* stops all timers for Deleted */
/* Delete from all peer list. */
@@ -1203,10 +1240,7 @@ peer_delete (struct peer *peer)
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
- {
- bgp_table_finish (peer->rib[afi][safi]);
- peer->rib[afi][safi] = NULL;
- }
+ bgp_table_finish (&peer->rib[afi][safi]);
/* Buffers. */
if (peer->ibuf)
@@ -1287,19 +1321,15 @@ peer_group_active (struct peer *peer)
/* Peer group cofiguration. */
static struct peer_group *
-peer_group_new (struct bgp *bgp)
+peer_group_new ()
{
- struct peer_group *group;
-
- group = XCALLOC (MTYPE_PEER_GROUP, sizeof (struct peer_group));
- group->bgp = bgp_lock (bgp);
- return group;
+ return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP,
+ sizeof (struct peer_group));
}
static void
peer_group_free (struct peer_group *group)
{
- bgp_unlock (group->bgp);
XFREE (MTYPE_PEER_GROUP, group);
}
@@ -1326,7 +1356,8 @@ peer_group_get (struct bgp *bgp, const char *name)
if (group)
return group;
- group = peer_group_new (bgp);
+ group = peer_group_new ();
+ group->bgp = bgp;
group->name = strdup (name);
group->peer = list_new ();
group->conf = peer_new (bgp);
@@ -1398,26 +1429,16 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
else
peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
-#ifdef HAVE_TCP_MD5SIG
/* password apply */
- if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
- {
- if (peer->password)
- free (peer->password);
- peer->password = strdup (conf->password);
+ if (peer->password)
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
- }
- else if (peer->password)
- {
- free (peer->password);
- peer->password = NULL;
+ if (conf->password)
+ peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
+ else
+ peer->password = NULL;
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, NULL);
- }
-#endif /* HAVE_TCP_MD5SIG */
+ bgp_md5_set (peer);
/* maximum-prefix */
peer->pmax[afi][safi] = conf->pmax[afi][safi];
@@ -1800,8 +1821,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su,
list_delete_node (bgp->rsclient, pn);
}
- bgp_table_finish (peer->rib[afi][safi]);
- peer->rib[afi][safi] = NULL;
+ bgp_table_finish (&peer->rib[afi][safi]);
/* Import policy. */
if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
@@ -1889,7 +1909,6 @@ bgp_create (as_t *as, const char *name)
if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
return NULL;
- bgp_lock(bgp); /* initial reference */
bgp->peer_self = peer_new (bgp);
bgp->peer_self->host = strdup ("Static announcement");
@@ -2018,7 +2037,7 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
}
/* Delete BGP instance. */
-void
+int
bgp_delete (struct bgp *bgp)
{
struct peer *peer;
@@ -2026,6 +2045,7 @@ bgp_delete (struct bgp *bgp)
struct listnode *node;
struct listnode *next;
afi_t afi;
+ safi_t safi;
int i;
/* Delete static route. */
@@ -2050,16 +2070,7 @@ bgp_delete (struct bgp *bgp)
list_delete (bgp->rsclient);
listnode_delete (bm->bgp, bgp);
-
- bgp_unlock(bgp);
-}
-
-void
-bgp_free(struct bgp *bgp)
-{
- afi_t afi;
- safi_t safi;
-
+
if (bgp->name)
free (bgp->name);
@@ -2074,6 +2085,8 @@ bgp_free(struct bgp *bgp)
XFREE (MTYPE_ROUTE_TABLE,bgp->rib[afi][safi]);
}
XFREE (MTYPE_BGP, bgp);
+
+ return 0;
}
struct peer *
@@ -3389,26 +3402,25 @@ peer_local_as_unset (struct peer *peer)
return 0;
}
-#ifdef HAVE_TCP_MD5SIG
/* Set password for authenticating with the peer. */
int
peer_password_set (struct peer *peer, const char *password)
{
- struct peer_group *group;
struct listnode *nn, *nnode;
int len = password ? strlen(password) : 0;
+ int ret = BGP_SUCCESS;
if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
return BGP_ERR_INVALID_VALUE;
if (peer->password && strcmp (peer->password, password) == 0
&& ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
- return 0;
+ return 0;
- SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
if (peer->password)
- free (peer->password);
- peer->password = strdup (password);
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
+
+ peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
@@ -3416,50 +3428,46 @@ peer_password_set (struct peer *peer, const char *password)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
BGP_EVENT_ADD (peer, BGP_Stop);
-
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
- return 0;
+
+ return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED;
}
- group = peer->group;
- /* #42# LIST_LOOP (group->peer, peer, nn) */
- for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
+ for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
{
if (peer->password && strcmp (peer->password, password) == 0)
continue;
-
- SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
+
if (peer->password)
- free (peer->password);
- peer->password = strdup (password);
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
+
+ peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password);
if (peer->status == Established)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
BGP_EVENT_ADD (peer, BGP_Stop);
-
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
+
+ if (bgp_md5_set (peer) < 0)
+ ret = BGP_ERR_TCPSIG_FAILED;
}
- return 0;
+ return ret;
}
int
peer_password_unset (struct peer *peer)
{
- struct peer_group *group;
struct listnode *nn, *nnode;
- if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
- && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ if (!peer->password
+ && !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
- if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
+ if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer_group_active (peer)
- && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
+ && peer->group->conf->password
+ && strcmp (peer->group->conf->password, peer->password) == 0)
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
if (peer->status == Established)
@@ -3467,46 +3475,37 @@ peer_password_unset (struct peer *peer)
else
BGP_EVENT_ADD (peer, BGP_Stop);
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, NULL);
-
- UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
if (peer->password)
- free (peer->password);
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
+
peer->password = NULL;
+
+ bgp_md5_set (peer);
return 0;
}
- UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
- if (peer->password)
- free (peer->password);
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
- group = peer->group;
- /* #42# LIST_LOOP (group->peer, peer, nn) */
- for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
+ for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
{
- if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
+ if (!peer->password)
continue;
if (peer->status == Established)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
BGP_EVENT_ADD (peer, BGP_Stop);
-
- if (sockunion_family (&peer->su) == AF_INET)
- bgp_md5_set (bm->sock, &peer->su.sin, NULL);
-
- UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
- if (peer->password)
- free (peer->password);
+
+ XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
+
+ bgp_md5_set (peer);
}
return 0;
}
-#endif /* HAVE_TCP_MD5SIG */
/* Set distribute list to the peer. */
int
@@ -4513,13 +4512,13 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
vty_out (vty, " neighbor %s peer-group%s", addr,
VTY_NEWLINE);
if (peer->as)
- vty_out (vty, " neighbor %s remote-as %u%s", addr, (unsigned)peer->as,
+ vty_out (vty, " neighbor %s remote-as %d%s", addr, peer->as,
VTY_NEWLINE);
}
else
{
if (! g_peer->as)
- vty_out (vty, " neighbor %s remote-as %u%s", addr, (unsigned)peer->as,
+ vty_out (vty, " neighbor %s remote-as %d%s", addr, peer->as,
VTY_NEWLINE);
if (peer->af_group[AFI_IP][SAFI_UNICAST])
vty_out (vty, " neighbor %s peer-group %s%s", addr,
@@ -4545,19 +4544,17 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
-#ifdef HAVE_TCP_MD5SIG
/* Password. */
- if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
- if (! peer_group_active (peer)
- || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
+ if (peer->password)
+ if (!peer_group_active (peer)
+ || ! g_peer->password
|| strcmp (peer->password, g_peer->password) != 0)
vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
VTY_NEWLINE);
-#endif /* HAVE_TCP_MD5SIG */
/* BGP port. */
if (peer->port != BGP_PORT_DEFAULT)
- vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
+ vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
VTY_NEWLINE);
/* Local interface name. */
@@ -4920,7 +4917,7 @@ bgp_config_write (struct vty *vty)
vty_out (vty, "!%s", VTY_NEWLINE);
/* Router bgp ASN */
- vty_out (vty, "router bgp %u", (unsigned)bgp->as);
+ vty_out (vty, "router bgp %d", bgp->as);
if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
{
@@ -5087,12 +5084,10 @@ bgp_master_init (void)
bm = &bgp_master;
bm->bgp = list_new ();
+ bm->listen_sockets = list_new ();
bm->port = BGP_PORT_DEFAULT;
bm->master = thread_master_create ();
bm->start_time = time (NULL);
-#ifdef HAVE_TCP_MD5SIG
- bm->sock = -1;
-#endif /* HAVE_TCP_MD5SIG */
}