/*
 * mactable.h - macaddress table and functions header file
 *
 * Copyright (C) 2020-2024 IOPSYS Software Solutions AB. All rights reserved.
 *
 */

#ifndef CNTLR_MACTABLE_H
#define CNTLR_MACTABLE_H


#include <stdint.h>
#include <stdio.h>
#include <easy/hlist.h>
#include <libubox/list.h>

#ifndef MAC_ADDR_HASH
#define MAC_ADDR_HASH(a)    (a[0] ^ a[1] ^ a[2] ^ a[3] ^ a[4] ^ a[5])
#endif

#define MAC_HASHTABLE_SIZE    128
#define mac_hash(a)           (MAC_ADDR_HASH(a) & (MAC_HASHTABLE_SIZE - 1))

enum macaddr_type {
	MAC_ENTRY_UNKNOWN = 0,
	MAC_ENTRY_FBSS  = (1 << 0),  /**< data points to struct netif_iface */
	MAC_ENTRY_BBSS  = (1 << 1),  /**< data points to struct netif_iface */
	MAC_ENTRY_BSTA  = (1 << 2),  /**< data points to struct sta */
	MAC_ENTRY_ALID  = (1 << 3),  /**< data points to struct node */
	MAC_ENTRY_RADIO = (1 << 4),  /**< data points to struct netif_radio */
	NUM_MAC_ENTRY_TYPES,
};

struct macaddr_entry {
	uint8_t macaddr[6];
	enum macaddr_type type;

	/* points to appropriate struct based on type */
	void *data;
	struct hlist_node hlist;
};

struct macaddr_entry *mactable_lookup(struct hlist_head *table,
				      uint8_t *macaddr,
				      uint32_t type);

struct macaddr_entry *mactable_add_entry(struct hlist_head *table,
					  uint8_t *macaddr,
					  enum macaddr_type type,
					  void *data);

int mactable_del_entry(struct hlist_head *table,
		       uint8_t *macaddr,
		       enum macaddr_type type);


int mactable_set_entry_type(struct hlist_head *table,
			    uint8_t *macaddr,
			    uint32_t type);

int mactable_get_entry_type(struct hlist_head *table,
			    uint8_t *macaddr,
			    uint32_t *type);

void mactable_flush(struct hlist_head *table);
void mactable_print(struct hlist_head *table);
const char *macaddr_type2str(enum macaddr_type type);

#endif /* CNTLR_MACTABLE_H */
