1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
/*
* 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/route.h"
#include "nest/password.h"
#include "conf/conf.h"
#include "lib/hash.h"
#include "lib/resource.h"
#include "lib/socket.h"
#include "lib/string.h"
#include "nest/bfd.h"
#include "io.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;
struct birdloop *loop;
pool *tpool;
pthread_spinlock_t lock;
node bfd_node;
slab *session_slab;
HASH(struct bfd_session) session_hash_id;
HASH(struct bfd_session) session_hash_ip;
sock *notify_rs;
sock *notify_ws;
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 notify_running; /* 1 if notify hooks are running */
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, int details);
/* 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_ */
|