X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/08b8dffa7806b5cdb2de070199cb876dbfc037fa..e7c9a1993778e9ac375d7f956dda7c3c802a83a5:/bgp.c?ds=inline diff --git a/bgp.c b/bgp.c index 600c950..36894be 100644 --- a/bgp.c +++ b/bgp.c @@ -10,8 +10,6 @@ * 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 #include #include @@ -22,6 +20,7 @@ char const *cvs_id_bgp = "$Id: bgp.c,v 1.12 2005/09/02 23:39:36 bodea Exp $"; #include #include #include +#include #include "l2tpns.h" #include "bgp.h" @@ -29,12 +28,12 @@ char const *cvs_id_bgp = "$Id: bgp.c,v 1.12 2005/09/02 23:39:36 bodea Exp $"; 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); @@ -393,26 +392,6 @@ static void bgp_set_retry(struct bgp_peer *peer) 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) @@ -474,13 +453,14 @@ static struct bgp_route6_list *bgp_insert_route6(struct bgp_route6_list *head, * 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 */ @@ -573,14 +553,15 @@ int bgp_add_route6(struct in6_addr ip, int prefixlen) } /* 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 */ @@ -826,35 +807,59 @@ int bgp_process(uint32_t events[]) } /* 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) @@ -1383,7 +1388,11 @@ static int bgp_send_open(struct bgp_peer *peer) 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 */