#ifndef _NETLINK_NETLINK_VAR_H_
#define _NETLINK_NETLINK_VAR_H_
#ifdef _KERNEL
#include <sys/ck.h>
#include <sys/epoch.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <net/vnet.h>
#define NLSNDQ 65536
#define NLRCVQ 65536
#define NLMBUFSIZE 2048
struct ucred;
struct nl_buf {
TAILQ_ENTRY(nl_buf) tailq;
u_int buflen;
u_int datalen;
u_int offset;
char data[];
};
#define NLP_MAX_GROUPS 128
BITSET_DEFINE(nl_groups, NLP_MAX_GROUPS);
struct nlpcb {
struct socket *nl_socket;
struct nl_groups nl_groups;
uint32_t nl_port;
uint32_t nl_flags;
uint32_t nl_process_id;
int nl_proto;
bool nl_bound;
bool nl_task_pending;
bool nl_tx_blocked;
bool nl_linux;
bool nl_unconstrained_vnet;
bool nl_need_thread_setup;
struct taskqueue *nl_taskqueue;
struct task nl_task;
uint64_t nl_dropped_bytes;
uint64_t nl_dropped_messages;
CK_LIST_ENTRY(nlpcb) nl_next;
CK_LIST_ENTRY(nlpcb) nl_port_next;
volatile u_int nl_refcount;
struct mtx nl_lock;
struct epoch_context nl_epoch_ctx;
};
#define sotonlpcb(so) ((struct nlpcb *)(so)->so_pcb)
#define NLP_LOCK_INIT(_nlp) mtx_init(&((_nlp)->nl_lock), "nlp mtx", NULL, MTX_DEF)
#define NLP_LOCK_DESTROY(_nlp) mtx_destroy(&((_nlp)->nl_lock))
#define NLP_LOCK(_nlp) mtx_lock(&((_nlp)->nl_lock))
#define NLP_UNLOCK(_nlp) mtx_unlock(&((_nlp)->nl_lock))
#define ALIGNED_NL_SZ(_data) roundup2((((struct nlmsghdr *)(_data))->nlmsg_len), 16)
#define NLF_CAP_ACK 0x01
#define NLF_EXT_ACK 0x02
#define NLF_STRICT 0x04
#define NLF_MSG_INFO 0x08
SYSCTL_DECL(_net_netlink);
SYSCTL_DECL(_net_netlink_debug);
struct nl_control {
CK_LIST_HEAD(nl_pid_head, nlpcb) ctl_port_head;
CK_LIST_HEAD(nlpcb_head, nlpcb) ctl_pcb_head;
CK_LIST_ENTRY(nl_control) ctl_next;
struct rmlock ctl_lock;
};
VNET_DECLARE(struct nl_control, nl_ctl);
#define V_nl_ctl VNET(nl_ctl)
struct sockaddr_nl;
struct sockaddr;
struct nlmsghdr;
int nl_verify_proto(int proto);
const char *nl_get_proto_name(int proto);
extern int netlink_unloading;
struct nl_proto_handler {
nl_handler_f cb;
const char *proto_name;
};
extern struct nl_proto_handler *nl_handlers;
bool nl_send_group(struct nl_writer *);
void nl_clear_group(u_int);
void nl_osd_register(void);
void nl_osd_unregister(void);
void nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp);
bool nl_send(struct nl_writer *, struct nlpcb *);
void nlmsg_ack(struct nlpcb *nlp, int error, struct nlmsghdr *nlmsg,
struct nl_pstate *npt);
void nl_on_transmit(struct nlpcb *nlp);
void nl_taskqueue_handler(void *_arg, int pending);
void nl_schedule_taskqueue(struct nlpcb *nlp);
void nl_process_receive_locked(struct nlpcb *nlp);
void nl_set_source_metadata(struct mbuf *m, int num_messages);
struct nl_buf *nl_buf_alloc(size_t len, int mflag);
void nl_buf_free(struct nl_buf *nb);
#define MAX_FAMILIES 20
#define MAX_GROUPS 64
#define MIN_GROUP_NUM 48
#define CTRL_FAMILY_ID 0
#define CTRL_FAMILY_NAME "nlctrl"
#define CTRL_GROUP_ID 0
#define CTRL_GROUP_NAME "notify"
struct ifnet;
struct nl_parsed_link;
struct nlattr_bmask;
struct nl_pstate;
struct nl_function_wrapper {
bool (*nlmsg_add)(struct nl_writer *nw, uint32_t portid, uint32_t seq, uint16_t type,
uint16_t flags, uint32_t len);
bool (*nlmsg_refill_buffer)(struct nl_writer *nw, size_t required_len);
bool (*nlmsg_flush)(struct nl_writer *nw);
bool (*nlmsg_end)(struct nl_writer *nw);
void (*nlmsg_abort)(struct nl_writer *nw);
void (*nlmsg_ignore_limit)(struct nl_writer *nw);
bool (*nl_writer_unicast)(struct nl_writer *nw, size_t size,
struct nlpcb *nlp, bool waitok);
bool (*nl_writer_group)(struct nl_writer *nw, size_t size,
uint16_t protocol, uint16_t group_id, int priv, bool waitok);
bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
int (*nl_modify_ifp_generic)(struct ifnet *ifp, struct nl_parsed_link *lattrs,
const struct nlattr_bmask *bm, struct nl_pstate *npt);
void (*nl_store_ifp_cookie)(struct nl_pstate *npt, struct ifnet *ifp);
struct nlpcb * (*nl_get_thread_nlp)(struct thread *td);
};
void nl_set_functions(const struct nl_function_wrapper *nl);
#endif
#endif