Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
6a8d3f1c
Commit
6a8d3f1c
authored
Sep 16, 2013
by
Ondřej Zajíček
Browse files
BFD work in progress.
Now it compiles and mostly works.
parent
bf139664
Changes
21
Hide whitespace changes
Inline
Side-by-side
conf/confbase.Y
View file @
6a8d3f1c
...
...
@@ -73,6 +73,7 @@ CF_DECLS
%type <iface> ipa_scope
%type <i> expr bool pxlen
%type <i32> expr_us
%type <time> datetime
%type <a> ipa
%type <px> prefix prefix_or_ipa
...
...
@@ -86,7 +87,7 @@ CF_DECLS
%left '!'
%nonassoc '.'
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO)
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO
, XS, XMS, XUS
)
CF_GRAMMAR
...
...
@@ -124,6 +125,14 @@ expr:
$$ = SYM_VAL($1).i; }
;
/* XXX fix X* symbols, they collide with macros */
expr_us:
expr XS { $$ = (u32) $1 * 1000000; }
| expr XMS { $$ = (u32) $1 * 1000; }
| expr XUS { $$ = (u32) $1 * 1; }
;
/* expr_u16: expr { check_u16($1); $$ = $1; }; */
/* Switches */
...
...
configure.in
View file @
6a8d3f1c
...
...
@@ -47,11 +47,11 @@ AC_SUBST(runtimedir)
if test "$enable_ipv6" = yes ; then
ip=ipv6
SUFFIX=6
all_protocols=bgp,ospf,pipe,radv,rip,static
all_protocols=
bfd,
bgp,ospf,pipe,radv,rip,static
else
ip=ipv4
SUFFIX=""
all_protocols=bgp,ospf,pipe,rip,static
all_protocols=
bfd,
bgp,ospf,pipe,rip,static
fi
if test "$given_suffix" = yes ; then
...
...
@@ -92,7 +92,7 @@ if test "$bird_cflags_default" = yes ; then
BIRD_CHECK_GCC_OPTION(bird_cv_c_option_fno_strict_aliasing, -fno-strict-aliasing)
BIRD_CHECK_GCC_OPTION(bird_cv_c_option_fno_strict_overflow, -fno-strict-overflow)
CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wno-parentheses"
CFLAGS="$CFLAGS
-pthread
-Wall -Wstrict-prototypes -Wno-parentheses"
BIRD_ADD_GCC_OPTION(bird_cv_c_option_wno_pointer_sign, -Wno-pointer-sign)
BIRD_ADD_GCC_OPTION(bird_cv_c_option_fno_strict_aliasing, -fno-strict-aliasing)
BIRD_ADD_GCC_OPTION(bird_cv_c_option_fno_strict_overflow, -fno-strict-overflow)
...
...
lib/hash.h
View file @
6a8d3f1c
#define HASH(type) struct { type **data; uint
used, size
; }
#define HASH(type) struct { type **data; uint
count, order
; }
#define HASH_TYPE(v) typeof(** (v).data)
#define HASH_SIZE(v) ((v).size * sizeof(* (v).data))
#define HASH_SIZE(v) (1 << (v).order)
#define HASH_MASK(v) ((1 << (v).order)-1)
#define HASH_INIT(v,pool,isize) \
#define HASH_INIT(v,pool,init_order) \
({ \
(v).
used
= 0; \
(v).
size = (isize
);
\
(v).data = mb_allocz(pool, HASH_SIZE(v)
);
\
(v).
count
= 0; \
(v).
order = (init_order
); \
(v).data = mb_allocz(pool, HASH_SIZE(v)
* sizeof(* (v).data));
\
})
#define HASH_FIND(v,id,key) \
#define HASH_FIND(v,id,key
...
) \
({ \
HASH_TYPE(v) *_n = (v).data[id##_FN(key, (v).size)]; \
while (_n && !id##_EQ(_n, key)) \
_n = _n->id##_NEXT; \
uint _h = id##_FN((key)) & HASH_MASK(v); \
HASH_TYPE(v) *_n = (v).data[_h]; \
while (_n && !id##_EQ(id##_KEY(_n), (key))) \
_n = id##_NEXT(_n); \
_n; \
})
#define HASH_INSERT(v,id,
key,
node) \
#define HASH_INSERT(v,id,node)
\
({ \
HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size); \
node->id##_NEXT = *_nn; \
uint _h = id##_FN(id##_KEY((node))) & HASH_MASK(v); \
HASH_TYPE(v) **_nn = (v).data + _h; \
id##_NEXT(node) = *_nn; \
*_nn = node; \
(v).count++; \
})
#define HASH_D
ELET
E(v,id,
key)
\
#define HASH_D
O_REMOV
E(v,id,
_nn)
\
({ \
HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size); \
while ((*_nn) && !id##_EQ(*_nn, key)) \
_nn = &((*_nn)->id##_NEXT); \
\
HASH_TYPE(v) *_n = *_nn; \
if (_n) \
*_nn = _n->id##_NEXT; \
{ \
*_nn = id##_NEXT(_n); \
(v).count--; \
} \
_n; \
})
#define HASH_DELETE(v,id,key...) \
({ \
uint _h = id##_FN((key)) & HASH_MASK(v); \
HASH_TYPE(v) **_nn = (v).data + _h; \
\
while ((*_nn) && !id##_EQ(id##_KEY((*_nn)), (key))) \
_nn = &(id##_NEXT((*_nn))); \
\
HASH_DO_REMOVE(v,id,_nn); \
})
#define HASH_REMOVE(v,id,node) \
({ \
HASH_TYPE(v) **_nn = (v).data + id##_FN(key, (v).size); \
uint _h = id##_FN(id##_KEY((node))) & HASH_MASK(v); \
HASH_TYPE(v) **_nn = (v).data + _h; \
\
while ((*_nn) && (*_nn != (node))) \
_nn = &(
(*_nn)->
id##_NEXT); \
_nn = &(id##_NEXT
((*_nn))
); \
\
HASH_TYPE(v) *_n = *_nn; \
if (_n) \
*_nn = _n->id##_NEXT; \
_n; \
HASH_DO_REMOVE(v,id,_nn); \
})
#define HASH_REHASH(v,id,pool,step) \
({ \
HASH_TYPE(v) *_n, *_n2, **_od; \
uint _i, _s; \
\
_s = HASH_SIZE(v); \
_od = (v).data; \
(v).count = 0; \
(v).order += (step); \
(v).data = mb_allocz(pool, HASH_SIZE(v) * sizeof(* (v).data)); \
\
for (_i = 0; _i < _s; _i++) \
for (_n = _od[_i]; _n && (_n2 = id##_NEXT(_n), 1); _n = _n2) \
HASH_INSERT(v, id, _n); \
\
mb_free(_od); \
})
#define HASH_DEFINE_REHASH_FN(id, type) \
static void id##_REHASH_FN(void *v, pool *p, int step) \
{ HASH_REHASH(* (HASH(type) *) v, id, p, step); }
#define HASH_TRY_REHASH_UP(v,id,pool) \
({ \
if (((v).order < id##_REHASH_MAX) && ((v).count > HASH_SIZE(v))) \
id##_REHASH_FN(&v, pool, 1); \
})
#define HASH_TRY_REHASH_DOWN(v,id,pool) \
({ \
if (((v).order > id##_REHASH_MIN) && ((v).count < HASH_SIZE(v)/2)) \
id##_REHASH_FN(&v, pool, -1); \
})
#define HASH_WALK(v,next,n) \
do { \
HASH_TYPE(v) *n; \
uint _i; \
for (_i = 0; _i < ((v).size); _i++) \
uint _s = HASH_SIZE(v); \
for (_i = 0; _i < _s; _i++) \
for (n = (v).data[_i]; n; n = n->next)
#define HASH_WALK_END } while (0)
...
...
@@ -66,18 +114,10 @@
do { \
HASH_TYPE(v) *n, *_next; \
uint _i; \
for (_i = 0; _i < ((v).size); _i++) \
uint _s = HASH_SIZE(v); \
for (_i = 0; _i < _s; _i++) \
for (n = (v).data[_i]; n && (_next = n->next, 1); n = _next)
#define HASH_WALK_DELSAFE_END } while (0)
/*
define HASH_REHASH(s) \
({ \
type *_n; \
uint _i; \
for (_i = 0; _i < (size_f); _i++) \
for (_n = (hash)[_i]; _n != NULL; _n =
*/
lib/heap.h
View file @
6a8d3f1c
...
...
@@ -72,8 +72,8 @@
**/
#define HEAP_INIT(heap,num,type,less,swap) \
do { \
u
ns
_i = num; \
u
ns
_j, _l; \
u
int
_i = num; \
u
int
_j, _l; \
type x; \
while (_i >= 1) \
{ \
...
...
@@ -89,7 +89,7 @@
**/
#define HEAP_DELMIN(heap,num,type,less,swap) \
do { \
u
ns
_j, _l; \
u
int
_j, _l; \
type x; \
swap(heap,1,num,x); \
num--; \
...
...
@@ -102,7 +102,7 @@
**/
#define HEAP_INSERT(heap,num,type,less,swap) \
do { \
u
ns
_j, _u; \
u
int
_j, _u; \
type x; \
_j = num; \
HEAP_BUBBLE_UP_J(heap,num,less,swap); \
...
...
@@ -115,7 +115,7 @@
**/
#define HEAP_INCREASE(heap,num,type,less,swap,pos) \
do { \
u
ns
_j, _l; \
u
int
_j, _l; \
type x; \
_j = pos; \
HEAP_BUBBLE_DOWN_J(heap,num,less,swap); \
...
...
@@ -128,7 +128,7 @@
**/
#define HEAP_DECREASE(heap,num,type,less,swap,pos) \
do { \
u
ns
_j, _u; \
u
int
_j, _u; \
type x; \
_j = pos; \
HEAP_BUBBLE_UP_J(heap,num,less,swap); \
...
...
@@ -139,7 +139,7 @@
**/
#define HEAP_DELETE(heap,num,type,less,swap,pos) \
do { \
u
ns
_j, _l, _u; \
u
int
_j, _l, _u; \
type x; \
_j = pos; \
swap(heap,_j,num,x); \
...
...
lib/lists.c
View file @
6a8d3f1c
...
...
@@ -100,6 +100,25 @@ rem_node(node *n)
x
->
prev
=
z
;
}
/**
* rem2_node - remove a node from a list, with cleanup
* @n: node to be removed
*
* Removes a node @n from the list it's linked in and resets its pointers to NULL.
* Useful if you want to distinguish between linked and unlinked nodes.
*/
LIST_INLINE
void
rem2_node
(
node
*
n
)
{
node
*
z
=
n
->
prev
;
node
*
x
=
n
->
next
;
z
->
next
=
x
;
x
->
prev
=
z
;
n
->
next
=
NULL
;
n
->
prev
=
NULL
;
}
/**
* replace_node - replace a node in a list with another one
* @old: node to be removed
...
...
lib/lists.h
View file @
6a8d3f1c
...
...
@@ -51,6 +51,7 @@ typedef struct list { /* In fact two overlayed nodes */
void
add_tail
(
list
*
,
node
*
);
void
add_head
(
list
*
,
node
*
);
void
rem_node
(
node
*
);
void
rem2_node
(
node
*
);
void
add_tail_list
(
list
*
,
list
*
);
void
init_list
(
list
*
);
void
insert_node
(
node
*
,
node
*
);
...
...
lib/resource.c
View file @
6a8d3f1c
...
...
@@ -220,7 +220,8 @@ ralloc(pool *p, struct resclass *c)
bzero
(
r
,
c
->
size
);
r
->
class
=
c
;
add_tail
(
&
p
->
inside
,
&
r
->
n
);
if
(
p
)
add_tail
(
&
p
->
inside
,
&
r
->
n
);
return
r
;
}
...
...
@@ -423,6 +424,6 @@ buffer_realloc(void **buf, unsigned *size, unsigned need, unsigned item_size)
while
(
nsize
<
need
)
nsize
=
STEP_UP
(
nsize
);
*
buf
=
mb_realloc
(
*
buf
,
nsize
*
i
size
);
*
buf
=
mb_realloc
(
*
buf
,
nsize
*
item_
size
);
*
size
=
nsize
;
}
lib/resource.h
View file @
6a8d3f1c
...
...
@@ -52,7 +52,7 @@ extern pool root_pool;
void
*
mb_alloc
(
pool
*
,
unsigned
size
);
void
*
mb_allocz
(
pool
*
,
unsigned
size
);
void
*
mb_realloc
(
pool
*
p
,
void
*
m
,
unsigned
size
);
void
*
mb_realloc
(
void
*
m
,
unsigned
size
);
void
mb_free
(
void
*
);
/* Memory pools with linear allocation */
...
...
@@ -78,6 +78,9 @@ void sl_free(slab *, void *);
* outside resource manager and possibly sysdep code.
*/
void
buffer_realloc
(
void
**
buf
,
unsigned
*
size
,
unsigned
need
,
unsigned
item_size
);
#ifdef HAVE_LIBDMALLOC
/*
* The standard dmalloc macros tend to produce lots of namespace
...
...
@@ -103,3 +106,4 @@ void *xrealloc(void *, unsigned);
#endif
#endif
nest/proto.c
View file @
6a8d3f1c
...
...
@@ -718,6 +718,9 @@ protos_build(void)
#ifdef CONFIG_BGP
proto_build
(
&
proto_bgp
);
#endif
// XXX
proto_build
(
&
proto_bfd
);
proto_pool
=
rp_new
(
&
root_pool
,
"Protocols"
);
proto_flush_event
=
ev_new
(
proto_pool
);
proto_flush_event
->
hook
=
proto_flush_loop
;
...
...
nest/protocol.h
View file @
6a8d3f1c
...
...
@@ -75,7 +75,7 @@ void protos_dump_all(void);
extern
struct
protocol
proto_device
,
proto_radv
,
proto_rip
,
proto_static
,
proto_ospf
,
proto_pipe
,
proto_bgp
;
proto_ospf
,
proto_pipe
,
proto_bgp
,
proto_bfd
;
/*
* Routing Protocol Instance
...
...
@@ -358,6 +358,12 @@ void proto_notify_state(struct proto *p, unsigned state);
#define D_EVENTS 16
/* Protocol events */
#define D_PACKETS 32
/* Packets sent/received */
#ifndef PARSER
#define TRACE(flags, msg, args...) \
do { if (p->p.debug & flags) log(L_TRACE "%s: " msg, p->p.name , ## args ); } while(0)
#endif
/*
* MRTDump flags
*/
...
...
proto/bfd/Makefile
View file @
6a8d3f1c
source
=
bfd.c
source
=
bfd.c
packets.c io.c
root-rel
=
../../
dir-name
=
proto/bfd
...
...
proto/bfd/bfd.c
View file @
6a8d3f1c
#include
"nest/bird.h"
#include
"nest/iface.h"
#include
"nest/protocol.h"
#include
"nest/route.h"
#include
"nest/cli.h"
#include
"conf/conf.h"
#include
"lib/socket.h"
#include
"lib/resource.h"
#include
"lib/string.h"
/*
* BIRD -- Bidirectional Forwarding Detection (BFD)
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include
"bfd.h"
#define HASH_ID_KEY
loc_id
#define HASH_ID_NEXT
next_id
#define HASH_ID_EQ(a,b)
(
(a
)
==
(
b)
)
#define HASH_ID_FN(
a)
(
a
)
#define HASH_ID_KEY
(n) n->
loc_id
#define HASH_ID_NEXT
(n) n->
next_id
#define HASH_ID_EQ(a,b)
(a
==
b)
#define HASH_ID_FN(
k)
(
k
)
#define HASH_IP_KEY
addr
#define HASH_IP_NEXT
next_ip
#define HASH_IP_EQ(a,b)
((a)==(
b)
)
#define HASH_IP_FN(
a
)
(a == b
)
#define HASH_IP_KEY
(n) n->
addr
#define HASH_IP_NEXT
(n) n->
next_ip
#define HASH_IP_EQ(a,b)
ipa_equal(a,
b)
#define HASH_IP_FN(
k
)
ipa_hash(k
)
static
u32
bfd_get_free_id
(
struct
bfd_proto
*
p
)
{
u32
id
;
for
(
id
=
random_u32
();
1
;
id
++
)
if
(
id
&&
!
bfd_find_session_by_id
(
p
,
id
))
break
;
return
id
;
}
static
inline
void
bfd_notify_kick
(
struct
bfd_proto
*
p
);
static
void
bfd_
add_
session
(
struct
bfd_
proto
*
p
,
ip_addr
addr
,
struct
bfd_session_config
*
opts
)
static
void
bfd_session
_update_state
(
struct
bfd_
session
*
s
,
uint
state
,
uint
diag
)
{
birdloop_enter
(
p
->
loop
);
struct
bfd_session
*
s
=
sl_alloc
(
p
->
session_slab
);
bzero
(
s
,
sizeof
(
struct
bfd_session
));
struct
bfd_proto
*
p
=
s
->
bfd
;
int
notify
;
/* Initialization of state variables - see RFC 5880 3.8.1 */
s
->
loc_state
=
BFD_STATE_DOWN
;
s
->
rem_state
=
BFD_STATE_DOWN
;
s
->
loc_id
=
bfd_get_free_id
(
p
);
s
->
des_min_tx_int
=
s
->
des_min_tx_new
=
s
->
opts
->
idle_tx_int
;
s
->
req_min_rx_int
=
s
->
req_min_rx_new
=
s
->
opts
->
min_rx_int
;
s
->
detect_mult
=
s
->
opts
->
multiplier
;
s
->
rem_min_rx_int
=
1
;
HASH_INSERT
(
p
->
session_hash_id
,
HASH_ID
,
s
);
HASH_INSERT
(
p
->
session_hash_ip
,
HASH_IP
,
s
);
s
->
tx_timer
=
tm2_new_set
(
xxx
,
bfd_rx_timer_hook
,
s
,
0
,
0
);
s
->
hold_timer
=
tm2_new_set
(
xxx
,
bfd_hold_timer_hook
,
s
,
0
,
0
);
bfd_session_update_tx_interval
(
s
);
birdloop_leave
(
p
->
loop
);
}
static
void
bfd_open_session
(
struct
bfd_proto
*
p
,
struct
bfd_session
*
s
,
ip_addr
local
,
struct
iface
*
ifa
)
{
birdloop_enter
(
p
->
loop
);
if
(
s
->
loc_state
==
state
)
return
;
s
->
bsock
=
bfd_get_socket
(
p
,
local
,
ifa
);
s
->
local
=
local
;
s
->
iface
=
ifa
;
s
->
opened
=
1
;
//TRACE(D_EVENTS, "Session changed %I %d %d", s->addr, state, diag);
debug
(
"STATE %I %d %d %d
\n
"
,
s
->
addr
,
s
->
loc_state
,
state
,
diag
);
bfd_lock_sessions
(
p
);
s
->
loc_state
=
state
;
s
->
loc_diag
=
diag
;
bfd_session_control_tx_timer
(
s
);
notify
=
!
NODE_VALID
(
&
s
->
n
);
if
(
notify
)
add_tail
(
&
p
->
notify_list
,
&
s
->
n
);
bfd_unlock_sessions
(
p
);
birdloop_leave
(
p
->
loop
);
if
(
notify
)
bfd_notify_kick
(
p
);
}
static
void
bfd_
close_
session
(
struct
bfd_proto
*
p
,
struct
bfd_session
*
s
)
static
void
bfd_session
_timeout
(
struct
bfd_session
*
s
)
{
birdloop_enter
(
p
->
loop
);
bfd_free_socket
(
s
->
bsock
);
s
->
bsock
=
NULL
;
s
->
local
=
IPA_NONE
;
s
->
iface
=
NULL
;
s
->
opened
=
0
;
bfd_session_control_tx_timer
(
s
);
s
->
rem_state
=
BFD_STATE_DOWN
;
s
->
rem_id
=
0
;
s
->
rem_min_tx_int
=
0
;
s
->
rem_min_rx_int
=
1
;
s
->
rem_demand_mode
=
0
;
s
->
rem_detect_mult
=
0
;
b
irdloop_leave
(
p
->
loop
);
b
fd_session_update_state
(
s
,
BFD_STATE_DOWN
,
BFD_DIAG_TIMEOUT
);
}
static
void
bfd_
remove_session
(
struct
bfd_proto
*
p
,
struct
bfd_session
*
s
)
bfd_
session_update_tx_interval
(
struct
bfd_session
*
s
)
{
birdloop_enter
(
p
->
loop
);
bfd_free_socket
(
s
->
bsock
);
rfree
(
s
->
tx_timer
);
rfree
(
s
->
hold_timer
);
HASH_REMOVE
(
p
->
session_hash_id
,
HASH_ID
,
s
);
HASH_REMOVE
(
p
->
session_hash_ip
,
HASH_IP
,
s
);
sl_free
(
p
->
session_slab
,
s
);
u32
tx_int
=
MAX
(
s
->
des_min_tx_int
,
s
->
rem_min_rx_int
);
u32
tx_int_l
=
tx_int
-
(
tx_int
/
4
);
// 75 %
u32
tx_int_h
=
tx_int
-
(
tx_int
/
10
);
// 90 %
birdloop_leave
(
p
->
loop
)
;
}
s
->
tx_timer
->
recurrent
=
tx_int_l
;
s
->
tx_timer
->
randomize
=
tx_int_h
-
tx_int_l
;
struct
bfd_session
*
bfd_find_session_by_id
(
struct
bfd_proto
*
p
,
u32
id
)
{
return
HASH_FIND
(
p
->
session_hash_id
,
HASH_ID
,
id
);
}
/* Do not set timer if no previous event */
if
(
!
s
->
last_tx
)
return
;
struct
bfd_session
*
bfd_find_session_by_addr
(
struct
bfd_proto
*
p
,
ip_addr
addr
)
{
return
HASH_FIND
(
p
->
session_hash_ip
,
HASH_IP
,
addr
);
/* Set timer relative to last tx_timer event */
tm2_set
(
s
->
tx_timer
,
s
->
last_tx
+
tx_int_l
);
}
static
void
bfd_
rx_timer_hook
(
timer2
*
t
)
bfd_
session_update_detection_time
(
struct
bfd_session
*
s
,
int
kick
)
{
struct
bfd_session
*
s
=
timer
->
data
;
btime
timeout
=
(
btime
)
MAX
(
s
->
req_min_rx_int
,
s
->
rem_min_tx_int
)
*
s
->
rem_detect_mult
;
s
->
last_tx
=
xxx_now
;
bfd_send_ctl
(
s
->
bfd
,
s
,
0
);
}
static
void
bfd_hold_timer_hook
(
timer2
*
t
)
{
bfd_session_timeout
(
timer
->
data
);
}
if
(
kick
)
s
->
last_rx
=
current_time
();
static
void
bfd_session_timeout
(
struct
bfd_session
*
s
)
{
s
->
rem_state
=
BFD_STATE_DOWN
;
s
->
rem_id
=
0
;
s
->
rem_min_tx_int
=
0
;
s
->
rem_min_rx_int
=
1
;
s
->
rem_demand_mode
=
0
;
if
(
!
s
->
last_rx
)
return
;
bfd_session_update_state
(
s
,
BFD_STATE_DOWN
,
BFD_DIAG_TIMEOUT
);
tm2_set
(
s
->
hold_timer
,
s
->
last_rx
+
timeout
);
}
static
void
...
...
@@ -178,38 +120,6 @@ bfd_session_control_tx_timer(struct bfd_session *s)
}
static
void
bfd_session_update_tx_interval
(
struct
bfd_session
*
s
)
{
u32
tx_int
=
MAX
(
s
->
des_min_tx_int
,
s
->
rem_min_rx_int
);
u32
tx_int_l
=
tx_int
-
(
tx_int
/
4
);
// 75 %
u32
tx_int_h
=
tx_int
-
(
tx_int
/
10
);
// 90 %
s
->
tx_timer
->
recurrent
=
tx_int_l
;
s
->
tx_timer
->
randomize
=
tx_int_h
-
tx_int_l
;
/* Do not set timer if no previous event */
if
(
!
s
->
last_tx
)
return
;
/* Set timer relative to last tx_timer event */
tm2_set
(
s
->
tx_timer
,
s
->
last_tx
+
tx_int_l
);
}
static
void
bfd_session_update_detection_time
(
struct
bfd_session
*
s
,
int
kick
)
{
xxx_time
timeout
=
(
xxx_time
)
MAX
(
s
->
req_min_rx_int
,
s
->
rem_min_tx_int
)
*
s
->
rem_detect_mult
;
if
(
kick
)
s
->
last_rx
=
xxx_now
;
if
(
!
s
->
last_rx
)
return
;
tm2_set
(
s
->
hold_timer
,
s
->
last_rx
+
timeout
);
}
void
bfd_session_request_poll
(
struct
bfd_session
*
s
,
u8
request
)
{
s
->
poll_scheduled
|=
request
;
...
...
@@ -222,7 +132,7 @@ bfd_session_request_poll(struct bfd_session *s, u8 request)
bfd_send_ctl
(
s
->
bfd
,
s
,
0
);
}
void
static
void
bfd_session_terminate_poll
(
struct
bfd_session
*
s
)
{
u8
poll_done
=
s
->
poll_active
&
~
s
->
poll_scheduled
;
...
...
@@ -237,16 +147,16 @@ bfd_session_terminate_poll(struct bfd_session *s)