| .. | .. |
|---|
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
|---|
| 2 | | -/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: |
|---|
| 2 | +/* Copyright (C) 2007-2020 B.A.T.M.A.N. contributors: |
|---|
| 3 | 3 | * |
|---|
| 4 | 4 | * Marek Lindner, Simon Wunderlich |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of version 2 of the GNU General Public |
|---|
| 8 | | - * License as published by the Free Software Foundation. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | | - * General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License |
|---|
| 16 | | - * along with this program; if not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | 5 | */ |
|---|
| 18 | 6 | |
|---|
| 19 | 7 | #include "soft-interface.h" |
|---|
| .. | .. |
|---|
| 36 | 24 | #include <linux/list.h> |
|---|
| 37 | 25 | #include <linux/lockdep.h> |
|---|
| 38 | 26 | #include <linux/netdevice.h> |
|---|
| 27 | +#include <linux/netlink.h> |
|---|
| 39 | 28 | #include <linux/percpu.h> |
|---|
| 40 | 29 | #include <linux/printk.h> |
|---|
| 41 | 30 | #include <linux/random.h> |
|---|
| .. | .. |
|---|
| 50 | 39 | #include <linux/string.h> |
|---|
| 51 | 40 | #include <linux/types.h> |
|---|
| 52 | 41 | #include <uapi/linux/batadv_packet.h> |
|---|
| 42 | +#include <uapi/linux/batman_adv.h> |
|---|
| 53 | 43 | |
|---|
| 54 | 44 | #include "bat_algo.h" |
|---|
| 55 | 45 | #include "bridge_loop_avoidance.h" |
|---|
| 56 | 46 | #include "debugfs.h" |
|---|
| 57 | 47 | #include "distributed-arp-table.h" |
|---|
| 58 | 48 | #include "gateway_client.h" |
|---|
| 59 | | -#include "gateway_common.h" |
|---|
| 60 | 49 | #include "hard-interface.h" |
|---|
| 61 | 50 | #include "multicast.h" |
|---|
| 62 | 51 | #include "network-coding.h" |
|---|
| .. | .. |
|---|
| 167 | 156 | |
|---|
| 168 | 157 | static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) |
|---|
| 169 | 158 | { |
|---|
| 159 | + struct batadv_priv *bat_priv = netdev_priv(dev); |
|---|
| 160 | + |
|---|
| 170 | 161 | /* check ranges */ |
|---|
| 171 | 162 | if (new_mtu < 68 || new_mtu > batadv_hardif_min_mtu(dev)) |
|---|
| 172 | 163 | return -EINVAL; |
|---|
| 173 | 164 | |
|---|
| 174 | 165 | dev->mtu = new_mtu; |
|---|
| 166 | + bat_priv->mtu_set_by_user = new_mtu; |
|---|
| 175 | 167 | |
|---|
| 176 | 168 | return 0; |
|---|
| 177 | 169 | } |
|---|
| .. | .. |
|---|
| 209 | 201 | unsigned short vid; |
|---|
| 210 | 202 | u32 seqno; |
|---|
| 211 | 203 | int gw_mode; |
|---|
| 212 | | - enum batadv_forw_mode forw_mode; |
|---|
| 204 | + enum batadv_forw_mode forw_mode = BATADV_FORW_SINGLE; |
|---|
| 213 | 205 | struct batadv_orig_node *mcast_single_orig = NULL; |
|---|
| 206 | + int mcast_is_routable = 0; |
|---|
| 214 | 207 | int network_offset = ETH_HLEN; |
|---|
| 208 | + __be16 proto; |
|---|
| 215 | 209 | |
|---|
| 216 | 210 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
|---|
| 217 | 211 | goto dropped; |
|---|
| .. | .. |
|---|
| 225 | 219 | skb_reset_mac_header(skb); |
|---|
| 226 | 220 | ethhdr = eth_hdr(skb); |
|---|
| 227 | 221 | |
|---|
| 228 | | - switch (ntohs(ethhdr->h_proto)) { |
|---|
| 222 | + proto = ethhdr->h_proto; |
|---|
| 223 | + |
|---|
| 224 | + switch (ntohs(proto)) { |
|---|
| 229 | 225 | case ETH_P_8021Q: |
|---|
| 230 | 226 | if (!pskb_may_pull(skb, sizeof(*vhdr))) |
|---|
| 231 | 227 | goto dropped; |
|---|
| 232 | 228 | vhdr = vlan_eth_hdr(skb); |
|---|
| 229 | + proto = vhdr->h_vlan_encapsulated_proto; |
|---|
| 233 | 230 | |
|---|
| 234 | 231 | /* drop batman-in-batman packets to prevent loops */ |
|---|
| 235 | | - if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) { |
|---|
| 232 | + if (proto != htons(ETH_P_BATMAN)) { |
|---|
| 236 | 233 | network_offset += VLAN_HLEN; |
|---|
| 237 | 234 | break; |
|---|
| 238 | 235 | } |
|---|
| 239 | 236 | |
|---|
| 240 | | - /* fall through */ |
|---|
| 237 | + fallthrough; |
|---|
| 241 | 238 | case ETH_P_BATMAN: |
|---|
| 242 | 239 | goto dropped; |
|---|
| 243 | 240 | } |
|---|
| .. | .. |
|---|
| 259 | 256 | if (!client_added) |
|---|
| 260 | 257 | goto dropped; |
|---|
| 261 | 258 | } |
|---|
| 259 | + |
|---|
| 260 | + /* Snoop address candidates from DHCPACKs for early DAT filling */ |
|---|
| 261 | + batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid); |
|---|
| 262 | 262 | |
|---|
| 263 | 263 | /* don't accept stp packets. STP does not help in meshes. |
|---|
| 264 | 264 | * better use the bridge loop avoidance ... |
|---|
| .. | .. |
|---|
| 306 | 306 | send: |
|---|
| 307 | 307 | if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { |
|---|
| 308 | 308 | forw_mode = batadv_mcast_forw_mode(bat_priv, skb, |
|---|
| 309 | | - &mcast_single_orig); |
|---|
| 309 | + &mcast_single_orig, |
|---|
| 310 | + &mcast_is_routable); |
|---|
| 310 | 311 | if (forw_mode == BATADV_FORW_NONE) |
|---|
| 311 | 312 | goto dropped; |
|---|
| 312 | 313 | |
|---|
| 313 | | - if (forw_mode == BATADV_FORW_SINGLE) |
|---|
| 314 | + if (forw_mode == BATADV_FORW_SINGLE || |
|---|
| 315 | + forw_mode == BATADV_FORW_SOME) |
|---|
| 314 | 316 | do_bcast = false; |
|---|
| 315 | 317 | } |
|---|
| 316 | 318 | } |
|---|
| .. | .. |
|---|
| 369 | 371 | } else if (mcast_single_orig) { |
|---|
| 370 | 372 | ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid, |
|---|
| 371 | 373 | mcast_single_orig); |
|---|
| 374 | + } else if (forw_mode == BATADV_FORW_SOME) { |
|---|
| 375 | + ret = batadv_mcast_forw_send(bat_priv, skb, vid, |
|---|
| 376 | + mcast_is_routable); |
|---|
| 372 | 377 | } else { |
|---|
| 373 | 378 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, |
|---|
| 374 | 379 | skb)) |
|---|
| .. | .. |
|---|
| 406 | 411 | * @hdr_size: size of already parsed batman-adv header |
|---|
| 407 | 412 | * @orig_node: originator from which the batman-adv packet was sent |
|---|
| 408 | 413 | * |
|---|
| 409 | | - * Sends a ethernet frame to the receive path of the local @soft_iface. |
|---|
| 414 | + * Sends an ethernet frame to the receive path of the local @soft_iface. |
|---|
| 410 | 415 | * skb->data has still point to the batman-adv header with the size @hdr_size. |
|---|
| 411 | 416 | * The caller has to have parsed this header already and made sure that at least |
|---|
| 412 | 417 | * @hdr_size bytes are still available for pull in @skb. |
|---|
| .. | .. |
|---|
| 436 | 441 | /* clean the netfilter state now that the batman-adv header has been |
|---|
| 437 | 442 | * removed |
|---|
| 438 | 443 | */ |
|---|
| 439 | | - nf_reset(skb); |
|---|
| 444 | + nf_reset_ct(skb); |
|---|
| 440 | 445 | |
|---|
| 441 | 446 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) |
|---|
| 442 | 447 | goto dropped; |
|---|
| .. | .. |
|---|
| 455 | 460 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) |
|---|
| 456 | 461 | break; |
|---|
| 457 | 462 | |
|---|
| 458 | | - /* fall through */ |
|---|
| 463 | + fallthrough; |
|---|
| 459 | 464 | case ETH_P_BATMAN: |
|---|
| 460 | 465 | goto dropped; |
|---|
| 461 | 466 | } |
|---|
| .. | .. |
|---|
| 510 | 515 | * after rcu grace period |
|---|
| 511 | 516 | * @ref: kref pointer of the vlan object |
|---|
| 512 | 517 | */ |
|---|
| 513 | | -static void batadv_softif_vlan_release(struct kref *ref) |
|---|
| 518 | +void batadv_softif_vlan_release(struct kref *ref) |
|---|
| 514 | 519 | { |
|---|
| 515 | 520 | struct batadv_softif_vlan *vlan; |
|---|
| 516 | 521 | |
|---|
| .. | .. |
|---|
| 521 | 526 | spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); |
|---|
| 522 | 527 | |
|---|
| 523 | 528 | kfree_rcu(vlan, rcu); |
|---|
| 524 | | -} |
|---|
| 525 | | - |
|---|
| 526 | | -/** |
|---|
| 527 | | - * batadv_softif_vlan_put() - decrease the vlan object refcounter and |
|---|
| 528 | | - * possibly release it |
|---|
| 529 | | - * @vlan: the vlan object to release |
|---|
| 530 | | - */ |
|---|
| 531 | | -void batadv_softif_vlan_put(struct batadv_softif_vlan *vlan) |
|---|
| 532 | | -{ |
|---|
| 533 | | - if (!vlan) |
|---|
| 534 | | - return; |
|---|
| 535 | | - |
|---|
| 536 | | - kref_put(&vlan->refcount, batadv_softif_vlan_release); |
|---|
| 537 | 529 | } |
|---|
| 538 | 530 | |
|---|
| 539 | 531 | /** |
|---|
| .. | .. |
|---|
| 649 | 641 | /** |
|---|
| 650 | 642 | * batadv_interface_add_vid() - ndo_add_vid API implementation |
|---|
| 651 | 643 | * @dev: the netdev of the mesh interface |
|---|
| 652 | | - * @proto: protocol of the the vlan id |
|---|
| 644 | + * @proto: protocol of the vlan id |
|---|
| 653 | 645 | * @vid: identifier of the new vlan |
|---|
| 654 | 646 | * |
|---|
| 655 | 647 | * Set up all the internal structures for handling the new vlan on top of the |
|---|
| .. | .. |
|---|
| 707 | 699 | /** |
|---|
| 708 | 700 | * batadv_interface_kill_vid() - ndo_kill_vid API implementation |
|---|
| 709 | 701 | * @dev: the netdev of the mesh interface |
|---|
| 710 | | - * @proto: protocol of the the vlan id |
|---|
| 702 | + * @proto: protocol of the vlan id |
|---|
| 711 | 703 | * @vid: identifier of the deleted vlan |
|---|
| 712 | 704 | * |
|---|
| 713 | 705 | * Destroy all the internal structures used to handle the vlan identified by vid |
|---|
| .. | .. |
|---|
| 804 | 796 | atomic_set(&bat_priv->distributed_arp_table, 1); |
|---|
| 805 | 797 | #endif |
|---|
| 806 | 798 | #ifdef CONFIG_BATMAN_ADV_MCAST |
|---|
| 807 | | - bat_priv->mcast.querier_ipv4.exists = false; |
|---|
| 808 | | - bat_priv->mcast.querier_ipv4.shadowing = false; |
|---|
| 809 | | - bat_priv->mcast.querier_ipv6.exists = false; |
|---|
| 810 | | - bat_priv->mcast.querier_ipv6.shadowing = false; |
|---|
| 811 | | - bat_priv->mcast.flags = BATADV_NO_FLAGS; |
|---|
| 812 | 799 | atomic_set(&bat_priv->multicast_mode, 1); |
|---|
| 800 | + atomic_set(&bat_priv->multicast_fanout, 16); |
|---|
| 813 | 801 | atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); |
|---|
| 814 | 802 | atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); |
|---|
| 815 | 803 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); |
|---|
| .. | .. |
|---|
| 847 | 835 | atomic_set(&bat_priv->frag_seqno, random_seqno); |
|---|
| 848 | 836 | |
|---|
| 849 | 837 | bat_priv->primary_if = NULL; |
|---|
| 850 | | - bat_priv->num_ifaces = 0; |
|---|
| 851 | 838 | |
|---|
| 852 | 839 | batadv_nc_init_bat_priv(bat_priv); |
|---|
| 853 | 840 | |
|---|
| .. | .. |
|---|
| 948 | 935 | static void batadv_get_drvinfo(struct net_device *dev, |
|---|
| 949 | 936 | struct ethtool_drvinfo *info) |
|---|
| 950 | 937 | { |
|---|
| 951 | | - strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); |
|---|
| 952 | | - strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); |
|---|
| 953 | | - strlcpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
|---|
| 954 | | - strlcpy(info->bus_info, "batman", sizeof(info->bus_info)); |
|---|
| 938 | + strscpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); |
|---|
| 939 | + strscpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); |
|---|
| 940 | + strscpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
|---|
| 941 | + strscpy(info->bus_info, "batman", sizeof(info->bus_info)); |
|---|
| 955 | 942 | } |
|---|
| 956 | 943 | |
|---|
| 957 | 944 | /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 |
|---|
| .. | .. |
|---|
| 1065 | 1052 | dev->needs_free_netdev = true; |
|---|
| 1066 | 1053 | dev->priv_destructor = batadv_softif_free; |
|---|
| 1067 | 1054 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; |
|---|
| 1055 | + dev->features |= NETIF_F_LLTX; |
|---|
| 1068 | 1056 | dev->priv_flags |= IFF_NO_QUEUE; |
|---|
| 1069 | 1057 | |
|---|
| 1070 | 1058 | /* can't call min_mtu, because the needed variables |
|---|