36#include <netlink-private/netlink.h>
37#include <netlink/netlink.h>
38#include <netlink/utils.h>
39#include <netlink/route/link.h>
40#include <netlink-private/route/link/api.h>
42static NL_LIST_HEAD(info_ops);
45static NL_RW_LOCK(info_lock);
47static struct rtnl_link_info_ops *__rtnl_link_info_ops_lookup(
const char *name)
49 struct rtnl_link_info_ops *ops;
51 nl_list_for_each_entry(ops, &info_ops, io_list)
52 if (!strcmp(ops->io_name, name))
73 struct rtnl_link_info_ops *ops;
75 nl_write_lock(&info_lock);
76 if ((ops = __rtnl_link_info_ops_lookup(name)))
78 nl_write_unlock(&info_lock);
92 nl_write_lock(&info_lock);
94 nl_write_unlock(&info_lock);
106 nl_write_lock(&info_lock);
107 _nl_assert(ops->io_refcnt > 0);
109 nl_write_unlock(&info_lock);
128 if (ops->io_name == NULL)
131 nl_write_lock(&info_lock);
132 if (__rtnl_link_info_ops_lookup(ops->io_name)) {
137 NL_DBG(1,
"Registered link info operations %s\n", ops->io_name);
139 nl_list_add_tail(&ops->io_list, &info_ops);
141 nl_write_unlock(&info_lock);
161 struct rtnl_link_info_ops *t;
162 int err = -NLE_OPNOTSUPP;
164 nl_write_lock(&info_lock);
166 nl_list_for_each_entry(t, &info_ops, io_list) {
168 _nl_assert(t->io_refcnt >= 0);
169 if (t->io_refcnt > 0) {
174 nl_list_del(&t->io_list);
176 NL_DBG(1,
"Unregistered link info operations %s\n",
184 nl_write_unlock(&info_lock);
196static struct rtnl_link_af_ops *af_ops[AF_MAX];
208 if (family == AF_UNSPEC || family >= AF_MAX)
211 nl_write_lock(&info_lock);
213 af_ops[family]->ao_refcnt++;
214 nl_write_unlock(&info_lock);
216 return af_ops[family];
226 nl_write_lock(&info_lock);
228 nl_write_unlock(&info_lock);
247 const struct rtnl_link_af_ops *ops)
254 family = ops->ao_family;
256 if (!link->l_af_data[family]) {
260 link->l_af_data[family] = ops->ao_alloc(link);
261 if (!link->l_af_data[family])
265 return link->l_af_data[family];
282 const struct rtnl_link_af_ops *ops)
287 return link->l_af_data[ops->ao_family];
306 if (ops->ao_family == AF_UNSPEC || ops->ao_family >= AF_MAX)
309 nl_write_lock(&info_lock);
310 if (af_ops[ops->ao_family]) {
316 af_ops[ops->ao_family] = ops;
318 NL_DBG(1,
"Registered link address family operations %u\n",
322 nl_write_unlock(&info_lock);
343 int err = -NLE_INVAL;
348 nl_write_lock(&info_lock);
349 if (!af_ops[ops->ao_family]) {
350 err = -NLE_OBJ_NOTFOUND;
354 if (ops->ao_refcnt > 0) {
359 af_ops[ops->ao_family] = NULL;
361 NL_DBG(1,
"Unregistered link address family operations %u\n",
365 nl_write_unlock(&info_lock);
385 struct rtnl_link_af_ops *af_ops;
388 if (!a->l_af_data[family] && !b->l_af_data[family])
391 if (!a->l_af_data[family] || !b->l_af_data[family])
398 if (af_ops->ao_compare == NULL) {
403 ret = af_ops->ao_compare(a, b, family, ~0, 0);
424 if (a->l_info_ops != b->l_info_ops)
427 if (!a->l_info_ops || !a->l_info_ops->io_compare)
430 return a->l_info_ops->io_compare(a, b, flags);
void rtnl_link_af_ops_put(struct rtnl_link_af_ops *ops)
Give back reference to a set of operations.
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
void * rtnl_link_af_alloc(struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Allocate and return data buffer for link address family modules.
int rtnl_link_info_data_compare(struct rtnl_link *a, struct rtnl_link *b, int flags)
Compare link info data.
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
void rtnl_link_info_ops_get(struct rtnl_link_info_ops *ops)
Take reference to a set of operations.
int rtnl_link_af_unregister(struct rtnl_link_af_ops *ops)
Unregister operations for a link address family.
int rtnl_link_af_register(struct rtnl_link_af_ops *ops)
Register operations for a link address family.
struct rtnl_link_info_ops * rtnl_link_info_ops_lookup(const char *name)
Return operations of a specific link info type.
int rtnl_link_af_data_compare(struct rtnl_link *a, struct rtnl_link *b, int family)
Compare af data for a link address family.
void rtnl_link_info_ops_put(struct rtnl_link_info_ops *ops)
Give back reference to a set of operations.
struct rtnl_link_af_ops * rtnl_link_af_ops_lookup(const unsigned int family)
Return operations of a specific link address family.
void * rtnl_link_af_data(const struct rtnl_link *link, const struct rtnl_link_af_ops *ops)
Return data buffer for link address family modules.