17e5bf684SAlexander V. Chernikov /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
37e5bf684SAlexander V. Chernikov *
47e5bf684SAlexander V. Chernikov * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
57e5bf684SAlexander V. Chernikov *
67e5bf684SAlexander V. Chernikov * Redistribution and use in source and binary forms, with or without
77e5bf684SAlexander V. Chernikov * modification, are permitted provided that the following conditions
87e5bf684SAlexander V. Chernikov * are met:
97e5bf684SAlexander V. Chernikov * 1. Redistributions of source code must retain the above copyright
107e5bf684SAlexander V. Chernikov * notice, this list of conditions and the following disclaimer.
117e5bf684SAlexander V. Chernikov * 2. Redistributions in binary form must reproduce the above copyright
127e5bf684SAlexander V. Chernikov * notice, this list of conditions and the following disclaimer in the
137e5bf684SAlexander V. Chernikov * documentation and/or other materials provided with the distribution.
147e5bf684SAlexander V. Chernikov *
157e5bf684SAlexander V. Chernikov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
167e5bf684SAlexander V. Chernikov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
177e5bf684SAlexander V. Chernikov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
187e5bf684SAlexander V. Chernikov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
197e5bf684SAlexander V. Chernikov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
207e5bf684SAlexander V. Chernikov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
217e5bf684SAlexander V. Chernikov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
227e5bf684SAlexander V. Chernikov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
237e5bf684SAlexander V. Chernikov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
247e5bf684SAlexander V. Chernikov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
257e5bf684SAlexander V. Chernikov * SUCH DAMAGE.
267e5bf684SAlexander V. Chernikov */
277e5bf684SAlexander V. Chernikov
287e5bf684SAlexander V. Chernikov #ifndef _NETLINK_NETLINK_CTL_H_
297e5bf684SAlexander V. Chernikov #define _NETLINK_NETLINK_CTL_H_
307e5bf684SAlexander V. Chernikov
31dddafa8dSAlexander V. Chernikov #ifdef _KERNEL
327e5bf684SAlexander V. Chernikov /*
337e5bf684SAlexander V. Chernikov * This file provides headers for the public KPI of the netlink
347e5bf684SAlexander V. Chernikov * subsystem
357e5bf684SAlexander V. Chernikov */
3619e43c16SAlexander V. Chernikov #include <sys/_eventhandler.h>
377e5bf684SAlexander V. Chernikov
387e5bf684SAlexander V. Chernikov MALLOC_DECLARE(M_NETLINK);
397e5bf684SAlexander V. Chernikov
407e5bf684SAlexander V. Chernikov /*
417e5bf684SAlexander V. Chernikov * Macro for handling attribute TLVs
427e5bf684SAlexander V. Chernikov */
437e5bf684SAlexander V. Chernikov #define _roundup2(x, y) (((x)+((y)-1))&(~((y)-1)))
447e5bf684SAlexander V. Chernikov
457e5bf684SAlexander V. Chernikov #define NETLINK_ALIGN_SIZE sizeof(uint32_t)
467e5bf684SAlexander V. Chernikov #define NETLINK_ALIGN(_len) _roundup2(_len, NETLINK_ALIGN_SIZE)
477e5bf684SAlexander V. Chernikov
487e5bf684SAlexander V. Chernikov #define NLA_ALIGN_SIZE sizeof(uint32_t)
497e5bf684SAlexander V. Chernikov #define NLA_ALIGN(_len) _roundup2(_len, NLA_ALIGN_SIZE)
50876b88a4SGleb Smirnoff #define NLA_HDRLEN ((uint16_t)sizeof(struct nlattr))
51876b88a4SGleb Smirnoff #define NLA_DATA_LEN(_nla) ((_nla)->nla_len - NLA_HDRLEN)
527e5bf684SAlexander V. Chernikov #define NLA_DATA(_nla) NL_ITEM_DATA(_nla, NLA_HDRLEN)
537e5bf684SAlexander V. Chernikov #define NLA_DATA_CONST(_nla) NL_ITEM_DATA_CONST(_nla, NLA_HDRLEN)
547e5bf684SAlexander V. Chernikov #define NLA_TYPE(_nla) ((_nla)->nla_type & 0x3FFF)
557e5bf684SAlexander V. Chernikov
567e5bf684SAlexander V. Chernikov #ifndef typeof
577e5bf684SAlexander V. Chernikov #define typeof __typeof
587e5bf684SAlexander V. Chernikov #endif
597e5bf684SAlexander V. Chernikov
607e5bf684SAlexander V. Chernikov #define NLA_NEXT(_attr) (struct nlattr *)((char *)_attr + NLA_ALIGN(_attr->nla_len))
617e5bf684SAlexander V. Chernikov #define _NLA_END(_start, _len) ((char *)(_start) + (_len))
627e5bf684SAlexander V. Chernikov #define NLA_FOREACH(_attr, _start, _len) \
637e5bf684SAlexander V. Chernikov for (typeof(_attr) _end = (typeof(_attr))_NLA_END(_start, _len), _attr = (_start); \
647e5bf684SAlexander V. Chernikov ((char *)_attr < (char *)_end) && \
657e5bf684SAlexander V. Chernikov ((char *)NLA_NEXT(_attr) <= (char *)_end); \
667e5bf684SAlexander V. Chernikov _attr = (_len -= NLA_ALIGN(_attr->nla_len), NLA_NEXT(_attr)))
677e5bf684SAlexander V. Chernikov
687e5bf684SAlexander V. Chernikov #include <netlink/netlink_message_writer.h>
697e5bf684SAlexander V. Chernikov #include <netlink/netlink_message_parser.h>
707e5bf684SAlexander V. Chernikov
717e5bf684SAlexander V. Chernikov
727e5bf684SAlexander V. Chernikov /* Protocol handlers */
737e5bf684SAlexander V. Chernikov struct nl_pstate;
747e5bf684SAlexander V. Chernikov typedef int (*nl_handler_f)(struct nlmsghdr *hdr, struct nl_pstate *npt);
757e5bf684SAlexander V. Chernikov
767e5bf684SAlexander V. Chernikov bool netlink_register_proto(int proto, const char *proto_name, nl_handler_f handler);
777e5bf684SAlexander V. Chernikov bool netlink_unregister_proto(int proto);
787e5bf684SAlexander V. Chernikov
797e5bf684SAlexander V. Chernikov /* Common helpers */
807e5bf684SAlexander V. Chernikov bool nlp_has_priv(struct nlpcb *nlp, int priv);
81046acc2bSAlexander V. Chernikov struct ucred *nlp_get_cred(struct nlpcb *nlp);
8219e43c16SAlexander V. Chernikov uint32_t nlp_get_pid(const struct nlpcb *nlp);
8304f75b98SAlexander V. Chernikov bool nlp_unconstrained_vnet(const struct nlpcb *nlp);
847e5bf684SAlexander V. Chernikov
857e5bf684SAlexander V. Chernikov /* netlink_generic.c */
867e5bf684SAlexander V. Chernikov struct genl_cmd {
877e5bf684SAlexander V. Chernikov const char *cmd_name;
887e5bf684SAlexander V. Chernikov nl_handler_f cmd_cb;
897e5bf684SAlexander V. Chernikov uint32_t cmd_flags;
907e5bf684SAlexander V. Chernikov uint32_t cmd_priv;
917e5bf684SAlexander V. Chernikov uint32_t cmd_num;
927e5bf684SAlexander V. Chernikov };
937e5bf684SAlexander V. Chernikov
94926d2eadSGleb Smirnoff uint16_t genl_register_family(const char *family_name, size_t hdrsize,
95fe048349SGleb Smirnoff uint16_t family_version, uint16_t max_attr_idx);
96ee507b70SGleb Smirnoff void genl_unregister_family(uint16_t family);
97ee507b70SGleb Smirnoff bool genl_register_cmds(uint16_t family, const struct genl_cmd *cmds,
98ee507b70SGleb Smirnoff u_int count);
99ee507b70SGleb Smirnoff uint32_t genl_register_group(uint16_t family, const char *group_name);
10006cf3651SGleb Smirnoff void genl_unregister_group(uint16_t family, uint32_t group);
1017e5bf684SAlexander V. Chernikov
102ee507b70SGleb Smirnoff typedef void (*genl_family_event_handler_t)(void *arg, const char *family_name,
103ee507b70SGleb Smirnoff uint16_t family_id, u_int action);
10419e43c16SAlexander V. Chernikov EVENTHANDLER_DECLARE(genl_family_event, genl_family_event_handler_t);
1057e5bf684SAlexander V. Chernikov
10630d7e724SAlexander V. Chernikov struct thread;
10730d7e724SAlexander V. Chernikov #if defined(NETLINK) || defined(NETLINK_MODULE)
10830d7e724SAlexander V. Chernikov /* Provide optimized calls to the functions inside the same linking unit */
10930d7e724SAlexander V. Chernikov struct nlpcb *_nl_get_thread_nlp(struct thread *td);
11030d7e724SAlexander V. Chernikov
11130d7e724SAlexander V. Chernikov static inline struct nlpcb *
nl_get_thread_nlp(struct thread * td)11230d7e724SAlexander V. Chernikov nl_get_thread_nlp(struct thread *td)
11330d7e724SAlexander V. Chernikov {
11430d7e724SAlexander V. Chernikov return (_nl_get_thread_nlp(td));
11530d7e724SAlexander V. Chernikov }
11630d7e724SAlexander V. Chernikov
11730d7e724SAlexander V. Chernikov #else
11830d7e724SAlexander V. Chernikov /* Provide access to the functions via netlink_glue.c */
11930d7e724SAlexander V. Chernikov struct nlpcb *nl_get_thread_nlp(struct thread *td);
12030d7e724SAlexander V. Chernikov
12130d7e724SAlexander V. Chernikov #endif /* defined(NETLINK) || defined(NETLINK_MODULE) */
12230d7e724SAlexander V. Chernikov
1237e5bf684SAlexander V. Chernikov #endif
124dddafa8dSAlexander V. Chernikov #endif
125