194433355SSven Eckelmann // SPDX-License-Identifier: GPL-2.0 294433355SSven Eckelmann /* Copyright (C) B.A.T.M.A.N. contributors: 394433355SSven Eckelmann * 494433355SSven Eckelmann * Marek Lindner, Simon Wunderlich 594433355SSven Eckelmann */ 694433355SSven Eckelmann 794433355SSven Eckelmann #include "mesh-interface.h" 894433355SSven Eckelmann #include "main.h" 994433355SSven Eckelmann 1094433355SSven Eckelmann #include <linux/atomic.h> 1194433355SSven Eckelmann #include <linux/byteorder/generic.h> 1294433355SSven Eckelmann #include <linux/cache.h> 1394433355SSven Eckelmann #include <linux/compiler.h> 1494433355SSven Eckelmann #include <linux/container_of.h> 1594433355SSven Eckelmann #include <linux/cpumask.h> 1694433355SSven Eckelmann #include <linux/errno.h> 1794433355SSven Eckelmann #include <linux/etherdevice.h> 1894433355SSven Eckelmann #include <linux/ethtool.h> 1994433355SSven Eckelmann #include <linux/gfp.h> 2094433355SSven Eckelmann #include <linux/if_ether.h> 2194433355SSven Eckelmann #include <linux/if_vlan.h> 2294433355SSven Eckelmann #include <linux/jiffies.h> 2394433355SSven Eckelmann #include <linux/kref.h> 2494433355SSven Eckelmann #include <linux/list.h> 2594433355SSven Eckelmann #include <linux/lockdep.h> 2694433355SSven Eckelmann #include <linux/netdevice.h> 2794433355SSven Eckelmann #include <linux/netlink.h> 2894433355SSven Eckelmann #include <linux/percpu.h> 2994433355SSven Eckelmann #include <linux/random.h> 3094433355SSven Eckelmann #include <linux/rculist.h> 3194433355SSven Eckelmann #include <linux/rcupdate.h> 3294433355SSven Eckelmann #include <linux/skbuff.h> 3394433355SSven Eckelmann #include <linux/slab.h> 3494433355SSven Eckelmann #include <linux/socket.h> 3594433355SSven Eckelmann #include <linux/spinlock.h> 3694433355SSven Eckelmann #include <linux/stddef.h> 3794433355SSven Eckelmann #include <linux/string.h> 3894433355SSven Eckelmann #include <linux/types.h> 3994433355SSven Eckelmann #include <net/net_namespace.h> 4094433355SSven Eckelmann #include <net/netlink.h> 4194433355SSven Eckelmann #include <uapi/linux/batadv_packet.h> 4294433355SSven Eckelmann #include <uapi/linux/batman_adv.h> 4394433355SSven Eckelmann 4494433355SSven Eckelmann #include "bat_algo.h" 4594433355SSven Eckelmann #include "bridge_loop_avoidance.h" 4694433355SSven Eckelmann #include "distributed-arp-table.h" 4794433355SSven Eckelmann #include "gateway_client.h" 4894433355SSven Eckelmann #include "hard-interface.h" 4994433355SSven Eckelmann #include "multicast.h" 5094433355SSven Eckelmann #include "network-coding.h" 5194433355SSven Eckelmann #include "send.h" 5294433355SSven Eckelmann #include "translation-table.h" 5394433355SSven Eckelmann 5494433355SSven Eckelmann /** 5594433355SSven Eckelmann * batadv_skb_head_push() - Increase header size and move (push) head pointer 5694433355SSven Eckelmann * @skb: packet buffer which should be modified 5794433355SSven Eckelmann * @len: number of bytes to add 5894433355SSven Eckelmann * 5994433355SSven Eckelmann * Return: 0 on success or negative error number in case of failure 6094433355SSven Eckelmann */ 6194433355SSven Eckelmann int batadv_skb_head_push(struct sk_buff *skb, unsigned int len) 6294433355SSven Eckelmann { 6394433355SSven Eckelmann int result; 6494433355SSven Eckelmann 6594433355SSven Eckelmann /* TODO: We must check if we can release all references to non-payload 6694433355SSven Eckelmann * data using __skb_header_release in our skbs to allow skb_cow_header 6794433355SSven Eckelmann * to work optimally. This means that those skbs are not allowed to read 6894433355SSven Eckelmann * or write any data which is before the current position of skb->data 6994433355SSven Eckelmann * after that call and thus allow other skbs with the same data buffer 7094433355SSven Eckelmann * to write freely in that area. 7194433355SSven Eckelmann */ 7294433355SSven Eckelmann result = skb_cow_head(skb, len); 7394433355SSven Eckelmann if (result < 0) 7494433355SSven Eckelmann return result; 7594433355SSven Eckelmann 7694433355SSven Eckelmann skb_push(skb, len); 7794433355SSven Eckelmann return 0; 7894433355SSven Eckelmann } 7994433355SSven Eckelmann 8094433355SSven Eckelmann static int batadv_interface_open(struct net_device *dev) 8194433355SSven Eckelmann { 8294433355SSven Eckelmann netif_start_queue(dev); 8394433355SSven Eckelmann return 0; 8494433355SSven Eckelmann } 8594433355SSven Eckelmann 8694433355SSven Eckelmann static int batadv_interface_release(struct net_device *dev) 8794433355SSven Eckelmann { 8894433355SSven Eckelmann netif_stop_queue(dev); 8994433355SSven Eckelmann return 0; 9094433355SSven Eckelmann } 9194433355SSven Eckelmann 9294433355SSven Eckelmann /** 9394433355SSven Eckelmann * batadv_sum_counter() - Sum the cpu-local counters for index 'idx' 9494433355SSven Eckelmann * @bat_priv: the bat priv with all the mesh interface information 9594433355SSven Eckelmann * @idx: index of counter to sum up 9694433355SSven Eckelmann * 9794433355SSven Eckelmann * Return: sum of all cpu-local counters 9894433355SSven Eckelmann */ 9994433355SSven Eckelmann static u64 batadv_sum_counter(struct batadv_priv *bat_priv, size_t idx) 10094433355SSven Eckelmann { 10194433355SSven Eckelmann u64 *counters, sum = 0; 10294433355SSven Eckelmann int cpu; 10394433355SSven Eckelmann 10494433355SSven Eckelmann for_each_possible_cpu(cpu) { 10594433355SSven Eckelmann counters = per_cpu_ptr(bat_priv->bat_counters, cpu); 10694433355SSven Eckelmann sum += counters[idx]; 10794433355SSven Eckelmann } 10894433355SSven Eckelmann 10994433355SSven Eckelmann return sum; 11094433355SSven Eckelmann } 11194433355SSven Eckelmann 11294433355SSven Eckelmann static struct net_device_stats *batadv_interface_stats(struct net_device *dev) 11394433355SSven Eckelmann { 11494433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 11594433355SSven Eckelmann struct net_device_stats *stats = &dev->stats; 11694433355SSven Eckelmann 11794433355SSven Eckelmann stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX); 11894433355SSven Eckelmann stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES); 11994433355SSven Eckelmann stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED); 12094433355SSven Eckelmann stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX); 12194433355SSven Eckelmann stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES); 12294433355SSven Eckelmann return stats; 12394433355SSven Eckelmann } 12494433355SSven Eckelmann 12594433355SSven Eckelmann static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) 12694433355SSven Eckelmann { 12794433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 12894433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 12994433355SSven Eckelmann struct sockaddr *addr = p; 13094433355SSven Eckelmann u8 old_addr[ETH_ALEN]; 13194433355SSven Eckelmann 13294433355SSven Eckelmann if (!is_valid_ether_addr(addr->sa_data)) 13394433355SSven Eckelmann return -EADDRNOTAVAIL; 13494433355SSven Eckelmann 13594433355SSven Eckelmann ether_addr_copy(old_addr, dev->dev_addr); 13694433355SSven Eckelmann eth_hw_addr_set(dev, addr->sa_data); 13794433355SSven Eckelmann 13894433355SSven Eckelmann /* only modify transtable if it has been initialized before */ 13994433355SSven Eckelmann if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 14094433355SSven Eckelmann return 0; 14194433355SSven Eckelmann 14294433355SSven Eckelmann rcu_read_lock(); 14394433355SSven Eckelmann hlist_for_each_entry_rcu(vlan, &bat_priv->meshif_vlan_list, list) { 14494433355SSven Eckelmann batadv_tt_local_remove(bat_priv, old_addr, vlan->vid, 14594433355SSven Eckelmann "mac address changed", false); 14694433355SSven Eckelmann batadv_tt_local_add(dev, addr->sa_data, vlan->vid, 14794433355SSven Eckelmann BATADV_NULL_IFINDEX, BATADV_NO_MARK); 14894433355SSven Eckelmann } 14994433355SSven Eckelmann rcu_read_unlock(); 15094433355SSven Eckelmann 15194433355SSven Eckelmann return 0; 15294433355SSven Eckelmann } 15394433355SSven Eckelmann 15494433355SSven Eckelmann static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu) 15594433355SSven Eckelmann { 15694433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 15794433355SSven Eckelmann 15894433355SSven Eckelmann /* check ranges */ 15994433355SSven Eckelmann if (new_mtu < ETH_MIN_MTU || new_mtu > batadv_hardif_min_mtu(dev)) 16094433355SSven Eckelmann return -EINVAL; 16194433355SSven Eckelmann 16294433355SSven Eckelmann WRITE_ONCE(dev->mtu, new_mtu); 16394433355SSven Eckelmann bat_priv->mtu_set_by_user = new_mtu; 16494433355SSven Eckelmann 16594433355SSven Eckelmann return 0; 16694433355SSven Eckelmann } 16794433355SSven Eckelmann 16894433355SSven Eckelmann /** 16994433355SSven Eckelmann * batadv_interface_set_rx_mode() - set the rx mode of a device 17094433355SSven Eckelmann * @dev: registered network device to modify 17194433355SSven Eckelmann * 17294433355SSven Eckelmann * We do not actually need to set any rx filters for the virtual batman 17394433355SSven Eckelmann * mesh interface. However a dummy handler enables a user to set static 17494433355SSven Eckelmann * multicast listeners for instance. 17594433355SSven Eckelmann */ 17694433355SSven Eckelmann static void batadv_interface_set_rx_mode(struct net_device *dev) 17794433355SSven Eckelmann { 17894433355SSven Eckelmann } 17994433355SSven Eckelmann 18094433355SSven Eckelmann static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, 18194433355SSven Eckelmann struct net_device *mesh_iface) 18294433355SSven Eckelmann { 18394433355SSven Eckelmann struct ethhdr *ethhdr; 18494433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(mesh_iface); 18594433355SSven Eckelmann struct batadv_hard_iface *primary_if = NULL; 18694433355SSven Eckelmann struct batadv_bcast_packet *bcast_packet; 18794433355SSven Eckelmann static const u8 stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00, 18894433355SSven Eckelmann 0x00, 0x00}; 18994433355SSven Eckelmann static const u8 ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00, 19094433355SSven Eckelmann 0x00, 0x00}; 19194433355SSven Eckelmann enum batadv_dhcp_recipient dhcp_rcp = BATADV_DHCP_NO; 19294433355SSven Eckelmann u8 *dst_hint = NULL, chaddr[ETH_ALEN]; 19394433355SSven Eckelmann struct vlan_ethhdr *vhdr; 19494433355SSven Eckelmann unsigned int header_len = 0; 19594433355SSven Eckelmann int data_len = skb->len, ret; 19694433355SSven Eckelmann unsigned long brd_delay = 0; 19794433355SSven Eckelmann bool do_bcast = false, client_added; 19894433355SSven Eckelmann unsigned short vid; 19994433355SSven Eckelmann u32 seqno; 20094433355SSven Eckelmann int gw_mode; 20194433355SSven Eckelmann enum batadv_forw_mode forw_mode = BATADV_FORW_BCAST; 20294433355SSven Eckelmann int mcast_is_routable = 0; 20394433355SSven Eckelmann int network_offset = ETH_HLEN; 20494433355SSven Eckelmann __be16 proto; 20594433355SSven Eckelmann 20694433355SSven Eckelmann if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) 20794433355SSven Eckelmann goto dropped; 20894433355SSven Eckelmann 20994433355SSven Eckelmann /* reset control block to avoid left overs from previous users */ 21094433355SSven Eckelmann memset(skb->cb, 0, sizeof(struct batadv_skb_cb)); 21194433355SSven Eckelmann 21294433355SSven Eckelmann netif_trans_update(mesh_iface); 21394433355SSven Eckelmann vid = batadv_get_vid(skb, 0); 21494433355SSven Eckelmann 21594433355SSven Eckelmann skb_reset_mac_header(skb); 21694433355SSven Eckelmann ethhdr = eth_hdr(skb); 21794433355SSven Eckelmann 21894433355SSven Eckelmann proto = ethhdr->h_proto; 21994433355SSven Eckelmann 22094433355SSven Eckelmann switch (ntohs(proto)) { 22194433355SSven Eckelmann case ETH_P_8021Q: 22294433355SSven Eckelmann if (!pskb_may_pull(skb, sizeof(*vhdr))) 22394433355SSven Eckelmann goto dropped; 22494433355SSven Eckelmann vhdr = vlan_eth_hdr(skb); 22594433355SSven Eckelmann proto = vhdr->h_vlan_encapsulated_proto; 22694433355SSven Eckelmann 22794433355SSven Eckelmann /* drop batman-in-batman packets to prevent loops */ 22894433355SSven Eckelmann if (proto != htons(ETH_P_BATMAN)) { 22994433355SSven Eckelmann network_offset += VLAN_HLEN; 23094433355SSven Eckelmann break; 23194433355SSven Eckelmann } 23294433355SSven Eckelmann 23394433355SSven Eckelmann fallthrough; 23494433355SSven Eckelmann case ETH_P_BATMAN: 23594433355SSven Eckelmann goto dropped; 23694433355SSven Eckelmann } 23794433355SSven Eckelmann 23894433355SSven Eckelmann skb_set_network_header(skb, network_offset); 23994433355SSven Eckelmann 24094433355SSven Eckelmann if (batadv_bla_tx(bat_priv, skb, vid)) 24194433355SSven Eckelmann goto dropped; 24294433355SSven Eckelmann 24394433355SSven Eckelmann /* skb->data might have been reallocated by batadv_bla_tx() */ 24494433355SSven Eckelmann ethhdr = eth_hdr(skb); 24594433355SSven Eckelmann 24694433355SSven Eckelmann /* Register the client MAC in the transtable */ 24794433355SSven Eckelmann if (!is_multicast_ether_addr(ethhdr->h_source) && 24894433355SSven Eckelmann !batadv_bla_is_loopdetect_mac(ethhdr->h_source)) { 24994433355SSven Eckelmann client_added = batadv_tt_local_add(mesh_iface, ethhdr->h_source, 25094433355SSven Eckelmann vid, skb->skb_iif, 25194433355SSven Eckelmann skb->mark); 25294433355SSven Eckelmann if (!client_added) 25394433355SSven Eckelmann goto dropped; 25494433355SSven Eckelmann } 25594433355SSven Eckelmann 25694433355SSven Eckelmann /* Snoop address candidates from DHCPACKs for early DAT filling */ 25794433355SSven Eckelmann batadv_dat_snoop_outgoing_dhcp_ack(bat_priv, skb, proto, vid); 25894433355SSven Eckelmann 25994433355SSven Eckelmann /* don't accept stp packets. STP does not help in meshes. 26094433355SSven Eckelmann * better use the bridge loop avoidance ... 26194433355SSven Eckelmann * 26294433355SSven Eckelmann * The same goes for ECTP sent at least by some Cisco Switches, 26394433355SSven Eckelmann * it might confuse the mesh when used with bridge loop avoidance. 26494433355SSven Eckelmann */ 26594433355SSven Eckelmann if (batadv_compare_eth(ethhdr->h_dest, stp_addr)) 26694433355SSven Eckelmann goto dropped; 26794433355SSven Eckelmann 26894433355SSven Eckelmann if (batadv_compare_eth(ethhdr->h_dest, ectp_addr)) 26994433355SSven Eckelmann goto dropped; 27094433355SSven Eckelmann 27194433355SSven Eckelmann gw_mode = atomic_read(&bat_priv->gw.mode); 27294433355SSven Eckelmann if (is_multicast_ether_addr(ethhdr->h_dest)) { 27394433355SSven Eckelmann /* if gw mode is off, broadcast every packet */ 27494433355SSven Eckelmann if (gw_mode == BATADV_GW_MODE_OFF) { 27594433355SSven Eckelmann do_bcast = true; 27694433355SSven Eckelmann goto send; 27794433355SSven Eckelmann } 27894433355SSven Eckelmann 27994433355SSven Eckelmann dhcp_rcp = batadv_gw_dhcp_recipient_get(skb, &header_len, 28094433355SSven Eckelmann chaddr); 28194433355SSven Eckelmann /* skb->data may have been modified by 28294433355SSven Eckelmann * batadv_gw_dhcp_recipient_get() 28394433355SSven Eckelmann */ 28494433355SSven Eckelmann ethhdr = eth_hdr(skb); 28594433355SSven Eckelmann /* if gw_mode is on, broadcast any non-DHCP message. 28694433355SSven Eckelmann * All the DHCP packets are going to be sent as unicast 28794433355SSven Eckelmann */ 28894433355SSven Eckelmann if (dhcp_rcp == BATADV_DHCP_NO) { 28994433355SSven Eckelmann do_bcast = true; 29094433355SSven Eckelmann goto send; 29194433355SSven Eckelmann } 29294433355SSven Eckelmann 29394433355SSven Eckelmann if (dhcp_rcp == BATADV_DHCP_TO_CLIENT) 29494433355SSven Eckelmann dst_hint = chaddr; 29594433355SSven Eckelmann else if ((gw_mode == BATADV_GW_MODE_SERVER) && 29694433355SSven Eckelmann (dhcp_rcp == BATADV_DHCP_TO_SERVER)) 29794433355SSven Eckelmann /* gateways should not forward any DHCP message if 29894433355SSven Eckelmann * directed to a DHCP server 29994433355SSven Eckelmann */ 30094433355SSven Eckelmann goto dropped; 30194433355SSven Eckelmann 30294433355SSven Eckelmann send: 30394433355SSven Eckelmann if (do_bcast && !is_broadcast_ether_addr(ethhdr->h_dest)) { 30494433355SSven Eckelmann forw_mode = batadv_mcast_forw_mode(bat_priv, skb, vid, 30594433355SSven Eckelmann &mcast_is_routable); 30694433355SSven Eckelmann switch (forw_mode) { 30794433355SSven Eckelmann case BATADV_FORW_BCAST: 30894433355SSven Eckelmann break; 30994433355SSven Eckelmann case BATADV_FORW_UCASTS: 31094433355SSven Eckelmann case BATADV_FORW_MCAST: 31194433355SSven Eckelmann do_bcast = false; 31294433355SSven Eckelmann break; 31394433355SSven Eckelmann case BATADV_FORW_NONE: 31494433355SSven Eckelmann fallthrough; 31594433355SSven Eckelmann default: 31694433355SSven Eckelmann goto dropped; 31794433355SSven Eckelmann } 31894433355SSven Eckelmann } 31994433355SSven Eckelmann } 32094433355SSven Eckelmann 32194433355SSven Eckelmann batadv_skb_set_priority(skb, 0); 32294433355SSven Eckelmann 32394433355SSven Eckelmann /* ethernet packet should be broadcasted */ 32494433355SSven Eckelmann if (do_bcast) { 32594433355SSven Eckelmann primary_if = batadv_primary_if_get_selected(bat_priv); 32694433355SSven Eckelmann if (!primary_if) 32794433355SSven Eckelmann goto dropped; 32894433355SSven Eckelmann 32994433355SSven Eckelmann /* in case of ARP request, we do not immediately broadcasti the 33094433355SSven Eckelmann * packet, instead we first wait for DAT to try to retrieve the 33194433355SSven Eckelmann * correct ARP entry 33294433355SSven Eckelmann */ 33394433355SSven Eckelmann if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb)) 33494433355SSven Eckelmann brd_delay = msecs_to_jiffies(ARP_REQ_DELAY); 33594433355SSven Eckelmann 33694433355SSven Eckelmann if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0) 33794433355SSven Eckelmann goto dropped; 33894433355SSven Eckelmann 33994433355SSven Eckelmann bcast_packet = (struct batadv_bcast_packet *)skb->data; 34094433355SSven Eckelmann bcast_packet->version = BATADV_COMPAT_VERSION; 34194433355SSven Eckelmann bcast_packet->ttl = BATADV_TTL - 1; 34294433355SSven Eckelmann 34394433355SSven Eckelmann /* batman packet type: broadcast */ 34494433355SSven Eckelmann bcast_packet->packet_type = BATADV_BCAST; 34594433355SSven Eckelmann bcast_packet->reserved = 0; 34694433355SSven Eckelmann 34794433355SSven Eckelmann /* hw address of first interface is the orig mac because only 34894433355SSven Eckelmann * this mac is known throughout the mesh 34994433355SSven Eckelmann */ 35094433355SSven Eckelmann ether_addr_copy(bcast_packet->orig, 35194433355SSven Eckelmann primary_if->net_dev->dev_addr); 35294433355SSven Eckelmann 35394433355SSven Eckelmann /* set broadcast sequence number */ 35494433355SSven Eckelmann seqno = atomic_inc_return(&bat_priv->bcast_seqno); 35594433355SSven Eckelmann bcast_packet->seqno = htonl(seqno); 35694433355SSven Eckelmann 35794433355SSven Eckelmann batadv_send_bcast_packet(bat_priv, skb, brd_delay, true); 35894433355SSven Eckelmann /* unicast packet */ 35994433355SSven Eckelmann } else { 36094433355SSven Eckelmann /* DHCP packets going to a server will use the GW feature */ 36194433355SSven Eckelmann if (dhcp_rcp == BATADV_DHCP_TO_SERVER) { 36294433355SSven Eckelmann ret = batadv_gw_out_of_range(bat_priv, skb); 36394433355SSven Eckelmann if (ret) 36494433355SSven Eckelmann goto dropped; 36594433355SSven Eckelmann ret = batadv_send_skb_via_gw(bat_priv, skb, vid); 36694433355SSven Eckelmann } else if (forw_mode == BATADV_FORW_UCASTS) { 36794433355SSven Eckelmann ret = batadv_mcast_forw_send(bat_priv, skb, vid, 36894433355SSven Eckelmann mcast_is_routable); 36994433355SSven Eckelmann } else if (forw_mode == BATADV_FORW_MCAST) { 37094433355SSven Eckelmann ret = batadv_mcast_forw_mcsend(bat_priv, skb); 37194433355SSven Eckelmann } else { 37294433355SSven Eckelmann if (batadv_dat_snoop_outgoing_arp_request(bat_priv, 37394433355SSven Eckelmann skb)) 37494433355SSven Eckelmann goto dropped; 37594433355SSven Eckelmann 37694433355SSven Eckelmann batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb); 37794433355SSven Eckelmann 37894433355SSven Eckelmann ret = batadv_send_skb_via_tt(bat_priv, skb, dst_hint, 37994433355SSven Eckelmann vid); 38094433355SSven Eckelmann } 38194433355SSven Eckelmann if (ret != NET_XMIT_SUCCESS) 38294433355SSven Eckelmann goto dropped_freed; 38394433355SSven Eckelmann } 38494433355SSven Eckelmann 38594433355SSven Eckelmann batadv_inc_counter(bat_priv, BATADV_CNT_TX); 38694433355SSven Eckelmann batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len); 38794433355SSven Eckelmann goto end; 38894433355SSven Eckelmann 38994433355SSven Eckelmann dropped: 39094433355SSven Eckelmann kfree_skb(skb); 39194433355SSven Eckelmann dropped_freed: 39294433355SSven Eckelmann batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED); 39394433355SSven Eckelmann end: 39494433355SSven Eckelmann batadv_hardif_put(primary_if); 39594433355SSven Eckelmann return NETDEV_TX_OK; 39694433355SSven Eckelmann } 39794433355SSven Eckelmann 39894433355SSven Eckelmann /** 39994433355SSven Eckelmann * batadv_interface_rx() - receive ethernet frame on local batman-adv interface 40094433355SSven Eckelmann * @mesh_iface: local interface which will receive the ethernet frame 40194433355SSven Eckelmann * @skb: ethernet frame for @mesh_iface 40294433355SSven Eckelmann * @hdr_size: size of already parsed batman-adv header 40394433355SSven Eckelmann * @orig_node: originator from which the batman-adv packet was sent 40494433355SSven Eckelmann * 40594433355SSven Eckelmann * Sends an ethernet frame to the receive path of the local @mesh_iface. 40694433355SSven Eckelmann * skb->data has still point to the batman-adv header with the size @hdr_size. 40794433355SSven Eckelmann * The caller has to have parsed this header already and made sure that at least 40894433355SSven Eckelmann * @hdr_size bytes are still available for pull in @skb. 40994433355SSven Eckelmann * 41094433355SSven Eckelmann * The packet may still get dropped. This can happen when the encapsulated 41194433355SSven Eckelmann * ethernet frame is invalid or contains again an batman-adv packet. Also 41294433355SSven Eckelmann * unicast packets will be dropped directly when it was sent between two 41394433355SSven Eckelmann * isolated clients. 41494433355SSven Eckelmann */ 41594433355SSven Eckelmann void batadv_interface_rx(struct net_device *mesh_iface, 41694433355SSven Eckelmann struct sk_buff *skb, int hdr_size, 41794433355SSven Eckelmann struct batadv_orig_node *orig_node) 41894433355SSven Eckelmann { 41994433355SSven Eckelmann struct batadv_bcast_packet *batadv_bcast_packet; 42094433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(mesh_iface); 42194433355SSven Eckelmann struct vlan_ethhdr *vhdr; 42294433355SSven Eckelmann struct ethhdr *ethhdr; 42394433355SSven Eckelmann unsigned short vid; 42494433355SSven Eckelmann int packet_type; 42594433355SSven Eckelmann 42694433355SSven Eckelmann batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data; 42794433355SSven Eckelmann packet_type = batadv_bcast_packet->packet_type; 42894433355SSven Eckelmann 42994433355SSven Eckelmann skb_pull_rcsum(skb, hdr_size); 43094433355SSven Eckelmann skb_reset_mac_header(skb); 43194433355SSven Eckelmann 43294433355SSven Eckelmann /* clean the netfilter state now that the batman-adv header has been 43394433355SSven Eckelmann * removed 43494433355SSven Eckelmann */ 43594433355SSven Eckelmann nf_reset_ct(skb); 43694433355SSven Eckelmann 43794433355SSven Eckelmann if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) 43894433355SSven Eckelmann goto dropped; 43994433355SSven Eckelmann 44094433355SSven Eckelmann vid = batadv_get_vid(skb, 0); 44194433355SSven Eckelmann ethhdr = eth_hdr(skb); 44294433355SSven Eckelmann 44394433355SSven Eckelmann switch (ntohs(ethhdr->h_proto)) { 44494433355SSven Eckelmann case ETH_P_8021Q: 44594433355SSven Eckelmann if (!pskb_may_pull(skb, VLAN_ETH_HLEN)) 44694433355SSven Eckelmann goto dropped; 44794433355SSven Eckelmann 44894433355SSven Eckelmann vhdr = skb_vlan_eth_hdr(skb); 44994433355SSven Eckelmann 45094433355SSven Eckelmann /* drop batman-in-batman packets to prevent loops */ 45194433355SSven Eckelmann if (vhdr->h_vlan_encapsulated_proto != htons(ETH_P_BATMAN)) 45294433355SSven Eckelmann break; 45394433355SSven Eckelmann 45494433355SSven Eckelmann fallthrough; 45594433355SSven Eckelmann case ETH_P_BATMAN: 45694433355SSven Eckelmann goto dropped; 45794433355SSven Eckelmann } 45894433355SSven Eckelmann 45994433355SSven Eckelmann /* skb->dev & skb->pkt_type are set here */ 46094433355SSven Eckelmann skb->protocol = eth_type_trans(skb, mesh_iface); 46194433355SSven Eckelmann skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); 46294433355SSven Eckelmann 46394433355SSven Eckelmann batadv_inc_counter(bat_priv, BATADV_CNT_RX); 46494433355SSven Eckelmann batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES, 46594433355SSven Eckelmann skb->len + ETH_HLEN); 46694433355SSven Eckelmann 46794433355SSven Eckelmann /* Let the bridge loop avoidance check the packet. If will 46894433355SSven Eckelmann * not handle it, we can safely push it up. 46994433355SSven Eckelmann */ 47094433355SSven Eckelmann if (batadv_bla_rx(bat_priv, skb, vid, packet_type)) 47194433355SSven Eckelmann goto out; 47294433355SSven Eckelmann 47394433355SSven Eckelmann if (orig_node) 47494433355SSven Eckelmann batadv_tt_add_temporary_global_entry(bat_priv, orig_node, 47594433355SSven Eckelmann ethhdr->h_source, vid); 47694433355SSven Eckelmann 47794433355SSven Eckelmann if (is_multicast_ether_addr(ethhdr->h_dest)) { 47894433355SSven Eckelmann /* set the mark on broadcast packets if AP isolation is ON and 47994433355SSven Eckelmann * the packet is coming from an "isolated" client 48094433355SSven Eckelmann */ 48194433355SSven Eckelmann if (batadv_vlan_ap_isola_get(bat_priv, vid) && 48294433355SSven Eckelmann batadv_tt_global_is_isolated(bat_priv, ethhdr->h_source, 48394433355SSven Eckelmann vid)) { 48494433355SSven Eckelmann /* save bits in skb->mark not covered by the mask and 48594433355SSven Eckelmann * apply the mark on the rest 48694433355SSven Eckelmann */ 48794433355SSven Eckelmann skb->mark &= ~bat_priv->isolation_mark_mask; 48894433355SSven Eckelmann skb->mark |= bat_priv->isolation_mark; 48994433355SSven Eckelmann } 49094433355SSven Eckelmann } else if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, 49194433355SSven Eckelmann ethhdr->h_dest, vid)) { 49294433355SSven Eckelmann goto dropped; 49394433355SSven Eckelmann } 49494433355SSven Eckelmann 49594433355SSven Eckelmann netif_rx(skb); 49694433355SSven Eckelmann goto out; 49794433355SSven Eckelmann 49894433355SSven Eckelmann dropped: 49994433355SSven Eckelmann kfree_skb(skb); 50094433355SSven Eckelmann out: 50194433355SSven Eckelmann return; 50294433355SSven Eckelmann } 50394433355SSven Eckelmann 50494433355SSven Eckelmann /** 50594433355SSven Eckelmann * batadv_meshif_vlan_release() - release vlan from lists and queue for free 50694433355SSven Eckelmann * after rcu grace period 50794433355SSven Eckelmann * @ref: kref pointer of the vlan object 50894433355SSven Eckelmann */ 50994433355SSven Eckelmann void batadv_meshif_vlan_release(struct kref *ref) 51094433355SSven Eckelmann { 51194433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 51294433355SSven Eckelmann 51394433355SSven Eckelmann vlan = container_of(ref, struct batadv_meshif_vlan, refcount); 51494433355SSven Eckelmann 51594433355SSven Eckelmann spin_lock_bh(&vlan->bat_priv->meshif_vlan_list_lock); 51694433355SSven Eckelmann hlist_del_rcu(&vlan->list); 51794433355SSven Eckelmann spin_unlock_bh(&vlan->bat_priv->meshif_vlan_list_lock); 51894433355SSven Eckelmann 51994433355SSven Eckelmann kfree_rcu(vlan, rcu); 52094433355SSven Eckelmann } 52194433355SSven Eckelmann 52294433355SSven Eckelmann /** 52394433355SSven Eckelmann * batadv_meshif_vlan_get() - get the vlan object for a specific vid 52494433355SSven Eckelmann * @bat_priv: the bat priv with all the mesh interface information 52594433355SSven Eckelmann * @vid: the identifier of the vlan object to retrieve 52694433355SSven Eckelmann * 52794433355SSven Eckelmann * Return: the private data of the vlan matching the vid passed as argument or 52894433355SSven Eckelmann * NULL otherwise. The refcounter of the returned object is incremented by 1. 52994433355SSven Eckelmann */ 53094433355SSven Eckelmann struct batadv_meshif_vlan *batadv_meshif_vlan_get(struct batadv_priv *bat_priv, 53194433355SSven Eckelmann unsigned short vid) 53294433355SSven Eckelmann { 53394433355SSven Eckelmann struct batadv_meshif_vlan *vlan_tmp, *vlan = NULL; 53494433355SSven Eckelmann 53594433355SSven Eckelmann rcu_read_lock(); 53694433355SSven Eckelmann hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->meshif_vlan_list, list) { 53794433355SSven Eckelmann if (vlan_tmp->vid != vid) 53894433355SSven Eckelmann continue; 53994433355SSven Eckelmann 54094433355SSven Eckelmann if (!kref_get_unless_zero(&vlan_tmp->refcount)) 54194433355SSven Eckelmann continue; 54294433355SSven Eckelmann 54394433355SSven Eckelmann vlan = vlan_tmp; 54494433355SSven Eckelmann break; 54594433355SSven Eckelmann } 54694433355SSven Eckelmann rcu_read_unlock(); 54794433355SSven Eckelmann 54894433355SSven Eckelmann return vlan; 54994433355SSven Eckelmann } 55094433355SSven Eckelmann 55194433355SSven Eckelmann /** 55294433355SSven Eckelmann * batadv_meshif_create_vlan() - allocate the needed resources for a new vlan 55394433355SSven Eckelmann * @bat_priv: the bat priv with all the mesh interface information 55494433355SSven Eckelmann * @vid: the VLAN identifier 55594433355SSven Eckelmann * 55694433355SSven Eckelmann * Return: 0 on success, a negative error otherwise. 55794433355SSven Eckelmann */ 55894433355SSven Eckelmann int batadv_meshif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) 55994433355SSven Eckelmann { 56094433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 56194433355SSven Eckelmann 56294433355SSven Eckelmann spin_lock_bh(&bat_priv->meshif_vlan_list_lock); 56394433355SSven Eckelmann 56494433355SSven Eckelmann vlan = batadv_meshif_vlan_get(bat_priv, vid); 56594433355SSven Eckelmann if (vlan) { 56694433355SSven Eckelmann batadv_meshif_vlan_put(vlan); 56794433355SSven Eckelmann spin_unlock_bh(&bat_priv->meshif_vlan_list_lock); 56894433355SSven Eckelmann return -EEXIST; 56994433355SSven Eckelmann } 57094433355SSven Eckelmann 57194433355SSven Eckelmann vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); 57294433355SSven Eckelmann if (!vlan) { 57394433355SSven Eckelmann spin_unlock_bh(&bat_priv->meshif_vlan_list_lock); 57494433355SSven Eckelmann return -ENOMEM; 57594433355SSven Eckelmann } 57694433355SSven Eckelmann 57794433355SSven Eckelmann vlan->bat_priv = bat_priv; 57894433355SSven Eckelmann vlan->vid = vid; 57994433355SSven Eckelmann kref_init(&vlan->refcount); 58094433355SSven Eckelmann 58194433355SSven Eckelmann atomic_set(&vlan->ap_isolation, 0); 58294433355SSven Eckelmann 58394433355SSven Eckelmann kref_get(&vlan->refcount); 58494433355SSven Eckelmann hlist_add_head_rcu(&vlan->list, &bat_priv->meshif_vlan_list); 58594433355SSven Eckelmann spin_unlock_bh(&bat_priv->meshif_vlan_list_lock); 58694433355SSven Eckelmann 58794433355SSven Eckelmann /* add a new TT local entry. This one will be marked with the NOPURGE 58894433355SSven Eckelmann * flag 58994433355SSven Eckelmann */ 59094433355SSven Eckelmann batadv_tt_local_add(bat_priv->mesh_iface, 59194433355SSven Eckelmann bat_priv->mesh_iface->dev_addr, vid, 59294433355SSven Eckelmann BATADV_NULL_IFINDEX, BATADV_NO_MARK); 59394433355SSven Eckelmann 59494433355SSven Eckelmann /* don't return reference to new meshif_vlan */ 59594433355SSven Eckelmann batadv_meshif_vlan_put(vlan); 59694433355SSven Eckelmann 59794433355SSven Eckelmann return 0; 59894433355SSven Eckelmann } 59994433355SSven Eckelmann 60094433355SSven Eckelmann /** 60194433355SSven Eckelmann * batadv_meshif_destroy_vlan() - remove and destroy a meshif_vlan object 60294433355SSven Eckelmann * @bat_priv: the bat priv with all the mesh interface information 60394433355SSven Eckelmann * @vlan: the object to remove 60494433355SSven Eckelmann */ 60594433355SSven Eckelmann static void batadv_meshif_destroy_vlan(struct batadv_priv *bat_priv, 60694433355SSven Eckelmann struct batadv_meshif_vlan *vlan) 60794433355SSven Eckelmann { 60894433355SSven Eckelmann /* explicitly remove the associated TT local entry because it is marked 60994433355SSven Eckelmann * with the NOPURGE flag 61094433355SSven Eckelmann */ 61194433355SSven Eckelmann batadv_tt_local_remove(bat_priv, bat_priv->mesh_iface->dev_addr, 61294433355SSven Eckelmann vlan->vid, "vlan interface destroyed", false); 61394433355SSven Eckelmann 61494433355SSven Eckelmann batadv_meshif_vlan_put(vlan); 61594433355SSven Eckelmann } 61694433355SSven Eckelmann 61794433355SSven Eckelmann /** 61894433355SSven Eckelmann * batadv_interface_add_vid() - ndo_add_vid API implementation 61994433355SSven Eckelmann * @dev: the netdev of the mesh interface 62094433355SSven Eckelmann * @proto: protocol of the vlan id 62194433355SSven Eckelmann * @vid: identifier of the new vlan 62294433355SSven Eckelmann * 62394433355SSven Eckelmann * Set up all the internal structures for handling the new vlan on top of the 62494433355SSven Eckelmann * mesh interface 62594433355SSven Eckelmann * 62694433355SSven Eckelmann * Return: 0 on success or a negative error code in case of failure. 62794433355SSven Eckelmann */ 62894433355SSven Eckelmann static int batadv_interface_add_vid(struct net_device *dev, __be16 proto, 62994433355SSven Eckelmann unsigned short vid) 63094433355SSven Eckelmann { 63194433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 63294433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 63394433355SSven Eckelmann 63494433355SSven Eckelmann /* only 802.1Q vlans are supported. 63594433355SSven Eckelmann * batman-adv does not know how to handle other types 63694433355SSven Eckelmann */ 63794433355SSven Eckelmann if (proto != htons(ETH_P_8021Q)) 63894433355SSven Eckelmann return -EINVAL; 63994433355SSven Eckelmann 64094433355SSven Eckelmann /* VID 0 is only used to indicate "priority tag" frames which only 64194433355SSven Eckelmann * contain priority information and no VID. No management structures 64294433355SSven Eckelmann * should be created for this VID and it should be handled like an 64394433355SSven Eckelmann * untagged frame. 64494433355SSven Eckelmann */ 64594433355SSven Eckelmann if (vid == 0) 64694433355SSven Eckelmann return 0; 64794433355SSven Eckelmann 64894433355SSven Eckelmann vid |= BATADV_VLAN_HAS_TAG; 64994433355SSven Eckelmann 65094433355SSven Eckelmann /* if a new vlan is getting created and it already exists, it means that 65194433355SSven Eckelmann * it was not deleted yet. batadv_meshif_vlan_get() increases the 65294433355SSven Eckelmann * refcount in order to revive the object. 65394433355SSven Eckelmann * 65494433355SSven Eckelmann * if it does not exist then create it. 65594433355SSven Eckelmann */ 65694433355SSven Eckelmann vlan = batadv_meshif_vlan_get(bat_priv, vid); 65794433355SSven Eckelmann if (!vlan) 65894433355SSven Eckelmann return batadv_meshif_create_vlan(bat_priv, vid); 65994433355SSven Eckelmann 66094433355SSven Eckelmann /* add a new TT local entry. This one will be marked with the NOPURGE 66194433355SSven Eckelmann * flag. This must be added again, even if the vlan object already 66294433355SSven Eckelmann * exists, because the entry was deleted by kill_vid() 66394433355SSven Eckelmann */ 66494433355SSven Eckelmann batadv_tt_local_add(bat_priv->mesh_iface, 66594433355SSven Eckelmann bat_priv->mesh_iface->dev_addr, vid, 66694433355SSven Eckelmann BATADV_NULL_IFINDEX, BATADV_NO_MARK); 66794433355SSven Eckelmann 66894433355SSven Eckelmann return 0; 66994433355SSven Eckelmann } 67094433355SSven Eckelmann 67194433355SSven Eckelmann /** 67294433355SSven Eckelmann * batadv_interface_kill_vid() - ndo_kill_vid API implementation 67394433355SSven Eckelmann * @dev: the netdev of the mesh interface 67494433355SSven Eckelmann * @proto: protocol of the vlan id 67594433355SSven Eckelmann * @vid: identifier of the deleted vlan 67694433355SSven Eckelmann * 67794433355SSven Eckelmann * Destroy all the internal structures used to handle the vlan identified by vid 67894433355SSven Eckelmann * on top of the mesh interface 67994433355SSven Eckelmann * 68094433355SSven Eckelmann * Return: 0 on success, -EINVAL if the specified prototype is not ETH_P_8021Q 68194433355SSven Eckelmann * or -ENOENT if the specified vlan id wasn't registered. 68294433355SSven Eckelmann */ 68394433355SSven Eckelmann static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, 68494433355SSven Eckelmann unsigned short vid) 68594433355SSven Eckelmann { 68694433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 68794433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 68894433355SSven Eckelmann 68994433355SSven Eckelmann /* only 802.1Q vlans are supported. batman-adv does not know how to 69094433355SSven Eckelmann * handle other types 69194433355SSven Eckelmann */ 69294433355SSven Eckelmann if (proto != htons(ETH_P_8021Q)) 69394433355SSven Eckelmann return -EINVAL; 69494433355SSven Eckelmann 69594433355SSven Eckelmann /* "priority tag" frames are handled like "untagged" frames 69694433355SSven Eckelmann * and no meshif_vlan needs to be destroyed 69794433355SSven Eckelmann */ 69894433355SSven Eckelmann if (vid == 0) 69994433355SSven Eckelmann return 0; 70094433355SSven Eckelmann 70194433355SSven Eckelmann vlan = batadv_meshif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG); 70294433355SSven Eckelmann if (!vlan) 70394433355SSven Eckelmann return -ENOENT; 70494433355SSven Eckelmann 70594433355SSven Eckelmann batadv_meshif_destroy_vlan(bat_priv, vlan); 70694433355SSven Eckelmann 70794433355SSven Eckelmann /* finally free the vlan object */ 70894433355SSven Eckelmann batadv_meshif_vlan_put(vlan); 70994433355SSven Eckelmann 71094433355SSven Eckelmann return 0; 71194433355SSven Eckelmann } 71294433355SSven Eckelmann 71394433355SSven Eckelmann /* batman-adv network devices have devices nesting below it and are a special 71494433355SSven Eckelmann * "super class" of normal network devices; split their locks off into a 71594433355SSven Eckelmann * separate class since they always nest. 71694433355SSven Eckelmann */ 71794433355SSven Eckelmann static struct lock_class_key batadv_netdev_xmit_lock_key; 71894433355SSven Eckelmann static struct lock_class_key batadv_netdev_addr_lock_key; 71994433355SSven Eckelmann 72094433355SSven Eckelmann /** 72194433355SSven Eckelmann * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue 72294433355SSven Eckelmann * @dev: device which owns the tx queue 72394433355SSven Eckelmann * @txq: tx queue to modify 72494433355SSven Eckelmann * @_unused: always NULL 72594433355SSven Eckelmann */ 72694433355SSven Eckelmann static void batadv_set_lockdep_class_one(struct net_device *dev, 72794433355SSven Eckelmann struct netdev_queue *txq, 72894433355SSven Eckelmann void *_unused) 72994433355SSven Eckelmann { 73094433355SSven Eckelmann lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key); 73194433355SSven Eckelmann } 73294433355SSven Eckelmann 73394433355SSven Eckelmann /** 73494433355SSven Eckelmann * batadv_set_lockdep_class() - Set txq and addr_list lockdep class 73594433355SSven Eckelmann * @dev: network device to modify 73694433355SSven Eckelmann */ 73794433355SSven Eckelmann static void batadv_set_lockdep_class(struct net_device *dev) 73894433355SSven Eckelmann { 73994433355SSven Eckelmann lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); 74094433355SSven Eckelmann netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); 74194433355SSven Eckelmann } 74294433355SSven Eckelmann 74394433355SSven Eckelmann /** 74494433355SSven Eckelmann * batadv_meshif_init_late() - late stage initialization of mesh interface 74594433355SSven Eckelmann * @dev: registered network device to modify 74694433355SSven Eckelmann * 74794433355SSven Eckelmann * Return: error code on failures 74894433355SSven Eckelmann */ 74994433355SSven Eckelmann static int batadv_meshif_init_late(struct net_device *dev) 75094433355SSven Eckelmann { 75194433355SSven Eckelmann struct batadv_priv *bat_priv; 75294433355SSven Eckelmann u32 random_seqno; 75394433355SSven Eckelmann int ret; 75494433355SSven Eckelmann size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM; 75594433355SSven Eckelmann 75694433355SSven Eckelmann batadv_set_lockdep_class(dev); 75794433355SSven Eckelmann 75894433355SSven Eckelmann bat_priv = netdev_priv(dev); 75994433355SSven Eckelmann bat_priv->mesh_iface = dev; 76094433355SSven Eckelmann 76194433355SSven Eckelmann /* batadv_interface_stats() needs to be available as soon as 76294433355SSven Eckelmann * register_netdevice() has been called 76394433355SSven Eckelmann */ 76494433355SSven Eckelmann bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(u64)); 76594433355SSven Eckelmann if (!bat_priv->bat_counters) 76694433355SSven Eckelmann return -ENOMEM; 76794433355SSven Eckelmann 76894433355SSven Eckelmann atomic_set(&bat_priv->aggregated_ogms, 1); 76994433355SSven Eckelmann atomic_set(&bat_priv->bonding, 0); 77094433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_BLA 77194433355SSven Eckelmann atomic_set(&bat_priv->bridge_loop_avoidance, 1); 77294433355SSven Eckelmann #endif 77394433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_DAT 77494433355SSven Eckelmann atomic_set(&bat_priv->distributed_arp_table, 1); 77594433355SSven Eckelmann #endif 77694433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_MCAST 77794433355SSven Eckelmann atomic_set(&bat_priv->multicast_mode, 1); 77894433355SSven Eckelmann atomic_set(&bat_priv->multicast_fanout, 16); 77994433355SSven Eckelmann atomic_set(&bat_priv->mcast.num_want_all_unsnoopables, 0); 78094433355SSven Eckelmann atomic_set(&bat_priv->mcast.num_want_all_ipv4, 0); 78194433355SSven Eckelmann atomic_set(&bat_priv->mcast.num_want_all_ipv6, 0); 78294433355SSven Eckelmann atomic_set(&bat_priv->mcast.num_no_mc_ptype_capa, 0); 78394433355SSven Eckelmann #endif 78494433355SSven Eckelmann atomic_set(&bat_priv->gw.mode, BATADV_GW_MODE_OFF); 78594433355SSven Eckelmann atomic_set(&bat_priv->gw.bandwidth_down, 100); 78694433355SSven Eckelmann atomic_set(&bat_priv->gw.bandwidth_up, 20); 78794433355SSven Eckelmann atomic_set(&bat_priv->orig_interval, 1000); 78894433355SSven Eckelmann atomic_set(&bat_priv->hop_penalty, 30); 78994433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_DEBUG 79094433355SSven Eckelmann atomic_set(&bat_priv->log_level, 0); 79194433355SSven Eckelmann #endif 79294433355SSven Eckelmann atomic_set(&bat_priv->fragmentation, 1); 79394433355SSven Eckelmann atomic_set(&bat_priv->packet_size_max, BATADV_MAX_MTU); 79494433355SSven Eckelmann atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); 79594433355SSven Eckelmann atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); 79694433355SSven Eckelmann 79794433355SSven Eckelmann atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); 79894433355SSven Eckelmann atomic_set(&bat_priv->bcast_seqno, 1); 79994433355SSven Eckelmann atomic_set(&bat_priv->tt.vn, 0); 80094433355SSven Eckelmann atomic_set(&bat_priv->tt.ogm_append_cnt, 0); 80194433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_BLA 80294433355SSven Eckelmann atomic_set(&bat_priv->bla.num_requests, 0); 80394433355SSven Eckelmann #endif 80494433355SSven Eckelmann atomic_set(&bat_priv->tp_num, 0); 80594433355SSven Eckelmann 80694433355SSven Eckelmann WRITE_ONCE(bat_priv->tt.local_changes, 0); 80794433355SSven Eckelmann bat_priv->tt.last_changeset = NULL; 80894433355SSven Eckelmann bat_priv->tt.last_changeset_len = 0; 80994433355SSven Eckelmann bat_priv->isolation_mark = 0; 81094433355SSven Eckelmann bat_priv->isolation_mark_mask = 0; 81194433355SSven Eckelmann 81294433355SSven Eckelmann /* randomize initial seqno to avoid collision */ 81394433355SSven Eckelmann get_random_bytes(&random_seqno, sizeof(random_seqno)); 81494433355SSven Eckelmann atomic_set(&bat_priv->frag_seqno, random_seqno); 81594433355SSven Eckelmann 81694433355SSven Eckelmann bat_priv->primary_if = NULL; 81794433355SSven Eckelmann 81894433355SSven Eckelmann batadv_nc_init_bat_priv(bat_priv); 81994433355SSven Eckelmann 82094433355SSven Eckelmann if (!bat_priv->algo_ops) { 82194433355SSven Eckelmann ret = batadv_algo_select(bat_priv, batadv_routing_algo); 82294433355SSven Eckelmann if (ret < 0) 82394433355SSven Eckelmann goto free_bat_counters; 82494433355SSven Eckelmann } 82594433355SSven Eckelmann 82694433355SSven Eckelmann ret = batadv_mesh_init(dev); 82794433355SSven Eckelmann if (ret < 0) 82894433355SSven Eckelmann goto free_bat_counters; 82994433355SSven Eckelmann 83094433355SSven Eckelmann return 0; 83194433355SSven Eckelmann 83294433355SSven Eckelmann free_bat_counters: 83394433355SSven Eckelmann free_percpu(bat_priv->bat_counters); 83494433355SSven Eckelmann bat_priv->bat_counters = NULL; 83594433355SSven Eckelmann 83694433355SSven Eckelmann return ret; 83794433355SSven Eckelmann } 83894433355SSven Eckelmann 83994433355SSven Eckelmann /** 84094433355SSven Eckelmann * batadv_meshif_slave_add() - Add a slave interface to a batadv_mesh_interface 84194433355SSven Eckelmann * @dev: batadv_mesh_interface used as master interface 84294433355SSven Eckelmann * @slave_dev: net_device which should become the slave interface 84394433355SSven Eckelmann * @extack: extended ACK report struct 84494433355SSven Eckelmann * 84594433355SSven Eckelmann * Return: 0 if successful or error otherwise. 84694433355SSven Eckelmann */ 84794433355SSven Eckelmann static int batadv_meshif_slave_add(struct net_device *dev, 84894433355SSven Eckelmann struct net_device *slave_dev, 84994433355SSven Eckelmann struct netlink_ext_ack *extack) 85094433355SSven Eckelmann { 85194433355SSven Eckelmann struct batadv_hard_iface *hard_iface; 85294433355SSven Eckelmann int ret = -EINVAL; 85394433355SSven Eckelmann 85494433355SSven Eckelmann hard_iface = batadv_hardif_get_by_netdev(slave_dev); 85594433355SSven Eckelmann if (!hard_iface || hard_iface->mesh_iface) 85694433355SSven Eckelmann goto out; 85794433355SSven Eckelmann 85894433355SSven Eckelmann ret = batadv_hardif_enable_interface(hard_iface, dev); 85994433355SSven Eckelmann 86094433355SSven Eckelmann out: 86194433355SSven Eckelmann batadv_hardif_put(hard_iface); 86294433355SSven Eckelmann return ret; 86394433355SSven Eckelmann } 86494433355SSven Eckelmann 86594433355SSven Eckelmann /** 86694433355SSven Eckelmann * batadv_meshif_slave_del() - Delete a slave iface from a batadv_mesh_interface 86794433355SSven Eckelmann * @dev: batadv_mesh_interface used as master interface 86894433355SSven Eckelmann * @slave_dev: net_device which should be removed from the master interface 86994433355SSven Eckelmann * 87094433355SSven Eckelmann * Return: 0 if successful or error otherwise. 87194433355SSven Eckelmann */ 87294433355SSven Eckelmann static int batadv_meshif_slave_del(struct net_device *dev, 87394433355SSven Eckelmann struct net_device *slave_dev) 87494433355SSven Eckelmann { 87594433355SSven Eckelmann struct batadv_hard_iface *hard_iface; 87694433355SSven Eckelmann int ret = -EINVAL; 87794433355SSven Eckelmann 87894433355SSven Eckelmann hard_iface = batadv_hardif_get_by_netdev(slave_dev); 87994433355SSven Eckelmann 88094433355SSven Eckelmann if (!hard_iface || hard_iface->mesh_iface != dev) 88194433355SSven Eckelmann goto out; 88294433355SSven Eckelmann 88394433355SSven Eckelmann batadv_hardif_disable_interface(hard_iface); 88494433355SSven Eckelmann ret = 0; 88594433355SSven Eckelmann 88694433355SSven Eckelmann out: 88794433355SSven Eckelmann batadv_hardif_put(hard_iface); 88894433355SSven Eckelmann return ret; 88994433355SSven Eckelmann } 89094433355SSven Eckelmann 89194433355SSven Eckelmann static const struct net_device_ops batadv_netdev_ops = { 89294433355SSven Eckelmann .ndo_init = batadv_meshif_init_late, 89394433355SSven Eckelmann .ndo_open = batadv_interface_open, 89494433355SSven Eckelmann .ndo_stop = batadv_interface_release, 89594433355SSven Eckelmann .ndo_get_stats = batadv_interface_stats, 89694433355SSven Eckelmann .ndo_vlan_rx_add_vid = batadv_interface_add_vid, 89794433355SSven Eckelmann .ndo_vlan_rx_kill_vid = batadv_interface_kill_vid, 89894433355SSven Eckelmann .ndo_set_mac_address = batadv_interface_set_mac_addr, 89994433355SSven Eckelmann .ndo_change_mtu = batadv_interface_change_mtu, 90094433355SSven Eckelmann .ndo_set_rx_mode = batadv_interface_set_rx_mode, 90194433355SSven Eckelmann .ndo_start_xmit = batadv_interface_tx, 90294433355SSven Eckelmann .ndo_validate_addr = eth_validate_addr, 90394433355SSven Eckelmann .ndo_add_slave = batadv_meshif_slave_add, 90494433355SSven Eckelmann .ndo_del_slave = batadv_meshif_slave_del, 90594433355SSven Eckelmann }; 90694433355SSven Eckelmann 90794433355SSven Eckelmann static void batadv_get_drvinfo(struct net_device *dev, 90894433355SSven Eckelmann struct ethtool_drvinfo *info) 90994433355SSven Eckelmann { 91094433355SSven Eckelmann strscpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver)); 91194433355SSven Eckelmann strscpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version)); 91294433355SSven Eckelmann strscpy(info->fw_version, "N/A", sizeof(info->fw_version)); 91394433355SSven Eckelmann strscpy(info->bus_info, "batman", sizeof(info->bus_info)); 91494433355SSven Eckelmann } 91594433355SSven Eckelmann 91694433355SSven Eckelmann /* Inspired by drivers/net/ethernet/dlink/sundance.c:1702 91794433355SSven Eckelmann * Declare each description string in struct.name[] to get fixed sized buffer 91894433355SSven Eckelmann * and compile time checking for strings longer than ETH_GSTRING_LEN. 91994433355SSven Eckelmann */ 92094433355SSven Eckelmann static const struct { 92194433355SSven Eckelmann const char name[ETH_GSTRING_LEN]; 92294433355SSven Eckelmann } batadv_counters_strings[] = { 92394433355SSven Eckelmann { "tx" }, 92494433355SSven Eckelmann { "tx_bytes" }, 92594433355SSven Eckelmann { "tx_dropped" }, 92694433355SSven Eckelmann { "rx" }, 92794433355SSven Eckelmann { "rx_bytes" }, 92894433355SSven Eckelmann { "forward" }, 92994433355SSven Eckelmann { "forward_bytes" }, 93094433355SSven Eckelmann { "mgmt_tx" }, 93194433355SSven Eckelmann { "mgmt_tx_bytes" }, 93294433355SSven Eckelmann { "mgmt_rx" }, 93394433355SSven Eckelmann { "mgmt_rx_bytes" }, 93494433355SSven Eckelmann { "frag_tx" }, 93594433355SSven Eckelmann { "frag_tx_bytes" }, 93694433355SSven Eckelmann { "frag_rx" }, 93794433355SSven Eckelmann { "frag_rx_bytes" }, 93894433355SSven Eckelmann { "frag_fwd" }, 93994433355SSven Eckelmann { "frag_fwd_bytes" }, 94094433355SSven Eckelmann { "tt_request_tx" }, 94194433355SSven Eckelmann { "tt_request_rx" }, 94294433355SSven Eckelmann { "tt_response_tx" }, 94394433355SSven Eckelmann { "tt_response_rx" }, 94494433355SSven Eckelmann { "tt_roam_adv_tx" }, 94594433355SSven Eckelmann { "tt_roam_adv_rx" }, 94694433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_MCAST 94794433355SSven Eckelmann { "mcast_tx" }, 94894433355SSven Eckelmann { "mcast_tx_bytes" }, 94994433355SSven Eckelmann { "mcast_tx_local" }, 95094433355SSven Eckelmann { "mcast_tx_local_bytes" }, 95194433355SSven Eckelmann { "mcast_rx" }, 95294433355SSven Eckelmann { "mcast_rx_bytes" }, 95394433355SSven Eckelmann { "mcast_rx_local" }, 95494433355SSven Eckelmann { "mcast_rx_local_bytes" }, 95594433355SSven Eckelmann { "mcast_fwd" }, 95694433355SSven Eckelmann { "mcast_fwd_bytes" }, 95794433355SSven Eckelmann #endif 95894433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_DAT 95994433355SSven Eckelmann { "dat_get_tx" }, 96094433355SSven Eckelmann { "dat_get_rx" }, 96194433355SSven Eckelmann { "dat_put_tx" }, 96294433355SSven Eckelmann { "dat_put_rx" }, 96394433355SSven Eckelmann { "dat_cached_reply_tx" }, 96494433355SSven Eckelmann #endif 96594433355SSven Eckelmann #ifdef CONFIG_BATMAN_ADV_NC 96694433355SSven Eckelmann { "nc_code" }, 96794433355SSven Eckelmann { "nc_code_bytes" }, 96894433355SSven Eckelmann { "nc_recode" }, 96994433355SSven Eckelmann { "nc_recode_bytes" }, 97094433355SSven Eckelmann { "nc_buffer" }, 97194433355SSven Eckelmann { "nc_decode" }, 97294433355SSven Eckelmann { "nc_decode_bytes" }, 97394433355SSven Eckelmann { "nc_decode_failed" }, 97494433355SSven Eckelmann { "nc_sniffed" }, 97594433355SSven Eckelmann #endif 97694433355SSven Eckelmann }; 97794433355SSven Eckelmann 97894433355SSven Eckelmann static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data) 97994433355SSven Eckelmann { 98094433355SSven Eckelmann if (stringset == ETH_SS_STATS) 98194433355SSven Eckelmann memcpy(data, batadv_counters_strings, 98294433355SSven Eckelmann sizeof(batadv_counters_strings)); 98394433355SSven Eckelmann } 98494433355SSven Eckelmann 98594433355SSven Eckelmann static void batadv_get_ethtool_stats(struct net_device *dev, 98694433355SSven Eckelmann struct ethtool_stats *stats, u64 *data) 98794433355SSven Eckelmann { 98894433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 98994433355SSven Eckelmann int i; 99094433355SSven Eckelmann 99194433355SSven Eckelmann for (i = 0; i < BATADV_CNT_NUM; i++) 99294433355SSven Eckelmann data[i] = batadv_sum_counter(bat_priv, i); 99394433355SSven Eckelmann } 99494433355SSven Eckelmann 99594433355SSven Eckelmann static int batadv_get_sset_count(struct net_device *dev, int stringset) 99694433355SSven Eckelmann { 99794433355SSven Eckelmann if (stringset == ETH_SS_STATS) 99894433355SSven Eckelmann return BATADV_CNT_NUM; 99994433355SSven Eckelmann 100094433355SSven Eckelmann return -EOPNOTSUPP; 100194433355SSven Eckelmann } 100294433355SSven Eckelmann 100394433355SSven Eckelmann static const struct ethtool_ops batadv_ethtool_ops = { 100494433355SSven Eckelmann .get_drvinfo = batadv_get_drvinfo, 100594433355SSven Eckelmann .get_link = ethtool_op_get_link, 100694433355SSven Eckelmann .get_strings = batadv_get_strings, 100794433355SSven Eckelmann .get_ethtool_stats = batadv_get_ethtool_stats, 100894433355SSven Eckelmann .get_sset_count = batadv_get_sset_count, 100994433355SSven Eckelmann }; 101094433355SSven Eckelmann 101194433355SSven Eckelmann /** 101294433355SSven Eckelmann * batadv_meshif_free() - Deconstructor of batadv_mesh_interface 101394433355SSven Eckelmann * @dev: Device to cleanup and remove 101494433355SSven Eckelmann */ 101594433355SSven Eckelmann static void batadv_meshif_free(struct net_device *dev) 101694433355SSven Eckelmann { 101794433355SSven Eckelmann batadv_mesh_free(dev); 101894433355SSven Eckelmann 101994433355SSven Eckelmann /* some scheduled RCU callbacks need the bat_priv struct to accomplish 102094433355SSven Eckelmann * their tasks. Wait for them all to be finished before freeing the 102194433355SSven Eckelmann * netdev and its private data (bat_priv) 102294433355SSven Eckelmann */ 102394433355SSven Eckelmann rcu_barrier(); 102494433355SSven Eckelmann } 102594433355SSven Eckelmann 102694433355SSven Eckelmann /** 102794433355SSven Eckelmann * batadv_meshif_init_early() - early stage initialization of mesh interface 102894433355SSven Eckelmann * @dev: registered network device to modify 102994433355SSven Eckelmann */ 103094433355SSven Eckelmann static void batadv_meshif_init_early(struct net_device *dev) 103194433355SSven Eckelmann { 103294433355SSven Eckelmann ether_setup(dev); 103394433355SSven Eckelmann 103494433355SSven Eckelmann dev->netdev_ops = &batadv_netdev_ops; 103594433355SSven Eckelmann dev->needs_free_netdev = true; 103694433355SSven Eckelmann dev->priv_destructor = batadv_meshif_free; 103794433355SSven Eckelmann dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 103894433355SSven Eckelmann dev->priv_flags |= IFF_NO_QUEUE; 103994433355SSven Eckelmann dev->lltx = true; 1040*ed6bcbe3SPaolo Abeni dev->netns_immutable = true; 104194433355SSven Eckelmann 104294433355SSven Eckelmann /* can't call min_mtu, because the needed variables 104394433355SSven Eckelmann * have not been initialized yet 104494433355SSven Eckelmann */ 104594433355SSven Eckelmann dev->mtu = ETH_DATA_LEN; 104694433355SSven Eckelmann dev->max_mtu = BATADV_MAX_MTU; 104794433355SSven Eckelmann 104894433355SSven Eckelmann /* generate random address */ 104994433355SSven Eckelmann eth_hw_addr_random(dev); 105094433355SSven Eckelmann 105194433355SSven Eckelmann dev->ethtool_ops = &batadv_ethtool_ops; 105294433355SSven Eckelmann } 105394433355SSven Eckelmann 105494433355SSven Eckelmann /** 105594433355SSven Eckelmann * batadv_meshif_validate() - validate configuration of new batadv link 105694433355SSven Eckelmann * @tb: IFLA_INFO_DATA netlink attributes 105794433355SSven Eckelmann * @data: enum batadv_ifla_attrs attributes 105894433355SSven Eckelmann * @extack: extended ACK report struct 105994433355SSven Eckelmann * 106094433355SSven Eckelmann * Return: 0 if successful or error otherwise. 106194433355SSven Eckelmann */ 106294433355SSven Eckelmann static int batadv_meshif_validate(struct nlattr *tb[], struct nlattr *data[], 106394433355SSven Eckelmann struct netlink_ext_ack *extack) 106494433355SSven Eckelmann { 106594433355SSven Eckelmann struct batadv_algo_ops *algo_ops; 106694433355SSven Eckelmann 106794433355SSven Eckelmann if (!data) 106894433355SSven Eckelmann return 0; 106994433355SSven Eckelmann 107094433355SSven Eckelmann if (data[IFLA_BATADV_ALGO_NAME]) { 107194433355SSven Eckelmann algo_ops = batadv_algo_get(nla_data(data[IFLA_BATADV_ALGO_NAME])); 107294433355SSven Eckelmann if (!algo_ops) 107394433355SSven Eckelmann return -EINVAL; 107494433355SSven Eckelmann } 107594433355SSven Eckelmann 107694433355SSven Eckelmann return 0; 107794433355SSven Eckelmann } 107894433355SSven Eckelmann 107994433355SSven Eckelmann /** 108094433355SSven Eckelmann * batadv_meshif_newlink() - pre-initialize and register new batadv link 108194433355SSven Eckelmann * @dev: network device to register 108294433355SSven Eckelmann * @params: rtnl newlink parameters 108394433355SSven Eckelmann * @extack: extended ACK report struct 108494433355SSven Eckelmann * 108594433355SSven Eckelmann * Return: 0 if successful or error otherwise. 108694433355SSven Eckelmann */ 108794433355SSven Eckelmann static int batadv_meshif_newlink(struct net_device *dev, 108894433355SSven Eckelmann struct rtnl_newlink_params *params, 108994433355SSven Eckelmann struct netlink_ext_ack *extack) 109094433355SSven Eckelmann { 109194433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(dev); 109294433355SSven Eckelmann struct nlattr **data = params->data; 109394433355SSven Eckelmann const char *algo_name; 109494433355SSven Eckelmann int err; 109594433355SSven Eckelmann 109694433355SSven Eckelmann if (data && data[IFLA_BATADV_ALGO_NAME]) { 109794433355SSven Eckelmann algo_name = nla_data(data[IFLA_BATADV_ALGO_NAME]); 109894433355SSven Eckelmann err = batadv_algo_select(bat_priv, algo_name); 109994433355SSven Eckelmann if (err) 110094433355SSven Eckelmann return -EINVAL; 110194433355SSven Eckelmann } 110294433355SSven Eckelmann 110394433355SSven Eckelmann return register_netdevice(dev); 110494433355SSven Eckelmann } 110594433355SSven Eckelmann 110694433355SSven Eckelmann /** 110794433355SSven Eckelmann * batadv_meshif_destroy_netlink() - deletion of batadv_mesh_interface via 110894433355SSven Eckelmann * netlink 110994433355SSven Eckelmann * @mesh_iface: the to-be-removed batman-adv interface 111094433355SSven Eckelmann * @head: list pointer 111194433355SSven Eckelmann */ 111294433355SSven Eckelmann static void batadv_meshif_destroy_netlink(struct net_device *mesh_iface, 111394433355SSven Eckelmann struct list_head *head) 111494433355SSven Eckelmann { 111594433355SSven Eckelmann struct batadv_priv *bat_priv = netdev_priv(mesh_iface); 111694433355SSven Eckelmann struct batadv_hard_iface *hard_iface; 111794433355SSven Eckelmann struct batadv_meshif_vlan *vlan; 111894433355SSven Eckelmann 111994433355SSven Eckelmann list_for_each_entry(hard_iface, &batadv_hardif_list, list) { 112094433355SSven Eckelmann if (hard_iface->mesh_iface == mesh_iface) 112194433355SSven Eckelmann batadv_hardif_disable_interface(hard_iface); 112294433355SSven Eckelmann } 112394433355SSven Eckelmann 112494433355SSven Eckelmann /* destroy the "untagged" VLAN */ 112594433355SSven Eckelmann vlan = batadv_meshif_vlan_get(bat_priv, BATADV_NO_FLAGS); 112694433355SSven Eckelmann if (vlan) { 112794433355SSven Eckelmann batadv_meshif_destroy_vlan(bat_priv, vlan); 112894433355SSven Eckelmann batadv_meshif_vlan_put(vlan); 112994433355SSven Eckelmann } 113094433355SSven Eckelmann 113194433355SSven Eckelmann unregister_netdevice_queue(mesh_iface, head); 113294433355SSven Eckelmann } 113394433355SSven Eckelmann 113494433355SSven Eckelmann /** 113594433355SSven Eckelmann * batadv_meshif_is_valid() - Check whether device is a batadv mesh interface 113694433355SSven Eckelmann * @net_dev: device which should be checked 113794433355SSven Eckelmann * 113894433355SSven Eckelmann * Return: true when net_dev is a batman-adv interface, false otherwise 113994433355SSven Eckelmann */ 114094433355SSven Eckelmann bool batadv_meshif_is_valid(const struct net_device *net_dev) 114194433355SSven Eckelmann { 114294433355SSven Eckelmann if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx) 114394433355SSven Eckelmann return true; 114494433355SSven Eckelmann 114594433355SSven Eckelmann return false; 114694433355SSven Eckelmann } 114794433355SSven Eckelmann 114894433355SSven Eckelmann static const struct nla_policy batadv_ifla_policy[IFLA_BATADV_MAX + 1] = { 114994433355SSven Eckelmann [IFLA_BATADV_ALGO_NAME] = { .type = NLA_NUL_STRING }, 115094433355SSven Eckelmann }; 115194433355SSven Eckelmann 115294433355SSven Eckelmann struct rtnl_link_ops batadv_link_ops __read_mostly = { 115394433355SSven Eckelmann .kind = "batadv", 115494433355SSven Eckelmann .priv_size = sizeof(struct batadv_priv), 115594433355SSven Eckelmann .setup = batadv_meshif_init_early, 115694433355SSven Eckelmann .maxtype = IFLA_BATADV_MAX, 115794433355SSven Eckelmann .policy = batadv_ifla_policy, 115894433355SSven Eckelmann .validate = batadv_meshif_validate, 115994433355SSven Eckelmann .newlink = batadv_meshif_newlink, 116094433355SSven Eckelmann .dellink = batadv_meshif_destroy_netlink, 116194433355SSven Eckelmann }; 1162