1 /*
2 * BIRD -- Bidirectional Forwarding Detection (BFD)
3 *
4 * Can be freely distributed and used under the terms of the GNU GPL.
5 */
6
7 #ifndef _BIRD_BFD_H_
8 #define _BIRD_BFD_H_
9
10 #include <pthread.h>
11
12 #include "nest/bird.h"
13 #include "nest/cli.h"
14 #include "nest/iface.h"
15 #include "nest/protocol.h"
16 #include "nest/route.h"
17 #include "nest/password.h"
18 #include "conf/conf.h"
19 #include "lib/hash.h"
20 #include "lib/resource.h"
21 #include "lib/socket.h"
22 #include "lib/string.h"
23
24 #include "nest/bfd.h"
25 #include "io.h"
26
27
28 #define BFD_CONTROL_PORT 3784
29 #define BFD_ECHO_PORT 3785
30 #define BFD_MULTI_CTL_PORT 4784
31
32 #define BFD_DEFAULT_MIN_RX_INT (10 MS_)
33 #define BFD_DEFAULT_MIN_TX_INT (100 MS_)
34 #define BFD_DEFAULT_IDLE_TX_INT (1 S_)
35 #define BFD_DEFAULT_MULTIPLIER 5
36
37
38 struct bfd_iface_config;
39
40 struct bfd_config
41 {
42 struct proto_config c;
43 list patt_list; /* List of iface configs (struct bfd_iface_config) */
44 list neigh_list; /* List of configured neighbors (struct bfd_neighbor) */
45 struct bfd_iface_config *multihop; /* Multihop pseudoiface config */
46 u8 accept_ipv4;
47 u8 accept_ipv6;
48 u8 accept_direct;
49 u8 accept_multihop;
50 };
51
52 struct bfd_iface_config
53 {
54 struct iface_patt i;
55 u32 min_rx_int;
56 u32 min_tx_int;
57 u32 idle_tx_int;
58 u8 multiplier;
59 u8 passive;
60 u8 auth_type; /* Authentication type (BFD_AUTH_*) */
61 list *passwords; /* Passwords for authentication */
62 };
63
64 struct bfd_session_config
65 {
66 u32 min_rx_int;
67 u32 min_tx_int;
68 u32 idle_tx_int;
69 u8 multiplier;
70 u8 passive;
71 };
72
73 struct bfd_neighbor
74 {
75 node n;
76 ip_addr addr;
77 ip_addr local;
78 struct iface *iface;
79
80 struct neighbor *neigh;
81 struct bfd_request *req;
82
83 u8 multihop;
84 u8 active;
85 };
86
87 struct bfd_proto
88 {
89 struct proto p;
90 struct birdloop *loop;
91 pool *tpool;
92 pthread_spinlock_t lock;
93 node bfd_node;
94
95 slab *session_slab;
96 HASH(struct bfd_session) session_hash_id;
97 HASH(struct bfd_session) session_hash_ip;
98
99 sock *notify_rs;
100 sock *notify_ws;
101 list notify_list;
102
103 sock *rx4_1;
104 sock *rx6_1;
105 sock *rx4_m;
106 sock *rx6_m;
107 list iface_list;
108 };
109
110 struct bfd_iface
111 {
112 node n;
113 ip_addr local;
114 struct iface *iface;
115 struct bfd_iface_config *cf;
116 struct bfd_proto *bfd;
117
118 sock *sk;
119 u32 uc;
120 u8 changed;
121 };
122
123 struct bfd_session
124 {
125 node n;
126 ip_addr addr; /* Address of session */
127 struct bfd_iface *ifa; /* Iface associated with session */
128 struct bfd_session *next_id; /* Next in bfd.session_hash_id */
129 struct bfd_session *next_ip; /* Next in bfd.session_hash_ip */
130
131 u8 opened_unused;
132 u8 passive;
133 u8 poll_active;
134 u8 poll_scheduled;
135
136 u8 loc_state;
137 u8 rem_state;
138 u8 loc_diag;
139 u8 rem_diag;
140 u32 loc_id; /* Local session ID (local discriminator) */
141 u32 rem_id; /* Remote session ID (remote discriminator) */
142
143 struct bfd_session_config cf; /* Static configuration parameters */
144
145 u32 des_min_tx_int; /* Desired min rx interval, local option */
146 u32 des_min_tx_new; /* Used for des_min_tx_int change */
147 u32 req_min_rx_int; /* Required min tx interval, local option */
148 u32 req_min_rx_new; /* Used for req_min_rx_int change */
149 u32 rem_min_tx_int; /* Last received des_min_tx_int */
150 u32 rem_min_rx_int; /* Last received req_min_rx_int */
151 u8 demand_mode; /* Currently unused */
152 u8 rem_demand_mode;
153 u8 detect_mult; /* Announced detect_mult, local option */
154 u8 rem_detect_mult; /* Last received detect_mult */
155
156 uint ifindex; /* Iface index, for hashing in bfd.session_hash_ip */
157 btime last_tx; /* Time of last sent periodic control packet */
158 btime last_rx; /* Time of last received valid control packet */
159
160 timer *tx_timer; /* Periodic control packet timer */
161 timer *hold_timer; /* Timer for session down detection time */
162
163 list request_list; /* List of client requests (struct bfd_request) */
164 btime last_state_change; /* Time of last state change */
165 u8 notify_running; /* 1 if notify hooks are running */
166
167 u8 rx_csn_known; /* Received crypto sequence number is known */
168 u32 rx_csn; /* Last received crypto sequence number */
169 u32 tx_csn; /* Last transmitted crypto sequence number */
170 u32 tx_csn_time; /* Timestamp of last tx_csn change */
171 };
172
173
174 extern const char *bfd_state_names[];
175
176 #define BFD_STATE_ADMIN_DOWN 0
177 #define BFD_STATE_DOWN 1
178 #define BFD_STATE_INIT 2
179 #define BFD_STATE_UP 3
180
181 #define BFD_DIAG_NOTHING 0
182 #define BFD_DIAG_TIMEOUT 1
183 #define BFD_DIAG_ECHO_FAILED 2
184 #define BFD_DIAG_NEIGHBOR_DOWN 3
185 #define BFD_DIAG_FWD_RESET 4
186 #define BFD_DIAG_PATH_DOWN 5
187 #define BFD_DIAG_C_PATH_DOWN 6
188 #define BFD_DIAG_ADMIN_DOWN 7
189 #define BFD_DIAG_RC_PATH_DOWN 8
190
191 #define BFD_POLL_TX 1
192 #define BFD_POLL_RX 2
193
194 #define BFD_FLAGS 0x3f
195 #define BFD_FLAG_POLL (1 << 5)
196 #define BFD_FLAG_FINAL (1 << 4)
197 #define BFD_FLAG_CPI (1 << 3)
198 #define BFD_FLAG_AP (1 << 2)
199 #define BFD_FLAG_DEMAND (1 << 1)
200 #define BFD_FLAG_MULTIPOINT (1 << 0)
201
202 #define BFD_AUTH_NONE 0
203 #define BFD_AUTH_SIMPLE 1
204 #define BFD_AUTH_KEYED_MD5 2
205 #define BFD_AUTH_METICULOUS_KEYED_MD5 3
206 #define BFD_AUTH_KEYED_SHA1 4
207 #define BFD_AUTH_METICULOUS_KEYED_SHA1 5
208
209 extern const u8 bfd_auth_type_to_hash_alg[];
210
211
bfd_lock_sessions(struct bfd_proto * p)212 static inline void bfd_lock_sessions(struct bfd_proto *p) { pthread_spin_lock(&p->lock); }
bfd_unlock_sessions(struct bfd_proto * p)213 static inline void bfd_unlock_sessions(struct bfd_proto *p) { pthread_spin_unlock(&p->lock); }
214
215 /* bfd.c */
216 struct bfd_session * bfd_find_session_by_id(struct bfd_proto *p, u32 id);
217 struct bfd_session * bfd_find_session_by_addr(struct bfd_proto *p, ip_addr addr, uint ifindex);
218 void bfd_session_process_ctl(struct bfd_session *s, u8 flags, u32 old_tx_int, u32 old_rx_int);
219 void bfd_show_sessions(struct proto *P);
220
221 /* packets.c */
222 void bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final);
223 sock * bfd_open_rx_sk(struct bfd_proto *p, int multihop, int inet_version);
224 sock * bfd_open_tx_sk(struct bfd_proto *p, ip_addr local, struct iface *ifa);
225
226
227 #endif /* _BIRD_BFD_H_ */
228