Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
eac56465
Commit
eac56465
authored
Jun 20, 2011
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'batman-adv/next' of
git://git.open-mesh.org/ecsv/linux-merge
parents
1b9c4134
43676ab5
Changes
27
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
2080 additions
and
462 deletions
+2080
-462
net/batman-adv/Kconfig
net/batman-adv/Kconfig
+1
-0
net/batman-adv/aggregation.c
net/batman-adv/aggregation.c
+11
-14
net/batman-adv/aggregation.h
net/batman-adv/aggregation.h
+5
-3
net/batman-adv/bat_sysfs.c
net/batman-adv/bat_sysfs.c
+72
-1
net/batman-adv/bat_sysfs.h
net/batman-adv/bat_sysfs.h
+2
-0
net/batman-adv/bitarray.c
net/batman-adv/bitarray.c
+4
-4
net/batman-adv/bitarray.h
net/batman-adv/bitarray.h
+4
-4
net/batman-adv/gateway_client.c
net/batman-adv/gateway_client.c
+179
-59
net/batman-adv/gateway_client.h
net/batman-adv/gateway_client.h
+2
-1
net/batman-adv/gateway_common.c
net/batman-adv/gateway_common.c
+3
-3
net/batman-adv/hard-interface.c
net/batman-adv/hard-interface.c
+10
-7
net/batman-adv/main.c
net/batman-adv/main.c
+10
-8
net/batman-adv/main.h
net/batman-adv/main.h
+24
-3
net/batman-adv/originator.c
net/batman-adv/originator.c
+14
-3
net/batman-adv/originator.h
net/batman-adv/originator.h
+0
-8
net/batman-adv/packet.h
net/batman-adv/packet.h
+79
-13
net/batman-adv/routing.c
net/batman-adv/routing.c
+262
-55
net/batman-adv/routing.h
net/batman-adv/routing.h
+4
-3
net/batman-adv/send.c
net/batman-adv/send.c
+70
-22
net/batman-adv/send.h
net/batman-adv/send.h
+1
-1
net/batman-adv/soft-interface.c
net/batman-adv/soft-interface.c
+19
-7
net/batman-adv/soft-interface.h
net/batman-adv/soft-interface.h
+0
-1
net/batman-adv/translation-table.c
net/batman-adv/translation-table.c
+1206
-222
net/batman-adv/translation-table.h
net/batman-adv/translation-table.h
+30
-8
net/batman-adv/types.h
net/batman-adv/types.h
+59
-5
net/batman-adv/unicast.c
net/batman-adv/unicast.c
+3
-0
net/batman-adv/vis.c
net/batman-adv/vis.c
+6
-7
No files found.
net/batman-adv/Kconfig
View file @
eac56465
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
config BATMAN_ADV
config BATMAN_ADV
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
depends on NET
depends on NET
select CRC16
default n
default n
---help---
---help---
...
...
net/batman-adv/aggregation.c
View file @
eac56465
...
@@ -20,17 +20,12 @@
...
@@ -20,17 +20,12 @@
*/
*/
#include "main.h"
#include "main.h"
#include "translation-table.h"
#include "aggregation.h"
#include "aggregation.h"
#include "send.h"
#include "send.h"
#include "routing.h"
#include "routing.h"
#include "hard-interface.h"
#include "hard-interface.h"
/* calculate the size of the tt information for a given packet */
static
int
tt_len
(
const
struct
batman_packet
*
batman_packet
)
{
return
batman_packet
->
num_tt
*
ETH_ALEN
;
}
/* return true if new_packet can be aggregated with forw_packet */
/* return true if new_packet can be aggregated with forw_packet */
static
bool
can_aggregate_with
(
const
struct
batman_packet
*
new_batman_packet
,
static
bool
can_aggregate_with
(
const
struct
batman_packet
*
new_batman_packet
,
int
packet_len
,
int
packet_len
,
...
@@ -195,7 +190,7 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
...
@@ -195,7 +190,7 @@ static void aggregate(struct forw_packet *forw_packet_aggr,
void
add_bat_packet_to_list
(
struct
bat_priv
*
bat_priv
,
void
add_bat_packet_to_list
(
struct
bat_priv
*
bat_priv
,
unsigned
char
*
packet_buff
,
int
packet_len
,
unsigned
char
*
packet_buff
,
int
packet_len
,
struct
hard_iface
*
if_incoming
,
char
own_packet
,
struct
hard_iface
*
if_incoming
,
int
own_packet
,
unsigned
long
send_time
)
unsigned
long
send_time
)
{
{
/**
/**
...
@@ -264,18 +259,20 @@ void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
...
@@ -264,18 +259,20 @@ void receive_aggr_bat_packet(const struct ethhdr *ethhdr,
batman_packet
=
(
struct
batman_packet
*
)
packet_buff
;
batman_packet
=
(
struct
batman_packet
*
)
packet_buff
;
do
{
do
{
/* network to host order for our 32bit seqno
,
and the
/* network to host order for our 32bit seqno and the
orig_interval
.
*/
orig_interval */
batman_packet
->
seqno
=
ntohl
(
batman_packet
->
seqno
);
batman_packet
->
seqno
=
ntohl
(
batman_packet
->
seqno
);
batman_packet
->
tt_crc
=
ntohs
(
batman_packet
->
tt_crc
);
tt_buff
=
packet_buff
+
buff_pos
+
BAT_PACKET_LEN
;
tt_buff
=
packet_buff
+
buff_pos
+
BAT_PACKET_LEN
;
receive_bat_packet
(
ethhdr
,
batman_packet
,
tt_buff
,
tt_len
(
batman_packet
),
if_incoming
);
buff_pos
+=
BAT_PACKET_LEN
+
tt_len
(
batman_packet
);
receive_bat_packet
(
ethhdr
,
batman_packet
,
tt_buff
,
if_incoming
);
buff_pos
+=
BAT_PACKET_LEN
+
tt_len
(
batman_packet
->
tt_num_changes
);
batman_packet
=
(
struct
batman_packet
*
)
batman_packet
=
(
struct
batman_packet
*
)
(
packet_buff
+
buff_pos
);
(
packet_buff
+
buff_pos
);
}
while
(
aggregated_packet
(
buff_pos
,
packet_len
,
}
while
(
aggregated_packet
(
buff_pos
,
packet_len
,
batman_packet
->
num_tt
));
batman_packet
->
tt_num_changes
));
}
}
net/batman-adv/aggregation.h
View file @
eac56465
...
@@ -25,9 +25,11 @@
...
@@ -25,9 +25,11 @@
#include "main.h"
#include "main.h"
/* is there another aggregated packet here? */
/* is there another aggregated packet here? */
static
inline
int
aggregated_packet
(
int
buff_pos
,
int
packet_len
,
int
num_tt
)
static
inline
int
aggregated_packet
(
int
buff_pos
,
int
packet_len
,
int
tt_num_changes
)
{
{
int
next_buff_pos
=
buff_pos
+
BAT_PACKET_LEN
+
(
num_tt
*
ETH_ALEN
);
int
next_buff_pos
=
buff_pos
+
BAT_PACKET_LEN
+
(
tt_num_changes
*
sizeof
(
struct
tt_change
));
return
(
next_buff_pos
<=
packet_len
)
&&
return
(
next_buff_pos
<=
packet_len
)
&&
(
next_buff_pos
<=
MAX_AGGREGATION_BYTES
);
(
next_buff_pos
<=
MAX_AGGREGATION_BYTES
);
...
@@ -35,7 +37,7 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
...
@@ -35,7 +37,7 @@ static inline int aggregated_packet(int buff_pos, int packet_len, int num_tt)
void
add_bat_packet_to_list
(
struct
bat_priv
*
bat_priv
,
void
add_bat_packet_to_list
(
struct
bat_priv
*
bat_priv
,
unsigned
char
*
packet_buff
,
int
packet_len
,
unsigned
char
*
packet_buff
,
int
packet_len
,
struct
hard_iface
*
if_incoming
,
char
own_packet
,
struct
hard_iface
*
if_incoming
,
int
own_packet
,
unsigned
long
send_time
);
unsigned
long
send_time
);
void
receive_aggr_bat_packet
(
const
struct
ethhdr
*
ethhdr
,
void
receive_aggr_bat_packet
(
const
struct
ethhdr
*
ethhdr
,
unsigned
char
*
packet_buff
,
int
packet_len
,
unsigned
char
*
packet_buff
,
int
packet_len
,
...
...
net/batman-adv/bat_sysfs.c
View file @
eac56465
...
@@ -40,6 +40,20 @@ static struct bat_priv *kobj_to_batpriv(struct kobject *obj)
...
@@ -40,6 +40,20 @@ static struct bat_priv *kobj_to_batpriv(struct kobject *obj)
return
netdev_priv
(
net_dev
);
return
netdev_priv
(
net_dev
);
}
}
#define UEV_TYPE_VAR "BATTYPE="
#define UEV_ACTION_VAR "BATACTION="
#define UEV_DATA_VAR "BATDATA="
static
char
*
uev_action_str
[]
=
{
"add"
,
"del"
,
"change"
};
static
char
*
uev_type_str
[]
=
{
"gw"
};
/* Use this, if you have customized show and store functions */
/* Use this, if you have customized show and store functions */
#define BAT_ATTR(_name, _mode, _show, _store) \
#define BAT_ATTR(_name, _mode, _show, _store) \
struct bat_attribute bat_attr_##_name = { \
struct bat_attribute bat_attr_##_name = { \
...
@@ -375,7 +389,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
...
@@ -375,7 +389,7 @@ BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE,
static
BAT_ATTR
(
gw_bandwidth
,
S_IRUGO
|
S_IWUSR
,
show_gw_bwidth
,
static
BAT_ATTR
(
gw_bandwidth
,
S_IRUGO
|
S_IWUSR
,
show_gw_bwidth
,
store_gw_bwidth
);
store_gw_bwidth
);
#ifdef CONFIG_BATMAN_ADV_DEBUG
#ifdef CONFIG_BATMAN_ADV_DEBUG
BAT_ATTR_UINT
(
log_level
,
S_IRUGO
|
S_IWUSR
,
0
,
3
,
NULL
);
BAT_ATTR_UINT
(
log_level
,
S_IRUGO
|
S_IWUSR
,
0
,
7
,
NULL
);
#endif
#endif
static
struct
bat_attribute
*
mesh_attrs
[]
=
{
static
struct
bat_attribute
*
mesh_attrs
[]
=
{
...
@@ -601,3 +615,60 @@ void sysfs_del_hardif(struct kobject **hardif_obj)
...
@@ -601,3 +615,60 @@ void sysfs_del_hardif(struct kobject **hardif_obj)
kobject_put
(
*
hardif_obj
);
kobject_put
(
*
hardif_obj
);
*
hardif_obj
=
NULL
;
*
hardif_obj
=
NULL
;
}
}
int
throw_uevent
(
struct
bat_priv
*
bat_priv
,
enum
uev_type
type
,
enum
uev_action
action
,
const
char
*
data
)
{
int
ret
=
-
1
;
struct
hard_iface
*
primary_if
=
NULL
;
struct
kobject
*
bat_kobj
;
char
*
uevent_env
[
4
]
=
{
NULL
,
NULL
,
NULL
,
NULL
};
primary_if
=
primary_if_get_selected
(
bat_priv
);
if
(
!
primary_if
)
goto
out
;
bat_kobj
=
&
primary_if
->
soft_iface
->
dev
.
kobj
;
uevent_env
[
0
]
=
kmalloc
(
strlen
(
UEV_TYPE_VAR
)
+
strlen
(
uev_type_str
[
type
])
+
1
,
GFP_ATOMIC
);
if
(
!
uevent_env
[
0
])
goto
out
;
sprintf
(
uevent_env
[
0
],
"%s%s"
,
UEV_TYPE_VAR
,
uev_type_str
[
type
]);
uevent_env
[
1
]
=
kmalloc
(
strlen
(
UEV_ACTION_VAR
)
+
strlen
(
uev_action_str
[
action
])
+
1
,
GFP_ATOMIC
);
if
(
!
uevent_env
[
1
])
goto
out
;
sprintf
(
uevent_env
[
1
],
"%s%s"
,
UEV_ACTION_VAR
,
uev_action_str
[
action
]);
/* If the event is DEL, ignore the data field */
if
(
action
!=
UEV_DEL
)
{
uevent_env
[
2
]
=
kmalloc
(
strlen
(
UEV_DATA_VAR
)
+
strlen
(
data
)
+
1
,
GFP_ATOMIC
);
if
(
!
uevent_env
[
2
])
goto
out
;
sprintf
(
uevent_env
[
2
],
"%s%s"
,
UEV_DATA_VAR
,
data
);
}
ret
=
kobject_uevent_env
(
bat_kobj
,
KOBJ_CHANGE
,
uevent_env
);
out:
kfree
(
uevent_env
[
0
]);
kfree
(
uevent_env
[
1
]);
kfree
(
uevent_env
[
2
]);
if
(
primary_if
)
hardif_free_ref
(
primary_if
);
if
(
ret
)
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Impossible to send "
"uevent for (%s,%s,%s) event (err: %d)
\n
"
,
uev_type_str
[
type
],
uev_action_str
[
action
],
(
action
==
UEV_DEL
?
"NULL"
:
data
),
ret
);
return
ret
;
}
net/batman-adv/bat_sysfs.h
View file @
eac56465
...
@@ -38,5 +38,7 @@ int sysfs_add_meshif(struct net_device *dev);
...
@@ -38,5 +38,7 @@ int sysfs_add_meshif(struct net_device *dev);
void
sysfs_del_meshif
(
struct
net_device
*
dev
);
void
sysfs_del_meshif
(
struct
net_device
*
dev
);
int
sysfs_add_hardif
(
struct
kobject
**
hardif_obj
,
struct
net_device
*
dev
);
int
sysfs_add_hardif
(
struct
kobject
**
hardif_obj
,
struct
net_device
*
dev
);
void
sysfs_del_hardif
(
struct
kobject
**
hardif_obj
);
void
sysfs_del_hardif
(
struct
kobject
**
hardif_obj
);
int
throw_uevent
(
struct
bat_priv
*
bat_priv
,
enum
uev_type
type
,
enum
uev_action
action
,
const
char
*
data
);
#endif
/* _NET_BATMAN_ADV_SYSFS_H_ */
#endif
/* _NET_BATMAN_ADV_SYSFS_H_ */
net/batman-adv/bitarray.c
View file @
eac56465
...
@@ -26,8 +26,8 @@
...
@@ -26,8 +26,8 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
* and curr_seqno is within range of last_seqno */
uint8_
t
get_bit_status
(
const
unsigned
long
*
seq_bits
,
uint32_t
last_seqno
,
in
t
get_bit_status
(
const
unsigned
long
*
seq_bits
,
uint32_t
last_seqno
,
uint32_t
curr_seqno
)
uint32_t
curr_seqno
)
{
{
int32_t
diff
,
word_offset
,
word_num
;
int32_t
diff
,
word_offset
,
word_num
;
...
@@ -127,8 +127,8 @@ static void bit_reset_window(unsigned long *seq_bits)
...
@@ -127,8 +127,8 @@ static void bit_reset_window(unsigned long *seq_bits)
* 1 if the window was moved (either new or very old)
* 1 if the window was moved (either new or very old)
* 0 if the window was not moved/shifted.
* 0 if the window was not moved/shifted.
*/
*/
char
bit_get_packet
(
void
*
priv
,
unsigned
long
*
seq_bits
,
int
bit_get_packet
(
void
*
priv
,
unsigned
long
*
seq_bits
,
int32_t
seq_num_diff
,
int
8_t
set_mark
)
int32_t
seq_num_diff
,
int
set_mark
)
{
{
struct
bat_priv
*
bat_priv
=
priv
;
struct
bat_priv
*
bat_priv
=
priv
;
...
...
net/batman-adv/bitarray.h
View file @
eac56465
...
@@ -26,8 +26,8 @@
...
@@ -26,8 +26,8 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
* and curr_seqno is within range of last_seqno */
uint8_
t
get_bit_status
(
const
unsigned
long
*
seq_bits
,
uint32_t
last_seqno
,
in
t
get_bit_status
(
const
unsigned
long
*
seq_bits
,
uint32_t
last_seqno
,
uint32_t
curr_seqno
);
uint32_t
curr_seqno
);
/* turn corresponding bit on, so we can remember that we got the packet */
/* turn corresponding bit on, so we can remember that we got the packet */
void
bit_mark
(
unsigned
long
*
seq_bits
,
int32_t
n
);
void
bit_mark
(
unsigned
long
*
seq_bits
,
int32_t
n
);
...
@@ -35,8 +35,8 @@ void bit_mark(unsigned long *seq_bits, int32_t n);
...
@@ -35,8 +35,8 @@ void bit_mark(unsigned long *seq_bits, int32_t n);
/* receive and process one packet, returns 1 if received seq_num is considered
/* receive and process one packet, returns 1 if received seq_num is considered
* new, 0 if old */
* new, 0 if old */
char
bit_get_packet
(
void
*
priv
,
unsigned
long
*
seq_bits
,
int
bit_get_packet
(
void
*
priv
,
unsigned
long
*
seq_bits
,
int32_t
seq_num_diff
,
int8_
t
set_mark
);
int32_t
seq_num_diff
,
in
t
set_mark
);
/* count the hamming weight, how many good packets did we receive? */
/* count the hamming weight, how many good packets did we receive? */
int
bit_packet_count
(
const
unsigned
long
*
seq_bits
);
int
bit_packet_count
(
const
unsigned
long
*
seq_bits
);
...
...
net/batman-adv/gateway_client.c
View file @
eac56465
...
@@ -20,15 +20,22 @@
...
@@ -20,15 +20,22 @@
*/
*/
#include "main.h"
#include "main.h"
#include "bat_sysfs.h"
#include "gateway_client.h"
#include "gateway_client.h"
#include "gateway_common.h"
#include "gateway_common.h"
#include "hard-interface.h"
#include "hard-interface.h"
#include "originator.h"
#include "originator.h"
#include "routing.h"
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/udp.h>
#include <linux/if_vlan.h>
#include <linux/if_vlan.h>
/* This is the offset of the options field in a dhcp packet starting at
* the beginning of the dhcp header */
#define DHCP_OPTIONS_OFFSET 240
#define DHCP_REQUEST 3
static
void
gw_node_free_ref
(
struct
gw_node
*
gw_node
)
static
void
gw_node_free_ref
(
struct
gw_node
*
gw_node
)
{
{
if
(
atomic_dec_and_test
(
&
gw_node
->
refcount
))
if
(
atomic_dec_and_test
(
&
gw_node
->
refcount
))
...
@@ -97,40 +104,19 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
...
@@ -97,40 +104,19 @@ static void gw_select(struct bat_priv *bat_priv, struct gw_node *new_gw_node)
void
gw_deselect
(
struct
bat_priv
*
bat_priv
)
void
gw_deselect
(
struct
bat_priv
*
bat_priv
)
{
{
gw_select
(
bat_priv
,
NULL
);
atomic_set
(
&
bat_priv
->
gw_reselect
,
1
);
}
}
void
gw_election
(
struct
bat_priv
*
bat_priv
)
static
struct
gw_node
*
gw_get_best_gw_node
(
struct
bat_priv
*
bat_priv
)
{
{
struct
hlist_node
*
node
;
struct
gw_node
*
gw_node
,
*
curr_gw
=
NULL
,
*
curr_gw_tmp
=
NULL
;
struct
neigh_node
*
router
;
struct
neigh_node
*
router
;
uint8_t
max_tq
=
0
;
struct
hlist_node
*
node
;
struct
gw_node
*
gw_node
,
*
curr_gw
=
NULL
;
uint32_t
max_gw_factor
=
0
,
tmp_gw_factor
=
0
;
uint32_t
max_gw_factor
=
0
,
tmp_gw_factor
=
0
;
uint8_t
max_tq
=
0
;
int
down
,
up
;
int
down
,
up
;
/**
* The batman daemon checks here if we already passed a full originator
* cycle in order to make sure we don't choose the first gateway we
* hear about. This check is based on the daemon's uptime which we
* don't have.
**/
if
(
atomic_read
(
&
bat_priv
->
gw_mode
)
!=
GW_MODE_CLIENT
)
return
;
curr_gw
=
gw_get_selected_gw_node
(
bat_priv
);
if
(
curr_gw
)
goto
out
;
rcu_read_lock
();
rcu_read_lock
();
if
(
hlist_empty
(
&
bat_priv
->
gw_list
))
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Removing selected gateway - "
"no gateway in range
\n
"
);
gw_deselect
(
bat_priv
);
goto
unlock
;
}
hlist_for_each_entry_rcu
(
gw_node
,
node
,
&
bat_priv
->
gw_list
,
list
)
{
hlist_for_each_entry_rcu
(
gw_node
,
node
,
&
bat_priv
->
gw_list
,
list
)
{
if
(
gw_node
->
deleted
)
if
(
gw_node
->
deleted
)
continue
;
continue
;
...
@@ -139,6 +125,9 @@ void gw_election(struct bat_priv *bat_priv)
...
@@ -139,6 +125,9 @@ void gw_election(struct bat_priv *bat_priv)
if
(
!
router
)
if
(
!
router
)
continue
;
continue
;
if
(
!
atomic_inc_not_zero
(
&
gw_node
->
refcount
))
goto
next
;
switch
(
atomic_read
(
&
bat_priv
->
gw_sel_class
))
{
switch
(
atomic_read
(
&
bat_priv
->
gw_sel_class
))
{
case
1
:
/* fast connection */
case
1
:
/* fast connection */
gw_bandwidth_to_kbit
(
gw_node
->
orig_node
->
gw_flags
,
gw_bandwidth_to_kbit
(
gw_node
->
orig_node
->
gw_flags
,
...
@@ -151,8 +140,12 @@ void gw_election(struct bat_priv *bat_priv)
...
@@ -151,8 +140,12 @@ void gw_election(struct bat_priv *bat_priv)
if
((
tmp_gw_factor
>
max_gw_factor
)
||
if
((
tmp_gw_factor
>
max_gw_factor
)
||
((
tmp_gw_factor
==
max_gw_factor
)
&&
((
tmp_gw_factor
==
max_gw_factor
)
&&
(
router
->
tq_avg
>
max_tq
)))
(
router
->
tq_avg
>
max_tq
)))
{
curr_gw_tmp
=
gw_node
;
if
(
curr_gw
)
gw_node_free_ref
(
curr_gw
);
curr_gw
=
gw_node
;
atomic_inc
(
&
curr_gw
->
refcount
);
}
break
;
break
;
default:
/**
default:
/**
...
@@ -163,8 +156,12 @@ void gw_election(struct bat_priv *bat_priv)
...
@@ -163,8 +156,12 @@ void gw_election(struct bat_priv *bat_priv)
* soon as a better gateway appears which has
* soon as a better gateway appears which has
* $routing_class more tq points)
* $routing_class more tq points)
**/
**/
if
(
router
->
tq_avg
>
max_tq
)
if
(
router
->
tq_avg
>
max_tq
)
{
curr_gw_tmp
=
gw_node
;
if
(
curr_gw
)
gw_node_free_ref
(
curr_gw
);
curr_gw
=
gw_node
;
atomic_inc
(
&
curr_gw
->
refcount
);
}
break
;
break
;
}
}
...
@@ -174,42 +171,81 @@ void gw_election(struct bat_priv *bat_priv)
...
@@ -174,42 +171,81 @@ void gw_election(struct bat_priv *bat_priv)
if
(
tmp_gw_factor
>
max_gw_factor
)
if
(
tmp_gw_factor
>
max_gw_factor
)
max_gw_factor
=
tmp_gw_factor
;
max_gw_factor
=
tmp_gw_factor
;
gw_node_free_ref
(
gw_node
);
next:
neigh_node_free_ref
(
router
);
neigh_node_free_ref
(
router
);
}
}
rcu_read_unlock
();
if
(
curr_gw
!=
curr_gw_tmp
)
{
return
curr_gw
;
router
=
orig_node_get_router
(
curr_gw_tmp
->
orig_node
);
}
if
(
!
router
)
goto
unlock
;
if
((
curr_gw
)
&&
(
!
curr_gw_tmp
))
void
gw_election
(
struct
bat_priv
*
bat_priv
)
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
{
"Removing selected gateway - "
struct
gw_node
*
curr_gw
=
NULL
,
*
next_gw
=
NULL
;
"no gateway in range
\n
"
);
struct
neigh_node
*
router
=
NULL
;
else
if
((
!
curr_gw
)
&&
(
curr_gw_tmp
))
char
gw_addr
[
18
]
=
{
'\0'
};
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Adding route to gateway %pM "
"(gw_flags: %i, tq: %i)
\n
"
,
curr_gw_tmp
->
orig_node
->
orig
,
curr_gw_tmp
->
orig_node
->
gw_flags
,
router
->
tq_avg
);
else
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Changing route to gateway %pM "
"(gw_flags: %i, tq: %i)
\n
"
,
curr_gw_tmp
->
orig_node
->
orig
,
curr_gw_tmp
->
orig_node
->
gw_flags
,
router
->
tq_avg
);
neigh_node_free_ref
(
router
);
/**
gw_select
(
bat_priv
,
curr_gw_tmp
);
* The batman daemon checks here if we already passed a full originator
* cycle in order to make sure we don't choose the first gateway we
* hear about. This check is based on the daemon's uptime which we
* don't have.
**/
if
(
atomic_read
(
&
bat_priv
->
gw_mode
)
!=
GW_MODE_CLIENT
)
goto
out
;
if
(
!
atomic_dec_not_zero
(
&
bat_priv
->
gw_reselect
))
goto
out
;
curr_gw
=
gw_get_selected_gw_node
(
bat_priv
);
next_gw
=
gw_get_best_gw_node
(
bat_priv
);
if
(
curr_gw
==
next_gw
)
goto
out
;
if
(
next_gw
)
{
sprintf
(
gw_addr
,
"%pM"
,
next_gw
->
orig_node
->
orig
);
router
=
orig_node_get_router
(
next_gw
->
orig_node
);
if
(
!
router
)
{
gw_deselect
(
bat_priv
);
goto
out
;
}
}
}
unlock:
if
((
curr_gw
)
&&
(
!
next_gw
))
{
rcu_read_unlock
();
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Removing selected gateway - no gateway in range
\n
"
);
throw_uevent
(
bat_priv
,
UEV_GW
,
UEV_DEL
,
NULL
);
}
else
if
((
!
curr_gw
)
&&
(
next_gw
))
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Adding route to gateway %pM (gw_flags: %i, tq: %i)
\n
"
,
next_gw
->
orig_node
->
orig
,
next_gw
->
orig_node
->
gw_flags
,
router
->
tq_avg
);
throw_uevent
(
bat_priv
,
UEV_GW
,
UEV_ADD
,
gw_addr
);
}
else
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"Changing route to gateway %pM "
"(gw_flags: %i, tq: %i)
\n
"
,
next_gw
->
orig_node
->
orig
,
next_gw
->
orig_node
->
gw_flags
,
router
->
tq_avg
);
throw_uevent
(
bat_priv
,
UEV_GW
,
UEV_CHANGE
,
gw_addr
);
}
gw_select
(
bat_priv
,
next_gw
);
out:
out:
if
(
curr_gw
)
if
(
curr_gw
)
gw_node_free_ref
(
curr_gw
);
gw_node_free_ref
(
curr_gw
);
if
(
next_gw
)
gw_node_free_ref
(
next_gw
);
if
(
router
)
neigh_node_free_ref
(
router
);
}
}
void
gw_check_election
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
)
void
gw_check_election
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
)
...
@@ -360,7 +396,7 @@ void gw_node_purge(struct bat_priv *bat_priv)
...
@@ -360,7 +396,7 @@ void gw_node_purge(struct bat_priv *bat_priv)
struct
gw_node
*
gw_node
,
*
curr_gw
;
struct
gw_node
*
gw_node
,
*
curr_gw
;
struct
hlist_node
*
node
,
*
node_tmp
;
struct
hlist_node
*
node
,
*
node_tmp
;
unsigned
long
timeout
=
2
*
PURGE_TIMEOUT
*
HZ
;
unsigned
long
timeout
=
2
*
PURGE_TIMEOUT
*
HZ
;
char
do_deselect
=
0
;
int
do_deselect
=
0
;
curr_gw
=
gw_get_selected_gw_node
(
bat_priv
);
curr_gw
=
gw_get_selected_gw_node
(
bat_priv
);
...
@@ -479,14 +515,75 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
...
@@ -479,14 +515,75 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset)
return
ret
;
return
ret
;
}
}
int
gw_is_target
(
struct
bat_priv
*
bat_priv
,
struct
sk_buff
*
skb
)
static
bool
is_type_dhcprequest
(
struct
sk_buff
*
skb
,
int
header_len
)
{
int
ret
=
false
;
unsigned
char
*
p
;
int
pkt_len
;
if
(
skb_linearize
(
skb
)
<
0
)
goto
out
;
pkt_len
=
skb_headlen
(
skb
);
if
(
pkt_len
<
header_len
+
DHCP_OPTIONS_OFFSET
+
1
)
goto
out
;
p
=
skb
->
data
+
header_len
+
DHCP_OPTIONS_OFFSET
;
pkt_len
-=
header_len
+
DHCP_OPTIONS_OFFSET
+
1
;
/* Access the dhcp option lists. Each entry is made up by:
* - octect 1: option type
* - octect 2: option data len (only if type != 255 and 0)
* - octect 3: option data */
while
(
*
p
!=
255
&&
!
ret
)
{
/* p now points to the first octect: option type */
if
(
*
p
==
53
)
{
/* type 53 is the message type option.
* Jump the len octect and go to the data octect */
if
(
pkt_len
<
2
)
goto
out
;
p
+=
2
;
/* check if the message type is what we need */
if
(
*
p
==
DHCP_REQUEST
)
ret
=
true
;
break
;
}
else
if
(
*
p
==
0
)
{
/* option type 0 (padding), just go forward */
if
(
pkt_len
<
1
)
goto
out
;
pkt_len
--
;
p
++
;
}
else
{
/* This is any other option. So we get the length... */
if
(
pkt_len
<
1
)
goto
out
;
pkt_len
--
;
p
++
;
/* ...and then we jump over the data */
if
(
pkt_len
<
*
p
)
goto
out
;
pkt_len
-=
*
p
;
p
+=
(
*
p
);
}
}
out:
return
ret
;
}
int
gw_is_target
(
struct
bat_priv
*
bat_priv
,
struct
sk_buff
*
skb
,
struct
orig_node
*
old_gw
)
{
{
struct
ethhdr
*
ethhdr
;
struct
ethhdr
*
ethhdr
;
struct
iphdr
*
iphdr
;
struct
iphdr
*
iphdr
;
struct
ipv6hdr
*
ipv6hdr
;
struct
ipv6hdr
*
ipv6hdr
;
struct
udphdr
*
udphdr
;
struct
udphdr
*
udphdr
;
struct
gw_node
*
curr_gw
;
struct
gw_node
*
curr_gw
;
struct
neigh_node
*
neigh_curr
=
NULL
,
*
neigh_old
=
NULL
;
unsigned
int
header_len
=
0
;
unsigned
int
header_len
=
0
;
int
ret
=
1
;
if
(
atomic_read
(
&
bat_priv
->
gw_mode
)
==
GW_MODE_OFF
)
if
(
atomic_read
(
&
bat_priv
->
gw_mode
)
==
GW_MODE_OFF
)
return
0
;
return
0
;
...
@@ -554,7 +651,30 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
...
@@ -554,7 +651,30 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb)
if
(
!
curr_gw
)
if
(
!
curr_gw
)
return
0
;
return
0
;
/* If old_gw != NULL then this packet is unicast.
* So, at this point we have to check the message type: if it is a
* DHCPREQUEST we have to decide whether to drop it or not */
if
(
old_gw
&&
curr_gw
->
orig_node
!=
old_gw
)
{
if
(
is_type_dhcprequest
(
skb
,
header_len
))
{
/* If the dhcp packet has been sent to a different gw,
* we have to evaluate whether the old gw is still
* reliable enough */
neigh_curr
=
find_router
(
bat_priv
,
curr_gw
->
orig_node
,
NULL
);
neigh_old
=
find_router
(
bat_priv
,
old_gw
,
NULL
);
if
(
!
neigh_curr
||
!
neigh_old
)
goto
free_neigh
;
if
(
neigh_curr
->
tq_avg
-
neigh_old
->
tq_avg
<
GW_THRESHOLD
)
ret
=
-
1
;
}
}
free_neigh:
if
(
neigh_old
)
neigh_node_free_ref
(
neigh_old
);
if
(
neigh_curr
)
neigh_node_free_ref
(
neigh_curr
);
if
(
curr_gw
)
if
(
curr_gw
)
gw_node_free_ref
(
curr_gw
);
gw_node_free_ref
(
curr_gw
);
return
1
;
return
ret
;
}
}
net/batman-adv/gateway_client.h
View file @
eac56465
...
@@ -31,6 +31,7 @@ void gw_node_update(struct bat_priv *bat_priv,
...
@@ -31,6 +31,7 @@ void gw_node_update(struct bat_priv *bat_priv,
void
gw_node_delete
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
);
void
gw_node_delete
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
);
void
gw_node_purge
(
struct
bat_priv
*
bat_priv
);
void
gw_node_purge
(
struct
bat_priv
*
bat_priv
);
int
gw_client_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
int
gw_client_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
int
gw_is_target
(
struct
bat_priv
*
bat_priv
,
struct
sk_buff
*
skb
);
int
gw_is_target
(
struct
bat_priv
*
bat_priv
,
struct
sk_buff
*
skb
,
struct
orig_node
*
old_gw
);
#endif
/* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
#endif
/* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */
net/batman-adv/gateway_common.c
View file @
eac56465
...
@@ -61,9 +61,9 @@ static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class)
...
@@ -61,9 +61,9 @@ static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class)
/* returns the up and downspeeds in kbit, calculated from the class */
/* returns the up and downspeeds in kbit, calculated from the class */
void
gw_bandwidth_to_kbit
(
uint8_t
gw_srv_class
,
int
*
down
,
int
*
up
)
void
gw_bandwidth_to_kbit
(
uint8_t
gw_srv_class
,
int
*
down
,
int
*
up
)
{
{
char
sbit
=
(
gw_srv_class
&
0x80
)
>>
7
;
int
sbit
=
(
gw_srv_class
&
0x80
)
>>
7
;
char
dpart
=
(
gw_srv_class
&
0x78
)
>>
3
;
int
dpart
=
(
gw_srv_class
&
0x78
)
>>
3
;
char
upart
=
(
gw_srv_class
&
0x07
);
int
upart
=
(
gw_srv_class
&
0x07
);
if
(
!
gw_srv_class
)
{
if
(
!
gw_srv_class
)
{
*
down
=
0
;
*
down
=
0
;
...
...
net/batman-adv/hard-interface.c
View file @
eac56465
...
@@ -152,12 +152,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
...
@@ -152,12 +152,6 @@ static void primary_if_select(struct bat_priv *bat_priv,
batman_packet
->
ttl
=
TTL
;
batman_packet
->
ttl
=
TTL
;
primary_if_update_addr
(
bat_priv
);
primary_if_update_addr
(
bat_priv
);
/***
* hacky trick to make sure that we send the TT information via
* our new primary interface
*/
atomic_set
(
&
bat_priv
->
tt_local_changed
,
1
);
}
}
static
bool
hardif_is_iface_up
(
const
struct
hard_iface
*
hard_iface
)
static
bool
hardif_is_iface_up
(
const
struct
hard_iface
*
hard_iface
)
...
@@ -340,7 +334,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
...
@@ -340,7 +334,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface,
batman_packet
->
flags
=
NO_FLAGS
;
batman_packet
->
flags
=
NO_FLAGS
;
batman_packet
->
ttl
=
2
;
batman_packet
->
ttl
=
2
;
batman_packet
->
tq
=
TQ_MAX_VALUE
;
batman_packet
->
tq
=
TQ_MAX_VALUE
;
batman_packet
->
num_tt
=
0
;
batman_packet
->
tt_num_changes
=
0
;
batman_packet
->
ttvn
=
0
;
hard_iface
->
if_num
=
bat_priv
->
num_ifaces
;
hard_iface
->
if_num
=
bat_priv
->
num_ifaces
;
bat_priv
->
num_ifaces
++
;
bat_priv
->
num_ifaces
++
;
...
@@ -659,6 +654,14 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
...
@@ -659,6 +654,14 @@ static int batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
case
BAT_VIS
:
case
BAT_VIS
:
ret
=
recv_vis_packet
(
skb
,
hard_iface
);
ret
=
recv_vis_packet
(
skb
,
hard_iface
);
break
;
break
;
/* Translation table query (request or response) */
case
BAT_TT_QUERY
:
ret
=
recv_tt_query
(
skb
,
hard_iface
);
break
;
/* Roaming advertisement */
case
BAT_ROAM_ADV
:
ret
=
recv_roam_adv
(
skb
,
hard_iface
);
break
;
default:
default:
ret
=
NET_RX_DROP
;
ret
=
NET_RX_DROP
;
}
}
...
...
net/batman-adv/main.c
View file @
eac56465
...
@@ -84,8 +84,10 @@ int mesh_init(struct net_device *soft_iface)
...
@@ -84,8 +84,10 @@ int mesh_init(struct net_device *soft_iface)
spin_lock_init
(
&
bat_priv
->
forw_bat_list_lock
);
spin_lock_init
(
&
bat_priv
->
forw_bat_list_lock
);
spin_lock_init
(
&
bat_priv
->
forw_bcast_list_lock
);
spin_lock_init
(
&
bat_priv
->
forw_bcast_list_lock
);
spin_lock_init
(
&
bat_priv
->
tt_lhash_lock
);
spin_lock_init
(
&
bat_priv
->
tt_changes_list_lock
);
spin_lock_init
(
&
bat_priv
->
tt_ghash_lock
);
spin_lock_init
(
&
bat_priv
->
tt_req_list_lock
);
spin_lock_init
(
&
bat_priv
->
tt_roam_list_lock
);
spin_lock_init
(
&
bat_priv
->
tt_buff_lock
);
spin_lock_init
(
&
bat_priv
->
gw_list_lock
);
spin_lock_init
(
&
bat_priv
->
gw_list_lock
);
spin_lock_init
(
&
bat_priv
->
vis_hash_lock
);
spin_lock_init
(
&
bat_priv
->
vis_hash_lock
);
spin_lock_init
(
&
bat_priv
->
vis_list_lock
);
spin_lock_init
(
&
bat_priv
->
vis_list_lock
);
...
@@ -96,14 +98,14 @@ int mesh_init(struct net_device *soft_iface)
...
@@ -96,14 +98,14 @@ int mesh_init(struct net_device *soft_iface)
INIT_HLIST_HEAD
(
&
bat_priv
->
forw_bcast_list
);
INIT_HLIST_HEAD
(
&
bat_priv
->
forw_bcast_list
);
INIT_HLIST_HEAD
(
&
bat_priv
->
gw_list
);
INIT_HLIST_HEAD
(
&
bat_priv
->
gw_list
);
INIT_HLIST_HEAD
(
&
bat_priv
->
softif_neigh_vids
);
INIT_HLIST_HEAD
(
&
bat_priv
->
softif_neigh_vids
);
INIT_LIST_HEAD
(
&
bat_priv
->
tt_changes_list
);
INIT_LIST_HEAD
(
&
bat_priv
->
tt_req_list
);
INIT_LIST_HEAD
(
&
bat_priv
->
tt_roam_list
);
if
(
originator_init
(
bat_priv
)
<
1
)
if
(
originator_init
(
bat_priv
)
<
1
)
goto
err
;
goto
err
;
if
(
tt_local_init
(
bat_priv
)
<
1
)
if
(
tt_init
(
bat_priv
)
<
1
)
goto
err
;
if
(
tt_global_init
(
bat_priv
)
<
1
)
goto
err
;
goto
err
;
tt_local_add
(
soft_iface
,
soft_iface
->
dev_addr
);
tt_local_add
(
soft_iface
,
soft_iface
->
dev_addr
);
...
@@ -111,6 +113,7 @@ int mesh_init(struct net_device *soft_iface)
...
@@ -111,6 +113,7 @@ int mesh_init(struct net_device *soft_iface)
if
(
vis_init
(
bat_priv
)
<
1
)
if
(
vis_init
(
bat_priv
)
<
1
)
goto
err
;
goto
err
;
atomic_set
(
&
bat_priv
->
gw_reselect
,
0
);
atomic_set
(
&
bat_priv
->
mesh_state
,
MESH_ACTIVE
);
atomic_set
(
&
bat_priv
->
mesh_state
,
MESH_ACTIVE
);
goto
end
;
goto
end
;
...
@@ -137,8 +140,7 @@ void mesh_free(struct net_device *soft_iface)
...
@@ -137,8 +140,7 @@ void mesh_free(struct net_device *soft_iface)
gw_node_purge
(
bat_priv
);
gw_node_purge
(
bat_priv
);
originator_free
(
bat_priv
);
originator_free
(
bat_priv
);
tt_local_free
(
bat_priv
);
tt_free
(
bat_priv
);
tt_global_free
(
bat_priv
);
softif_neigh_purge
(
bat_priv
);
softif_neigh_purge
(
bat_priv
);
...
...
net/batman-adv/main.h
View file @
eac56465
...
@@ -42,15 +42,23 @@
...
@@ -42,15 +42,23 @@
* -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
* -> TODO: check influence on TQ_LOCAL_WINDOW_SIZE */
#define PURGE_TIMEOUT 200
#define PURGE_TIMEOUT 200
#define TT_LOCAL_TIMEOUT 3600
/* in seconds */
#define TT_LOCAL_TIMEOUT 3600
/* in seconds */
#define TT_CLIENT_ROAM_TIMEOUT 600
/* sliding packet range of received originator messages in squence numbers
/* sliding packet range of received originator messages in squence numbers
* (should be a multiple of our word size) */
* (should be a multiple of our word size) */
#define TQ_LOCAL_WINDOW_SIZE 64
#define TQ_LOCAL_WINDOW_SIZE 64
#define TT_REQUEST_TIMEOUT 3
/* seconds we have to keep pending tt_req */
#define TQ_GLOBAL_WINDOW_SIZE 5
#define TQ_GLOBAL_WINDOW_SIZE 5
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1
#define TQ_TOTAL_BIDRECT_LIMIT 1
#define TQ_TOTAL_BIDRECT_LIMIT 1
#define TT_OGM_APPEND_MAX 3
/* number of OGMs sent with the last tt diff */
#define ROAMING_MAX_TIME 20
/* Time in which a client can roam at most
* ROAMING_MAX_COUNT times */
#define ROAMING_MAX_COUNT 5
#define NO_FLAGS 0
#define NO_FLAGS 0
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE)
...
@@ -83,6 +91,18 @@ enum mesh_state {
...
@@ -83,6 +91,18 @@ enum mesh_state {
#define BCAST_QUEUE_LEN 256
#define BCAST_QUEUE_LEN 256
#define BATMAN_QUEUE_LEN 256
#define BATMAN_QUEUE_LEN 256
enum
uev_action
{
UEV_ADD
=
0
,
UEV_DEL
,
UEV_CHANGE
};
enum
uev_type
{
UEV_GW
=
0
};
#define GW_THRESHOLD 50
/*
/*
* Debug Messages
* Debug Messages
*/
*/
...
@@ -96,7 +116,8 @@ enum mesh_state {
...
@@ -96,7 +116,8 @@ enum mesh_state {
enum
dbg_level
{
enum
dbg_level
{
DBG_BATMAN
=
1
<<
0
,
DBG_BATMAN
=
1
<<
0
,
DBG_ROUTES
=
1
<<
1
,
/* route added / changed / deleted */
DBG_ROUTES
=
1
<<
1
,
/* route added / changed / deleted */
DBG_ALL
=
3
DBG_TT
=
1
<<
2
,
/* translation table operations */
DBG_ALL
=
7
};
};
...
@@ -151,7 +172,7 @@ int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3);
...
@@ -151,7 +172,7 @@ int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3);
while (0)
while (0)
#else
/* !CONFIG_BATMAN_ADV_DEBUG */
#else
/* !CONFIG_BATMAN_ADV_DEBUG */
__printf
(
3
,
4
)
__printf
(
3
,
4
)
static
inline
void
bat_dbg
(
char
type
__always_unused
,
static
inline
void
bat_dbg
(
int
type
__always_unused
,
struct
bat_priv
*
bat_priv
__always_unused
,
struct
bat_priv
*
bat_priv
__always_unused
,
const
char
*
fmt
__always_unused
,
...)
const
char
*
fmt
__always_unused
,
...)
{
{
...
...
net/batman-adv/originator.c
View file @
eac56465
...
@@ -37,6 +37,14 @@ static void start_purge_timer(struct bat_priv *bat_priv)
...
@@ -37,6 +37,14 @@ static void start_purge_timer(struct bat_priv *bat_priv)
queue_delayed_work
(
bat_event_workqueue
,
&
bat_priv
->
orig_work
,
1
*
HZ
);
queue_delayed_work
(
bat_event_workqueue
,
&
bat_priv
->
orig_work
,
1
*
HZ
);
}
}
/* returns 1 if they are the same originator */
static
int
compare_orig
(
const
struct
hlist_node
*
node
,
const
void
*
data2
)
{
const
void
*
data1
=
container_of
(
node
,
struct
orig_node
,
hash_entry
);
return
(
memcmp
(
data1
,
data2
,
ETH_ALEN
)
==
0
?
1
:
0
);
}
int
originator_init
(
struct
bat_priv
*
bat_priv
)
int
originator_init
(
struct
bat_priv
*
bat_priv
)
{
{
if
(
bat_priv
->
orig_hash
)
if
(
bat_priv
->
orig_hash
)
...
@@ -137,6 +145,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
...
@@ -137,6 +145,7 @@ static void orig_node_free_rcu(struct rcu_head *rcu)
tt_global_del_orig
(
orig_node
->
bat_priv
,
orig_node
,
tt_global_del_orig
(
orig_node
->
bat_priv
,
orig_node
,
"originator timed out"
);
"originator timed out"
);
kfree
(
orig_node
->
tt_buff
);
kfree
(
orig_node
->
bcast_own
);
kfree
(
orig_node
->
bcast_own
);
kfree
(
orig_node
->
bcast_own_sum
);
kfree
(
orig_node
->
bcast_own_sum
);
kfree
(
orig_node
);
kfree
(
orig_node
);
...
@@ -205,14 +214,18 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
...
@@ -205,14 +214,18 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, const uint8_t *addr)
spin_lock_init
(
&
orig_node
->
ogm_cnt_lock
);
spin_lock_init
(
&
orig_node
->
ogm_cnt_lock
);
spin_lock_init
(
&
orig_node
->
bcast_seqno_lock
);
spin_lock_init
(
&
orig_node
->
bcast_seqno_lock
);
spin_lock_init
(
&
orig_node
->
neigh_list_lock
);
spin_lock_init
(
&
orig_node
->
neigh_list_lock
);
spin_lock_init
(
&
orig_node
->
tt_buff_lock
);
/* extra reference for return */
/* extra reference for return */
atomic_set
(
&
orig_node
->
refcount
,
2
);
atomic_set
(
&
orig_node
->
refcount
,
2
);
orig_node
->
tt_poss_change
=
false
;
orig_node
->
bat_priv
=
bat_priv
;
orig_node
->
bat_priv
=
bat_priv
;
memcpy
(
orig_node
->
orig
,
addr
,
ETH_ALEN
);
memcpy
(
orig_node
->
orig
,
addr
,
ETH_ALEN
);
orig_node
->
router
=
NULL
;
orig_node
->
router
=
NULL
;
orig_node
->
tt_buff
=
NULL
;
orig_node
->
tt_buff
=
NULL
;
orig_node
->
tt_buff_len
=
0
;
atomic_set
(
&
orig_node
->
tt_size
,
0
);
orig_node
->
bcast_seqno_reset
=
jiffies
-
1
orig_node
->
bcast_seqno_reset
=
jiffies
-
1
-
msecs_to_jiffies
(
RESET_PROTECTION_MS
);
-
msecs_to_jiffies
(
RESET_PROTECTION_MS
);
orig_node
->
batman_seqno_reset
=
jiffies
-
1
orig_node
->
batman_seqno_reset
=
jiffies
-
1
...
@@ -322,9 +335,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
...
@@ -322,9 +335,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv,
if
(
purge_orig_neighbors
(
bat_priv
,
orig_node
,
if
(
purge_orig_neighbors
(
bat_priv
,
orig_node
,
&
best_neigh_node
))
{
&
best_neigh_node
))
{
update_routes
(
bat_priv
,
orig_node
,
update_routes
(
bat_priv
,
orig_node
,
best_neigh_node
,
best_neigh_node
);
orig_node
->
tt_buff
,
orig_node
->
tt_buff_len
);
}
}
}
}
...
...
net/batman-adv/originator.h
View file @
eac56465
...
@@ -40,14 +40,6 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num);
...
@@ -40,14 +40,6 @@ int orig_hash_add_if(struct hard_iface *hard_iface, int max_if_num);
int
orig_hash_del_if
(
struct
hard_iface
*
hard_iface
,
int
max_if_num
);
int
orig_hash_del_if
(
struct
hard_iface
*
hard_iface
,
int
max_if_num
);
/* returns 1 if they are the same originator */
static
inline
int
compare_orig
(
const
struct
hlist_node
*
node
,
const
void
*
data2
)
{
const
void
*
data1
=
container_of
(
node
,
struct
orig_node
,
hash_entry
);
return
(
memcmp
(
data1
,
data2
,
ETH_ALEN
)
==
0
?
1
:
0
);
}
/* hashfunction to choose an entry in a hash table of given size */
/* hashfunction to choose an entry in a hash table of given size */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
static
inline
int
choose_orig
(
const
void
*
data
,
int32_t
size
)
static
inline
int
choose_orig
(
const
void
*
data
,
int32_t
size
)
...
...
net/batman-adv/packet.h
View file @
eac56465
...
@@ -30,11 +30,13 @@ enum bat_packettype {
...
@@ -30,11 +30,13 @@ enum bat_packettype {
BAT_UNICAST
=
0x03
,
BAT_UNICAST
=
0x03
,
BAT_BCAST
=
0x04
,
BAT_BCAST
=
0x04
,
BAT_VIS
=
0x05
,
BAT_VIS
=
0x05
,
BAT_UNICAST_FRAG
=
0x06
BAT_UNICAST_FRAG
=
0x06
,
BAT_TT_QUERY
=
0x07
,
BAT_ROAM_ADV
=
0x08
};
};
/* this file is included by batctl which needs these defines */
/* this file is included by batctl which needs these defines */
#define COMPAT_VERSION 1
2
#define COMPAT_VERSION 1
4
enum
batman_flags
{
enum
batman_flags
{
PRIMARIES_FIRST_HOP
=
1
<<
4
,
PRIMARIES_FIRST_HOP
=
1
<<
4
,
...
@@ -63,18 +65,38 @@ enum unicast_frag_flags {
...
@@ -63,18 +65,38 @@ enum unicast_frag_flags {
UNI_FRAG_LARGETAIL
=
1
<<
1
UNI_FRAG_LARGETAIL
=
1
<<
1
};
};
/* TT_QUERY subtypes */
#define TT_QUERY_TYPE_MASK 0x3
enum
tt_query_packettype
{
TT_REQUEST
=
0
,
TT_RESPONSE
=
1
};
/* TT_QUERY flags */
enum
tt_query_flags
{
TT_FULL_TABLE
=
1
<<
2
};
/* TT_CHANGE flags */
enum
tt_change_flags
{
TT_CHANGE_DEL
=
0x01
,
TT_CLIENT_ROAM
=
0x02
};
struct
batman_packet
{
struct
batman_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
ttl
;
uint8_t
flags
;
/* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
uint8_t
flags
;
/* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
uint8_t
tq
;
uint32_t
seqno
;
uint32_t
seqno
;
uint8_t
orig
[
6
];
uint8_t
orig
[
6
];
uint8_t
prev_sender
[
6
];
uint8_t
prev_sender
[
6
];
uint8_t
ttl
;
uint8_t
num_tt
;
uint8_t
gw_flags
;
/* flags related to gateway class */
uint8_t
gw_flags
;
/* flags related to gateway class */
uint8_t
align
;
uint8_t
tq
;
uint8_t
tt_num_changes
;
uint8_t
ttvn
;
/* translation table version number */
uint16_t
tt_crc
;
}
__packed
;
}
__packed
;
#define BAT_PACKET_LEN sizeof(struct batman_packet)
#define BAT_PACKET_LEN sizeof(struct batman_packet)
...
@@ -82,12 +104,13 @@ struct batman_packet {
...
@@ -82,12 +104,13 @@ struct batman_packet {
struct
icmp_packet
{
struct
icmp_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
msg_type
;
/* see ICMP message types above */
uint8_t
ttl
;
uint8_t
ttl
;
uint8_t
msg_type
;
/* see ICMP message types above */
uint8_t
dst
[
6
];
uint8_t
dst
[
6
];
uint8_t
orig
[
6
];
uint8_t
orig
[
6
];
uint16_t
seqno
;
uint16_t
seqno
;
uint8_t
uid
;
uint8_t
uid
;
uint8_t
reserved
;
}
__packed
;
}
__packed
;
#define BAT_RR_LEN 16
#define BAT_RR_LEN 16
...
@@ -97,8 +120,8 @@ struct icmp_packet {
...
@@ -97,8 +120,8 @@ struct icmp_packet {
struct
icmp_packet_rr
{
struct
icmp_packet_rr
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
msg_type
;
/* see ICMP message types above */
uint8_t
ttl
;
uint8_t
ttl
;
uint8_t
msg_type
;
/* see ICMP message types above */
uint8_t
dst
[
6
];
uint8_t
dst
[
6
];
uint8_t
orig
[
6
];
uint8_t
orig
[
6
];
uint16_t
seqno
;
uint16_t
seqno
;
...
@@ -110,16 +133,19 @@ struct icmp_packet_rr {
...
@@ -110,16 +133,19 @@ struct icmp_packet_rr {
struct
unicast_packet
{
struct
unicast_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
dest
[
6
];
uint8_t
ttl
;
uint8_t
ttl
;
uint8_t
ttvn
;
/* destination translation table version number */
uint8_t
dest
[
6
];
}
__packed
;
}
__packed
;
struct
unicast_frag_packet
{
struct
unicast_frag_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
dest
[
6
];
uint8_t
ttl
;
uint8_t
ttl
;
uint8_t
ttvn
;
/* destination translation table version number */
uint8_t
dest
[
6
];
uint8_t
flags
;
uint8_t
flags
;
uint8_t
align
;
uint8_t
orig
[
6
];
uint8_t
orig
[
6
];
uint16_t
seqno
;
uint16_t
seqno
;
}
__packed
;
}
__packed
;
...
@@ -127,21 +153,61 @@ struct unicast_frag_packet {
...
@@ -127,21 +153,61 @@ struct unicast_frag_packet {
struct
bcast_packet
{
struct
bcast_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
orig
[
6
];
uint8_t
ttl
;
uint8_t
ttl
;
uint8_t
reserved
;
uint32_t
seqno
;
uint32_t
seqno
;
uint8_t
orig
[
6
];
}
__packed
;
}
__packed
;
struct
vis_packet
{
struct
vis_packet
{
uint8_t
packet_type
;
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
version
;
/* batman version field */
uint8_t
ttl
;
/* TTL */
uint8_t
vis_type
;
/* which type of vis-participant sent this? */
uint8_t
vis_type
;
/* which type of vis-participant sent this? */
uint8_t
entries
;
/* number of entries behind this struct */
uint32_t
seqno
;
/* sequence number */
uint32_t
seqno
;
/* sequence number */
uint8_t
ttl
;
/* TTL */
uint8_t
entries
;
/* number of entries behind this struct */
uint8_t
reserved
;
uint8_t
vis_orig
[
6
];
/* originator that announces its neighbors */
uint8_t
vis_orig
[
6
];
/* originator that announces its neighbors */
uint8_t
target_orig
[
6
];
/* who should receive this packet */
uint8_t
target_orig
[
6
];
/* who should receive this packet */
uint8_t
sender_orig
[
6
];
/* who sent or rebroadcasted this packet */
uint8_t
sender_orig
[
6
];
/* who sent or rebroadcasted this packet */
}
__packed
;
}
__packed
;
struct
tt_query_packet
{
uint8_t
packet_type
;
uint8_t
version
;
/* batman version field */
uint8_t
ttl
;
/* the flag field is a combination of:
* - TT_REQUEST or TT_RESPONSE
* - TT_FULL_TABLE */
uint8_t
flags
;
uint8_t
dst
[
ETH_ALEN
];
uint8_t
src
[
ETH_ALEN
];
/* the ttvn field is:
* if TT_REQUEST: ttvn that triggered the
* request
* if TT_RESPONSE: new ttvn for the src
* orig_node */
uint8_t
ttvn
;
/* tt_data field is:
* if TT_REQUEST: crc associated with the
* ttvn
* if TT_RESPONSE: table_size */
uint16_t
tt_data
;
}
__packed
;
struct
roam_adv_packet
{
uint8_t
packet_type
;
uint8_t
version
;
uint8_t
ttl
;
uint8_t
reserved
;
uint8_t
dst
[
ETH_ALEN
];
uint8_t
src
[
ETH_ALEN
];
uint8_t
client
[
ETH_ALEN
];
}
__packed
;
struct
tt_change
{
uint8_t
flags
;
uint8_t
addr
[
ETH_ALEN
];
}
__packed
;
#endif
/* _NET_BATMAN_ADV_PACKET_H_ */
#endif
/* _NET_BATMAN_ADV_PACKET_H_ */
net/batman-adv/routing.c
View file @
eac56465
This diff is collapsed.
Click to expand it.
net/batman-adv/routing.h
View file @
eac56465
...
@@ -25,11 +25,10 @@
...
@@ -25,11 +25,10 @@
void
slide_own_bcast_window
(
struct
hard_iface
*
hard_iface
);
void
slide_own_bcast_window
(
struct
hard_iface
*
hard_iface
);
void
receive_bat_packet
(
const
struct
ethhdr
*
ethhdr
,
void
receive_bat_packet
(
const
struct
ethhdr
*
ethhdr
,
struct
batman_packet
*
batman_packet
,
struct
batman_packet
*
batman_packet
,
const
unsigned
char
*
tt_buff
,
int
tt_buff_len
,
const
unsigned
char
*
tt_buff
,
struct
hard_iface
*
if_incoming
);
struct
hard_iface
*
if_incoming
);
void
update_routes
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
void
update_routes
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
struct
neigh_node
*
neigh_node
,
const
unsigned
char
*
tt_buff
,
struct
neigh_node
*
neigh_node
);
int
tt_buff_len
);
int
route_unicast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
route_unicast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_icmp_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_icmp_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_unicast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_unicast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
...
@@ -37,6 +36,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if);
...
@@ -37,6 +36,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct hard_iface *recv_if);
int
recv_bcast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_bcast_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_vis_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_vis_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_bat_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_bat_packet
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_tt_query
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
int
recv_roam_adv
(
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
);
struct
neigh_node
*
find_router
(
struct
bat_priv
*
bat_priv
,
struct
neigh_node
*
find_router
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
struct
orig_node
*
orig_node
,
const
struct
hard_iface
*
recv_if
);
const
struct
hard_iface
*
recv_if
);
...
...
net/batman-adv/send.c
View file @
eac56465
...
@@ -120,7 +120,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
...
@@ -120,7 +120,7 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
/* adjust all flags and log packets */
/* adjust all flags and log packets */
while
(
aggregated_packet
(
buff_pos
,
while
(
aggregated_packet
(
buff_pos
,
forw_packet
->
packet_len
,
forw_packet
->
packet_len
,
batman_packet
->
num_tt
))
{
batman_packet
->
tt_num_changes
))
{
/* we might have aggregated direct link packets with an
/* we might have aggregated direct link packets with an
* ordinary base packet */
* ordinary base packet */
...
@@ -135,17 +135,17 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
...
@@ -135,17 +135,17 @@ static void send_packet_to_if(struct forw_packet *forw_packet,
"Forwarding"
));
"Forwarding"
));
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d,"
" IDF %s) on interface %s [%pM]
\n
"
,
" IDF %s
, hvn %d
) on interface %s [%pM]
\n
"
,
fwd_str
,
(
packet_num
>
0
?
"aggregated "
:
""
),
fwd_str
,
(
packet_num
>
0
?
"aggregated "
:
""
),
batman_packet
->
orig
,
ntohl
(
batman_packet
->
seqno
),
batman_packet
->
orig
,
ntohl
(
batman_packet
->
seqno
),
batman_packet
->
tq
,
batman_packet
->
ttl
,
batman_packet
->
tq
,
batman_packet
->
ttl
,
(
batman_packet
->
flags
&
DIRECTLINK
?
(
batman_packet
->
flags
&
DIRECTLINK
?
"on"
:
"off"
),
"on"
:
"off"
),
hard_iface
->
net_dev
->
name
,
batman_packet
->
ttvn
,
hard_iface
->
net_dev
->
name
,
hard_iface
->
net_dev
->
dev_addr
);
hard_iface
->
net_dev
->
dev_addr
);
buff_pos
+=
sizeof
(
*
batman_packet
)
+
buff_pos
+=
sizeof
(
*
batman_packet
)
+
(
batman_packet
->
num_tt
*
ETH_ALEN
);
tt_len
(
batman_packet
->
tt_num_changes
);
packet_num
++
;
packet_num
++
;
batman_packet
=
(
struct
batman_packet
*
)
batman_packet
=
(
struct
batman_packet
*
)
(
forw_packet
->
skb
->
data
+
buff_pos
);
(
forw_packet
->
skb
->
data
+
buff_pos
);
...
@@ -165,7 +165,7 @@ static void send_packet(struct forw_packet *forw_packet)
...
@@ -165,7 +165,7 @@ static void send_packet(struct forw_packet *forw_packet)
struct
bat_priv
*
bat_priv
;
struct
bat_priv
*
bat_priv
;
struct
batman_packet
*
batman_packet
=
struct
batman_packet
*
batman_packet
=
(
struct
batman_packet
*
)(
forw_packet
->
skb
->
data
);
(
struct
batman_packet
*
)(
forw_packet
->
skb
->
data
);
unsigned
char
directlink
=
(
batman_packet
->
flags
&
DIRECTLINK
?
1
:
0
);
int
directlink
=
(
batman_packet
->
flags
&
DIRECTLINK
?
1
:
0
);
if
(
!
forw_packet
->
if_incoming
)
{
if
(
!
forw_packet
->
if_incoming
)
{
pr_err
(
"Error - can't forward packet: incoming iface not "
pr_err
(
"Error - can't forward packet: incoming iface not "
...
@@ -213,25 +213,18 @@ static void send_packet(struct forw_packet *forw_packet)
...
@@ -213,25 +213,18 @@ static void send_packet(struct forw_packet *forw_packet)
rcu_read_unlock
();
rcu_read_unlock
();
}
}
static
void
re
build_batman_packet
(
struct
bat_priv
*
bat_priv
,
static
void
re
alloc_packet_buffer
(
struct
hard_iface
*
hard_iface
,
struct
hard_iface
*
hard_iface
)
int
new_len
)
{
{
int
new_len
;
unsigned
char
*
new_buff
;
unsigned
char
*
new_buff
;
struct
batman_packet
*
batman_packet
;
struct
batman_packet
*
batman_packet
;
new_len
=
sizeof
(
*
batman_packet
)
+
(
bat_priv
->
num_local_tt
*
ETH_ALEN
);
new_buff
=
kmalloc
(
new_len
,
GFP_ATOMIC
);
new_buff
=
kmalloc
(
new_len
,
GFP_ATOMIC
);
/* keep old buffer if kmalloc should fail */
/* keep old buffer if kmalloc should fail */
if
(
new_buff
)
{
if
(
new_buff
)
{
memcpy
(
new_buff
,
hard_iface
->
packet_buff
,
memcpy
(
new_buff
,
hard_iface
->
packet_buff
,
sizeof
(
*
batman_packet
));
sizeof
(
*
batman_packet
));
batman_packet
=
(
struct
batman_packet
*
)
new_buff
;
batman_packet
->
num_tt
=
tt_local_fill_buffer
(
bat_priv
,
new_buff
+
sizeof
(
*
batman_packet
),
new_len
-
sizeof
(
*
batman_packet
));
kfree
(
hard_iface
->
packet_buff
);
kfree
(
hard_iface
->
packet_buff
);
hard_iface
->
packet_buff
=
new_buff
;
hard_iface
->
packet_buff
=
new_buff
;
...
@@ -239,6 +232,46 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
...
@@ -239,6 +232,46 @@ static void rebuild_batman_packet(struct bat_priv *bat_priv,
}
}
}
}
/* when calling this function (hard_iface == primary_if) has to be true */
static
void
prepare_packet_buffer
(
struct
bat_priv
*
bat_priv
,
struct
hard_iface
*
hard_iface
)
{
int
new_len
;
struct
batman_packet
*
batman_packet
;
new_len
=
BAT_PACKET_LEN
+
tt_len
((
uint8_t
)
atomic_read
(
&
bat_priv
->
tt_local_changes
));
/* if we have too many changes for one packet don't send any
* and wait for the tt table request which will be fragmented */
if
(
new_len
>
hard_iface
->
soft_iface
->
mtu
)
new_len
=
BAT_PACKET_LEN
;
realloc_packet_buffer
(
hard_iface
,
new_len
);
batman_packet
=
(
struct
batman_packet
*
)
hard_iface
->
packet_buff
;
atomic_set
(
&
bat_priv
->
tt_crc
,
tt_local_crc
(
bat_priv
));
/* reset the sending counter */
atomic_set
(
&
bat_priv
->
tt_ogm_append_cnt
,
TT_OGM_APPEND_MAX
);
batman_packet
->
tt_num_changes
=
tt_changes_fill_buffer
(
bat_priv
,
hard_iface
->
packet_buff
+
BAT_PACKET_LEN
,
hard_iface
->
packet_len
-
BAT_PACKET_LEN
);
}
static
void
reset_packet_buffer
(
struct
bat_priv
*
bat_priv
,
struct
hard_iface
*
hard_iface
)
{
struct
batman_packet
*
batman_packet
;
realloc_packet_buffer
(
hard_iface
,
BAT_PACKET_LEN
);
batman_packet
=
(
struct
batman_packet
*
)
hard_iface
->
packet_buff
;
batman_packet
->
tt_num_changes
=
0
;
}
void
schedule_own_packet
(
struct
hard_iface
*
hard_iface
)
void
schedule_own_packet
(
struct
hard_iface
*
hard_iface
)
{
{
struct
bat_priv
*
bat_priv
=
netdev_priv
(
hard_iface
->
soft_iface
);
struct
bat_priv
*
bat_priv
=
netdev_priv
(
hard_iface
->
soft_iface
);
...
@@ -264,14 +297,23 @@ void schedule_own_packet(struct hard_iface *hard_iface)
...
@@ -264,14 +297,23 @@ void schedule_own_packet(struct hard_iface *hard_iface)
if
(
hard_iface
->
if_status
==
IF_TO_BE_ACTIVATED
)
if
(
hard_iface
->
if_status
==
IF_TO_BE_ACTIVATED
)
hard_iface
->
if_status
=
IF_ACTIVE
;
hard_iface
->
if_status
=
IF_ACTIVE
;
/* if local tt has changed and interface is a primary interface */
if
(
hard_iface
==
primary_if
)
{
if
((
atomic_read
(
&
bat_priv
->
tt_local_changed
))
&&
/* if at least one change happened */
(
hard_iface
==
primary_if
))
if
(
atomic_read
(
&
bat_priv
->
tt_local_changes
)
>
0
)
{
rebuild_batman_packet
(
bat_priv
,
hard_iface
);
prepare_packet_buffer
(
bat_priv
,
hard_iface
);
/* Increment the TTVN only once per OGM interval */
atomic_inc
(
&
bat_priv
->
ttvn
);
bat_priv
->
tt_poss_change
=
false
;
}
/* if the changes have been sent enough times */
if
(
!
atomic_dec_not_zero
(
&
bat_priv
->
tt_ogm_append_cnt
))
reset_packet_buffer
(
bat_priv
,
hard_iface
);
}
/**
/**
* NOTE: packet_buff might just have been re-allocated in
* NOTE: packet_buff might just have been re-allocated in
*
rebuild_batman_packet
()
*
prepare_packet_buffer() or in reset_packet_buffer
()
*/
*/
batman_packet
=
(
struct
batman_packet
*
)
hard_iface
->
packet_buff
;
batman_packet
=
(
struct
batman_packet
*
)
hard_iface
->
packet_buff
;
...
@@ -279,6 +321,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
...
@@ -279,6 +321,9 @@ void schedule_own_packet(struct hard_iface *hard_iface)
batman_packet
->
seqno
=
batman_packet
->
seqno
=
htonl
((
uint32_t
)
atomic_read
(
&
hard_iface
->
seqno
));
htonl
((
uint32_t
)
atomic_read
(
&
hard_iface
->
seqno
));
batman_packet
->
ttvn
=
atomic_read
(
&
bat_priv
->
ttvn
);
batman_packet
->
tt_crc
=
htons
((
uint16_t
)
atomic_read
(
&
bat_priv
->
tt_crc
));
if
(
vis_server
==
VIS_TYPE_SERVER_SYNC
)
if
(
vis_server
==
VIS_TYPE_SERVER_SYNC
)
batman_packet
->
flags
|=
VIS_SERVER
;
batman_packet
->
flags
|=
VIS_SERVER
;
else
else
...
@@ -307,13 +352,14 @@ void schedule_own_packet(struct hard_iface *hard_iface)
...
@@ -307,13 +352,14 @@ void schedule_own_packet(struct hard_iface *hard_iface)
void
schedule_forward_packet
(
struct
orig_node
*
orig_node
,
void
schedule_forward_packet
(
struct
orig_node
*
orig_node
,
const
struct
ethhdr
*
ethhdr
,
const
struct
ethhdr
*
ethhdr
,
struct
batman_packet
*
batman_packet
,
struct
batman_packet
*
batman_packet
,
uint8_t
directlink
,
int
tt_buff_len
,
int
directlink
,
struct
hard_iface
*
if_incoming
)
struct
hard_iface
*
if_incoming
)
{
{
struct
bat_priv
*
bat_priv
=
netdev_priv
(
if_incoming
->
soft_iface
);
struct
bat_priv
*
bat_priv
=
netdev_priv
(
if_incoming
->
soft_iface
);
struct
neigh_node
*
router
;
struct
neigh_node
*
router
;
u
nsigned
char
in_tq
,
in_ttl
,
tq_avg
=
0
;
u
int8_t
in_tq
,
in_ttl
,
tq_avg
=
0
;
unsigned
long
send_time
;
unsigned
long
send_time
;
uint8_t
tt_num_changes
;
if
(
batman_packet
->
ttl
<=
1
)
{
if
(
batman_packet
->
ttl
<=
1
)
{
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"ttl exceeded
\n
"
);
bat_dbg
(
DBG_BATMAN
,
bat_priv
,
"ttl exceeded
\n
"
);
...
@@ -324,6 +370,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
...
@@ -324,6 +370,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
in_tq
=
batman_packet
->
tq
;
in_tq
=
batman_packet
->
tq
;
in_ttl
=
batman_packet
->
ttl
;
in_ttl
=
batman_packet
->
ttl
;
tt_num_changes
=
batman_packet
->
tt_num_changes
;
batman_packet
->
ttl
--
;
batman_packet
->
ttl
--
;
memcpy
(
batman_packet
->
prev_sender
,
ethhdr
->
h_source
,
ETH_ALEN
);
memcpy
(
batman_packet
->
prev_sender
,
ethhdr
->
h_source
,
ETH_ALEN
);
...
@@ -356,6 +403,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
...
@@ -356,6 +403,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
batman_packet
->
ttl
);
batman_packet
->
ttl
);
batman_packet
->
seqno
=
htonl
(
batman_packet
->
seqno
);
batman_packet
->
seqno
=
htonl
(
batman_packet
->
seqno
);
batman_packet
->
tt_crc
=
htons
(
batman_packet
->
tt_crc
);
/* switch of primaries first hop flag when forwarding */
/* switch of primaries first hop flag when forwarding */
batman_packet
->
flags
&=
~
PRIMARIES_FIRST_HOP
;
batman_packet
->
flags
&=
~
PRIMARIES_FIRST_HOP
;
...
@@ -367,7 +415,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
...
@@ -367,7 +415,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
send_time
=
forward_send_time
();
send_time
=
forward_send_time
();
add_bat_packet_to_list
(
bat_priv
,
add_bat_packet_to_list
(
bat_priv
,
(
unsigned
char
*
)
batman_packet
,
(
unsigned
char
*
)
batman_packet
,
sizeof
(
*
batman_packet
)
+
tt_
buff_len
,
sizeof
(
*
batman_packet
)
+
tt_
len
(
tt_num_changes
)
,
if_incoming
,
0
,
send_time
);
if_incoming
,
0
,
send_time
);
}
}
...
...
net/batman-adv/send.h
View file @
eac56465
...
@@ -28,7 +28,7 @@ void schedule_own_packet(struct hard_iface *hard_iface);
...
@@ -28,7 +28,7 @@ void schedule_own_packet(struct hard_iface *hard_iface);
void
schedule_forward_packet
(
struct
orig_node
*
orig_node
,
void
schedule_forward_packet
(
struct
orig_node
*
orig_node
,
const
struct
ethhdr
*
ethhdr
,
const
struct
ethhdr
*
ethhdr
,
struct
batman_packet
*
batman_packet
,
struct
batman_packet
*
batman_packet
,
uint8_t
directlink
,
int
tt_buff_len
,
int
directlink
,
struct
hard_iface
*
if_outgoing
);
struct
hard_iface
*
if_outgoing
);
int
add_bcast_packet_to_list
(
struct
bat_priv
*
bat_priv
,
int
add_bcast_packet_to_list
(
struct
bat_priv
*
bat_priv
,
const
struct
sk_buff
*
skb
);
const
struct
sk_buff
*
skb
);
...
...
net/batman-adv/soft-interface.c
View file @
eac56465
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "gateway_common.h"
#include "gateway_common.h"
#include "gateway_client.h"
#include "gateway_client.h"
#include "bat_sysfs.h"
#include "bat_sysfs.h"
#include "originator.h"
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
...
@@ -380,7 +381,7 @@ void softif_neigh_purge(struct bat_priv *bat_priv)
...
@@ -380,7 +381,7 @@ void softif_neigh_purge(struct bat_priv *bat_priv)
struct
softif_neigh
*
softif_neigh
,
*
curr_softif_neigh
;
struct
softif_neigh
*
softif_neigh
,
*
curr_softif_neigh
;
struct
softif_neigh_vid
*
softif_neigh_vid
;
struct
softif_neigh_vid
*
softif_neigh_vid
;
struct
hlist_node
*
node
,
*
node_tmp
,
*
node_tmp2
;
struct
hlist_node
*
node
,
*
node_tmp
,
*
node_tmp2
;
char
do_deselect
;
int
do_deselect
;
rcu_read_lock
();
rcu_read_lock
();
hlist_for_each_entry_rcu
(
softif_neigh_vid
,
node
,
hlist_for_each_entry_rcu
(
softif_neigh_vid
,
node
,
...
@@ -534,7 +535,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
...
@@ -534,7 +535,7 @@ static int interface_set_mac_addr(struct net_device *dev, void *p)
/* only modify transtable if it has been initialised before */
/* only modify transtable if it has been initialised before */
if
(
atomic_read
(
&
bat_priv
->
mesh_state
)
==
MESH_ACTIVE
)
{
if
(
atomic_read
(
&
bat_priv
->
mesh_state
)
==
MESH_ACTIVE
)
{
tt_local_remove
(
bat_priv
,
dev
->
dev_addr
,
tt_local_remove
(
bat_priv
,
dev
->
dev_addr
,
"mac address changed"
);
"mac address changed"
,
false
);
tt_local_add
(
dev
,
addr
->
sa_data
);
tt_local_add
(
dev
,
addr
->
sa_data
);
}
}
...
@@ -553,7 +554,7 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu)
...
@@ -553,7 +554,7 @@ static int interface_change_mtu(struct net_device *dev, int new_mtu)
return
0
;
return
0
;
}
}
int
interface_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
soft_iface
)
static
int
interface_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
soft_iface
)
{
{
struct
ethhdr
*
ethhdr
=
(
struct
ethhdr
*
)
skb
->
data
;
struct
ethhdr
*
ethhdr
=
(
struct
ethhdr
*
)
skb
->
data
;
struct
bat_priv
*
bat_priv
=
netdev_priv
(
soft_iface
);
struct
bat_priv
*
bat_priv
=
netdev_priv
(
soft_iface
);
...
@@ -561,6 +562,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
...
@@ -561,6 +562,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
struct
bcast_packet
*
bcast_packet
;
struct
bcast_packet
*
bcast_packet
;
struct
vlan_ethhdr
*
vhdr
;
struct
vlan_ethhdr
*
vhdr
;
struct
softif_neigh
*
curr_softif_neigh
=
NULL
;
struct
softif_neigh
*
curr_softif_neigh
=
NULL
;
struct
orig_node
*
orig_node
=
NULL
;
int
data_len
=
skb
->
len
,
ret
;
int
data_len
=
skb
->
len
,
ret
;
short
vid
=
-
1
;
short
vid
=
-
1
;
bool
do_bcast
=
false
;
bool
do_bcast
=
false
;
...
@@ -592,11 +594,13 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
...
@@ -592,11 +594,13 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
if
(
curr_softif_neigh
)
if
(
curr_softif_neigh
)
goto
dropped
;
goto
dropped
;
/*
TODO: check this for locks
*/
/*
Register the client MAC in the transtable
*/
tt_local_add
(
soft_iface
,
ethhdr
->
h_source
);
tt_local_add
(
soft_iface
,
ethhdr
->
h_source
);
if
(
is_multicast_ether_addr
(
ethhdr
->
h_dest
))
{
orig_node
=
transtable_search
(
bat_priv
,
ethhdr
->
h_dest
);
ret
=
gw_is_target
(
bat_priv
,
skb
);
if
(
is_multicast_ether_addr
(
ethhdr
->
h_dest
)
||
(
orig_node
&&
orig_node
->
gw_flags
))
{
ret
=
gw_is_target
(
bat_priv
,
skb
,
orig_node
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
dropped
;
goto
dropped
;
...
@@ -656,6 +660,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
...
@@ -656,6 +660,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
softif_neigh_free_ref
(
curr_softif_neigh
);
softif_neigh_free_ref
(
curr_softif_neigh
);
if
(
primary_if
)
if
(
primary_if
)
hardif_free_ref
(
primary_if
);
hardif_free_ref
(
primary_if
);
if
(
orig_node
)
orig_node_free_ref
(
orig_node
);
return
NETDEV_TX_OK
;
return
NETDEV_TX_OK
;
}
}
...
@@ -830,7 +836,13 @@ struct net_device *softif_create(const char *name)
...
@@ -830,7 +836,13 @@ struct net_device *softif_create(const char *name)
atomic_set
(
&
bat_priv
->
mesh_state
,
MESH_INACTIVE
);
atomic_set
(
&
bat_priv
->
mesh_state
,
MESH_INACTIVE
);
atomic_set
(
&
bat_priv
->
bcast_seqno
,
1
);
atomic_set
(
&
bat_priv
->
bcast_seqno
,
1
);
atomic_set
(
&
bat_priv
->
tt_local_changed
,
0
);
atomic_set
(
&
bat_priv
->
ttvn
,
0
);
atomic_set
(
&
bat_priv
->
tt_local_changes
,
0
);
atomic_set
(
&
bat_priv
->
tt_ogm_append_cnt
,
0
);
bat_priv
->
tt_buff
=
NULL
;
bat_priv
->
tt_buff_len
=
0
;
bat_priv
->
tt_poss_change
=
false
;
bat_priv
->
primary_if
=
NULL
;
bat_priv
->
primary_if
=
NULL
;
bat_priv
->
num_ifaces
=
0
;
bat_priv
->
num_ifaces
=
0
;
...
...
net/batman-adv/soft-interface.h
View file @
eac56465
...
@@ -25,7 +25,6 @@
...
@@ -25,7 +25,6 @@
int
my_skb_head_push
(
struct
sk_buff
*
skb
,
unsigned
int
len
);
int
my_skb_head_push
(
struct
sk_buff
*
skb
,
unsigned
int
len
);
int
softif_neigh_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
int
softif_neigh_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
void
softif_neigh_purge
(
struct
bat_priv
*
bat_priv
);
void
softif_neigh_purge
(
struct
bat_priv
*
bat_priv
);
int
interface_tx
(
struct
sk_buff
*
skb
,
struct
net_device
*
soft_iface
);
void
interface_rx
(
struct
net_device
*
soft_iface
,
void
interface_rx
(
struct
net_device
*
soft_iface
,
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
,
struct
sk_buff
*
skb
,
struct
hard_iface
*
recv_if
,
int
hdr_size
);
int
hdr_size
);
...
...
net/batman-adv/translation-table.c
View file @
eac56465
This diff is collapsed.
Click to expand it.
net/batman-adv/translation-table.h
View file @
eac56465
...
@@ -22,23 +22,45 @@
...
@@ -22,23 +22,45 @@
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_
int
tt_local_init
(
struct
bat_priv
*
bat_priv
);
int
tt_len
(
int
changes_num
);
int
tt_changes_fill_buffer
(
struct
bat_priv
*
bat_priv
,
unsigned
char
*
buff
,
int
buff_len
);
int
tt_init
(
struct
bat_priv
*
bat_priv
);
void
tt_local_add
(
struct
net_device
*
soft_iface
,
const
uint8_t
*
addr
);
void
tt_local_add
(
struct
net_device
*
soft_iface
,
const
uint8_t
*
addr
);
void
tt_local_remove
(
struct
bat_priv
*
bat_priv
,
void
tt_local_remove
(
struct
bat_priv
*
bat_priv
,
const
uint8_t
*
addr
,
const
char
*
message
);
const
uint8_t
*
addr
,
const
char
*
message
,
bool
roaming
);
int
tt_local_fill_buffer
(
struct
bat_priv
*
bat_priv
,
unsigned
char
*
buff
,
int
buff_len
);
int
tt_local_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
int
tt_local_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
void
tt_local_free
(
struct
bat_priv
*
bat_priv
);
int
tt_global_init
(
struct
bat_priv
*
bat_priv
);
void
tt_global_add_orig
(
struct
bat_priv
*
bat_priv
,
void
tt_global_add_orig
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
struct
orig_node
*
orig_node
,
const
unsigned
char
*
tt_buff
,
int
tt_buff_len
);
const
unsigned
char
*
tt_buff
,
int
tt_buff_len
);
int
tt_global_add
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
const
unsigned
char
*
addr
,
uint8_t
ttvn
,
bool
roaming
);
int
tt_global_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
int
tt_global_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
void
tt_global_del_orig
(
struct
bat_priv
*
bat_priv
,
void
tt_global_del_orig
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
const
char
*
message
);
struct
orig_node
*
orig_node
,
const
char
*
message
);
void
tt_global_free
(
struct
bat_priv
*
bat_priv
);
void
tt_global_del
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
const
unsigned
char
*
addr
,
const
char
*
message
,
bool
roaming
);
struct
orig_node
*
transtable_search
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
transtable_search
(
struct
bat_priv
*
bat_priv
,
const
uint8_t
*
addr
);
const
uint8_t
*
addr
);
void
tt_save_orig_buffer
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
const
unsigned
char
*
tt_buff
,
uint8_t
tt_num_changes
);
uint16_t
tt_local_crc
(
struct
bat_priv
*
bat_priv
);
uint16_t
tt_global_crc
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
);
void
tt_free
(
struct
bat_priv
*
bat_priv
);
int
send_tt_request
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
dst_orig_node
,
uint8_t
hvn
,
uint16_t
tt_crc
,
bool
full_table
);
bool
send_tt_response
(
struct
bat_priv
*
bat_priv
,
struct
tt_query_packet
*
tt_request
);
void
tt_update_changes
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
uint16_t
tt_num_changes
,
uint8_t
ttvn
,
struct
tt_change
*
tt_change
);
bool
is_my_client
(
struct
bat_priv
*
bat_priv
,
const
uint8_t
*
addr
);
void
handle_tt_response
(
struct
bat_priv
*
bat_priv
,
struct
tt_query_packet
*
tt_response
);
void
send_roam_adv
(
struct
bat_priv
*
bat_priv
,
uint8_t
*
client
,
struct
orig_node
*
orig_node
);
#endif
/* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
#endif
/* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
net/batman-adv/types.h
View file @
eac56465
...
@@ -75,8 +75,18 @@ struct orig_node {
...
@@ -75,8 +75,18 @@ struct orig_node {
unsigned
long
batman_seqno_reset
;
unsigned
long
batman_seqno_reset
;
uint8_t
gw_flags
;
uint8_t
gw_flags
;
uint8_t
flags
;
uint8_t
flags
;
atomic_t
last_ttvn
;
/* last seen translation table version number */
uint16_t
tt_crc
;
unsigned
char
*
tt_buff
;
unsigned
char
*
tt_buff
;
int16_t
tt_buff_len
;
int16_t
tt_buff_len
;
spinlock_t
tt_buff_lock
;
/* protects tt_buff */
atomic_t
tt_size
;
/* The tt_poss_change flag is used to detect an ongoing roaming phase.
* If true, then I sent a Roaming_adv to this orig_node and I have to
* inspect every packet directed to it to check whether it is still
* the true destination or not. This flag will be reset to false as
* soon as I receive a new TTVN from this orig_node */
bool
tt_poss_change
;
uint32_t
last_real_seqno
;
uint32_t
last_real_seqno
;
uint8_t
last_ttl
;
uint8_t
last_ttl
;
unsigned
long
bcast_bits
[
NUM_WORDS
];
unsigned
long
bcast_bits
[
NUM_WORDS
];
...
@@ -94,6 +104,7 @@ struct orig_node {
...
@@ -94,6 +104,7 @@ struct orig_node {
spinlock_t
ogm_cnt_lock
;
spinlock_t
ogm_cnt_lock
;
/* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
/* bcast_seqno_lock protects bcast_bits, last_bcast_seqno */
spinlock_t
bcast_seqno_lock
;
spinlock_t
bcast_seqno_lock
;
spinlock_t
tt_list_lock
;
/* protects tt_list */
atomic_t
bond_candidates
;
atomic_t
bond_candidates
;
struct
list_head
bond_list
;
struct
list_head
bond_list
;
};
};
...
@@ -145,6 +156,15 @@ struct bat_priv {
...
@@ -145,6 +156,15 @@ struct bat_priv {
atomic_t
bcast_seqno
;
atomic_t
bcast_seqno
;
atomic_t
bcast_queue_left
;
atomic_t
bcast_queue_left
;
atomic_t
batman_queue_left
;
atomic_t
batman_queue_left
;
atomic_t
ttvn
;
/* tranlation table version number */
atomic_t
tt_ogm_append_cnt
;
atomic_t
tt_local_changes
;
/* changes registered in a OGM interval */
/* The tt_poss_change flag is used to detect an ongoing roaming phase.
* If true, then I received a Roaming_adv and I have to inspect every
* packet directed to me to check whether I am still the true
* destination or not. This flag will be reset to false as soon as I
* increase my TTVN */
bool
tt_poss_change
;
char
num_ifaces
;
char
num_ifaces
;
struct
debug_log
*
debug_log
;
struct
debug_log
*
debug_log
;
struct
kobject
*
mesh_obj
;
struct
kobject
*
mesh_obj
;
...
@@ -153,26 +173,35 @@ struct bat_priv {
...
@@ -153,26 +173,35 @@ struct bat_priv {
struct
hlist_head
forw_bcast_list
;
struct
hlist_head
forw_bcast_list
;
struct
hlist_head
gw_list
;
struct
hlist_head
gw_list
;
struct
hlist_head
softif_neigh_vids
;
struct
hlist_head
softif_neigh_vids
;
struct
list_head
tt_changes_list
;
/* tracks changes in a OGM int */
struct
list_head
vis_send_list
;
struct
list_head
vis_send_list
;
struct
hashtable_t
*
orig_hash
;
struct
hashtable_t
*
orig_hash
;
struct
hashtable_t
*
tt_local_hash
;
struct
hashtable_t
*
tt_local_hash
;
struct
hashtable_t
*
tt_global_hash
;
struct
hashtable_t
*
tt_global_hash
;
struct
list_head
tt_req_list
;
/* list of pending tt_requests */
struct
list_head
tt_roam_list
;
struct
hashtable_t
*
vis_hash
;
struct
hashtable_t
*
vis_hash
;
spinlock_t
forw_bat_list_lock
;
/* protects forw_bat_list */
spinlock_t
forw_bat_list_lock
;
/* protects forw_bat_list */
spinlock_t
forw_bcast_list_lock
;
/* protects */
spinlock_t
forw_bcast_list_lock
;
/* protects */
spinlock_t
tt_lhash_lock
;
/* protects tt_local_hash */
spinlock_t
tt_changes_list_lock
;
/* protects tt_changes */
spinlock_t
tt_ghash_lock
;
/* protects tt_global_hash */
spinlock_t
tt_req_list_lock
;
/* protects tt_req_list */
spinlock_t
tt_roam_list_lock
;
/* protects tt_roam_list */
spinlock_t
gw_list_lock
;
/* protects gw_list and curr_gw */
spinlock_t
gw_list_lock
;
/* protects gw_list and curr_gw */
spinlock_t
vis_hash_lock
;
/* protects vis_hash */
spinlock_t
vis_hash_lock
;
/* protects vis_hash */
spinlock_t
vis_list_lock
;
/* protects vis_info::recv_list */
spinlock_t
vis_list_lock
;
/* protects vis_info::recv_list */
spinlock_t
softif_neigh_lock
;
/* protects soft-interface neigh list */
spinlock_t
softif_neigh_lock
;
/* protects soft-interface neigh list */
spinlock_t
softif_neigh_vid_lock
;
/* protects soft-interface vid list */
spinlock_t
softif_neigh_vid_lock
;
/* protects soft-interface vid list */
int16_t
num_local_tt
;
atomic_t
num_local_tt
;
atomic_t
tt_local_changed
;
/* Checksum of the local table, recomputed before sending a new OGM */
atomic_t
tt_crc
;
unsigned
char
*
tt_buff
;
int16_t
tt_buff_len
;
spinlock_t
tt_buff_lock
;
/* protects tt_buff */
struct
delayed_work
tt_work
;
struct
delayed_work
tt_work
;
struct
delayed_work
orig_work
;
struct
delayed_work
orig_work
;
struct
delayed_work
vis_work
;
struct
delayed_work
vis_work
;
struct
gw_node
__rcu
*
curr_gw
;
/* rcu protected pointer */
struct
gw_node
__rcu
*
curr_gw
;
/* rcu protected pointer */
atomic_t
gw_reselect
;
struct
hard_iface
__rcu
*
primary_if
;
/* rcu protected pointer */
struct
hard_iface
__rcu
*
primary_if
;
/* rcu protected pointer */
struct
vis_info
*
my_vis_info
;
struct
vis_info
*
my_vis_info
;
};
};
...
@@ -196,13 +225,38 @@ struct tt_local_entry {
...
@@ -196,13 +225,38 @@ struct tt_local_entry {
uint8_t
addr
[
ETH_ALEN
];
uint8_t
addr
[
ETH_ALEN
];
unsigned
long
last_seen
;
unsigned
long
last_seen
;
char
never_purge
;
char
never_purge
;
atomic_t
refcount
;
struct
rcu_head
rcu
;
struct
hlist_node
hash_entry
;
struct
hlist_node
hash_entry
;
};
};
struct
tt_global_entry
{
struct
tt_global_entry
{
uint8_t
addr
[
ETH_ALEN
];
uint8_t
addr
[
ETH_ALEN
];
struct
orig_node
*
orig_node
;
struct
orig_node
*
orig_node
;
struct
hlist_node
hash_entry
;
uint8_t
ttvn
;
uint8_t
flags
;
/* only TT_GLOBAL_ROAM is used */
unsigned
long
roam_at
;
/* time at which TT_GLOBAL_ROAM was set */
atomic_t
refcount
;
struct
rcu_head
rcu
;
struct
hlist_node
hash_entry
;
/* entry in the global table */
};
struct
tt_change_node
{
struct
list_head
list
;
struct
tt_change
change
;
};
struct
tt_req_node
{
uint8_t
addr
[
ETH_ALEN
];
unsigned
long
issued_at
;
struct
list_head
list
;
};
struct
tt_roam_node
{
uint8_t
addr
[
ETH_ALEN
];
atomic_t
counter
;
unsigned
long
first_time
;
struct
list_head
list
;
};
};
/**
/**
...
...
net/batman-adv/unicast.c
View file @
eac56465
...
@@ -325,6 +325,9 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
...
@@ -325,6 +325,9 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
unicast_packet
->
ttl
=
TTL
;
unicast_packet
->
ttl
=
TTL
;
/* copy the destination for faster routing */
/* copy the destination for faster routing */
memcpy
(
unicast_packet
->
dest
,
orig_node
->
orig
,
ETH_ALEN
);
memcpy
(
unicast_packet
->
dest
,
orig_node
->
orig
,
ETH_ALEN
);
/* set the destination tt version number */
unicast_packet
->
ttvn
=
(
uint8_t
)
atomic_read
(
&
orig_node
->
last_ttvn
);
if
(
atomic_read
(
&
bat_priv
->
fragmentation
)
&&
if
(
atomic_read
(
&
bat_priv
->
fragmentation
)
&&
data_len
+
sizeof
(
*
unicast_packet
)
>
data_len
+
sizeof
(
*
unicast_packet
)
>
...
...
net/batman-adv/vis.c
View file @
eac56465
...
@@ -665,11 +665,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
...
@@ -665,11 +665,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
hash
=
bat_priv
->
tt_local_hash
;
hash
=
bat_priv
->
tt_local_hash
;
spin_lock_bh
(
&
bat_priv
->
tt_lhash_lock
);
for
(
i
=
0
;
i
<
hash
->
size
;
i
++
)
{
for
(
i
=
0
;
i
<
hash
->
size
;
i
++
)
{
head
=
&
hash
->
table
[
i
];
head
=
&
hash
->
table
[
i
];
hlist_for_each_entry
(
tt_local_entry
,
node
,
head
,
hash_entry
)
{
rcu_read_lock
();
hlist_for_each_entry_rcu
(
tt_local_entry
,
node
,
head
,
hash_entry
)
{
entry
=
(
struct
vis_info_entry
*
)
entry
=
(
struct
vis_info_entry
*
)
skb_put
(
info
->
skb_packet
,
skb_put
(
info
->
skb_packet
,
sizeof
(
*
entry
));
sizeof
(
*
entry
));
...
@@ -678,14 +679,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
...
@@ -678,14 +679,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
entry
->
quality
=
0
;
/* 0 means TT */
entry
->
quality
=
0
;
/* 0 means TT */
packet
->
entries
++
;
packet
->
entries
++
;
if
(
vis_packet_full
(
info
))
{
if
(
vis_packet_full
(
info
))
spin_unlock_bh
(
&
bat_priv
->
tt_lhash_lock
);
goto
unlock
;
return
0
;
}
}
}
rcu_read_unlock
();
}
}
spin_unlock_bh
(
&
bat_priv
->
tt_lhash_lock
);
return
0
;
return
0
;
unlock:
unlock:
...
...
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