mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-17 06:53:26 +08:00
iproute2: add libgenl files
Create libgenl.h and libgenl.c. They will contain common code for GENL users such as ipl2tp, tcp_metrics, etc. Somewhat simplified by Stephen Hemminger Signed-off-by: Julian Anastasov <ja@ssi.bg>
This commit is contained in:
parent
8325daf7de
commit
8afcc28879
28
include/libgenl.h
Normal file
28
include/libgenl.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __LIBGENL_H__
|
||||||
|
#define __LIBGENL_H__
|
||||||
|
|
||||||
|
#include "libnetlink.h"
|
||||||
|
|
||||||
|
#define GENL_REQUEST(_req, _hdrsiz, _bufsiz) \
|
||||||
|
struct { \
|
||||||
|
struct nlmsghdr n; \
|
||||||
|
struct genlmsghdr g; \
|
||||||
|
char buf[NLMSG_ALIGN(_hdrsiz) + (_bufsiz)]; \
|
||||||
|
} _req
|
||||||
|
|
||||||
|
#define GENL_INITIALIZER(_family, _hdrsiz, _ver, _cmd, _flags) \
|
||||||
|
{ \
|
||||||
|
.n = { \
|
||||||
|
.nlmsg_type = (_family), \
|
||||||
|
.nlmsg_flags = (_flags), \
|
||||||
|
.nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN + (_hdrsiz)), \
|
||||||
|
}, \
|
||||||
|
.g = { \
|
||||||
|
.cmd = (_cmd), \
|
||||||
|
.version = (_ver), \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
extern int genl_resolve_family(struct rtnl_handle *grth, const char *family);
|
||||||
|
|
||||||
|
#endif /* __LIBGENL_H__ */
|
@ -2,7 +2,7 @@ CFLAGS += -fPIC
|
|||||||
|
|
||||||
UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
|
UTILOBJ=utils.o rt_names.o ll_types.o ll_proto.o ll_addr.o inet_proto.o
|
||||||
|
|
||||||
NLOBJ=ll_map.o libnetlink.o
|
NLOBJ=libgenl.o ll_map.o libnetlink.o
|
||||||
|
|
||||||
all: libnetlink.a libutil.a
|
all: libnetlink.a libutil.a
|
||||||
|
|
||||||
|
64
lib/libgenl.c
Normal file
64
lib/libgenl.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* libgenl.c GENL library
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <linux/genetlink.h>
|
||||||
|
#include "libgenl.h"
|
||||||
|
|
||||||
|
static int genl_parse_getfamily(struct nlmsghdr *nlh)
|
||||||
|
{
|
||||||
|
struct rtattr *tb[CTRL_ATTR_MAX + 1];
|
||||||
|
struct genlmsghdr *ghdr = NLMSG_DATA(nlh);
|
||||||
|
int len = nlh->nlmsg_len;
|
||||||
|
struct rtattr *attrs;
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type != GENL_ID_CTRL) {
|
||||||
|
fprintf(stderr, "Not a controller message, nlmsg_len=%d "
|
||||||
|
"nlmsg_type=0x%x\n", nlh->nlmsg_len, nlh->nlmsg_type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
len -= NLMSG_LENGTH(GENL_HDRLEN);
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
fprintf(stderr, "wrong controller message len %d\n", len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ghdr->cmd != CTRL_CMD_NEWFAMILY) {
|
||||||
|
fprintf(stderr, "Unknown controller command %d\n", ghdr->cmd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
attrs = (struct rtattr *) ((char *) ghdr + GENL_HDRLEN);
|
||||||
|
parse_rtattr(tb, CTRL_ATTR_MAX, attrs, len);
|
||||||
|
|
||||||
|
if (tb[CTRL_ATTR_FAMILY_ID] == NULL) {
|
||||||
|
fprintf(stderr, "Missing family id TLV\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rta_getattr_u16(tb[CTRL_ATTR_FAMILY_ID]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int genl_resolve_family(struct rtnl_handle *grth, const char *family)
|
||||||
|
{
|
||||||
|
GENL_REQUEST(req, 0, 1024)
|
||||||
|
= GENL_INITIALIZER(GENL_ID_CTRL, 0,
|
||||||
|
0, CTRL_CMD_GETFAMILY, NLM_F_REQUEST);
|
||||||
|
|
||||||
|
addattr_l(&req.n, 1024, CTRL_ATTR_FAMILY_NAME,
|
||||||
|
family, strlen(family) + 1);
|
||||||
|
|
||||||
|
if (rtnl_talk(grth, &req.n, 0, 0, &req.n) < 0) {
|
||||||
|
fprintf(stderr, "Error talking to the kernel\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return genl_parse_getfamily(&req.n);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user