/* $Id: ha.h 1.12 06/05/07 21:52:43+03:00 anttit@tcs.hut.fi $ */

#ifndef __HA_H__
#define __HA_H__ 1

extern struct in6_addr ha_myaddr;
extern struct in6_addr ha_mnaddr;

#include "tqueue.h"
#include "mh.h"

struct ha_interface {
	int ifindex;
	struct list_head addr_list;
	struct list_head ha_list;	/* protected by ha_lock */
	uint16_t mpa_flags;		/* protected by mpa_lock */
	struct list_head prefix_list;	/* protected by prefix_lock */
	int prefix_count;		/* protected by prefix_lock */
	struct list_head iflist;
};

struct home_agent {
	struct list_head list;
	struct in6_addr addr;
	uint16_t preference;
	uint16_t flags;
	struct timespec lifetime;
	struct ha_interface *iface;
	struct tq_elem tqe;
};

struct ha_addr_holder {
	struct list_head list;
	struct in6_addr ha_addr;
	struct in6_addr anycast_addr;
};


int homeagents_ifall_init(void);
int homeagent_if_init(int ifindex);
struct ha_interface *ha_get_if(int ifindex);
struct ha_interface *ha_get_if_by_addr(const struct in6_addr *addr);
struct ha_interface *ha_get_if_by_anycast(const struct in6_addr *anycast,
					  struct in6_addr **addr);
int ha_recv_home_bu(const struct ip6_mh *mh, ssize_t len,
		    const struct in6_addr_bundle *in, int iif, uint32_t flags);
#define HA_BU_F_THREAD_JOIN	0x01
#define HA_BU_F_PASSIVE_SEQ	0x02
#define HA_BU_F_SKIP_DAD	0x04
#define HA_BU_F_SKIP_BA		0x08

int ha_init(void);
void ha_cleanup(void);

#endif /* __HA_H__ */
