diff options
Diffstat (limited to 'net/batman-adv/soft-interface.c')
-rw-r--r-- | net/batman-adv/soft-interface.c | 269 |
1 files changed, 241 insertions, 28 deletions
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 813db4e64602..36f050876f82 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
35 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
36 | #include <linux/if_vlan.h> | 36 | #include <linux/if_vlan.h> |
37 | #include <linux/if_ether.h> | ||
38 | #include "unicast.h" | ||
39 | #include "bridge_loop_avoidance.h" | 37 | #include "bridge_loop_avoidance.h" |
40 | #include "network-coding.h" | 38 | #include "network-coding.h" |
41 | 39 | ||
@@ -120,9 +118,10 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) | |||
120 | 118 | ||
121 | /* only modify transtable if it has been initialized before */ | 119 | /* only modify transtable if it has been initialized before */ |
122 | if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { | 120 | if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) { |
123 | batadv_tt_local_remove(bat_priv, old_addr, | 121 | batadv_tt_local_remove(bat_priv, old_addr, BATADV_NO_FLAGS, |
124 | "mac address changed", false); | 122 | "mac address changed", false); |
125 | batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX); | 123 | batadv_tt_local_add(dev, addr->sa_data, BATADV_NO_FLAGS, |
124 | BATADV_NULL_IFINDEX); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | return 0; | 127 | return 0; |
@@ -139,36 +138,48 @@ static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) | |||
139 | return 0; | 138 | return 0; |
140 | } | 139 | } |
141 | 140 | ||
141 | /** | ||
142 | * batadv_interface_set_rx_mode - set the rx mode of a device | ||
143 | * @dev: registered network device to modify | ||
144 | * | ||
145 | * We do not actually need to set any rx filters for the virtual batman | ||
146 | * soft interface. However a dummy handler enables a user to set static | ||
147 | * multicast listeners for instance. | ||
148 | */ | ||
149 | static void batadv_interface_set_rx_mode(struct net_device *dev) | ||
150 | { | ||
151 | } | ||
152 | |||
142 | static int batadv_interface_tx(struct sk_buff *skb, | 153 | static int batadv_interface_tx(struct sk_buff *skb, |
143 | struct net_device *soft_iface) | 154 | struct net_device *soft_iface) |
144 | { | 155 | { |
145 | struct ethhdr *ethhdr = (struct ethhdr *)skb->data; | 156 | struct ethhdr *ethhdr; |
146 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 157 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
147 | struct batadv_hard_iface *primary_if = NULL; | 158 | struct batadv_hard_iface *primary_if = NULL; |
148 | struct batadv_bcast_packet *bcast_packet; | 159 | struct batadv_bcast_packet *bcast_packet; |
149 | struct vlan_ethhdr *vhdr; | 160 | __be16 ethertype = htons(ETH_P_BATMAN); |
150 | __be16 ethertype = __constant_htons(ETH_P_BATMAN); | ||
151 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, | 161 | static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, |
152 | 0x00, 0x00}; | 162 | 0x00, 0x00}; |
153 | static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, | 163 | static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, |
154 | 0x00, 0x00}; | 164 | 0x00, 0x00}; |
165 | struct vlan_ethhdr *vhdr; | ||
155 | unsigned int header_len = 0; | 166 | unsigned int header_len = 0; |
156 | int data_len = skb->len, ret; | 167 | int data_len = skb->len, ret; |
157 | unsigned short vid __maybe_unused = BATADV_NO_FLAGS; | ||
158 | bool do_bcast = false; | ||
159 | uint32_t seqno; | ||
160 | unsigned long brd_delay = 1; | 168 | unsigned long brd_delay = 1; |
169 | bool do_bcast = false, client_added; | ||
170 | unsigned short vid; | ||
171 | uint32_t seqno; | ||
161 | 172 | ||
162 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) | 173 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
163 | goto dropped; | 174 | goto dropped; |
164 | 175 | ||
165 | soft_iface->trans_start = jiffies; | 176 | soft_iface->trans_start = jiffies; |
177 | vid = batadv_get_vid(skb, 0); | ||
178 | ethhdr = (struct ethhdr *)skb->data; | ||
166 | 179 | ||
167 | switch (ntohs(ethhdr->h_proto)) { | 180 | switch (ntohs(ethhdr->h_proto)) { |
168 | case ETH_P_8021Q: | 181 | case ETH_P_8021Q: |
169 | vhdr = (struct vlan_ethhdr *)skb->data; | 182 | vhdr = (struct vlan_ethhdr *)skb->data; |
170 | vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; | ||
171 | vid |= BATADV_VLAN_HAS_TAG; | ||
172 | 183 | ||
173 | if (vhdr->h_vlan_encapsulated_proto != ethertype) | 184 | if (vhdr->h_vlan_encapsulated_proto != ethertype) |
174 | break; | 185 | break; |
@@ -185,8 +196,12 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
185 | ethhdr = (struct ethhdr *)skb->data; | 196 | ethhdr = (struct ethhdr *)skb->data; |
186 | 197 | ||
187 | /* Register the client MAC in the transtable */ | 198 | /* Register the client MAC in the transtable */ |
188 | if (!is_multicast_ether_addr(ethhdr->h_source)) | 199 | if (!is_multicast_ether_addr(ethhdr->h_source)) { |
189 | batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif); | 200 | client_added = batadv_tt_local_add(soft_iface, ethhdr->h_source, |
201 | vid, skb->skb_iif); | ||
202 | if (!client_added) | ||
203 | goto dropped; | ||
204 | } | ||
190 | 205 | ||
191 | /* don't accept stp packets. STP does not help in meshes. | 206 | /* don't accept stp packets. STP does not help in meshes. |
192 | * better use the bridge loop avoidance ... | 207 | * better use the bridge loop avoidance ... |
@@ -286,8 +301,12 @@ static int batadv_interface_tx(struct sk_buff *skb, | |||
286 | 301 | ||
287 | batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); | 302 | batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); |
288 | 303 | ||
289 | ret = batadv_unicast_send_skb(bat_priv, skb); | 304 | if (is_multicast_ether_addr(ethhdr->h_dest)) |
290 | if (ret != 0) | 305 | ret = batadv_send_skb_via_gw(bat_priv, skb, vid); |
306 | else | ||
307 | ret = batadv_send_skb_via_tt(bat_priv, skb, vid); | ||
308 | |||
309 | if (ret == NET_XMIT_DROP) | ||
291 | goto dropped_freed; | 310 | goto dropped_freed; |
292 | } | 311 | } |
293 | 312 | ||
@@ -309,12 +328,12 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
309 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, | 328 | struct sk_buff *skb, struct batadv_hard_iface *recv_if, |
310 | int hdr_size, struct batadv_orig_node *orig_node) | 329 | int hdr_size, struct batadv_orig_node *orig_node) |
311 | { | 330 | { |
331 | struct batadv_header *batadv_header = (struct batadv_header *)skb->data; | ||
312 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); | 332 | struct batadv_priv *bat_priv = netdev_priv(soft_iface); |
313 | struct ethhdr *ethhdr; | 333 | __be16 ethertype = htons(ETH_P_BATMAN); |
314 | struct vlan_ethhdr *vhdr; | 334 | struct vlan_ethhdr *vhdr; |
315 | struct batadv_header *batadv_header = (struct batadv_header *)skb->data; | 335 | struct ethhdr *ethhdr; |
316 | unsigned short vid __maybe_unused = BATADV_NO_FLAGS; | 336 | unsigned short vid; |
317 | __be16 ethertype = __constant_htons(ETH_P_BATMAN); | ||
318 | bool is_bcast; | 337 | bool is_bcast; |
319 | 338 | ||
320 | is_bcast = (batadv_header->packet_type == BATADV_BCAST); | 339 | is_bcast = (batadv_header->packet_type == BATADV_BCAST); |
@@ -326,13 +345,12 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
326 | skb_pull_rcsum(skb, hdr_size); | 345 | skb_pull_rcsum(skb, hdr_size); |
327 | skb_reset_mac_header(skb); | 346 | skb_reset_mac_header(skb); |
328 | 347 | ||
348 | vid = batadv_get_vid(skb, hdr_size); | ||
329 | ethhdr = eth_hdr(skb); | 349 | ethhdr = eth_hdr(skb); |
330 | 350 | ||
331 | switch (ntohs(ethhdr->h_proto)) { | 351 | switch (ntohs(ethhdr->h_proto)) { |
332 | case ETH_P_8021Q: | 352 | case ETH_P_8021Q: |
333 | vhdr = (struct vlan_ethhdr *)skb->data; | 353 | vhdr = (struct vlan_ethhdr *)skb->data; |
334 | vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; | ||
335 | vid |= BATADV_VLAN_HAS_TAG; | ||
336 | 354 | ||
337 | if (vhdr->h_vlan_encapsulated_proto != ethertype) | 355 | if (vhdr->h_vlan_encapsulated_proto != ethertype) |
338 | break; | 356 | break; |
@@ -368,9 +386,10 @@ void batadv_interface_rx(struct net_device *soft_iface, | |||
368 | 386 | ||
369 | if (orig_node) | 387 | if (orig_node) |
370 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, | 388 | batadv_tt_add_temporary_global_entry(bat_priv, orig_node, |
371 | ethhdr->h_source); | 389 | ethhdr->h_source, vid); |
372 | 390 | ||
373 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) | 391 | if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest, |
392 | vid)) | ||
374 | goto dropped; | 393 | goto dropped; |
375 | 394 | ||
376 | netif_rx(skb); | 395 | netif_rx(skb); |
@@ -382,6 +401,177 @@ out: | |||
382 | return; | 401 | return; |
383 | } | 402 | } |
384 | 403 | ||
404 | /** | ||
405 | * batadv_softif_vlan_free_ref - decrease the vlan object refcounter and | ||
406 | * possibly free it | ||
407 | * @softif_vlan: the vlan object to release | ||
408 | */ | ||
409 | void batadv_softif_vlan_free_ref(struct batadv_softif_vlan *softif_vlan) | ||
410 | { | ||
411 | if (atomic_dec_and_test(&softif_vlan->refcount)) | ||
412 | kfree_rcu(softif_vlan, rcu); | ||
413 | } | ||
414 | |||
415 | /** | ||
416 | * batadv_softif_vlan_get - get the vlan object for a specific vid | ||
417 | * @bat_priv: the bat priv with all the soft interface information | ||
418 | * @vid: the identifier of the vlan object to retrieve | ||
419 | * | ||
420 | * Returns the private data of the vlan matching the vid passed as argument or | ||
421 | * NULL otherwise. The refcounter of the returned object is incremented by 1. | ||
422 | */ | ||
423 | struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv, | ||
424 | unsigned short vid) | ||
425 | { | ||
426 | struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; | ||
427 | |||
428 | rcu_read_lock(); | ||
429 | hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { | ||
430 | if (vlan_tmp->vid != vid) | ||
431 | continue; | ||
432 | |||
433 | if (!atomic_inc_not_zero(&vlan_tmp->refcount)) | ||
434 | continue; | ||
435 | |||
436 | vlan = vlan_tmp; | ||
437 | break; | ||
438 | } | ||
439 | rcu_read_unlock(); | ||
440 | |||
441 | return vlan; | ||
442 | } | ||
443 | |||
444 | /** | ||
445 | * batadv_create_vlan - allocate the needed resources for a new vlan | ||
446 | * @bat_priv: the bat priv with all the soft interface information | ||
447 | * @vid: the VLAN identifier | ||
448 | * | ||
449 | * Returns 0 on success, a negative error otherwise. | ||
450 | */ | ||
451 | int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) | ||
452 | { | ||
453 | struct batadv_softif_vlan *vlan; | ||
454 | int err; | ||
455 | |||
456 | vlan = batadv_softif_vlan_get(bat_priv, vid); | ||
457 | if (vlan) { | ||
458 | batadv_softif_vlan_free_ref(vlan); | ||
459 | return -EEXIST; | ||
460 | } | ||
461 | |||
462 | vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); | ||
463 | if (!vlan) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | vlan->vid = vid; | ||
467 | atomic_set(&vlan->refcount, 1); | ||
468 | |||
469 | atomic_set(&vlan->ap_isolation, 0); | ||
470 | |||
471 | err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan); | ||
472 | if (err) { | ||
473 | kfree(vlan); | ||
474 | return err; | ||
475 | } | ||
476 | |||
477 | /* add a new TT local entry. This one will be marked with the NOPURGE | ||
478 | * flag | ||
479 | */ | ||
480 | batadv_tt_local_add(bat_priv->soft_iface, | ||
481 | bat_priv->soft_iface->dev_addr, vid, | ||
482 | BATADV_NULL_IFINDEX); | ||
483 | |||
484 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
485 | hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list); | ||
486 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
487 | |||
488 | return 0; | ||
489 | } | ||
490 | |||
491 | /** | ||
492 | * batadv_softif_destroy_vlan - remove and destroy a softif_vlan object | ||
493 | * @bat_priv: the bat priv with all the soft interface information | ||
494 | * @vlan: the object to remove | ||
495 | */ | ||
496 | static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv, | ||
497 | struct batadv_softif_vlan *vlan) | ||
498 | { | ||
499 | spin_lock_bh(&bat_priv->softif_vlan_list_lock); | ||
500 | hlist_del_rcu(&vlan->list); | ||
501 | spin_unlock_bh(&bat_priv->softif_vlan_list_lock); | ||
502 | |||
503 | batadv_sysfs_del_vlan(bat_priv, vlan); | ||
504 | |||
505 | /* explicitly remove the associated TT local entry because it is marked | ||
506 | * with the NOPURGE flag | ||
507 | */ | ||
508 | batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr, | ||
509 | vlan->vid, "vlan interface destroyed", false); | ||
510 | |||
511 | batadv_softif_vlan_free_ref(vlan); | ||
512 | } | ||
513 | |||
514 | /** | ||
515 | * batadv_interface_add_vid - ndo_add_vid API implementation | ||
516 | * @dev: the netdev of the mesh interface | ||
517 | * @vid: identifier of the new vlan | ||
518 | * | ||
519 | * Set up all the internal structures for handling the new vlan on top of the | ||
520 | * mesh interface | ||
521 | * | ||
522 | * Returns 0 on success or a negative error code in case of failure. | ||
523 | */ | ||
524 | static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, | ||
525 | unsigned short vid) | ||
526 | { | ||
527 | struct batadv_priv *bat_priv = netdev_priv(dev); | ||
528 | |||
529 | /* only 802.1Q vlans are supported. | ||
530 | * batman-adv does not know how to handle other types | ||
531 | */ | ||
532 | if (proto != htons(ETH_P_8021Q)) | ||
533 | return -EINVAL; | ||
534 | |||
535 | vid |= BATADV_VLAN_HAS_TAG; | ||
536 | |||
537 | return batadv_softif_create_vlan(bat_priv, vid); | ||
538 | } | ||
539 | |||
540 | /** | ||
541 | * batadv_interface_kill_vid - ndo_kill_vid API implementation | ||
542 | * @dev: the netdev of the mesh interface | ||
543 | * @vid: identifier of the deleted vlan | ||
544 | * | ||
545 | * Destroy all the internal structures used to handle the vlan identified by vid | ||
546 | * on top of the mesh interface | ||
547 | * | ||
548 | * Returns 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q | ||
549 | * or -ENOENT if the specified vlan id wasn't registered. | ||
550 | */ | ||
551 | static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, | ||
552 | unsigned short vid) | ||
553 | { | ||
554 | struct batadv_priv *bat_priv = netdev_priv(dev); | ||
555 | struct batadv_softif_vlan *vlan; | ||
556 | |||
557 | /* only 802.1Q vlans are supported. batman-adv does not know how to | ||
558 | * handle other types | ||
559 | */ | ||
560 | if (proto != htons(ETH_P_8021Q)) | ||
561 | return -EINVAL; | ||
562 | |||
563 | vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); | ||
564 | if (!vlan) | ||
565 | return -ENOENT; | ||
566 | |||
567 | batadv_softif_destroy_vlan(bat_priv, vlan); | ||
568 | |||
569 | /* finally free the vlan object */ | ||
570 | batadv_softif_vlan_free_ref(vlan); | ||
571 | |||
572 | return 0; | ||
573 | } | ||
574 | |||
385 | /* batman-adv network devices have devices nesting below it and are a special | 575 | /* batman-adv network devices have devices nesting below it and are a special |
386 | * "super class" of normal network devices; split their locks off into a | 576 | * "super class" of normal network devices; split their locks off into a |
387 | * separate class since they always nest. | 577 | * separate class since they always nest. |
@@ -421,6 +611,7 @@ static void batadv_set_lockdep_class(struct net_device *dev) | |||
421 | */ | 611 | */ |
422 | static void batadv_softif_destroy_finish(struct work_struct *work) | 612 | static void batadv_softif_destroy_finish(struct work_struct *work) |
423 | { | 613 | { |
614 | struct batadv_softif_vlan *vlan; | ||
424 | struct batadv_priv *bat_priv; | 615 | struct batadv_priv *bat_priv; |
425 | struct net_device *soft_iface; | 616 | struct net_device *soft_iface; |
426 | 617 | ||
@@ -428,6 +619,13 @@ static void batadv_softif_destroy_finish(struct work_struct *work) | |||
428 | cleanup_work); | 619 | cleanup_work); |
429 | soft_iface = bat_priv->soft_iface; | 620 | soft_iface = bat_priv->soft_iface; |
430 | 621 | ||
622 | /* destroy the "untagged" VLAN */ | ||
623 | vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS); | ||
624 | if (vlan) { | ||
625 | batadv_softif_destroy_vlan(bat_priv, vlan); | ||
626 | batadv_softif_vlan_free_ref(vlan); | ||
627 | } | ||
628 | |||
431 | batadv_sysfs_del_meshif(soft_iface); | 629 | batadv_sysfs_del_meshif(soft_iface); |
432 | 630 | ||
433 | rtnl_lock(); | 631 | rtnl_lock(); |
@@ -444,6 +642,7 @@ static void batadv_softif_destroy_finish(struct work_struct *work) | |||
444 | static int batadv_softif_init_late(struct net_device *dev) | 642 | static int batadv_softif_init_late(struct net_device *dev) |
445 | { | 643 | { |
446 | struct batadv_priv *bat_priv; | 644 | struct batadv_priv *bat_priv; |
645 | uint32_t random_seqno; | ||
447 | int ret; | 646 | int ret; |
448 | size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; | 647 | size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM; |
449 | 648 | ||
@@ -468,17 +667,17 @@ static int batadv_softif_init_late(struct net_device *dev) | |||
468 | #ifdef CONFIG_BATMAN_ADV_DAT | 667 | #ifdef CONFIG_BATMAN_ADV_DAT |
469 | atomic_set(&bat_priv->distributed_arp_table, 1); | 668 | atomic_set(&bat_priv->distributed_arp_table, 1); |
470 | #endif | 669 | #endif |
471 | atomic_set(&bat_priv->ap_isolation, 0); | ||
472 | atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE); | ||
473 | atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); | 670 | atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF); |
474 | atomic_set(&bat_priv->gw_sel_class, 20); | 671 | atomic_set(&bat_priv->gw_sel_class, 20); |
475 | atomic_set(&bat_priv->gw_bandwidth, 41); | 672 | atomic_set(&bat_priv->gw.bandwidth_down, 100); |
673 | atomic_set(&bat_priv->gw.bandwidth_up, 20); | ||
476 | atomic_set(&bat_priv->orig_interval, 1000); | 674 | atomic_set(&bat_priv->orig_interval, 1000); |
477 | atomic_set(&bat_priv->hop_penalty, 30); | 675 | atomic_set(&bat_priv->hop_penalty, 30); |
478 | #ifdef CONFIG_BATMAN_ADV_DEBUG | 676 | #ifdef CONFIG_BATMAN_ADV_DEBUG |
479 | atomic_set(&bat_priv->log_level, 0); | 677 | atomic_set(&bat_priv->log_level, 0); |
480 | #endif | 678 | #endif |
481 | atomic_set(&bat_priv->fragmentation, 1); | 679 | atomic_set(&bat_priv->fragmentation, 1); |
680 | atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN); | ||
482 | atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); | 681 | atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); |
483 | atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); | 682 | atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); |
484 | 683 | ||
@@ -493,6 +692,10 @@ static int batadv_softif_init_late(struct net_device *dev) | |||
493 | bat_priv->tt.last_changeset = NULL; | 692 | bat_priv->tt.last_changeset = NULL; |
494 | bat_priv->tt.last_changeset_len = 0; | 693 | bat_priv->tt.last_changeset_len = 0; |
495 | 694 | ||
695 | /* randomize initial seqno to avoid collision */ | ||
696 | get_random_bytes(&random_seqno, sizeof(random_seqno)); | ||
697 | atomic_set(&bat_priv->frag_seqno, random_seqno); | ||
698 | |||
496 | bat_priv->primary_if = NULL; | 699 | bat_priv->primary_if = NULL; |
497 | bat_priv->num_ifaces = 0; | 700 | bat_priv->num_ifaces = 0; |
498 | 701 | ||
@@ -578,8 +781,11 @@ static const struct net_device_ops batadv_netdev_ops = { | |||
578 | .ndo_open = batadv_interface_open, | 781 | .ndo_open = batadv_interface_open, |
579 | .ndo_stop = batadv_interface_release, | 782 | .ndo_stop = batadv_interface_release, |
580 | .ndo_get_stats = batadv_interface_stats, | 783 | .ndo_get_stats = batadv_interface_stats, |
784 | .ndo_vlan_rx_add_vid = batadv_interface_add_vid, | ||
785 | .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, | ||
581 | .ndo_set_mac_address = batadv_interface_set_mac_addr, | 786 | .ndo_set_mac_address = batadv_interface_set_mac_addr, |
582 | .ndo_change_mtu = batadv_interface_change_mtu, | 787 | .ndo_change_mtu = batadv_interface_change_mtu, |
788 | .ndo_set_rx_mode = batadv_interface_set_rx_mode, | ||
583 | .ndo_start_xmit = batadv_interface_tx, | 789 | .ndo_start_xmit = batadv_interface_tx, |
584 | .ndo_validate_addr = eth_validate_addr, | 790 | .ndo_validate_addr = eth_validate_addr, |
585 | .ndo_add_slave = batadv_softif_slave_add, | 791 | .ndo_add_slave = batadv_softif_slave_add, |
@@ -616,6 +822,7 @@ static void batadv_softif_init_early(struct net_device *dev) | |||
616 | 822 | ||
617 | dev->netdev_ops = &batadv_netdev_ops; | 823 | dev->netdev_ops = &batadv_netdev_ops; |
618 | dev->destructor = batadv_softif_free; | 824 | dev->destructor = batadv_softif_free; |
825 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; | ||
619 | dev->tx_queue_len = 0; | 826 | dev->tx_queue_len = 0; |
620 | 827 | ||
621 | /* can't call min_mtu, because the needed variables | 828 | /* can't call min_mtu, because the needed variables |
@@ -623,7 +830,7 @@ static void batadv_softif_init_early(struct net_device *dev) | |||
623 | */ | 830 | */ |
624 | dev->mtu = ETH_DATA_LEN; | 831 | dev->mtu = ETH_DATA_LEN; |
625 | /* reserve more space in the skbuff for our header */ | 832 | /* reserve more space in the skbuff for our header */ |
626 | dev->hard_header_len = BATADV_HEADER_LEN; | 833 | dev->hard_header_len = batadv_max_header_len(); |
627 | 834 | ||
628 | /* generate random address */ | 835 | /* generate random address */ |
629 | eth_hw_addr_random(dev); | 836 | eth_hw_addr_random(dev); |
@@ -760,6 +967,12 @@ static const struct { | |||
760 | { "mgmt_tx_bytes" }, | 967 | { "mgmt_tx_bytes" }, |
761 | { "mgmt_rx" }, | 968 | { "mgmt_rx" }, |
762 | { "mgmt_rx_bytes" }, | 969 | { "mgmt_rx_bytes" }, |
970 | { "frag_tx" }, | ||
971 | { "frag_tx_bytes" }, | ||
972 | { "frag_rx" }, | ||
973 | { "frag_rx_bytes" }, | ||
974 | { "frag_fwd" }, | ||
975 | { "frag_fwd_bytes" }, | ||
763 | { "tt_request_tx" }, | 976 | { "tt_request_tx" }, |
764 | { "tt_request_rx" }, | 977 | { "tt_request_rx" }, |
765 | { "tt_response_tx" }, | 978 | { "tt_response_tx" }, |