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