linux/net/batman-adv/fragmentation.c

// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) B.A.T.M.A.N. contributors:
 *
 * Martin Hundebøll <[email protected]>
 */

#include "fragmentation.h"
#include "main.h"

#include <linux/atomic.h>
#include <linux/byteorder/generic.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/jiffies.h>
#include <linux/lockdep.h>
#include <linux/minmax.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <uapi/linux/batadv_packet.h>

#include "hard-interface.h"
#include "originator.h"
#include "send.h"

/**
 * batadv_frag_clear_chain() - delete entries in the fragment buffer chain
 * @head: head of chain with entries.
 * @dropped: whether the chain is cleared because all fragments are dropped
 *
 * Free fragments in the passed hlist. Should be called with appropriate lock.
 */
static void batadv_frag_clear_chain(struct hlist_head *head, bool dropped)
{}

/**
 * batadv_frag_purge_orig() - free fragments associated to an orig
 * @orig_node: originator to free fragments from
 * @check_cb: optional function to tell if an entry should be purged
 */
void batadv_frag_purge_orig(struct batadv_orig_node *orig_node,
			    bool (*check_cb)(struct batadv_frag_table_entry *))
{}

/**
 * batadv_frag_size_limit() - maximum possible size of packet to be fragmented
 *
 * Return: the maximum size of payload that can be fragmented.
 */
static int batadv_frag_size_limit(void)
{}

/**
 * batadv_frag_init_chain() - check and prepare fragment chain for new fragment
 * @chain: chain in fragments table to init
 * @seqno: sequence number of the received fragment
 *
 * Make chain ready for a fragment with sequence number "seqno". Delete existing
 * entries if they have an "old" sequence number.
 *
 * Caller must hold chain->lock.
 *
 * Return: true if chain is empty and the caller can just insert the new
 * fragment without searching for the right position.
 */
static bool batadv_frag_init_chain(struct batadv_frag_table_entry *chain,
				   u16 seqno)
{}

/**
 * batadv_frag_insert_packet() - insert a fragment into a fragment chain
 * @orig_node: originator that the fragment was received from
 * @skb: skb to insert
 * @chain_out: list head to attach complete chains of fragments to
 *
 * Insert a new fragment into the reverse ordered chain in the right table
 * entry. The hash table entry is cleared if "old" fragments exist in it.
 *
 * Return: true if skb is buffered, false on error. If the chain has all the
 * fragments needed to merge the packet, the chain is moved to the passed head
 * to avoid locking the chain in the table.
 */
static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node,
				      struct sk_buff *skb,
				      struct hlist_head *chain_out)
{}

/**
 * batadv_frag_merge_packets() - merge a chain of fragments
 * @chain: head of chain with fragments
 *
 * Expand the first skb in the chain and copy the content of the remaining
 * skb's into the expanded one. After doing so, clear the chain.
 *
 * Return: the merged skb or NULL on error.
 */
static struct sk_buff *
batadv_frag_merge_packets(struct hlist_head *chain)
{}

/**
 * batadv_frag_skb_buffer() - buffer fragment for later merge
 * @skb: skb to buffer
 * @orig_node_src: originator that the skb is received from
 *
 * Add fragment to buffer and merge fragments if possible.
 *
 * There are three possible outcomes: 1) Packet is merged: Return true and
 * set *skb to merged packet; 2) Packet is buffered: Return true and set *skb
 * to NULL; 3) Error: Return false and free skb.
 *
 * Return: true when the packet is merged or buffered, false when skb is not
 * used.
 */
bool batadv_frag_skb_buffer(struct sk_buff **skb,
			    struct batadv_orig_node *orig_node_src)
{}

/**
 * batadv_frag_skb_fwd() - forward fragments that would exceed MTU when merged
 * @skb: skb to forward
 * @recv_if: interface that the skb is received on
 * @orig_node_src: originator that the skb is received from
 *
 * Look up the next-hop of the fragments payload and check if the merged packet
 * will exceed the MTU towards the next-hop. If so, the fragment is forwarded
 * without merging it.
 *
 * Return: true if the fragment is consumed/forwarded, false otherwise.
 */
bool batadv_frag_skb_fwd(struct sk_buff *skb,
			 struct batadv_hard_iface *recv_if,
			 struct batadv_orig_node *orig_node_src)
{}

/**
 * batadv_frag_create() - create a fragment from skb
 * @net_dev: outgoing device for fragment
 * @skb: skb to create fragment from
 * @frag_head: header to use in new fragment
 * @fragment_size: size of new fragment
 *
 * Split the passed skb into two fragments: A new one with size matching the
 * passed mtu and the old one with the rest. The new skb contains data from the
 * tail of the old skb.
 *
 * Return: the new fragment, NULL on error.
 */
static struct sk_buff *batadv_frag_create(struct net_device *net_dev,
					  struct sk_buff *skb,
					  struct batadv_frag_packet *frag_head,
					  unsigned int fragment_size)
{}

/**
 * batadv_frag_send_packet() - create up to 16 fragments from the passed skb
 * @skb: skb to create fragments from
 * @orig_node: final destination of the created fragments
 * @neigh_node: next-hop of the created fragments
 *
 * Return: the netdev tx status or a negative errno code on a failure
 */
int batadv_frag_send_packet(struct sk_buff *skb,
			    struct batadv_orig_node *orig_node,
			    struct batadv_neigh_node *neigh_node)
{}