linux/drivers/net/bonding/bond_alb.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
 */

#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/pkt_sched.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_bonding.h>
#include <linux/if_vlan.h>
#include <linux/in.h>
#include <net/arp.h>
#include <net/ipv6.h>
#include <net/ndisc.h>
#include <asm/byteorder.h>
#include <net/bonding.h>
#include <net/bond_alb.h>

static const u8 mac_v6_allmcast[ETH_ALEN + 2] __long_aligned =;
static const int alb_delta_in_ticks =;

#pragma pack(1)
struct learning_pkt {};

struct arp_pkt {};
#pragma pack()

/* Forward declaration */
static void alb_send_learning_packets(struct slave *slave, const u8 mac_addr[],
				      bool strict_match);
static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp);
static void rlb_src_unlink(struct bonding *bond, u32 index);
static void rlb_src_link(struct bonding *bond, u32 ip_src_hash,
			 u32 ip_dst_hash);

static inline u8 _simple_hash(const u8 *hash_start, int hash_size)
{}

/*********************** tlb specific functions ***************************/

static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load)
{}

static inline void tlb_init_slave(struct slave *slave)
{}

static void __tlb_clear_slave(struct bonding *bond, struct slave *slave,
			 int save_load)
{}

static void tlb_clear_slave(struct bonding *bond, struct slave *slave,
			 int save_load)
{}

/* Must be called before starting the monitor timer */
static int tlb_initialize(struct bonding *bond)
{}

/* Must be called only after all slaves have been released */
static void tlb_deinitialize(struct bonding *bond)
{}

static long long compute_gap(struct slave *slave)
{}

static struct slave *tlb_get_least_loaded_slave(struct bonding *bond)
{}

static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index,
						u32 skb_len)
{}

static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index,
					u32 skb_len)
{}

/*********************** rlb specific functions ***************************/

/* when an ARP REPLY is received from a client update its info
 * in the rx_hashtbl
 */
static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
{}

static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
			struct slave *slave)
{}

/* Caller must hold rcu_read_lock() */
static struct slave *__rlb_next_rx_slave(struct bonding *bond)
{}

/* Caller must hold RTNL, rcu_read_lock is obtained only to silence checkers */
static struct slave *rlb_next_rx_slave(struct bonding *bond)
{}

/* teach the switch the mac of a disabled slave
 * on the primary for fault tolerance
 *
 * Caller must hold RTNL
 */
static void rlb_teach_disabled_mac_on_primary(struct bonding *bond,
					      const u8 addr[])
{}

/* slave being removed should not be active at this point
 *
 * Caller must hold rtnl.
 */
static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
{}

static void rlb_update_client(struct rlb_client_info *client_info)
{}

/* sends ARP REPLIES that update the clients that need updating */
static void rlb_update_rx_clients(struct bonding *bond)
{}

/* The slave was assigned a new mac address - update the clients */
static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *slave)
{}

/* mark all clients using src_ip to be updated */
static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
{}

static struct slave *rlb_choose_channel(struct sk_buff *skb,
					struct bonding *bond,
					const struct arp_pkt *arp)
{}

/* chooses (and returns) transmit channel for arp reply
 * does not choose channel for other arp types since they are
 * sent on the curr_active_slave
 */
static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
{}

static void rlb_rebalance(struct bonding *bond)
{}

/* Caller must hold mode_lock */
static void rlb_init_table_entry_dst(struct rlb_client_info *entry)
{}
static void rlb_init_table_entry_src(struct rlb_client_info *entry)
{}

static void rlb_init_table_entry(struct rlb_client_info *entry)
{}

static void rlb_delete_table_entry_dst(struct bonding *bond, u32 index)
{}

/* unlink a rlb hash table entry from the src list */
static void rlb_src_unlink(struct bonding *bond, u32 index)
{}

static void rlb_delete_table_entry(struct bonding *bond, u32 index)
{}

/* add the rx_hashtbl[ip_dst_hash] entry to the list
 * of entries with identical ip_src_hash
 */
static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, u32 ip_dst_hash)
{}

/* deletes all rx_hashtbl entries with arp->ip_src if their mac_src does
 * not match arp->mac_src
 */
static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp)
{}

