Blame view
net/batman-adv/soft-interface.c
21.6 KB
0b8739314 batman-adv: updat... |
1 |
/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors: |
c6c8fea29 net: Add batman-a... |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
* * Marek Lindner, Simon Wunderlich * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA |
c6c8fea29 net: Add batman-a... |
18 19 20 21 22 |
*/ #include "main.h" #include "soft-interface.h" #include "hard-interface.h" |
c384ea3ec batman-adv: Distr... |
23 |
#include "distributed-arp-table.h" |
c6c8fea29 net: Add batman-a... |
24 25 |
#include "routing.h" #include "send.h" |
b706b13b6 batman-adv: Remov... |
26 |
#include "debugfs.h" |
c6c8fea29 net: Add batman-a... |
27 |
#include "translation-table.h" |
c6c8fea29 net: Add batman-a... |
28 29 30 |
#include "hash.h" #include "gateway_common.h" #include "gateway_client.h" |
b706b13b6 batman-adv: Remov... |
31 |
#include "sysfs.h" |
43676ab59 batman-adv: impro... |
32 |
#include "originator.h" |
c6c8fea29 net: Add batman-a... |
33 34 35 36 |
#include <linux/slab.h> #include <linux/ethtool.h> #include <linux/etherdevice.h> #include <linux/if_vlan.h> |
af5d4f773 batman-adv: use E... |
37 |
#include <linux/if_ether.h> |
c6c8fea29 net: Add batman-a... |
38 |
#include "unicast.h" |
23721387c batman-adv: add b... |
39 |
#include "bridge_loop_avoidance.h" |
d353d8d4d batman-adv: netwo... |
40 |
#include "network-coding.h" |
c6c8fea29 net: Add batman-a... |
41 |
|
0294ca0d9 batman-adv: Prefi... |
42 43 44 45 46 47 |
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); static void batadv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info); static u32 batadv_get_msglevel(struct net_device *dev); static void batadv_set_msglevel(struct net_device *dev, u32 value); static u32 batadv_get_link(struct net_device *dev); |
f8214865a batman-adv: Add g... |
48 49 50 51 |
static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data); static void batadv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data); static int batadv_get_sset_count(struct net_device *dev, int stringset); |
c6c8fea29 net: Add batman-a... |
52 |
|
0294ca0d9 batman-adv: Prefi... |
53 54 55 56 57 58 |
static const struct ethtool_ops batadv_ethtool_ops = { .get_settings = batadv_get_settings, .get_drvinfo = batadv_get_drvinfo, .get_msglevel = batadv_get_msglevel, .set_msglevel = batadv_set_msglevel, .get_link = batadv_get_link, |
f8214865a batman-adv: Add g... |
59 60 61 |
.get_strings = batadv_get_strings, .get_ethtool_stats = batadv_get_ethtool_stats, .get_sset_count = batadv_get_sset_count, |
c6c8fea29 net: Add batman-a... |
62 |
}; |
04b482a21 batman-adv: Prefi... |
63 |
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) |
c6c8fea29 net: Add batman-a... |
64 65 |
{ int result; |
9cfc7bd60 batman-adv: Refor... |
66 |
/* TODO: We must check if we can release all references to non-payload |
c6c8fea29 net: Add batman-a... |
67 68 69 70 71 72 73 74 75 76 77 78 79 |
* data using skb_header_release in our skbs to allow skb_cow_header to * work optimally. This means that those skbs are not allowed to read * or write any data which is before the current position of skb->data * after that call and thus allow other skbs with the same data buffer * to write freely in that area. */ result = skb_cow_head(skb, len); if (result < 0) return result; skb_push(skb, len); return 0; } |
0294ca0d9 batman-adv: Prefi... |
80 |
static int batadv_interface_open(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
81 82 83 84 |
{ netif_start_queue(dev); return 0; } |
0294ca0d9 batman-adv: Prefi... |
85 |
static int batadv_interface_release(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
86 87 88 89 |
{ netif_stop_queue(dev); return 0; } |
0294ca0d9 batman-adv: Prefi... |
90 |
static struct net_device_stats *batadv_interface_stats(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
91 |
{ |
56303d34a batman-adv: Prefi... |
92 |
struct batadv_priv *bat_priv = netdev_priv(dev); |
1c9b0550f batman-adv: conve... |
93 94 95 96 97 98 99 100 |
struct net_device_stats *stats = &bat_priv->stats; stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); return stats; |
c6c8fea29 net: Add batman-a... |
101 |
} |
0294ca0d9 batman-adv: Prefi... |
102 |
static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) |
c6c8fea29 net: Add batman-a... |
103 |
{ |
56303d34a batman-adv: Prefi... |
104 |
struct batadv_priv *bat_priv = netdev_priv(dev); |
c6c8fea29 net: Add batman-a... |
105 |
struct sockaddr *addr = p; |
40a3eb33e batman-adv: Fix c... |
106 |
uint8_t old_addr[ETH_ALEN]; |
c6c8fea29 net: Add batman-a... |
107 108 109 |
if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; |
40a3eb33e batman-adv: Fix c... |
110 111 |
memcpy(old_addr, dev->dev_addr, ETH_ALEN); memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
015758d00 batman-adv: corre... |
112 |
/* only modify transtable if it has been initialized before */ |
39c75a51e batman-adv: Prefi... |
113 |
if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { |
40a3eb33e batman-adv: Fix c... |
114 |
batadv_tt_local_remove(bat_priv, old_addr, |
08c36d3e8 batman-adv: Prefi... |
115 |
"mac address changed", false); |
42d0b044b batman-adv: Prefi... |
116 |
batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); |
c6c8fea29 net: Add batman-a... |
117 |
} |
c6c8fea29 net: Add batman-a... |
118 119 |
return 0; } |
0294ca0d9 batman-adv: Prefi... |
120 |
static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) |
c6c8fea29 net: Add batman-a... |
121 122 |
{ /* check ranges */ |
9563877ea batman-adv: Prefi... |
123 |
if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev))) |
c6c8fea29 net: Add batman-a... |
124 125 126 127 128 129 |
return -EINVAL; dev->mtu = new_mtu; return 0; } |
0294ca0d9 batman-adv: Prefi... |
130 131 |
static int batadv_interface_tx(struct sk_buff *skb, struct net_device *soft_iface) |
c6c8fea29 net: Add batman-a... |
132 133 |
{ struct ethhdr *ethhdr = (struct ethhdr *)skb->data; |
56303d34a batman-adv: Prefi... |
134 135 |
struct batadv_priv *bat_priv = netdev_priv(soft_iface); struct batadv_hard_iface *primary_if = NULL; |
964126901 batman-adv: Prefi... |
136 |
struct batadv_bcast_packet *bcast_packet; |
c6c8fea29 net: Add batman-a... |
137 |
struct vlan_ethhdr *vhdr; |
af5d4f773 batman-adv: use E... |
138 |
__be16 ethertype = __constant_htons(ETH_P_BATMAN); |
4934ab951 batman-adv: don't... |
139 140 141 142 |
static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}; static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 0x00, 0x00}; |
be7af5cf9 batman-adv: refac... |
143 |
unsigned int header_len = 0; |
c6c8fea29 net: Add batman-a... |
144 |
int data_len = skb->len, ret; |
7a5cc2427 batman-adv: add b... |
145 |
short vid __maybe_unused = -1; |
be7af5cf9 batman-adv: refac... |
146 |
bool do_bcast = false; |
bbb1f90ef batman-adv: Don't... |
147 |
uint32_t seqno; |
c384ea3ec batman-adv: Distr... |
148 |
unsigned long brd_delay = 1; |
c6c8fea29 net: Add batman-a... |
149 |
|
39c75a51e batman-adv: Prefi... |
150 |
if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
c6c8fea29 net: Add batman-a... |
151 152 153 154 155 156 157 158 |
goto dropped; soft_iface->trans_start = jiffies; switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: vhdr = (struct vlan_ethhdr *)skb->data; vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; |
7e071c79a batman-adv: Prefi... |
159 |
if (vhdr->h_vlan_encapsulated_proto != ethertype) |
c6c8fea29 net: Add batman-a... |
160 161 162 |
break; /* fall through */ |
af5d4f773 batman-adv: use E... |
163 |
case ETH_P_BATMAN: |
c6c8fea29 net: Add batman-a... |
164 |
goto dropped; |
a7f6ee949 batman-adv: remov... |
165 |
} |
c6c8fea29 net: Add batman-a... |
166 |
|
08adf1512 batman-adv: Prefi... |
167 |
if (batadv_bla_tx(bat_priv, skb, vid)) |
23721387c batman-adv: add b... |
168 |
goto dropped; |
a73105b8d batman-adv: impro... |
169 |
/* Register the client MAC in the transtable */ |
02233e0c7 batman-adv: Do no... |
170 171 |
if (!is_multicast_ether_addr(ethhdr->h_source)) batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); |
c6c8fea29 net: Add batman-a... |
172 |
|
b1a8c04b8 batman-adv: drop ... |
173 174 |
/* don't accept stp packets. STP does not help in meshes. * better use the bridge loop avoidance ... |
4934ab951 batman-adv: don't... |
175 176 177 |
* * The same goes for ECTP sent at least by some Cisco Switches, * it might confuse the mesh when used with bridge loop avoidance. |
b1a8c04b8 batman-adv: drop ... |
178 |
*/ |
1eda58bfc batman-adv: Prefi... |
179 |
if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) |
b1a8c04b8 batman-adv: drop ... |
180 |
goto dropped; |
4934ab951 batman-adv: don't... |
181 182 |
if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) goto dropped; |
be7af5cf9 batman-adv: refac... |
183 184 |
if (is_multicast_ether_addr(ethhdr->h_dest)) { do_bcast = true; |
c6c8fea29 net: Add batman-a... |
185 |
|
be7af5cf9 batman-adv: refac... |
186 |
switch (atomic_read(&bat_priv->gw_mode)) { |
cd646ab1e batman-adv: Prefi... |
187 |
case BATADV_GW_MODE_SERVER: |
be7af5cf9 batman-adv: refac... |
188 |
/* gateway servers should not send dhcp |
9cfc7bd60 batman-adv: Refor... |
189 190 |
* requests into the mesh */ |
7cf06bc6f batman-adv: Prefi... |
191 |
ret = batadv_gw_is_dhcp_target(skb, &header_len); |
be7af5cf9 batman-adv: refac... |
192 193 194 |
if (ret) goto dropped; break; |
cd646ab1e batman-adv: Prefi... |
195 |
case BATADV_GW_MODE_CLIENT: |
be7af5cf9 batman-adv: refac... |
196 |
/* gateway clients should send dhcp requests |
9cfc7bd60 batman-adv: Refor... |
197 198 |
* via unicast to their gateway */ |
7cf06bc6f batman-adv: Prefi... |
199 |
ret = batadv_gw_is_dhcp_target(skb, &header_len); |
be7af5cf9 batman-adv: refac... |
200 201 202 |
if (ret) do_bcast = false; break; |
cd646ab1e batman-adv: Prefi... |
203 |
case BATADV_GW_MODE_OFF: |
be7af5cf9 batman-adv: refac... |
204 205 206 |
default: break; } |
c6c8fea29 net: Add batman-a... |
207 208 209 210 |
} /* ethernet packet should be broadcasted */ if (do_bcast) { |
e5d89254b batman-adv: Prefi... |
211 |
primary_if = batadv_primary_if_get_selected(bat_priv); |
32ae9b221 batman-adv: Make ... |
212 |
if (!primary_if) |
c6c8fea29 net: Add batman-a... |
213 |
goto dropped; |
c384ea3ec batman-adv: Distr... |
214 215 216 217 218 219 |
/* in case of ARP request, we do not immediately broadcasti the * packet, instead we first wait for DAT to try to retrieve the * correct ARP entry */ if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); |
04b482a21 batman-adv: Prefi... |
220 |
if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) |
c6c8fea29 net: Add batman-a... |
221 |
goto dropped; |
964126901 batman-adv: Prefi... |
222 |
bcast_packet = (struct batadv_bcast_packet *)skb->data; |
7e071c79a batman-adv: Prefi... |
223 |
bcast_packet->header.version = BATADV_COMPAT_VERSION; |
42d0b044b batman-adv: Prefi... |
224 |
bcast_packet->header.ttl = BATADV_TTL; |
c6c8fea29 net: Add batman-a... |
225 226 |
/* batman packet type: broadcast */ |
acd34afa8 batman-adv: Prefi... |
227 |
bcast_packet->header.packet_type = BATADV_BCAST; |
162d549c6 batman-adv: Don't... |
228 |
bcast_packet->reserved = 0; |
c6c8fea29 net: Add batman-a... |
229 230 |
/* hw address of first interface is the orig mac because only |
9cfc7bd60 batman-adv: Refor... |
231 232 |
* this mac is known throughout the mesh */ |
c6c8fea29 net: Add batman-a... |
233 |
memcpy(bcast_packet->orig, |
32ae9b221 batman-adv: Make ... |
234 |
primary_if->net_dev->dev_addr, ETH_ALEN); |
c6c8fea29 net: Add batman-a... |
235 236 |
/* set broadcast sequence number */ |
bbb1f90ef batman-adv: Don't... |
237 238 |
seqno = atomic_inc_return(&bat_priv->bcast_seqno); bcast_packet->seqno = htonl(seqno); |
c6c8fea29 net: Add batman-a... |
239 |
|
c384ea3ec batman-adv: Distr... |
240 |
batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay); |
c6c8fea29 net: Add batman-a... |
241 242 |
/* a copy is stored in the bcast list, therefore removing |
9cfc7bd60 batman-adv: Refor... |
243 244 |
* the original skb. */ |
c6c8fea29 net: Add batman-a... |
245 246 247 248 |
kfree_skb(skb); /* unicast packet */ } else { |
cd646ab1e batman-adv: Prefi... |
249 |
if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_OFF) { |
7cf06bc6f batman-adv: Prefi... |
250 |
ret = batadv_gw_out_of_range(bat_priv, skb, ethhdr); |
be7af5cf9 batman-adv: refac... |
251 252 253 |
if (ret) goto dropped; } |
c384ea3ec batman-adv: Distr... |
254 255 256 257 |
if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) goto dropped; batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); |
7cdcf6ddd batman-adv: add U... |
258 |
ret = batadv_unicast_send_skb(bat_priv, skb); |
c6c8fea29 net: Add batman-a... |
259 260 261 |
if (ret != 0) goto dropped_freed; } |
1c9b0550f batman-adv: conve... |
262 263 |
batadv_inc_counter(bat_priv, BATADV_CNT_TX); batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); |
c6c8fea29 net: Add batman-a... |
264 265 266 267 268 |
goto end; dropped: kfree_skb(skb); dropped_freed: |
1c9b0550f batman-adv: conve... |
269 |
batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); |
c6c8fea29 net: Add batman-a... |
270 |
end: |
32ae9b221 batman-adv: Make ... |
271 |
if (primary_if) |
e5d89254b batman-adv: Prefi... |
272 |
batadv_hardif_free_ref(primary_if); |
c6c8fea29 net: Add batman-a... |
273 274 |
return NETDEV_TX_OK; } |
04b482a21 batman-adv: Prefi... |
275 |
void batadv_interface_rx(struct net_device *soft_iface, |
56303d34a batman-adv: Prefi... |
276 |
struct sk_buff *skb, struct batadv_hard_iface *recv_if, |
371351731 batman-adv: chang... |
277 |
int hdr_size, struct batadv_orig_node *orig_node) |
c6c8fea29 net: Add batman-a... |
278 |
{ |
56303d34a batman-adv: Prefi... |
279 |
struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
c6c8fea29 net: Add batman-a... |
280 281 |
struct ethhdr *ethhdr; struct vlan_ethhdr *vhdr; |
04c9f416e Merge git://git.k... |
282 |
struct batadv_header *batadv_header = (struct batadv_header *)skb->data; |
7a5cc2427 batman-adv: add b... |
283 |
short vid __maybe_unused = -1; |
af5d4f773 batman-adv: use E... |
284 |
__be16 ethertype = __constant_htons(ETH_P_BATMAN); |
2d3f6ccc4 batman-adv: check... |
285 |
bool is_bcast; |
04c9f416e Merge git://git.k... |
286 |
is_bcast = (batadv_header->packet_type == BATADV_BCAST); |
c6c8fea29 net: Add batman-a... |
287 288 289 290 291 292 293 294 295 296 297 298 299 300 |
/* check if enough space is available for pulling, and pull */ if (!pskb_may_pull(skb, hdr_size)) goto dropped; skb_pull_rcsum(skb, hdr_size); skb_reset_mac_header(skb); ethhdr = (struct ethhdr *)skb_mac_header(skb); switch (ntohs(ethhdr->h_proto)) { case ETH_P_8021Q: vhdr = (struct vlan_ethhdr *)skb->data; vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; |
7e071c79a batman-adv: Prefi... |
301 |
if (vhdr->h_vlan_encapsulated_proto != ethertype) |
c6c8fea29 net: Add batman-a... |
302 303 304 |
break; /* fall through */ |
af5d4f773 batman-adv: use E... |
305 |
case ETH_P_BATMAN: |
c6c8fea29 net: Add batman-a... |
306 307 |
goto dropped; } |
c6c8fea29 net: Add batman-a... |
308 309 310 311 |
/* skb->dev & skb->pkt_type are set here */ if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) goto dropped; skb->protocol = eth_type_trans(skb, soft_iface); |
25985edce Fix common misspe... |
312 |
/* should not be necessary anymore as we use skb_pull_rcsum() |
c6c8fea29 net: Add batman-a... |
313 |
* TODO: please verify this and remove this TODO |
9cfc7bd60 batman-adv: Refor... |
314 315 |
* -- Dec 21st 2009, Simon Wunderlich */ |
c6c8fea29 net: Add batman-a... |
316 |
|
9cfc7bd60 batman-adv: Refor... |
317 |
/* skb->ip_summed = CHECKSUM_UNNECESSARY; */ |
c6c8fea29 net: Add batman-a... |
318 |
|
1c9b0550f batman-adv: conve... |
319 320 321 |
batadv_inc_counter(bat_priv, BATADV_CNT_RX); batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, skb->len + ETH_HLEN); |
c6c8fea29 net: Add batman-a... |
322 323 |
soft_iface->last_rx = jiffies; |
74490f969 batman-adv: proce... |
324 325 326 327 328 |
/* Let the bridge loop avoidance check the packet. If will * not handle it, we can safely push it up. */ if (batadv_bla_rx(bat_priv, skb, vid, is_bcast)) goto out; |
371351731 batman-adv: chang... |
329 330 331 |
if (orig_node) batadv_tt_add_temporary_global_entry(bat_priv, orig_node, ethhdr->h_source); |
08c36d3e8 batman-adv: Prefi... |
332 |
if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) |
59b699cde batman-adv: imple... |
333 |
goto dropped; |
c6c8fea29 net: Add batman-a... |
334 |
netif_rx(skb); |
ba85fac28 batman-adv: prote... |
335 |
goto out; |
c6c8fea29 net: Add batman-a... |
336 337 338 339 340 341 |
dropped: kfree_skb(skb); out: return; } |
36c1d1531 batman-adv: Set s... |
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 |
/* batman-adv network devices have devices nesting below it and are a special * "super class" of normal network devices; split their locks off into a * separate class since they always nest. */ static struct lock_class_key batadv_netdev_xmit_lock_key; static struct lock_class_key batadv_netdev_addr_lock_key; /** * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue * @dev: device which owns the tx queue * @txq: tx queue to modify * @_unused: always NULL */ static void batadv_set_lockdep_class_one(struct net_device *dev, struct netdev_queue *txq, void *_unused) { lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); } /** * batadv_set_lockdep_class - Set txq and addr_list lockdep class * @dev: network device to modify */ static void batadv_set_lockdep_class(struct net_device *dev) { lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); } /** |
5bc44dc84 batman-adv: postp... |
373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
* batadv_softif_destroy_finish - cleans up the remains of a softif * @work: work queue item * * Free the parts of the soft interface which can not be removed under * rtnl lock (to prevent deadlock situations). */ static void batadv_softif_destroy_finish(struct work_struct *work) { struct batadv_priv *bat_priv; struct net_device *soft_iface; bat_priv = container_of(work, struct batadv_priv, cleanup_work); soft_iface = bat_priv->soft_iface; |
5bc44dc84 batman-adv: postp... |
387 388 389 390 391 392 |
batadv_sysfs_del_meshif(soft_iface); rtnl_lock(); unregister_netdevice(soft_iface); rtnl_unlock(); } |
37130293f batman-adv: Move ... |
393 394 395 396 397 398 399 |
/** * batadv_softif_init_late - late stage initialization of soft interface * @dev: registered network device to modify * * Returns error code on failures */ static int batadv_softif_init_late(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
400 |
{ |
56303d34a batman-adv: Prefi... |
401 |
struct batadv_priv *bat_priv; |
c6c8fea29 net: Add batman-a... |
402 |
int ret; |
d69909d2f batman-adv: Prefi... |
403 |
size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; |
c6c8fea29 net: Add batman-a... |
404 |
|
37130293f batman-adv: Move ... |
405 |
batadv_set_lockdep_class(dev); |
c6c8fea29 net: Add batman-a... |
406 |
|
37130293f batman-adv: Move ... |
407 408 |
bat_priv = netdev_priv(dev); bat_priv->soft_iface = dev; |
5bc44dc84 batman-adv: postp... |
409 |
INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish); |
1c9b0550f batman-adv: conve... |
410 411 412 413 414 415 |
/* batadv_interface_stats() needs to be available as soon as * register_netdevice() has been called */ bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t)); if (!bat_priv->bat_counters) |
37130293f batman-adv: Move ... |
416 |
return -ENOMEM; |
c6c8fea29 net: Add batman-a... |
417 |
|
c6c8fea29 net: Add batman-a... |
418 419 |
atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); |
fa706554d batman-adv: don't... |
420 |
#ifdef CONFIG_BATMAN_ADV_BLA |
23721387c batman-adv: add b... |
421 |
atomic_set(&bat_priv->bridge_loop_avoidance, 0); |
fa706554d batman-adv: don't... |
422 |
#endif |
33af49ad8 batman-adv: Distr... |
423 424 425 |
#ifdef CONFIG_BATMAN_ADV_DAT atomic_set(&bat_priv->distributed_arp_table, 1); #endif |
59b699cde batman-adv: imple... |
426 |
atomic_set(&bat_priv->ap_isolation, 0); |
acd34afa8 batman-adv: Prefi... |
427 |
atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); |
cd646ab1e batman-adv: Prefi... |
428 |
atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); |
c6c8fea29 net: Add batman-a... |
429 430 431 |
atomic_set(&bat_priv->gw_sel_class, 20); atomic_set(&bat_priv->gw_bandwidth, 41); atomic_set(&bat_priv->orig_interval, 1000); |
8681a1c4d batman-adv: encou... |
432 |
atomic_set(&bat_priv->hop_penalty, 30); |
0c430d0d7 batman-adv: unblo... |
433 |
#ifdef CONFIG_BATMAN_ADV_DEBUG |
c6c8fea29 net: Add batman-a... |
434 |
atomic_set(&bat_priv->log_level, 0); |
0c430d0d7 batman-adv: unblo... |
435 |
#endif |
c6c8fea29 net: Add batman-a... |
436 |
atomic_set(&bat_priv->fragmentation, 1); |
42d0b044b batman-adv: Prefi... |
437 438 |
atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); |
c6c8fea29 net: Add batman-a... |
439 |
|
39c75a51e batman-adv: Prefi... |
440 |
atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
c6c8fea29 net: Add batman-a... |
441 |
atomic_set(&bat_priv->bcast_seqno, 1); |
807736f6e batman-adv: Split... |
442 443 444 445 446 447 448 449 |
atomic_set(&bat_priv->tt.vn, 0); atomic_set(&bat_priv->tt.local_changes, 0); atomic_set(&bat_priv->tt.ogm_append_cnt, 0); #ifdef CONFIG_BATMAN_ADV_BLA atomic_set(&bat_priv->bla.num_requests, 0); #endif bat_priv->tt.last_changeset = NULL; bat_priv->tt.last_changeset_len = 0; |
c6c8fea29 net: Add batman-a... |
450 451 452 |
bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; |
c6c8fea29 net: Add batman-a... |
453 |
|
d353d8d4d batman-adv: netwo... |
454 |
batadv_nc_init_bat_priv(bat_priv); |
37130293f batman-adv: Move ... |
455 |
ret = batadv_algo_select(bat_priv, batadv_routing_algo); |
c6c8fea29 net: Add batman-a... |
456 |
if (ret < 0) |
37130293f batman-adv: Move ... |
457 |
goto free_bat_counters; |
c6c8fea29 net: Add batman-a... |
458 |
|
37130293f batman-adv: Move ... |
459 |
ret = batadv_debugfs_add_meshif(dev); |
c6c8fea29 net: Add batman-a... |
460 |
if (ret < 0) |
37130293f batman-adv: Move ... |
461 |
goto free_bat_counters; |
c6c8fea29 net: Add batman-a... |
462 |
|
37130293f batman-adv: Move ... |
463 |
ret = batadv_mesh_init(dev); |
c6c8fea29 net: Add batman-a... |
464 465 |
if (ret < 0) goto unreg_debugfs; |
37130293f batman-adv: Move ... |
466 |
return 0; |
c6c8fea29 net: Add batman-a... |
467 468 |
unreg_debugfs: |
37130293f batman-adv: Move ... |
469 |
batadv_debugfs_del_meshif(dev); |
1c9b0550f batman-adv: conve... |
470 471 |
free_bat_counters: free_percpu(bat_priv->bat_counters); |
f69ae770e batman-adv: Avoid... |
472 |
bat_priv->bat_counters = NULL; |
37130293f batman-adv: Move ... |
473 474 475 |
return ret; } |
3dbd550b8 batman-adv: Allow... |
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
/** * batadv_softif_slave_add - Add a slave interface to a batadv_soft_interface * @dev: batadv_soft_interface used as master interface * @slave_dev: net_device which should become the slave interface * * Return 0 if successful or error otherwise. */ static int batadv_softif_slave_add(struct net_device *dev, struct net_device *slave_dev) { struct batadv_hard_iface *hard_iface; int ret = -EINVAL; hard_iface = batadv_hardif_get_by_netdev(slave_dev); if (!hard_iface || hard_iface->soft_iface != NULL) goto out; ret = batadv_hardif_enable_interface(hard_iface, dev->name); out: if (hard_iface) batadv_hardif_free_ref(hard_iface); return ret; } /** * batadv_softif_slave_del - Delete a slave iface from a batadv_soft_interface * @dev: batadv_soft_interface used as master interface * @slave_dev: net_device which should be removed from the master interface * * Return 0 if successful or error otherwise. */ static int batadv_softif_slave_del(struct net_device *dev, struct net_device *slave_dev) { struct batadv_hard_iface *hard_iface; int ret = -EINVAL; hard_iface = batadv_hardif_get_by_netdev(slave_dev); if (!hard_iface || hard_iface->soft_iface != dev) goto out; batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); ret = 0; out: if (hard_iface) batadv_hardif_free_ref(hard_iface); return ret; } |
37130293f batman-adv: Move ... |
527 528 529 530 531 532 533 534 |
static const struct net_device_ops batadv_netdev_ops = { .ndo_init = batadv_softif_init_late, .ndo_open = batadv_interface_open, .ndo_stop = batadv_interface_release, .ndo_get_stats = batadv_interface_stats, .ndo_set_mac_address = batadv_interface_set_mac_addr, .ndo_change_mtu = batadv_interface_change_mtu, .ndo_start_xmit = batadv_interface_tx, |
3dbd550b8 batman-adv: Allow... |
535 536 537 |
.ndo_validate_addr = eth_validate_addr, .ndo_add_slave = batadv_softif_slave_add, .ndo_del_slave = batadv_softif_slave_del, |
37130293f batman-adv: Move ... |
538 539 540 |
}; /** |
b3246020e batman-adv: Move ... |
541 542 543 544 545 546 547 |
* batadv_softif_free - Deconstructor of batadv_soft_interface * @dev: Device to cleanup and remove */ static void batadv_softif_free(struct net_device *dev) { batadv_debugfs_del_meshif(dev); batadv_mesh_free(dev); |
0c501345c batman-adv: fix g... |
548 549 550 551 552 553 |
/* some scheduled RCU callbacks need the bat_priv struct to accomplish * their tasks. Wait for them all to be finished before freeing the * netdev and its private data (bat_priv) */ rcu_barrier(); |
b3246020e batman-adv: Move ... |
554 555 556 557 |
free_netdev(dev); } /** |
37130293f batman-adv: Move ... |
558 559 560 561 562 563 564 565 566 567 |
* batadv_softif_init_early - early stage initialization of soft interface * @dev: registered network device to modify */ static void batadv_softif_init_early(struct net_device *dev) { struct batadv_priv *priv = netdev_priv(dev); ether_setup(dev); dev->netdev_ops = &batadv_netdev_ops; |
b3246020e batman-adv: Move ... |
568 |
dev->destructor = batadv_softif_free; |
37130293f batman-adv: Move ... |
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 |
dev->tx_queue_len = 0; /* can't call min_mtu, because the needed variables * have not been initialized yet */ dev->mtu = ETH_DATA_LEN; /* reserve more space in the skbuff for our header */ dev->hard_header_len = BATADV_HEADER_LEN; /* generate random address */ eth_hw_addr_random(dev); SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops); memset(priv, 0, sizeof(*priv)); } struct net_device *batadv_softif_create(const char *name) { struct net_device *soft_iface; int ret; soft_iface = alloc_netdev(sizeof(struct batadv_priv), name, batadv_softif_init_early); if (!soft_iface) return NULL; |
a4ac28c0d batman-adv: Allow... |
595 |
soft_iface->rtnl_link_ops = &batadv_link_ops; |
37130293f batman-adv: Move ... |
596 597 598 599 600 601 602 603 604 605 |
ret = register_netdevice(soft_iface); if (ret < 0) { pr_err("Unable to register the batman interface '%s': %i ", name, ret); free_netdev(soft_iface); return NULL; } return soft_iface; |
c6c8fea29 net: Add batman-a... |
606 |
} |
e07932ae6 batman-adv: renam... |
607 608 609 610 611 |
/** * batadv_softif_destroy_sysfs - deletion of batadv_soft_interface via sysfs * @soft_iface: the to-be-removed batman-adv interface */ void batadv_softif_destroy_sysfs(struct net_device *soft_iface) |
c6c8fea29 net: Add batman-a... |
612 |
{ |
5bc44dc84 batman-adv: postp... |
613 |
struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
5bc44dc84 batman-adv: postp... |
614 |
queue_work(batadv_event_workqueue, &bat_priv->cleanup_work); |
c6c8fea29 net: Add batman-a... |
615 |
} |
a4ac28c0d batman-adv: Allow... |
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
/** * batadv_softif_destroy_netlink - deletion of batadv_soft_interface via netlink * @soft_iface: the to-be-removed batman-adv interface * @head: list pointer */ static void batadv_softif_destroy_netlink(struct net_device *soft_iface, struct list_head *head) { struct batadv_hard_iface *hard_iface; list_for_each_entry(hard_iface, &batadv_hardif_list, list) { if (hard_iface->soft_iface == soft_iface) batadv_hardif_disable_interface(hard_iface, BATADV_IF_CLEANUP_KEEP); } batadv_sysfs_del_meshif(soft_iface); unregister_netdevice_queue(soft_iface, head); } |
04b482a21 batman-adv: Prefi... |
635 |
int batadv_softif_is_valid(const struct net_device *net_dev) |
e44d8fe2b batman-adv: Disal... |
636 |
{ |
0294ca0d9 batman-adv: Prefi... |
637 |
if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) |
e44d8fe2b batman-adv: Disal... |
638 |
return 1; |
e44d8fe2b batman-adv: Disal... |
639 640 641 |
return 0; } |
a4ac28c0d batman-adv: Allow... |
642 643 644 645 646 647 |
struct rtnl_link_ops batadv_link_ops __read_mostly = { .kind = "batadv", .priv_size = sizeof(struct batadv_priv), .setup = batadv_softif_init_early, .dellink = batadv_softif_destroy_netlink, }; |
c6c8fea29 net: Add batman-a... |
648 |
/* ethtool */ |
0294ca0d9 batman-adv: Prefi... |
649 |
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
c6c8fea29 net: Add batman-a... |
650 651 652 |
{ cmd->supported = 0; cmd->advertising = 0; |
707394972 ethtool: cosmetic... |
653 |
ethtool_cmd_speed_set(cmd, SPEED_10); |
c6c8fea29 net: Add batman-a... |
654 655 656 657 658 659 660 661 662 663 |
cmd->duplex = DUPLEX_FULL; cmd->port = PORT_TP; cmd->phy_address = 0; cmd->transceiver = XCVR_INTERNAL; cmd->autoneg = AUTONEG_DISABLE; cmd->maxtxpkt = 0; cmd->maxrxpkt = 0; return 0; } |
0294ca0d9 batman-adv: Prefi... |
664 665 |
static void batadv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
c6c8fea29 net: Add batman-a... |
666 |
{ |
7826d43f2 ethtool: fix drvi... |
667 668 669 670 |
strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); strlcpy(info->bus_info, "batman", sizeof(info->bus_info)); |
c6c8fea29 net: Add batman-a... |
671 |
} |
0294ca0d9 batman-adv: Prefi... |
672 |
static u32 batadv_get_msglevel(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
673 674 675 |
{ return -EOPNOTSUPP; } |
0294ca0d9 batman-adv: Prefi... |
676 |
static void batadv_set_msglevel(struct net_device *dev, u32 value) |
c6c8fea29 net: Add batman-a... |
677 678 |
{ } |
0294ca0d9 batman-adv: Prefi... |
679 |
static u32 batadv_get_link(struct net_device *dev) |
c6c8fea29 net: Add batman-a... |
680 681 682 |
{ return 1; } |
f8214865a batman-adv: Add g... |
683 684 685 686 687 688 689 |
/* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 * Declare each description string in struct.name[] to get fixed sized buffer * and compile time checking for strings longer than ETH_GSTRING_LEN. */ static const struct { const char name[ETH_GSTRING_LEN]; |
0294ca0d9 batman-adv: Prefi... |
690 |
} batadv_counters_strings[] = { |
1c9b0550f batman-adv: conve... |
691 692 693 694 695 |
{ "tx" }, { "tx_bytes" }, { "tx_dropped" }, { "rx" }, { "rx_bytes" }, |
f8214865a batman-adv: Add g... |
696 697 698 699 700 701 702 703 704 705 706 707 |
{ "forward" }, { "forward_bytes" }, { "mgmt_tx" }, { "mgmt_tx_bytes" }, { "mgmt_rx" }, { "mgmt_rx_bytes" }, { "tt_request_tx" }, { "tt_request_rx" }, { "tt_response_tx" }, { "tt_response_rx" }, { "tt_roam_adv_tx" }, { "tt_roam_adv_rx" }, |
4046b24af batman-adv: Add g... |
708 709 710 711 712 713 714 |
#ifdef CONFIG_BATMAN_ADV_DAT { "dat_get_tx" }, { "dat_get_rx" }, { "dat_put_tx" }, { "dat_put_rx" }, { "dat_cached_reply_tx" }, #endif |
3c12de9a5 batman-adv: netwo... |
715 716 717 718 719 |
#ifdef CONFIG_BATMAN_ADV_NC { "nc_code" }, { "nc_code_bytes" }, { "nc_recode" }, { "nc_recode_bytes" }, |
612d2b4fe batman-adv: netwo... |
720 |
{ "nc_buffer" }, |
2df5278b0 batman-adv: netwo... |
721 722 723 724 |
{ "nc_decode" }, { "nc_decode_bytes" }, { "nc_decode_failed" }, { "nc_sniffed" }, |
3c12de9a5 batman-adv: netwo... |
725 |
#endif |
f8214865a batman-adv: Add g... |
726 727 728 729 730 731 |
}; static void batadv_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { if (stringset == ETH_SS_STATS) |
0294ca0d9 batman-adv: Prefi... |
732 733 |
memcpy(data, batadv_counters_strings, sizeof(batadv_counters_strings)); |
f8214865a batman-adv: Add g... |
734 735 736 737 738 739 |
} static void batadv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, uint64_t *data) { |
56303d34a batman-adv: Prefi... |
740 |
struct batadv_priv *bat_priv = netdev_priv(dev); |
f8214865a batman-adv: Add g... |
741 |
int i; |
d69909d2f batman-adv: Prefi... |
742 |
for (i = 0; i < BATADV_CNT_NUM; i++) |
f8214865a batman-adv: Add g... |
743 744 745 746 747 748 |
data[i] = batadv_sum_counter(bat_priv, i); } static int batadv_get_sset_count(struct net_device *dev, int stringset) { if (stringset == ETH_SS_STATS) |
d69909d2f batman-adv: Prefi... |
749 |
return BATADV_CNT_NUM; |
f8214865a batman-adv: Add g... |
750 751 752 |
return -EOPNOTSUPP; } |