mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
22a0900ec2
When several BGPs requested a BFD session in short time, chances were that the second BGP would file a request while the pickup routine was still running and it would get enqueued into the waiting list instead of being picked up. Fixed this by enforcing pickup loop restart when new requests got added, and also by atomically moving the unpicked requests to a temporary list to announce admin down before actually being added into the wait list.
231 lines
5.8 KiB
C
231 lines
5.8 KiB
C
/*
|
|
* BIRD -- Bidirectional Forwarding Detection (BFD)
|
|
*
|
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
*/
|
|
|
|
#ifndef _BIRD_BFD_H_
|
|
#define _BIRD_BFD_H_
|
|
|
|
#include <pthread.h>
|
|
|
|
#include "nest/bird.h"
|
|
#include "nest/cli.h"
|
|
#include "nest/iface.h"
|
|
#include "nest/protocol.h"
|
|
#include "nest/rt.h"
|
|
#include "nest/password.h"
|
|
#include "conf/conf.h"
|
|
#include "lib/hash.h"
|
|
#include "lib/io-loop.h"
|
|
#include "lib/resource.h"
|
|
#include "lib/socket.h"
|
|
#include "lib/string.h"
|
|
|
|
#include "nest/bfd.h"
|
|
|
|
|
|
#define BFD_CONTROL_PORT 3784
|
|
#define BFD_ECHO_PORT 3785
|
|
#define BFD_MULTI_CTL_PORT 4784
|
|
|
|
#define BFD_DEFAULT_MIN_RX_INT (10 MS_)
|
|
#define BFD_DEFAULT_MIN_TX_INT (100 MS_)
|
|
#define BFD_DEFAULT_IDLE_TX_INT (1 S_)
|
|
#define BFD_DEFAULT_MULTIPLIER 5
|
|
|
|
|
|
struct bfd_iface_config;
|
|
|
|
struct bfd_config
|
|
{
|
|
struct proto_config c;
|
|
list patt_list; /* List of iface configs (struct bfd_iface_config) */
|
|
list neigh_list; /* List of configured neighbors (struct bfd_neighbor) */
|
|
struct bfd_iface_config *multihop; /* Multihop pseudoiface config */
|
|
u8 accept_ipv4;
|
|
u8 accept_ipv6;
|
|
u8 accept_direct;
|
|
u8 accept_multihop;
|
|
u8 strict_bind;
|
|
};
|
|
|
|
struct bfd_iface_config
|
|
{
|
|
struct iface_patt i;
|
|
u32 min_rx_int;
|
|
u32 min_tx_int;
|
|
u32 idle_tx_int;
|
|
u8 multiplier;
|
|
u8 passive;
|
|
u8 auth_type; /* Authentication type (BFD_AUTH_*) */
|
|
list *passwords; /* Passwords for authentication */
|
|
};
|
|
|
|
struct bfd_session_config
|
|
{
|
|
u32 min_rx_int;
|
|
u32 min_tx_int;
|
|
u32 idle_tx_int;
|
|
u8 multiplier;
|
|
u8 passive;
|
|
};
|
|
|
|
struct bfd_neighbor
|
|
{
|
|
node n;
|
|
ip_addr addr;
|
|
ip_addr local;
|
|
struct iface *iface;
|
|
|
|
struct neighbor *neigh;
|
|
struct bfd_request *req;
|
|
|
|
u8 multihop;
|
|
u8 active;
|
|
};
|
|
|
|
struct bfd_proto
|
|
{
|
|
struct proto p;
|
|
|
|
pthread_spinlock_t lock;
|
|
|
|
pool *tpool;
|
|
|
|
node bfd_node;
|
|
|
|
slab *session_slab;
|
|
HASH(struct bfd_session) session_hash_id;
|
|
HASH(struct bfd_session) session_hash_ip;
|
|
|
|
event notify_event;
|
|
list notify_list;
|
|
|
|
sock *rx4_1;
|
|
sock *rx6_1;
|
|
sock *rx4_m;
|
|
sock *rx6_m;
|
|
list iface_list;
|
|
};
|
|
|
|
struct bfd_iface
|
|
{
|
|
node n;
|
|
ip_addr local;
|
|
struct iface *iface;
|
|
struct bfd_iface_config *cf;
|
|
struct bfd_proto *bfd;
|
|
|
|
sock *sk;
|
|
sock *rx;
|
|
u32 uc;
|
|
u8 changed;
|
|
};
|
|
|
|
struct bfd_session
|
|
{
|
|
node n;
|
|
ip_addr addr; /* Address of session */
|
|
struct bfd_iface *ifa; /* Iface associated with session */
|
|
struct bfd_session *next_id; /* Next in bfd.session_hash_id */
|
|
struct bfd_session *next_ip; /* Next in bfd.session_hash_ip */
|
|
|
|
u8 opened_unused;
|
|
u8 passive;
|
|
u8 poll_active;
|
|
u8 poll_scheduled;
|
|
|
|
u8 loc_state;
|
|
u8 rem_state;
|
|
u8 loc_diag;
|
|
u8 rem_diag;
|
|
u32 loc_id; /* Local session ID (local discriminator) */
|
|
u32 rem_id; /* Remote session ID (remote discriminator) */
|
|
|
|
struct bfd_session_config cf; /* Static configuration parameters */
|
|
|
|
u32 des_min_tx_int; /* Desired min rx interval, local option */
|
|
u32 des_min_tx_new; /* Used for des_min_tx_int change */
|
|
u32 req_min_rx_int; /* Required min tx interval, local option */
|
|
u32 req_min_rx_new; /* Used for req_min_rx_int change */
|
|
u32 rem_min_tx_int; /* Last received des_min_tx_int */
|
|
u32 rem_min_rx_int; /* Last received req_min_rx_int */
|
|
u8 demand_mode; /* Currently unused */
|
|
u8 rem_demand_mode;
|
|
u8 detect_mult; /* Announced detect_mult, local option */
|
|
u8 rem_detect_mult; /* Last received detect_mult */
|
|
|
|
uint ifindex; /* Iface index, for hashing in bfd.session_hash_ip */
|
|
btime last_tx; /* Time of last sent periodic control packet */
|
|
btime last_rx; /* Time of last received valid control packet */
|
|
|
|
timer *tx_timer; /* Periodic control packet timer */
|
|
timer *hold_timer; /* Timer for session down detection time */
|
|
|
|
list request_list; /* List of client requests (struct bfd_request) */
|
|
btime last_state_change; /* Time of last state change */
|
|
|
|
u8 rx_csn_known; /* Received crypto sequence number is known */
|
|
u32 rx_csn; /* Last received crypto sequence number */
|
|
u32 tx_csn; /* Last transmitted crypto sequence number */
|
|
u32 tx_csn_time; /* Timestamp of last tx_csn change */
|
|
};
|
|
|
|
|
|
extern const char *bfd_state_names[];
|
|
|
|
#define BFD_STATE_ADMIN_DOWN 0
|
|
#define BFD_STATE_DOWN 1
|
|
#define BFD_STATE_INIT 2
|
|
#define BFD_STATE_UP 3
|
|
|
|
#define BFD_DIAG_NOTHING 0
|
|
#define BFD_DIAG_TIMEOUT 1
|
|
#define BFD_DIAG_ECHO_FAILED 2
|
|
#define BFD_DIAG_NEIGHBOR_DOWN 3
|
|
#define BFD_DIAG_FWD_RESET 4
|
|
#define BFD_DIAG_PATH_DOWN 5
|
|
#define BFD_DIAG_C_PATH_DOWN 6
|
|
#define BFD_DIAG_ADMIN_DOWN 7
|
|
#define BFD_DIAG_RC_PATH_DOWN 8
|
|
|
|
#define BFD_POLL_TX 1
|
|
#define BFD_POLL_RX 2
|
|
|
|
#define BFD_FLAGS 0x3f
|
|
#define BFD_FLAG_POLL (1 << 5)
|
|
#define BFD_FLAG_FINAL (1 << 4)
|
|
#define BFD_FLAG_CPI (1 << 3)
|
|
#define BFD_FLAG_AP (1 << 2)
|
|
#define BFD_FLAG_DEMAND (1 << 1)
|
|
#define BFD_FLAG_MULTIPOINT (1 << 0)
|
|
|
|
#define BFD_AUTH_NONE 0
|
|
#define BFD_AUTH_SIMPLE 1
|
|
#define BFD_AUTH_KEYED_MD5 2
|
|
#define BFD_AUTH_METICULOUS_KEYED_MD5 3
|
|
#define BFD_AUTH_KEYED_SHA1 4
|
|
#define BFD_AUTH_METICULOUS_KEYED_SHA1 5
|
|
|
|
extern const u8 bfd_auth_type_to_hash_alg[];
|
|
|
|
|
|
static inline void bfd_lock_sessions(struct bfd_proto *p) { pthread_spin_lock(&p->lock); }
|
|
static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unlock(&p->lock); }
|
|
|
|
/* bfd.c */
|
|
struct bfd_session * bfd_find_session_by_id(struct bfd_proto *p, u32 id);
|
|
struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex);
|
|
void bfd_session_process_ctl(struct bfd_session *s, u8 flags, u32 old_tx_int, u32 old_rx_int);
|
|
void bfd_show_sessions(struct proto *P);
|
|
|
|
/* packets.c */
|
|
void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final);
|
|
sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop, int inet_version);
|
|
sock * bfd_open_rx_sk_bound(struct bfd_proto *p, ip_addr local, struct iface *ifa);
|
|
sock * bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa);
|
|
|
|
|
|
#endif /* _BIRD_BFD_H_ */
|