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
1c3b2bb8
Commit
1c3b2bb8
authored
Sep 09, 2011
by
Matthieu Boutier
Committed by
Juliusz Chroboczek
Sep 09, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename struct network to interface and associated changes.
parent
5f40b621
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
700 additions
and
701 deletions
+700
-701
babeld.c
babeld.c
+64
-64
configuration.c
configuration.c
+46
-46
kernel_netlink.c
kernel_netlink.c
+3
-3
local.c
local.c
+2
-2
message.c
message.c
+303
-303
message.h
message.h
+13
-13
neighbour.c
neighbour.c
+16
-16
neighbour.h
neighbour.h
+2
-2
network.c
network.c
+185
-185
network.h
network.h
+28
-29
resend.c
resend.c
+12
-12
resend.h
resend.h
+4
-4
route.c
route.c
+19
-19
route.h
route.h
+3
-3
No files found.
babeld.c
View file @
1c3b2bb8
...
@@ -108,7 +108,7 @@ main(int argc, char **argv)
...
@@ -108,7 +108,7 @@ main(int argc, char **argv)
char
*
config_file
=
NULL
;
char
*
config_file
=
NULL
;
void
*
vrc
;
void
*
vrc
;
unsigned
int
seed
;
unsigned
int
seed
;
struct
network
*
net
;
struct
interface
*
ifp
;
gettime
(
&
now
);
gettime
(
&
now
);
...
@@ -362,22 +362,22 @@ main(int argc, char **argv)
...
@@ -362,22 +362,22 @@ main(int argc, char **argv)
}
}
for
(
i
=
optind
;
i
<
argc
;
i
++
)
{
for
(
i
=
optind
;
i
<
argc
;
i
++
)
{
vrc
=
add_
network
(
argv
[
i
],
NULL
);
vrc
=
add_
interface
(
argv
[
i
],
NULL
);
if
(
vrc
==
NULL
)
if
(
vrc
==
NULL
)
goto
fail
;
goto
fail
;
}
}
if
(
network
s
==
NULL
)
{
if
(
interface
s
==
NULL
)
{
fprintf
(
stderr
,
"Eek... asked to run on no interfaces!
\n
"
);
fprintf
(
stderr
,
"Eek... asked to run on no interfaces!
\n
"
);
goto
fail
;
goto
fail
;
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
/*
net
->ifindex is not necessarily valid at this point */
/*
ifp
->ifindex is not necessarily valid at this point */
int
ifindex
=
if_nametoindex
(
net
->
if
name
);
int
ifindex
=
if_nametoindex
(
ifp
->
name
);
if
(
ifindex
>
0
)
{
if
(
ifindex
>
0
)
{
unsigned
char
eui
[
8
];
unsigned
char
eui
[
8
];
rc
=
if_eui64
(
net
->
if
name
,
ifindex
,
eui
);
rc
=
if_eui64
(
ifp
->
name
,
ifindex
,
eui
);
if
(
rc
<
0
)
if
(
rc
<
0
)
continue
;
continue
;
memcpy
(
myid
,
eui
,
8
);
memcpy
(
myid
,
eui
,
8
);
...
@@ -482,7 +482,7 @@ main(int argc, char **argv)
...
@@ -482,7 +482,7 @@ main(int argc, char **argv)
rc
=
resize_receive_buffer
(
1500
);
rc
=
resize_receive_buffer
(
1500
);
if
(
rc
<
0
)
if
(
rc
<
0
)
goto
fail
;
goto
fail
;
check_
network
s
();
check_
interface
s
();
if
(
receive_buffer
==
NULL
)
if
(
receive_buffer
==
NULL
)
goto
fail
;
goto
fail
;
...
@@ -499,27 +499,27 @@ main(int argc, char **argv)
...
@@ -499,27 +499,27 @@ main(int argc, char **argv)
/* Make some noise so that others notice us, and send retractions in
/* Make some noise so that others notice us, and send retractions in
case we were restarted recently */
case we were restarted recently */
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
/* Apply jitter before we send the first message. */
/* Apply jitter before we send the first message. */
usleep
(
roughly
(
10000
));
usleep
(
roughly
(
10000
));
gettime
(
&
now
);
gettime
(
&
now
);
send_hello
(
net
);
send_hello
(
ifp
);
send_wildcard_retraction
(
net
);
send_wildcard_retraction
(
ifp
);
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
usleep
(
roughly
(
10000
));
usleep
(
roughly
(
10000
));
gettime
(
&
now
);
gettime
(
&
now
);
send_hello
(
net
);
send_hello
(
ifp
);
send_wildcard_retraction
(
net
);
send_wildcard_retraction
(
ifp
);
send_self_update
(
net
);
send_self_update
(
ifp
);
send_request
(
net
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
flushupdates
(
net
);
flushupdates
(
ifp
);
flushbuf
(
net
);
flushbuf
(
ifp
);
}
}
debugf
(
"Entering main loop.
\n
"
);
debugf
(
"Entering main loop.
\n
"
);
...
@@ -535,13 +535,13 @@ main(int argc, char **argv)
...
@@ -535,13 +535,13 @@ main(int argc, char **argv)
timeval_min_sec
(
&
tv
,
source_expiry_time
);
timeval_min_sec
(
&
tv
,
source_expiry_time
);
timeval_min_sec
(
&
tv
,
kernel_dump_time
);
timeval_min_sec
(
&
tv
,
kernel_dump_time
);
timeval_min
(
&
tv
,
&
resend_time
);
timeval_min
(
&
tv
,
&
resend_time
);
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
timeval_min
(
&
tv
,
&
net
->
flush_timeout
);
timeval_min
(
&
tv
,
&
ifp
->
flush_timeout
);
timeval_min
(
&
tv
,
&
net
->
hello_timeout
);
timeval_min
(
&
tv
,
&
ifp
->
hello_timeout
);
timeval_min
(
&
tv
,
&
net
->
update_timeout
);
timeval_min
(
&
tv
,
&
ifp
->
update_timeout
);
timeval_min
(
&
tv
,
&
net
->
update_flush_timeout
);
timeval_min
(
&
tv
,
&
ifp
->
update_flush_timeout
);
}
}
timeval_min
(
&
tv
,
&
unicast_flush_timeout
);
timeval_min
(
&
tv
,
&
unicast_flush_timeout
);
FD_ZERO
(
&
readfds
);
FD_ZERO
(
&
readfds
);
...
@@ -593,11 +593,11 @@ main(int argc, char **argv)
...
@@ -593,11 +593,11 @@ main(int argc, char **argv)
sleep
(
1
);
sleep
(
1
);
}
}
}
else
{
}
else
{
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
if
(
net
->
ifindex
==
sin6
.
sin6_scope_id
)
{
if
(
ifp
->
ifindex
==
sin6
.
sin6_scope_id
)
{
parse_packet
((
unsigned
char
*
)
&
sin6
.
sin6_addr
,
net
,
parse_packet
((
unsigned
char
*
)
&
sin6
.
sin6_addr
,
ifp
,
receive_buffer
,
rc
);
receive_buffer
,
rc
);
VALGRIND_MAKE_MEM_UNDEFINED
(
receive_buffer
,
VALGRIND_MAKE_MEM_UNDEFINED
(
receive_buffer
,
receive_buffer_size
);
receive_buffer_size
);
...
@@ -647,7 +647,7 @@ main(int argc, char **argv)
...
@@ -647,7 +647,7 @@ main(int argc, char **argv)
}
}
if
(
kernel_link_changed
||
kernel_addr_changed
)
{
if
(
kernel_link_changed
||
kernel_addr_changed
)
{
check_
network
s
();
check_
interface
s
();
kernel_link_changed
=
0
;
kernel_link_changed
=
0
;
}
}
...
@@ -671,7 +671,7 @@ main(int argc, char **argv)
...
@@ -671,7 +671,7 @@ main(int argc, char **argv)
}
}
if
(
now
.
tv_sec
>=
expiry_time
)
{
if
(
now
.
tv_sec
>=
expiry_time
)
{
check_
network
s
();
check_
interface
s
();
expire_routes
();
expire_routes
();
expire_resend
();
expire_resend
();
expiry_time
=
now
.
tv_sec
+
roughly
(
30
);
expiry_time
=
now
.
tv_sec
+
roughly
(
30
);
...
@@ -682,15 +682,15 @@ main(int argc, char **argv)
...
@@ -682,15 +682,15 @@ main(int argc, char **argv)
source_expiry_time
=
now
.
tv_sec
+
roughly
(
300
);
source_expiry_time
=
now
.
tv_sec
+
roughly
(
300
);
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
if
(
timeval_compare
(
&
now
,
&
net
->
hello_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
hello_timeout
)
>=
0
)
send_hello
(
net
);
send_hello
(
ifp
);
if
(
timeval_compare
(
&
now
,
&
net
->
update_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_timeout
)
>=
0
)
send_update
(
net
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
);
if
(
timeval_compare
(
&
now
,
&
net
->
update_flush_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
update_flush_timeout
)
>=
0
)
flushupdates
(
net
);
flushupdates
(
ifp
);
}
}
if
(
resend_time
.
tv_sec
!=
0
)
{
if
(
resend_time
.
tv_sec
!=
0
)
{
...
@@ -703,12 +703,12 @@ main(int argc, char **argv)
...
@@ -703,12 +703,12 @@ main(int argc, char **argv)
flush_unicast
(
1
);
flush_unicast
(
1
);
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
if
(
net
->
flush_timeout
.
tv_sec
!=
0
)
{
if
(
ifp
->
flush_timeout
.
tv_sec
!=
0
)
{
if
(
timeval_compare
(
&
now
,
&
net
->
flush_timeout
)
>=
0
)
if
(
timeval_compare
(
&
now
,
&
ifp
->
flush_timeout
)
>=
0
)
flushbuf
(
net
);
flushbuf
(
ifp
);
}
}
}
}
...
@@ -726,31 +726,31 @@ main(int argc, char **argv)
...
@@ -726,31 +726,31 @@ main(int argc, char **argv)
while
(
numroutes
>
0
)
{
while
(
numroutes
>
0
)
{
if
(
routes
[
0
].
installed
)
if
(
routes
[
0
].
installed
)
uninstall_route
(
&
routes
[
0
]);
uninstall_route
(
&
routes
[
0
]);
/* We need to flush the route so
network
_up won't reinstall it */
/* We need to flush the route so
interface
_up won't reinstall it */
flush_route
(
&
routes
[
0
]);
flush_route
(
&
routes
[
0
]);
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
send_wildcard_retraction
(
net
);
send_wildcard_retraction
(
ifp
);
/* Make sure that we expire quickly from our neighbours'
/* Make sure that we expire quickly from our neighbours'
association caches. */
association caches. */
send_hello_noupdate
(
net
,
10
);
send_hello_noupdate
(
ifp
,
10
);
flushbuf
(
net
);
flushbuf
(
ifp
);
usleep
(
roughly
(
1000
));
usleep
(
roughly
(
1000
));
gettime
(
&
now
);
gettime
(
&
now
);
}
}
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
/* Make sure they got it. */
/* Make sure they got it. */
send_wildcard_retraction
(
net
);
send_wildcard_retraction
(
ifp
);
send_hello_noupdate
(
net
,
1
);
send_hello_noupdate
(
ifp
,
1
);
flushbuf
(
net
);
flushbuf
(
ifp
);
usleep
(
roughly
(
10000
));
usleep
(
roughly
(
10000
));
gettime
(
&
now
);
gettime
(
&
now
);
network_up
(
net
,
0
);
interface_up
(
ifp
,
0
);
}
}
kernel_setup_socket
(
0
);
kernel_setup_socket
(
0
);
kernel_setup
(
0
);
kernel_setup
(
0
);
...
@@ -802,10 +802,10 @@ main(int argc, char **argv)
...
@@ -802,10 +802,10 @@ main(int argc, char **argv)
exit
(
1
);
exit
(
1
);
fail:
fail:
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
continue
;
continue
;
network_up
(
net
,
0
);
interface_up
(
ifp
,
0
);
}
}
kernel_setup_socket
(
0
);
kernel_setup_socket
(
0
);
kernel_setup
(
0
);
kernel_setup
(
0
);
...
@@ -936,12 +936,12 @@ dump_tables(FILE *out)
...
@@ -936,12 +936,12 @@ dump_tables(FILE *out)
FOR_ALL_NEIGHBOURS
(
neigh
)
{
FOR_ALL_NEIGHBOURS
(
neigh
)
{
fprintf
(
out
,
"Neighbour %s dev %s reach %04x rxcost %d txcost %d chan %d%s.
\n
"
,
fprintf
(
out
,
"Neighbour %s dev %s reach %04x rxcost %d txcost %d chan %d%s.
\n
"
,
format_address
(
neigh
->
address
),
format_address
(
neigh
->
address
),
neigh
->
network
->
if
name
,
neigh
->
ifp
->
name
,
neigh
->
reach
,
neigh
->
reach
,
neighbour_rxcost
(
neigh
),
neighbour_rxcost
(
neigh
),
neigh
->
txcost
,
neigh
->
txcost
,
neigh
->
network
->
channel
,
neigh
->
ifp
->
channel
,
net_up
(
neigh
->
network
)
?
""
:
" (down)"
);
if_up
(
neigh
->
ifp
)
?
""
:
" (down)"
);
}
}
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
{
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
{
fprintf
(
out
,
"%s metric %d (exported)
\n
"
,
fprintf
(
out
,
"%s metric %d (exported)
\n
"
,
...
@@ -980,7 +980,7 @@ dump_tables(FILE *out)
...
@@ -980,7 +980,7 @@ dump_tables(FILE *out)
(
int
)
routes
[
i
].
seqno
,
(
int
)
routes
[
i
].
seqno
,
channels
,
channels
,
(
int
)(
now
.
tv_sec
-
routes
[
i
].
time
),
(
int
)(
now
.
tv_sec
-
routes
[
i
].
time
),
routes
[
i
].
neigh
->
network
->
if
name
,
routes
[
i
].
neigh
->
ifp
->
name
,
format_address
(
routes
[
i
].
neigh
->
address
),
format_address
(
routes
[
i
].
neigh
->
address
),
nexthop
?
" nexthop "
:
""
,
nexthop
?
" nexthop "
:
""
,
nexthop
?
format_address
(
nexthop
)
:
""
,
nexthop
?
format_address
(
nexthop
)
:
""
,
...
...
configuration.c
View file @
1c3b2bb8
...
@@ -40,7 +40,7 @@ THE SOFTWARE.
...
@@ -40,7 +40,7 @@ THE SOFTWARE.
struct
filter
*
input_filters
=
NULL
;
struct
filter
*
input_filters
=
NULL
;
struct
filter
*
output_filters
=
NULL
;
struct
filter
*
output_filters
=
NULL
;
struct
filter
*
redistribute_filters
=
NULL
;
struct
filter
*
redistribute_filters
=
NULL
;
struct
network_conf
*
network
_confs
=
NULL
;
struct
interface_conf
*
interface
_confs
=
NULL
;
/* get_next_char callback */
/* get_next_char callback */
typedef
int
(
*
gnc_t
)(
void
*
);
typedef
int
(
*
gnc_t
)(
void
*
);
...
@@ -370,15 +370,15 @@ parse_filter(gnc_t gnc, void *closure)
...
@@ -370,15 +370,15 @@ parse_filter(gnc_t gnc, void *closure)
return
NULL
;
return
NULL
;
}
}
static
struct
network
_conf
*
static
struct
interface
_conf
*
parse_
n
conf
(
gnc_t
gnc
,
void
*
closure
)
parse_
if
conf
(
gnc_t
gnc
,
void
*
closure
)
{
{
int
c
;
int
c
;
char
*
token
;
char
*
token
;
struct
network_conf
*
n
conf
;
struct
interface_conf
*
if_
conf
;
nconf
=
calloc
(
1
,
sizeof
(
struct
network
_conf
));
if_conf
=
calloc
(
1
,
sizeof
(
struct
interface
_conf
));
if
(
n
conf
==
NULL
)
if
(
if_
conf
==
NULL
)
goto
error
;
goto
error
;
c
=
gnc
(
closure
);
c
=
gnc
(
closure
);
...
@@ -393,7 +393,7 @@ parse_nconf(gnc_t gnc, void *closure)
...
@@ -393,7 +393,7 @@ parse_nconf(gnc_t gnc, void *closure)
if
(
c
<
-
1
||
token
==
NULL
)
if
(
c
<
-
1
||
token
==
NULL
)
goto
error
;
goto
error
;
n
conf
->
ifname
=
token
;
if_
conf
->
ifname
=
token
;
while
(
c
>=
0
&&
c
!=
'\n'
)
{
while
(
c
>=
0
&&
c
!=
'\n'
)
{
c
=
skip_whitespace
(
c
,
gnc
,
closure
);
c
=
skip_whitespace
(
c
,
gnc
,
closure
);
...
@@ -410,43 +410,43 @@ parse_nconf(gnc_t gnc, void *closure)
...
@@ -410,43 +410,43 @@ parse_nconf(gnc_t gnc, void *closure)
c
=
getint
(
c
,
&
cost
,
gnc
,
closure
);
c
=
getint
(
c
,
&
cost
,
gnc
,
closure
);
if
(
c
<
-
1
||
cost
<=
0
||
cost
>
0xFFFF
)
if
(
c
<
-
1
||
cost
<=
0
||
cost
>
0xFFFF
)
goto
error
;
goto
error
;
n
conf
->
cost
=
cost
;
if_
conf
->
cost
=
cost
;
}
else
if
(
strcmp
(
token
,
"hello-interval"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"hello-interval"
)
==
0
)
{
int
interval
;
int
interval
;
c
=
getmsec
(
c
,
&
interval
,
gnc
,
closure
);
c
=
getmsec
(
c
,
&
interval
,
gnc
,
closure
);
if
(
c
<
-
1
||
interval
<=
0
||
interval
>
10
*
0xFFFF
)
if
(
c
<
-
1
||
interval
<=
0
||
interval
>
10
*
0xFFFF
)
goto
error
;
goto
error
;
n
conf
->
hello_interval
=
interval
;
if_
conf
->
hello_interval
=
interval
;
}
else
if
(
strcmp
(
token
,
"update-interval"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"update-interval"
)
==
0
)
{
int
interval
;
int
interval
;
c
=
getmsec
(
c
,
&
interval
,
gnc
,
closure
);
c
=
getmsec
(
c
,
&
interval
,
gnc
,
closure
);
if
(
c
<
-
1
||
interval
<=
0
||
interval
>
10
*
0xFFFF
)
if
(
c
<
-
1
||
interval
<=
0
||
interval
>
10
*
0xFFFF
)
goto
error
;
goto
error
;
n
conf
->
update_interval
=
interval
;
if_
conf
->
update_interval
=
interval
;
}
else
if
(
strcmp
(
token
,
"wired"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"wired"
)
==
0
)
{
int
v
;
int
v
;
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
if
(
c
<
-
1
)
if
(
c
<
-
1
)
goto
error
;
goto
error
;
n
conf
->
wired
=
v
;
if_
conf
->
wired
=
v
;
}
else
if
(
strcmp
(
token
,
"faraway"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"faraway"
)
==
0
)
{
int
v
;
int
v
;
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
if
(
c
<
-
1
)
if
(
c
<
-
1
)
goto
error
;
goto
error
;
n
conf
->
faraway
=
v
;
if_
conf
->
faraway
=
v
;
}
else
if
(
strcmp
(
token
,
"link-quality"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"link-quality"
)
==
0
)
{
int
v
;
int
v
;
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
if
(
c
<
-
1
)
if
(
c
<
-
1
)
goto
error
;
goto
error
;
n
conf
->
lq
=
v
;
if_
conf
->
lq
=
v
;
}
else
if
(
strcmp
(
token
,
"split-horizon"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"split-horizon"
)
==
0
)
{
int
v
;
int
v
;
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
c
=
getbool
(
c
,
&
v
,
gnc
,
closure
);
if
(
c
<
-
1
)
if
(
c
<
-
1
)
goto
error
;
goto
error
;
n
conf
->
split_horizon
=
v
;
if_
conf
->
split_horizon
=
v
;
}
else
if
(
strcmp
(
token
,
"channel"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"channel"
)
==
0
)
{
char
*
t
,
*
end
;
char
*
t
,
*
end
;
...
@@ -455,19 +455,19 @@ parse_nconf(gnc_t gnc, void *closure)
...
@@ -455,19 +455,19 @@ parse_nconf(gnc_t gnc, void *closure)
goto
error
;
goto
error
;
if
(
strcmp
(
t
,
"noninterfering"
)
==
0
)
if
(
strcmp
(
t
,
"noninterfering"
)
==
0
)
nconf
->
channel
=
NET
_CHANNEL_NONINTERFERING
;
if_conf
->
channel
=
IF
_CHANNEL_NONINTERFERING
;
else
if
(
strcmp
(
t
,
"interfering"
)
==
0
)
else
if
(
strcmp
(
t
,
"interfering"
)
==
0
)
nconf
->
channel
=
NET
_CHANNEL_INTERFERING
;
if_conf
->
channel
=
IF
_CHANNEL_INTERFERING
;
else
{
else
{
n
conf
->
channel
=
strtol
(
t
,
&
end
,
0
);
if_
conf
->
channel
=
strtol
(
t
,
&
end
,
0
);
if
(
*
end
!=
'\0'
)
if
(
*
end
!=
'\0'
)
goto
error
;
goto
error
;
}
}
free
(
t
);
free
(
t
);
if
((
nconf
->
channel
<
1
||
n
conf
->
channel
>
254
)
&&
if
((
if_conf
->
channel
<
1
||
if_
conf
->
channel
>
254
)
&&
nconf
->
channel
!=
NET
_CHANNEL_NONINTERFERING
)
if_conf
->
channel
!=
IF
_CHANNEL_NONINTERFERING
)
goto
error
;
goto
error
;
}
else
{
}
else
{
goto
error
;
goto
error
;
...
@@ -475,10 +475,10 @@ parse_nconf(gnc_t gnc, void *closure)
...
@@ -475,10 +475,10 @@ parse_nconf(gnc_t gnc, void *closure)
free
(
token
);
free
(
token
);
}
}
return
n
conf
;
return
if_
conf
;
error:
error:
free
(
n
conf
);
free
(
if_
conf
);
return
NULL
;
return
NULL
;
}
}
...
@@ -499,7 +499,7 @@ add_filter(struct filter *filter, struct filter **filters)
...
@@ -499,7 +499,7 @@ add_filter(struct filter *filter, struct filter **filters)
}
}
static
void
static
void
merge_
nconf
(
struct
network_conf
*
dest
,
struct
network
_conf
*
src
)
merge_
ifconf
(
struct
interface_conf
*
dest
,
struct
interface
_conf
*
src
)
{
{
assert
(
strcmp
(
dest
->
ifname
,
src
->
ifname
)
==
0
);
assert
(
strcmp
(
dest
->
ifname
,
src
->
ifname
)
==
0
);
...
@@ -520,24 +520,24 @@ merge_nconf(struct network_conf *dest, struct network_conf *src)
...
@@ -520,24 +520,24 @@ merge_nconf(struct network_conf *dest, struct network_conf *src)
}
}
static
void
static
void
add_
nconf
(
struct
network_conf
*
nconf
,
struct
network_conf
**
n
confs
)
add_
ifconf
(
struct
interface_conf
*
if_conf
,
struct
interface_conf
**
if_
confs
)
{
{
if
(
*
n
confs
==
NULL
)
{
if
(
*
if_
confs
==
NULL
)
{
n
conf
->
next
=
NULL
;
if_
conf
->
next
=
NULL
;
*
nconfs
=
n
conf
;
*
if_confs
=
if_
conf
;
}
else
{
}
else
{
struct
network_conf
*
n
;
struct
interface_conf
*
if_c
;
n
=
*
n
confs
;
if_c
=
*
if_
confs
;
while
(
n
->
next
)
{
while
(
if_c
->
next
)
{
if
(
strcmp
(
n
->
ifname
,
n
conf
->
ifname
)
==
0
)
{
if
(
strcmp
(
if_c
->
ifname
,
if_
conf
->
ifname
)
==
0
)
{
merge_
nconf
(
n
,
n
conf
);
merge_
ifconf
(
if_c
,
if_
conf
);
free
(
n
conf
);
free
(
if_
conf
);
return
;
return
;
}
}
n
=
n
->
next
;
if_c
=
if_c
->
next
;
}
}
n
conf
->
next
=
NULL
;
if_
conf
->
next
=
NULL
;
n
->
next
=
n
conf
;
if_c
->
next
=
if_
conf
;
}
}
}
}
...
@@ -582,11 +582,11 @@ parse_config(gnc_t gnc, void *closure)
...
@@ -582,11 +582,11 @@ parse_config(gnc_t gnc, void *closure)
return
-
1
;
return
-
1
;
add_filter
(
filter
,
&
redistribute_filters
);
add_filter
(
filter
,
&
redistribute_filters
);
}
else
if
(
strcmp
(
token
,
"interface"
)
==
0
)
{
}
else
if
(
strcmp
(
token
,
"interface"
)
==
0
)
{
struct
network_conf
*
n
conf
;
struct
interface_conf
*
if_
conf
;
nconf
=
parse_n
conf
(
gnc
,
closure
);
if_conf
=
parse_if
conf
(
gnc
,
closure
);
if
(
n
conf
==
NULL
)
if
(
if_
conf
==
NULL
)
return
-
1
;
return
-
1
;
add_
nconf
(
nconf
,
&
network
_confs
);
add_
ifconf
(
if_conf
,
&
interface
_confs
);
}
else
{
}
else
{
return
-
1
;
return
-
1
;
}
}
...
@@ -759,15 +759,15 @@ finalise_config()
...
@@ -759,15 +759,15 @@ finalise_config()
filter
->
plen_le
=
128
;
filter
->
plen_le
=
128
;
add_filter
(
filter
,
&
redistribute_filters
);
add_filter
(
filter
,
&
redistribute_filters
);
while
(
network
_confs
)
{
while
(
interface
_confs
)
{
struct
network_conf
*
n
;
struct
interface_conf
*
if_conf
;
void
*
vrc
;
void
*
vrc
;
n
=
network
_confs
;
if_conf
=
interface
_confs
;
network_confs
=
network
_confs
->
next
;
interface_confs
=
interface
_confs
->
next
;
n
->
next
=
NULL
;
if_conf
->
next
=
NULL
;
vrc
=
add_
network
(
n
->
ifname
,
n
);
vrc
=
add_
interface
(
if_conf
->
ifname
,
if_conf
);
if
(
vrc
==
NULL
)
{
if
(
vrc
==
NULL
)
{
fprintf
(
stderr
,
"Couldn't add interface %s.
\n
"
,
n
->
ifname
);
fprintf
(
stderr
,
"Couldn't add interface %s.
\n
"
,
if_conf
->
ifname
);
return
-
1
;
return
-
1
;
}
}
}
}
...
...
kernel_netlink.c
View file @
1c3b2bb8
...
@@ -1239,7 +1239,7 @@ filter_link(struct nlmsghdr *nh, void *data)
...
@@ -1239,7 +1239,7 @@ filter_link(struct nlmsghdr *nh, void *data)
int
ifindex
;
int
ifindex
;
char
*
ifname
;
char
*
ifname
;
unsigned
int
ifflags
;
unsigned
int
ifflags
;
struct
network
*
net
;
struct
interface
*
ifp
;
len
=
nh
->
nlmsg_len
;
len
=
nh
->
nlmsg_len
;
...
@@ -1257,8 +1257,8 @@ filter_link(struct nlmsghdr *nh, void *data)
...
@@ -1257,8 +1257,8 @@ filter_link(struct nlmsghdr *nh, void *data)
return
0
;
return
0
;
kdebugf
(
"filter_interfaces: link change on if %s(%d): 0x%x
\n
"
,
kdebugf
(
"filter_interfaces: link change on if %s(%d): 0x%x
\n
"
,
ifname
,
ifindex
,
(
unsigned
)
ifflags
);
ifname
,
ifindex
,
(
unsigned
)
ifflags
);
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
strcmp
(
net
->
if
name
,
ifname
)
==
0
)
if
(
strcmp
(
ifp
->
name
,
ifname
)
==
0
)
return
1
;
return
1
;
}
}
return
0
;
return
0
;
...
...
local.c
View file @
1c3b2bb8
...
@@ -140,7 +140,7 @@ local_notify_neighbour(struct neighbour *neigh, int kind)
...
@@ -140,7 +140,7 @@ local_notify_neighbour(struct neighbour *neigh, int kind)
address as a unique identifier. */
address as a unique identifier. */
(
unsigned
long
int
)
neigh
,
(
unsigned
long
int
)
neigh
,
format_address
(
neigh
->
address
),
format_address
(
neigh
->
address
),
neigh
->
network
->
if
name
,
neigh
->
ifp
->
name
,
neigh
->
reach
,
neigh
->
reach
,
neighbour_rxcost
(
neigh
),
neighbour_rxcost
(
neigh
),
neighbour_txcost
(
neigh
),
neighbour_txcost
(
neigh
),
...
@@ -207,7 +207,7 @@ local_notify_route(struct route *route, int kind)
...
@@ -207,7 +207,7 @@ local_notify_route(struct route *route, int kind)
format_eui64
(
route
->
src
->
id
),
format_eui64
(
route
->
src
->
id
),
route_metric
(
route
),
route
->
refmetric
,
route_metric
(
route
),
route
->
refmetric
,
format_address
(
route
->
neigh
->
address
),
format_address
(
route
->
neigh
->
address
),
route
->
neigh
->
network
->
if
name
);
route
->
neigh
->
ifp
->
name
);
if
(
rc
<
0
||
rc
>=
512
)
if
(
rc
<
0
||
rc
>=
512
)
goto
fail
;
goto
fail
;
...
...
message.c
View file @
1c3b2bb8
...
@@ -182,7 +182,7 @@ channels_len(unsigned char *channels)
...
@@ -182,7 +182,7 @@ channels_len(unsigned char *channels)
}
}
void
void
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
parse_packet
(
const
unsigned
char
*
from
,
struct
interface
*
ifp
,
const
unsigned
char
*
packet
,
int
packetlen
)
const
unsigned
char
*
packet
,
int
packetlen
)
{
{
int
i
;
int
i
;
...
@@ -203,18 +203,18 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -203,18 +203,18 @@ parse_packet(const unsigned char *from, struct network *net,
if
(
packet
[
0
]
!=
42
)
{
if
(
packet
[
0
]
!=
42
)
{
fprintf
(
stderr
,
"Received malformed packet on %s from %s.
\n
"
,
fprintf
(
stderr
,
"Received malformed packet on %s from %s.
\n
"
,
net
->
if
name
,
format_address
(
from
));
ifp
->
name
,
format_address
(
from
));
return
;
return
;
}
}
if
(
packet
[
1
]
!=
2
)
{
if
(
packet
[
1
]
!=
2
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Received packet with unknown version %d on %s from %s.
\n
"
,
"Received packet with unknown version %d on %s from %s.
\n
"
,
packet
[
1
],
net
->
if
name
,
format_address
(
from
));
packet
[
1
],
ifp
->
name
,
format_address
(
from
));
return
;
return
;
}
}
neigh
=
find_neighbour
(
from
,
net
);
neigh
=
find_neighbour
(
from
,
ifp
);
if
(
neigh
==
NULL
)
{
if
(
neigh
==
NULL
)
{
fprintf
(
stderr
,
"Couldn't allocate neighbour.
\n
"
);
fprintf
(
stderr
,
"Couldn't allocate neighbour.
\n
"
);
return
;
return
;
...
@@ -234,7 +234,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -234,7 +234,7 @@ parse_packet(const unsigned char *from, struct network *net,
type
=
message
[
0
];
type
=
message
[
0
];
if
(
type
==
MESSAGE_PAD1
)
{
if
(
type
==
MESSAGE_PAD1
)
{
debugf
(
"Received pad1 from %s on %s.
\n
"
,
debugf
(
"Received pad1 from %s on %s.
\n
"
,
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
i
++
;
i
++
;
continue
;
continue
;
}
}
...
@@ -250,18 +250,18 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -250,18 +250,18 @@ parse_packet(const unsigned char *from, struct network *net,
if
(
type
==
MESSAGE_PADN
)
{
if
(
type
==
MESSAGE_PADN
)
{
debugf
(
"Received pad%d from %s on %s.
\n
"
,
debugf
(
"Received pad%d from %s on %s.
\n
"
,
len
,
format_address
(
from
),
net
->
if
name
);
len
,
format_address
(
from
),
ifp
->
name
);
}
else
if
(
type
==
MESSAGE_ACK_REQ
)
{
}
else
if
(
type
==
MESSAGE_ACK_REQ
)
{
unsigned
short
nonce
,
interval
;
unsigned
short
nonce
,
interval
;
if
(
len
<
6
)
goto
fail
;
if
(
len
<
6
)
goto
fail
;
DO_NTOHS
(
nonce
,
message
+
4
);
DO_NTOHS
(
nonce
,
message
+
4
);
DO_NTOHS
(
interval
,
message
+
6
);
DO_NTOHS
(
interval
,
message
+
6
);
debugf
(
"Received ack-req (%04X %d) from %s on %s.
\n
"
,
debugf
(
"Received ack-req (%04X %d) from %s on %s.
\n
"
,
nonce
,
interval
,
format_address
(
from
),
net
->
if
name
);
nonce
,
interval
,
format_address
(
from
),
ifp
->
name
);
send_ack
(
neigh
,
nonce
,
interval
);
send_ack
(
neigh
,
nonce
,
interval
);
}
else
if
(
type
==
MESSAGE_ACK
)
{
}
else
if
(
type
==
MESSAGE_ACK
)
{
debugf
(
"Received ack from %s on %s.
\n
"
,
debugf
(
"Received ack from %s on %s.
\n
"
,
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
/* Nothing right now */
/* Nothing right now */
}
else
if
(
type
==
MESSAGE_HELLO
)
{
}
else
if
(
type
==
MESSAGE_HELLO
)
{
unsigned
short
seqno
,
interval
;
unsigned
short
seqno
,
interval
;
...
@@ -271,9 +271,9 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -271,9 +271,9 @@ parse_packet(const unsigned char *from, struct network *net,
DO_NTOHS
(
interval
,
message
+
6
);
DO_NTOHS
(
interval
,
message
+
6
);
debugf
(
"Received hello %d (%d) from %s on %s.
\n
"
,
debugf
(
"Received hello %d (%d) from %s on %s.
\n
"
,
seqno
,
interval
,
seqno
,
interval
,
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
net
->
activity_time
=
now
.
tv_sec
;
ifp
->
activity_time
=
now
.
tv_sec
;
update_hello_interval
(
net
);
update_hello_interval
(
ifp
);
changed
=
update_neighbour
(
neigh
,
seqno
,
interval
);
changed
=
update_neighbour
(
neigh
,
seqno
,
interval
);
update_neighbour_metric
(
neigh
,
changed
);
update_neighbour_metric
(
neigh
,
changed
);
if
(
interval
>
0
)
if
(
interval
>
0
)
...
@@ -289,9 +289,9 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -289,9 +289,9 @@ parse_packet(const unsigned char *from, struct network *net,
if
(
rc
<
0
)
goto
fail
;
if
(
rc
<
0
)
goto
fail
;
debugf
(
"Received ihu %d (%d) from %s on %s for %s.
\n
"
,
debugf
(
"Received ihu %d (%d) from %s on %s for %s.
\n
"
,
txcost
,
interval
,
txcost
,
interval
,
format_address
(
from
),
net
->
if
name
,
format_address
(
from
),
ifp
->
name
,
format_address
(
address
));
format_address
(
address
));
if
(
message
[
2
]
==
0
||
network_ll_address
(
net
,
address
))
{
if
(
message
[
2
]
==
0
||
interface_ll_address
(
ifp
,
address
))
{
int
changed
=
txcost
!=
neigh
->
txcost
;
int
changed
=
txcost
!=
neigh
->
txcost
;
neigh
->
txcost
=
txcost
;
neigh
->
txcost
=
txcost
;
neigh
->
ihu_time
=
now
;
neigh
->
ihu_time
=
now
;
...
@@ -308,7 +308,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -308,7 +308,7 @@ parse_packet(const unsigned char *from, struct network *net,
memcpy
(
router_id
,
message
+
4
,
8
);
memcpy
(
router_id
,
message
+
4
,
8
);
have_router_id
=
1
;
have_router_id
=
1
;
debugf
(
"Received router-id %s from %s on %s.
\n
"
,
debugf
(
"Received router-id %s from %s on %s.
\n
"
,
format_eui64
(
router_id
),
format_address
(
from
),
net
->
if
name
);
format_eui64
(
router_id
),
format_address
(
from
),
ifp
->
name
);
}
else
if
(
type
==
MESSAGE_NH
)
{
}
else
if
(
type
==
MESSAGE_NH
)
{
unsigned
char
nh
[
16
];
unsigned
char
nh
[
16
];
int
rc
;
int
rc
;
...
@@ -326,7 +326,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -326,7 +326,7 @@ parse_packet(const unsigned char *from, struct network *net,
}
}
debugf
(
"Received nh %s (%d) from %s on %s.
\n
"
,
debugf
(
"Received nh %s (%d) from %s on %s.
\n
"
,
format_address
(
nh
),
message
[
2
],
format_address
(
nh
),
message
[
2
],
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
if
(
message
[
2
]
==
1
)
{
if
(
message
[
2
]
==
1
)
{
memcpy
(
v4_nh
,
nh
,
16
);
memcpy
(
v4_nh
,
nh
,
16
);
have_v4_nh
=
1
;
have_v4_nh
=
1
;
...
@@ -391,7 +391,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -391,7 +391,7 @@ parse_packet(const unsigned char *from, struct network *net,
(
message
[
3
]
&
0x80
)
?
"/prefix"
:
""
,
(
message
[
3
]
&
0x80
)
?
"/prefix"
:
""
,
(
message
[
3
]
&
0x40
)
?
"/id"
:
""
,
(
message
[
3
]
&
0x40
)
?
"/id"
:
""
,
format_prefix
(
prefix
,
plen
),
format_prefix
(
prefix
,
plen
),
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
if
(
message
[
2
]
==
0
)
{
if
(
message
[
2
]
==
0
)
{
if
(
metric
<
0xFFFF
)
{
if
(
metric
<
0xFFFF
)
{
...
@@ -412,11 +412,11 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -412,11 +412,11 @@ parse_packet(const unsigned char *from, struct network *net,
}
}
if
(
message
[
2
]
==
1
)
{
if
(
message
[
2
]
==
1
)
{
if
(
!
net
->
ipv4
)
if
(
!
ifp
->
ipv4
)
goto
done
;
goto
done
;
}
}
if
((
net
->
flags
&
NET
_FARAWAY
))
{
if
((
ifp
->
flags
&
IF
_FARAWAY
))
{
channels
[
0
]
=
0
;
channels
[
0
]
=
0
;
}
else
{
}
else
{
/* This will be overwritten by parse_route_attributes below. */
/* This will be overwritten by parse_route_attributes below. */
...
@@ -425,7 +425,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -425,7 +425,7 @@ parse_packet(const unsigned char *from, struct network *net,
channels
[
0
]
=
0
;
channels
[
0
]
=
0
;
}
else
{
}
else
{
/* Assume interfering. */
/* Assume interfering. */
channels
[
0
]
=
NET
_CHANNEL_INTERFERING
;
channels
[
0
]
=
IF
_CHANNEL_INTERFERING
;
channels
[
1
]
=
0
;
channels
[
1
]
=
0
;
}
}
...
@@ -447,14 +447,14 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -447,14 +447,14 @@ parse_packet(const unsigned char *from, struct network *net,
plen
=
message
[
3
]
+
(
message
[
2
]
==
1
?
96
:
0
);
plen
=
message
[
3
]
+
(
message
[
2
]
==
1
?
96
:
0
);
debugf
(
"Received request for %s from %s on %s.
\n
"
,
debugf
(
"Received request for %s from %s on %s.
\n
"
,
message
[
2
]
==
0
?
"any"
:
format_prefix
(
prefix
,
plen
),
message
[
2
]
==
0
?
"any"
:
format_prefix
(
prefix
,
plen
),
format_address
(
from
),
net
->
if
name
);
format_address
(
from
),
ifp
->
name
);
if
(
message
[
2
]
==
0
)
{
if
(
message
[
2
]
==
0
)
{
/* If a neighbour is requesting a full route dump from us,
/* If a neighbour is requesting a full route dump from us,
we might as well send it an IHU. */
we might as well send it an IHU. */
send_ihu
(
neigh
,
NULL
);
send_ihu
(
neigh
,
NULL
);
send_update
(
neigh
->
network
,
0
,
NULL
,
0
);
send_update
(
neigh
->
ifp
,
0
,
NULL
,
0
);
}
else
{
}
else
{
send_update
(
neigh
->
network
,
0
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
0
,
prefix
,
plen
);
}
}
}
else
if
(
type
==
MESSAGE_MH_REQUEST
)
{
}
else
if
(
type
==
MESSAGE_MH_REQUEST
)
{
unsigned
char
prefix
[
16
],
plen
;
unsigned
char
prefix
[
16
],
plen
;
...
@@ -469,13 +469,13 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -469,13 +469,13 @@ parse_packet(const unsigned char *from, struct network *net,
debugf
(
"Received request (%d) for %s from %s on %s (%s, %d).
\n
"
,
debugf
(
"Received request (%d) for %s from %s on %s (%s, %d).
\n
"
,
message
[
6
],
message
[
6
],
format_prefix
(
prefix
,
plen
),
format_prefix
(
prefix
,
plen
),
format_address
(
from
),
net
->
if
name
,
format_address
(
from
),
ifp
->
name
,
format_eui64
(
message
+
8
),
seqno
);
format_eui64
(
message
+
8
),
seqno
);
handle_request
(
neigh
,
prefix
,
plen
,
message
[
6
],
handle_request
(
neigh
,
prefix
,
plen
,
message
[
6
],
seqno
,
message
+
8
);
seqno
,
message
+
8
);
}
else
{
}
else
{
debugf
(
"Received unknown packet type %d from %s on %s.
\n
"
,
debugf
(
"Received unknown packet type %d from %s on %s.
\n
"
,
type
,
format_address
(
from
),
net
->
if
name
);
type
,
format_address
(
from
),
ifp
->
name
);
}
}
done:
done:
i
+=
len
+
2
;
i
+=
len
+
2
;
...
@@ -483,7 +483,7 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -483,7 +483,7 @@ parse_packet(const unsigned char *from, struct network *net,
fail:
fail:
fprintf
(
stderr
,
"Couldn't parse packet (%d, %d) from %s on %s.
\n
"
,
fprintf
(
stderr
,
"Couldn't parse packet (%d, %d) from %s on %s.
\n
"
,
message
[
0
],
message
[
1
],
format_address
(
from
),
net
->
if
name
);
message
[
0
],
message
[
1
],
format_address
(
from
),
ifp
->
name
);
goto
done
;
goto
done
;
}
}
return
;
return
;
...
@@ -494,20 +494,20 @@ parse_packet(const unsigned char *from, struct network *net,
...
@@ -494,20 +494,20 @@ parse_packet(const unsigned char *from, struct network *net,
should never trigger. But I'm superstitious. */
should never trigger. But I'm superstitious. */
static
int
static
int
check_bucket
(
struct
network
*
net
)
check_bucket
(
struct
interface
*
ifp
)
{
{
if
(
net
->
bucket
<=
0
)
{
if
(
ifp
->
bucket
<=
0
)
{
int
seconds
=
now
.
tv_sec
-
net
->
bucket_time
;
int
seconds
=
now
.
tv_sec
-
ifp
->
bucket_time
;
if
(
seconds
>
0
)
{
if
(
seconds
>
0
)
{
net
->
bucket
=
MIN
(
BUCKET_TOKENS_MAX
,
ifp
->
bucket
=
MIN
(
BUCKET_TOKENS_MAX
,
seconds
*
BUCKET_TOKENS_PER_SEC
);
seconds
*
BUCKET_TOKENS_PER_SEC
);
}
}
/* Reset bucket time unconditionally, in case clock is stepped. */
/* Reset bucket time unconditionally, in case clock is stepped. */
net
->
bucket_time
=
now
.
tv_sec
;
ifp
->
bucket_time
=
now
.
tv_sec
;
}
}
if
(
net
->
bucket
>
0
)
{
if
(
ifp
->
bucket
>
0
)
{
net
->
bucket
--
;
ifp
->
bucket
--
;
return
1
;
return
1
;
}
else
{
}
else
{
return
0
;
return
0
;
...
@@ -515,65 +515,65 @@ check_bucket(struct network *net)
...
@@ -515,65 +515,65 @@ check_bucket(struct network *net)
}
}
void
void
flushbuf
(
struct
network
*
net
)
flushbuf
(
struct
interface
*
ifp
)
{
{
int
rc
;
int
rc
;
struct
sockaddr_in6
sin6
;
struct
sockaddr_in6
sin6
;
assert
(
net
->
buffered
<=
net
->
bufsize
);
assert
(
ifp
->
buffered
<=
ifp
->
bufsize
);
flushupdates
(
net
);
flushupdates
(
ifp
);
if
(
net
->
buffered
>
0
)
{
if
(
ifp
->
buffered
>
0
)
{
debugf
(
" (flushing %d buffered bytes on %s)
\n
"
,
debugf
(
" (flushing %d buffered bytes on %s)
\n
"
,
net
->
buffered
,
net
->
if
name
);
ifp
->
buffered
,
ifp
->
name
);
if
(
check_bucket
(
net
))
{
if
(
check_bucket
(
ifp
))
{
memset
(
&
sin6
,
0
,
sizeof
(
sin6
));
memset
(
&
sin6
,
0
,
sizeof
(
sin6
));
sin6
.
sin6_family
=
AF_INET6
;
sin6
.
sin6_family
=
AF_INET6
;
memcpy
(
&
sin6
.
sin6_addr
,
protocol_group
,
16
);
memcpy
(
&
sin6
.
sin6_addr
,
protocol_group
,
16
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_scope_id
=
net
->
ifindex
;
sin6
.
sin6_scope_id
=
ifp
->
ifindex
;
DO_HTONS
(
packet_header
+
2
,
net
->
buffered
);
DO_HTONS
(
packet_header
+
2
,
ifp
->
buffered
);
rc
=
babel_send
(
protocol_socket
,
rc
=
babel_send
(
protocol_socket
,
packet_header
,
sizeof
(
packet_header
),
packet_header
,
sizeof
(
packet_header
),
net
->
sendbuf
,
net
->
buffered
,
ifp
->
sendbuf
,
ifp
->
buffered
,
(
struct
sockaddr
*
)
&
sin6
,
sizeof
(
sin6
));
(
struct
sockaddr
*
)
&
sin6
,
sizeof
(
sin6
));
if
(
rc
<
0
)
if
(
rc
<
0
)
perror
(
"send"
);
perror
(
"send"
);
}
else
{
}
else
{
fprintf
(
stderr
,
"Warning: bucket full, dropping packet to %s.
\n
"
,
fprintf
(
stderr
,
"Warning: bucket full, dropping packet to %s.
\n
"
,
net
->
if
name
);
ifp
->
name
);
}
}
}
}
VALGRIND_MAKE_MEM_UNDEFINED
(
net
->
sendbuf
,
net
->
bufsize
);
VALGRIND_MAKE_MEM_UNDEFINED
(
ifp
->
sendbuf
,
ifp
->
bufsize
);
net
->
buffered
=
0
;
ifp
->
buffered
=
0
;
net
->
have_buffered_hello
=
0
;
ifp
->
have_buffered_hello
=
0
;
net
->
have_buffered_id
=
0
;
ifp
->
have_buffered_id
=
0
;
net
->
have_buffered_nh
=
0
;
ifp
->
have_buffered_nh
=
0
;
net
->
have_buffered_prefix
=
0
;
ifp
->
have_buffered_prefix
=
0
;
net
->
flush_timeout
.
tv_sec
=
0
;
ifp
->
flush_timeout
.
tv_sec
=
0
;
net
->
flush_timeout
.
tv_usec
=
0
;
ifp
->
flush_timeout
.
tv_usec
=
0
;
}
}
static
void
static
void
schedule_flush
(
struct
network
*
net
)
schedule_flush
(
struct
interface
*
ifp
)
{
{
unsigned
msecs
=
jitter
(
net
,
0
);
unsigned
msecs
=
jitter
(
ifp
,
0
);
if
(
net
->
flush_timeout
.
tv_sec
!=
0
&&
if
(
ifp
->
flush_timeout
.
tv_sec
!=
0
&&
timeval_minus_msec
(
&
net
->
flush_timeout
,
&
now
)
<
msecs
)
timeval_minus_msec
(
&
ifp
->
flush_timeout
,
&
now
)
<
msecs
)
return
;
return
;
set_timeout
(
&
net
->
flush_timeout
,
msecs
);
set_timeout
(
&
ifp
->
flush_timeout
,
msecs
);
}
}
static
void
static
void
schedule_flush_now
(
struct
network
*
net
)
schedule_flush_now
(
struct
interface
*
ifp
)
{
{
/* Almost now */
/* Almost now */
unsigned
msecs
=
roughly
(
10
);
unsigned
msecs
=
roughly
(
10
);
if
(
net
->
flush_timeout
.
tv_sec
!=
0
&&
if
(
ifp
->
flush_timeout
.
tv_sec
!=
0
&&
timeval_minus_msec
(
&
net
->
flush_timeout
,
&
now
)
<
msecs
)
timeval_minus_msec
(
&
ifp
->
flush_timeout
,
&
now
)
<
msecs
)
return
;
return
;
set_timeout
(
&
net
->
flush_timeout
,
msecs
);
set_timeout
(
&
ifp
->
flush_timeout
,
msecs
);
}
}
static
void
static
void
...
@@ -590,49 +590,49 @@ schedule_unicast_flush(unsigned msecs)
...
@@ -590,49 +590,49 @@ schedule_unicast_flush(unsigned msecs)
}
}
static
void
static
void
ensure_space
(
struct
network
*
net
,
int
space
)
ensure_space
(
struct
interface
*
ifp
,
int
space
)
{
{
if
(
net
->
bufsize
-
net
->
buffered
<
space
)
if
(
ifp
->
bufsize
-
ifp
->
buffered
<
space
)
flushbuf
(
net
);
flushbuf
(
ifp
);
}
}
static
void
static
void
start_message
(
struct
network
*
net
,
int
type
,
int
len
)
start_message
(
struct
interface
*
ifp
,
int
type
,
int
len
)
{
{
if
(
net
->
bufsize
-
net
->
buffered
<
len
+
2
)
if
(
ifp
->
bufsize
-
ifp
->
buffered
<
len
+
2
)
flushbuf
(
net
);
flushbuf
(
ifp
);
net
->
sendbuf
[
net
->
buffered
++
]
=
type
;
ifp
->
sendbuf
[
ifp
->
buffered
++
]
=
type
;
net
->
sendbuf
[
net
->
buffered
++
]
=
len
;
ifp
->
sendbuf
[
ifp
->
buffered
++
]
=
len
;
}
}
static
void
static
void
end_message
(
struct
network
*
net
,
int
type
,
int
bytes
)
end_message
(
struct
interface
*
ifp
,
int
type
,
int
bytes
)
{
{
assert
(
net
->
buffered
>=
bytes
+
2
&&
assert
(
ifp
->
buffered
>=
bytes
+
2
&&
net
->
sendbuf
[
net
->
buffered
-
bytes
-
2
]
==
type
&&
ifp
->
sendbuf
[
ifp
->
buffered
-
bytes
-
2
]
==
type
&&
net
->
sendbuf
[
net
->
buffered
-
bytes
-
1
]
==
bytes
);
ifp
->
sendbuf
[
ifp
->
buffered
-
bytes
-
1
]
==
bytes
);
schedule_flush
(
net
);
schedule_flush
(
ifp
);
}
}
static
void
static
void
accumulate_byte
(
struct
network
*
net
,
unsigned
char
value
)
accumulate_byte
(
struct
interface
*
ifp
,
unsigned
char
value
)
{
{
net
->
sendbuf
[
net
->
buffered
++
]
=
value
;
ifp
->
sendbuf
[
ifp
->
buffered
++
]
=
value
;
}
}
static
void
static
void
accumulate_short
(
struct
network
*
net
,
unsigned
short
value
)
accumulate_short
(
struct
interface
*
ifp
,
unsigned
short
value
)
{
{
DO_HTONS
(
net
->
sendbuf
+
net
->
buffered
,
value
);
DO_HTONS
(
ifp
->
sendbuf
+
ifp
->
buffered
,
value
);
net
->
buffered
+=
2
;
ifp
->
buffered
+=
2
;
}
}
static
void
static
void
accumulate_bytes
(
struct
network
*
net
,
accumulate_bytes
(
struct
interface
*
ifp
,
const
unsigned
char
*
value
,
unsigned
len
)
const
unsigned
char
*
value
,
unsigned
len
)
{
{
memcpy
(
net
->
sendbuf
+
net
->
buffered
,
value
,
len
);
memcpy
(
ifp
->
sendbuf
+
ifp
->
buffered
,
value
,
len
);
net
->
buffered
+=
len
;
ifp
->
buffered
+=
len
;
}
}
static
int
static
int
...
@@ -641,7 +641,7 @@ start_unicast_message(struct neighbour *neigh, int type, int len)
...
@@ -641,7 +641,7 @@ start_unicast_message(struct neighbour *neigh, int type, int len)
if
(
unicast_neighbour
)
{
if
(
unicast_neighbour
)
{
if
(
neigh
!=
unicast_neighbour
||
if
(
neigh
!=
unicast_neighbour
||
unicast_buffered
+
len
+
2
>=
unicast_buffered
+
len
+
2
>=
MIN
(
UNICAST_BUFSIZE
,
neigh
->
network
->
bufsize
))
MIN
(
UNICAST_BUFSIZE
,
neigh
->
ifp
->
bufsize
))
flush_unicast
(
0
);
flush_unicast
(
0
);
}
}
if
(
!
unicast_buffer
)
if
(
!
unicast_buffer
)
...
@@ -664,7 +664,7 @@ end_unicast_message(struct neighbour *neigh, int type, int bytes)
...
@@ -664,7 +664,7 @@ end_unicast_message(struct neighbour *neigh, int type, int bytes)
assert
(
unicast_neighbour
==
neigh
&&
unicast_buffered
>=
bytes
+
2
&&
assert
(
unicast_neighbour
==
neigh
&&
unicast_buffered
>=
bytes
+
2
&&
unicast_buffer
[
unicast_buffered
-
bytes
-
2
]
==
type
&&
unicast_buffer
[
unicast_buffered
-
bytes
-
2
]
==
type
&&
unicast_buffer
[
unicast_buffered
-
bytes
-
1
]
==
bytes
);
unicast_buffer
[
unicast_buffered
-
bytes
-
1
]
==
bytes
);
schedule_unicast_flush
(
jitter
(
neigh
->
network
,
0
));
schedule_unicast_flush
(
jitter
(
neigh
->
ifp
,
0
));
}
}
static
void
static
void
...
@@ -693,7 +693,7 @@ send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
...
@@ -693,7 +693,7 @@ send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
{
{
int
rc
;
int
rc
;
debugf
(
"Sending ack (%04x) to %s on %s.
\n
"
,
debugf
(
"Sending ack (%04x) to %s on %s.
\n
"
,
nonce
,
format_address
(
neigh
->
address
),
neigh
->
network
->
if
name
);
nonce
,
format_address
(
neigh
->
address
),
neigh
->
ifp
->
name
);
rc
=
start_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
if
(
rc
<
0
)
return
;
rc
=
start_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
if
(
rc
<
0
)
return
;
accumulate_unicast_short
(
neigh
,
nonce
);
accumulate_unicast_short
(
neigh
,
nonce
);
end_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
end_unicast_message
(
neigh
,
MESSAGE_ACK
,
2
);
...
@@ -702,41 +702,41 @@ send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
...
@@ -702,41 +702,41 @@ send_ack(struct neighbour *neigh, unsigned short nonce, unsigned short interval)
}
}
void
void
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
)
send_hello_noupdate
(
struct
interface
*
ifp
,
unsigned
interval
)
{
{
/* This avoids sending multiple hellos in a single packet, which breaks
/* This avoids sending multiple hellos in a single packet, which breaks
link quality estimation. */
link quality estimation. */
if
(
net
->
have_buffered_hello
)
if
(
ifp
->
have_buffered_hello
)
flushbuf
(
net
);
flushbuf
(
ifp
);
net
->
hello_seqno
=
seqno_plus
(
net
->
hello_seqno
,
1
);
ifp
->
hello_seqno
=
seqno_plus
(
ifp
->
hello_seqno
,
1
);
set_timeout
(
&
net
->
hello_timeout
,
net
->
hello_interval
);
set_timeout
(
&
ifp
->
hello_timeout
,
ifp
->
hello_interval
);
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
debugf
(
"Sending hello %d (%d) to %s.
\n
"
,
debugf
(
"Sending hello %d (%d) to %s.
\n
"
,
net
->
hello_seqno
,
interval
,
net
->
if
name
);
ifp
->
hello_seqno
,
interval
,
ifp
->
name
);
start_message
(
net
,
MESSAGE_HELLO
,
6
);
start_message
(
ifp
,
MESSAGE_HELLO
,
6
);
accumulate_short
(
net
,
0
);
accumulate_short
(
ifp
,
0
);
accumulate_short
(
net
,
net
->
hello_seqno
);
accumulate_short
(
ifp
,
ifp
->
hello_seqno
);
accumulate_short
(
net
,
interval
>
0xFFFF
?
0xFFFF
:
interval
);
accumulate_short
(
ifp
,
interval
>
0xFFFF
?
0xFFFF
:
interval
);
end_message
(
net
,
MESSAGE_HELLO
,
6
);
end_message
(
ifp
,
MESSAGE_HELLO
,
6
);
net
->
have_buffered_hello
=
1
;
ifp
->
have_buffered_hello
=
1
;
}
}
void
void
send_hello
(
struct
network
*
net
)
send_hello
(
struct
interface
*
ifp
)
{
{
int
changed
;
int
changed
;
changed
=
update_hello_interval
(
net
);
changed
=
update_hello_interval
(
ifp
);
send_hello_noupdate
(
net
,
(
net
->
hello_interval
+
9
)
/
10
);
send_hello_noupdate
(
ifp
,
(
ifp
->
hello_interval
+
9
)
/
10
);
/* Send full IHU every 3 hellos, and marginal IHU each time */
/* Send full IHU every 3 hellos, and marginal IHU each time */
if
(
changed
||
net
->
hello_seqno
%
3
==
0
)
if
(
changed
||
ifp
->
hello_seqno
%
3
==
0
)
send_ihu
(
NULL
,
net
);
send_ihu
(
NULL
,
ifp
);
else
else
send_marginal_ihu
(
net
);
send_marginal_ihu
(
ifp
);
}
}
void
void
...
@@ -748,18 +748,18 @@ flush_unicast(int dofree)
...
@@ -748,18 +748,18 @@ flush_unicast(int dofree)
if
(
unicast_buffered
==
0
)
if
(
unicast_buffered
==
0
)
goto
done
;
goto
done
;
if
(
!
net_up
(
unicast_neighbour
->
network
))
if
(
!
if_up
(
unicast_neighbour
->
ifp
))
goto
done
;
goto
done
;
/* Preserve ordering of messages */
/* Preserve ordering of messages */
flushbuf
(
unicast_neighbour
->
network
);
flushbuf
(
unicast_neighbour
->
ifp
);
if
(
check_bucket
(
unicast_neighbour
->
network
))
{
if
(
check_bucket
(
unicast_neighbour
->
ifp
))
{
memset
(
&
sin6
,
0
,
sizeof
(
sin6
));
memset
(
&
sin6
,
0
,
sizeof
(
sin6
));
sin6
.
sin6_family
=
AF_INET6
;
sin6
.
sin6_family
=
AF_INET6
;
memcpy
(
&
sin6
.
sin6_addr
,
unicast_neighbour
->
address
,
16
);
memcpy
(
&
sin6
.
sin6_addr
,
unicast_neighbour
->
address
,
16
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_port
=
htons
(
protocol_port
);
sin6
.
sin6_scope_id
=
unicast_neighbour
->
network
->
ifindex
;
sin6
.
sin6_scope_id
=
unicast_neighbour
->
ifp
->
ifindex
;
DO_HTONS
(
packet_header
+
2
,
unicast_buffered
);
DO_HTONS
(
packet_header
+
2
,
unicast_buffered
);
rc
=
babel_send
(
protocol_socket
,
rc
=
babel_send
(
protocol_socket
,
packet_header
,
sizeof
(
packet_header
),
packet_header
,
sizeof
(
packet_header
),
...
@@ -772,7 +772,7 @@ flush_unicast(int dofree)
...
@@ -772,7 +772,7 @@ flush_unicast(int dofree)
"Warning: bucket full, dropping unicast packet"
"Warning: bucket full, dropping unicast packet"
"to %s if %s.
\n
"
,
"to %s if %s.
\n
"
,
format_address
(
unicast_neighbour
->
address
),
format_address
(
unicast_neighbour
->
address
),
unicast_neighbour
->
network
->
if
name
);
unicast_neighbour
->
ifp
->
name
);
}
}
done:
done:
...
@@ -788,7 +788,7 @@ flush_unicast(int dofree)
...
@@ -788,7 +788,7 @@ flush_unicast(int dofree)
}
}
static
void
static
void
really_send_update
(
struct
network
*
net
,
really_send_update
(
struct
interface
*
ifp
,
const
unsigned
char
*
id
,
const
unsigned
char
*
id
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
unsigned
short
metric
,
unsigned
short
seqno
,
unsigned
short
metric
,
...
@@ -804,82 +804,82 @@ really_send_update(struct network *net,
...
@@ -804,82 +804,82 @@ really_send_update(struct network *net,
channels_size
=
channels_len
>=
0
?
channels_len
+
2
:
0
;
channels_size
=
channels_len
>=
0
?
channels_len
+
2
:
0
;
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
net
->
ifindex
);
add_metric
=
output_filter
(
id
,
prefix
,
plen
,
ifp
->
ifindex
);
if
(
add_metric
>=
INFINITY
)
if
(
add_metric
>=
INFINITY
)
return
;
return
;
metric
=
MIN
(
metric
+
add_metric
,
INFINITY
);
metric
=
MIN
(
metric
+
add_metric
,
INFINITY
);
/* Worst case */
/* Worst case */
ensure_space
(
net
,
20
+
12
+
28
);
ensure_space
(
ifp
,
20
+
12
+
28
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
if
(
v4
)
{
if
(
v4
)
{
if
(
!
net
->
ipv4
)
if
(
!
ifp
->
ipv4
)
return
;
return
;
if
(
!
net
->
have_buffered_nh
||
if
(
!
ifp
->
have_buffered_nh
||
memcmp
(
net
->
buffered_nh
,
net
->
ipv4
,
4
)
!=
0
)
{
memcmp
(
ifp
->
buffered_nh
,
ifp
->
ipv4
,
4
)
!=
0
)
{
start_message
(
net
,
MESSAGE_NH
,
6
);
start_message
(
ifp
,
MESSAGE_NH
,
6
);
accumulate_byte
(
net
,
1
);
accumulate_byte
(
ifp
,
1
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_bytes
(
net
,
net
->
ipv4
,
4
);
accumulate_bytes
(
ifp
,
ifp
->
ipv4
,
4
);
end_message
(
net
,
MESSAGE_NH
,
6
);
end_message
(
ifp
,
MESSAGE_NH
,
6
);
memcpy
(
net
->
buffered_nh
,
net
->
ipv4
,
4
);
memcpy
(
ifp
->
buffered_nh
,
ifp
->
ipv4
,
4
);
net
->
have_buffered_nh
=
1
;
ifp
->
have_buffered_nh
=
1
;
}
}
real_prefix
=
prefix
+
12
;
real_prefix
=
prefix
+
12
;
real_plen
=
plen
-
96
;
real_plen
=
plen
-
96
;
}
else
{
}
else
{
if
(
net
->
have_buffered_prefix
)
{
if
(
ifp
->
have_buffered_prefix
)
{
while
(
omit
<
plen
/
8
&&
while
(
omit
<
plen
/
8
&&
net
->
buffered_prefix
[
omit
]
==
prefix
[
omit
])
ifp
->
buffered_prefix
[
omit
]
==
prefix
[
omit
])
omit
++
;
omit
++
;
}
}
if
(
!
net
->
have_buffered_prefix
||
plen
>=
48
)
if
(
!
ifp
->
have_buffered_prefix
||
plen
>=
48
)
flags
|=
0x80
;
flags
|=
0x80
;
real_prefix
=
prefix
;
real_prefix
=
prefix
;
real_plen
=
plen
;
real_plen
=
plen
;
}
}
if
(
!
net
->
have_buffered_id
||
memcmp
(
id
,
net
->
buffered_id
,
8
)
!=
0
)
{
if
(
!
ifp
->
have_buffered_id
||
memcmp
(
id
,
ifp
->
buffered_id
,
8
)
!=
0
)
{
if
(
real_plen
==
128
&&
memcmp
(
real_prefix
+
8
,
id
,
8
)
==
0
)
{
if
(
real_plen
==
128
&&
memcmp
(
real_prefix
+
8
,
id
,
8
)
==
0
)
{
flags
|=
0x40
;
flags
|=
0x40
;
}
else
{
}
else
{
start_message
(
net
,
MESSAGE_ROUTER_ID
,
10
);
start_message
(
ifp
,
MESSAGE_ROUTER_ID
,
10
);
accumulate_short
(
net
,
0
);
accumulate_short
(
ifp
,
0
);
accumulate_bytes
(
net
,
id
,
8
);
accumulate_bytes
(
ifp
,
id
,
8
);
end_message
(
net
,
MESSAGE_ROUTER_ID
,
10
);
end_message
(
ifp
,
MESSAGE_ROUTER_ID
,
10
);
}
}
memcpy
(
net
->
buffered_id
,
id
,
16
);
memcpy
(
ifp
->
buffered_id
,
id
,
16
);
net
->
have_buffered_id
=
1
;
ifp
->
have_buffered_id
=
1
;
}
}
start_message
(
net
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
+
start_message
(
ifp
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
+
channels_size
);
channels_size
);
accumulate_byte
(
net
,
v4
?
1
:
2
);
accumulate_byte
(
ifp
,
v4
?
1
:
2
);
accumulate_byte
(
net
,
flags
);
accumulate_byte
(
ifp
,
flags
);
accumulate_byte
(
net
,
real_plen
);
accumulate_byte
(
ifp
,
real_plen
);
accumulate_byte
(
net
,
omit
);
accumulate_byte
(
ifp
,
omit
);
accumulate_short
(
net
,
(
net
->
update_interval
+
5
)
/
10
);
accumulate_short
(
ifp
,
(
ifp
->
update_interval
+
5
)
/
10
);
accumulate_short
(
net
,
seqno
);
accumulate_short
(
ifp
,
seqno
);
accumulate_short
(
net
,
metric
);
accumulate_short
(
ifp
,
metric
);
accumulate_bytes
(
net
,
real_prefix
+
omit
,
(
real_plen
+
7
)
/
8
-
omit
);
accumulate_bytes
(
ifp
,
real_prefix
+
omit
,
(
real_plen
+
7
)
/
8
-
omit
);
/* Note that an empty channels TLV is different from no such TLV. */
/* Note that an empty channels TLV is different from no such TLV. */
if
(
channels_len
>=
0
)
{
if
(
channels_len
>=
0
)
{
accumulate_byte
(
net
,
2
);
accumulate_byte
(
ifp
,
2
);
accumulate_byte
(
net
,
channels_len
);
accumulate_byte
(
ifp
,
channels_len
);
accumulate_bytes
(
net
,
channels
,
channels_len
);
accumulate_bytes
(
ifp
,
channels
,
channels_len
);
}
}
end_message
(
net
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
+
end_message
(
ifp
,
MESSAGE_UPDATE
,
10
+
(
real_plen
+
7
)
/
8
-
omit
+
channels_size
);
channels_size
);
if
(
flags
&
0x80
)
{
if
(
flags
&
0x80
)
{
memcpy
(
net
->
buffered_prefix
,
prefix
,
16
);
memcpy
(
ifp
->
buffered_prefix
,
prefix
,
16
);
net
->
have_buffered_prefix
=
1
;
ifp
->
have_buffered_prefix
=
1
;
}
}
}
}
...
@@ -918,7 +918,7 @@ compare_buffered_updates(const void *av, const void *bv)
...
@@ -918,7 +918,7 @@ compare_buffered_updates(const void *av, const void *bv)
}
}
void
void
flushupdates
(
struct
network
*
net
)
flushupdates
(
struct
interface
*
ifp
)
{
{
struct
xroute
*
xroute
;
struct
xroute
*
xroute
;
struct
route
*
route
;
struct
route
*
route
;
...
@@ -926,26 +926,26 @@ flushupdates(struct network *net)
...
@@ -926,26 +926,26 @@ flushupdates(struct network *net)
unsigned
char
last_plen
=
0xFF
;
unsigned
char
last_plen
=
0xFF
;
int
i
;
int
i
;
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
FOR_ALL_
NETS
(
n
)
FOR_ALL_
INTERFACES
(
ifp_aux
)
flushupdates
(
n
);
flushupdates
(
ifp_aux
);
return
;
return
;
}
}
if
(
net
->
num_buffered_updates
>
0
)
{
if
(
ifp
->
num_buffered_updates
>
0
)
{
struct
buffered_update
*
b
=
net
->
buffered_updates
;
struct
buffered_update
*
b
=
ifp
->
buffered_updates
;
int
n
=
net
->
num_buffered_updates
;
int
n
=
ifp
->
num_buffered_updates
;
net
->
buffered_updates
=
NULL
;
ifp
->
buffered_updates
=
NULL
;
net
->
update_bufsize
=
0
;
ifp
->
update_bufsize
=
0
;
net
->
num_buffered_updates
=
0
;
ifp
->
num_buffered_updates
=
0
;
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
goto
done
;
goto
done
;
debugf
(
" (flushing %d buffered updates on %s (%d))
\n
"
,
debugf
(
" (flushing %d buffered updates on %s (%d))
\n
"
,
n
,
net
->
ifname
,
net
->
ifindex
);
n
,
ifp
->
name
,
ifp
->
ifindex
);
/* In order to send fewer update messages, we want to send updates
/* In order to send fewer update messages, we want to send updates
with the same router-id together, with IPv6 going out before IPv4. */
with the same router-id together, with IPv6 going out before IPv4. */
...
@@ -975,7 +975,7 @@ flushupdates(struct network *net)
...
@@ -975,7 +975,7 @@ flushupdates(struct network *net)
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
);
route
=
find_installed_route
(
b
[
i
].
prefix
,
b
[
i
].
plen
);
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
if
(
xroute
&&
(
!
route
||
xroute
->
metric
<=
kernel_metric
))
{
really_send_update
(
net
,
myid
,
really_send_update
(
ifp
,
myid
,
xroute
->
prefix
,
xroute
->
plen
,
xroute
->
prefix
,
xroute
->
plen
,
myseqno
,
xroute
->
metric
,
myseqno
,
xroute
->
metric
,
NULL
,
0
);
NULL
,
0
);
...
@@ -984,39 +984,39 @@ flushupdates(struct network *net)
...
@@ -984,39 +984,39 @@ flushupdates(struct network *net)
}
else
if
(
route
)
{
}
else
if
(
route
)
{
unsigned
char
channels
[
DIVERSITY_HOPS
];
unsigned
char
channels
[
DIVERSITY_HOPS
];
int
chlen
;
int
chlen
;
struct
network
*
route_net
=
route
->
neigh
->
network
;
struct
interface
*
route_ifp
=
route
->
neigh
->
ifp
;
unsigned
short
metric
;
unsigned
short
metric
;
unsigned
short
seqno
;
unsigned
short
seqno
;
seqno
=
route
->
seqno
;
seqno
=
route
->
seqno
;
metric
=
metric
=
route_interferes
(
route
,
net
)
?
route_interferes
(
route
,
ifp
)
?
route_metric
(
route
)
:
route_metric
(
route
)
:
route_metric_noninterfering
(
route
);
route_metric_noninterfering
(
route
);
if
(
metric
<
INFINITY
)
if
(
metric
<
INFINITY
)
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
satisfy_request
(
route
->
src
->
prefix
,
route
->
src
->
plen
,
seqno
,
route
->
src
->
id
,
net
);
seqno
,
route
->
src
->
id
,
ifp
);
if
((
net
->
flags
&
NET
_SPLIT_HORIZON
)
&&
if
((
ifp
->
flags
&
IF
_SPLIT_HORIZON
)
&&
route
->
neigh
->
network
==
net
)
route
->
neigh
->
ifp
==
ifp
)
continue
;
continue
;
if
(
route_
net
->
channel
==
NET
_CHANNEL_NONINTERFERING
)
{
if
(
route_
ifp
->
channel
==
IF
_CHANNEL_NONINTERFERING
)
{
memcpy
(
channels
,
route
->
channels
,
DIVERSITY_HOPS
);
memcpy
(
channels
,
route
->
channels
,
DIVERSITY_HOPS
);
}
else
{
}
else
{
if
(
route_
net
->
channel
==
NET
_CHANNEL_UNKNOWN
)
if
(
route_
ifp
->
channel
==
IF
_CHANNEL_UNKNOWN
)
channels
[
0
]
=
NET
_CHANNEL_INTERFERING
;
channels
[
0
]
=
IF
_CHANNEL_INTERFERING
;
else
{
else
{
assert
(
route_
net
->
channel
>
0
&&
assert
(
route_
ifp
->
channel
>
0
&&
route_
net
->
channel
<=
254
);
route_
ifp
->
channel
<=
254
);
channels
[
0
]
=
route_
net
->
channel
;
channels
[
0
]
=
route_
ifp
->
channel
;
}
}
memcpy
(
channels
+
1
,
route
->
channels
,
DIVERSITY_HOPS
-
1
);
memcpy
(
channels
+
1
,
route
->
channels
,
DIVERSITY_HOPS
-
1
);
}
}
chlen
=
channels_len
(
channels
);
chlen
=
channels_len
(
channels
);
really_send_update
(
net
,
route
->
src
->
id
,
really_send_update
(
ifp
,
route
->
src
->
id
,
route
->
src
->
prefix
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
src
->
plen
,
seqno
,
metric
,
seqno
,
metric
,
...
@@ -1027,44 +1027,44 @@ flushupdates(struct network *net)
...
@@ -1027,44 +1027,44 @@ flushupdates(struct network *net)
}
else
{
}
else
{
/* There's no route for this prefix. This can happen shortly
/* There's no route for this prefix. This can happen shortly
after an xroute has been retracted, so send a retraction. */
after an xroute has been retracted, so send a retraction. */
really_send_update
(
net
,
myid
,
b
[
i
].
prefix
,
b
[
i
].
plen
,
really_send_update
(
ifp
,
myid
,
b
[
i
].
prefix
,
b
[
i
].
plen
,
myseqno
,
INFINITY
,
NULL
,
-
1
);
myseqno
,
INFINITY
,
NULL
,
-
1
);
}
}
}
}
schedule_flush_now
(
net
);
schedule_flush_now
(
ifp
);
done:
done:
free
(
b
);
free
(
b
);
}
}
net
->
update_flush_timeout
.
tv_sec
=
0
;
ifp
->
update_flush_timeout
.
tv_sec
=
0
;
net
->
update_flush_timeout
.
tv_usec
=
0
;
ifp
->
update_flush_timeout
.
tv_usec
=
0
;
}
}
static
void
static
void
schedule_update_flush
(
struct
network
*
net
,
int
urgent
)
schedule_update_flush
(
struct
interface
*
ifp
,
int
urgent
)
{
{
unsigned
msecs
;
unsigned
msecs
;
msecs
=
update_jitter
(
net
,
urgent
);
msecs
=
update_jitter
(
ifp
,
urgent
);
if
(
net
->
update_flush_timeout
.
tv_sec
!=
0
&&
if
(
ifp
->
update_flush_timeout
.
tv_sec
!=
0
&&
timeval_minus_msec
(
&
net
->
update_flush_timeout
,
&
now
)
<
msecs
)
timeval_minus_msec
(
&
ifp
->
update_flush_timeout
,
&
now
)
<
msecs
)
return
;
return
;
set_timeout
(
&
net
->
update_flush_timeout
,
msecs
);
set_timeout
(
&
ifp
->
update_flush_timeout
,
msecs
);
}
}
static
void
static
void
buffer_update
(
struct
network
*
net
,
buffer_update
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
{
if
(
net
->
num_buffered_updates
>
0
&&
if
(
ifp
->
num_buffered_updates
>
0
&&
net
->
num_buffered_updates
>=
net
->
update_bufsize
)
ifp
->
num_buffered_updates
>=
ifp
->
update_bufsize
)
flushupdates
(
net
);
flushupdates
(
ifp
);
if
(
net
->
update_bufsize
==
0
)
{
if
(
ifp
->
update_bufsize
==
0
)
{
int
n
;
int
n
;
assert
(
net
->
buffered_updates
==
NULL
);
assert
(
ifp
->
buffered_updates
==
NULL
);
n
=
MAX
(
net
->
bufsize
/
16
,
4
);
n
=
MAX
(
ifp
->
bufsize
/
16
,
4
);
again:
again:
net
->
buffered_updates
=
malloc
(
n
*
sizeof
(
struct
buffered_update
));
ifp
->
buffered_updates
=
malloc
(
n
*
sizeof
(
struct
buffered_update
));
if
(
net
->
buffered_updates
==
NULL
)
{
if
(
ifp
->
buffered_updates
==
NULL
)
{
perror
(
"malloc(buffered_updates)"
);
perror
(
"malloc(buffered_updates)"
);
if
(
n
>
4
)
{
if
(
n
>
4
)
{
n
=
4
;
n
=
4
;
...
@@ -1072,27 +1072,27 @@ buffer_update(struct network *net,
...
@@ -1072,27 +1072,27 @@ buffer_update(struct network *net,
}
}
return
;
return
;
}
}
net
->
update_bufsize
=
n
;
ifp
->
update_bufsize
=
n
;
net
->
num_buffered_updates
=
0
;
ifp
->
num_buffered_updates
=
0
;
}
}
memcpy
(
net
->
buffered_updates
[
net
->
num_buffered_updates
].
prefix
,
memcpy
(
ifp
->
buffered_updates
[
ifp
->
num_buffered_updates
].
prefix
,
prefix
,
16
);
prefix
,
16
);
net
->
buffered_updates
[
net
->
num_buffered_updates
].
plen
=
plen
;
ifp
->
buffered_updates
[
ifp
->
num_buffered_updates
].
plen
=
plen
;
net
->
num_buffered_updates
++
;
ifp
->
num_buffered_updates
++
;
}
}
void
void
send_update
(
struct
network
*
net
,
int
urgent
,
send_update
(
struct
interface
*
ifp
,
int
urgent
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
{
int
i
;
int
i
;
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
struct
route
*
route
;
struct
route
*
route
;
FOR_ALL_
NETS
(
n
)
FOR_ALL_
INTERFACES
(
ifp_aux
)
send_update
(
n
,
urgent
,
prefix
,
plen
);
send_update
(
ifp_aux
,
urgent
,
prefix
,
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. */
...
@@ -1104,41 +1104,41 @@ send_update(struct network *net, int urgent,
...
@@ -1104,41 +1104,41 @@ send_update(struct network *net, int urgent,
return
;
return
;
}
}
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
if
(
prefix
)
{
if
(
prefix
)
{
if
(
!
parasitic
||
find_xroute
(
prefix
,
plen
))
{
if
(
!
parasitic
||
find_xroute
(
prefix
,
plen
))
{
debugf
(
"Sending update to %s for %s.
\n
"
,
debugf
(
"Sending update to %s for %s.
\n
"
,
net
->
if
name
,
format_prefix
(
prefix
,
plen
));
ifp
->
name
,
format_prefix
(
prefix
,
plen
));
buffer_update
(
net
,
prefix
,
plen
);
buffer_update
(
ifp
,
prefix
,
plen
);
}
}
}
else
{
}
else
{
if
(
!
network_idle
(
net
))
{
if
(
!
interface_idle
(
ifp
))
{
send_self_update
(
net
);
send_self_update
(
ifp
);
if
(
!
parasitic
)
{
if
(
!
parasitic
)
{
debugf
(
"Sending update to %s for any.
\n
"
,
net
->
if
name
);
debugf
(
"Sending update to %s for any.
\n
"
,
ifp
->
name
);
for
(
i
=
0
;
i
<
numroutes
;
i
++
)
for
(
i
=
0
;
i
<
numroutes
;
i
++
)
if
(
routes
[
i
].
installed
)
if
(
routes
[
i
].
installed
)
buffer_update
(
net
,
buffer_update
(
ifp
,
routes
[
i
].
src
->
prefix
,
routes
[
i
].
src
->
prefix
,
routes
[
i
].
src
->
plen
);
routes
[
i
].
src
->
plen
);
}
}
}
}
set_timeout
(
&
net
->
update_timeout
,
net
->
update_interval
);
set_timeout
(
&
ifp
->
update_timeout
,
ifp
->
update_interval
);
}
}
schedule_update_flush
(
net
,
urgent
);
schedule_update_flush
(
ifp
,
urgent
);
}
}
void
void
send_update_resend
(
struct
network
*
net
,
send_update_resend
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
{
int
delay
;
int
delay
;
assert
(
prefix
!=
NULL
);
assert
(
prefix
!=
NULL
);
send_update
(
net
,
1
,
prefix
,
plen
);
send_update
(
ifp
,
1
,
prefix
,
plen
);
delay
=
2000
;
delay
=
2000
;
delay
=
MIN
(
delay
,
wireless_hello_interval
/
2
);
delay
=
MIN
(
delay
,
wireless_hello_interval
/
2
);
...
@@ -1148,29 +1148,29 @@ send_update_resend(struct network *net,
...
@@ -1148,29 +1148,29 @@ send_update_resend(struct network *net,
}
}
void
void
send_wildcard_retraction
(
struct
network
*
net
)
send_wildcard_retraction
(
struct
interface
*
ifp
)
{
{
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
FOR_ALL_
NETS
(
n
)
FOR_ALL_
INTERFACES
(
ifp_aux
)
send_wildcard_retraction
(
n
);
send_wildcard_retraction
(
ifp_aux
);
return
;
return
;
}
}
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
start_message
(
net
,
MESSAGE_UPDATE
,
10
);
start_message
(
ifp
,
MESSAGE_UPDATE
,
10
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_byte
(
net
,
0x40
);
accumulate_byte
(
ifp
,
0x40
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_short
(
net
,
0xFFFF
);
accumulate_short
(
ifp
,
0xFFFF
);
accumulate_short
(
net
,
myseqno
);
accumulate_short
(
ifp
,
myseqno
);
accumulate_short
(
net
,
0xFFFF
);
accumulate_short
(
ifp
,
0xFFFF
);
end_message
(
net
,
MESSAGE_UPDATE
,
10
);
end_message
(
ifp
,
MESSAGE_UPDATE
,
10
);
net
->
have_buffered_id
=
0
;
ifp
->
have_buffered_id
=
0
;
}
}
void
void
...
@@ -1181,39 +1181,39 @@ update_myseqno()
...
@@ -1181,39 +1181,39 @@ update_myseqno()
}
}
void
void
send_self_update
(
struct
network
*
net
)
send_self_update
(
struct
interface
*
ifp
)
{
{
int
i
;
int
i
;
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
FOR_ALL_
NETS
(
n
)
{
FOR_ALL_
INTERFACES
(
ifp_aux
)
{
if
(
!
net_up
(
n
))
if
(
!
if_up
(
ifp_aux
))
continue
;
continue
;
send_self_update
(
n
);
send_self_update
(
ifp_aux
);
}
}
return
;
return
;
}
}
if
(
!
network_idle
(
net
))
{
if
(
!
interface_idle
(
ifp
))
{
debugf
(
"Sending self update to %s.
\n
"
,
net
->
if
name
);
debugf
(
"Sending self update to %s.
\n
"
,
ifp
->
name
);
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
for
(
i
=
0
;
i
<
numxroutes
;
i
++
)
send_update
(
net
,
0
,
xroutes
[
i
].
prefix
,
xroutes
[
i
].
plen
);
send_update
(
ifp
,
0
,
xroutes
[
i
].
prefix
,
xroutes
[
i
].
plen
);
}
}
}
}
void
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
)
send_ihu
(
struct
neighbour
*
neigh
,
struct
interface
*
ifp
)
{
{
int
rxcost
,
interval
;
int
rxcost
,
interval
;
int
ll
;
int
ll
;
if
(
neigh
==
NULL
&&
net
==
NULL
)
{
if
(
neigh
==
NULL
&&
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
FOR_ALL_
NETS
(
n
)
{
FOR_ALL_
INTERFACES
(
ifp_aux
)
{
if
(
net_up
(
n
))
if
(
if_up
(
ifp_aux
))
continue
;
continue
;
send_ihu
(
NULL
,
n
);
send_ihu
(
NULL
,
ifp_aux
);
}
}
return
;
return
;
}
}
...
@@ -1221,22 +1221,22 @@ send_ihu(struct neighbour *neigh, struct network *net)
...
@@ -1221,22 +1221,22 @@ send_ihu(struct neighbour *neigh, struct network *net)
if
(
neigh
==
NULL
)
{
if
(
neigh
==
NULL
)
{
struct
neighbour
*
ngh
;
struct
neighbour
*
ngh
;
FOR_ALL_NEIGHBOURS
(
ngh
)
{
FOR_ALL_NEIGHBOURS
(
ngh
)
{
if
(
ngh
->
network
==
net
)
if
(
ngh
->
ifp
==
ifp
)
send_ihu
(
ngh
,
net
);
send_ihu
(
ngh
,
ifp
);
}
}
return
;
return
;
}
}
if
(
net
&&
neigh
->
network
!=
net
)
if
(
ifp
&&
neigh
->
ifp
!=
ifp
)
return
;
return
;
net
=
neigh
->
network
;
ifp
=
neigh
->
ifp
;
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
rxcost
=
neighbour_rxcost
(
neigh
);
rxcost
=
neighbour_rxcost
(
neigh
);
interval
=
(
net
->
hello_interval
*
3
+
9
)
/
10
;
interval
=
(
ifp
->
hello_interval
*
3
+
9
)
/
10
;
/* Conceptually, an IHU is a unicast message. We usually send them as
/* Conceptually, an IHU is a unicast message. We usually send them as
multicast, since this allows aggregation into a single packet and
multicast, since this allows aggregation into a single packet and
...
@@ -1245,22 +1245,22 @@ send_ihu(struct neighbour *neigh, struct network *net)
...
@@ -1245,22 +1245,22 @@ send_ihu(struct neighbour *neigh, struct network *net)
debugf
(
"Sending %sihu %d on %s to %s.
\n
"
,
debugf
(
"Sending %sihu %d on %s to %s.
\n
"
,
unicast_neighbour
==
neigh
?
"unicast "
:
""
,
unicast_neighbour
==
neigh
?
"unicast "
:
""
,
rxcost
,
rxcost
,
neigh
->
network
->
if
name
,
neigh
->
ifp
->
name
,
format_address
(
neigh
->
address
));
format_address
(
neigh
->
address
));
ll
=
linklocal
(
neigh
->
address
);
ll
=
linklocal
(
neigh
->
address
);
if
(
unicast_neighbour
!=
neigh
)
{
if
(
unicast_neighbour
!=
neigh
)
{
start_message
(
net
,
MESSAGE_IHU
,
ll
?
14
:
22
);
start_message
(
ifp
,
MESSAGE_IHU
,
ll
?
14
:
22
);
accumulate_byte
(
net
,
ll
?
3
:
2
);
accumulate_byte
(
ifp
,
ll
?
3
:
2
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_short
(
net
,
rxcost
);
accumulate_short
(
ifp
,
rxcost
);
accumulate_short
(
net
,
interval
);
accumulate_short
(
ifp
,
interval
);
if
(
ll
)
if
(
ll
)
accumulate_bytes
(
net
,
neigh
->
address
+
8
,
8
);
accumulate_bytes
(
ifp
,
neigh
->
address
+
8
,
8
);
else
else
accumulate_bytes
(
net
,
neigh
->
address
,
16
);
accumulate_bytes
(
ifp
,
neigh
->
address
,
16
);
end_message
(
net
,
MESSAGE_IHU
,
ll
?
14
:
22
);
end_message
(
ifp
,
MESSAGE_IHU
,
ll
?
14
:
22
);
}
else
{
}
else
{
int
rc
;
int
rc
;
rc
=
start_unicast_message
(
neigh
,
MESSAGE_IHU
,
ll
?
14
:
22
);
rc
=
start_unicast_message
(
neigh
,
MESSAGE_IHU
,
ll
?
14
:
22
);
...
@@ -1279,54 +1279,54 @@ send_ihu(struct neighbour *neigh, struct network *net)
...
@@ -1279,54 +1279,54 @@ send_ihu(struct neighbour *neigh, struct network *net)
/* Send IHUs to all marginal neighbours */
/* Send IHUs to all marginal neighbours */
void
void
send_marginal_ihu
(
struct
network
*
net
)
send_marginal_ihu
(
struct
interface
*
ifp
)
{
{
struct
neighbour
*
neigh
;
struct
neighbour
*
neigh
;
FOR_ALL_NEIGHBOURS
(
neigh
)
{
FOR_ALL_NEIGHBOURS
(
neigh
)
{
if
(
net
&&
neigh
->
network
!=
net
)
if
(
ifp
&&
neigh
->
ifp
!=
ifp
)
continue
;
continue
;
if
(
neigh
->
txcost
>=
384
||
(
neigh
->
reach
&
0xF000
)
!=
0xF000
)
if
(
neigh
->
txcost
>=
384
||
(
neigh
->
reach
&
0xF000
)
!=
0xF000
)
send_ihu
(
neigh
,
net
);
send_ihu
(
neigh
,
ifp
);
}
}
}
}
void
void
send_request
(
struct
network
*
net
,
send_request
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
const
unsigned
char
*
prefix
,
unsigned
char
plen
)
{
{
int
v4
,
len
;
int
v4
,
len
;
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
n
;
FOR_ALL_
NETS
(
n
)
{
FOR_ALL_
INTERFACES
(
ifp_aux
n
)
{
if
(
net_up
(
n
))
if
(
if_up
(
ifp_aux
n
))
continue
;
continue
;
send_request
(
n
,
prefix
,
plen
);
send_request
(
ifp_aux
n
,
prefix
,
plen
);
}
}
return
;
return
;
}
}
/* make sure any buffered updates go out before this request. */
/* make sure any buffered updates go out before this request. */
flushupdates
(
net
);
flushupdates
(
ifp
);
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
debugf
(
"sending request to %s for %s.
\n
"
,
debugf
(
"sending request to %s for %s.
\n
"
,
net
->
if
name
,
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
);
ifp
->
name
,
prefix
?
format_prefix
(
prefix
,
plen
)
:
"any"
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
len
=
!
prefix
?
2
:
v4
?
6
:
18
;
len
=
!
prefix
?
2
:
v4
?
6
:
18
;
start_message
(
net
,
MESSAGE_REQUEST
,
len
);
start_message
(
ifp
,
MESSAGE_REQUEST
,
len
);
accumulate_byte
(
net
,
!
prefix
?
0
:
v4
?
1
:
2
);
accumulate_byte
(
ifp
,
!
prefix
?
0
:
v4
?
1
:
2
);
accumulate_byte
(
net
,
!
prefix
?
0
:
v4
?
plen
-
96
:
plen
);
accumulate_byte
(
ifp
,
!
prefix
?
0
:
v4
?
plen
-
96
:
plen
);
if
(
prefix
)
{
if
(
prefix
)
{
if
(
v4
)
if
(
v4
)
accumulate_bytes
(
net
,
prefix
+
12
,
4
);
accumulate_bytes
(
ifp
,
prefix
+
12
,
4
);
else
else
accumulate_bytes
(
net
,
prefix
,
16
);
accumulate_bytes
(
ifp
,
prefix
,
16
);
}
}
end_message
(
net
,
MESSAGE_REQUEST
,
len
);
end_message
(
ifp
,
MESSAGE_REQUEST
,
len
);
}
}
void
void
...
@@ -1336,7 +1336,7 @@ send_unicast_request(struct neighbour *neigh,
...
@@ -1336,7 +1336,7 @@ send_unicast_request(struct neighbour *neigh,
int
rc
,
v4
,
len
;
int
rc
,
v4
,
len
;
/* make sure any buffered updates go out before this request. */
/* make sure any buffered updates go out before this request. */
flushupdates
(
neigh
->
network
);
flushupdates
(
neigh
->
ifp
);
debugf
(
"sending unicast request to %s for %s.
\n
"
,
debugf
(
"sending unicast request to %s for %s.
\n
"
,
format_address
(
neigh
->
address
),
format_address
(
neigh
->
address
),
...
@@ -1358,7 +1358,7 @@ send_unicast_request(struct neighbour *neigh,
...
@@ -1358,7 +1358,7 @@ send_unicast_request(struct neighbour *neigh,
}
}
void
void
send_multihop_request
(
struct
network
*
net
,
send_multihop_request
(
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
,
unsigned
short
hop_count
)
unsigned
short
hop_count
)
...
@@ -1366,41 +1366,41 @@ send_multihop_request(struct network *net,
...
@@ -1366,41 +1366,41 @@ send_multihop_request(struct network *net,
int
v4
,
pb
,
len
;
int
v4
,
pb
,
len
;
/* Make sure any buffered updates go out before this request. */
/* Make sure any buffered updates go out before this request. */
flushupdates
(
net
);
flushupdates
(
ifp
);
if
(
net
==
NULL
)
{
if
(
ifp
==
NULL
)
{
struct
network
*
n
;
struct
interface
*
ifp_aux
;
FOR_ALL_
NETS
(
n
)
{
FOR_ALL_
INTERFACES
(
ifp_aux
)
{
if
(
!
net_up
(
n
))
if
(
!
if_up
(
ifp_aux
))
continue
;
continue
;
send_multihop_request
(
n
,
prefix
,
plen
,
seqno
,
id
,
hop_count
);
send_multihop_request
(
ifp_aux
,
prefix
,
plen
,
seqno
,
id
,
hop_count
);
}
}
return
;
return
;
}
}
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
;
return
;
debugf
(
"Sending request (%d) on %s for %s.
\n
"
,
debugf
(
"Sending request (%d) on %s for %s.
\n
"
,
hop_count
,
net
->
if
name
,
format_prefix
(
prefix
,
plen
));
hop_count
,
ifp
->
name
,
format_prefix
(
prefix
,
plen
));
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
v4
=
plen
>=
96
&&
v4mapped
(
prefix
);
pb
=
v4
?
((
plen
-
96
)
+
7
)
/
8
:
(
plen
+
7
)
/
8
;
pb
=
v4
?
((
plen
-
96
)
+
7
)
/
8
:
(
plen
+
7
)
/
8
;
len
=
6
+
8
+
pb
;
len
=
6
+
8
+
pb
;
start_message
(
net
,
MESSAGE_MH_REQUEST
,
len
);
start_message
(
ifp
,
MESSAGE_MH_REQUEST
,
len
);
accumulate_byte
(
net
,
v4
?
1
:
2
);
accumulate_byte
(
ifp
,
v4
?
1
:
2
);
accumulate_byte
(
net
,
v4
?
plen
-
96
:
plen
);
accumulate_byte
(
ifp
,
v4
?
plen
-
96
:
plen
);
accumulate_short
(
net
,
seqno
);
accumulate_short
(
ifp
,
seqno
);
accumulate_byte
(
net
,
hop_count
);
accumulate_byte
(
ifp
,
hop_count
);
accumulate_byte
(
net
,
0
);
accumulate_byte
(
ifp
,
0
);
accumulate_bytes
(
net
,
id
,
8
);
accumulate_bytes
(
ifp
,
id
,
8
);
if
(
prefix
)
{
if
(
prefix
)
{
if
(
v4
)
if
(
v4
)
accumulate_bytes
(
net
,
prefix
+
12
,
pb
);
accumulate_bytes
(
ifp
,
prefix
+
12
,
pb
);
else
else
accumulate_bytes
(
net
,
prefix
,
pb
);
accumulate_bytes
(
ifp
,
prefix
,
pb
);
}
}
end_message
(
net
,
MESSAGE_MH_REQUEST
,
len
);
end_message
(
ifp
,
MESSAGE_MH_REQUEST
,
len
);
}
}
void
void
...
@@ -1412,7 +1412,7 @@ send_unicast_multihop_request(struct neighbour *neigh,
...
@@ -1412,7 +1412,7 @@ send_unicast_multihop_request(struct neighbour *neigh,
int
rc
,
v4
,
pb
,
len
;
int
rc
,
v4
,
pb
,
len
;
/* Make sure any buffered updates go out before this request. */
/* Make sure any buffered updates go out before this request. */
flushupdates
(
neigh
->
network
);
flushupdates
(
neigh
->
ifp
);
debugf
(
"Sending multi-hop request to %s for %s (%d hops).
\n
"
,
debugf
(
"Sending multi-hop request to %s for %s (%d hops).
\n
"
,
format_address
(
neigh
->
address
),
format_address
(
neigh
->
address
),
...
@@ -1455,7 +1455,7 @@ send_request_resend(struct neighbour *neigh,
...
@@ -1455,7 +1455,7 @@ send_request_resend(struct neighbour *neigh,
delay
=
MIN
(
delay
,
wired_hello_interval
/
2
);
delay
=
MIN
(
delay
,
wired_hello_interval
/
2
);
delay
=
MAX
(
delay
,
10
);
delay
=
MAX
(
delay
,
10
);
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
record_resend
(
RESEND_REQUEST
,
prefix
,
plen
,
seqno
,
id
,
neigh
?
neigh
->
network
:
NULL
,
delay
);
neigh
?
neigh
->
ifp
:
NULL
,
delay
);
}
}
void
void
...
@@ -1480,14 +1480,14 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1480,14 +1480,14 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
update_myseqno
();
update_myseqno
();
}
}
}
}
send_update
(
neigh
->
network
,
1
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
1
,
prefix
,
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
->
network
,
1
,
prefix
,
plen
);
send_update
(
neigh
->
ifp
,
1
,
prefix
,
plen
);
return
;
return
;
}
}
...
@@ -1500,7 +1500,7 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1500,7 +1500,7 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
return
;
return
;
}
}
if
(
request_redundant
(
neigh
->
network
,
prefix
,
plen
,
seqno
,
id
))
if
(
request_redundant
(
neigh
->
ifp
,
prefix
,
plen
,
seqno
,
id
))
return
;
return
;
/* Let's try to forward this request. */
/* Let's try to forward this request. */
...
@@ -1524,5 +1524,5 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
...
@@ -1524,5 +1524,5 @@ 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
,
seqno
,
id
,
neigh
->
network
,
0
);
neigh
->
ifp
,
0
);
}
}
message.h
View file @
1c3b2bb8
...
@@ -50,29 +50,29 @@ extern unsigned char packet_header[4];
...
@@ -50,29 +50,29 @@ extern unsigned char packet_header[4];
extern
struct
neighbour
*
unicast_neighbour
;
extern
struct
neighbour
*
unicast_neighbour
;
extern
struct
timeval
unicast_flush_timeout
;
extern
struct
timeval
unicast_flush_timeout
;
void
parse_packet
(
const
unsigned
char
*
from
,
struct
network
*
net
,
void
parse_packet
(
const
unsigned
char
*
from
,
struct
interface
*
ifp
,
const
unsigned
char
*
packet
,
int
packetlen
);
const
unsigned
char
*
packet
,
int
packetlen
);
void
flushbuf
(
struct
network
*
net
);
void
flushbuf
(
struct
interface
*
ifp
);
void
flushupdates
(
struct
network
*
net
);
void
flushupdates
(
struct
interface
*
ifp
);
void
send_ack
(
struct
neighbour
*
neigh
,
unsigned
short
nonce
,
void
send_ack
(
struct
neighbour
*
neigh
,
unsigned
short
nonce
,
unsigned
short
interval
);
unsigned
short
interval
);
void
send_hello_noupdate
(
struct
network
*
net
,
unsigned
interval
);
void
send_hello_noupdate
(
struct
interface
*
ifp
,
unsigned
interval
);
void
send_hello
(
struct
network
*
net
);
void
send_hello
(
struct
interface
*
ifp
);
void
flush_unicast
(
int
dofree
);
void
flush_unicast
(
int
dofree
);
void
send_update
(
struct
network
*
net
,
int
urgent
,
void
send_update
(
struct
interface
*
ifp
,
int
urgent
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_update_resend
(
struct
network
*
net
,
void
send_update_resend
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_wildcard_retraction
(
struct
network
*
net
);
void
send_wildcard_retraction
(
struct
interface
*
ifp
);
void
update_myseqno
(
void
);
void
update_myseqno
(
void
);
void
send_self_update
(
struct
network
*
net
);
void
send_self_update
(
struct
interface
*
ifp
);
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
network
*
net
);
void
send_ihu
(
struct
neighbour
*
neigh
,
struct
interface
*
ifp
);
void
send_marginal_ihu
(
struct
network
*
net
);
void
send_marginal_ihu
(
struct
interface
*
ifp
);
void
send_request
(
struct
network
*
net
,
void
send_request
(
struct
interface
*
ifp
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_unicast_request
(
struct
neighbour
*
neigh
,
void
send_unicast_request
(
struct
neighbour
*
neigh
,
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
const
unsigned
char
*
prefix
,
unsigned
char
plen
);
void
send_multihop_request
(
struct
network
*
net
,
void
send_multihop_request
(
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
,
unsigned
short
hop_count
);
unsigned
short
hop_count
);
...
...
neighbour.c
View file @
1c3b2bb8
...
@@ -39,12 +39,12 @@ THE SOFTWARE.
...
@@ -39,12 +39,12 @@ THE SOFTWARE.
struct
neighbour
*
neighs
=
NULL
;
struct
neighbour
*
neighs
=
NULL
;
static
struct
neighbour
*
static
struct
neighbour
*
find_neighbour_nocreate
(
const
unsigned
char
*
address
,
struct
network
*
net
)
find_neighbour_nocreate
(
const
unsigned
char
*
address
,
struct
interface
*
ifp
)
{
{
struct
neighbour
*
neigh
;
struct
neighbour
*
neigh
;
FOR_ALL_NEIGHBOURS
(
neigh
)
{
FOR_ALL_NEIGHBOURS
(
neigh
)
{
if
(
memcmp
(
address
,
neigh
->
address
,
16
)
==
0
&&
if
(
memcmp
(
address
,
neigh
->
address
,
16
)
==
0
&&
neigh
->
network
==
net
)
neigh
->
ifp
==
ifp
)
return
neigh
;
return
neigh
;
}
}
return
NULL
;
return
NULL
;
...
@@ -71,17 +71,17 @@ flush_neighbour(struct neighbour *neigh)
...
@@ -71,17 +71,17 @@ flush_neighbour(struct neighbour *neigh)
}
}
struct
neighbour
*
struct
neighbour
*
find_neighbour
(
const
unsigned
char
*
address
,
struct
network
*
net
)
find_neighbour
(
const
unsigned
char
*
address
,
struct
interface
*
ifp
)
{
{
struct
neighbour
*
neigh
;
struct
neighbour
*
neigh
;
const
struct
timeval
zero
=
{
0
,
0
};
const
struct
timeval
zero
=
{
0
,
0
};
neigh
=
find_neighbour_nocreate
(
address
,
net
);
neigh
=
find_neighbour_nocreate
(
address
,
ifp
);
if
(
neigh
)
if
(
neigh
)
return
neigh
;
return
neigh
;
debugf
(
"Creating neighbour %s on %s.
\n
"
,
debugf
(
"Creating neighbour %s on %s.
\n
"
,
format_address
(
address
),
net
->
if
name
);
format_address
(
address
),
ifp
->
name
);
neigh
=
malloc
(
sizeof
(
struct
neighbour
));
neigh
=
malloc
(
sizeof
(
struct
neighbour
));
if
(
neigh
==
NULL
)
{
if
(
neigh
==
NULL
)
{
...
@@ -97,11 +97,11 @@ find_neighbour(const unsigned char *address, struct network *net)
...
@@ -97,11 +97,11 @@ find_neighbour(const unsigned char *address, struct network *net)
neigh
->
hello_time
=
zero
;
neigh
->
hello_time
=
zero
;
neigh
->
hello_interval
=
0
;
neigh
->
hello_interval
=
0
;
neigh
->
ihu_interval
=
0
;
neigh
->
ihu_interval
=
0
;
neigh
->
network
=
net
;
neigh
->
ifp
=
ifp
;
neigh
->
next
=
neighs
;
neigh
->
next
=
neighs
;
neighs
=
neigh
;
neighs
=
neigh
;
local_notify_neighbour
(
neigh
,
LOCAL_ADD
);
local_notify_neighbour
(
neigh
,
LOCAL_ADD
);
send_hello
(
net
);
send_hello
(
ifp
);
return
neigh
;
return
neigh
;
}
}
...
@@ -174,14 +174,14 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
...
@@ -174,14 +174,14 @@ update_neighbour(struct neighbour *neigh, int hello, int hello_interval)
/* Make sure to give neighbours some feedback early after association */
/* Make sure to give neighbours some feedback early after association */
if
((
neigh
->
reach
&
0xBF00
)
==
0x8000
)
{
if
((
neigh
->
reach
&
0xBF00
)
==
0x8000
)
{
/* A new neighbour */
/* A new neighbour */
send_hello
(
neigh
->
network
);
send_hello
(
neigh
->
ifp
);
}
else
{
}
else
{
/* Don't send hellos, in order to avoid a positive feedback loop. */
/* Don't send hellos, in order to avoid a positive feedback loop. */
int
a
=
(
neigh
->
reach
&
0xC000
);
int
a
=
(
neigh
->
reach
&
0xC000
);
int
b
=
(
neigh
->
reach
&
0x3000
);
int
b
=
(
neigh
->
reach
&
0x3000
);
if
((
a
==
0xC000
&&
b
==
0
)
||
(
a
==
0
&&
b
==
0x3000
))
{
if
((
a
==
0xC000
&&
b
==
0
)
||
(
a
==
0
&&
b
==
0x3000
))
{
/* Reachability is either 1100 or 0011 */
/* Reachability is either 1100 or 0011 */
send_self_update
(
neigh
->
network
);
send_self_update
(
neigh
->
ifp
);
}
}
}
}
...
@@ -269,25 +269,25 @@ neighbour_rxcost(struct neighbour *neigh)
...
@@ -269,25 +269,25 @@ neighbour_rxcost(struct neighbour *neigh)
if
((
reach
&
0xFFF0
)
==
0
||
delay
>=
180000
)
{
if
((
reach
&
0xFFF0
)
==
0
||
delay
>=
180000
)
{
return
INFINITY
;
return
INFINITY
;
}
else
if
((
neigh
->
network
->
flags
&
NET
_LQ
))
{
}
else
if
((
neigh
->
ifp
->
flags
&
IF
_LQ
))
{
int
sreach
=
int
sreach
=
((
reach
&
0x8000
)
>>
2
)
+
((
reach
&
0x8000
)
>>
2
)
+
((
reach
&
0x4000
)
>>
1
)
+
((
reach
&
0x4000
)
>>
1
)
+
(
reach
&
0x3FFF
);
(
reach
&
0x3FFF
);
/* 0 <= sreach <= 0x7FFF */
/* 0 <= sreach <= 0x7FFF */
int
cost
=
(
0x8000
*
neigh
->
network
->
cost
)
/
(
sreach
+
1
);
int
cost
=
(
0x8000
*
neigh
->
ifp
->
cost
)
/
(
sreach
+
1
);
/* cost >=
network
->cost */
/* cost >=
interface
->cost */
if
(
delay
>=
40000
)
if
(
delay
>=
40000
)
cost
=
(
cost
*
(
delay
-
20000
)
+
10000
)
/
20000
;
cost
=
(
cost
*
(
delay
-
20000
)
+
10000
)
/
20000
;
return
MIN
(
cost
,
INFINITY
);
return
MIN
(
cost
,
INFINITY
);
}
else
{
}
else
{
/* To lose one hello is a misfortune, to lose two is carelessness. */
/* To lose one hello is a misfortune, to lose two is carelessness. */
if
((
reach
&
0xC000
)
==
0xC000
)
if
((
reach
&
0xC000
)
==
0xC000
)
return
neigh
->
network
->
cost
;
return
neigh
->
ifp
->
cost
;
else
if
((
reach
&
0xC000
)
==
0
)
else
if
((
reach
&
0xC000
)
==
0
)
return
INFINITY
;
return
INFINITY
;
else
if
((
reach
&
0x2000
))
else
if
((
reach
&
0x2000
))
return
neigh
->
network
->
cost
;
return
neigh
->
ifp
->
cost
;
else
else
return
INFINITY
;
return
INFINITY
;
}
}
...
@@ -298,7 +298,7 @@ neighbour_cost(struct neighbour *neigh)
...
@@ -298,7 +298,7 @@ neighbour_cost(struct neighbour *neigh)
{
{
unsigned
a
,
b
;
unsigned
a
,
b
;
if
(
!
net_up
(
neigh
->
network
))
if
(
!
if_up
(
neigh
->
ifp
))
return
INFINITY
;
return
INFINITY
;
a
=
neighbour_txcost
(
neigh
);
a
=
neighbour_txcost
(
neigh
);
...
@@ -310,7 +310,7 @@ neighbour_cost(struct neighbour *neigh)
...
@@ -310,7 +310,7 @@ neighbour_cost(struct neighbour *neigh)
if
(
b
>=
INFINITY
)
if
(
b
>=
INFINITY
)
return
INFINITY
;
return
INFINITY
;
if
(
!
(
neigh
->
network
->
flags
&
NET
_LQ
)
||
(
a
<=
256
&&
b
<=
256
))
{
if
(
!
(
neigh
->
ifp
->
flags
&
IF
_LQ
)
||
(
a
<=
256
&&
b
<=
256
))
{
return
a
;
return
a
;
}
else
{
}
else
{
/* a = 256/alpha, b = 256/beta, where alpha and beta are the expected
/* a = 256/alpha, b = 256/beta, where alpha and beta are the expected
...
...
neighbour.h
View file @
1c3b2bb8
...
@@ -31,7 +31,7 @@ struct neighbour {
...
@@ -31,7 +31,7 @@ struct neighbour {
struct
timeval
ihu_time
;
struct
timeval
ihu_time
;
unsigned
short
hello_interval
;
/* in centiseconds */
unsigned
short
hello_interval
;
/* in centiseconds */
unsigned
short
ihu_interval
;
/* in centiseconds */
unsigned
short
ihu_interval
;
/* in centiseconds */
struct
network
*
network
;
struct
interface
*
ifp
;
};
};
extern
struct
neighbour
*
neighs
;
extern
struct
neighbour
*
neighs
;
...
@@ -42,7 +42,7 @@ extern struct neighbour *neighs;
...
@@ -42,7 +42,7 @@ extern struct neighbour *neighs;
int
neighbour_valid
(
struct
neighbour
*
neigh
);
int
neighbour_valid
(
struct
neighbour
*
neigh
);
void
flush_neighbour
(
struct
neighbour
*
neigh
);
void
flush_neighbour
(
struct
neighbour
*
neigh
);
struct
neighbour
*
find_neighbour
(
const
unsigned
char
*
address
,
struct
neighbour
*
find_neighbour
(
const
unsigned
char
*
address
,
struct
network
*
net
);
struct
interface
*
ifp
);
int
update_neighbour
(
struct
neighbour
*
neigh
,
int
hello
,
int
hello_interval
);
int
update_neighbour
(
struct
neighbour
*
neigh
,
int
hello
,
int
hello_interval
);
unsigned
check_neighbours
(
void
);
unsigned
check_neighbours
(
void
);
unsigned
neighbour_txcost
(
struct
neighbour
*
neigh
);
unsigned
neighbour_txcost
(
struct
neighbour
*
neigh
);
...
...
network.c
View file @
1c3b2bb8
...
@@ -41,80 +41,80 @@ THE SOFTWARE.
...
@@ -41,80 +41,80 @@ THE SOFTWARE.
#include "route.h"
#include "route.h"
#include "configuration.h"
#include "configuration.h"
struct
network
*
network
s
=
NULL
;
struct
interface
*
interface
s
=
NULL
;
static
struct
network
*
static
struct
interface
*
last_
network
(
void
)
last_
interface
(
void
)
{
{
struct
network
*
net
=
network
s
;
struct
interface
*
ifp
=
interface
s
;
if
(
!
net
)
if
(
!
ifp
)
return
NULL
;
return
NULL
;
while
(
net
->
next
)
while
(
ifp
->
next
)
net
=
net
->
next
;
ifp
=
ifp
->
next
;
return
net
;
return
ifp
;
}
}
struct
network
*
struct
interface
*
add_
network
(
char
*
ifname
,
struct
network_conf
*
conf
)
add_
interface
(
char
*
ifname
,
struct
interface_conf
*
if_
conf
)
{
{
struct
network
*
net
;
struct
interface
*
ifp
;
assert
(
!
conf
||
strcmp
(
ifname
,
conf
->
ifname
)
==
0
);
assert
(
!
if_conf
||
strcmp
(
ifname
,
if_
conf
->
ifname
)
==
0
);
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
if
(
strcmp
(
net
->
if
name
,
ifname
)
==
0
)
{
if
(
strcmp
(
ifp
->
name
,
ifname
)
==
0
)
{
assert
(
conf
==
NULL
);
assert
(
if_
conf
==
NULL
);
return
net
;
return
ifp
;
}
}
}
}
net
=
malloc
(
sizeof
(
struct
network
));
ifp
=
malloc
(
sizeof
(
struct
interface
));
if
(
net
==
NULL
)
if
(
ifp
==
NULL
)
return
NULL
;
return
NULL
;
memset
(
net
,
0
,
sizeof
(
struct
network
));
memset
(
ifp
,
0
,
sizeof
(
struct
interface
));
strncpy
(
net
->
if
name
,
ifname
,
IF_NAMESIZE
);
strncpy
(
ifp
->
name
,
ifname
,
IF_NAMESIZE
);
net
->
conf
=
conf
;
ifp
->
conf
=
if_
conf
;
net
->
activity_time
=
now
.
tv_sec
;
ifp
->
activity_time
=
now
.
tv_sec
;
net
->
bucket_time
=
now
.
tv_sec
;
ifp
->
bucket_time
=
now
.
tv_sec
;
net
->
bucket
=
BUCKET_TOKENS_MAX
;
ifp
->
bucket
=
BUCKET_TOKENS_MAX
;
net
->
hello_seqno
=
(
random
()
&
0xFFFF
);
ifp
->
hello_seqno
=
(
random
()
&
0xFFFF
);
if
(
network
s
==
NULL
)
if
(
interface
s
==
NULL
)
networks
=
net
;
interfaces
=
ifp
;
else
else
last_
network
()
->
next
=
net
;
last_
interface
()
->
next
=
ifp
;
return
net
;
return
ifp
;
}
}
int
int
network_idle
(
struct
network
*
net
)
interface_idle
(
struct
interface
*
ifp
)
{
{
return
(
idle_hello_interval
>
0
&&
return
(
idle_hello_interval
>
0
&&
net
->
activity_time
<
now
.
tv_sec
-
idle_time
);
ifp
->
activity_time
<
now
.
tv_sec
-
idle_time
);
}
}
int
int
update_hello_interval
(
struct
network
*
net
)
update_hello_interval
(
struct
interface
*
ifp
)
{
{
int
rc
=
0
;
int
rc
=
0
;
unsigned
short
interval
;
unsigned
short
interval
;
if
(
network_idle
(
net
))
if
(
interface_idle
(
ifp
))
interval
=
idle_hello_interval
;
interval
=
idle_hello_interval
;
else
if
(
NET_CONF
(
net
,
hello_interval
)
>
0
)
else
if
(
IF_CONF
(
ifp
,
hello_interval
)
>
0
)
interval
=
NET_CONF
(
net
,
hello_interval
);
interval
=
IF_CONF
(
ifp
,
hello_interval
);
else
if
((
net
->
flags
&
NET
_WIRED
))
else
if
((
ifp
->
flags
&
IF
_WIRED
))
interval
=
wired_hello_interval
;
interval
=
wired_hello_interval
;
else
else
interval
=
wireless_hello_interval
;
interval
=
wireless_hello_interval
;
if
(
net
->
hello_interval
!=
interval
)
{
if
(
ifp
->
hello_interval
!=
interval
)
{
net
->
hello_interval
=
interval
;
ifp
->
hello_interval
=
interval
;
rc
=
1
;
rc
=
1
;
}
}
...
@@ -124,9 +124,9 @@ update_hello_interval(struct network *net)
...
@@ -124,9 +124,9 @@ update_hello_interval(struct network *net)
/* This should be no more than half the hello interval, so that hellos
/* This should be no more than half the hello interval, so that hellos
aren't sent late. The result is in milliseconds. */
aren't sent late. The result is in milliseconds. */
unsigned
unsigned
jitter
(
struct
network
*
net
,
int
urgent
)
jitter
(
struct
interface
*
ifp
,
int
urgent
)
{
{
unsigned
interval
=
net
->
hello_interval
;
unsigned
interval
=
ifp
->
hello_interval
;
if
(
urgent
)
if
(
urgent
)
interval
=
MIN
(
interval
,
100
);
interval
=
MIN
(
interval
,
100
);
else
else
...
@@ -135,9 +135,9 @@ jitter(struct network *net, int urgent)
...
@@ -135,9 +135,9 @@ jitter(struct network *net, int urgent)
}
}
unsigned
unsigned
update_jitter
(
struct
network
*
net
,
int
urgent
)
update_jitter
(
struct
interface
*
ifp
,
int
urgent
)
{
{
unsigned
interval
=
net
->
hello_interval
;
unsigned
interval
=
ifp
->
hello_interval
;
if
(
urgent
)
if
(
urgent
)
interval
=
MIN
(
interval
,
100
);
interval
=
MIN
(
interval
,
100
);
else
else
...
@@ -152,32 +152,32 @@ set_timeout(struct timeval *timeout, int msecs)
...
@@ -152,32 +152,32 @@ set_timeout(struct timeval *timeout, int msecs)
}
}
static
int
static
int
check_
network_ipv4
(
struct
network
*
net
)
check_
interface_ipv4
(
struct
interface
*
ifp
)
{
{
unsigned
char
ipv4
[
4
];
unsigned
char
ipv4
[
4
];
int
rc
;
int
rc
;
if
(
net
->
ifindex
>
0
)
if
(
ifp
->
ifindex
>
0
)
rc
=
kernel_interface_ipv4
(
net
->
ifname
,
net
->
ifindex
,
ipv4
);
rc
=
kernel_interface_ipv4
(
ifp
->
name
,
ifp
->
ifindex
,
ipv4
);
else
else
rc
=
0
;
rc
=
0
;
if
(
rc
>
0
)
{
if
(
rc
>
0
)
{
if
(
!
net
->
ipv4
||
memcmp
(
ipv4
,
net
->
ipv4
,
4
)
!=
0
)
{
if
(
!
ifp
->
ipv4
||
memcmp
(
ipv4
,
ifp
->
ipv4
,
4
)
!=
0
)
{
debugf
(
"Noticed IPv4 change for %s.
\n
"
,
net
->
if
name
);
debugf
(
"Noticed IPv4 change for %s.
\n
"
,
ifp
->
name
);
flush_
network_routes
(
net
,
0
);
flush_
interface_routes
(
ifp
,
0
);
if
(
!
net
->
ipv4
)
if
(
!
ifp
->
ipv4
)
net
->
ipv4
=
malloc
(
4
);
ifp
->
ipv4
=
malloc
(
4
);
if
(
net
->
ipv4
)
if
(
ifp
->
ipv4
)
memcpy
(
net
->
ipv4
,
ipv4
,
4
);
memcpy
(
ifp
->
ipv4
,
ipv4
,
4
);
return
1
;
return
1
;
}
}
}
else
{
}
else
{
if
(
net
->
ipv4
)
{
if
(
ifp
->
ipv4
)
{
debugf
(
"Noticed IPv4 change for %s.
\n
"
,
net
->
if
name
);
debugf
(
"Noticed IPv4 change for %s.
\n
"
,
ifp
->
name
);
flush_
network_routes
(
net
,
0
);
flush_
interface_routes
(
ifp
,
0
);
free
(
net
->
ipv4
);
free
(
ifp
->
ipv4
);
net
->
ipv4
=
NULL
;
ifp
->
ipv4
=
NULL
;
return
1
;
return
1
;
}
}
}
}
...
@@ -185,64 +185,64 @@ check_network_ipv4(struct network *net)
...
@@ -185,64 +185,64 @@ check_network_ipv4(struct network *net)
}
}
int
int
check_
network_channel
(
struct
network
*
net
)
check_
interface_channel
(
struct
interface
*
ifp
)
{
{
int
channel
=
NET_CONF
(
net
,
channel
);
int
channel
=
IF_CONF
(
ifp
,
channel
);
if
(
channel
==
NET
_CHANNEL_UNKNOWN
)
{
if
(
channel
==
IF
_CHANNEL_UNKNOWN
)
{
if
((
net
->
flags
&
NET
_WIRED
))
{
if
((
ifp
->
flags
&
IF
_WIRED
))
{
channel
=
NET
_CHANNEL_NONINTERFERING
;
channel
=
IF
_CHANNEL_NONINTERFERING
;
}
else
{
}
else
{
channel
=
kernel_interface_channel
(
net
->
ifname
,
net
->
ifindex
);
channel
=
kernel_interface_channel
(
ifp
->
name
,
ifp
->
ifindex
);
if
(
channel
<
0
)
if
(
channel
<
0
)
fprintf
(
stderr
,
fprintf
(
stderr
,
"Couldn't determine channel of interface %s: %s.
\n
"
,
"Couldn't determine channel of interface %s: %s.
\n
"
,
net
->
if
name
,
strerror
(
errno
));
ifp
->
name
,
strerror
(
errno
));
if
(
channel
<=
0
)
if
(
channel
<=
0
)
channel
=
NET
_CHANNEL_INTERFERING
;
channel
=
IF
_CHANNEL_INTERFERING
;
}
}
}
}
if
(
net
->
channel
!=
channel
)
{
if
(
ifp
->
channel
!=
channel
)
{
net
->
channel
=
channel
;
ifp
->
channel
=
channel
;
return
1
;
return
1
;
}
}
return
0
;
return
0
;
}
}
int
int
network_up
(
struct
network
*
net
,
int
up
)
interface_up
(
struct
interface
*
ifp
,
int
up
)
{
{
int
mtu
,
rc
,
wired
;
int
mtu
,
rc
,
wired
;
struct
ipv6_mreq
mreq
;
struct
ipv6_mreq
mreq
;
if
((
!!
up
)
==
net_up
(
net
))
if
((
!!
up
)
==
if_up
(
ifp
))
return
0
;
return
0
;
if
(
up
)
if
(
up
)
net
->
flags
|=
NET
_UP
;
ifp
->
flags
|=
IF
_UP
;
else
else
net
->
flags
&=
~
NET
_UP
;
ifp
->
flags
&=
~
IF
_UP
;
if
(
up
)
{
if
(
up
)
{
struct
kernel_route
ll
[
32
];
struct
kernel_route
ll
[
32
];
if
(
net
->
ifindex
<=
0
)
{
if
(
ifp
->
ifindex
<=
0
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Upping unknown interface %s.
\n
"
,
net
->
if
name
);
"Upping unknown interface %s.
\n
"
,
ifp
->
name
);
return
network_up
(
net
,
0
);
return
interface_up
(
ifp
,
0
);
}
}
rc
=
kernel_setup_interface
(
1
,
net
->
ifname
,
net
->
ifindex
);
rc
=
kernel_setup_interface
(
1
,
ifp
->
name
,
ifp
->
ifindex
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
fprintf
(
stderr
,
"kernel_setup_interface(%s, %d) failed.
\n
"
,
fprintf
(
stderr
,
"kernel_setup_interface(%s, %d) failed.
\n
"
,
net
->
ifname
,
net
->
ifindex
);
ifp
->
name
,
ifp
->
ifindex
);
return
network_up
(
net
,
0
);
return
interface_up
(
ifp
,
0
);
}
}
mtu
=
kernel_interface_mtu
(
net
->
ifname
,
net
->
ifindex
);
mtu
=
kernel_interface_mtu
(
ifp
->
name
,
ifp
->
ifindex
);
if
(
mtu
<
0
)
{
if
(
mtu
<
0
)
{
fprintf
(
stderr
,
"Warning: couldn't get MTU of interface %s (%d).
\n
"
,
fprintf
(
stderr
,
"Warning: couldn't get MTU of interface %s (%d).
\n
"
,
net
->
ifname
,
net
->
ifindex
);
ifp
->
name
,
ifp
->
ifindex
);
mtu
=
1280
;
mtu
=
1280
;
}
}
...
@@ -252,37 +252,37 @@ network_up(struct network *net, int up)
...
@@ -252,37 +252,37 @@ network_up(struct network *net, int up)
to reassemble up to 1500 bytes, but I'd rather not rely on this. */
to reassemble up to 1500 bytes, but I'd rather not rely on this. */
if
(
mtu
<
128
)
{
if
(
mtu
<
128
)
{
fprintf
(
stderr
,
"Suspiciously low MTU %d on interface %s (%d).
\n
"
,
fprintf
(
stderr
,
"Suspiciously low MTU %d on interface %s (%d).
\n
"
,
mtu
,
net
->
ifname
,
net
->
ifindex
);
mtu
,
ifp
->
name
,
ifp
->
ifindex
);
mtu
=
128
;
mtu
=
128
;
}
}
if
(
net
->
sendbuf
)
if
(
ifp
->
sendbuf
)
free
(
net
->
sendbuf
);
free
(
ifp
->
sendbuf
);
/* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
/* 40 for IPv6 header, 8 for UDP header, 12 for good luck. */
net
->
bufsize
=
mtu
-
sizeof
(
packet_header
)
-
60
;
ifp
->
bufsize
=
mtu
-
sizeof
(
packet_header
)
-
60
;
net
->
sendbuf
=
malloc
(
net
->
bufsize
);
ifp
->
sendbuf
=
malloc
(
ifp
->
bufsize
);
if
(
net
->
sendbuf
==
NULL
)
{
if
(
ifp
->
sendbuf
==
NULL
)
{
fprintf
(
stderr
,
"Couldn't allocate sendbuf.
\n
"
);
fprintf
(
stderr
,
"Couldn't allocate sendbuf.
\n
"
);
net
->
bufsize
=
0
;
ifp
->
bufsize
=
0
;
return
network_up
(
net
,
0
);
return
interface_up
(
ifp
,
0
);
}
}
resize_receive_buffer
(
mtu
);
resize_receive_buffer
(
mtu
);
if
(
NET_CONF
(
net
,
wired
)
==
CONFIG_NO
)
{
if
(
IF_CONF
(
ifp
,
wired
)
==
CONFIG_NO
)
{
wired
=
0
;
wired
=
0
;
}
else
if
(
NET_CONF
(
net
,
wired
)
==
CONFIG_YES
)
{
}
else
if
(
IF_CONF
(
ifp
,
wired
)
==
CONFIG_YES
)
{
wired
=
1
;
wired
=
1
;
}
else
if
(
all_wireless
)
{
}
else
if
(
all_wireless
)
{
wired
=
0
;
wired
=
0
;
}
else
{
}
else
{
rc
=
kernel_interface_wireless
(
net
->
ifname
,
net
->
ifindex
);
rc
=
kernel_interface_wireless
(
ifp
->
name
,
ifp
->
ifindex
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
fprintf
(
stderr
,
fprintf
(
stderr
,
"Warning: couldn't determine whether %s (%d) "
"Warning: couldn't determine whether %s (%d) "
"is a wireless interface.
\n
"
,
"is a wireless interface.
\n
"
,
net
->
ifname
,
net
->
ifindex
);
ifp
->
name
,
ifp
->
ifindex
);
wired
=
0
;
wired
=
0
;
}
else
{
}
else
{
wired
=
!
rc
;
wired
=
!
rc
;
...
@@ -290,172 +290,172 @@ network_up(struct network *net, int up)
...
@@ -290,172 +290,172 @@ network_up(struct network *net, int up)
}
}
if
(
wired
)
{
if
(
wired
)
{
net
->
flags
|=
NET
_WIRED
;
ifp
->
flags
|=
IF
_WIRED
;
net
->
cost
=
NET_CONF
(
net
,
cost
);
ifp
->
cost
=
IF_CONF
(
ifp
,
cost
);
if
(
net
->
cost
<=
0
)
net
->
cost
=
96
;
if
(
ifp
->
cost
<=
0
)
ifp
->
cost
=
96
;
if
(
NET_CONF
(
net
,
split_horizon
)
==
CONFIG_NO
)
if
(
IF_CONF
(
ifp
,
split_horizon
)
==
CONFIG_NO
)
net
->
flags
&=
~
NET
_SPLIT_HORIZON
;
ifp
->
flags
&=
~
IF
_SPLIT_HORIZON
;
else
if
(
NET_CONF
(
net
,
split_horizon
)
==
CONFIG_YES
)
else
if
(
IF_CONF
(
ifp
,
split_horizon
)
==
CONFIG_YES
)
net
->
flags
|=
NET
_SPLIT_HORIZON
;
ifp
->
flags
|=
IF
_SPLIT_HORIZON
;
else
if
(
split_horizon
)
else
if
(
split_horizon
)
net
->
flags
|=
NET
_SPLIT_HORIZON
;
ifp
->
flags
|=
IF
_SPLIT_HORIZON
;
else
else
net
->
flags
&=
~
NET
_SPLIT_HORIZON
;
ifp
->
flags
&=
~
IF
_SPLIT_HORIZON
;
if
(
NET_CONF
(
net
,
lq
)
==
CONFIG_YES
)
if
(
IF_CONF
(
ifp
,
lq
)
==
CONFIG_YES
)
net
->
flags
|=
NET
_LQ
;
ifp
->
flags
|=
IF
_LQ
;
else
else
net
->
flags
&=
~
NET
_LQ
;
ifp
->
flags
&=
~
IF
_LQ
;
}
else
{
}
else
{
net
->
flags
&=
~
NET
_WIRED
;
ifp
->
flags
&=
~
IF
_WIRED
;
net
->
cost
=
NET_CONF
(
net
,
cost
);
ifp
->
cost
=
IF_CONF
(
ifp
,
cost
);
if
(
net
->
cost
<=
0
)
net
->
cost
=
256
;
if
(
ifp
->
cost
<=
0
)
ifp
->
cost
=
256
;
if
(
NET_CONF
(
net
,
split_horizon
)
==
CONFIG_YES
)
if
(
IF_CONF
(
ifp
,
split_horizon
)
==
CONFIG_YES
)
net
->
flags
|=
NET
_SPLIT_HORIZON
;
ifp
->
flags
|=
IF
_SPLIT_HORIZON
;
else
else
net
->
flags
&=
~
NET
_SPLIT_HORIZON
;
ifp
->
flags
&=
~
IF
_SPLIT_HORIZON
;
if
(
NET_CONF
(
net
,
lq
)
==
CONFIG_NO
)
if
(
IF_CONF
(
ifp
,
lq
)
==
CONFIG_NO
)
net
->
flags
&=
~
NET
_LQ
;
ifp
->
flags
&=
~
IF
_LQ
;
else
else
net
->
flags
|=
NET
_LQ
;
ifp
->
flags
|=
IF
_LQ
;
}
}
if
(
NET_CONF
(
net
,
faraway
)
==
CONFIG_YES
)
if
(
IF_CONF
(
ifp
,
faraway
)
==
CONFIG_YES
)
net
->
flags
|=
NET
_FARAWAY
;
ifp
->
flags
|=
IF
_FARAWAY
;
net
->
activity_time
=
now
.
tv_sec
;
ifp
->
activity_time
=
now
.
tv_sec
;
update_hello_interval
(
net
);
update_hello_interval
(
ifp
);
/* Since the interface was marked as active above, the
/* Since the interface was marked as active above, the
idle_hello_interval cannot be the one being used here. */
idle_hello_interval cannot be the one being used here. */
net
->
update_interval
=
ifp
->
update_interval
=
NET_CONF
(
net
,
update_interval
)
>
0
?
IF_CONF
(
ifp
,
update_interval
)
>
0
?
NET_CONF
(
net
,
update_interval
)
:
IF_CONF
(
ifp
,
update_interval
)
:
net
->
hello_interval
*
4
;
ifp
->
hello_interval
*
4
;
memset
(
&
mreq
,
0
,
sizeof
(
mreq
));
memset
(
&
mreq
,
0
,
sizeof
(
mreq
));
memcpy
(
&
mreq
.
ipv6mr_multiaddr
,
protocol_group
,
16
);
memcpy
(
&
mreq
.
ipv6mr_multiaddr
,
protocol_group
,
16
);
mreq
.
ipv6mr_interface
=
net
->
ifindex
;
mreq
.
ipv6mr_interface
=
ifp
->
ifindex
;
rc
=
setsockopt
(
protocol_socket
,
IPPROTO_IPV6
,
IPV6_JOIN_GROUP
,
rc
=
setsockopt
(
protocol_socket
,
IPPROTO_IPV6
,
IPV6_JOIN_GROUP
,
(
char
*
)
&
mreq
,
sizeof
(
mreq
));
(
char
*
)
&
mreq
,
sizeof
(
mreq
));
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
perror
(
"setsockopt(IPV6_JOIN_GROUP)"
);
perror
(
"setsockopt(IPV6_JOIN_GROUP)"
);
/* This is probably due to a missing link-local address,
/* This is probably due to a missing link-local address,
so down this
network
, and wait until the main loop
so down this
interface
, and wait until the main loop
tries to up it again. */
tries to up it again. */
return
network_up
(
net
,
0
);
return
interface_up
(
ifp
,
0
);
}
}
if
(
net
->
ll
)
if
(
ifp
->
ll
)
free
(
net
->
ll
);
free
(
ifp
->
ll
);
net
->
numll
=
0
;
ifp
->
numll
=
0
;
net
->
ll
=
NULL
;
ifp
->
ll
=
NULL
;
rc
=
kernel_addresses
(
net
->
ifname
,
net
->
ifindex
,
1
,
ll
,
32
);
rc
=
kernel_addresses
(
ifp
->
name
,
ifp
->
ifindex
,
1
,
ll
,
32
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
perror
(
"kernel_ll_addresses"
);
perror
(
"kernel_ll_addresses"
);
}
else
if
(
rc
>
0
)
{
}
else
if
(
rc
>
0
)
{
net
->
ll
=
malloc
(
16
*
rc
);
ifp
->
ll
=
malloc
(
16
*
rc
);
if
(
net
->
ll
==
NULL
)
{
if
(
ifp
->
ll
==
NULL
)
{
perror
(
"malloc(ll)"
);
perror
(
"malloc(ll)"
);
}
else
{
}
else
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
rc
;
i
++
)
for
(
i
=
0
;
i
<
rc
;
i
++
)
memcpy
(
net
->
ll
[
i
],
ll
[
i
].
prefix
,
16
);
memcpy
(
ifp
->
ll
[
i
],
ll
[
i
].
prefix
,
16
);
net
->
numll
=
rc
;
ifp
->
numll
=
rc
;
}
}
}
}
set_timeout
(
&
net
->
hello_timeout
,
net
->
hello_interval
);
set_timeout
(
&
ifp
->
hello_timeout
,
ifp
->
hello_interval
);
set_timeout
(
&
net
->
update_timeout
,
net
->
update_interval
);
set_timeout
(
&
ifp
->
update_timeout
,
ifp
->
update_interval
);
send_hello
(
net
);
send_hello
(
ifp
);
send_request
(
net
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
}
else
{
}
else
{
flush_
network_routes
(
net
,
0
);
flush_
interface_routes
(
ifp
,
0
);
net
->
buffered
=
0
;
ifp
->
buffered
=
0
;
net
->
bufsize
=
0
;
ifp
->
bufsize
=
0
;
free
(
net
->
sendbuf
);
free
(
ifp
->
sendbuf
);
net
->
num_buffered_updates
=
0
;
ifp
->
num_buffered_updates
=
0
;
net
->
update_bufsize
=
0
;
ifp
->
update_bufsize
=
0
;
if
(
net
->
buffered_updates
)
if
(
ifp
->
buffered_updates
)
free
(
net
->
buffered_updates
);
free
(
ifp
->
buffered_updates
);
net
->
buffered_updates
=
NULL
;
ifp
->
buffered_updates
=
NULL
;
net
->
sendbuf
=
NULL
;
ifp
->
sendbuf
=
NULL
;
if
(
net
->
ifindex
>
0
)
{
if
(
ifp
->
ifindex
>
0
)
{
memset
(
&
mreq
,
0
,
sizeof
(
mreq
));
memset
(
&
mreq
,
0
,
sizeof
(
mreq
));
memcpy
(
&
mreq
.
ipv6mr_multiaddr
,
protocol_group
,
16
);
memcpy
(
&
mreq
.
ipv6mr_multiaddr
,
protocol_group
,
16
);
mreq
.
ipv6mr_interface
=
net
->
ifindex
;
mreq
.
ipv6mr_interface
=
ifp
->
ifindex
;
rc
=
setsockopt
(
protocol_socket
,
IPPROTO_IPV6
,
IPV6_LEAVE_GROUP
,
rc
=
setsockopt
(
protocol_socket
,
IPPROTO_IPV6
,
IPV6_LEAVE_GROUP
,
(
char
*
)
&
mreq
,
sizeof
(
mreq
));
(
char
*
)
&
mreq
,
sizeof
(
mreq
));
if
(
rc
<
0
)
if
(
rc
<
0
)
perror
(
"setsockopt(IPV6_LEAVE_GROUP)"
);
perror
(
"setsockopt(IPV6_LEAVE_GROUP)"
);
kernel_setup_interface
(
0
,
net
->
ifname
,
net
->
ifindex
);
kernel_setup_interface
(
0
,
ifp
->
name
,
ifp
->
ifindex
);
}
}
if
(
net
->
ll
)
if
(
ifp
->
ll
)
free
(
net
->
ll
);
free
(
ifp
->
ll
);
net
->
ll
=
NULL
;
ifp
->
ll
=
NULL
;
net
->
numll
=
0
;
ifp
->
numll
=
0
;
}
}
check_
network_channel
(
net
);
check_
interface_channel
(
ifp
);
update_
network_metric
(
net
);
update_
interface_metric
(
ifp
);
rc
=
check_
network_ipv4
(
net
);
rc
=
check_
interface_ipv4
(
ifp
);
debugf
(
"Upped
network
%s (%s, cost=%d, channel=%d%s).
\n
"
,
debugf
(
"Upped
interface
%s (%s, cost=%d, channel=%d%s).
\n
"
,
net
->
if
name
,
ifp
->
name
,
(
net
->
flags
&
NET
_WIRED
)
?
"wired"
:
"wireless"
,
(
ifp
->
flags
&
IF
_WIRED
)
?
"wired"
:
"wireless"
,
net
->
cost
,
ifp
->
cost
,
net
->
channel
,
ifp
->
channel
,
net
->
ipv4
?
", IPv4"
:
""
);
ifp
->
ipv4
?
", IPv4"
:
""
);
if
(
up
&&
rc
>
0
)
if
(
up
&&
rc
>
0
)
send_update
(
net
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
);
return
1
;
return
1
;
}
}
int
int
network_ll_address
(
struct
network
*
net
,
const
unsigned
char
*
address
)
interface_ll_address
(
struct
interface
*
ifp
,
const
unsigned
char
*
address
)
{
{
int
i
;
int
i
;
if
(
!
net_up
(
net
))
if
(
!
if_up
(
ifp
))
return
0
;
return
0
;
for
(
i
=
0
;
i
<
net
->
numll
;
i
++
)
for
(
i
=
0
;
i
<
ifp
->
numll
;
i
++
)
if
(
memcmp
(
net
->
ll
[
i
],
address
,
16
)
==
0
)
if
(
memcmp
(
ifp
->
ll
[
i
],
address
,
16
)
==
0
)
return
1
;
return
1
;
return
0
;
return
0
;
}
}
void
void
check_
network
s
(
void
)
check_
interface
s
(
void
)
{
{
struct
network
*
net
;
struct
interface
*
ifp
;
int
rc
,
ifindex
,
ifindex_changed
=
0
;
int
rc
,
ifindex
,
ifindex_changed
=
0
;
FOR_ALL_
NETS
(
net
)
{
FOR_ALL_
INTERFACES
(
ifp
)
{
ifindex
=
if_nametoindex
(
net
->
if
name
);
ifindex
=
if_nametoindex
(
ifp
->
name
);
if
(
ifindex
!=
net
->
ifindex
)
{
if
(
ifindex
!=
ifp
->
ifindex
)
{
debugf
(
"Noticed ifindex change for %s.
\n
"
,
net
->
if
name
);
debugf
(
"Noticed ifindex change for %s.
\n
"
,
ifp
->
name
);
net
->
ifindex
=
0
;
ifp
->
ifindex
=
0
;
network_up
(
net
,
0
);
interface_up
(
ifp
,
0
);
net
->
ifindex
=
ifindex
;
ifp
->
ifindex
=
ifindex
;
ifindex_changed
=
1
;
ifindex_changed
=
1
;
}
}
if
(
net
->
ifindex
>
0
)
if
(
ifp
->
ifindex
>
0
)
rc
=
kernel_interface_operational
(
net
->
ifname
,
net
->
ifindex
);
rc
=
kernel_interface_operational
(
ifp
->
name
,
ifp
->
ifindex
);
else
else
rc
=
0
;
rc
=
0
;
if
((
rc
>
0
)
!=
net_up
(
net
))
{
if
((
rc
>
0
)
!=
if_up
(
ifp
))
{
debugf
(
"Noticed status change for %s.
\n
"
,
net
->
if
name
);
debugf
(
"Noticed status change for %s.
\n
"
,
ifp
->
name
);
network_up
(
net
,
rc
>
0
);
interface_up
(
ifp
,
rc
>
0
);
}
}
check_
network_channel
(
net
);
check_
interface_channel
(
ifp
);
rc
=
check_
network_ipv4
(
net
);
rc
=
check_
interface_ipv4
(
ifp
);
if
(
rc
>
0
)
{
if
(
rc
>
0
)
{
send_request
(
net
,
NULL
,
0
);
send_request
(
ifp
,
NULL
,
0
);
send_update
(
net
,
0
,
NULL
,
0
);
send_update
(
ifp
,
0
,
NULL
,
0
);
}
}
}
}
...
...
network.h
View file @
1c3b2bb8
...
@@ -27,7 +27,7 @@ struct buffered_update {
...
@@ -27,7 +27,7 @@ struct buffered_update {
unsigned
char
pad
[
3
];
unsigned
char
pad
[
3
];
};
};
struct
network
_conf
{
struct
interface
_conf
{
char
*
ifname
;
char
*
ifname
;
unsigned
hello_interval
;
unsigned
hello_interval
;
unsigned
update_interval
;
unsigned
update_interval
;
...
@@ -37,27 +37,27 @@ struct network_conf {
...
@@ -37,27 +37,27 @@ struct network_conf {
char
lq
;
char
lq
;
char
faraway
;
char
faraway
;
int
channel
;
int
channel
;
struct
network
_conf
*
next
;
struct
interface
_conf
*
next
;
};
};
#define CONFIG_DEFAULT 0
#define CONFIG_DEFAULT 0
#define CONFIG_NO 1
#define CONFIG_NO 1
#define CONFIG_YES 2
#define CONFIG_YES 2
#define
NET
_UP (1 << 0)
#define
IF
_UP (1 << 0)
#define
NET
_WIRED (1<<1)
#define
IF
_WIRED (1<<1)
#define
NET
_SPLIT_HORIZON (1 << 2)
#define
IF
_SPLIT_HORIZON (1 << 2)
#define
NET
_LQ (1 << 3)
#define
IF
_LQ (1 << 3)
#define
NET
_FARAWAY (1 << 4)
#define
IF
_FARAWAY (1 << 4)
/* Only INTERFERING can appear on the wire. */
/* Only INTERFERING can appear on the wire. */
#define
NET
_CHANNEL_UNKNOWN 0
#define
IF
_CHANNEL_UNKNOWN 0
#define
NET
_CHANNEL_INTERFERING 255
#define
IF
_CHANNEL_INTERFERING 255
#define
NET
_CHANNEL_NONINTERFERING -2
#define
IF
_CHANNEL_NONINTERFERING -2
struct
network
{
struct
interface
{
struct
network
*
next
;
struct
interface
*
next
;
struct
network
_conf
*
conf
;
struct
interface
_conf
*
conf
;
unsigned
int
ifindex
;
unsigned
int
ifindex
;
unsigned
short
flags
;
unsigned
short
flags
;
unsigned
short
cost
;
unsigned
short
cost
;
...
@@ -66,7 +66,7 @@ struct network {
...
@@ -66,7 +66,7 @@ struct network {
struct
timeval
update_timeout
;
struct
timeval
update_timeout
;
struct
timeval
flush_timeout
;
struct
timeval
flush_timeout
;
struct
timeval
update_flush_timeout
;
struct
timeval
update_flush_timeout
;
char
if
name
[
IF_NAMESIZE
];
char
name
[
IF_NAMESIZE
];
unsigned
char
*
ipv4
;
unsigned
char
*
ipv4
;
int
numll
;
int
numll
;
unsigned
char
(
*
ll
)[
16
];
unsigned
char
(
*
ll
)[
16
];
...
@@ -91,26 +91,25 @@ struct network {
...
@@ -91,26 +91,25 @@ struct network {
unsigned
update_interval
;
unsigned
update_interval
;
};
};
#define
NET_CONF(_net
, _field) \
#define
IF_CONF(_ifp
, _field) \
((_
net)->conf ? (_net
)->conf->_field : 0)
((_
ifp)->conf ? (_ifp
)->conf->_field : 0)
extern
struct
network
*
networks
;
extern
struct
interface
*
interfaces
;
extern
int
numnets
;
#define FOR_ALL_
NETS(_net) for(_net = networks; _net; _net = _net
->next)
#define FOR_ALL_
INTERFACES(_ifp) for(_ifp = interfaces; _ifp; _ifp = _ifp
->next)
static
inline
int
static
inline
int
net_up
(
struct
network
*
net
)
if_up
(
struct
interface
*
ifp
)
{
{
return
!!
(
net
->
flags
&
NET
_UP
);
return
!!
(
ifp
->
flags
&
IF
_UP
);
}
}
struct
network
*
add_network
(
char
*
ifname
,
struct
network_conf
*
conf
);
struct
interface
*
add_interface
(
char
*
ifname
,
struct
interface_conf
*
if_
conf
);
int
network_idle
(
struct
network
*
net
);
int
interface_idle
(
struct
interface
*
ifp
);
int
update_hello_interval
(
struct
network
*
net
);
int
update_hello_interval
(
struct
interface
*
ifp
);
unsigned
jitter
(
struct
network
*
net
,
int
urgent
);
unsigned
jitter
(
struct
interface
*
ifp
,
int
urgent
);
unsigned
update_jitter
(
struct
network
*
net
,
int
urgent
);
unsigned
update_jitter
(
struct
interface
*
ifp
,
int
urgent
);
void
set_timeout
(
struct
timeval
*
timeout
,
int
msecs
);
void
set_timeout
(
struct
timeval
*
timeout
,
int
msecs
);
int
network_up
(
struct
network
*
net
,
int
up
);
int
interface_up
(
struct
interface
*
ifp
,
int
up
);
int
network_ll_address
(
struct
network
*
net
,
const
unsigned
char
*
address
);
int
interface_ll_address
(
struct
interface
*
ifp
,
const
unsigned
char
*
address
);
void
check_
network
s
(
void
);
void
check_
interface
s
(
void
);
resend.c
View file @
1c3b2bb8
...
@@ -83,10 +83,10 @@ find_request(const unsigned char *prefix, unsigned char plen,
...
@@ -83,10 +83,10 @@ 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
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
network
*
network
,
int
delay
)
struct
interface
*
ifp
,
int
delay
)
{
{
struct
resend
*
resend
;
struct
resend
*
resend
;
unsigned
int
ifindex
=
network
?
network
->
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
,
ifindex
)
>=
INFINITY
)
||
...
@@ -114,8 +114,8 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
...
@@ -114,8 +114,8 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
else
else
memset
(
resend
->
id
,
0
,
8
);
memset
(
resend
->
id
,
0
,
8
);
resend
->
seqno
=
seqno
;
resend
->
seqno
=
seqno
;
if
(
resend
->
network
!=
network
)
if
(
resend
->
ifp
!=
ifp
)
resend
->
network
=
NULL
;
resend
->
ifp
=
NULL
;
}
else
{
}
else
{
resend
=
malloc
(
sizeof
(
struct
resend
));
resend
=
malloc
(
sizeof
(
struct
resend
));
if
(
resend
==
NULL
)
if
(
resend
==
NULL
)
...
@@ -130,7 +130,7 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
...
@@ -130,7 +130,7 @@ record_resend(int kind, const unsigned char *prefix, unsigned char plen,
memcpy
(
resend
->
id
,
id
,
8
);
memcpy
(
resend
->
id
,
id
,
8
);
else
else
memset
(
resend
->
id
,
0
,
8
);
memset
(
resend
->
id
,
0
,
8
);
resend
->
network
=
network
;
resend
->
ifp
=
ifp
;
resend
->
time
=
now
;
resend
->
time
=
now
;
resend
->
next
=
to_resend
;
resend
->
next
=
to_resend
;
to_resend
=
resend
;
to_resend
=
resend
;
...
@@ -174,7 +174,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
...
@@ -174,7 +174,7 @@ unsatisfied_request(const unsigned char *prefix, unsigned char plen,
/* Determine whether a given request should be forwarded. */
/* Determine whether a given request should be forwarded. */
int
int
request_redundant
(
struct
network
*
net
,
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
)
{
{
...
@@ -188,7 +188,7 @@ request_redundant(struct network *net,
...
@@ -188,7 +188,7 @@ request_redundant(struct network *net,
seqno_compare
(
request
->
seqno
,
seqno
)
>
0
)
seqno_compare
(
request
->
seqno
,
seqno
)
>
0
)
return
0
;
return
0
;
if
(
request
->
network
!=
NULL
&&
request
->
network
!=
net
)
if
(
request
->
ifp
!=
NULL
&&
request
->
ifp
!=
ifp
)
return
0
;
return
0
;
if
(
request
->
max
>
0
)
if
(
request
->
max
>
0
)
...
@@ -196,7 +196,7 @@ request_redundant(struct network *net,
...
@@ -196,7 +196,7 @@ request_redundant(struct network *net,
return
1
;
return
1
;
if
(
timeval_minus_msec
(
&
now
,
&
request
->
time
)
<
if
(
timeval_minus_msec
(
&
now
,
&
request
->
time
)
<
(
net
?
MIN
(
net
->
hello_interval
,
1000
)
:
1000
))
(
ifp
?
MIN
(
ifp
->
hello_interval
,
1000
)
:
1000
))
/* Fairly recent. */
/* Fairly recent. */
return
1
;
return
1
;
...
@@ -206,7 +206,7 @@ request_redundant(struct network *net,
...
@@ -206,7 +206,7 @@ request_redundant(struct network *net,
int
int
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
satisfy_request
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
network
*
network
)
struct
interface
*
ifp
)
{
{
struct
resend
*
request
,
*
previous
;
struct
resend
*
request
,
*
previous
;
...
@@ -214,7 +214,7 @@ satisfy_request(const unsigned char *prefix, unsigned char plen,
...
@@ -214,7 +214,7 @@ satisfy_request(const unsigned char *prefix, unsigned char plen,
if
(
request
==
NULL
)
if
(
request
==
NULL
)
return
0
;
return
0
;
if
(
network
!=
NULL
&&
request
->
network
!=
network
)
if
(
ifp
!=
NULL
&&
request
->
ifp
!=
ifp
)
return
0
;
return
0
;
if
(
memcmp
(
request
->
id
,
id
,
8
)
!=
0
||
if
(
memcmp
(
request
->
id
,
id
,
8
)
!=
0
||
...
@@ -291,12 +291,12 @@ do_resend()
...
@@ -291,12 +291,12 @@ do_resend()
if
(
timeval_compare
(
&
now
,
&
timeout
)
>=
0
)
{
if
(
timeval_compare
(
&
now
,
&
timeout
)
>=
0
)
{
switch
(
resend
->
kind
)
{
switch
(
resend
->
kind
)
{
case
RESEND_REQUEST
:
case
RESEND_REQUEST
:
send_multihop_request
(
resend
->
network
,
send_multihop_request
(
resend
->
ifp
,
resend
->
prefix
,
resend
->
plen
,
resend
->
prefix
,
resend
->
plen
,
resend
->
seqno
,
resend
->
id
,
127
);
resend
->
seqno
,
resend
->
id
,
127
);
break
;
break
;
case
RESEND_UPDATE
:
case
RESEND_UPDATE
:
send_update
(
resend
->
network
,
1
,
send_update
(
resend
->
ifp
,
1
,
resend
->
prefix
,
resend
->
plen
);
resend
->
prefix
,
resend
->
plen
);
break
;
break
;
default:
abort
();
default:
abort
();
...
...
resend.h
View file @
1c3b2bb8
...
@@ -35,7 +35,7 @@ struct resend {
...
@@ -35,7 +35,7 @@ struct resend {
unsigned
char
plen
;
unsigned
char
plen
;
unsigned
short
seqno
;
unsigned
short
seqno
;
unsigned
char
id
[
8
];
unsigned
char
id
[
8
];
struct
network
*
network
;
struct
interface
*
ifp
;
struct
resend
*
next
;
struct
resend
*
next
;
};
};
...
@@ -46,15 +46,15 @@ struct resend *find_request(const unsigned char *prefix, unsigned char plen,
...
@@ -46,15 +46,15 @@ struct resend *find_request(const unsigned char *prefix, unsigned char plen,
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
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
network
*
net
,
int
delay
);
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
network
*
net
,
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
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
unsigned
short
seqno
,
const
unsigned
char
*
id
,
struct
network
*
net
);
struct
interface
*
ifp
);
void
expire_resend
(
void
);
void
expire_resend
(
void
);
void
recompute_resend_time
(
void
);
void
recompute_resend_time
(
void
);
...
...
route.c
View file @
1c3b2bb8
...
@@ -134,13 +134,13 @@ flush_neighbour_routes(struct neighbour *neigh)
...
@@ -134,13 +134,13 @@ flush_neighbour_routes(struct neighbour *neigh)
}
}
void
void
flush_
network_routes
(
struct
network
*
net
,
int
v4only
)
flush_
interface_routes
(
struct
interface
*
ifp
,
int
v4only
)
{
{
int
i
;
int
i
;
i
=
0
;
i
=
0
;
while
(
i
<
numroutes
)
{
while
(
i
<
numroutes
)
{
if
(
routes
[
i
].
neigh
->
network
==
net
&&
if
(
routes
[
i
].
neigh
->
ifp
==
ifp
&&
(
!
v4only
||
v4mapped
(
routes
[
i
].
nexthop
)))
{
(
!
v4only
||
v4mapped
(
routes
[
i
].
nexthop
)))
{
flush_route
(
&
routes
[
i
]);
flush_route
(
&
routes
[
i
]);
continue
;
continue
;
...
@@ -169,7 +169,7 @@ install_route(struct route *route)
...
@@ -169,7 +169,7 @@ install_route(struct route *route)
rc
=
kernel_route
(
ROUTE_ADD
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_ADD
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
nexthop
,
route
->
nexthop
,
route
->
neigh
->
network
->
ifindex
,
route
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
int
save
=
errno
;
int
save
=
errno
;
...
@@ -191,7 +191,7 @@ uninstall_route(struct route *route)
...
@@ -191,7 +191,7 @@ uninstall_route(struct route *route)
rc
=
kernel_route
(
ROUTE_FLUSH
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
rc
=
kernel_route
(
ROUTE_FLUSH
,
route
->
src
->
prefix
,
route
->
src
->
plen
,
route
->
nexthop
,
route
->
nexthop
,
route
->
neigh
->
network
->
ifindex
,
route
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
metric_to_kernel
(
route_metric
(
route
)),
NULL
,
0
,
0
);
if
(
rc
<
0
)
if
(
rc
<
0
)
perror
(
"kernel_route(FLUSH)"
);
perror
(
"kernel_route(FLUSH)"
);
...
@@ -222,9 +222,9 @@ switch_routes(struct route *old, struct route *new)
...
@@ -222,9 +222,9 @@ switch_routes(struct route *old, struct 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
,
old
->
nexthop
,
old
->
neigh
->
network
->
ifindex
,
old
->
nexthop
,
old
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
old
)),
metric_to_kernel
(
route_metric
(
old
)),
new
->
nexthop
,
new
->
neigh
->
network
->
ifindex
,
new
->
nexthop
,
new
->
neigh
->
ifp
->
ifindex
,
metric_to_kernel
(
route_metric
(
new
)));
metric_to_kernel
(
route_metric
(
new
)));
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
perror
(
"kernel_route(MODIFY)"
);
perror
(
"kernel_route(MODIFY)"
);
...
@@ -251,9 +251,9 @@ change_route_metric(struct route *route,
...
@@ -251,9 +251,9 @@ change_route_metric(struct 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
,
route
->
nexthop
,
route
->
neigh
->
network
->
ifindex
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
old
,
old
,
route
->
nexthop
,
route
->
neigh
->
network
->
ifindex
,
route
->
nexthop
,
route
->
neigh
->
ifp
->
ifindex
,
new
);
new
);
if
(
rc
<
0
)
{
if
(
rc
<
0
)
{
perror
(
"kernel_route(MODIFY metric)"
);
perror
(
"kernel_route(MODIFY metric)"
);
...
@@ -294,33 +294,33 @@ route_expired(struct route *route)
...
@@ -294,33 +294,33 @@ route_expired(struct route *route)
static
int
static
int
channels_interfere
(
int
ch1
,
int
ch2
)
channels_interfere
(
int
ch1
,
int
ch2
)
{
{
if
(
ch1
==
NET_CHANNEL_NONINTERFERING
||
ch2
==
NET
_CHANNEL_NONINTERFERING
)
if
(
ch1
==
IF_CHANNEL_NONINTERFERING
||
ch2
==
IF
_CHANNEL_NONINTERFERING
)
return
0
;
return
0
;
if
(
ch1
==
NET_CHANNEL_INTERFERING
||
ch2
==
NET
_CHANNEL_INTERFERING
)
if
(
ch1
==
IF_CHANNEL_INTERFERING
||
ch2
==
IF
_CHANNEL_INTERFERING
)
return
1
;
return
1
;
return
ch1
==
ch2
;
return
ch1
==
ch2
;
}
}
int
int
route_interferes
(
struct
route
*
route
,
struct
network
*
net
)
route_interferes
(
struct
route
*
route
,
struct
interface
*
ifp
)
{
{
switch
(
diversity_kind
)
{
switch
(
diversity_kind
)
{
case
DIVERSITY_NONE
:
case
DIVERSITY_NONE
:
return
1
;
return
1
;
case
DIVERSITY_INTERFACE_1
:
case
DIVERSITY_INTERFACE_1
:
return
route
->
neigh
->
network
==
net
;
return
route
->
neigh
->
ifp
==
ifp
;
case
DIVERSITY_CHANNEL_1
:
case
DIVERSITY_CHANNEL_1
:
case
DIVERSITY_CHANNEL
:
case
DIVERSITY_CHANNEL
:
if
(
route
->
neigh
->
network
==
net
)
if
(
route
->
neigh
->
ifp
==
ifp
)
return
1
;
return
1
;
if
(
channels_interfere
(
net
->
channel
,
route
->
neigh
->
network
->
channel
))
if
(
channels_interfere
(
ifp
->
channel
,
route
->
neigh
->
ifp
->
channel
))
return
1
;
return
1
;
if
(
diversity_kind
==
DIVERSITY_CHANNEL
)
{
if
(
diversity_kind
==
DIVERSITY_CHANNEL
)
{
int
i
;
int
i
;
for
(
i
=
0
;
i
<
DIVERSITY_HOPS
;
i
++
)
{
for
(
i
=
0
;
i
<
DIVERSITY_HOPS
;
i
++
)
{
if
(
route
->
channels
[
i
]
==
0
)
if
(
route
->
channels
[
i
]
==
0
)
break
;
break
;
if
(
channels_interfere
(
net
->
channel
,
route
->
channels
[
i
]))
if
(
channels_interfere
(
ifp
->
channel
,
route
->
channels
[
i
]))
return
1
;
return
1
;
}
}
}
}
...
@@ -391,7 +391,7 @@ update_route_metric(struct route *route)
...
@@ -391,7 +391,7 @@ update_route_metric(struct route *route)
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
,
neigh
->
address
,
neigh
->
address
,
neigh
->
network
->
ifindex
);
neigh
->
ifp
->
ifindex
);
change_route_metric
(
route
,
route
->
refmetric
,
change_route_metric
(
route
,
route
->
refmetric
,
neighbour_cost
(
route
->
neigh
),
add_metric
);
neighbour_cost
(
route
->
neigh
),
add_metric
);
if
(
route_metric
(
route
)
!=
oldmetric
)
if
(
route_metric
(
route
)
!=
oldmetric
)
...
@@ -420,13 +420,13 @@ update_neighbour_metric(struct neighbour *neigh, int changed)
...
@@ -420,13 +420,13 @@ update_neighbour_metric(struct neighbour *neigh, int changed)
}
}
void
void
update_
network_metric
(
struct
network
*
net
)
update_
interface_metric
(
struct
interface
*
ifp
)
{
{
int
i
;
int
i
;
i
=
0
;
i
=
0
;
while
(
i
<
numroutes
)
{
while
(
i
<
numroutes
)
{
if
(
routes
[
i
].
neigh
->
network
==
net
)
if
(
routes
[
i
].
neigh
->
ifp
==
ifp
)
update_route_metric
(
&
routes
[
i
]);
update_route_metric
(
&
routes
[
i
]);
i
++
;
i
++
;
}
}
...
@@ -456,7 +456,7 @@ update_route(const unsigned char *a, const unsigned char *p, unsigned char plen,
...
@@ -456,7 +456,7 @@ update_route(const unsigned char *a, const unsigned char *p, unsigned char plen,
}
}
add_metric
=
input_filter
(
a
,
p
,
plen
,
add_metric
=
input_filter
(
a
,
p
,
plen
,
neigh
->
address
,
neigh
->
network
->
ifindex
);
neigh
->
address
,
neigh
->
ifp
->
ifindex
);
if
(
add_metric
>=
INFINITY
)
if
(
add_metric
>=
INFINITY
)
return
NULL
;
return
NULL
;
...
...
route.h
View file @
1c3b2bb8
...
@@ -71,14 +71,14 @@ struct route *find_installed_route(const unsigned char *prefix,
...
@@ -71,14 +71,14 @@ struct route *find_installed_route(const unsigned char *prefix,
unsigned
char
plen
);
unsigned
char
plen
);
void
flush_route
(
struct
route
*
route
);
void
flush_route
(
struct
route
*
route
);
void
flush_neighbour_routes
(
struct
neighbour
*
neigh
);
void
flush_neighbour_routes
(
struct
neighbour
*
neigh
);
void
flush_
network_routes
(
struct
network
*
net
,
int
v4only
);
void
flush_
interface_routes
(
struct
interface
*
ifp
,
int
v4only
);
void
install_route
(
struct
route
*
route
);
void
install_route
(
struct
route
*
route
);
void
uninstall_route
(
struct
route
*
route
);
void
uninstall_route
(
struct
route
*
route
);
void
switch_route
(
struct
route
*
old
,
struct
route
*
new
);
void
switch_route
(
struct
route
*
old
,
struct
route
*
new
);
int
route_feasible
(
struct
route
*
route
);
int
route_feasible
(
struct
route
*
route
);
int
route_old
(
struct
route
*
route
);
int
route_old
(
struct
route
*
route
);
int
route_expired
(
struct
route
*
route
);
int
route_expired
(
struct
route
*
route
);
int
route_interferes
(
struct
route
*
route
,
struct
network
*
net
);
int
route_interferes
(
struct
route
*
route
,
struct
interface
*
ifp
);
int
update_feasible
(
struct
source
*
src
,
int
update_feasible
(
struct
source
*
src
,
unsigned
short
seqno
,
unsigned
short
refmetric
);
unsigned
short
seqno
,
unsigned
short
refmetric
);
struct
route
*
find_best_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
struct
route
*
find_best_route
(
const
unsigned
char
*
prefix
,
unsigned
char
plen
,
...
@@ -86,7 +86,7 @@ struct route *find_best_route(const unsigned char *prefix, unsigned char plen,
...
@@ -86,7 +86,7 @@ struct route *find_best_route(const unsigned char *prefix, unsigned char plen,
struct
route
*
install_best_route
(
const
unsigned
char
prefix
[
16
],
struct
route
*
install_best_route
(
const
unsigned
char
prefix
[
16
],
unsigned
char
plen
);
unsigned
char
plen
);
void
update_neighbour_metric
(
struct
neighbour
*
neigh
,
int
changed
);
void
update_neighbour_metric
(
struct
neighbour
*
neigh
,
int
changed
);
void
update_
network_metric
(
struct
network
*
net
);
void
update_
interface_metric
(
struct
interface
*
ifp
);
void
update_route_metric
(
struct
route
*
route
);
void
update_route_metric
(
struct
route
*
route
);
struct
route
*
update_route
(
const
unsigned
char
*
a
,
struct
route
*
update_route
(
const
unsigned
char
*
a
,
const
unsigned
char
*
p
,
unsigned
char
plen
,
const
unsigned
char
*
p
,
unsigned
char
plen
,
...
...
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