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
538264cf
Commit
538264cf
authored
Jul 24, 2015
by
Ondřej Zajíček
Browse files
Static: Support for BFD controlled static routes
parent
1321e12a
Changes
4
Hide whitespace changes
Inline
Side-by-side
nest/bfd.h
View file @
538264cf
...
...
@@ -32,6 +32,12 @@ struct bfd_request {
};
#define BFD_STATE_ADMIN_DOWN 0
#define BFD_STATE_DOWN 1
#define BFD_STATE_INIT 2
#define BFD_STATE_UP 3
#ifdef CONFIG_BFD
struct
bfd_request
*
bfd_request_session
(
pool
*
p
,
ip_addr
addr
,
ip_addr
local
,
struct
iface
*
iface
,
void
(
*
hook
)(
struct
bfd_request
*
),
void
*
data
);
...
...
proto/static/config.Y
View file @
538264cf
...
...
@@ -16,10 +16,22 @@ CF_DEFINES
static struct static_route *this_srt, *this_srt_nh, *last_srt_nh;
static struct f_inst **this_srt_last_cmd;
static void
static_route_finish(void)
{
struct static_route *r;
/* Update undefined use_bfd entries in multipath nexthops */
if (this_srt->dest == RTD_MULTIPATH)
for (r = this_srt->mp_next; r; r = r->mp_next)
if (r->use_bfd < 0)
r->use_bfd = this_srt->use_bfd;
}
CF_DECLS
CF_KEYWORDS(STATIC, ROUTE, VIA, DROP, REJECT, PROHIBIT, PREFERENCE, CHECK, LINK)
CF_KEYWORDS(MULTIPATH, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE)
CF_KEYWORDS(MULTIPATH, WEIGHT, RECURSIVE, IGP, TABLE, BLACKHOLE, UNREACHABLE
, BFD
)
CF_GRAMMAR
...
...
@@ -37,7 +49,7 @@ static_proto:
| static_proto proto_item ';'
| static_proto CHECK LINK bool ';' { STATIC_CFG->check_link = $4; }
| static_proto IGP TABLE rtable ';' { STATIC_CFG->igp_table = $4; }
| static_proto stat_route stat_route_opt_list ';'
| static_proto stat_route stat_route_opt_list ';'
{ static_route_finish(); }
;
stat_route0: ROUTE prefix {
...
...
@@ -57,11 +69,15 @@ stat_multipath1:
this_srt_nh->via = $2;
this_srt_nh->via_if = $3;
this_srt_nh->if_name = (void *) this_srt; /* really */
this_srt_nh->use_bfd = -1; /* undefined */
}
| stat_multipath1 WEIGHT expr {
this_srt_nh->masklen = $3 - 1; /* really */
if (($3<1) || ($3>256)) cf_error("Weight must be in range 1-256");
}
| stat_multipath1 BFD bool {
this_srt_nh->use_bfd = $3; cf_check_bfd($3);
}
;
stat_multipath:
...
...
@@ -98,6 +114,7 @@ stat_route:
stat_route_item:
cmd { *this_srt_last_cmd = $1; this_srt_last_cmd = &($1->next); }
| BFD bool ';' { this_srt->use_bfd = $2; cf_check_bfd($2); }
;
stat_route_opts:
...
...
proto/static/static.c
View file @
538264cf
...
...
@@ -141,6 +141,29 @@ static_remove(struct proto *p, struct static_route *r)
r
->
installed
=
0
;
}
static
void
static_bfd_notify
(
struct
bfd_request
*
req
);
static
void
static_update_bfd
(
struct
proto
*
p
,
struct
static_route
*
r
)
{
struct
neighbor
*
nb
=
r
->
neigh
;
int
bfd_up
=
(
nb
->
scope
>
0
)
&&
r
->
use_bfd
;
if
(
bfd_up
&&
!
r
->
bfd_req
)
{
// ip_addr local = ipa_nonzero(r->local) ? r->local : nb->ifa->ip;
r
->
bfd_req
=
bfd_request_session
(
p
->
pool
,
r
->
via
,
nb
->
ifa
->
ip
,
nb
->
iface
,
static_bfd_notify
,
r
);
}
if
(
!
bfd_up
&&
r
->
bfd_req
)
{
rfree
(
r
->
bfd_req
);
r
->
bfd_req
=
NULL
;
}
}
static
int
static_decide
(
struct
static_config
*
cf
,
struct
static_route
*
r
)
{
...
...
@@ -153,6 +176,9 @@ static_decide(struct static_config *cf, struct static_route *r)
if
(
cf
->
check_link
&&
!
(
r
->
neigh
->
iface
->
flags
&
IF_LINK_UP
))
return
0
;
if
(
r
->
bfd_req
&&
r
->
bfd_req
->
state
!=
BFD_STATE_UP
)
return
0
;
return
1
;
}
...
...
@@ -171,6 +197,8 @@ static_add(struct proto *p, struct static_config *cf, struct static_route *r)
r
->
chain
=
n
->
data
;
n
->
data
=
r
;
r
->
neigh
=
n
;
static_update_bfd
(
p
,
r
);
if
(
static_decide
(
cf
,
r
))
static_install
(
p
,
r
,
n
->
iface
);
else
...
...
@@ -200,6 +228,8 @@ static_add(struct proto *p, struct static_config *cf, struct static_route *r)
r2
->
chain
=
n
->
data
;
n
->
data
=
r2
;
r2
->
neigh
=
n
;
static_update_bfd
(
p
,
r2
);
r2
->
installed
=
static_decide
(
cf
,
r2
);
count
+=
r2
->
installed
;
}
...
...
@@ -222,6 +252,26 @@ static_add(struct proto *p, struct static_config *cf, struct static_route *r)
}
}
static
void
static_rte_cleanup
(
struct
proto
*
p
,
struct
static_route
*
r
)
{
struct
static_route
*
r2
;
if
(
r
->
bfd_req
)
{
rfree
(
r
->
bfd_req
);
r
->
bfd_req
=
NULL
;
}
if
(
r
->
dest
==
RTD_MULTIPATH
)
for
(
r2
=
r
->
mp_next
;
r2
;
r2
=
r2
->
mp_next
)
if
(
r2
->
bfd_req
)
{
rfree
(
r2
->
bfd_req
);
r2
->
bfd_req
=
NULL
;
}
}
static
int
static_start
(
struct
proto
*
p
)
{
...
...
@@ -254,7 +304,10 @@ static_shutdown(struct proto *p)
WALK_LIST
(
r
,
cf
->
iface_routes
)
r
->
installed
=
0
;
WALK_LIST
(
r
,
cf
->
other_routes
)
{
static_rte_cleanup
(
p
,
r
);
r
->
installed
=
0
;
}
return
PS_DOWN
;
}
...
...
@@ -268,6 +321,44 @@ static_cleanup(struct proto *p)
rt_unlock_table
(
cf
->
igp_table
->
table
);
}
static
void
static_update_rte
(
struct
proto
*
p
,
struct
static_route
*
r
)
{
switch
(
r
->
dest
)
{
case
RTD_ROUTER
:
if
(
static_decide
((
struct
static_config
*
)
p
->
cf
,
r
))
static_install
(
p
,
r
,
r
->
neigh
->
iface
);
else
static_remove
(
p
,
r
);
break
;
case
RTD_NONE
:
/* a part of multipath route */
{
int
decision
=
static_decide
((
struct
static_config
*
)
p
->
cf
,
r
);
if
(
decision
==
r
->
installed
)
break
;
/* no change */
r
->
installed
=
decision
;
struct
static_route
*
r1
,
*
r2
;
int
count
=
0
;
r1
=
(
void
*
)
r
->
if_name
;
/* really */
for
(
r2
=
r1
->
mp_next
;
r2
;
r2
=
r2
->
mp_next
)
count
+=
r2
->
installed
;
if
(
count
)
{
/* Set of nexthops changed - force reinstall */
r1
->
installed
=
0
;
static_install
(
p
,
r1
,
NULL
);
}
else
static_remove
(
p
,
r1
);
break
;
}
}
}
static
void
static_neigh_notify
(
struct
neighbor
*
n
)
...
...
@@ -277,40 +368,21 @@ static_neigh_notify(struct neighbor *n)
DBG
(
"Static: neighbor notify for %I: iface %p
\n
"
,
n
->
addr
,
n
->
iface
);
for
(
r
=
n
->
data
;
r
;
r
=
r
->
chain
)
switch
(
r
->
dest
)
{
case
RTD_ROUTER
:
if
(
static_decide
((
struct
static_config
*
)
p
->
cf
,
r
))
static_install
(
p
,
r
,
n
->
iface
);
else
static_remove
(
p
,
r
);
break
;
{
static_update_bfd
(
p
,
r
);
static_update_rte
(
p
,
r
);
}
}
case
RTD_NONE
:
/* a part of multipath route */
{
int
decision
=
static_decide
((
struct
static_config
*
)
p
->
cf
,
r
);
if
(
decision
==
r
->
installed
)
break
;
/* no change */
r
->
installed
=
decision
;
struct
static_route
*
r1
,
*
r2
;
int
count
=
0
;
r1
=
(
void
*
)
r
->
if_name
;
/* really */
for
(
r2
=
r1
->
mp_next
;
r2
;
r2
=
r2
->
mp_next
)
count
+=
r2
->
installed
;
if
(
count
)
{
/* Set of nexthops changed - force reinstall */
r1
->
installed
=
0
;
static_install
(
p
,
r1
,
NULL
);
}
else
static_remove
(
p
,
r1
);
static
void
static_bfd_notify
(
struct
bfd_request
*
req
)
{
struct
static_route
*
r
=
req
->
data
;
struct
proto
*
p
=
r
->
neigh
->
proto
;
break
;
}
}
// if (req->down) TRACE(D_EVENTS, "BFD session down for nbr %I on %s", XXXX)
;
static_update_rte
(
p
,
r
);
}
static
void
...
...
@@ -414,7 +486,7 @@ static_same_dest(struct static_route *x, struct static_route *y)
for
(
x
=
x
->
mp_next
,
y
=
y
->
mp_next
;
x
&&
y
;
x
=
x
->
mp_next
,
y
=
y
->
mp_next
)
if
(
!
ipa_equal
(
x
->
via
,
y
->
via
)
||
(
x
->
via_if
!=
y
->
via_if
))
if
(
!
ipa_equal
(
x
->
via
,
y
->
via
)
||
(
x
->
via_if
!=
y
->
via_if
)
||
(
x
->
use_bfd
!=
y
->
use_bfd
)
)
return
0
;
return
!
x
&&
!
y
;
...
...
@@ -499,6 +571,9 @@ static_reconfigure(struct proto *p, struct proto_config *new)
WALK_LIST
(
r
,
n
->
other_routes
)
static_add
(
p
,
n
,
r
);
WALK_LIST
(
r
,
o
->
other_routes
)
static_rte_cleanup
(
p
,
r
);
return
1
;
}
...
...
@@ -584,13 +659,14 @@ static_show_rt(struct static_route *r)
case
RTDX_RECURSIVE
:
bsprintf
(
via
,
"recursive %I"
,
r
->
via
);
break
;
default:
bsprintf
(
via
,
"???"
);
}
cli_msg
(
-
1009
,
"%I/%d %s%s"
,
r
->
net
,
r
->
masklen
,
via
,
r
->
installed
?
""
:
" (dormant)"
);
cli_msg
(
-
1009
,
"%I/%d %s%s%s"
,
r
->
net
,
r
->
masklen
,
via
,
r
->
bfd_req
?
" (bfd)"
:
""
,
r
->
installed
?
""
:
" (dormant)"
);
struct
static_route
*
r2
;
if
(
r
->
dest
==
RTD_MULTIPATH
)
for
(
r2
=
r
->
mp_next
;
r2
;
r2
=
r2
->
mp_next
)
cli_msg
(
-
1009
,
"
\t
via %I%J weight %d%s"
,
r2
->
via
,
r2
->
via_if
,
r2
->
masklen
+
1
,
/* really */
r2
->
installed
?
""
:
" (dormant)"
);
cli_msg
(
-
1009
,
"
\t
via %I%J weight %d%s
%s
"
,
r2
->
via
,
r2
->
via_if
,
r2
->
masklen
+
1
,
/* really */
r2
->
bfd_req
?
" (bfd)"
:
""
,
r2
->
installed
?
""
:
" (dormant)"
);
}
void
...
...
proto/static/static.h
View file @
538264cf
...
...
@@ -9,6 +9,9 @@
#ifndef _BIRD_STATIC_H_
#define _BIRD_STATIC_H_
#include "nest/route.h"
#include "nest/bfd.h"
struct
static_config
{
struct
proto_config
c
;
list
iface_routes
;
/* Routes to search on interface events */
...
...
@@ -33,6 +36,8 @@ struct static_route {
struct
static_route
*
mp_next
;
/* Nexthops for RTD_MULTIPATH routes */
struct
f_inst
*
cmds
;
/* List of commands for setting attributes */
int
installed
;
/* Installed in rt table, -1 for reinstall */
int
use_bfd
;
/* Configured to use BFD */
struct
bfd_request
*
bfd_req
;
/* BFD request, if BFD is used */
};
/* Dummy nodes (parts of multipath route) abuses masklen field for weight
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment