Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
labs
BIRD Internet Routing Daemon
Commits
538264cf
Commit
538264cf
authored
Jul 24, 2015
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Static: Support for BFD controlled static routes
parent
1321e12a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
142 additions
and
38 deletions
+142
-38
nest/bfd.h
nest/bfd.h
+6
-0
proto/static/config.Y
proto/static/config.Y
+19
-2
proto/static/static.c
proto/static/static.c
+112
-36
proto/static/static.h
proto/static/static.h
+5
-0
No files found.
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