| .. | .. |
|---|
| 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" |
|---|
| .. | .. |
|---|
| 209 | 198 | unsigned short vid; |
|---|
| 210 | 199 | u32 seqno; |
|---|
| 211 | 200 | int gw_mode; |
|---|
| 212 | | - enum batadv_forw_mode forw_mode; |
|---|
| 201 | + enum batadv_forw_mode forw_mode = BATADV_FORW_SINGLE; |
|---|
| 213 | 202 | struct batadv_orig_node *mcast_single_orig = NULL; |
|---|
| 203 | + int mcast_is_routable = 0; |
|---|
| 214 | 204 | int network_offset = ETH_HLEN; |
|---|
| 205 | + __be16 proto; |
|---|
| 215 | 206 | |
|---|
| 216 | 207 | if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) |
|---|
| 217 | 208 | goto dropped; |
|---|
| .. | .. |
|---|
| 225 | 216 | skb_reset_mac_header(skb); |
|---|
| 226 | 217 | ethhdr = eth_hdr(skb); |
|---|
| 227 | 218 | |
|---|
| 228 | | - switch (ntohs(ethhdr->h_proto)) { |
|---|
| 219 | + proto = ethhdr->h_proto; |
|---|
| 220 | + |
|---|
| 221 | + switch (ntohs(proto)) { |
|---|
| 229 | 222 | case ETH_P_8021Q: |
|---|
| 230 | 223 | if (!pskb_may_pull(skb, sizeof(*vhdr))) |
|---|
| 231 | 224 | goto dropped; |
|---|
| 232 | 225 | vhdr = vlan_eth_hdr(skb); |
|---|
| 226 | + proto = vhdr->h_vlan_encapsulated_proto; |
|---|
| 233 | 227 | |
|---|
| 234 | 228 | /* drop batman-in-batman packets to prevent loops */ |
|---|
| 235 | | - if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) { |
|---|
| 229 | + if (proto != htons(ETH_P_BATMAN)) { |
|---|
| 236 | 230 | network_offset += VLAN_HLEN; |
|---|
| 237 | 231 | break; |
|---|
| 238 | 232 | } |
|---|
| 239 | 233 | |
|---|
| 240 | | - /* fall through */ |
|---|
| 234 | + fallthrough; |
|---|
| 241 | 235 | case ETH_P_BATMAN: |
|---|
| 242 | 236 | goto dropped; |
|---|
| 243 | 237 | } |
|---|
| .. | .. |
|---|
| 259 | 253 | if (!client_added) |
|---|
| 260 | 254 | goto dropped; |
|---|
| 261 | 255 | } |
|---|
| 256 | + |
|---|
| 257 | + /* Snoop address candidates from DHCPACKs for early DAT filling */ |
|---|
| 258 | + batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid); |
|---|
| 262 | 259 | |
|---|
| 263 | 260 | /* don't accept stp packets. STP does not help in meshes. |
|---|
| 264 | 261 | * better use the bridge loop avoidance ... |
|---|
| .. | .. |
|---|
| 306 | 303 | send: |
|---|
| 307 | 304 | if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { |
|---|
| 308 | 305 | forw_mode = batadv_mcast_forw_mode(bat_priv, skb, |
|---|
| 309 | | - &mcast_single_orig); |
|---|
| 306 | + &mcast_single_orig, |
|---|
| 307 | + &mcast_is_routable); |
|---|
| 310 | 308 | if (forw_mode == BATADV_FORW_NONE) |
|---|
| 311 | 309 | goto dropped; |
|---|
| 312 | 310 | |
|---|
| 313 | | - if (forw_mode == BATADV_FORW_SINGLE) |
|---|
| 311 | + if (forw_mode == BATADV_FORW_SINGLE || |
|---|
| 312 | + forw_mode == BATADV_FORW_SOME) |
|---|
| 314 | 313 | do_bcast = false; |
|---|
| 315 | 314 | } |
|---|
| 316 | 315 | } |
|---|
| .. | .. |
|---|
| 369 | 368 | } else if (mcast_single_orig) { |
|---|
| 370 | 369 | ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid, |
|---|
| 371 | 370 | mcast_single_orig); |
|---|
| 371 | + } else if (forw_mode == BATADV_FORW_SOME) { |
|---|
| 372 | + ret = batadv_mcast_forw_send(bat_priv, skb, vid, |
|---|
| 373 | + mcast_is_routable); |
|---|
| 372 | 374 | } else { |
|---|
| 373 | 375 | if (batadv_dat_snoop_outgoing_arp_request(bat_priv, |
|---|
| 374 | 376 | skb)) |
|---|
| .. | .. |
|---|
| 406 | 408 | * @hdr_size: size of already parsed batman-adv header |
|---|
| 407 | 409 | * @orig_node: originator from which the batman-adv packet was sent |
|---|
| 408 | 410 | * |
|---|
| 409 | | - * Sends a ethernet frame to the receive path of the local @soft_iface. |
|---|
| 411 | + * Sends an ethernet frame to the receive path of the local @soft_iface. |
|---|
| 410 | 412 | * skb->data has still point to the batman-adv header with the size @hdr_size. |
|---|
| 411 | 413 | * The caller has to have parsed this header already and made sure that at least |
|---|
| 412 | 414 | * @hdr_size bytes are still available for pull in @skb. |
|---|
| .. | .. |
|---|
| 436 | 438 | /* clean the netfilter state now that the batman-adv header has been |
|---|
| 437 | 439 | * removed |
|---|
| 438 | 440 | */ |
|---|
| 439 | | - nf_reset(skb); |
|---|
| 441 | + nf_reset_ct(skb); |
|---|
| 440 | 442 | |
|---|
| 441 | 443 | if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) |
|---|
| 442 | 444 | goto dropped; |
|---|
| .. | .. |
|---|
| 455 | 457 | if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) |
|---|
| 456 | 458 | break; |
|---|
| 457 | 459 | |
|---|
| 458 | | - /* fall through */ |
|---|
| 460 | + fallthrough; |
|---|
| 459 | 461 | case ETH_P_BATMAN: |
|---|
| 460 | 462 | goto dropped; |
|---|
| 461 | 463 | } |
|---|
| .. | .. |
|---|
| 510 | 512 | * after rcu grace period |
|---|
| 511 | 513 | * @ref: kref pointer of the vlan object |
|---|
| 512 | 514 | */ |
|---|
| 513 | | -static void batadv_softif_vlan_release(struct kref *ref) |
|---|
| 515 | +void batadv_softif_vlan_release(struct kref *ref) |
|---|
| 514 | 516 | { |
|---|
| 515 | 517 | struct batadv_softif_vlan *vlan; |
|---|
| 516 | 518 | |
|---|
| .. | .. |
|---|
| 521 | 523 | spin_unlock_bh(&vlan->bat_priv->softif_vlan_list_lock); |
|---|
| 522 | 524 | |
|---|
| 523 | 525 | 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 | 526 | } |
|---|
| 538 | 527 | |
|---|
| 539 | 528 | /** |
|---|
| .. | .. |
|---|
| 649 | 638 | /** |
|---|
| 650 | 639 | * batadv_interface_add_vid() - ndo_add_vid API implementation |
|---|
| 651 | 640 | * @dev: the netdev of the mesh interface |
|---|
| 652 | | - * @proto: protocol of the the vlan id |
|---|
| 641 | + * @proto: protocol of the vlan id |
|---|
| 653 | 642 | * @vid: identifier of the new vlan |
|---|
| 654 | 643 | * |
|---|
| 655 | 644 | * Set up all the internal structures for handling the new vlan on top of the |
|---|
| .. | .. |
|---|
| 707 | 696 | /** |
|---|
| 708 | 697 | * batadv_interface_kill_vid() - ndo_kill_vid API implementation |
|---|
| 709 | 698 | * @dev: the netdev of the mesh interface |
|---|
| 710 | | - * @proto: protocol of the the vlan id |
|---|
| 699 | + * @proto: protocol of the vlan id |
|---|
| 711 | 700 | * @vid: identifier of the deleted vlan |
|---|
| 712 | 701 | * |
|---|
| 713 | 702 | * Destroy all the internal structures used to handle the vlan identified by vid |
|---|
| .. | .. |
|---|
| 804 | 793 | atomic_set(&bat_priv->distributed_arp_table, 1); |
|---|
| 805 | 794 | #endif |
|---|
| 806 | 795 | #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 | 796 | atomic_set(&bat_priv->multicast_mode, 1); |
|---|
| 797 | + atomic_set(&bat_priv->multicast_fanout, 16); |
|---|
| 813 | 798 | atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); |
|---|
| 814 | 799 | atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); |
|---|
| 815 | 800 | atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); |
|---|
| .. | .. |
|---|
| 847 | 832 | atomic_set(&bat_priv->frag_seqno, random_seqno); |
|---|
| 848 | 833 | |
|---|
| 849 | 834 | bat_priv->primary_if = NULL; |
|---|
| 850 | | - bat_priv->num_ifaces = 0; |
|---|
| 851 | 835 | |
|---|
| 852 | 836 | batadv_nc_init_bat_priv(bat_priv); |
|---|
| 853 | 837 | |
|---|
| .. | .. |
|---|
| 948 | 932 | static void batadv_get_drvinfo(struct net_device *dev, |
|---|
| 949 | 933 | struct ethtool_drvinfo *info) |
|---|
| 950 | 934 | { |
|---|
| 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)); |
|---|
| 935 | + strscpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); |
|---|
| 936 | + strscpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); |
|---|
| 937 | + strscpy(info->fw_version, "N/A", sizeof(info->fw_version)); |
|---|
| 938 | + strscpy(info->bus_info, "batman", sizeof(info->bus_info)); |
|---|
| 955 | 939 | } |
|---|
| 956 | 940 | |
|---|
| 957 | 941 | /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 |
|---|
| .. | .. |
|---|
| 1065 | 1049 | dev->needs_free_netdev = true; |
|---|
| 1066 | 1050 | dev->priv_destructor = batadv_softif_free; |
|---|
| 1067 | 1051 | dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL; |
|---|
| 1052 | + dev->features |= NETIF_F_LLTX; |
|---|
| 1068 | 1053 | dev->priv_flags |= IFF_NO_QUEUE; |
|---|
| 1069 | 1054 | |
|---|
| 1070 | 1055 | /* can't call min_mtu, because the needed variables |
|---|