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
Kirill Smelkov
linux
Commits
9c6bc165
Commit
9c6bc165
authored
Apr 17, 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
03746b0a
af20b710
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
537 additions
and
393 deletions
+537
-393
net/batman-adv/gateway_client.c
net/batman-adv/gateway_client.c
+151
-108
net/batman-adv/gateway_client.h
net/batman-adv/gateway_client.h
+1
-1
net/batman-adv/icmp_socket.c
net/batman-adv/icmp_socket.c
+3
-15
net/batman-adv/originator.c
net/batman-adv/originator.c
+29
-9
net/batman-adv/originator.h
net/batman-adv/originator.h
+1
-0
net/batman-adv/routing.c
net/batman-adv/routing.c
+202
-176
net/batman-adv/send.c
net/batman-adv/send.c
+12
-7
net/batman-adv/soft-interface.c
net/batman-adv/soft-interface.c
+88
-27
net/batman-adv/types.h
net/batman-adv/types.h
+4
-3
net/batman-adv/unicast.c
net/batman-adv/unicast.c
+1
-1
net/batman-adv/vis.c
net/batman-adv/vis.c
+45
-46
No files found.
net/batman-adv/gateway_client.c
View file @
9c6bc165
This diff is collapsed.
Click to expand it.
net/batman-adv/gateway_client.h
View file @
9c6bc165
...
...
@@ -24,7 +24,7 @@
void
gw_deselect
(
struct
bat_priv
*
bat_priv
);
void
gw_election
(
struct
bat_priv
*
bat_priv
);
void
*
gw_get_selected
(
struct
bat_priv
*
bat_priv
);
struct
orig_node
*
gw_get_selected_orig
(
struct
bat_priv
*
bat_priv
);
void
gw_check_election
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
);
void
gw_node_update
(
struct
bat_priv
*
bat_priv
,
struct
orig_node
*
orig_node
,
uint8_t
new_gwflags
);
...
...
net/batman-adv/icmp_socket.c
View file @
9c6bc165
...
...
@@ -218,23 +218,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
if
(
atomic_read
(
&
bat_priv
->
mesh_state
)
!=
MESH_ACTIVE
)
goto
dst_unreach
;
rcu_read_lock
();
orig_node
=
orig_hash_find
(
bat_priv
,
icmp_packet
->
dst
);
if
(
!
orig_node
)
goto
unlock
;
neigh_node
=
orig_node
->
router
;
goto
dst_unreach
;
neigh_node
=
orig_node_get_router
(
orig_node
);
if
(
!
neigh_node
)
goto
unlock
;
if
(
!
atomic_inc_not_zero
(
&
neigh_node
->
refcount
))
{
neigh_node
=
NULL
;
goto
unlock
;
}
rcu_read_unlock
();
goto
dst_unreach
;
if
(
!
neigh_node
->
if_incoming
)
goto
dst_unreach
;
...
...
@@ -252,8 +242,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
send_skb_packet
(
skb
,
neigh_node
->
if_incoming
,
neigh_node
->
addr
);
goto
out
;
unlock:
rcu_read_unlock
();
dst_unreach:
icmp_packet
->
msg_type
=
DESTINATION_UNREACHABLE
;
bat_socket_add_packet
(
socket_client
,
icmp_packet
,
packet_len
);
...
...
net/batman-adv/originator.c
View file @
9c6bc165
...
...
@@ -70,6 +70,21 @@ void neigh_node_free_ref(struct neigh_node *neigh_node)
call_rcu
(
&
neigh_node
->
rcu
,
neigh_node_free_rcu
);
}
/* increases the refcounter of a found router */
struct
neigh_node
*
orig_node_get_router
(
struct
orig_node
*
orig_node
)
{
struct
neigh_node
*
router
;
rcu_read_lock
();
router
=
rcu_dereference
(
orig_node
->
router
);
if
(
router
&&
!
atomic_inc_not_zero
(
&
router
->
refcount
))
router
=
NULL
;
rcu_read_unlock
();
return
router
;
}
struct
neigh_node
*
create_neighbor
(
struct
orig_node
*
orig_node
,
struct
orig_node
*
orig_neigh_node
,
uint8_t
*
neigh
,
...
...
@@ -87,6 +102,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
INIT_HLIST_NODE
(
&
neigh_node
->
list
);
INIT_LIST_HEAD
(
&
neigh_node
->
bonding_list
);
spin_lock_init
(
&
neigh_node
->
tq_lock
);
memcpy
(
neigh_node
->
addr
,
neigh
,
ETH_ALEN
);
neigh_node
->
orig_node
=
orig_neigh_node
;
...
...
@@ -390,7 +406,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
struct
hlist_node
*
node
,
*
node_tmp
;
struct
hlist_head
*
head
;
struct
orig_node
*
orig_node
;
struct
neigh_node
*
neigh_node
;
struct
neigh_node
*
neigh_node
,
*
neigh_node_tmp
;
int
batman_count
=
0
;
int
last_seen_secs
;
int
last_seen_msecs
;
...
...
@@ -421,37 +437,41 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
rcu_read_lock
();
hlist_for_each_entry_rcu
(
orig_node
,
node
,
head
,
hash_entry
)
{
if
(
!
orig_node
->
router
)
neigh_node
=
orig_node_get_router
(
orig_node
);
if
(
!
neigh_node
)
continue
;
if
(
orig_node
->
router
->
tq_avg
==
0
)
continue
;
if
(
neigh_node
->
tq_avg
==
0
)
goto
next
;
last_seen_secs
=
jiffies_to_msecs
(
jiffies
-
orig_node
->
last_valid
)
/
1000
;
last_seen_msecs
=
jiffies_to_msecs
(
jiffies
-
orig_node
->
last_valid
)
%
1000
;
neigh_node
=
orig_node
->
router
;
seq_printf
(
seq
,
"%pM %4i.%03is (%3i) %pM [%10s]:"
,
orig_node
->
orig
,
last_seen_secs
,
last_seen_msecs
,
neigh_node
->
tq_avg
,
neigh_node
->
addr
,
neigh_node
->
if_incoming
->
net_dev
->
name
);
hlist_for_each_entry_rcu
(
neigh_node
,
node_tmp
,
hlist_for_each_entry_rcu
(
neigh_node
_tmp
,
node_tmp
,
&
orig_node
->
neigh_list
,
list
)
{
seq_printf
(
seq
,
" %pM (%3i)"
,
neigh_node
->
addr
,
neigh_node
->
tq_avg
);
seq_printf
(
seq
,
" %pM (%3i)"
,
neigh_node_tmp
->
addr
,
neigh_node_tmp
->
tq_avg
);
}
seq_printf
(
seq
,
"
\n
"
);
batman_count
++
;
next:
neigh_node_free_ref
(
neigh_node
);
}
rcu_read_unlock
();
}
if
(
(
batman_count
==
0
)
)
if
(
batman_count
==
0
)
seq_printf
(
seq
,
"No batman nodes in range ...
\n
"
);
return
0
;
...
...
net/batman-adv/originator.h
View file @
9c6bc165
...
...
@@ -34,6 +34,7 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
uint8_t
*
neigh
,
struct
hard_iface
*
if_incoming
);
void
neigh_node_free_ref
(
struct
neigh_node
*
neigh_node
);
struct
neigh_node
*
orig_node_get_router
(
struct
orig_node
*
orig_node
);
int
orig_seq_print_text
(
struct
seq_file
*
seq
,
void
*
offset
);
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
);
...
...
net/batman-adv/routing.c
View file @
9c6bc165
This diff is collapsed.
Click to expand it.
net/batman-adv/send.c
View file @
9c6bc165
...
...
@@ -308,6 +308,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
struct
hard_iface
*
if_incoming
)
{
struct
bat_priv
*
bat_priv
=
netdev_priv
(
if_incoming
->
soft_iface
);
struct
neigh_node
*
router
;
unsigned
char
in_tq
,
in_ttl
,
tq_avg
=
0
;
unsigned
long
send_time
;
...
...
@@ -316,6 +317,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
return
;
}
router
=
orig_node_get_router
(
orig_node
);
in_tq
=
batman_packet
->
tq
;
in_ttl
=
batman_packet
->
ttl
;
...
...
@@ -324,20 +327,22 @@ void schedule_forward_packet(struct orig_node *orig_node,
/* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
* of our best tq value */
if
(
(
orig_node
->
router
)
&&
(
orig_node
->
router
->
tq_avg
!=
0
)
)
{
if
(
router
&&
router
->
tq_avg
!=
0
)
{
/* rebroadcast ogm of best ranking neighbor as is */
if
(
!
compare_eth
(
orig_node
->
router
->
addr
,
ethhdr
->
h_source
))
{
batman_packet
->
tq
=
orig_node
->
router
->
tq_avg
;
if
(
!
compare_eth
(
router
->
addr
,
ethhdr
->
h_source
))
{
batman_packet
->
tq
=
router
->
tq_avg
;
if
(
orig_node
->
router
->
last_ttl
)
batman_packet
->
ttl
=
orig_node
->
router
->
last_ttl
-
1
;
if
(
router
->
last_ttl
)
batman_packet
->
ttl
=
router
->
last_ttl
-
1
;
}
tq_avg
=
orig_node
->
router
->
tq_avg
;
tq_avg
=
router
->
tq_avg
;
}
if
(
router
)
neigh_node_free_ref
(
router
);
/* apply hop penalty */
batman_packet
->
tq
=
hop_penalty
(
batman_packet
->
tq
,
bat_priv
);
...
...
net/batman-adv/soft-interface.c
View file @
9c6bc165
...
...
@@ -90,10 +90,51 @@ static void softif_neigh_free_ref(struct softif_neigh *softif_neigh)
call_rcu
(
&
softif_neigh
->
rcu
,
softif_neigh_free_rcu
);
}
static
struct
softif_neigh
*
softif_neigh_get_selected
(
struct
bat_priv
*
bat_priv
)
{
struct
softif_neigh
*
neigh
;
rcu_read_lock
();
neigh
=
rcu_dereference
(
bat_priv
->
softif_neigh
);
if
(
neigh
&&
!
atomic_inc_not_zero
(
&
neigh
->
refcount
))
neigh
=
NULL
;
rcu_read_unlock
();
return
neigh
;
}
static
void
softif_neigh_select
(
struct
bat_priv
*
bat_priv
,
struct
softif_neigh
*
new_neigh
)
{
struct
softif_neigh
*
curr_neigh
;
spin_lock_bh
(
&
bat_priv
->
softif_neigh_lock
);
if
(
new_neigh
&&
!
atomic_inc_not_zero
(
&
new_neigh
->
refcount
))
new_neigh
=
NULL
;
curr_neigh
=
bat_priv
->
softif_neigh
;
rcu_assign_pointer
(
bat_priv
->
softif_neigh
,
new_neigh
);
if
(
curr_neigh
)
softif_neigh_free_ref
(
curr_neigh
);
spin_unlock_bh
(
&
bat_priv
->
softif_neigh_lock
);
}
static
void
softif_neigh_deselect
(
struct
bat_priv
*
bat_priv
)
{
softif_neigh_select
(
bat_priv
,
NULL
);
}
void
softif_neigh_purge
(
struct
bat_priv
*
bat_priv
)
{
struct
softif_neigh
*
softif_neigh
,
*
softif_neigh_tmp
;
struct
softif_neigh
*
softif_neigh
,
*
curr_softif_neigh
;
struct
hlist_node
*
node
,
*
node_tmp
;
char
do_deselect
=
0
;
curr_softif_neigh
=
softif_neigh_get_selected
(
bat_priv
);
spin_lock_bh
(
&
bat_priv
->
softif_neigh_lock
);
...
...
@@ -105,22 +146,26 @@ void softif_neigh_purge(struct bat_priv *bat_priv)
(
atomic_read
(
&
bat_priv
->
mesh_state
)
==
MESH_ACTIVE
))
continue
;
hlist_del_rcu
(
&
softif_neigh
->
list
);
if
(
bat_priv
->
softif_neigh
==
softif_neigh
)
{
if
(
curr_softif_neigh
==
softif_neigh
)
{
bat_dbg
(
DBG_ROUTES
,
bat_priv
,
"Current mesh exit point '%pM' vanished "
"(vid: %d).
\n
"
,
softif_neigh
->
addr
,
softif_neigh
->
vid
);
softif_neigh_tmp
=
bat_priv
->
softif_neigh
;
bat_priv
->
softif_neigh
=
NULL
;
softif_neigh_free_ref
(
softif_neigh_tmp
);
do_deselect
=
1
;
}
hlist_del_rcu
(
&
softif_neigh
->
list
);
softif_neigh_free_ref
(
softif_neigh
);
}
spin_unlock_bh
(
&
bat_priv
->
softif_neigh_lock
);
/* soft_neigh_deselect() needs to acquire the softif_neigh_lock */
if
(
do_deselect
)
softif_neigh_deselect
(
bat_priv
);
if
(
curr_softif_neigh
)
softif_neigh_free_ref
(
curr_softif_neigh
);
}
static
struct
softif_neigh
*
softif_neigh_get
(
struct
bat_priv
*
bat_priv
,
...
...
@@ -171,6 +216,7 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
struct
bat_priv
*
bat_priv
=
netdev_priv
(
net_dev
);
struct
softif_neigh
*
softif_neigh
;
struct
hlist_node
*
node
;
struct
softif_neigh
*
curr_softif_neigh
;
if
(
!
bat_priv
->
primary_if
)
{
return
seq_printf
(
seq
,
"BATMAN mesh %s disabled - "
...
...
@@ -180,14 +226,17 @@ int softif_neigh_seq_print_text(struct seq_file *seq, void *offset)
seq_printf
(
seq
,
"Softif neighbor list (%s)
\n
"
,
net_dev
->
name
);
curr_softif_neigh
=
softif_neigh_get_selected
(
bat_priv
);
rcu_read_lock
();
hlist_for_each_entry_rcu
(
softif_neigh
,
node
,
&
bat_priv
->
softif_neigh_list
,
list
)
seq_printf
(
seq
,
"%s %pM (vid: %d)
\n
"
,
bat_priv
->
softif_neigh
==
softif_neigh
curr_
softif_neigh
==
softif_neigh
?
"=>"
:
" "
,
softif_neigh
->
addr
,
softif_neigh
->
vid
);
rcu_read_unlock
();
if
(
curr_softif_neigh
)
softif_neigh_free_ref
(
curr_softif_neigh
);
return
0
;
}
...
...
@@ -198,7 +247,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
struct
bat_priv
*
bat_priv
=
netdev_priv
(
dev
);
struct
ethhdr
*
ethhdr
=
(
struct
ethhdr
*
)
skb
->
data
;
struct
batman_packet
*
batman_packet
;
struct
softif_neigh
*
softif_neigh
,
*
softif_neigh_tmp
;
struct
softif_neigh
*
softif_neigh
;
struct
softif_neigh
*
curr_softif_neigh
=
NULL
;
if
(
ntohs
(
ethhdr
->
h_proto
)
==
ETH_P_8021Q
)
batman_packet
=
(
struct
batman_packet
*
)
...
...
@@ -223,7 +273,8 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
if
(
!
softif_neigh
)
goto
err
;
if
(
bat_priv
->
softif_neigh
==
softif_neigh
)
curr_softif_neigh
=
softif_neigh_get_selected
(
bat_priv
);
if
(
curr_softif_neigh
==
softif_neigh
)
goto
out
;
/* we got a neighbor but its mac is 'bigger' than ours */
...
...
@@ -232,38 +283,39 @@ static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev,
goto
out
;
/* switch to new 'smallest neighbor' */
if
((
bat_priv
->
softif_neigh
)
&&
(
memcmp
(
softif_neigh
->
addr
,
bat_priv
->
softif_neigh
->
addr
,
if
((
curr_
softif_neigh
)
&&
(
memcmp
(
softif_neigh
->
addr
,
curr_
softif_neigh
->
addr
,
ETH_ALEN
)
<
0
))
{
bat_dbg
(
DBG_ROUTES
,
bat_priv
,
"Changing mesh exit point from %pM (vid: %d) "
"to %pM (vid: %d).
\n
"
,
bat_priv
->
softif_neigh
->
addr
,
bat_priv
->
softif_neigh
->
vid
,
curr_
softif_neigh
->
addr
,
curr_
softif_neigh
->
vid
,
softif_neigh
->
addr
,
softif_neigh
->
vid
);
softif_neigh_tmp
=
bat_priv
->
softif_neigh
;
bat_priv
->
softif_neigh
=
softif_neigh
;
softif_neigh_free_ref
(
softif_neigh_tmp
);
/* we need to hold the additional reference */
goto
err
;
softif_neigh_select
(
bat_priv
,
softif_neigh
);
goto
out
;
}
/* close own batX device and use softif_neigh as exit node */
if
((
!
bat_priv
->
softif_neigh
)
&&
if
((
!
curr_
softif_neigh
)
&&
(
memcmp
(
softif_neigh
->
addr
,
bat_priv
->
primary_if
->
net_dev
->
dev_addr
,
ETH_ALEN
)
<
0
))
{
bat_dbg
(
DBG_ROUTES
,
bat_priv
,
"Setting mesh exit point to %pM (vid: %d).
\n
"
,
softif_neigh
->
addr
,
softif_neigh
->
vid
);
bat_priv
->
softif_neigh
=
softif_neigh
;
/* we need to hold the additional reference */
goto
err
;
softif_neigh_select
(
bat_priv
,
softif_neigh
);
goto
out
;
}
out:
softif_neigh_free_ref
(
softif_neigh
);
err:
kfree_skb
(
skb
);
if
(
curr_softif_neigh
)
softif_neigh_free_ref
(
curr_softif_neigh
);
return
;
}
...
...
@@ -321,6 +373,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
struct
bat_priv
*
bat_priv
=
netdev_priv
(
soft_iface
);
struct
bcast_packet
*
bcast_packet
;
struct
vlan_ethhdr
*
vhdr
;
struct
softif_neigh
*
curr_softif_neigh
=
NULL
;
int
data_len
=
skb
->
len
,
ret
;
short
vid
=
-
1
;
bool
do_bcast
=
false
;
...
...
@@ -348,7 +401,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
* if we have a another chosen mesh exit node in range
* it will transport the packets to the mesh
*/
if
((
bat_priv
->
softif_neigh
)
&&
(
bat_priv
->
softif_neigh
->
vid
==
vid
))
curr_softif_neigh
=
softif_neigh_get_selected
(
bat_priv
);
if
((
curr_softif_neigh
)
&&
(
curr_softif_neigh
->
vid
==
vid
))
goto
dropped
;
/* TODO: check this for locks */
...
...
@@ -410,6 +464,8 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface)
dropped_freed:
bat_priv
->
stats
.
tx_dropped
++
;
end:
if
(
curr_softif_neigh
)
softif_neigh_free_ref
(
curr_softif_neigh
);
return
NETDEV_TX_OK
;
}
...
...
@@ -421,6 +477,7 @@ void interface_rx(struct net_device *soft_iface,
struct
unicast_packet
*
unicast_packet
;
struct
ethhdr
*
ethhdr
;
struct
vlan_ethhdr
*
vhdr
;
struct
softif_neigh
*
curr_softif_neigh
=
NULL
;
short
vid
=
-
1
;
int
ret
;
...
...
@@ -450,7 +507,8 @@ void interface_rx(struct net_device *soft_iface,
* if we have a another chosen mesh exit node in range
* it will transport the packets to the non-mesh network
*/
if
((
bat_priv
->
softif_neigh
)
&&
(
bat_priv
->
softif_neigh
->
vid
==
vid
))
{
curr_softif_neigh
=
softif_neigh_get_selected
(
bat_priv
);
if
(
curr_softif_neigh
&&
(
curr_softif_neigh
->
vid
==
vid
))
{
skb_push
(
skb
,
hdr_size
);
unicast_packet
=
(
struct
unicast_packet
*
)
skb
->
data
;
...
...
@@ -461,7 +519,7 @@ void interface_rx(struct net_device *soft_iface,
skb_reset_mac_header
(
skb
);
memcpy
(
unicast_packet
->
dest
,
bat_priv
->
softif_neigh
->
addr
,
ETH_ALEN
);
curr_
softif_neigh
->
addr
,
ETH_ALEN
);
ret
=
route_unicast_packet
(
skb
,
recv_if
);
if
(
ret
==
NET_RX_DROP
)
goto
dropped
;
...
...
@@ -486,11 +544,13 @@ void interface_rx(struct net_device *soft_iface,
soft_iface
->
last_rx
=
jiffies
;
netif_rx
(
skb
);
return
;
goto
out
;
dropped:
kfree_skb
(
skb
);
out:
if
(
curr_softif_neigh
)
softif_neigh_free_ref
(
curr_softif_neigh
);
return
;
}
...
...
@@ -524,6 +584,7 @@ static void interface_setup(struct net_device *dev)
dev
->
hard_start_xmit
=
interface_tx
;
#endif
dev
->
destructor
=
free_netdev
;
dev
->
tx_queue_len
=
0
;
/**
* can't call min_mtu, because the needed variables
...
...
net/batman-adv/types.h
View file @
9c6bc165
...
...
@@ -67,7 +67,7 @@ struct hard_iface {
struct
orig_node
{
uint8_t
orig
[
ETH_ALEN
];
uint8_t
primary_addr
[
ETH_ALEN
];
struct
neigh_node
*
router
;
struct
neigh_node
__rcu
*
router
;
/* rcu protected pointer */
unsigned
long
*
bcast_own
;
uint8_t
*
bcast_own_sum
;
unsigned
long
last_valid
;
...
...
@@ -83,7 +83,7 @@ struct orig_node {
uint32_t
last_bcast_seqno
;
struct
hlist_head
neigh_list
;
struct
list_head
frag_list
;
spinlock_t
neigh_list_lock
;
/* protects neigh
bor list
*/
spinlock_t
neigh_list_lock
;
/* protects neigh
_list and router
*/
atomic_t
refcount
;
struct
rcu_head
rcu
;
struct
hlist_node
hash_entry
;
...
...
@@ -125,6 +125,7 @@ struct neigh_node {
struct
rcu_head
rcu
;
struct
orig_node
*
orig_node
;
struct
hard_iface
*
if_incoming
;
spinlock_t
tq_lock
;
/* protects: tq_recv, tq_index */
};
...
...
@@ -146,7 +147,7 @@ struct bat_priv {
atomic_t
batman_queue_left
;
char
num_ifaces
;
struct
hlist_head
softif_neigh_list
;
struct
softif_neigh
*
softif_neigh
;
struct
softif_neigh
__rcu
*
softif_neigh
;
struct
debug_log
*
debug_log
;
struct
hard_iface
*
primary_if
;
struct
kobject
*
mesh_obj
;
...
...
net/batman-adv/unicast.c
View file @
9c6bc165
...
...
@@ -289,7 +289,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
/* get routing information */
if
(
is_multicast_ether_addr
(
ethhdr
->
h_dest
))
{
orig_node
=
(
struct
orig_node
*
)
gw_get_selected
(
bat_priv
);
orig_node
=
(
struct
orig_node
*
)
gw_get_selected
_orig
(
bat_priv
);
if
(
orig_node
)
goto
find_router
;
}
...
...
net/batman-adv/vis.c
View file @
9c6bc165
...
...
@@ -558,6 +558,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
struct
vis_info
*
info
)
{
struct
hashtable_t
*
hash
=
bat_priv
->
orig_hash
;
struct
neigh_node
*
router
;
struct
hlist_node
*
node
;
struct
hlist_head
*
head
;
struct
orig_node
*
orig_node
;
...
...
@@ -571,13 +572,17 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
rcu_read_lock
();
hlist_for_each_entry_rcu
(
orig_node
,
node
,
head
,
hash_entry
)
{
if
((
orig_node
)
&&
(
orig_node
->
router
)
&&
(
orig_node
->
flags
&
VIS_SERVER
)
&&
(
orig_node
->
router
->
tq_avg
>
best_tq
))
{
best_tq
=
orig_node
->
router
->
tq_avg
;
router
=
orig_node_get_router
(
orig_node
);
if
(
!
router
)
continue
;
if
((
orig_node
->
flags
&
VIS_SERVER
)
&&
(
router
->
tq_avg
>
best_tq
))
{
best_tq
=
router
->
tq_avg
;
memcpy
(
packet
->
target_orig
,
orig_node
->
orig
,
ETH_ALEN
);
}
neigh_node_free_ref
(
router
);
}
rcu_read_unlock
();
}
...
...
@@ -605,7 +610,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
struct
hlist_node
*
node
;
struct
hlist_head
*
head
;
struct
orig_node
*
orig_node
;
struct
neigh_node
*
neigh_node
;
struct
neigh_node
*
router
;
struct
vis_info
*
info
=
(
struct
vis_info
*
)
bat_priv
->
my_vis_info
;
struct
vis_packet
*
packet
=
(
struct
vis_packet
*
)
info
->
skb_packet
->
data
;
struct
vis_info_entry
*
entry
;
...
...
@@ -633,30 +638,32 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
rcu_read_lock
();
hlist_for_each_entry_rcu
(
orig_node
,
node
,
head
,
hash_entry
)
{
neigh_node
=
orig_node
->
router
;
if
(
!
neigh_node
)
router
=
orig_node_get_router
(
orig_node
);
if
(
!
router
)
continue
;
if
(
!
compare_eth
(
neigh_node
->
addr
,
orig_node
->
orig
))
continue
;
if
(
!
compare_eth
(
router
->
addr
,
orig_node
->
orig
))
goto
next
;
if
(
neigh_node
->
if_incoming
->
if_status
!=
IF_ACTIVE
)
continue
;
if
(
router
->
if_incoming
->
if_status
!=
IF_ACTIVE
)
goto
next
;
if
(
neigh_node
->
tq_avg
<
1
)
continue
;
if
(
router
->
tq_avg
<
1
)
goto
next
;
/* fill one entry into buffer. */
entry
=
(
struct
vis_info_entry
*
)
skb_put
(
info
->
skb_packet
,
sizeof
(
*
entry
));
memcpy
(
entry
->
src
,
neigh_node
->
if_incoming
->
net_dev
->
dev_addr
,
router
->
if_incoming
->
net_dev
->
dev_addr
,
ETH_ALEN
);
memcpy
(
entry
->
dest
,
orig_node
->
orig
,
ETH_ALEN
);
entry
->
quality
=
neigh_node
->
tq_avg
;
entry
->
quality
=
router
->
tq_avg
;
packet
->
entries
++
;
next:
neigh_node_free_ref
(
router
);
if
(
vis_packet_full
(
info
))
goto
unlock
;
}
...
...
@@ -725,6 +732,7 @@ static void purge_vis_packets(struct bat_priv *bat_priv)
static
void
broadcast_vis_packet
(
struct
bat_priv
*
bat_priv
,
struct
vis_info
*
info
)
{
struct
neigh_node
*
router
;
struct
hashtable_t
*
hash
=
bat_priv
->
orig_hash
;
struct
hlist_node
*
node
;
struct
hlist_head
*
head
;
...
...
@@ -745,19 +753,26 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
rcu_read_lock
();
hlist_for_each_entry_rcu
(
orig_node
,
node
,
head
,
hash_entry
)
{
/* if it's a vis server and reachable, send it. */
if
((
!
orig_node
)
||
(
!
orig_node
->
router
))
continue
;
if
(
!
(
orig_node
->
flags
&
VIS_SERVER
))
continue
;
router
=
orig_node_get_router
(
orig_node
);
if
(
!
router
)
continue
;
/* don't send it if we already received the packet from
* this node. */
* this node. */
if
(
recv_list_is_in
(
bat_priv
,
&
info
->
recv_list
,
orig_node
->
orig
))
orig_node
->
orig
))
{
neigh_node_free_ref
(
router
);
continue
;
}
memcpy
(
packet
->
target_orig
,
orig_node
->
orig
,
ETH_ALEN
);
hard_iface
=
orig_node
->
router
->
if_incoming
;
memcpy
(
dstaddr
,
orig_node
->
router
->
addr
,
ETH_ALEN
);
hard_iface
=
router
->
if_incoming
;
memcpy
(
dstaddr
,
router
->
addr
,
ETH_ALEN
);
neigh_node_free_ref
(
router
);
skb
=
skb_clone
(
info
->
skb_packet
,
GFP_ATOMIC
);
if
(
skb
)
...
...
@@ -772,45 +787,29 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
struct
vis_info
*
info
)
{
struct
orig_node
*
orig_node
;
struct
neigh_node
*
neigh_node
=
NULL
;
struct
neigh_node
*
router
=
NULL
;
struct
sk_buff
*
skb
;
struct
vis_packet
*
packet
;
packet
=
(
struct
vis_packet
*
)
info
->
skb_packet
->
data
;
rcu_read_lock
();
orig_node
=
orig_hash_find
(
bat_priv
,
packet
->
target_orig
);
if
(
!
orig_node
)
goto
unlock
;
goto
out
;
neigh_node
=
orig_node
->
router
;
if
(
!
neigh_node
)
goto
unlock
;
if
(
!
atomic_inc_not_zero
(
&
neigh_node
->
refcount
))
{
neigh_node
=
NULL
;
goto
unlock
;
}
rcu_read_unlock
();
router
=
orig_node_get_router
(
orig_node
);
if
(
!
router
)
goto
out
;
skb
=
skb_clone
(
info
->
skb_packet
,
GFP_ATOMIC
);
if
(
skb
)
send_skb_packet
(
skb
,
neigh_node
->
if_incoming
,
neigh_node
->
addr
);
goto
out
;
send_skb_packet
(
skb
,
router
->
if_incoming
,
router
->
addr
);
unlock:
rcu_read_unlock
();
out:
if
(
neigh_node
)
neigh_node_free_ref
(
neigh_node
);
if
(
router
)
neigh_node_free_ref
(
router
);
if
(
orig_node
)
orig_node_free_ref
(
orig_node
);
return
;
}
/* only send one vis packet. called from send_vis_packets() */
...
...
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