* nor RFC2385 (which requires a kernel patch on 2.4 kernels).
*/
-char const *cvs_id_bgp = "$Id: bgp.c,v 1.12 2005/09/02 23:39:36 bodea Exp $";
-
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
+#include "dhcp6.h"
#include "l2tpns.h"
#include "bgp.h"
#include "util.h"
static void bgp_clear(struct bgp_peer *peer);
static void bgp_set_retry(struct bgp_peer *peer);
-static void bgp_cidr(in_addr_t ip, in_addr_t mask, struct bgp_ip_prefix *pfx);
static struct bgp_route_list *bgp_insert_route(struct bgp_route_list *head,
struct bgp_route_list *new);
static struct bgp_route6_list *bgp_insert_route6(struct bgp_route6_list *head,
struct bgp_route6_list *new);
+static void bgp_process_timers(struct bgp_peer *peer);
static void bgp_free_routes(struct bgp_route_list *routes);
static void bgp_free_routes6(struct bgp_route6_list *routes);
static char const *bgp_msg_type_str(uint8_t type);
bgp_halt(peer); /* give up */
}
-/* convert ip/mask to CIDR notation */
-static void bgp_cidr(in_addr_t ip, in_addr_t mask, struct bgp_ip_prefix *pfx)
-{
- int i;
- uint32_t b;
-
- /* convert to prefix notation */
- pfx->len = 32;
- pfx->prefix = ip;
-
- if (!mask) /* bogus */
- mask = 0xffffffff;
-
- for (i = 0; i < 32 && ((b = ntohl(1 << i)), !(mask & b)); i++)
- {
- pfx->len--;
- pfx->prefix &= ~b;
- }
-}
-
/* insert route into list; sorted */
static struct bgp_route_list *bgp_insert_route(struct bgp_route_list *head,
struct bgp_route_list *new)
* that if that route is later deleted we don't have to be concerned
* about adding back the more specific one).
*/
-int bgp_add_route(in_addr_t ip, in_addr_t mask)
+int bgp_add_route(in_addr_t ip, int prefixlen)
{
struct bgp_route_list *r = bgp_routes;
struct bgp_route_list add;
int i;
- bgp_cidr(ip, mask, &add.dest);
+ add.dest.prefix = ip;
+ add.dest.len = prefixlen;
add.next = 0;
/* check for duplicate */
}
/* remove route from list for peers */
-int bgp_del_route(in_addr_t ip, in_addr_t mask)
+int bgp_del_route(in_addr_t ip, int prefixlen)
{
struct bgp_route_list *r = bgp_routes;
struct bgp_route_list *e = 0;
struct bgp_route_list del;
int i;
- bgp_cidr(ip, mask, &del.dest);
+ del.dest.prefix = ip;
+ del.dest.len = prefixlen;
del.next = 0;
/* find entry in routes list and remove */
}
/* process timers */
- if (peer->state == Established)
- {
- if (time_now > peer->expire_time)
- {
- LOG(1, 0, 0, "No message from BGP peer %s in %ds\n",
- peer->name, peer->hold);
+ bgp_process_timers(peer);
+ }
- bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
- continue;
- }
+ return 1;
+}
- if (time_now > peer->keepalive_time && !peer->outbuf->packet.header.len)
- bgp_send_keepalive(peer);
- }
- else if (peer->state == Idle)
- {
- if (time_now > peer->retry_time)
- bgp_connect(peer);
- }
- else if (time_now > peer->state_time + BGP_STATE_TIME)
+/* process bgp timers only */
+void bgp_process_peers_timers()
+{
+ int i;
+
+ if (!bgp_configured)
+ return;
+
+ for (i = 0; i < BGP_NUM_PEERS; i++)
+ {
+ struct bgp_peer *peer = &bgp_peers[i];
+
+ if (peer->state == Disabled)
+ continue;
+
+ bgp_process_timers(peer);
+ }
+}
+
+static void bgp_process_timers(struct bgp_peer *peer)
+{
+ if (peer->state == Established)
+ {
+ if (time_now > peer->expire_time)
{
- LOG(1, 0, 0, "%s timer expired for BGP peer %s\n",
- bgp_state_str(peer->state), peer->name);
+ LOG(1, 0, 0, "No message from BGP peer %s in %ds\n",
+ peer->name, peer->hold);
- bgp_restart(peer);
+ bgp_send_notification(peer, BGP_ERR_HOLD_TIMER_EXP, 0);
+ return;
}
+
+ if (time_now > peer->keepalive_time && !peer->outbuf->packet.header.len)
+ bgp_send_keepalive(peer);
}
+ else if (peer->state == Idle)
+ {
+ if (time_now > peer->retry_time)
+ bgp_connect(peer);
+ }
+ else if (time_now > peer->state_time + BGP_STATE_TIME)
+ {
+ LOG(1, 0, 0, "%s timer expired for BGP peer %s\n",
+ bgp_state_str(peer->state), peer->name);
- return 1;
+ bgp_restart(peer);
+ }
}
static void bgp_free_routes(struct bgp_route_list *routes)
data.version = BGP_VERSION;
data.as = htons(our_as);
data.hold_time = htons(peer->hold);
- data.identifier = my_address;
+ /* use the source IP we use as identifier, if available */
+ if (peer->source_addr != INADDR_ANY)
+ data.identifier = peer->source_addr;
+ else
+ data.identifier = my_address;
/* if we know peer doesn't support MP (mp_handling == DoesntHandleIPv6Routes)
then don't add this parameter */