Skip to content

Commit

Permalink
This patch adds support for allowing BGP to create and bring up neighbor
Browse files Browse the repository at this point in the history
sessions dynamically. The operator configures a range of neighbor addresses
to which peering is allowed. The ranges are configured as subnets and
multiple ranges are allowed. Each range is associated with a peer-group
so that additional parameters can be configured.

BGP neighbor sessions are dynamically created when connections are initiated
by remote neighbors whose addresses fall within a configured range. The
sessions are deleted when the BGP connection terminates.

A limit on the number of neighbors allowed from each range of addresses
can be specified.

IPv4 and IPv6 peering is supported. Over the peering, any of the address
families configured for the peer-group can be negotiated.
  • Loading branch information
donaldsharp committed May 20, 2015
1 parent 3f9c736 commit f14e6fd
Show file tree
Hide file tree
Showing 8 changed files with 935 additions and 18 deletions.
37 changes: 36 additions & 1 deletion bgpd/bgp_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,15 @@ bgp_stop (struct peer *peer)
char orf_name[BUFSIZ];
int ret = 0;

if (peer_dynamic_neighbor(peer) &&
!(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE)))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
peer_delete (peer);
return -1;
}

/* Can't do this in Clearing; events are used for state transitions */
if (peer->status != Clearing)
{
Expand Down Expand Up @@ -1117,6 +1126,14 @@ bgp_stop_with_error (struct peer *peer)
if (peer->v_start >= (60 * 2))
peer->v_start = (60 * 2);

if (peer_dynamic_neighbor(peer))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
peer_delete (peer);
return -1;
}

return(bgp_stop (peer));
}

Expand All @@ -1128,6 +1145,14 @@ bgp_stop_with_notify (struct peer *peer, u_char code, u_char sub_code)
/* Send notify to remote peer */
bgp_notify_send (peer, code, sub_code);

if (peer_dynamic_neighbor(peer))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
peer_delete (peer);
return -1;
}

/* Clear start timer value to default. */
peer->v_start = BGP_INIT_START_TIMER;

Expand Down Expand Up @@ -1180,6 +1205,14 @@ bgp_connect_success (struct peer *peer)
static int
bgp_connect_fail (struct peer *peer)
{
if (peer_dynamic_neighbor(peer))
{
if (bgp_debug_neighbor_events(peer))
zlog_debug ("%s (dynamic neighbor) deleted", peer->host);
peer_delete (peer);
return -1;
}

return (bgp_stop (peer));
}

Expand Down Expand Up @@ -1737,9 +1770,11 @@ bgp_event_update (struct peer *peer, int event)
int ret = 0;
struct peer *other;
int passive_conn = 0;
int dyn_nbr;

other = peer->doppelganger;
passive_conn = (CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER)) ? 1 : 0;
dyn_nbr = peer_dynamic_neighbor(peer);

/* Logging this event. */
next = FSM [peer->status -1][event - 1].next_state;
Expand Down Expand Up @@ -1772,7 +1807,7 @@ bgp_event_update (struct peer *peer, int event)
bgp_timer_set (peer);

}
else if (!passive_conn && peer->bgp)
else if (!dyn_nbr && !passive_conn && peer->bgp)
{
/* If we got a return value of -1, that means there was an error, restart
* the FSM. If the peer structure was deleted
Expand Down
21 changes: 20 additions & 1 deletion bgpd/bgp_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,30 @@ bgp_accept (struct thread *thread)

/* Check remote IP address */
peer1 = peer_lookup (NULL, &su);

if (! peer1)
{
peer1 = peer_lookup_dynamic_neighbor (NULL, &su);
if (peer1)
{
/* Dynamic neighbor has been created, let it proceed */
peer1->fd = bgp_sock;
bgp_fsm_change_status(peer1, Active);
BGP_TIMER_OFF(peer1->t_start); /* created in peer_create() */

if (peer_active (peer1))
BGP_EVENT_ADD (peer1, TCP_connection_open);

return 0;
}
}

if (! peer1)
{
if (bgp_debug_neighbor_events(peer))
{
zlog_debug ("[Event] BGP connection IP address %s is not configured",
zlog_debug ("[Event] %s connection rejected - not configured"
" and not valid for dynamic",
inet_sutop (&su, buf));
}
close (bgp_sock);
Expand Down
4 changes: 4 additions & 0 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2508,6 +2508,10 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
}

/* Dynamic peers will just close their connection. */
if (peer_dynamic_neighbor (peer))
return 1;

/* restart timer start */
if (peer->pmax_restart[afi][safi])
{
Expand Down
Loading

0 comments on commit f14e6fd

Please sign in to comment.