// SPDX-License-Identifier: GPL-2.0 /* Copyright (C) B.A.T.M.A.N. contributors: * * Marek Lindner, Simon Wunderlich */ #include "routing.h" #include "main.h" #include <linux/atomic.h> #include <linux/byteorder/generic.h> #include <linux/compiler.h> #include <linux/errno.h> #include <linux/etherdevice.h> #include <linux/if_ether.h> #include <linux/jiffies.h> #include <linux/kref.h> #include <linux/netdevice.h> #include <linux/printk.h> #include <linux/rculist.h> #include <linux/rcupdate.h> #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/stddef.h> #include <uapi/linux/batadv_packet.h> #include "bitarray.h" #include "bridge_loop_avoidance.h" #include "distributed-arp-table.h" #include "fragmentation.h" #include "hard-interface.h" #include "log.h" #include "network-coding.h" #include "originator.h" #include "send.h" #include "soft-interface.h" #include "tp_meter.h" #include "translation-table.h" #include "tvlv.h" static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if); /** * _batadv_update_route() - set the router for this originator * @bat_priv: the bat priv with all the soft interface information * @orig_node: orig node which is to be configured * @recv_if: the receive interface for which this route is set * @neigh_node: neighbor which should be the next router * * This function does not perform any error checks */ static void _batadv_update_route(struct batadv_priv *bat_priv, struct batadv_orig_node *orig_node, struct batadv_hard_iface *recv_if, struct batadv_neigh_node *neigh_node) { … } /** * batadv_update_route() - set the router for this originator * @bat_priv: the bat priv with all the soft interface information * @orig_node: orig node which is to be configured * @recv_if: the receive interface for which this route is set * @neigh_node: neighbor which should be the next router */ void batadv_update_route(struct batadv_priv *bat_priv, struct batadv_orig_node *orig_node, struct batadv_hard_iface *recv_if, struct batadv_neigh_node *neigh_node) { … } /** * batadv_window_protected() - checks whether the host restarted and is in the * protection time. * @bat_priv: the bat priv with all the soft interface information * @seq_num_diff: difference between the current/received sequence number and * the last sequence number * @seq_old_max_diff: maximum age of sequence number not considered as restart * @last_reset: jiffies timestamp of the last reset, will be updated when reset * is detected * @protection_started: is set to true if the protection window was started, * doesn't change otherwise. * * Return: * false if the packet is to be accepted. * true if the packet is to be ignored. */ bool batadv_window_protected(struct batadv_priv *bat_priv, s32 seq_num_diff, s32 seq_old_max_diff, unsigned long *last_reset, bool *protection_started) { … } /** * batadv_check_management_packet() - Check preconditions for management packets * @skb: incoming packet buffer * @hard_iface: incoming hard interface * @header_len: minimal header length of packet type * * Return: true when management preconditions are met, false otherwise */ bool batadv_check_management_packet(struct sk_buff *skb, struct batadv_hard_iface *hard_iface, int header_len) { … } /** * batadv_recv_my_icmp_packet() - receive an icmp packet locally * @bat_priv: the bat priv with all the soft interface information * @skb: icmp packet to process * * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP * otherwise. */ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, struct sk_buff *skb) { … } static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, struct sk_buff *skb) { … } /** * batadv_recv_icmp_packet() - Process incoming icmp packet * @skb: incoming packet buffer * @recv_if: incoming hard interface * * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure */ int batadv_recv_icmp_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_check_unicast_packet() - Check for malformed unicast packets * @bat_priv: the bat priv with all the soft interface information * @skb: packet to check * @hdr_size: size of header to pull * * Checks for short header and bad addresses in the given packet. * * Return: negative value when check fails and 0 otherwise. The negative value * depends on the reason: -ENODATA for bad header, -EBADR for broadcast * destination or source, and -EREMOTE for non-local (other host) destination. */ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, int hdr_size) { … } /** * batadv_last_bonding_get() - Get last_bonding_candidate of orig_node * @orig_node: originator node whose last bonding candidate should be retrieved * * Return: last bonding candidate of router or NULL if not found * * The object is returned with refcounter increased by 1. */ static struct batadv_orig_ifinfo * batadv_last_bonding_get(struct batadv_orig_node *orig_node) { … } /** * batadv_last_bonding_replace() - Replace last_bonding_candidate of orig_node * @orig_node: originator node whose bonding candidates should be replaced * @new_candidate: new bonding candidate or NULL */ static void batadv_last_bonding_replace(struct batadv_orig_node *orig_node, struct batadv_orig_ifinfo *new_candidate) { … } /** * batadv_find_router() - find a suitable router for this originator * @bat_priv: the bat priv with all the soft interface information * @orig_node: the destination node * @recv_if: pointer to interface this packet was received on * * Return: the router which should be used for this orig_node on * this interface, or NULL if not available. */ struct batadv_neigh_node * batadv_find_router(struct batadv_priv *bat_priv, struct batadv_orig_node *orig_node, struct batadv_hard_iface *recv_if) { … } static int batadv_route_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_reroute_unicast_packet() - update the unicast header for re-routing * @bat_priv: the bat priv with all the soft interface information * @skb: unicast packet to process * @unicast_packet: the unicast header to be updated * @dst_addr: the payload destination * @vid: VLAN identifier * * Search the translation table for dst_addr and update the unicast header with * the new corresponding information (originator address where the destination * client currently is and its known TTVN) * * Return: true if the packet header has been updated, false otherwise */ static bool batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, struct batadv_unicast_packet *unicast_packet, u8 *dst_addr, unsigned short vid) { … } static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, struct sk_buff *skb, int hdr_len) { … } /** * batadv_recv_unhandled_unicast_packet() - receive and process packets which * are in the unicast number space but not yet known to the implementation * @skb: unicast tvlv packet to process * @recv_if: pointer to interface this packet was received on * * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP * otherwise. */ int batadv_recv_unhandled_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_recv_unicast_packet() - Process incoming unicast packet * @skb: incoming packet buffer * @recv_if: incoming hard interface * * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure */ int batadv_recv_unicast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_recv_unicast_tvlv() - receive and process unicast tvlv packets * @skb: unicast tvlv packet to process * @recv_if: pointer to interface this packet was received on * * Return: NET_RX_SUCCESS if the packet has been consumed or NET_RX_DROP * otherwise. */ int batadv_recv_unicast_tvlv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_recv_frag_packet() - process received fragment * @skb: the received fragment * @recv_if: interface that the skb is received on * * This function does one of the three following things: 1) Forward fragment, if * the assembled packet will exceed our MTU; 2) Buffer fragment, if we still * lack further fragments; 3) Merge fragments, if we have all needed parts. * * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. */ int batadv_recv_frag_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } /** * batadv_recv_bcast_packet() - Process incoming broadcast packet * @skb: incoming packet buffer * @recv_if: incoming hard interface * * Return: NET_RX_SUCCESS on success or NET_RX_DROP in case of failure */ int batadv_recv_bcast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } #ifdef CONFIG_BATMAN_ADV_MCAST /** * batadv_recv_mcast_packet() - process received batman-adv multicast packet * @skb: the received batman-adv multicast packet * @recv_if: interface that the skb is received on * * Parses the given, received batman-adv multicast packet. Depending on the * contents of its TVLV forwards it and/or decapsulates it to hand it to the * soft interface. * * Return: NET_RX_DROP if the skb is not consumed, NET_RX_SUCCESS otherwise. */ int batadv_recv_mcast_packet(struct sk_buff *skb, struct batadv_hard_iface *recv_if) { … } #endif /* CONFIG_BATMAN_ADV_MCAST */