static int rlb_initialize(struct bonding *bond)
{}

static void rlb_deinitialize(struct bonding *bond)
{}

static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{}

/*********************** tlb/rlb shared functions *********************/

static void alb_send_lp_vid(struct slave *slave, const u8 mac_addr[],
			    __be16 vlan_proto, u16 vid)
{}

struct alb_walk_data {};

static int alb_upper_dev_walk(struct net_device *upper,
			      struct netdev_nested_priv *priv)
{}

static void alb_send_learning_packets(struct slave *slave, const u8 mac_addr[],
				      bool strict_match)
{}

static int alb_set_slave_mac_addr(struct slave *slave, const u8 addr[],
				  unsigned int len)
{}

/* Swap MAC addresses between two slaves.
 *
 * Called with RTNL held, and no other locks.
 */
static void alb_swap_mac_addr(struct slave *slave1, struct slave *slave2)
{}

/* Send learning packets after MAC address swap.
 *
 * Called with RTNL and no other locks
 */
static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
				struct slave *slave2)
{}

/**
 * alb_change_hw_addr_on_detach
 * @bond: bonding we're working on
 * @slave: the slave that was just detached
 *
 * We assume that @slave was already detached from the slave list.
 *
 * If @slave's permanent hw address is different both from its current
 * address and from @bond's address, then somewhere in the bond there's
 * a slave that has @slave's permanet address as its current address.
 * We'll make sure that slave no longer uses @slave's permanent address.
 *
 * Caller must hold RTNL and no other locks
 */
static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *slave)
{}

/**
 * alb_handle_addr_collision_on_attach
 * @bond: bonding we're working on
 * @slave: the slave that was just attached
 *
 * checks uniqueness of slave's mac address and handles the case the
 * new slave uses the bonds mac address.
 *
 * If the permanent hw address of @slave is @bond's hw address, we need to
 * find a different hw address to give @slave, that isn't in use by any other
 * slave in the bond. This address must be, of course, one of the permanent
 * addresses of the other slaves.
 *
 * We go over the slave list, and for each slave there we compare its
 * permanent hw address with the current address of all the other slaves.
 * If no match was found, then we've found a slave with a permanent address
 * that isn't used by any other slave in the bond, so we can assign it to
 * @slave.
 *
 * assumption: this function is called before @slave is attached to the
 *	       bond slave list.
 */
static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slave *slave)
{}

/**
 * alb_set_mac_address
 * @bond: bonding we're working on
 * @addr: MAC address to set
 *
 * In TLB mode all slaves are configured to the bond's hw address, but set
 * their dev_addr field to different addresses (based on their permanent hw
 * addresses).
 *
 * For each slave, this function sets the interface to the new address and then
 * changes its dev_addr field to its previous value.
 *
 * Unwinding assumes bond's mac address has not yet changed.
 */
static int alb_set_mac_address(struct bonding *bond, void *addr)
{}

/* determine if the packet is NA or NS */
static bool alb_determine_nd(struct sk_buff *skb, struct bonding *bond)
{}

/************************ exported alb functions ************************/

int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
{}

void bond_alb_deinitialize(struct bonding *bond)
{}

static netdev_tx_t bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
				    struct slave *tx_slave)
{}

struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
				      struct sk_buff *skb)
{}

netdev_tx_t bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
{}

struct slave *bond_xmit_alb_slave_get(struct bonding *bond,
				      struct sk_buff *skb)
{}

netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
{}

void bond_alb_monitor(struct work_struct *work)
{}

/* assumption: called before the slave is attached to the bond
 * and not locked by the bond lock
 */
int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
{}

/* Remove slave from tlb and rlb hash tables, and fix up MAC addresses
 * if necessary.
 *
 * Caller must hold RTNL and no other locks
 */
void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave)
{}

void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link)
{}

/**
 * bond_alb_handle_active_change - assign new curr_active_slave
 * @bond: our bonding struct
 * @new_slave: new slave to assign
 *
 * Set the bond->curr_active_slave to @new_slave and handle
 * mac address swapping and promiscuity changes as needed.
 *
 * Caller must hold RTNL
 */
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
{}

/* Called with RTNL */
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
{}

void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
{}