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
dac97fdf
Commit
dac97fdf
authored
Jan 22, 2018
by
Juliusz Chroboczek
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'rfc6126bis'
parents
6f3b45bb
13f0c503
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
199 additions
and
112 deletions
+199
-112
babeld.c
babeld.c
+5
-7
babeld.man
babeld.man
+0
-5
configuration.c
configuration.c
+3
-7
local.c
local.c
+4
-2
message.c
message.c
+111
-26
neighbour.c
neighbour.c
+64
-55
neighbour.h
neighbour.h
+11
-5
route.c
route.c
+1
-4
route.h
route.h
+0
-1
No files found.
babeld.c
View file @
dac97fdf
...
...
@@ -172,7 +172,7 @@ main(int argc, char **argv)
while
(
1
)
{
opt
=
getopt
(
argc
,
argv
,
"m:p:h:H:i:k:A:sr
u
S:d:g:G:lwz:M:t:T:c:C:DL:I:V"
);
"m:p:h:H:i:k:A:srS:d:g:G:lwz:M:t:T:c:C:DL:I:V"
);
if
(
opt
<
0
)
break
;
...
...
@@ -225,9 +225,6 @@ main(int argc, char **argv)
case
'r'
:
random_id
=
1
;
break
;
case
'u'
:
keep_unfeasible
=
1
;
break
;
case
'S'
:
state_file
=
optarg
;
break
;
...
...
@@ -1116,11 +1113,12 @@ dump_tables(FILE *out)
fprintf
(
out
,
"My id %s seqno %d
\n
"
,
format_eui64
(
myid
),
myseqno
);
FOR_ALL_NEIGHBOURS
(
neigh
)
{
fprintf
(
out
,
"Neighbour %s dev %s reach %04x
rxcost %d txcost %d
"
"rtt %s rttcost %d chan %d%s.
\n
"
,
fprintf
(
out
,
"Neighbour %s dev %s reach %04x
ureach %04x
"
"r
xcost %d txcost %d r
tt %s rttcost %d chan %d%s.
\n
"
,
format_address
(
neigh
->
address
),
neigh
->
ifp
->
name
,
neigh
->
reach
,
neigh
->
hello
.
reach
,
neigh
->
uhello
.
reach
,
neighbour_rxcost
(
neigh
),
neigh
->
txcost
,
format_thousands
(
neigh
->
rtt
),
...
...
babeld.man
View file @
dac97fdf
...
...
@@ -196,11 +196,6 @@ at least
Do not use this option unless you know what you are doing, as it can
cause persistent route flapping.
.TP
.BR keep-unfeasible " {" true | false }
This specifies whether to keep unfeasible (useless) routes, and is
equivalent to the command-line option
.BR \-u .
.TP
.BR random-id " {" true | false }
This specifies whether to use a random router-id, and is
equivalent to the command-line option
...
...
configuration.c
View file @
dac97fdf
...
...
@@ -755,8 +755,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
because they require no special setup or because there is special
case code for them. */
if
(
config_finalised
)
{
if
(
strcmp
(
token
,
"keep-unfeasible"
)
!=
0
&&
strcmp
(
token
,
"link-detect"
)
!=
0
&&
if
(
strcmp
(
token
,
"link-detect"
)
!=
0
&&
strcmp
(
token
,
"log-file"
)
!=
0
&&
strcmp
(
token
,
"diversity"
)
!=
0
&&
strcmp
(
token
,
"diversity-factor"
)
!=
0
&&
...
...
@@ -798,8 +797,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
add_import_table
(
v
);
else
abort
();
}
else
if
(
strcmp
(
token
,
"keep-unfeasible"
)
==
0
||
strcmp
(
token
,
"link-detect"
)
==
0
||
}
else
if
(
strcmp
(
token
,
"link-detect"
)
==
0
||
strcmp
(
token
,
"random-id"
)
==
0
||
strcmp
(
token
,
"daemonise"
)
==
0
||
strcmp
(
token
,
"skip-kernel-setup"
)
==
0
||
...
...
@@ -810,9 +808,7 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
if
(
c
<
-
1
)
goto
error
;
b
=
(
b
==
CONFIG_YES
);
if
(
strcmp
(
token
,
"keep-unfeasible"
)
==
0
)
keep_unfeasible
=
b
;
else
if
(
strcmp
(
token
,
"link-detect"
)
==
0
)
if
(
strcmp
(
token
,
"link-detect"
)
==
0
)
link_detect
=
b
;
else
if
(
strcmp
(
token
,
"random-id"
)
==
0
)
random_id
=
b
;
...
...
local.c
View file @
dac97fdf
...
...
@@ -153,14 +153,16 @@ local_notify_neighbour_1(struct local_socket *s,
rc
=
snprintf
(
buf
,
512
,
"%s neighbour %lx address %s "
"if %s reach %04x rxcost %d txcost %d%s cost %d
\n
"
,
"if %s reach %04x ureach %04x "
"rxcost %d txcost %d%s cost %d
\n
"
,
local_kind
(
kind
),
/* Neighbours never move around in memory , so we can use the
address as a unique identifier. */
(
unsigned
long
int
)
neigh
,
format_address
(
neigh
->
address
),
neigh
->
ifp
->
name
,
neigh
->
reach
,
neigh
->
hello
.
reach
,
neigh
->
uhello
.
reach
,
neighbour_rxcost
(
neigh
),
neighbour_txcost
(
neigh
),
rttbuf
,
...
...
message.c
View file @
dac97fdf
...
...
@@ -165,7 +165,10 @@ parse_update_subtlv(struct interface *ifp, int metric,
memcpy
(
channels
,
a
+
i
+
2
,
MIN
(
len
,
*
channels_len_return
));
channels_len
=
MIN
(
len
,
*
channels_len_return
);
}
else
{
debugf
(
"Received unknown update sub-TLV %d.
\n
"
,
type
);
debugf
(
"Received unknown%s Update sub-TLV %d.
\n
"
,
(
type
&
0x80
)
!=
0
?
" mandatory"
:
""
,
type
);
if
((
type
&
0x80
)
!=
0
)
return
-
1
;
}
i
+=
len
+
2
;
...
...
@@ -210,7 +213,10 @@ parse_hello_subtlv(const unsigned char *a, int alen,
/* But don't break. */
}
}
else
{
debugf
(
"Received unknown Hello sub-TLV type %d.
\n
"
,
type
);
debugf
(
"Received unknown%s Hello sub-TLV %d.
\n
"
,
(
type
&
0x80
)
!=
0
?
" mandatory"
:
""
,
type
);
if
((
type
&
0x80
)
!=
0
)
return
-
1
;
}
i
+=
len
+
2
;
...
...
@@ -262,7 +268,10 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
/* But don't break. */
}
}
else
{
debugf
(
"Received unknown IHU sub-TLV type %d.
\n
"
,
type
);
debugf
(
"Received unknown%s IHU sub-TLV %d.
\n
"
,
(
type
&
0x80
)
!=
0
?
" mandatory"
:
""
,
type
);
if
((
type
&
0x80
)
!=
0
)
return
-
1
;
}
i
+=
len
+
2
;
...
...
@@ -277,6 +286,38 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
return
1
;
}
static
int
parse_other_subtlv
(
const
unsigned
char
*
a
,
int
alen
)
{
int
type
,
len
,
i
=
0
;
while
(
i
<
alen
)
{
type
=
a
[
0
];
if
(
type
==
SUBTLV_PAD1
)
{
i
++
;
continue
;
}
if
(
i
+
1
>
alen
)
{
fprintf
(
stderr
,
"Received truncated sub-TLV.
\n
"
);
return
-
1
;
}
len
=
a
[
i
+
1
];
if
(
i
+
len
>
alen
)
{
fprintf
(
stderr
,
"Received truncated sub-TLV.
\n
"
);
return
-
1
;
}
if
((
type
&
0x80
)
!=
0
)
{
debugf
(
"Received unknown mandatory sub-TLV %d.
\n
"
,
type
);
return
-
1
;
}
i
+=
len
+
2
;
}
return
1
;
}
static
int
network_address
(
int
ae
,
const
unsigned
char
*
a
,
unsigned
int
len
,
unsigned
char
*
a_r
)
...
...
@@ -364,41 +405,52 @@ parse_packet(const unsigned char *from, struct interface *ifp,
len
,
format_address
(
from
),
ifp
->
name
);
}
else
if
(
type
==
MESSAGE_ACK_REQ
)
{
unsigned
short
nonce
,
interval
;
int
rc
;
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
),
ifp
->
name
);
rc
=
parse_other_subtlv
(
message
+
8
,
len
-
6
);
if
(
rc
<
0
)
goto
done
;
send_ack
(
neigh
,
nonce
,
interval
);
}
else
if
(
type
==
MESSAGE_ACK
)
{
int
rc
;
debugf
(
"Received ack from %s on %s.
\n
"
,
format_address
(
from
),
ifp
->
name
);
rc
=
parse_other_subtlv
(
message
+
4
,
len
-
2
);
if
(
rc
<
0
)
goto
done
;
/* Nothing right now */
}
else
if
(
type
==
MESSAGE_HELLO
)
{
unsigned
short
seqno
,
interval
;
int
changed
,
have_timestamp
;
int
unicast
,
changed
,
have_timestamp
,
rc
;
unsigned
int
timestamp
;
if
(
len
<
6
)
goto
fail
;
unicast
=
!!
(
message
[
2
]
&
0x80
);
DO_NTOHS
(
seqno
,
message
+
4
);
DO_NTOHS
(
interval
,
message
+
6
);
debugf
(
"Received hello %d (%d) from %s on %s.
\n
"
,
seqno
,
interval
,
format_address
(
from
),
ifp
->
name
);
changed
=
update_neighbour
(
neigh
,
seqno
,
interval
);
/* Sub-TLV handling. */
rc
=
parse_hello_subtlv
(
message
+
8
,
len
-
6
,
&
timestamp
,
&
have_timestamp
);
if
(
rc
<
0
)
goto
done
;
changed
=
update_neighbour
(
neigh
,
unicast
?
&
neigh
->
uhello
:
&
neigh
->
hello
,
unicast
,
seqno
,
interval
);
update_neighbour_metric
(
neigh
,
changed
);
if
(
interval
>
0
)
/* Multiply by 3/2 to allow hellos to expire. */
schedule_neighbours_check
(
interval
*
15
,
0
);
/* Sub-TLV handling. */
if
(
len
>
8
)
{
int
rc
;
rc
=
parse_hello_subtlv
(
message
+
8
,
len
-
6
,
&
timestamp
,
&
have_timestamp
);
if
(
rc
>=
0
&&
have_timestamp
)
{
neigh
->
hello_send_us
=
timestamp
;
neigh
->
hello_rtt_receive_time
=
now
;
have_hello_rtt
=
1
;
}
if
(
have_timestamp
)
{
neigh
->
hello_send_us
=
timestamp
;
neigh
->
hello_rtt_receive_time
=
now
;
have_hello_rtt
=
1
;
}
}
else
if
(
type
==
MESSAGE_IHU
)
{
unsigned
short
txcost
,
interval
;
...
...
@@ -414,7 +466,13 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_address
(
from
),
ifp
->
name
,
format_address
(
address
));
if
(
message
[
2
]
==
0
||
interface_ll_address
(
ifp
,
address
))
{
int
changed
=
txcost
!=
neigh
->
txcost
;
int
changed
;
rc
=
parse_ihu_subtlv
(
message
+
8
+
rc
,
len
-
6
-
rc
,
&
hello_send_us
,
&
hello_rtt_receive_time
,
NULL
);
if
(
rc
<
0
)
goto
done
;
changed
=
txcost
!=
neigh
->
txcost
;
neigh
->
txcost
=
txcost
;
neigh
->
ihu_time
=
now
;
neigh
->
ihu_interval
=
interval
;
...
...
@@ -422,13 +480,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
if
(
interval
>
0
)
/* Multiply by 3/2 to allow neighbours to expire. */
schedule_neighbours_check
(
interval
*
45
,
0
);
/* RTT sub-TLV. */
if
(
len
>
10
+
rc
)
parse_ihu_subtlv
(
message
+
8
+
rc
,
len
-
6
-
rc
,
&
hello_send_us
,
&
hello_rtt_receive_time
,
NULL
);
}
}
else
if
(
type
==
MESSAGE_ROUTER_ID
)
{
int
rc
;
if
(
len
<
10
)
{
have_router_id
=
0
;
goto
fail
;
...
...
@@ -437,6 +491,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
have_router_id
=
1
;
debugf
(
"Received router-id %s from %s on %s.
\n
"
,
format_eui64
(
router_id
),
format_address
(
from
),
ifp
->
name
);
rc
=
parse_other_subtlv
(
message
+
12
,
len
-
10
);
if
(
rc
<
0
)
goto
done
;
}
else
if
(
type
==
MESSAGE_NH
)
{
unsigned
char
nh
[
16
];
int
rc
;
...
...
@@ -462,6 +519,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
memcpy
(
v6_nh
,
nh
,
16
);
have_v6_nh
=
1
;
}
rc
=
parse_other_subtlv
(
message
+
4
+
rc
,
len
-
2
-
rc
);
if
(
rc
<
0
)
goto
done
;
}
else
if
(
type
==
MESSAGE_UPDATE
)
{
unsigned
char
prefix
[
16
],
src_prefix
[
16
],
*
nh
;
unsigned
char
plen
,
src_plen
;
...
...
@@ -530,6 +590,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_address
(
from
),
ifp
->
name
);
if
(
message
[
2
]
==
0
)
{
rc
=
parse_other_subtlv
(
message
+
12
,
len
-
10
);
if
(
rc
<
0
)
goto
done
;
if
(
metric
<
0xFFFF
)
{
fprintf
(
stderr
,
"Received wildcard update with finite metric.
\n
"
);
...
...
@@ -547,13 +610,16 @@ parse_packet(const unsigned char *from, struct interface *ifp,
nh
=
neigh
->
address
;
}
rc
=
parse_update_subtlv
(
ifp
,
metric
,
message
+
2
+
parsed_len
,
len
-
parsed_len
,
channels
,
&
channels_len
);
if
(
rc
<
0
)
goto
done
;
if
(
message
[
2
]
==
1
)
{
if
(
!
ifp
->
ipv4
)
goto
done
;
}
parse_update_subtlv
(
ifp
,
metric
,
message
+
2
+
parsed_len
,
len
-
parsed_len
,
channels
,
&
channels_len
);
update_route
(
router_id
,
prefix
,
plen
,
src_prefix
,
src_plen
,
seqno
,
metric
,
interval
,
neigh
,
nh
,
channels
,
channels_len
);
...
...
@@ -568,6 +634,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
debugf
(
"Received request for %s from %s on %s.
\n
"
,
message
[
2
]
==
0
?
"any"
:
format_prefix
(
prefix
,
plen
),
format_address
(
from
),
ifp
->
name
);
rc
=
parse_other_subtlv
(
message
+
4
+
rc
,
len
-
2
-
rc
);
if
(
rc
<
0
)
goto
done
;
if
(
message
[
2
]
==
0
)
{
/* If a neighbour is requesting a full route dump from us,
we might as well send it an IHU. */
...
...
@@ -598,6 +667,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
rc
=
network_prefix
(
message
[
2
],
message
[
3
],
0
,
message
+
16
,
NULL
,
len
-
14
,
prefix
);
if
(
rc
<
0
)
goto
fail
;
rc
=
parse_other_subtlv
(
message
+
16
+
rc
,
len
-
14
-
rc
);
if
(
rc
<
0
)
goto
done
;
plen
=
message
[
3
]
+
(
message
[
2
]
==
1
?
96
:
0
);
if
(
message
[
2
]
==
1
)
{
v4tov6
(
src_prefix
,
zeroes
);
...
...
@@ -663,6 +735,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
if
(
ae
==
0
)
{
debugf
(
"Received invalid Source-Specific wildcard update.
\n
"
);
rc
=
parse_other_subtlv
(
message
+
12
,
len
-
10
);
if
(
rc
<
0
)
goto
done
;
retract_neighbour_routes
(
neigh
);
goto
done
;
}
else
if
(
ae
==
1
)
{
...
...
@@ -675,13 +750,16 @@ parse_packet(const unsigned char *from, struct interface *ifp,
nh
=
neigh
->
address
;
}
rc
=
parse_update_subtlv
(
ifp
,
metric
,
message
+
2
+
parsed_len
,
len
-
parsed_len
,
channels
,
&
channels_len
);
if
(
rc
<
0
)
goto
done
;
if
(
ae
==
1
)
{
if
(
!
ifp
->
ipv4
)
goto
done
;
}
parse_update_subtlv
(
ifp
,
metric
,
message
+
2
+
parsed_len
,
len
-
parsed_len
,
channels
,
&
channels_len
);
update_route
(
router_id
,
prefix
,
plen
,
src_prefix
,
src_plen
,
seqno
,
metric
,
interval
,
neigh
,
nh
,
channels
,
channels_len
);
...
...
@@ -704,6 +782,9 @@ parse_packet(const unsigned char *from, struct interface *ifp,
if
(
ae
==
1
)
src_plen
+=
96
;
parsed
+=
rc
;
rc
=
parse_other_subtlv
(
message
+
parsed
,
len
-
parsed
+
2
);
if
(
rc
<
0
)
goto
done
;
if
(
ae
==
0
)
{
debugf
(
"Received request for any source-specific "
"from %s on %s.
\n
"
,
...
...
@@ -741,6 +822,10 @@ parse_packet(const unsigned char *from, struct interface *ifp,
rc
=
network_prefix
(
ae
,
src_plen
,
0
,
message
+
parsed
,
NULL
,
len
+
2
-
parsed
,
src_prefix
);
if
(
rc
<
0
)
goto
fail
;
parsed
+=
rc
;
rc
=
parse_other_subtlv
(
message
+
parsed
,
len
-
parsed
+
2
);
if
(
rc
<
0
)
goto
done
;
if
(
ae
==
1
)
src_plen
+=
96
;
debugf
(
"Received request (%d) for (%s, %s)"
...
...
@@ -1753,7 +1838,7 @@ send_marginal_ihu(struct interface *ifp)
FOR_ALL_NEIGHBOURS
(
neigh
)
{
if
(
ifp
&&
neigh
->
ifp
!=
ifp
)
continue
;
if
(
neigh
->
txcost
>=
384
||
(
neigh
->
reach
&
0xF000
)
!=
0xF000
)
if
(
neigh
->
txcost
>=
384
||
(
neigh
->
hello
.
reach
&
0xF000
)
!=
0xF000
)
send_ihu
(
neigh
,
ifp
);
}
}
...
...
neighbour.c
View file @
dac97fdf
...
...
@@ -90,11 +90,11 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
return
NULL
;
}
neigh
->
hello
_
seqno
=
-
1
;
neigh
->
hello
.
seqno
=
neigh
->
uhello
.
seqno
=
-
1
;
memcpy
(
neigh
->
address
,
address
,
16
);
neigh
->
txcost
=
INFINITY
;
neigh
->
ihu_time
=
now
;
neigh
->
hello
_
time
=
zero
;
neigh
->
hello
.
time
=
neigh
->
uhello
.
time
=
zero
;
neigh
->
hello_rtt_receive_time
=
zero
;
neigh
->
rtt_time
=
zero
;
neigh
->
ifp
=
ifp
;
...
...
@@ -108,84 +108,79 @@ find_neighbour(const unsigned char *address, struct interface *ifp)
/* Recompute a neighbour's rxcost. Return true if anything changed.
This does not call local_notify_neighbour, see update_neighbour_metric. */
int
update_neighbour
(
struct
neighbour
*
neigh
,
int
hello
,
int
hello_interval
)
update_neighbour
(
struct
neighbour
*
neigh
,
struct
hello_history
*
hist
,
int
unicast
,
int
hello
,
int
hello_interval
)
{
int
missed_hellos
;
int
rc
=
0
;
if
(
hello
<
0
)
{
if
(
neigh
->
hello_
interval
<=
0
)
if
(
hist
->
interval
<=
0
)
return
rc
;
missed_hellos
=
((
int
)
timeval_minus_msec
(
&
now
,
&
neigh
->
hello_
time
)
-
neigh
->
hello_
interval
*
7
)
/
(
neigh
->
hello_
interval
*
10
);
((
int
)
timeval_minus_msec
(
&
now
,
&
hist
->
time
)
-
hist
->
interval
*
7
)
/
(
hist
->
interval
*
10
);
if
(
missed_hellos
<=
0
)
return
rc
;
timeval_add_msec
(
&
neigh
->
hello_time
,
&
neigh
->
hello_
time
,
missed_hellos
*
neigh
->
hello_
interval
*
10
);
timeval_add_msec
(
&
hist
->
time
,
&
hist
->
time
,
missed_hellos
*
hist
->
interval
*
10
);
}
else
{
if
(
neigh
->
hello_seqno
>=
0
&&
neigh
->
reach
>
0
)
{
missed_hellos
=
seqno_minus
(
hello
,
neigh
->
hello_
seqno
)
-
1
;
if
(
hist
->
seqno
>=
0
&&
hist
->
reach
>
0
)
{
missed_hellos
=
seqno_minus
(
hello
,
hist
->
seqno
)
-
1
;
if
(
missed_hellos
<
-
8
)
{
/* Probably a neighbour that rebooted and lost its seqno.
Reboot the universe. */
neigh
->
reach
=
0
;
hist
->
reach
=
0
;
missed_hellos
=
0
;
rc
=
1
;
}
else
if
(
missed_hellos
<
0
)
{
if
(
hello_interval
>
neigh
->
hello_interval
)
{
/* This neighbour has increased its hello interval,
and we didn't notice. */
neigh
->
reach
<<=
-
missed_hellos
;
missed_hellos
=
0
;
}
else
{
/* Late hello. Probably due to the link layer buffering
packets during a link outage. Ignore it, but reset
the expected seqno. */
neigh
->
hello_seqno
=
hello
;
hello
=
-
1
;
missed_hellos
=
0
;
}
hist
->
reach
<<=
-
missed_hellos
;
missed_hellos
=
0
;
rc
=
1
;
}
}
else
{
missed_hellos
=
0
;
}
neigh
->
hello_time
=
now
;
neigh
->
hello_interval
=
hello_interval
;
if
(
hello_interval
!=
0
)
{
hist
->
time
=
now
;
hist
->
interval
=
hello_interval
;
}
}
if
(
missed_hellos
>
0
)
{
neigh
->
reach
>>=
missed_hellos
;
neigh
->
hello_seqno
=
seqno_plus
(
neigh
->
hello_
seqno
,
missed_hellos
);
hist
->
reach
>>=
missed_hellos
;
hist
->
seqno
=
seqno_plus
(
hist
->
seqno
,
missed_hellos
);
missed_hellos
=
0
;
rc
=
1
;
}
if
(
hello
>=
0
)
{
neigh
->
hello_
seqno
=
hello
;
neigh
->
reach
>>=
1
;
neigh
->
reach
|=
0x8000
;
if
((
neigh
->
reach
&
0xFC00
)
!=
0xFC00
)
hist
->
seqno
=
hello
;
hist
->
reach
>>=
1
;
hist
->
reach
|=
0x8000
;
if
((
hist
->
reach
&
0xFC00
)
!=
0xFC00
)
rc
=
1
;
}
if
(
unicast
)
return
rc
;
/* Make sure to give neighbours some feedback early after association */
if
((
neigh
->
reach
&
0xBF00
)
==
0x8000
)
{
if
((
hist
->
reach
&
0xBF00
)
==
0x8000
)
{
/* A new neighbour */
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
);
int
a
=
(
hist
->
reach
&
0xC000
);
int
b
=
(
hist
->
reach
&
0x3000
);
if
((
a
==
0xC000
&&
b
==
0
)
||
(
a
==
0
&&
b
==
0x3000
))
{
/* Reachability is either 1100 or 0011 */
send_self_update
(
neigh
->
ifp
);
}
}
if
((
neigh
->
reach
&
0xFC00
)
==
0xC000
)
{
if
((
hist
->
reach
&
0xFC00
)
==
0xC000
)
{
/* This is a newish neighbour, let's request a full route dump.
We ought to avoid this when the network is dense */
send_unicast_request
(
neigh
,
NULL
,
0
,
NULL
,
0
);
...
...
@@ -205,7 +200,7 @@ reset_txcost(struct neighbour *neigh)
return
0
;
/* If we're losing a lot of packets, we probably lost an IHU too */
if
(
delay
>=
180000
||
(
neigh
->
reach
&
0xFFF0
)
==
0
||
if
(
delay
>=
180000
||
(
neigh
->
hello
.
reach
&
0xFFF0
)
==
0
||
(
neigh
->
ihu_interval
>
0
&&
delay
>=
neigh
->
ihu_interval
*
10
*
10
))
{
neigh
->
txcost
=
INFINITY
;
...
...
@@ -226,18 +221,20 @@ unsigned
check_neighbours
()
{
struct
neighbour
*
neigh
;
int
changed
,
rc
;
unsigned
msecs
=
50000
;
debugf
(
"Checking neighbours.
\n
"
);
neigh
=
neighs
;
while
(
neigh
)
{
changed
=
update_neighbour
(
neigh
,
-
1
,
0
);
int
changed
,
rc
;
changed
=
update_neighbour
(
neigh
,
&
neigh
->
hello
,
0
,
-
1
,
0
);
rc
=
update_neighbour
(
neigh
,
&
neigh
->
uhello
,
1
,
-
1
,
0
);
changed
=
changed
||
rc
;
if
(
neigh
->
reach
==
0
||
neigh
->
hello
_
time
.
tv_sec
>
now
.
tv_sec
||
/* clock stepped */
timeval_minus_msec
(
&
now
,
&
neigh
->
hello
_
time
)
>
300000
)
{
if
(
neigh
->
hello
.
reach
==
0
||
neigh
->
hello
.
time
.
tv_sec
>
now
.
tv_sec
||
/* clock stepped */
timeval_minus_msec
(
&
now
,
&
neigh
->
hello
.
time
)
>
300000
)
{
struct
neighbour
*
old
=
neigh
;
neigh
=
neigh
->
next
;
flush_neighbour
(
old
);
...
...
@@ -249,8 +246,8 @@ check_neighbours()
update_neighbour_metric
(
neigh
,
changed
);
if
(
neigh
->
hello
_
interval
>
0
)
msecs
=
MIN
(
msecs
,
neigh
->
hello
_
interval
*
10
);
if
(
neigh
->
hello
.
interval
>
0
)
msecs
=
MIN
(
msecs
,
neigh
->
hello
.
interval
*
10
);
if
(
neigh
->
ihu_interval
>
0
)
msecs
=
MIN
(
msecs
,
neigh
->
ihu_interval
*
10
);
neigh
=
neigh
->
next
;
...
...
@@ -259,15 +256,32 @@ check_neighbours()
return
msecs
;
}
/* To lose one hello is a misfortune, to lose two is carelessness. */
static
int
two_three
(
int
reach
)
{
if
((
reach
&
0xC000
)
==
0xC000
)
return
1
;
else
if
((
reach
&
0xC000
)
==
0
)
return
0
;
else
if
((
reach
&
0x2000
))
return
1
;
else
return
0
;
}
unsigned
neighbour_rxcost
(
struct
neighbour
*
neigh
)
{
unsigned
delay
;
unsigned
short
reach
=
neigh
->
reach
;
unsigned
delay
,
udelay
;
unsigned
short
reach
=
neigh
->
hello
.
reach
;
unsigned
short
ureach
=
neigh
->
uhello
.
reach
;
delay
=
timeval_minus_msec
(
&
now
,
&
neigh
->
hello_time
);
delay
=
timeval_minus_msec
(
&
now
,
&
neigh
->
hello
.
time
);
udelay
=
timeval_minus_msec
(
&
now
,
&
neigh
->
uhello
.
time
);
if
((
reach
&
0xFFF0
)
==
0
||
delay
>=
180000
)
{
if
(((
reach
&
0xFFF0
)
==
0
||
delay
>=
180000
)
&&
((
ureach
&
0xFFF0
)
==
0
||
udelay
>=
180000
))
{
return
INFINITY
;
}
else
if
((
neigh
->
ifp
->
flags
&
IF_LQ
))
{
int
sreach
=
...
...
@@ -281,12 +295,7 @@ neighbour_rxcost(struct neighbour *neigh)
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
->
ifp
->
cost
;
else
if
((
reach
&
0xC000
)
==
0
)
return
INFINITY
;
else
if
((
reach
&
0x2000
))
if
(
two_three
(
reach
)
||
two_three
(
ureach
))
return
neigh
->
ifp
->
cost
;
else
return
INFINITY
;
...
...
neighbour.h
View file @
dac97fdf
...
...
@@ -20,16 +20,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
struct
hello_history
{
unsigned
short
reach
;
unsigned
short
interval
;
/* in centiseconds */
int
seqno
;
struct
timeval
time
;
};
struct
neighbour
{
struct
neighbour
*
next
;
/* This is -1 when unknown, so don't make it unsigned */
int
hello_seqno
;
unsigned
char
address
[
16
];
unsigned
short
reach
;
struct
hello_history
hello
;
struct
hello_history
uhello
;
/* for Unicast hellos */
unsigned
short
txcost
;
struct
timeval
hello_time
;
struct
timeval
ihu_time
;
unsigned
short
hello_interval
;
/* in centiseconds */
unsigned
short
ihu_interval
;
/* in centiseconds */
/* Used for RTT estimation. */
/* Absolute time (modulo 2^32) at which the Hello was sent,
...
...
@@ -50,7 +55,8 @@ int neighbour_valid(struct neighbour *neigh);
void
flush_neighbour
(
struct
neighbour
*
neigh
);
struct
neighbour
*
find_neighbour
(
const
unsigned
char
*
address
,
struct
interface
*
ifp
);
int
update_neighbour
(
struct
neighbour
*
neigh
,
int
hello
,
int
hello_interval
);
int
update_neighbour
(
struct
neighbour
*
neigh
,
struct
hello_history
*
hist
,
int
unicast
,
int
hello
,
int
hello_interval
);
unsigned
check_neighbours
(
void
);
unsigned
neighbour_txcost
(
struct
neighbour
*
neigh
);
unsigned
neighbour_rxcost
(
struct
neighbour
*
neigh
);
...
...
route.c
View file @
dac97fdf
...
...
@@ -47,7 +47,6 @@ int kernel_metric = 0, reflect_kernel_metric = 0;
int
allow_duplicates
=
-
1
;
int
diversity_kind
=
DIVERSITY_NONE
;
int
diversity_factor
=
256
;
/* in units of 1/256 */
int
keep_unfeasible
=
0
;
static
int
smoothing_half_life
=
0
;
static
int
two_to_the_one_over_hl
=
0
;
/* 2^(1/hl) * 0x10000 */
...
...
@@ -907,7 +906,7 @@ update_route(const unsigned char *id,
}
route
->
src
=
retain_source
(
src
);
if
(
(
feasible
||
keep_unfeasible
)
&&
refmetric
<
INFINITY
)
if
(
refmetric
<
INFINITY
)
route
->
time
=
now
.
tv_sec
;
route
->
seqno
=
seqno
;
...
...
@@ -953,8 +952,6 @@ update_route(const unsigned char *id,
return
NULL
;
if
(
!
feasible
)
{
send_unfeasible_request
(
neigh
,
0
,
seqno
,
metric
,
src
);
if
(
!
keep_unfeasible
)
return
NULL
;
}
route
=
calloc
(
1
,
sizeof
(
struct
babel_route
));
...
...
route.h
View file @
dac97fdf
...
...
@@ -51,7 +51,6 @@ struct route_stream;
extern
struct
babel_route
**
routes
;
extern
int
kernel_metric
,
allow_duplicates
,
reflect_kernel_metric
;
extern
int
diversity_kind
,
diversity_factor
;
extern
int
keep_unfeasible
;
static
inline
int
route_metric
(
const
struct
babel_route
*
route
)
...
...
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