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
78a2cc28
Commit
78a2cc28
authored
Jun 03, 2015
by
Ondřej Zajíček
Browse files
KRT: Fixes some minor bugs in kernel protocol
parent
d217ba51
Changes
2
Hide whitespace changes
Inline
Side-by-side
sysdep/linux/netlink.c
View file @
78a2cc28
...
...
@@ -703,6 +703,11 @@ nl_send_route(struct krt_proto *p, rte *e, struct ea_list *eattrs, int new)
r
.
r
.
rtm_scope
=
RT_SCOPE_UNIVERSE
;
nl_add_attr_ipa
(
&
r
.
h
,
sizeof
(
r
),
RTA_DST
,
net
->
n
.
prefix
);
/* For route delete, we do not specify route attributes */
if
(
!
new
)
return
nl_exchange
(
&
r
.
h
);
if
(
ea
=
ea_find
(
eattrs
,
EA_KRT_METRIC
))
nl_add_attr_u32
(
&
r
.
h
,
sizeof
(
r
),
RTA_PRIORITY
,
ea
->
u
.
data
);
...
...
sysdep/unix/krt.c
View file @
78a2cc28
...
...
@@ -592,6 +592,44 @@ krt_flush_routes(struct krt_proto *p)
FIB_WALK_END
;
}
static
struct
rte
*
krt_export_net
(
struct
krt_proto
*
p
,
net
*
net
,
rte
**
rt_free
,
ea_list
**
tmpa
)
{
struct
filter
*
filter
=
p
->
p
.
main_ahook
->
out_filter
;
rte
*
rt
;
rt
=
net
->
routes
;
*
rt_free
=
NULL
;
if
(
!
rte_is_valid
(
rt
))
return
NULL
;
if
(
filter
==
FILTER_REJECT
)
return
NULL
;
struct
proto
*
src
=
rt
->
attrs
->
src
->
proto
;
*
tmpa
=
src
->
make_tmp_attrs
?
src
->
make_tmp_attrs
(
rt
,
krt_filter_lp
)
:
NULL
;
/* We could run krt_import_control() here, but it is already handled by KRF_INSTALLED */
if
(
filter
==
FILTER_ACCEPT
)
goto
accept
;
if
(
f_run
(
filter
,
&
rt
,
tmpa
,
krt_filter_lp
,
FF_FORCE_TMPATTR
)
>
F_ACCEPT
)
goto
reject
;
accept:
if
(
rt
!=
net
->
routes
)
*
rt_free
=
rt
;
return
rt
;
reject:
if
(
rt
!=
net
->
routes
)
rte_free
(
rt
);
return
NULL
;
}
static
int
krt_same_dest
(
rte
*
k
,
rte
*
e
)
{
...
...
@@ -620,7 +658,6 @@ krt_same_dest(rte *k, rte *e)
void
krt_got_route
(
struct
krt_proto
*
p
,
rte
*
e
)
{
rte
*
old
;
net
*
net
=
e
->
net
;
int
verdict
;
...
...
@@ -663,15 +700,26 @@ krt_got_route(struct krt_proto *p, rte *e)
goto
sentenced
;
}
old
=
net
->
routes
;
if
((
net
->
n
.
flags
&
KRF_INSTALLED
)
&&
rte_is_valid
(
old
))
if
(
net
->
n
.
flags
&
KRF_INSTALLED
)
{
/* There may be changes in route attributes, we ignore that.
Also, this does not work well if gw is changed in export filter */
if
((
net
->
n
.
flags
&
KRF_SYNC_ERROR
)
||
!
krt_same_dest
(
e
,
old
))
rte
*
new
,
*
rt_free
;
ea_list
*
tmpa
;
new
=
krt_export_net
(
p
,
net
,
&
rt_free
,
&
tmpa
);
/* TODO: There also may be changes in route eattrs, we ignore that for now. */
if
(
!
new
)
verdict
=
KRF_DELETE
;
else
if
((
net
->
n
.
flags
&
KRF_SYNC_ERROR
)
||
!
krt_same_dest
(
e
,
new
))
verdict
=
KRF_UPDATE
;
else
verdict
=
KRF_SEEN
;
if
(
rt_free
)
rte_free
(
rt_free
);
lp_flush
(
krt_filter_lp
);
}
else
verdict
=
KRF_DELETE
;
...
...
@@ -692,25 +740,6 @@ krt_got_route(struct krt_proto *p, rte *e)
rte_free
(
e
);
}
static
inline
int
krt_export_rte
(
struct
krt_proto
*
p
,
rte
**
new
,
ea_list
**
tmpa
)
{
struct
filter
*
filter
=
p
->
p
.
main_ahook
->
out_filter
;
if
(
!
*
new
)
return
0
;
if
(
filter
==
FILTER_REJECT
)
return
0
;
if
(
filter
==
FILTER_ACCEPT
)
return
1
;
struct
proto
*
src
=
(
*
new
)
->
attrs
->
src
->
proto
;
*
tmpa
=
src
->
make_tmp_attrs
?
src
->
make_tmp_attrs
(
*
new
,
krt_filter_lp
)
:
NULL
;
return
f_run
(
filter
,
new
,
tmpa
,
krt_filter_lp
,
FF_FORCE_TMPATTR
)
<=
F_ACCEPT
;
}
static
void
krt_prune
(
struct
krt_proto
*
p
)
{
...
...
@@ -721,7 +750,7 @@ krt_prune(struct krt_proto *p)
{
net
*
n
=
(
net
*
)
f
;
int
verdict
=
f
->
flags
&
KRF_VERDICT_MASK
;
rte
*
new
,
*
new0
,
*
old
;
rte
*
new
,
*
old
,
*
rt_free
=
NULL
;
ea_list
*
tmpa
=
NULL
;
if
(
verdict
==
KRF_UPDATE
||
verdict
==
KRF_DELETE
)
...
...
@@ -733,23 +762,18 @@ krt_prune(struct krt_proto *p)
else
old
=
NULL
;
new
=
new0
=
n
->
routes
;
if
(
verdict
==
KRF_CREATE
||
verdict
==
KRF_UPDATE
)
{
/* We have to run export filter to get proper 'new' route */
if
(
!
krt_export_rte
(
p
,
&
new
,
&
tmpa
))
{
/* Route rejected, should not happen (KRF_INSTALLED) but to be sure .. */
verdict
=
(
verdict
==
KRF_CREATE
)
?
KRF_IGNORE
:
KRF_DELETE
;
}
new
=
krt_export_net
(
p
,
n
,
&
rt_free
,
&
tmpa
);
if
(
!
new
)
verdict
=
(
verdict
==
KRF_CREATE
)
?
KRF_IGNORE
:
KRF_DELETE
;
else
{
ea_list
**
x
=
&
tmpa
;
while
(
*
x
)
x
=
&
((
*
x
)
->
next
);
*
x
=
new
?
new
->
attrs
->
eattrs
:
NULL
;
}
tmpa
=
ea_append
(
tmpa
,
new
->
attrs
->
eattrs
);
}
else
new
=
NULL
;
switch
(
verdict
)
{
...
...
@@ -778,8 +802,8 @@ krt_prune(struct krt_proto *p)
if
(
old
)
rte_free
(
old
);
if
(
new
!=
new0
)
rte_free
(
new
);
if
(
rt_free
)
rte_free
(
rt_free
);
lp_flush
(
krt_filter_lp
);
f
->
flags
&=
~
KRF_VERDICT_MASK
;
}
...
...
@@ -974,7 +998,8 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *
* We will remove KRT_INSTALLED flag, which stops such withdraw to be
* processed in krt_rt_notify() and krt_replace_rte().
*/
e
->
net
->
n
.
flags
&=
~
KRF_INSTALLED
;
if
(
e
==
e
->
net
->
routes
)
e
->
net
->
n
.
flags
&=
~
KRF_INSTALLED
;
#endif
return
-
1
;
}
...
...
Write
Preview
Supports
Markdown
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