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
|
||||
|
||||
NLOBJ=ll_map.o libnetlink.o
|
||||
NLOBJ=libgenl.o ll_map.o libnetlink.o
|
||||
|
||||
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