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
78a2cc28
Commit
78a2cc28
authored
Jun 03, 2015
by
Ondřej Zajíček
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
KRT: Fixes some minor bugs in kernel protocol
parent
d217ba51
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
41 deletions
+71
-41
sysdep/linux/netlink.c
sysdep/linux/netlink.c
+5
-0
sysdep/unix/krt.c
sysdep/unix/krt.c
+66
-41
No files found.
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
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