Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
babeld
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
babeld
Commits
b8e832cb
Commit
b8e832cb
authored
Jun 12, 2013
by
Matthieu Boutier
Committed by
Juliusz Chroboczek
Jul 18, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change data structures and related functions to hold source prefixes.
parent
46ac5f94
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
200 additions
and
84 deletions
+200
-84
babeld.c
babeld.c
+1
-1
configuration.c
configuration.c
+6
-2
configuration.h
configuration.h
+7
-3
interface.c
interface.c
+2
-2
message.c
message.c
+35
-23
message.h
message.h
+5
-2
resend.c
resend.c
+12
-6
resend.h
resend.h
+6
-3
route.c
route.c
+70
-28
route.h
route.h
+12
-2
source.c
source.c
+11
-3
source.h
source.h
+5
-1
util.h
util.h
+1
-0
xroute.c
xroute.c
+22
-7
xroute.h
xroute.h
+5
-1
No files found.
babeld.c
View file @
b8e832cb
...
@@ -714,7 +714,7 @@ main(int argc, char **argv)
...
@@ -714,7 +714,7 @@ main(int argc, char **argv)
if
(
timeval_compare
(
&
now
,
&
ifp
->
hello_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
hello_timeout
)
>=
0
)
send_hello
(
ifp
);
send_hello
(
ifp
);
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_timeout
)
>=
0
)
send_update
(
ifp
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
,
NULL
,
0
);
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_flush_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_flush_timeout
)
>=
0
)
flushupdates
(
ifp
);
flushupdates
(
ifp
);
}
}
...
...
configuration.c
View file @
b8e832cb
...
@@ -938,6 +938,7 @@ do_filter(struct filter *f, const unsigned char *id,
...
@@ -938,6 +938,7 @@ do_filter(struct filter *f, const unsigned char *id,
int
int
input_filter
(
const
unsigned
char
*
id
,
input_filter
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
const
unsigned
char
*
neigh
,
unsigned
int
ifindex
)
const
unsigned
char
*
neigh
,
unsigned
int
ifindex
)
{
{
int
res
;
int
res
;
...
@@ -948,8 +949,10 @@ input_filter(const unsigned char *id,
...
@@ -948,8 +949,10 @@ input_filter(const unsigned char *id,
}
}
int
int
output_filter
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
output_filter
(
const
unsigned
char
*
id
,
unsigned
short
plen
,
unsigned
int
ifindex
)
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
unsigned
int
ifindex
)
{
{
int
res
;
int
res
;
res
=
do_filter
(
output_filters
,
id
,
prefix
,
plen
,
NULL
,
ifindex
,
0
);
res
=
do_filter
(
output_filters
,
id
,
prefix
,
plen
,
NULL
,
ifindex
,
0
);
...
@@ -960,6 +963,7 @@ output_filter(const unsigned char *id, const unsigned char *prefix,
...
@@ -960,6 +963,7 @@ output_filter(const unsigned char *id, const unsigned char *prefix,
int
int
redistribute_filter
(
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
redistribute_filter
(
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
unsigned
int
ifindex
,
int
proto
)
unsigned
int
ifindex
,
int
proto
)
{
{
int
res
;
int
res
;
...
...
configuration.h
View file @
b8e832cb
...
@@ -42,9 +42,13 @@ void renumber_filters(void);
...
@@ -42,9 +42,13 @@ void renumber_filters(void);
int
input_filter
(
const
unsigned
char
*
id
,
int
input_filter
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
const
unsigned
char
*
neigh
,
unsigned
int
ifindex
);
const
unsigned
char
*
neigh
,
unsigned
int
ifindex
);
int
output_filter
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
int
output_filter
(
const
unsigned
char
*
id
,
unsigned
short
plen
,
unsigned
int
ifindex
);
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
unsigned
int
ifindex
);
int
redistribute_filter
(
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
int
redistribute_filter
(
const
unsigned
char
*
prefix
,
unsigned
short
plen
,
unsigned
int
ifindex
,
int
proto
);
const
unsigned
char
*
src_prefix
,
unsigned
short
src_plen
,
unsigned
int
ifindex
,
int
proto
);
int
finalise_config
(
void
);
int
finalise_config
(
void
);
interface.c
View file @
b8e832cb
...
@@ -380,7 +380,7 @@ interface_up(struct interface *ifp, int up)
...
@@ -380,7 +380,7 @@ interface_up(struct interface *ifp, int up)
set_timeout
(
&
ifp
->
update_timeout
,
ifp
->
update_interval
);
set_timeout
(
&
ifp
->
update_timeout
,
ifp
->
update_interval
);
send_hello
(
ifp
);
send_hello
(
ifp
);
if
(
rc
>
0
)
if
(
rc
>
0
)
send_update
(
ifp
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
}
else
{
}
else
{
flush_interface_routes
(
ifp
,
0
);
flush_interface_routes
(
ifp
,
0
);
...
@@ -467,7 +467,7 @@ check_interfaces(void)
...
@@ -467,7 +467,7 @@ check_interfaces(void)
rc
=
check_interface_ipv4
(
ifp
);
rc
=
check_interface_ipv4
(
ifp
);
if
(
rc
>
0
)
{
if
(
rc
>
0
)
{
send_request
(
ifp
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
,
NULL
,
0
);
}
}
}
}
}
}
...
...
message.c
View file @
b8e832cb
...
@@ -541,7 +541,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
...
@@ -541,7 +541,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
len
-
parsed_len
,
channels
);
len
-
parsed_len
,
channels
);
}
}
update_route
(
router_id
,
prefix
,
plen
,
seqno
,
metric
,
interval
,
update_route
(
router_id
,
prefix
,
plen
,
NULL
,
0
,
seqno
,
metric
,
interval
,
neigh
,
nh
,
neigh
,
nh
,
channels
,
channels_len
(
channels
));
channels
,
channels_len
(
channels
));
}
else
if
(
type
==
MESSAGE_REQUEST
)
{
}
else
if
(
type
==
MESSAGE_REQUEST
)
{
...
@@ -565,9 +565,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
...
@@ -565,9 +565,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
shortly after we sent a full update. */
shortly after we sent a full update. */
if
(
neigh
->
ifp
->
last_update_time
<
if
(
neigh
->
ifp
->
last_update_time
<
now
.
tv_sec
-
MAX
(
neigh
->
ifp
->
hello_interval
/
100
,
1
))
now
.
tv_sec
-
MAX
(
neigh
->
ifp
->
hello_interval
/
100
,
1
))
send_update
(
neigh
->
ifp
,
0
,
NULL
,
0
);
send_update
(
neigh
->
ifp
,
0
,
NULL
,
0
,
zeroes
,
0
);
}
else
{
}
else
{
send_update
(
neigh
->
ifp
,
0
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
0
,
prefix
,
plen
,
zeroes
,
0
);
}
}
}
else
if
(
type
==
MESSAGE_MH_REQUEST
)
{
}
else
if
(
type
==
MESSAGE_MH_REQUEST
)
{
unsigned
char
prefix
[
16
],
plen
;
unsigned
char
prefix
[
16
],
plen
;
...
@@ -1002,7 +1002,8 @@ really_send_update(struct interface *ifp,
...
@@ -1002,7 +1002,8 @@ really_send_update(struct interface *ifp,
if
(
!
if_up
(
ifp
))
if
(
!
if_up
(
ifp
))
return
;
return
;
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
ifp
->
ifindex
);
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
zeroes
,
0
,
ifp
->
ifindex
);
if
(
add_metric
>=
INFINITY
)
if
(
add_metric
>=
INFINITY
)
return
;
return
;
...
@@ -1146,7 +1147,7 @@ flushupdates(struct interface *ifp)
...
@@ -1146,7 +1147,7 @@ flushupdates(struct interface *ifp)
with the same router-id together, with IPv6 going out before IPv4. */
with the same router-id together, with IPv6 going out before IPv4. */
for
(
i
=
0
;
i
<
n
;
i
++
)
{
for
(
i
=
0
;
i
<
n
;
i
++
)
{
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
);
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
,
zeroes
,
0
);
if
(
route
)
if
(
route
)
memcpy
(
b
[
i
].
id
,
route
->
src
->
id
,
8
);
memcpy
(
b
[
i
].
id
,
route
->
src
->
id
,
8
);
else
else
...
@@ -1166,8 +1167,10 @@ flushupdates(struct interface *ifp)
...
@@ -1166,8 +1167,10 @@ flushupdates(struct interface *ifp)
continue
;
continue
;
}
}
xroute
=
find_xroute
(
b
[
i
].
prefix
,
b
[
i
].
plen
);
xroute
=
find_xroute
(
b
[
i
].
prefix
,
b
[
i
].
plen
,
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
);
zeroes
,
0
);
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
,
zeroes
,
0
);
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
really_send_update
(
ifp
,
myid
,
really_send_update
(
ifp
,
myid
,
...
@@ -1191,6 +1194,8 @@ flushupdates(struct interface *ifp)
...
@@ -1191,6 +1194,8 @@ flushupdates(struct interface *ifp)
if
(
metric
<
INFINITY
)
if
(
metric
<
INFINITY
)
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
seqno
,
route
->
src
->
id
,
ifp
);
seqno
,
route
->
src
->
id
,
ifp
);
if
((
ifp
->
flags
&
IF_SPLIT_HORIZON
)
&&
if
((
ifp
->
flags
&
IF_SPLIT_HORIZON
)
&&
...
@@ -1284,20 +1289,21 @@ buffer_update(struct interface *ifp,
...
@@ -1284,20 +1289,21 @@ buffer_update(struct interface *ifp,
void
void
send_update
(
struct
interface
*
ifp
,
int
urgent
,
send_update
(
struct
interface
*
ifp
,
int
urgent
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
)
{
{
if
(
ifp
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
interface
*
ifp_aux
;
struct
interface
*
ifp_aux
;
struct
babel_route
*
route
;
struct
babel_route
*
route
;
FOR_ALL_INTERFACES
(
ifp_aux
)
FOR_ALL_INTERFACES
(
ifp_aux
)
send_update
(
ifp_aux
,
urgent
,
prefix
,
plen
);
send_update
(
ifp_aux
,
urgent
,
prefix
,
plen
,
src_prefix
,
src_plen
);
if
(
prefix
)
{
if
(
prefix
)
{
/* Since flushupdates only deals with non-wildcard interfaces, we
/* Since flushupdates only deals with non-wildcard interfaces, we
need to do this now. */
need to do this now. */
route
=
find_installed_route
(
prefix
,
plen
);
route
=
find_installed_route
(
prefix
,
plen
,
src_prefix
,
src_plen
);
if
(
route
&&
route_metric
(
route
)
<
INFINITY
)
if
(
route
&&
route_metric
(
route
)
<
INFINITY
)
satisfy_request
(
prefix
,
plen
,
route
->
src
->
seqno
,
route
->
src
->
id
,
satisfy_request
(
prefix
,
plen
,
src_prefix
,
src_plen
,
NULL
);
route
->
src
->
seqno
,
route
->
src
->
id
,
NULL
);
}
}
return
;
return
;
}
}
...
@@ -1333,12 +1339,14 @@ send_update(struct interface *ifp, int urgent,
...
@@ -1333,12 +1339,14 @@ send_update(struct interface *ifp, int urgent,
void
void
send_update_resend
(
struct
interface
*
ifp
,
send_update_resend
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
)
{
{
assert
(
prefix
!=
NULL
);
assert
(
prefix
!=
NULL
);
send_update
(
ifp
,
1
,
prefix
,
plen
);
send_update
(
ifp
,
1
,
prefix
,
plen
,
src_prefix
,
src_plen
);
record_resend
(
RESEND_UPDATE
,
prefix
,
plen
,
0
,
NULL
,
NULL
,
resend_delay
);
record_resend
(
RESEND_UPDATE
,
prefix
,
plen
,
src_prefix
,
src_plen
,
0
,
NULL
,
NULL
,
resend_delay
);
}
}
void
void
...
@@ -1394,7 +1402,8 @@ send_self_update(struct interface *ifp)
...
@@ -1394,7 +1402,8 @@ send_self_update(struct interface *ifp)
while
(
1
)
{
while
(
1
)
{
struct
xroute
*
xroute
=
xroute_stream_next
(
xroutes
);
struct
xroute
*
xroute
=
xroute_stream_next
(
xroutes
);
if
(
xroute
==
NULL
)
break
;
if
(
xroute
==
NULL
)
break
;
send_update
(
ifp
,
0
,
xroute
->
prefix
,
xroute
->
plen
);
send_update
(
ifp
,
0
,
xroute
->
prefix
,
xroute
->
plen
,
xroute
->
src_prefix
,
xroute
->
src_plen
);
}
}
xroute_stream_done
(
xroutes
);
xroute_stream_done
(
xroutes
);
}
else
{
}
else
{
...
@@ -1678,7 +1687,7 @@ send_request_resend(struct neighbour *neigh,
...
@@ -1678,7 +1687,7 @@ send_request_resend(struct neighbour *neigh,
else
else
send_multihop_request
(
NULL
,
prefix
,
plen
,
seqno
,
id
,
127
);
send_multihop_request
(
NULL
,
prefix
,
plen
,
seqno
,
id
,
127
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
zeroes
,
0
,
seqno
,
id
,
neigh
?
neigh
->
ifp
:
NULL
,
resend_delay
);
neigh
?
neigh
->
ifp
:
NULL
,
resend_delay
);
}
}
...
@@ -1691,8 +1700,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1691,8 +1700,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
struct
babel_route
*
route
;
struct
babel_route
*
route
;
struct
neighbour
*
successor
=
NULL
;
struct
neighbour
*
successor
=
NULL
;
xroute
=
find_xroute
(
prefix
,
plen
);
xroute
=
find_xroute
(
prefix
,
plen
,
zeroes
,
0
);
route
=
find_installed_route
(
prefix
,
plen
);
route
=
find_installed_route
(
prefix
,
plen
,
zeroes
,
0
);
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
if
(
hop_count
>
0
&&
memcmp
(
id
,
myid
,
8
)
==
0
)
{
if
(
hop_count
>
0
&&
memcmp
(
id
,
myid
,
8
)
==
0
)
{
...
@@ -1704,14 +1713,16 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1704,14 +1713,16 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
update_myseqno
();
update_myseqno
();
}
}
}
}
send_update
(
neigh
->
ifp
,
1
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
1
,
prefix
,
plen
,
xroute
->
src_prefix
,
xroute
->
src_plen
);
return
;
return
;
}
}
if
(
route
&&
if
(
route
&&
(
memcmp
(
id
,
route
->
src
->
id
,
8
)
!=
0
||
(
memcmp
(
id
,
route
->
src
->
id
,
8
)
!=
0
||
seqno_compare
(
seqno
,
route
->
seqno
)
<=
0
))
{
seqno_compare
(
seqno
,
route
->
seqno
)
<=
0
))
{
send_update
(
neigh
->
ifp
,
1
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
1
,
prefix
,
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
return
;
return
;
}
}
...
@@ -1736,7 +1747,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1736,7 +1747,8 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
find a different neighbour to forward the request to. */
find a different neighbour to forward the request to. */
struct
babel_route
*
other_route
;
struct
babel_route
*
other_route
;
other_route
=
find_best_route
(
prefix
,
plen
,
0
,
neigh
);
other_route
=
find_best_route
(
prefix
,
plen
,
zeroes
,
0
,
0
,
neigh
);
if
(
other_route
&&
route_metric
(
other_route
)
<
INFINITY
)
if
(
other_route
&&
route_metric
(
other_route
)
<
INFINITY
)
successor
=
other_route
->
neigh
;
successor
=
other_route
->
neigh
;
}
}
...
@@ -1747,6 +1759,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1747,6 +1759,6 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
send_unicast_multihop_request
(
successor
,
prefix
,
plen
,
seqno
,
id
,
send_unicast_multihop_request
(
successor
,
prefix
,
plen
,
seqno
,
id
,
hop_count
-
1
);
hop_count
-
1
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
zeroes
,
0
,
seqno
,
id
,
neigh
->
ifp
,
0
);
neigh
->
ifp
,
0
);
}
}
message.h
View file @
b8e832cb
...
@@ -67,9 +67,12 @@ void send_hello_noupdate(struct interface *ifp, unsigned interval);
...
@@ -67,9 +67,12 @@ void send_hello_noupdate(struct interface *ifp, unsigned interval);
void
send_hello
(
struct
interface
*
ifp
);
void
send_hello
(
struct
interface
*
ifp
);
void
flush_unicast
(
int
dofree
);
void
flush_unicast
(
int
dofree
);
void
send_update
(
struct
interface
*
ifp
,
int
urgent
,
void
send_update
(
struct
interface
*
ifp
,
int
urgent
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
);
void
send_update_resend
(
struct
interface
*
ifp
,
void
send_update_resend
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
);
void
send_wildcard_retraction
(
struct
interface
*
ifp
);
void
send_wildcard_retraction
(
struct
interface
*
ifp
);
void
update_myseqno
(
void
);
void
update_myseqno
(
void
);
void
send_self_update
(
struct
interface
*
ifp
);
void
send_self_update
(
struct
interface
*
ifp
);
...
...
resend.c
View file @
b8e832cb
...
@@ -75,6 +75,7 @@ find_resend(int kind, const unsigned char *prefix, unsigned char plen,
...
@@ -75,6 +75,7 @@ find_resend(int kind, const unsigned char *prefix, unsigned char plen,
struct
resend
*
struct
resend
*
find_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
find_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
resend
**
previous_return
)
struct
resend
**
previous_return
)
{
{
return
find_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
previous_return
);
return
find_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
previous_return
);
...
@@ -82,6 +83,7 @@ find_request(const unsigned char *prefix, unsigned char plen,
...
@@ -82,6 +83,7 @@ find_request(const unsigned char *prefix, unsigned char plen,
int
int
record_resend
(
int
kind
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
record_resend
(
int
kind
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
interface
*
ifp
,
int
delay
)
struct
interface
*
ifp
,
int
delay
)
{
{
...
@@ -89,9 +91,11 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
...
@@ -89,9 +91,11 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
unsigned
int
ifindex
=
ifp
?
ifp
->
ifindex
:
0
;
unsigned
int
ifindex
=
ifp
?
ifp
->
ifindex
:
0
;
if
((
kind
==
RESEND_REQUEST
&&
if
((
kind
==
RESEND_REQUEST
&&
input_filter
(
NULL
,
prefix
,
plen
,
NULL
,
ifindex
)
>=
INFINITY
)
||
input_filter
(
NULL
,
prefix
,
plen
,
NULL
,
0
,
NULL
,
ifindex
)
>=
INFINITY
)
||
(
kind
==
RESEND_UPDATE
&&
(
kind
==
RESEND_UPDATE
&&
output_filter
(
NULL
,
prefix
,
plen
,
ifindex
)
>=
INFINITY
))
output_filter
(
NULL
,
prefix
,
plen
,
src_prefix
,
src_plen
,
ifindex
)
>=
INFINITY
))
return
0
;
return
0
;
if
(
delay
>=
0xFFFF
)
if
(
delay
>=
0xFFFF
)
...
@@ -161,7 +165,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
...
@@ -161,7 +165,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
{
{
struct
resend
*
request
;
struct
resend
*
request
;
request
=
find_request
(
prefix
,
plen
,
NULL
);
request
=
find_request
(
prefix
,
plen
,
zeroes
,
0
,
NULL
);
if
(
request
==
NULL
||
resend_expired
(
request
))
if
(
request
==
NULL
||
resend_expired
(
request
))
return
0
;
return
0
;
...
@@ -180,7 +184,7 @@ request_redundant(struct interface *ifp,
...
@@ -180,7 +184,7 @@ request_redundant(struct interface *ifp,
{
{
struct
resend
*
request
;
struct
resend
*
request
;
request
=
find_request
(
prefix
,
plen
,
NULL
);
request
=
find_request
(
prefix
,
plen
,
zeroes
,
0
,
NULL
);
if
(
request
==
NULL
||
resend_expired
(
request
))
if
(
request
==
NULL
||
resend_expired
(
request
))
return
0
;
return
0
;
...
@@ -205,12 +209,13 @@ request_redundant(struct interface *ifp,
...
@@ -205,12 +209,13 @@ request_redundant(struct interface *ifp,
int
int
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
interface
*
ifp
)
struct
interface
*
ifp
)
{
{
struct
resend
*
request
,
*
previous
;
struct
resend
*
request
,
*
previous
;
request
=
find_request
(
prefix
,
plen
,
&
previous
);
request
=
find_request
(
prefix
,
plen
,
zeroes
,
0
,
&
previous
);
if
(
request
==
NULL
)
if
(
request
==
NULL
)
return
0
;
return
0
;
...
@@ -297,7 +302,8 @@ do_resend()
...
@@ -297,7 +302,8 @@ do_resend()
break
;
break
;
case
RESEND_UPDATE
:
case
RESEND_UPDATE
:
send_update
(
resend
->
ifp
,
1
,
send_update
(
resend
->
ifp
,
1
,
resend
->
prefix
,
resend
->
plen
);
resend
->
prefix
,
resend
->
plen
,
zeroes
,
0
);
break
;
break
;
default:
abort
();
default:
abort
();
}
}
...
...
resend.h
View file @
b8e832cb
...
@@ -42,17 +42,20 @@ struct resend {
...
@@ -42,17 +42,20 @@ struct resend {
extern
struct
timeval
resend_time
;
extern
struct
timeval
resend_time
;
struct
resend
*
find_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
resend
*
find_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
resend
**
previous_return
);
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
resend
**
previous_return
);
void
flush_resends
(
struct
neighbour
*
neigh
);
void
flush_resends
(
struct
neighbour
*
neigh
);
int
record_resend
(
int
kind
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
int
record_resend
(
int
kind
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
interface
*
ifp
,
int
delay
);
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
interface
*
ifp
,
int
delay
);
int
unsatisfied_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
int
unsatisfied_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
);
unsigned
short
seqno
,
const
unsigned
char
*
id
);
int
request_redundant
(
struct
interface
*
ifp
,
int
request_redundant
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
);
unsigned
short
seqno
,
const
unsigned
char
*
id
);
int
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
int
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
interface
*
ifp
);
struct
interface
*
ifp
);
...
...
route.c
View file @
b8e832cb
...
@@ -57,6 +57,7 @@ static int two_to_the_one_over_hl = 0; /* 2^(1/hl) * 0x10000 */
...
@@ -57,6 +57,7 @@ static int two_to_the_one_over_hl = 0; /* 2^(1/hl) * 0x10000 */
static
int
static
int
route_compare
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
route_compare
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
babel_route
*
route
)
struct
babel_route
*
route
)
{
{
int
i
=
memcmp
(
prefix
,
route
->
src
->
prefix
,
16
);
int
i
=
memcmp
(
prefix
,
route
->
src
->
prefix
,
16
);
...
@@ -65,10 +66,23 @@ route_compare(const unsigned char *prefix, unsigned char plen,
...
@@ -65,10 +66,23 @@ route_compare(const unsigned char *prefix, unsigned char plen,
if
(
plen
<
route
->
src
->
plen
)
if
(
plen
<
route
->
src
->
plen
)
return
-
1
;
return
-
1
;
else
if
(
plen
>
route
->
src
->
plen
)
if
(
plen
>
route
->
src
->
plen
)
return
1
;
return
1
;
else
return
0
;
if
(
src_plen
==
0
)
{
if
(
route
->
src
->
src_plen
>
0
)
return
-
1
;
}
else
{
i
=
memcmp
(
src_prefix
,
route
->
src
->
src_prefix
,
16
);
if
(
i
!=
0
)
return
i
;
if
(
src_plen
<
route
->
src
->
src_plen
)
return
-
1
;
if
(
src_plen
>
route
->
src
->
src_plen
)
return
1
;
}
return
0
;
}
}
/* Performs binary search, returns -1 in case of failure. In the latter
/* Performs binary search, returns -1 in case of failure. In the latter
...
@@ -76,6 +90,7 @@ route_compare(const unsigned char *prefix, unsigned char plen,
...
@@ -76,6 +90,7 @@ route_compare(const unsigned char *prefix, unsigned char plen,
static
int
static
int
find_route_slot
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
find_route_slot
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
*
new_return
)
int
*
new_return
)
{
{
int
p
,
m
,
g
,
c
;
int
p
,
m
,
g
,
c
;
...
@@ -90,7 +105,7 @@ find_route_slot(const unsigned char *prefix, unsigned char plen,
...
@@ -90,7 +105,7 @@ find_route_slot(const unsigned char *prefix, unsigned char plen,
do
{
do
{
m
=
(
p
+
g
)
/
2
;
m
=
(
p
+
g
)
/
2
;
c
=
route_compare
(
prefix
,
plen
,
routes
[
m
]);
c
=
route_compare
(
prefix
,
plen
,
src_prefix
,
src_plen
,
routes
[
m
]);
if
(
c
==
0
)
if
(
c
==
0
)
return
m
;
return
m
;
else
if
(
c
<
0
)
else
if
(
c
<
0
)
...
@@ -107,10 +122,11 @@ find_route_slot(const unsigned char *prefix, unsigned char plen,
...
@@ -107,10 +122,11 @@ find_route_slot(const unsigned char *prefix, unsigned char plen,
struct
babel_route
*
struct
babel_route
*
find_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
find_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
)
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
)
{
{
struct
babel_route
*
route
;
struct
babel_route
*
route
;
int
i
=
find_route_slot
(
prefix
,
plen
,
NULL
);
int
i
=
find_route_slot
(
prefix
,
plen
,
src_prefix
,
src_plen
,
NULL
);
if
(
i
<
0
)
if
(
i
<
0
)
return
NULL
;
return
NULL
;
...
@@ -127,9 +143,10 @@ find_route(const unsigned char *prefix, unsigned char plen,
...
@@ -127,9 +143,10 @@ find_route(const unsigned char *prefix, unsigned char plen,
}
}
struct
babel_route
*
struct
babel_route
*
find_installed_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
find_installed_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
)
{
{
int
i
=
find_route_slot
(
prefix
,
plen
,
NULL
);
int
i
=
find_route_slot
(
prefix
,
plen
,
src_prefix
,
src_plen
,
NULL
);
if
(
i
>=
0
&&
routes
[
i
]
->
installed
)
if
(
i
>=
0
&&
routes
[
i
]
->
installed
)
return
routes
[
i
];
return
routes
[
i
];
...
@@ -173,7 +190,8 @@ insert_route(struct babel_route *route)
...
@@ -173,7 +190,8 @@ insert_route(struct babel_route *route)
assert
(
!
route
->
installed
);
assert
(
!
route
->
installed
);
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
&
n
);
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
&
n
);
if
(
i
<
0
)
{
if
(
i
<
0
)
{
if
(
route_slots
>=
max_route_slots
)
if
(
route_slots
>=
max_route_slots
)
...
@@ -214,7 +232,8 @@ flush_route(struct babel_route *route)
...
@@ -214,7 +232,8 @@ flush_route(struct babel_route *route)
lost
=
1
;
lost
=
1
;
}
}
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
NULL
);
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
NULL
);
assert
(
i
>=
0
&&
i
<
route_slots
);
assert
(
i
>=
0
&&
i
<
route_slots
);
local_notify_route
(
route
,
LOCAL_FLUSH
);
local_notify_route
(
route
,
LOCAL_FLUSH
);
...
@@ -406,7 +425,8 @@ install_route(struct babel_route *route)
...
@@ -406,7 +425,8 @@ install_route(struct babel_route *route)
fprintf
(
stderr
,
"WARNING: installing unfeasible route "
fprintf
(
stderr
,
"WARNING: installing unfeasible route "
"(this shouldn't happen)."
);
"(this shouldn't happen)."
);
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
NULL
);
i
=
find_route_slot
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
NULL
);
assert
(
i
>=
0
&&
i
<
route_slots
);
assert
(
i
>=
0
&&
i
<
route_slots
);
if
(
routes
[
i
]
!=
route
&&
routes
[
i
]
->
installed
)
{
if
(
routes
[
i
]
!=
route
&&
routes
[
i
]
->
installed
)
{
...
@@ -416,7 +436,7 @@ install_route(struct babel_route *route)
...
@@ -416,7 +436,7 @@ install_route(struct babel_route *route)
}
}
rc
=
kernel_route
(
ROUTE_ADD
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_ADD
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
zeroes
,
0
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
route
->
nexthop
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
route
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
...
@@ -441,7 +461,7 @@ uninstall_route(struct babel_route *route)
...
@@ -441,7 +461,7 @@ uninstall_route(struct babel_route *route)
return
;
return
;
rc
=
kernel_route
(
ROUTE_FLUSH
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_FLUSH
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
zeroes
,
0
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
route
->
nexthop
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
route
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
...
@@ -474,11 +494,14 @@ switch_routes(struct babel_route *old, struct babel_route *new)
...
@@ -474,11 +494,14 @@ switch_routes(struct babel_route *old, struct babel_route *new)
"(this shouldn't happen)."
);
"(this shouldn't happen)."
);
rc
=
kernel_route
(
ROUTE_MODIFY
,
old
->
src
->
prefix
,
old
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_MODIFY
,
old
->
src
->
prefix
,
old
->
src
->
plen
,
zeroes
,
0
,
old
->
src
->
src_prefix
,
old
->
src
->
src_plen
,
old
->
nexthop
,
old
->
neigh
->
ifp
->
ifindex
,
old
->
nexthop
,
old
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
old
)),
metric_to_kernel
(
route_metric
(
old
)),
new
->
nexthop
,
new
->
neigh
->
ifp
->
ifindex
,
new
->
nexthop
,
new
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
new
)));
metric_to_kernel
(
route_metric
(
new
)));
/* XXX : should the source-ip be subject to changes ? */
assert
(
memcmp
(
old
->
src
->
src_prefix
,
new
->
src
->
src_prefix
,
16
)
==
0
&&
old
->
src
->
src_plen
==
new
->
src
->
src_plen
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
perror
(
"kernel_route(MODIFY)"
);
perror
(
"kernel_route(MODIFY)"
);
return
;
return
;
...
@@ -487,6 +510,8 @@ switch_routes(struct babel_route *old, struct babel_route *new)
...
@@ -487,6 +510,8 @@ switch_routes(struct babel_route *old, struct babel_route *new)
old
->
installed
=
0
;
old
->
installed
=
0
;
new
->
installed
=
1
;
new
->
installed
=
1
;
move_installed_route
(
new
,
find_route_slot
(
new
->
src
->
prefix
,
new
->
src
->
plen
,
move_installed_route
(
new
,
find_route_slot
(
new
->
src
->
prefix
,
new
->
src
->
plen
,
new
->
src
->
src_prefix
,
new
->
src
->
src_plen
,
NULL
));
NULL
));
local_notify_route
(
old
,
LOCAL_CHANGE
);
local_notify_route
(
old
,
LOCAL_CHANGE
);
local_notify_route
(
new
,
LOCAL_CHANGE
);
local_notify_route
(
new
,
LOCAL_CHANGE
);
...
@@ -505,7 +530,7 @@ change_route_metric(struct babel_route *route,
...
@@ -505,7 +530,7 @@ change_route_metric(struct babel_route *route,
if
(
route
->
installed
&&
old
!=
new
)
{
if
(
route
->
installed
&&
old
!=
new
)
{
int
rc
;
int
rc
;
rc
=
kernel_route
(
ROUTE_MODIFY
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_MODIFY
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
zeroes
,
0
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
old
,
old
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
...
@@ -694,11 +719,12 @@ route_acceptable(struct babel_route *route, int feasible,
...
@@ -694,11 +719,12 @@ route_acceptable(struct babel_route *route, int feasible,
that's probably overkill. */
that's probably overkill. */
struct
babel_route
*
struct
babel_route
*
find_best_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
int
feasible
,
find_best_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
neighbour
*
exclude
)
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
feasible
,
struct
neighbour
*
exclude
)
{
{
struct
babel_route
*
route
,
*
r
;
struct
babel_route
*
route
,
*
r
;
int
i
=
find_route_slot
(
prefix
,
plen
,
NULL
);
int
i
=
find_route_slot
(
prefix
,
plen
,
src_prefix
,
src_plen
,
NULL
);
if
(
i
<
0
)
if
(
i
<
0
)
return
NULL
;
return
NULL
;
...
@@ -738,6 +764,8 @@ update_route_metric(struct babel_route *route)
...
@@ -738,6 +764,8 @@ update_route_metric(struct babel_route *route)
struct
neighbour
*
neigh
=
route
->
neigh
;
struct
neighbour
*
neigh
=
route
->
neigh
;
int
add_metric
=
input_filter
(
route
->
src
->
id
,
int
add_metric
=
input_filter
(
route
->
src
->
id
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
neigh
->
address
,
neigh
->
address
,
neigh
->
ifp
->
ifindex
);
neigh
->
ifp
->
ifindex
);
change_route_metric
(
route
,
route
->
refmetric
,
change_route_metric
(
route
,
route
->
refmetric
,
...
@@ -789,6 +817,7 @@ update_interface_metric(struct interface *ifp)
...
@@ -789,6 +817,7 @@ update_interface_metric(struct interface *ifp)
struct
babel_route
*
struct
babel_route
*
update_route
(
const
unsigned
char
*
id
,
update_route
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
unsigned
short
seqno
,
unsigned
short
refmetric
,
unsigned
short
seqno
,
unsigned
short
refmetric
,
unsigned
short
interval
,
unsigned
short
interval
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
,
...
@@ -810,17 +839,18 @@ update_route(const unsigned char *id,
...
@@ -810,17 +839,18 @@ update_route(const unsigned char *id,
}
}
add_metric
=
input_filter
(
id
,
prefix
,
plen
,
add_metric
=
input_filter
(
id
,
prefix
,
plen
,
src_prefix
,
src_plen
,
neigh
->
address
,
neigh
->
ifp
->
ifindex
);
neigh
->
address
,
neigh
->
ifp
->
ifindex
);
if
(
add_metric
>=
INFINITY
)
if
(
add_metric
>=
INFINITY
)
return
NULL
;
return
NULL
;
route
=
find_route
(
prefix
,
plen
,
neigh
,
nexthop
);
route
=
find_route
(
prefix
,
plen
,
src_prefix
,
src_plen
,
neigh
,
nexthop
);
if
(
route
&&
memcmp
(
route
->
src
->
id
,
id
,
8
)
==
0
)
if
(
route
&&
memcmp
(
route
->
src
->
id
,
id
,
8
)
==
0
)
/* Avoid scanning the source table. */
/* Avoid scanning the source table. */
src
=
route
->
src
;
src
=
route
->
src
;
else
else
src
=
find_source
(
id
,
prefix
,
plen
,
1
,
seqno
);
src
=
find_source
(
id
,
prefix
,
plen
,
src_prefix
,
src_plen
,
1
,
seqno
);
if
(
src
==
NULL
)
if
(
src
==
NULL
)
return
NULL
;
return
NULL
;
...
@@ -929,7 +959,9 @@ send_unfeasible_request(struct neighbour *neigh, int force,
...
@@ -929,7 +959,9 @@ send_unfeasible_request(struct neighbour *neigh, int force,
unsigned
short
seqno
,
unsigned
short
metric
,
unsigned
short
seqno
,
unsigned
short
metric
,
struct
source
*
src
)
struct
source
*
src
)
{
{
struct
babel_route
*
route
=
find_installed_route
(
src
->
prefix
,
src
->
plen
);
struct
babel_route
*
route
=
find_installed_route
(
src
->
prefix
,
src
->
plen
,
src
->
src_prefix
,
src
->
src_plen
);
if
(
seqno_minus
(
src
->
seqno
,
seqno
)
>
100
)
{
if
(
seqno_minus
(
src
->
seqno
,
seqno
)
>
100
)
{
/* Probably a source that lost its seqno. Let it time-out. */
/* Probably a source that lost its seqno. Let it time-out. */
...
@@ -962,11 +994,14 @@ consider_route(struct babel_route *route)
...
@@ -962,11 +994,14 @@ consider_route(struct babel_route *route)
if
(
!
route_feasible
(
route
))
if
(
!
route_feasible
(
route
))
return
;
return
;
xroute
=
find_xroute
(
route
->
src
->
prefix
,
route
->
src
->
plen
);
xroute
=
find_xroute
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
if
(
xroute
&&
(
allow_duplicates
<
0
||
xroute
->
metric
>=
allow_duplicates
))
if
(
xroute
&&
(
allow_duplicates
<
0
||
xroute
->
metric
>=
allow_duplicates
))
return
;
return
;
installed
=
find_installed_route
(
route
->
src
->
prefix
,
route
->
src
->
plen
);
installed
=
find_installed_route
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
if
(
installed
==
NULL
)
if
(
installed
==
NULL
)
goto
install
;
goto
install
;
...
@@ -988,7 +1023,8 @@ consider_route(struct babel_route *route)
...
@@ -988,7 +1023,8 @@ consider_route(struct babel_route *route)
if
(
installed
&&
route
->
installed
)
if
(
installed
&&
route
->
installed
)
send_triggered_update
(
route
,
installed
->
src
,
route_metric
(
installed
));
send_triggered_update
(
route
,
installed
->
src
,
route_metric
(
installed
));
else
else
send_update
(
NULL
,
1
,
route
->
src
->
prefix
,
route
->
src
->
plen
);
send_update
(
NULL
,
1
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
return
;
return
;
}
}
...
@@ -1054,9 +1090,11 @@ send_triggered_update(struct babel_route *route, struct source *oldsrc,
...
@@ -1054,9 +1090,11 @@ send_triggered_update(struct babel_route *route, struct source *oldsrc,
urgent
=
0
;
urgent
=
0
;
if
(
urgent
>=
2
)
if
(
urgent
>=
2
)
send_update_resend
(
NULL
,
route
->
src
->
prefix
,
route
->
src
->
plen
);
send_update_resend
(
NULL
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
else
else
send_update
(
NULL
,
urgent
,
route
->
src
->
prefix
,
route
->
src
->
plen
);
send_update
(
NULL
,
urgent
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
);
if
(
oldmetric
<
INFINITY
)
{
if
(
oldmetric
<
INFINITY
)
{
if
(
newmetric
>=
oldmetric
+
512
)
{
if
(
newmetric
>=
oldmetric
+
512
)
{
...
@@ -1081,7 +1119,9 @@ route_changed(struct babel_route *route,
...
@@ -1081,7 +1119,9 @@ route_changed(struct babel_route *route,
struct
babel_route
*
better_route
;
struct
babel_route
*
better_route
;
/* Do this unconditionally -- microoptimisation is not worth it. */
/* Do this unconditionally -- microoptimisation is not worth it. */
better_route
=
better_route
=
find_best_route
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
1
,
NULL
);
find_best_route
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
src_prefix
,
route
->
src
->
src_plen
,
1
,
NULL
);
if
(
better_route
&&
route_metric
(
better_route
)
<
route_metric
(
route
))
if
(
better_route
&&
route_metric
(
better_route
)
<
route_metric
(
route
))
consider_route
(
better_route
);
consider_route
(
better_route
);
}
}
...
@@ -1101,12 +1141,14 @@ void
...
@@ -1101,12 +1141,14 @@ void
route_lost
(
struct
source
*
src
,
unsigned
oldmetric
)
route_lost
(
struct
source
*
src
,
unsigned
oldmetric
)
{
{
struct
babel_route
*
new_route
;
struct
babel_route
*
new_route
;
new_route
=
find_best_route
(
src
->
prefix
,
src
->
plen
,
1
,
NULL
);
new_route
=
find_best_route
(
src
->
prefix
,
src
->
plen
,
src
->
src_prefix
,
src
->
src_plen
,
1
,
NULL
);
if
(
new_route
)
{
if
(
new_route
)
{
consider_route
(
new_route
);
consider_route
(
new_route
);
}
else
if
(
oldmetric
<
INFINITY
)
{
}
else
if
(
oldmetric
<
INFINITY
)
{
/* Avoid creating a blackhole. */
/* Avoid creating a blackhole. */
send_update_resend
(
NULL
,
src
->
prefix
,
src
->
plen
);
send_update_resend
(
NULL
,
src
->
prefix
,
src
->
plen
,
src
->
src_prefix
,
src
->
src_plen
);
/* If the route was usable enough, try to get an alternate one.
/* If the route was usable enough, try to get an alternate one.
If it was not, we could be dealing with oscillations around
If it was not, we could be dealing with oscillations around
the value of INFINITY. */
the value of INFINITY. */
...
...
route.h
View file @
b8e832cb
...
@@ -70,9 +70,15 @@ route_metric_noninterfering(const struct babel_route *route)
...
@@ -70,9 +70,15 @@ route_metric_noninterfering(const struct babel_route *route)
}
}
struct
babel_route
*
find_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
babel_route
*
find_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
);
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
);
struct
babel_route
*
find_installed_route
(
const
unsigned
char
*
prefix
,
struct
babel_route
*
find_installed_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
);
struct
babel_route
*
find_min_iroute
(
const
unsigned
char
*
dst_prefix
,
unsigned
char
dst_plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
is_min_dst
,
int
is_min_src
,
int
exclusive_min
);
int
installed_routes_estimate
(
void
);
int
installed_routes_estimate
(
void
);
void
flush_route
(
struct
babel_route
*
route
);
void
flush_route
(
struct
babel_route
*
route
);
void
flush_all_routes
(
void
);
void
flush_all_routes
(
void
);
...
@@ -93,6 +99,8 @@ void change_smoothing_half_life(int half_life);
...
@@ -93,6 +99,8 @@ void change_smoothing_half_life(int half_life);
int
route_smoothed_metric
(
struct
babel_route
*
route
);
int
route_smoothed_metric
(
struct
babel_route
*
route
);
struct
babel_route
*
find_best_route
(
const
unsigned
char
*
prefix
,
struct
babel_route
*
find_best_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
feasible
,
struct
neighbour
*
exclude
);
int
feasible
,
struct
neighbour
*
exclude
);
struct
babel_route
*
install_best_route
(
const
unsigned
char
prefix
[
16
],
struct
babel_route
*
install_best_route
(
const
unsigned
char
prefix
[
16
],
unsigned
char
plen
);
unsigned
char
plen
);
...
@@ -101,6 +109,8 @@ void update_interface_metric(struct interface *ifp);
...
@@ -101,6 +109,8 @@ void update_interface_metric(struct interface *ifp);
void
update_route_metric
(
struct
babel_route
*
route
);
void
update_route_metric
(
struct
babel_route
*
route
);
struct
babel_route
*
update_route
(
const
unsigned
char
*
id
,
struct
babel_route
*
update_route
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
unsigned
short
seqno
,
unsigned
short
refmetric
,
unsigned
short
seqno
,
unsigned
short
refmetric
,
unsigned
short
interval
,
struct
neighbour
*
neigh
,
unsigned
short
interval
,
struct
neighbour
*
neigh
,
const
unsigned
char
*
nexthop
,
const
unsigned
char
*
nexthop
,
...
...
source.c
View file @
b8e832cb
...
@@ -35,7 +35,9 @@ THE SOFTWARE.
...
@@ -35,7 +35,9 @@ THE SOFTWARE.
struct
source
*
srcs
=
NULL
;
struct
source
*
srcs
=
NULL
;
struct
source
*
struct
source
*
find_source
(
const
unsigned
char
*
id
,
const
unsigned
char
*
p
,
unsigned
char
plen
,
find_source
(
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
create
,
unsigned
short
seqno
)
int
create
,
unsigned
short
seqno
)
{
{
struct
source
*
src
;
struct
source
*
src
;
...
@@ -49,7 +51,11 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
...
@@ -49,7 +51,11 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
continue
;
continue
;
if
(
src
->
plen
!=
plen
)
if
(
src
->
plen
!=
plen
)
continue
;
continue
;
if
(
memcmp
(
src
->
prefix
,
p
,
16
)
==
0
)
if
(
src
->
src_plen
!=
src_plen
)
continue
;
if
(
memcmp
(
src
->
prefix
,
prefix
,
16
)
!=
0
)
continue
;
if
(
memcmp
(
src
->
src_prefix
,
src_prefix
,
16
)
==
0
)
return
src
;
return
src
;
}
}
...
@@ -63,8 +69,10 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
...
@@ -63,8 +69,10 @@ find_source(const unsigned char *id, const unsigned char *p, unsigned char plen,
}
}
memcpy
(
src
->
id
,
id
,
8
);
memcpy
(
src
->
id
,
id
,
8
);
memcpy
(
src
->
prefix
,
p
,
16
);
memcpy
(
src
->
prefix
,
p
refix
,
16
);
src
->
plen
=
plen
;
src
->
plen
=
plen
;
memcpy
(
src
->
src_prefix
,
src_prefix
,
16
);
src
->
src_plen
=
src_plen
;
src
->
seqno
=
seqno
;
src
->
seqno
=
seqno
;
src
->
metric
=
INFINITY
;
src
->
metric
=
INFINITY
;
src
->
time
=
now
.
tv_sec
;
src
->
time
=
now
.
tv_sec
;
...
...
source.h
View file @
b8e832cb
...
@@ -27,6 +27,8 @@ struct source {
...
@@ -27,6 +27,8 @@ struct source {
unsigned
char
id
[
8
];
unsigned
char
id
[
8
];
unsigned
char
prefix
[
16
];
unsigned
char
prefix
[
16
];
unsigned
char
plen
;
unsigned
char
plen
;
unsigned
char
src_prefix
[
16
];
unsigned
char
src_plen
;
unsigned
short
seqno
;
unsigned
short
seqno
;
unsigned
short
metric
;
unsigned
short
metric
;
unsigned
short
route_count
;
unsigned
short
route_count
;
...
@@ -34,8 +36,10 @@ struct source {
...
@@ -34,8 +36,10 @@ struct source {
};
};
struct
source
*
find_source
(
const
unsigned
char
*
id
,
struct
source
*
find_source
(
const
unsigned
char
*
id
,
const
unsigned
char
*
p
,
const
unsigned
char
*
p
refix
,
unsigned
char
plen
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
,
int
create
,
unsigned
short
seqno
);
int
create
,
unsigned
short
seqno
);
struct
source
*
retain_source
(
struct
source
*
src
);
struct
source
*
retain_source
(
struct
source
*
src
);
void
release_source
(
struct
source
*
src
);
void
release_source
(
struct
source
*
src
);
...
...
util.h
View file @
b8e832cb
...
@@ -111,6 +111,7 @@ int linklocal(const unsigned char *address) ATTRIBUTE ((pure));
...
@@ -111,6 +111,7 @@ int linklocal(const unsigned char *address) ATTRIBUTE ((pure));
int
v4mapped
(
const
unsigned
char
*
address
)
ATTRIBUTE
((
pure
));
int
v4mapped
(
const
unsigned
char
*
address
)
ATTRIBUTE
((
pure
));
void
v4tov6
(
unsigned
char
*
dst
,
const
unsigned
char
*
src
);
void
v4tov6
(
unsigned
char
*
dst
,
const
unsigned
char
*
src
);
int
daemonise
(
void
);
int
daemonise
(
void
);
int
set_src_prefix
(
unsigned
char
*
src_addr
,
unsigned
char
*
src_plen
);
enum
prefix_status
{
enum
prefix_status
{
PST_DISJOINT
=
1
<<
0
,
PST_DISJOINT
=
1
<<
0
,
...
...
xroute.c
View file @
b8e832cb
...
@@ -43,12 +43,15 @@ static struct xroute *xroutes;
...
@@ -43,12 +43,15 @@ static struct xroute *xroutes;
static
int
numxroutes
=
0
,
maxxroutes
=
0
;
static
int
numxroutes
=
0
,
maxxroutes
=
0
;
struct
xroute
*
struct
xroute
*
find_xroute
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
find_xroute
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
)
{
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
{
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
{
if
(
xroutes
[
i
].
plen
==
plen
&&
if
(
xroutes
[
i
].
plen
==
plen
&&
memcmp
(
xroutes
[
i
].
prefix
,
prefix
,
16
)
==
0
)
memcmp
(
xroutes
[
i
].
prefix
,
prefix
,
16
)
==
0
&&
xroutes
[
i
].
src_plen
==
src_plen
&&
memcmp
(
xroutes
[
i
].
src_prefix
,
src_prefix
,
16
)
==
0
)
return
&
xroutes
[
i
];
return
&
xroutes
[
i
];
}
}
return
NULL
;
return
NULL
;
...
@@ -86,9 +89,10 @@ flush_xroute(struct xroute *xroute)
...
@@ -86,9 +89,10 @@ flush_xroute(struct xroute *xroute)
int
int
add_xroute
(
unsigned
char
prefix
[
16
],
unsigned
char
plen
,
add_xroute
(
unsigned
char
prefix
[
16
],
unsigned
char
plen
,
unsigned
char
src_prefix
[
16
],
unsigned
char
src_plen
,
unsigned
short
metric
,
unsigned
int
ifindex
,
int
proto
)
unsigned
short
metric
,
unsigned
int
ifindex
,
int
proto
)
{
{
struct
xroute
*
xroute
=
find_xroute
(
prefix
,
plen
);
struct
xroute
*
xroute
=
find_xroute
(
prefix
,
plen
,
src_prefix
,
src_plen
);
if
(
xroute
)
{
if
(
xroute
)
{
if
(
xroute
->
metric
<=
metric
)
if
(
xroute
->
metric
<=
metric
)
return
0
;
return
0
;
...
@@ -111,6 +115,8 @@ add_xroute(unsigned char prefix[16], unsigned char plen,
...
@@ -111,6 +115,8 @@ add_xroute(unsigned char prefix[16], unsigned char plen,
memcpy
(
xroutes
[
numxroutes
].
prefix
,
prefix
,
16
);
memcpy
(
xroutes
[
numxroutes
].
prefix
,
prefix
,
16
);
xroutes
[
numxroutes
].
plen
=
plen
;
xroutes
[
numxroutes
].
plen
=
plen
;
memcpy
(
xroutes
[
numxroutes
].
src_prefix
,
src_prefix
,
16
);
xroutes
[
numxroutes
].
src_plen
=
src_plen
;
xroutes
[
numxroutes
].
metric
=
metric
;
xroutes
[
numxroutes
].
metric
=
metric
;
xroutes
[
numxroutes
].
ifindex
=
ifindex
;
xroutes
[
numxroutes
].
ifindex
=
ifindex
;
xroutes
[
numxroutes
].
proto
=
proto
;
xroutes
[
numxroutes
].
proto
=
proto
;
...
@@ -200,6 +206,7 @@ check_xroutes(int send_updates)
...
@@ -200,6 +206,7 @@ check_xroutes(int send_updates)
while
(
i
<
numxroutes
)
{
while
(
i
<
numxroutes
)
{
export
=
0
;
export
=
0
;
metric
=
redistribute_filter
(
xroutes
[
i
].
prefix
,
xroutes
[
i
].
plen
,
metric
=
redistribute_filter
(
xroutes
[
i
].
prefix
,
xroutes
[
i
].
plen
,
xroutes
[
i
].
src_prefix
,
xroutes
[
i
].
src_plen
,
xroutes
[
i
].
ifindex
,
xroutes
[
i
].
proto
);
xroutes
[
i
].
ifindex
,
xroutes
[
i
].
proto
);
if
(
metric
<
INFINITY
&&
metric
==
xroutes
[
i
].
metric
)
{
if
(
metric
<
INFINITY
&&
metric
==
xroutes
[
i
].
metric
)
{
for
(
j
=
0
;
j
<
numroutes
;
j
++
)
{
for
(
j
=
0
;
j
<
numroutes
;
j
++
)
{
...
@@ -215,17 +222,20 @@ check_xroutes(int send_updates)
...
@@ -215,17 +222,20 @@ check_xroutes(int send_updates)
if
(
!
export
)
{
if
(
!
export
)
{
unsigned
char
prefix
[
16
],
plen
;
unsigned
char
prefix
[
16
],
plen
;
unsigned
char
src_prefix
[
16
],
src_plen
;
struct
babel_route
*
route
;
struct
babel_route
*
route
;
memcpy
(
prefix
,
xroutes
[
i
].
prefix
,
16
);
memcpy
(
prefix
,
xroutes
[
i
].
prefix
,
16
);
plen
=
xroutes
[
i
].
plen
;
plen
=
xroutes
[
i
].
plen
;
memcpy
(
src_prefix
,
xroutes
[
i
].
src_prefix
,
16
);
src_plen
=
xroutes
[
i
].
src_plen
;
flush_xroute
(
&
xroutes
[
i
]);
flush_xroute
(
&
xroutes
[
i
]);
route
=
find_best_route
(
prefix
,
plen
,
1
,
NULL
);
route
=
find_best_route
(
prefix
,
plen
,
src_prefix
,
src_plen
,
1
,
NULL
);
if
(
route
)
if
(
route
)
install_route
(
route
);
install_route
(
route
);
/* send_update_resend only records the prefix, so the update
/* send_update_resend only records the prefix, so the update
will only be sent after we perform all of the changes. */
will only be sent after we perform all of the changes. */
if
(
send_updates
)
if
(
send_updates
)
send_update_resend
(
NULL
,
prefix
,
plen
);
send_update_resend
(
NULL
,
prefix
,
plen
,
src_prefix
,
src_plen
);
change
=
1
;
change
=
1
;
}
else
{
}
else
{
i
++
;
i
++
;
...
@@ -238,13 +248,17 @@ check_xroutes(int send_updates)
...
@@ -238,13 +248,17 @@ check_xroutes(int send_updates)
if
(
martian_prefix
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
))
if
(
martian_prefix
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
))
continue
;
continue
;
metric
=
redistribute_filter
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
metric
=
redistribute_filter
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
routes
[
i
].
src_prefix
,
routes
[
i
].
src_plen
,
routes
[
i
].
ifindex
,
routes
[
i
].
proto
);
routes
[
i
].
ifindex
,
routes
[
i
].
proto
);
if
(
metric
<
INFINITY
)
{
if
(
metric
<
INFINITY
)
{
rc
=
add_xroute
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
rc
=
add_xroute
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
routes
[
i
].
src_prefix
,
routes
[
i
].
src_plen
,
metric
,
routes
[
i
].
ifindex
,
routes
[
i
].
proto
);
metric
,
routes
[
i
].
ifindex
,
routes
[
i
].
proto
);
if
(
rc
>
0
)
{
if
(
rc
>
0
)
{
struct
babel_route
*
route
;
struct
babel_route
*
route
;
route
=
find_installed_route
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
);
route
=
find_installed_route
(
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
routes
[
i
].
src_prefix
,
routes
[
i
].
src_plen
);
if
(
route
)
{
if
(
route
)
{
if
(
allow_duplicates
<
0
||
if
(
allow_duplicates
<
0
||
routes
[
i
].
metric
<
allow_duplicates
)
routes
[
i
].
metric
<
allow_duplicates
)
...
@@ -252,7 +266,8 @@ check_xroutes(int send_updates)
...
@@ -252,7 +266,8 @@ check_xroutes(int send_updates)
}
}
change
=
1
;
change
=
1
;
if
(
send_updates
)
if
(
send_updates
)
send_update
(
NULL
,
0
,
routes
[
i
].
prefix
,
routes
[
i
].
plen
);
send_update
(
NULL
,
0
,
routes
[
i
].
prefix
,
routes
[
i
].
plen
,
routes
[
i
].
src_prefix
,
routes
[
i
].
src_plen
);
}
}
}
}
}
}
...
...
xroute.h
View file @
b8e832cb
...
@@ -23,6 +23,8 @@ THE SOFTWARE.
...
@@ -23,6 +23,8 @@ THE SOFTWARE.
struct
xroute
{
struct
xroute
{
unsigned
char
prefix
[
16
];
unsigned
char
prefix
[
16
];
unsigned
char
plen
;
unsigned
char
plen
;
unsigned
char
src_prefix
[
16
];
unsigned
char
src_plen
;
unsigned
short
metric
;
unsigned
short
metric
;
unsigned
int
ifindex
;
unsigned
int
ifindex
;
int
proto
;
int
proto
;
...
@@ -30,9 +32,11 @@ struct xroute {
...
@@ -30,9 +32,11 @@ struct xroute {
struct
xroute_stream
;
struct
xroute_stream
;
struct
xroute
*
find_xroute
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
struct
xroute
*
find_xroute
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
src_prefix
,
unsigned
char
src_plen
);
void
flush_xroute
(
struct
xroute
*
xroute
);
void
flush_xroute
(
struct
xroute
*
xroute
);
int
add_xroute
(
unsigned
char
prefix
[
16
],
unsigned
char
plen
,
int
add_xroute
(
unsigned
char
prefix
[
16
],
unsigned
char
plen
,
unsigned
char
src_prefix
[
16
],
unsigned
char
src_plen
,
unsigned
short
metric
,
unsigned
int
ifindex
,
int
proto
);
unsigned
short
metric
,
unsigned
int
ifindex
,
int
proto
);
int
xroutes_estimate
(
void
);
int
xroutes_estimate
(
void
);
struct
xroute_stream
*
xroute_stream
();
struct
xroute_stream
*
xroute_stream
();
...
...
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