Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) B.A.T.M.A.N. contributors:
0003  *
0004  * Marek Lindner, Simon Wunderlich
0005  */
0006 
0007 #include "main.h"
0008 
0009 #include <linux/atomic.h>
0010 #include <linux/build_bug.h>
0011 #include <linux/byteorder/generic.h>
0012 #include <linux/container_of.h>
0013 #include <linux/crc32c.h>
0014 #include <linux/device.h>
0015 #include <linux/errno.h>
0016 #include <linux/genetlink.h>
0017 #include <linux/gfp.h>
0018 #include <linux/if_ether.h>
0019 #include <linux/if_vlan.h>
0020 #include <linux/init.h>
0021 #include <linux/ip.h>
0022 #include <linux/ipv6.h>
0023 #include <linux/kernel.h>
0024 #include <linux/kobject.h>
0025 #include <linux/kref.h>
0026 #include <linux/list.h>
0027 #include <linux/minmax.h>
0028 #include <linux/module.h>
0029 #include <linux/netdevice.h>
0030 #include <linux/printk.h>
0031 #include <linux/rculist.h>
0032 #include <linux/rcupdate.h>
0033 #include <linux/skbuff.h>
0034 #include <linux/slab.h>
0035 #include <linux/spinlock.h>
0036 #include <linux/stddef.h>
0037 #include <linux/string.h>
0038 #include <linux/workqueue.h>
0039 #include <net/dsfield.h>
0040 #include <net/rtnetlink.h>
0041 #include <uapi/linux/batadv_packet.h>
0042 #include <uapi/linux/batman_adv.h>
0043 
0044 #include "bat_algo.h"
0045 #include "bat_iv_ogm.h"
0046 #include "bat_v.h"
0047 #include "bridge_loop_avoidance.h"
0048 #include "distributed-arp-table.h"
0049 #include "gateway_client.h"
0050 #include "gateway_common.h"
0051 #include "hard-interface.h"
0052 #include "log.h"
0053 #include "multicast.h"
0054 #include "netlink.h"
0055 #include "network-coding.h"
0056 #include "originator.h"
0057 #include "routing.h"
0058 #include "send.h"
0059 #include "soft-interface.h"
0060 #include "tp_meter.h"
0061 #include "translation-table.h"
0062 
0063 /* List manipulations on hardif_list have to be rtnl_lock()'ed,
0064  * list traversals just rcu-locked
0065  */
0066 struct list_head batadv_hardif_list;
0067 unsigned int batadv_hardif_generation;
0068 static int (*batadv_rx_handler[256])(struct sk_buff *skb,
0069                      struct batadv_hard_iface *recv_if);
0070 
0071 unsigned char batadv_broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
0072 
0073 struct workqueue_struct *batadv_event_workqueue;
0074 
0075 static void batadv_recv_handler_init(void);
0076 
0077 #define BATADV_UEV_TYPE_VAR "BATTYPE="
0078 #define BATADV_UEV_ACTION_VAR   "BATACTION="
0079 #define BATADV_UEV_DATA_VAR "BATDATA="
0080 
0081 static char *batadv_uev_action_str[] = {
0082     "add",
0083     "del",
0084     "change",
0085     "loopdetect",
0086 };
0087 
0088 static char *batadv_uev_type_str[] = {
0089     "gw",
0090     "bla",
0091 };
0092 
0093 static int __init batadv_init(void)
0094 {
0095     int ret;
0096 
0097     ret = batadv_tt_cache_init();
0098     if (ret < 0)
0099         return ret;
0100 
0101     INIT_LIST_HEAD(&batadv_hardif_list);
0102     batadv_algo_init();
0103 
0104     batadv_recv_handler_init();
0105 
0106     batadv_v_init();
0107     batadv_iv_init();
0108     batadv_nc_init();
0109     batadv_tp_meter_init();
0110 
0111     batadv_event_workqueue = create_singlethread_workqueue("bat_events");
0112     if (!batadv_event_workqueue)
0113         goto err_create_wq;
0114 
0115     register_netdevice_notifier(&batadv_hard_if_notifier);
0116     rtnl_link_register(&batadv_link_ops);
0117     batadv_netlink_register();
0118 
0119     pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
0120         BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
0121 
0122     return 0;
0123 
0124 err_create_wq:
0125     batadv_tt_cache_destroy();
0126 
0127     return -ENOMEM;
0128 }
0129 
0130 static void __exit batadv_exit(void)
0131 {
0132     batadv_netlink_unregister();
0133     rtnl_link_unregister(&batadv_link_ops);
0134     unregister_netdevice_notifier(&batadv_hard_if_notifier);
0135 
0136     destroy_workqueue(batadv_event_workqueue);
0137     batadv_event_workqueue = NULL;
0138 
0139     rcu_barrier();
0140 
0141     batadv_tt_cache_destroy();
0142 }
0143 
0144 /**
0145  * batadv_mesh_init() - Initialize soft interface
0146  * @soft_iface: netdev struct of the soft interface
0147  *
0148  * Return: 0 on success or negative error number in case of failure
0149  */
0150 int batadv_mesh_init(struct net_device *soft_iface)
0151 {
0152     struct batadv_priv *bat_priv = netdev_priv(soft_iface);
0153     int ret;
0154 
0155     spin_lock_init(&bat_priv->forw_bat_list_lock);
0156     spin_lock_init(&bat_priv->forw_bcast_list_lock);
0157     spin_lock_init(&bat_priv->tt.changes_list_lock);
0158     spin_lock_init(&bat_priv->tt.req_list_lock);
0159     spin_lock_init(&bat_priv->tt.roam_list_lock);
0160     spin_lock_init(&bat_priv->tt.last_changeset_lock);
0161     spin_lock_init(&bat_priv->tt.commit_lock);
0162     spin_lock_init(&bat_priv->gw.list_lock);
0163 #ifdef CONFIG_BATMAN_ADV_MCAST
0164     spin_lock_init(&bat_priv->mcast.mla_lock);
0165     spin_lock_init(&bat_priv->mcast.want_lists_lock);
0166 #endif
0167     spin_lock_init(&bat_priv->tvlv.container_list_lock);
0168     spin_lock_init(&bat_priv->tvlv.handler_list_lock);
0169     spin_lock_init(&bat_priv->softif_vlan_list_lock);
0170     spin_lock_init(&bat_priv->tp_list_lock);
0171 
0172     INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
0173     INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
0174     INIT_HLIST_HEAD(&bat_priv->gw.gateway_list);
0175 #ifdef CONFIG_BATMAN_ADV_MCAST
0176     INIT_HLIST_HEAD(&bat_priv->mcast.want_all_unsnoopables_list);
0177     INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv4_list);
0178     INIT_HLIST_HEAD(&bat_priv->mcast.want_all_ipv6_list);
0179 #endif
0180     INIT_LIST_HEAD(&bat_priv->tt.changes_list);
0181     INIT_HLIST_HEAD(&bat_priv->tt.req_list);
0182     INIT_LIST_HEAD(&bat_priv->tt.roam_list);
0183 #ifdef CONFIG_BATMAN_ADV_MCAST
0184     INIT_HLIST_HEAD(&bat_priv->mcast.mla_list);
0185 #endif
0186     INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
0187     INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
0188     INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
0189     INIT_HLIST_HEAD(&bat_priv->tp_list);
0190 
0191     bat_priv->gw.generation = 0;
0192 
0193     ret = batadv_originator_init(bat_priv);
0194     if (ret < 0) {
0195         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0196         goto err_orig;
0197     }
0198 
0199     ret = batadv_tt_init(bat_priv);
0200     if (ret < 0) {
0201         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0202         goto err_tt;
0203     }
0204 
0205     ret = batadv_v_mesh_init(bat_priv);
0206     if (ret < 0) {
0207         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0208         goto err_v;
0209     }
0210 
0211     ret = batadv_bla_init(bat_priv);
0212     if (ret < 0) {
0213         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0214         goto err_bla;
0215     }
0216 
0217     ret = batadv_dat_init(bat_priv);
0218     if (ret < 0) {
0219         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0220         goto err_dat;
0221     }
0222 
0223     ret = batadv_nc_mesh_init(bat_priv);
0224     if (ret < 0) {
0225         atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0226         goto err_nc;
0227     }
0228 
0229     batadv_gw_init(bat_priv);
0230     batadv_mcast_init(bat_priv);
0231 
0232     atomic_set(&bat_priv->gw.reselect, 0);
0233     atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE);
0234 
0235     return 0;
0236 
0237 err_nc:
0238     batadv_dat_free(bat_priv);
0239 err_dat:
0240     batadv_bla_free(bat_priv);
0241 err_bla:
0242     batadv_v_mesh_free(bat_priv);
0243 err_v:
0244     batadv_tt_free(bat_priv);
0245 err_tt:
0246     batadv_originator_free(bat_priv);
0247 err_orig:
0248     batadv_purge_outstanding_packets(bat_priv, NULL);
0249     atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
0250 
0251     return ret;
0252 }
0253 
0254 /**
0255  * batadv_mesh_free() - Deinitialize soft interface
0256  * @soft_iface: netdev struct of the soft interface
0257  */
0258 void batadv_mesh_free(struct net_device *soft_iface)
0259 {
0260     struct batadv_priv *bat_priv = netdev_priv(soft_iface);
0261 
0262     atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
0263 
0264     batadv_purge_outstanding_packets(bat_priv, NULL);
0265 
0266     batadv_gw_node_free(bat_priv);
0267 
0268     batadv_v_mesh_free(bat_priv);
0269     batadv_nc_mesh_free(bat_priv);
0270     batadv_dat_free(bat_priv);
0271     batadv_bla_free(bat_priv);
0272 
0273     batadv_mcast_free(bat_priv);
0274 
0275     /* Free the TT and the originator tables only after having terminated
0276      * all the other depending components which may use these structures for
0277      * their purposes.
0278      */
0279     batadv_tt_free(bat_priv);
0280 
0281     /* Since the originator table clean up routine is accessing the TT
0282      * tables as well, it has to be invoked after the TT tables have been
0283      * freed and marked as empty. This ensures that no cleanup RCU callbacks
0284      * accessing the TT data are scheduled for later execution.
0285      */
0286     batadv_originator_free(bat_priv);
0287 
0288     batadv_gw_free(bat_priv);
0289 
0290     free_percpu(bat_priv->bat_counters);
0291     bat_priv->bat_counters = NULL;
0292 
0293     atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
0294 }
0295 
0296 /**
0297  * batadv_is_my_mac() - check if the given mac address belongs to any of the
0298  *  real interfaces in the current mesh
0299  * @bat_priv: the bat priv with all the soft interface information
0300  * @addr: the address to check
0301  *
0302  * Return: 'true' if the mac address was found, false otherwise.
0303  */
0304 bool batadv_is_my_mac(struct batadv_priv *bat_priv, const u8 *addr)
0305 {
0306     const struct batadv_hard_iface *hard_iface;
0307     bool is_my_mac = false;
0308 
0309     rcu_read_lock();
0310     list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
0311         if (hard_iface->if_status != BATADV_IF_ACTIVE)
0312             continue;
0313 
0314         if (hard_iface->soft_iface != bat_priv->soft_iface)
0315             continue;
0316 
0317         if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
0318             is_my_mac = true;
0319             break;
0320         }
0321     }
0322     rcu_read_unlock();
0323     return is_my_mac;
0324 }
0325 
0326 /**
0327  * batadv_max_header_len() - calculate maximum encapsulation overhead for a
0328  *  payload packet
0329  *
0330  * Return: the maximum encapsulation overhead in bytes.
0331  */
0332 int batadv_max_header_len(void)
0333 {
0334     int header_len = 0;
0335 
0336     header_len = max_t(int, header_len,
0337                sizeof(struct batadv_unicast_packet));
0338     header_len = max_t(int, header_len,
0339                sizeof(struct batadv_unicast_4addr_packet));
0340     header_len = max_t(int, header_len,
0341                sizeof(struct batadv_bcast_packet));
0342 
0343 #ifdef CONFIG_BATMAN_ADV_NC
0344     header_len = max_t(int, header_len,
0345                sizeof(struct batadv_coded_packet));
0346 #endif
0347 
0348     return header_len + ETH_HLEN;
0349 }
0350 
0351 /**
0352  * batadv_skb_set_priority() - sets skb priority according to packet content
0353  * @skb: the packet to be sent
0354  * @offset: offset to the packet content
0355  *
0356  * This function sets a value between 256 and 263 (802.1d priority), which
0357  * can be interpreted by the cfg80211 or other drivers.
0358  */
0359 void batadv_skb_set_priority(struct sk_buff *skb, int offset)
0360 {
0361     struct iphdr ip_hdr_tmp, *ip_hdr;
0362     struct ipv6hdr ip6_hdr_tmp, *ip6_hdr;
0363     struct ethhdr ethhdr_tmp, *ethhdr;
0364     struct vlan_ethhdr *vhdr, vhdr_tmp;
0365     u32 prio;
0366 
0367     /* already set, do nothing */
0368     if (skb->priority >= 256 && skb->priority <= 263)
0369         return;
0370 
0371     ethhdr = skb_header_pointer(skb, offset, sizeof(*ethhdr), &ethhdr_tmp);
0372     if (!ethhdr)
0373         return;
0374 
0375     switch (ethhdr->h_proto) {
0376     case htons(ETH_P_8021Q):
0377         vhdr = skb_header_pointer(skb, offset + sizeof(*vhdr),
0378                       sizeof(*vhdr), &vhdr_tmp);
0379         if (!vhdr)
0380             return;
0381         prio = ntohs(vhdr->h_vlan_TCI) & VLAN_PRIO_MASK;
0382         prio = prio >> VLAN_PRIO_SHIFT;
0383         break;
0384     case htons(ETH_P_IP):
0385         ip_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
0386                         sizeof(*ip_hdr), &ip_hdr_tmp);
0387         if (!ip_hdr)
0388             return;
0389         prio = (ipv4_get_dsfield(ip_hdr) & 0xfc) >> 5;
0390         break;
0391     case htons(ETH_P_IPV6):
0392         ip6_hdr = skb_header_pointer(skb, offset + sizeof(*ethhdr),
0393                          sizeof(*ip6_hdr), &ip6_hdr_tmp);
0394         if (!ip6_hdr)
0395             return;
0396         prio = (ipv6_get_dsfield(ip6_hdr) & 0xfc) >> 5;
0397         break;
0398     default:
0399         return;
0400     }
0401 
0402     skb->priority = prio + 256;
0403 }
0404 
0405 static int batadv_recv_unhandled_packet(struct sk_buff *skb,
0406                     struct batadv_hard_iface *recv_if)
0407 {
0408     kfree_skb(skb);
0409 
0410     return NET_RX_DROP;
0411 }
0412 
0413 /* incoming packets with the batman ethertype received on any active hard
0414  * interface
0415  */
0416 
0417 /**
0418  * batadv_batman_skb_recv() - Handle incoming message from an hard interface
0419  * @skb: the received packet
0420  * @dev: the net device that the packet was received on
0421  * @ptype: packet type of incoming packet (ETH_P_BATMAN)
0422  * @orig_dev: the original receive net device (e.g. bonded device)
0423  *
0424  * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure
0425  */
0426 int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
0427                struct packet_type *ptype,
0428                struct net_device *orig_dev)
0429 {
0430     struct batadv_priv *bat_priv;
0431     struct batadv_ogm_packet *batadv_ogm_packet;
0432     struct batadv_hard_iface *hard_iface;
0433     u8 idx;
0434 
0435     hard_iface = container_of(ptype, struct batadv_hard_iface,
0436                   batman_adv_ptype);
0437 
0438     /* Prevent processing a packet received on an interface which is getting
0439      * shut down otherwise the packet may trigger de-reference errors
0440      * further down in the receive path.
0441      */
0442     if (!kref_get_unless_zero(&hard_iface->refcount))
0443         goto err_out;
0444 
0445     skb = skb_share_check(skb, GFP_ATOMIC);
0446 
0447     /* skb was released by skb_share_check() */
0448     if (!skb)
0449         goto err_put;
0450 
0451     /* packet should hold at least type and version */
0452     if (unlikely(!pskb_may_pull(skb, 2)))
0453         goto err_free;
0454 
0455     /* expect a valid ethernet header here. */
0456     if (unlikely(skb->mac_len != ETH_HLEN || !skb_mac_header(skb)))
0457         goto err_free;
0458 
0459     if (!hard_iface->soft_iface)
0460         goto err_free;
0461 
0462     bat_priv = netdev_priv(hard_iface->soft_iface);
0463 
0464     if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
0465         goto err_free;
0466 
0467     /* discard frames on not active interfaces */
0468     if (hard_iface->if_status != BATADV_IF_ACTIVE)
0469         goto err_free;
0470 
0471     batadv_ogm_packet = (struct batadv_ogm_packet *)skb->data;
0472 
0473     if (batadv_ogm_packet->version != BATADV_COMPAT_VERSION) {
0474         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0475                "Drop packet: incompatible batman version (%i)\n",
0476                batadv_ogm_packet->version);
0477         goto err_free;
0478     }
0479 
0480     /* reset control block to avoid left overs from previous users */
0481     memset(skb->cb, 0, sizeof(struct batadv_skb_cb));
0482 
0483     idx = batadv_ogm_packet->packet_type;
0484     (*batadv_rx_handler[idx])(skb, hard_iface);
0485 
0486     batadv_hardif_put(hard_iface);
0487 
0488     /* return NET_RX_SUCCESS in any case as we
0489      * most probably dropped the packet for
0490      * routing-logical reasons.
0491      */
0492     return NET_RX_SUCCESS;
0493 
0494 err_free:
0495     kfree_skb(skb);
0496 err_put:
0497     batadv_hardif_put(hard_iface);
0498 err_out:
0499     return NET_RX_DROP;
0500 }
0501 
0502 static void batadv_recv_handler_init(void)
0503 {
0504     int i;
0505 
0506     for (i = 0; i < ARRAY_SIZE(batadv_rx_handler); i++)
0507         batadv_rx_handler[i] = batadv_recv_unhandled_packet;
0508 
0509     for (i = BATADV_UNICAST_MIN; i <= BATADV_UNICAST_MAX; i++)
0510         batadv_rx_handler[i] = batadv_recv_unhandled_unicast_packet;
0511 
0512     /* compile time checks for sizes */
0513     BUILD_BUG_ON(sizeof(struct batadv_bla_claim_dst) != 6);
0514     BUILD_BUG_ON(sizeof(struct batadv_ogm_packet) != 24);
0515     BUILD_BUG_ON(sizeof(struct batadv_icmp_header) != 20);
0516     BUILD_BUG_ON(sizeof(struct batadv_icmp_packet) != 20);
0517     BUILD_BUG_ON(sizeof(struct batadv_icmp_packet_rr) != 116);
0518     BUILD_BUG_ON(sizeof(struct batadv_unicast_packet) != 10);
0519     BUILD_BUG_ON(sizeof(struct batadv_unicast_4addr_packet) != 18);
0520     BUILD_BUG_ON(sizeof(struct batadv_frag_packet) != 20);
0521     BUILD_BUG_ON(sizeof(struct batadv_bcast_packet) != 14);
0522     BUILD_BUG_ON(sizeof(struct batadv_coded_packet) != 46);
0523     BUILD_BUG_ON(sizeof(struct batadv_unicast_tvlv_packet) != 20);
0524     BUILD_BUG_ON(sizeof(struct batadv_tvlv_hdr) != 4);
0525     BUILD_BUG_ON(sizeof(struct batadv_tvlv_gateway_data) != 8);
0526     BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_vlan_data) != 8);
0527     BUILD_BUG_ON(sizeof(struct batadv_tvlv_tt_change) != 12);
0528     BUILD_BUG_ON(sizeof(struct batadv_tvlv_roam_adv) != 8);
0529 
0530     i = sizeof_field(struct sk_buff, cb);
0531     BUILD_BUG_ON(sizeof(struct batadv_skb_cb) > i);
0532 
0533     /* broadcast packet */
0534     batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
0535 
0536     /* unicast packets ... */
0537     /* unicast with 4 addresses packet */
0538     batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
0539     /* unicast packet */
0540     batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
0541     /* unicast tvlv packet */
0542     batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
0543     /* batman icmp packet */
0544     batadv_rx_handler[BATADV_ICMP] = batadv_recv_icmp_packet;
0545     /* Fragmented packets */
0546     batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_frag_packet;
0547 }
0548 
0549 /**
0550  * batadv_recv_handler_register() - Register handler for batman-adv packet type
0551  * @packet_type: batadv_packettype which should be handled
0552  * @recv_handler: receive handler for the packet type
0553  *
0554  * Return: 0 on success or negative error number in case of failure
0555  */
0556 int
0557 batadv_recv_handler_register(u8 packet_type,
0558                  int (*recv_handler)(struct sk_buff *,
0559                          struct batadv_hard_iface *))
0560 {
0561     int (*curr)(struct sk_buff *skb,
0562             struct batadv_hard_iface *recv_if);
0563     curr = batadv_rx_handler[packet_type];
0564 
0565     if (curr != batadv_recv_unhandled_packet &&
0566         curr != batadv_recv_unhandled_unicast_packet)
0567         return -EBUSY;
0568 
0569     batadv_rx_handler[packet_type] = recv_handler;
0570     return 0;
0571 }
0572 
0573 /**
0574  * batadv_recv_handler_unregister() - Unregister handler for packet type
0575  * @packet_type: batadv_packettype which should no longer be handled
0576  */
0577 void batadv_recv_handler_unregister(u8 packet_type)
0578 {
0579     batadv_rx_handler[packet_type] = batadv_recv_unhandled_packet;
0580 }
0581 
0582 /**
0583  * batadv_skb_crc32() - calculate CRC32 of the whole packet and skip bytes in
0584  *  the header
0585  * @skb: skb pointing to fragmented socket buffers
0586  * @payload_ptr: Pointer to position inside the head buffer of the skb
0587  *  marking the start of the data to be CRC'ed
0588  *
0589  * payload_ptr must always point to an address in the skb head buffer and not to
0590  * a fragment.
0591  *
0592  * Return: big endian crc32c of the checksummed data
0593  */
0594 __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr)
0595 {
0596     u32 crc = 0;
0597     unsigned int from;
0598     unsigned int to = skb->len;
0599     struct skb_seq_state st;
0600     const u8 *data;
0601     unsigned int len;
0602     unsigned int consumed = 0;
0603 
0604     from = (unsigned int)(payload_ptr - skb->data);
0605 
0606     skb_prepare_seq_read(skb, from, to, &st);
0607     while ((len = skb_seq_read(consumed, &data, &st)) != 0) {
0608         crc = crc32c(crc, data, len);
0609         consumed += len;
0610     }
0611 
0612     return htonl(crc);
0613 }
0614 
0615 /**
0616  * batadv_get_vid() - extract the VLAN identifier from skb if any
0617  * @skb: the buffer containing the packet
0618  * @header_len: length of the batman header preceding the ethernet header
0619  *
0620  * Return: VID with the BATADV_VLAN_HAS_TAG flag when the packet embedded in the
0621  * skb is vlan tagged. Otherwise BATADV_NO_FLAGS.
0622  */
0623 unsigned short batadv_get_vid(struct sk_buff *skb, size_t header_len)
0624 {
0625     struct ethhdr *ethhdr = (struct ethhdr *)(skb->data + header_len);
0626     struct vlan_ethhdr *vhdr;
0627     unsigned short vid;
0628 
0629     if (ethhdr->h_proto != htons(ETH_P_8021Q))
0630         return BATADV_NO_FLAGS;
0631 
0632     if (!pskb_may_pull(skb, header_len + VLAN_ETH_HLEN))
0633         return BATADV_NO_FLAGS;
0634 
0635     vhdr = (struct vlan_ethhdr *)(skb->data + header_len);
0636     vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;
0637     vid |= BATADV_VLAN_HAS_TAG;
0638 
0639     return vid;
0640 }
0641 
0642 /**
0643  * batadv_vlan_ap_isola_get() - return AP isolation status for the given vlan
0644  * @bat_priv: the bat priv with all the soft interface information
0645  * @vid: the VLAN identifier for which the AP isolation attributed as to be
0646  *  looked up
0647  *
0648  * Return: true if AP isolation is on for the VLAN identified by vid, false
0649  * otherwise
0650  */
0651 bool batadv_vlan_ap_isola_get(struct batadv_priv *bat_priv, unsigned short vid)
0652 {
0653     bool ap_isolation_enabled = false;
0654     struct batadv_softif_vlan *vlan;
0655 
0656     /* if the AP isolation is requested on a VLAN, then check for its
0657      * setting in the proper VLAN private data structure
0658      */
0659     vlan = batadv_softif_vlan_get(bat_priv, vid);
0660     if (vlan) {
0661         ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
0662         batadv_softif_vlan_put(vlan);
0663     }
0664 
0665     return ap_isolation_enabled;
0666 }
0667 
0668 /**
0669  * batadv_throw_uevent() - Send an uevent with batman-adv specific env data
0670  * @bat_priv: the bat priv with all the soft interface information
0671  * @type: subsystem type of event. Stored in uevent's BATTYPE
0672  * @action: action type of event. Stored in uevent's BATACTION
0673  * @data: string with additional information to the event (ignored for
0674  *  BATADV_UEV_DEL). Stored in uevent's BATDATA
0675  *
0676  * Return: 0 on success or negative error number in case of failure
0677  */
0678 int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
0679             enum batadv_uev_action action, const char *data)
0680 {
0681     int ret = -ENOMEM;
0682     struct kobject *bat_kobj;
0683     char *uevent_env[4] = { NULL, NULL, NULL, NULL };
0684 
0685     bat_kobj = &bat_priv->soft_iface->dev.kobj;
0686 
0687     uevent_env[0] = kasprintf(GFP_ATOMIC,
0688                   "%s%s", BATADV_UEV_TYPE_VAR,
0689                   batadv_uev_type_str[type]);
0690     if (!uevent_env[0])
0691         goto out;
0692 
0693     uevent_env[1] = kasprintf(GFP_ATOMIC,
0694                   "%s%s", BATADV_UEV_ACTION_VAR,
0695                   batadv_uev_action_str[action]);
0696     if (!uevent_env[1])
0697         goto out;
0698 
0699     /* If the event is DEL, ignore the data field */
0700     if (action != BATADV_UEV_DEL) {
0701         uevent_env[2] = kasprintf(GFP_ATOMIC,
0702                       "%s%s", BATADV_UEV_DATA_VAR, data);
0703         if (!uevent_env[2])
0704             goto out;
0705     }
0706 
0707     ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
0708 out:
0709     kfree(uevent_env[0]);
0710     kfree(uevent_env[1]);
0711     kfree(uevent_env[2]);
0712 
0713     if (ret)
0714         batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
0715                "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
0716                batadv_uev_type_str[type],
0717                batadv_uev_action_str[action],
0718                (action == BATADV_UEV_DEL ? "NULL" : data), ret);
0719     return ret;
0720 }
0721 
0722 module_init(batadv_init);
0723 module_exit(batadv_exit);
0724 
0725 MODULE_LICENSE("GPL");
0726 
0727 MODULE_AUTHOR(BATADV_DRIVER_AUTHOR);
0728 MODULE_DESCRIPTION(BATADV_DRIVER_DESC);
0729 MODULE_VERSION(BATADV_SOURCE_VERSION);
0730 MODULE_ALIAS_RTNL_LINK("batadv");
0731 MODULE_ALIAS_GENL_FAMILY(BATADV_NL_NAME);