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