dect
/
libnl
Archived
13
0
Fork 0

Merge branch 'master' of /repos/git/libnl

Conflicts:
	lib/Makefile.am
	src/Makefile.am

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-10-15 04:16:08 +02:00
commit ac50c84f8c
34 changed files with 691 additions and 41 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
*.la
*.lo
*.o
*.swp
Makefile
/lib/stamp-h1

View File

@ -2,9 +2,18 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = include lib src doc
OPT_DIRS =
pkgconfig_DATA = libnl-2.0.pc
if ENABLE_CLI
OPT_DIRS += src
endif
SUBDIRS = include lib doc $(OPT_DIRS)
pkgconfig_DATA = libnl-2.1.pc
sysconfdir = @sysconfdir@/libnl
sysconf_DATA = etc/pktloc
.PHONY: cscope
cscope:

View File

@ -6,10 +6,10 @@
# License as published by the Free Software Foundation version 2.1
# of the License.
#
# Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
# Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
#
AC_INIT(libnl, 2.0, tgraf@suug.ch)
AC_INIT(libnl, 2.1, tgraf@suug.ch)
AC_CONFIG_HEADERS([lib/defs.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
@ -18,6 +18,8 @@ AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_INSTALL
AM_PROG_LIBTOOL
AM_PROG_LEX
AC_PROG_YACC
AC_C_CONST
AC_C_INLINE
@ -27,9 +29,14 @@ AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
AC_SUBST([pkgconfigdir])
AC_ARG_ENABLE([cli],
AS_HELP_STRING([--disable-cli], [Do not build command line interface utils]),
[enable_cli="$enableval"], [enable_cli="yes"])
AM_CONDITIONAL([ENABLE_CLI], [test "$enable_cli" = "yes"])
AC_CHECK_LIB([m], [pow], [], AC_MSG_ERROR([libm is required]))
AC_CONFIG_FILES([Makefile doc/Doxyfile doc/Makefile lib/Makefile
include/Makefile src/Makefile src/lib/Makefile \
libnl-2.0.pc include/netlink/version.h])
libnl-2.1.pc include/netlink/version.h])
AC_OUTPUT

44
etc/pktloc Normal file
View File

@ -0,0 +1,44 @@
#
# Location definitions for packet matching
#
# name alignment offset mask
ip.version u8 net+0 0xF0
ip.hdrlen u8 net+0 0x0F
ip.diffserv u8 net+1
ip.length u16 net+2
ip.id u16 net+4
ip.df u8 net+6 0x40
ip.mf u8 net+6 0x20
ip.offset u16 net+6 0x1FFF
ip.ttl u8 net+8
ip.proto u8 net+9
ip.chksum u16 net+10
ip.src u32 net+12
ip.dst u32 net+16
#
# Transmission Control Protocol (TCP)
#
# name alignment offset mask
tcp.sport u16 tcp+0
tcp.dport u16 tcp+2
tcp.seq u32 tcp+4
tcp.ack u32 tcp+8
tcp.off u8 tcp+12 0xF0
tcp.reserved u8 tcp+12 0x0F
# FLAGS
tcp.win u16 tcp+14
tcp.csum u16 tcp+16
tcp.urg u16 tcp+18
tcp.opts u32 tcp+20
#
# User Datagram Protocol (UDP)
#
# name alignment offset mask
udp.sport u16 tcp+0
udp.dport u16 tcp+2
udp.length u16 tcp+4
udp.csum u16 tcp+6

View File

@ -1,6 +1,7 @@
#ifndef __LINUX_GENERIC_NETLINK_H
#define __LINUX_GENERIC_NETLINK_H
#include <linux/types.h>
#include <linux/netlink.h>
#define GENL_NAMSIZ 16 /* length of family name */
@ -39,6 +40,9 @@ enum {
CTRL_CMD_NEWOPS,
CTRL_CMD_DELOPS,
CTRL_CMD_GETOPS,
CTRL_CMD_NEWMCAST_GRP,
CTRL_CMD_DELMCAST_GRP,
CTRL_CMD_GETMCAST_GRP, /* unused */
__CTRL_CMD_MAX,
};
@ -52,6 +56,7 @@ enum {
CTRL_ATTR_HDRSIZE,
CTRL_ATTR_MAXATTR,
CTRL_ATTR_OPS,
CTRL_ATTR_MCAST_GROUPS,
__CTRL_ATTR_MAX,
};
@ -66,4 +71,13 @@ enum {
#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
enum {
CTRL_ATTR_MCAST_GRP_UNSPEC,
CTRL_ATTR_MCAST_GRP_NAME,
CTRL_ATTR_MCAST_GRP_ID,
__CTRL_ATTR_MCAST_GRP_MAX,
};
#define CTRL_ATTR_MCAST_GRP_MAX (__CTRL_ATTR_MCAST_GRP_MAX - 1)
#endif /* __LINUX_GENERIC_NETLINK_H */

View File

@ -23,6 +23,7 @@
#include <stdarg.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <inttypes.h>
#include <assert.h>

View File

@ -83,6 +83,7 @@ struct nl_cache_assoc
{
struct nl_cache * ca_cache;
change_func_t ca_change;
void * ca_change_data;
};
struct nl_cache_mngr
@ -701,6 +702,13 @@ struct genl_family_op
struct nl_list_head o_list;
};
struct genl_family_grp {
struct genl_family *family; /* private */
struct nl_list_head list; /* private */
char name[GENL_NAMSIZ];
u_int32_t id;
};
struct genl_family
{
NLHDR_COMMON
@ -712,6 +720,7 @@ struct genl_family
uint32_t gf_maxattr;
struct nl_list_head gf_ops;
struct nl_list_head gf_mc_grps;
};
union nfnl_ct_proto

View File

@ -24,7 +24,7 @@ extern "C" {
struct nl_cache;
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int);
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
/* Access Functions */
extern int nl_cache_nitems(struct nl_cache *);
@ -59,10 +59,12 @@ extern int nl_cache_pickup(struct nl_sock *,
struct nl_cache *);
extern int nl_cache_resync(struct nl_sock *,
struct nl_cache *,
change_func_t);
change_func_t,
void *);
extern int nl_cache_include(struct nl_cache *,
struct nl_object *,
change_func_t);
change_func_t,
void *);
/* General */
extern int nl_cache_is_empty(struct nl_cache *);
@ -112,6 +114,7 @@ extern int nl_cache_mngr_alloc(struct nl_sock *,
extern int nl_cache_mngr_add(struct nl_cache_mngr *,
const char *,
change_func_t,
void *,
struct nl_cache **);
extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *);
extern int nl_cache_mngr_poll(struct nl_cache_mngr *,

View File

@ -45,8 +45,9 @@ extern "C" {
#define NLE_PROTO_MISMATCH 26
#define NLE_NOACCESS 27
#define NLE_PERM 28
#define NLE_PKTLOC_FILE 29
#define NLE_MAX NLE_PERM
#define NLE_MAX NLE_PKTLOC_FILE
extern const char * nl_geterror(int);
extern void nl_perror(int, const char *);

View File

@ -29,6 +29,9 @@ extern struct genl_family * genl_ctrl_search_by_name(struct nl_cache *,
const char *);
extern int genl_ctrl_resolve(struct nl_sock *,
const char *);
extern int genl_ctrl_resolve_grp(struct nl_sock *sk,
const char *family,
const char *grp);
#ifdef __cplusplus
}

View File

@ -42,6 +42,9 @@ extern void genl_family_set_maxattr(struct genl_family *,
extern int genl_family_add_op(struct genl_family *,
int, int);
extern int genl_family_add_grp(struct genl_family *,
uint32_t , const char *);
#ifdef __cplusplus
}

View File

@ -21,7 +21,6 @@ extern "C" {
#endif
extern int genl_connect(struct nl_sock *);
extern int genl_send_simple(struct nl_sock *, int, int,
int, int);

View File

@ -52,7 +52,7 @@ extern int nl_sendmsg(struct nl_sock *, struct nl_msg *,
struct msghdr *);
extern int nl_send(struct nl_sock *, struct nl_msg *);
extern int nl_send_iovec(struct nl_sock *, struct nl_msg *,
const struct iovec *, unsigned);
struct iovec *, unsigned);
extern void nl_auto_complete(struct nl_sock *,
struct nl_msg *);
extern int nl_send_auto_complete(struct nl_sock *,

View File

@ -0,0 +1,44 @@
/*
* netlink/route/pktloc.h Packet Location Aliasing
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_PKTLOC_H_
#define NETLINK_PKTLOC_H_
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/route/tc.h>
#include <linux/tc_ematch/tc_em_cmp.h>
#ifdef __cplusplus
extern "C" {
#endif
struct rtnl_pktloc
{
char * name;
uint8_t align:4;
uint8_t layer:4;
uint8_t flags;
uint16_t offset;
uint32_t mask;
struct nl_list_head list;
};
extern int rtnl_pktloc_lookup(const char *, struct rtnl_pktloc **);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -37,7 +37,8 @@ extern void nl_join_groups(struct nl_sock *, int);
extern uint32_t nl_socket_get_peer_port(struct nl_sock *);
extern void nl_socket_set_peer_port(struct nl_sock *,
uint32_t);
extern uint32_t nl_socket_get_peer_groups(struct nl_sock *sk);
extern void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups);
extern struct nl_cb * nl_socket_get_cb(struct nl_sock *);
extern void nl_socket_set_cb(struct nl_sock *,
struct nl_cb *);

View File

@ -1,21 +1,19 @@
# -*- Makefile -*-
AM_CFLAGS = -Wall -I${top_srcdir}/include -D_GNU_SOURCE
AM_CPPFLAGS = -Wall -I${top_srcdir}/include -I${top_builddir}/include -D_GNU_SOURCE -DSYSCONFDIR=\"$(sysconfdir)/libnl\"
AM_LDFLAGS = -version-info 3:0:0
lib_LTLIBRARIES = \
libnl.la libnl-genl.la libnl-route.la libnl-nf.la libnl-dect.la
libnl_la_LDFLAGS = -version-info 2:0:0
libnl_la_SOURCES = \
addr.c attr.c cache.c cache_mngr.c cache_mngt.c data.c doc.c \
error.c handlers.c msg.c nl.c object.c socket.c utils.c
libnl_genl_la_LDFLAGS = -version-info 2:0:0
libnl_genl_la_LIBADD = libnl.la
libnl_genl_la_SOURCES = \
genl/ctrl.c genl/family.c genl/genl.c genl/mngt.c
libnl_nf_la_LDFLAGS = -version-info 2:0:0
libnl_nf_la_LIBADD = libnl-route.la
libnl_nf_la_SOURCES = \
netfilter/ct.c netfilter/ct_obj.c netfilter/log.c \
@ -23,7 +21,18 @@ libnl_nf_la_SOURCES = \
netfilter/netfilter.c netfilter/nfnl.c netfilter/queue.c \
netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c
libnl_route_la_LDFLAGS = -version-info 2:0:0
CLEANFILES = \
route/pktloc_grammar.c route/pktloc_grammar.h \
route/pktloc_syntax.c route/pktloc_syntax.h
# Hack to avoid using ylwrap. It does not function correctly in combination
# with --header-file=
route/pktloc_grammar.c: route/pktloc_grammar.l
$(LEX) --header-file=route/pktloc_grammar.h $(LFLAGS) -o $@ $^
route/pktloc_syntax.c: route/pktloc_syntax.y
$(YACC) -d $(YFLAGS) -o $@ $^
libnl_route_la_LIBADD = libnl.la
libnl_route_la_SOURCES = \
route/addr.c route/class.c route/class_api.c route/class_obj.c \
@ -40,10 +49,12 @@ libnl_route_la_SOURCES = \
route/sch/fifo.c route/sch/htb.c route/sch/netem.c route/sch/prio.c \
route/sch/red.c route/sch/sfq.c route/sch/tbf.c \
\
fib_lookup/lookup.c fib_lookup/request.c
fib_lookup/lookup.c fib_lookup/request.c \
\
route/pktloc_syntax.c route/pktloc_grammar.c route/pktloc.c
libnl_dect_la_LDFLAGS = -version-info 2:0:0
libnl_dect_la_LIBADD = libnl.la
libnl_dect_la_SOURCES = \
dect/ari.c dect/cell.c dect/cell_obj.c dect/cluster.c dect/cluster_obj.c \
dect/dect.c dect/llme.c dect/transceiver.c dect/transceiver_obj.c
dect/ari.c dect/cell.c dect/cell_obj.c \
dect/cluster.c dect/cluster_obj.c dect/dect.c dect/llme.c \
dect/transceiver.c dect/transceiver_obj.c

View File

@ -517,7 +517,7 @@ int nl_cache_pickup(struct nl_sock *sk, struct nl_cache *cache)
}
static int cache_include(struct nl_cache *cache, struct nl_object *obj,
struct nl_msgtype *type, change_func_t cb)
struct nl_msgtype *type, change_func_t cb, void *data)
{
struct nl_object *old;
@ -529,7 +529,7 @@ static int cache_include(struct nl_cache *cache, struct nl_object *obj,
nl_cache_remove(old);
if (type->mt_act == NL_ACT_DEL) {
if (cb)
cb(cache, old, NL_ACT_DEL);
cb(cache, old, NL_ACT_DEL, data);
nl_object_put(old);
}
}
@ -537,10 +537,10 @@ static int cache_include(struct nl_cache *cache, struct nl_object *obj,
if (type->mt_act == NL_ACT_NEW) {
nl_cache_move(cache, obj);
if (old == NULL && cb)
cb(cache, obj, NL_ACT_NEW);
cb(cache, obj, NL_ACT_NEW, data);
else if (old) {
if (nl_object_diff(old, obj) && cb)
cb(cache, obj, NL_ACT_CHANGE);
cb(cache, obj, NL_ACT_CHANGE, data);
nl_object_put(old);
}
@ -555,7 +555,7 @@ static int cache_include(struct nl_cache *cache, struct nl_object *obj,
}
int nl_cache_include(struct nl_cache *cache, struct nl_object *obj,
change_func_t change_cb)
change_func_t change_cb, void *data)
{
struct nl_cache_ops *ops = cache->c_ops;
int i;
@ -566,7 +566,7 @@ int nl_cache_include(struct nl_cache *cache, struct nl_object *obj,
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
if (ops->co_msgtypes[i].mt_id == obj->ce_msgtype)
return cache_include(cache, obj, &ops->co_msgtypes[i],
change_cb);
change_cb, data);
return -NLE_MSGTYPE_NOSUPPORT;
}
@ -575,16 +575,17 @@ static int resync_cb(struct nl_object *c, struct nl_parser_param *p)
{
struct nl_cache_assoc *ca = p->pp_arg;
return nl_cache_include(ca->ca_cache, c, ca->ca_change);
return nl_cache_include(ca->ca_cache, c, ca->ca_change, ca->ca_change_data);
}
int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache,
change_func_t change_cb)
change_func_t change_cb, void *data)
{
struct nl_object *obj, *next;
struct nl_cache_assoc ca = {
.ca_cache = cache,
.ca_change = change_cb,
.ca_change_data = data,
};
struct nl_parser_param p = {
.pp_cb = resync_cb,
@ -610,7 +611,7 @@ int nl_cache_resync(struct nl_sock *sk, struct nl_cache *cache,
nl_object_get(obj);
nl_cache_remove(obj);
if (change_cb)
change_cb(cache, obj, NL_ACT_DEL);
change_cb(cache, obj, NL_ACT_DEL, data);
nl_object_put(obj);
}
}

View File

@ -95,7 +95,7 @@ static int include_cb(struct nl_object *obj, struct nl_parser_param *p)
if (nl_debug >= 4)
nl_object_dump(obj, &nl_debug_dp);
#endif
return nl_cache_include(ca->ca_cache, obj, ca->ca_change);
return nl_cache_include(ca->ca_cache, obj, ca->ca_change, ca->ca_change_data);
}
static int event_input(struct nl_msg *msg, void *arg)
@ -207,7 +207,7 @@ errout:
* @return 0 on success or a negative error code.
*/
int nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
change_func_t cb, struct nl_cache **result)
change_func_t cb, void *data, struct nl_cache **result)
{
struct nl_cache_ops *ops;
struct nl_cache *cache;
@ -264,6 +264,7 @@ retry:
mngr->cm_assocs[i].ca_cache = cache;
mngr->cm_assocs[i].ca_change = cb;
mngr->cm_assocs[i].ca_change_data = data;
if (mngr->cm_flags & NL_AUTO_PROVIDE)
nl_cache_mngt_provide(cache);

View File

@ -42,6 +42,7 @@ static const char *errmsg[NLE_MAX+1] = {
[NLE_PROTO_MISMATCH] = "Protocol mismatch",
[NLE_NOACCESS] = "No Access",
[NLE_PERM] = "Operation not permitted",
[NLE_PKTLOC_FILE] = "Unable to open packet location file",
};
/**

View File

@ -45,6 +45,7 @@ static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
[CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 },
[CTRL_ATTR_MAXATTR] = { .type = NLA_U32 },
[CTRL_ATTR_OPS] = { .type = NLA_NESTED },
[CTRL_ATTR_MCAST_GROUPS] = { .type = NLA_NESTED },
};
static struct nla_policy family_op_policy[CTRL_ATTR_OP_MAX+1] = {
@ -52,6 +53,11 @@ static struct nla_policy family_op_policy[CTRL_ATTR_OP_MAX+1] = {
[CTRL_ATTR_OP_FLAGS] = { .type = NLA_U32 },
};
static struct nla_policy family_grp_policy[CTRL_ATTR_MCAST_GRP_MAX+1] = {
[CTRL_ATTR_MCAST_GRP_NAME] = { .type = NLA_STRING },
[CTRL_ATTR_MCAST_GRP_ID] = { .type = NLA_U32 },
};
static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd,
struct genl_info *info, void *arg)
{
@ -126,6 +132,40 @@ static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd,
}
}
if (info->attrs[CTRL_ATTR_MCAST_GROUPS]) {
struct nlattr *nla, *nla_grps;
int remaining;
nla_grps = info->attrs[CTRL_ATTR_MCAST_GROUPS];
nla_for_each_nested(nla, nla_grps, remaining) {
struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1];
int id;
const char * name;
err = nla_parse_nested(tb, CTRL_ATTR_MCAST_GRP_MAX, nla,
family_grp_policy);
if (err < 0)
goto errout;
if (tb[CTRL_ATTR_MCAST_GRP_ID] == NULL) {
err = -NLE_MISSING_ATTR;
goto errout;
}
id = nla_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]);
if (tb[CTRL_ATTR_MCAST_GRP_NAME] == NULL) {
err = -NLE_MISSING_ATTR;
goto errout;
}
name = nla_get_string(tb[CTRL_ATTR_MCAST_GRP_NAME]);
err = genl_family_add_grp(family, id, name);
if (err < 0)
goto errout;
}
}
err = pp->pp_cb((struct nl_object *) family, pp);
errout:
@ -242,6 +282,44 @@ errout:
return err;
}
static int genl_ctrl_grp_by_name(const struct genl_family *family,
const char *grp_name)
{
struct genl_family_grp *grp;
nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
if (!strcmp(grp->name, grp_name)) {
return grp->id;
}
}
return 0;
}
int genl_ctrl_resolve_grp(struct nl_sock *sk, const char *family_name,
const char *grp_name)
{
struct nl_cache *cache;
struct genl_family *family;
int err;
if ((err = genl_ctrl_alloc_cache(sk, &cache)) < 0)
return err;
family = genl_ctrl_search_by_name(cache, family_name);
if (family == NULL) {
err = -NLE_OBJ_NOTFOUND;
goto errout;
}
err = genl_ctrl_grp_by_name(family, grp_name);
genl_family_put(family);
errout:
nl_cache_free(cache);
return err;
}
/** @} */
static struct genl_cmd genl_cmds[] = {

View File

@ -39,12 +39,14 @@ static void family_constructor(struct nl_object *c)
struct genl_family *family = (struct genl_family *) c;
nl_init_list_head(&family->gf_ops);
nl_init_list_head(&family->gf_mc_grps);
}
static void family_free_data(struct nl_object *c)
{
struct genl_family *family = (struct genl_family *) c;
struct genl_family_op *ops, *tmp;
struct genl_family_grp *grp, *t_grp;
if (family == NULL)
return;
@ -53,6 +55,12 @@ static void family_free_data(struct nl_object *c)
nl_list_del(&ops->o_list);
free(ops);
}
nl_list_for_each_entry_safe(grp, t_grp, &family->gf_mc_grps, list) {
nl_list_del(&grp->list);
free(grp);
}
}
static int family_clone(struct nl_object *_dst, struct nl_object *_src)
@ -60,6 +68,7 @@ static int family_clone(struct nl_object *_dst, struct nl_object *_src)
struct genl_family *dst = nl_object_priv(_dst);
struct genl_family *src = nl_object_priv(_src);
struct genl_family_op *ops;
struct genl_family_grp *grp;
int err;
nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
@ -67,6 +76,13 @@ static int family_clone(struct nl_object *_dst, struct nl_object *_src)
if (err < 0)
return err;
}
nl_list_for_each_entry(grp, &src->gf_mc_grps, list) {
err = genl_family_add_grp(dst, grp->id, grp->name);
if (err < 0)
return err;
}
return 0;
}
@ -93,6 +109,7 @@ static char *ops_flags2str(int flags, char *buf, size_t len)
static void family_dump_details(struct nl_object *obj, struct nl_dump_params *p)
{
struct genl_family_grp *grp;
struct genl_family *family = (struct genl_family *) obj;
family_dump_line(obj, p);
@ -118,6 +135,11 @@ static void family_dump_details(struct nl_object *obj, struct nl_dump_params *p)
nl_dump(p, "\n");
}
}
nl_list_for_each_entry(grp, &family->gf_mc_grps, list) {
nl_dump_line(p, " grp %s (0x%02x)\n", grp->name, grp->id);
}
}
static void family_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
@ -255,6 +277,23 @@ int genl_family_add_op(struct genl_family *family, int id, int flags)
return 0;
}
int genl_family_add_grp(struct genl_family *family, uint32_t id,
const char *name)
{
struct genl_family_grp *grp;
grp = calloc(1, sizeof(*grp));
if (grp == NULL)
return -NLE_NOMEM;
grp->id = id;
strncpy(grp->name, name, GENL_NAMSIZ - 1);
nl_list_add_tail(&grp->list, &family->gf_mc_grps);
return 0;
}
/** @} */
/** @cond SKIP */

View File

@ -232,7 +232,7 @@ int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
* @see nl_sendmsg()
* @return Number of characters sent on success or a negative error code.
*/
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, const struct iovec *iov, unsigned iovlen)
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
{
struct sockaddr_nl *dst;
struct ucred *creds;
@ -387,7 +387,7 @@ errout:
* Receives a netlink message, allocates a buffer in \c *buf and
* stores the message content. The peer's netlink address is stored
* in \c *nla. The caller is responsible for freeing the buffer allocated
* in \c *buf if a positive value is returned. Interruped system calls
* in \c *buf if a positive value is returned. Interrupted system calls
* are handled by repeating the read. The input buffer size is determined
* by peeking before the actual read is done.
*

4
lib/route/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
pktloc_grammar.h
pktloc_grammar.c
pktloc_syntax.h
pktloc_syntax.c

168
lib/route/pktloc.c Normal file
View File

@ -0,0 +1,168 @@
/*
* lib/route/pktloc.c Packet Location Aliasing
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2 of the License.
*
* Copyright (c) 2008-2010 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup tc
* @defgroup pktloc Packet Location Aliasing
* Packet Location Aliasing
*
* The packet location aliasing interface eases the use of offset definitions
* inside packets by allowing them to be referenced by name. Known positions
* of protocol fields are stored in a configuration file and associated with
* a name for later reference. The configuration file is distributed with the
* library and provides a well defined set of definitions for most common
* protocol fields.
*
* @subsection pktloc_examples Examples
* @par Example 1.1 Looking up a packet location
* @code
* struct rtnl_pktloc *loc;
*
* rtnl_pktloc_lookup("ip.src", &loc);
* @endcode
* @{
*/
#include <netlink-local.h>
#include <netlink-tc.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/pktloc.h>
#include "pktloc_syntax.h"
#include "pktloc_grammar.h"
/** @cond */
#define PKTLOC_NAME_HT_SIZ 256
static struct nl_list_head pktloc_name_ht[PKTLOC_NAME_HT_SIZ];
/* djb2 */
unsigned int pktloc_hash(const char *str)
{
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash % PKTLOC_NAME_HT_SIZ;
}
void rtnl_pktloc_add(struct rtnl_pktloc *loc)
{
nl_list_add_tail(&loc->list, &pktloc_name_ht[pktloc_hash(loc->name)]);
}
extern int pktloc_parse(void *scanner);
/** @endcond */
static void rtnl_pktloc_free(struct rtnl_pktloc *loc)
{
if (!loc)
return;
free(loc->name);
free(loc);
}
static int read_pktlocs(void)
{
YY_BUFFER_STATE buf;
yyscan_t scanner = NULL;
static time_t last_read;
struct stat st = {0};
char *path;
int i, err;
FILE *fd;
asprintf(&path, "%s/pktloc", SYSCONFDIR);
/* if stat fails, just try to read the file */
if (stat(path, &st) == 0) {
/* Don't re-read file if file is unchanged */
if (last_read == st.st_mtime)
return 0;
}
if (!(fd = fopen(path, "r")))
return -NLE_PKTLOC_FILE;
for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++) {
struct rtnl_pktloc *loc, *n;
nl_list_for_each_entry_safe(loc, n, &pktloc_name_ht[i], list)
rtnl_pktloc_free(loc);
nl_init_list_head(&pktloc_name_ht[i]);
}
if ((err = pktloc_lex_init(&scanner)) < 0)
return -NLE_FAILURE;
buf = pktloc__create_buffer(fd, YY_BUF_SIZE, scanner);
pktloc__switch_to_buffer(buf, scanner);
if ((err = pktloc_parse(scanner)) < 0)
return -NLE_FAILURE;
if (scanner)
pktloc_lex_destroy(scanner);
free(path);
last_read = st.st_mtime;
return 0;
}
/**
* Lookup packet location alias
* @arg name Name of packet location.
*
* Tries to find a matching packet location alias for the supplied
* packet location name.
*
* The file containing the packet location definitions is automatically
* re-read if its modification time has changed since the last call.
*
* @return 0 on success or a negative error code.
* @retval NLE_PKTLOC_FILE Unable to open packet location file.
* @retval NLE_OBJ_NOTFOUND No matching packet location alias found.
*/
int rtnl_pktloc_lookup(const char *name, struct rtnl_pktloc **result)
{
struct rtnl_pktloc *loc;
int hash, err;
if ((err = read_pktlocs()) < 0)
return err;
hash = pktloc_hash(name);
nl_list_for_each_entry(loc, &pktloc_name_ht[hash], list) {
if (!strcasecmp(loc->name, name)) {
*result = loc;
return 0;
}
}
return -NLE_OBJ_NOTFOUND;
}
static int __init pktloc_init(void)
{
int i;
for (i = 0; i < PKTLOC_NAME_HT_SIZ; i++)
nl_init_list_head(&pktloc_name_ht[i]);
return 0;
}

View File

@ -0,0 +1,42 @@
%{
#include <netlink-local.h>
#include <netlink-tc.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/pktloc.h>
#include "pktloc_syntax.h"
%}
%option 8bit
%option reentrant
%option warn
%option noyywrap
%option nounput
%option bison-bridge
%option bison-locations
%option prefix="pktloc_"
%%
[ \t\r\n]+
"#".*
[[:digit:]]+ |
0[xX][[:xdigit:]]+ {
yylval->i = strtoul(yytext, NULL, 0);
return NUMBER;
}
"+" { return yylval->i = yytext[0]; }
[lL][iI][nN][kK] { yylval->i = TCF_LAYER_LINK; return LAYER; }
[nN][eE][tT] { yylval->i = TCF_LAYER_NETWORK; return LAYER; }
[tT][cC][pP] { yylval->i = TCF_LAYER_TRANSPORT; return LAYER; }
[^ \t\r\n+]+ {
yylval->s = strdup(yytext);
if (yylval->s == NULL)
return ERROR;
return NAME;
}

108
lib/route/pktloc_syntax.y Normal file
View File

@ -0,0 +1,108 @@
%{
#include <netlink-local.h>
#include <netlink-tc.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/route/pktloc.h>
%}
%locations
%error-verbose
%define api.pure
%name-prefix "pktloc_"
%parse-param {void *scanner}
%lex-param {void *scanner}
%union {
struct rtnl_pktloc *l;
uint32_t i;
char *s;
}
%{
extern int pktloc_lex(YYSTYPE *, YYLTYPE *, void *);
extern void rtnl_pktloc_add(struct rtnl_pktloc *);
static void yyerror(YYLTYPE *locp, void *scanner, const char *msg)
{
/* FIXME */
}
%}
%token <i> ERROR NUMBER LAYER
%token <s> NAME
%type <i> mask layer
%type <l> location
%destructor { free($$); } NAME
%start input
%%
input:
def
{ }
;
def:
/* empty */
{ }
| location def
{ }
;
location:
NAME NAME layer NUMBER mask
{
struct rtnl_pktloc *loc;
if (!(loc = calloc(1, sizeof(*loc)))) {
/* FIXME */
}
if (!strcasecmp($2, "u8"))
loc->align = TCF_EM_ALIGN_U8;
else if (!strcasecmp($2, "h8")) {
loc->align = TCF_EM_ALIGN_U8;
loc->flags = TCF_EM_CMP_TRANS;
} else if (!strcasecmp($2, "u16"))
loc->align = TCF_EM_ALIGN_U16;
else if (!strcasecmp($2, "h16")) {
loc->align = TCF_EM_ALIGN_U16;
loc->flags = TCF_EM_CMP_TRANS;
} else if (!strcasecmp($2, "u32"))
loc->align = TCF_EM_ALIGN_U32;
else if (!strcasecmp($2, "h32")) {
loc->align = TCF_EM_ALIGN_U32;
loc->flags = TCF_EM_CMP_TRANS;
}
free($2);
loc->name = $1;
loc->layer = $3;
loc->offset = $4;
loc->mask = $5;
rtnl_pktloc_add(loc);
$$ = loc;
}
;
layer:
/* empty */
{ $$ = TCF_LAYER_NETWORK; }
| LAYER '+'
{ $$ = $1; }
;
mask:
/* empty */
{ $$ = 0; }
| NUMBER
{ $$ = $1; }
;

View File

@ -1108,7 +1108,8 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
* required to allow more than 256 tables. */
NLA_PUT_U32(msg, RTA_TABLE, route->rt_table);
NLA_PUT_ADDR(msg, RTA_DST, route->rt_dst);
if (nl_addr_get_len(route->rt_dst))
NLA_PUT_ADDR(msg, RTA_DST, route->rt_dst);
NLA_PUT_U32(msg, RTA_PRIORITY, route->rt_prio);
if (route->ce_mask & ROUTE_ATTR_SRC)

View File

@ -93,6 +93,11 @@ static int tbf_msg_parser(struct rtnl_qdisc *q)
return 0;
}
static void tbf_free_data(struct rtnl_qdisc *qdisc)
{
free(qdisc->q_subdata);
}
static void tbf_dump_line(struct rtnl_qdisc *qdisc, struct nl_dump_params *p)
{
double r, rbit, lim;
@ -517,6 +522,7 @@ static struct rtnl_qdisc_ops tbf_qdisc_ops = {
[NL_DUMP_LINE] = tbf_dump_line,
[NL_DUMP_DETAILS] = tbf_dump_details,
},
.qo_free_data = tbf_free_data,
.qo_get_opts = tbf_get_opts,
};

View File

@ -398,6 +398,18 @@ void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port)
sk->s_peer.nl_pid = port;
}
uint32_t nl_socket_get_peer_groups(struct nl_sock *sk)
{
return sk->s_peer.nl_groups;
}
void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups)
{
sk->s_peer.nl_groups = groups;
}
/** @} */
/**

View File

@ -316,7 +316,7 @@ static void __init get_psched_settings(void)
uint32_t tick, us;
/* the file contains 4 hexadecimals, but we just use
the first two of them */
int r = fscanf(fd, "%08x %08x", &tick, &us);
fscanf(fd, "%08x %08x", &tick, &us);
ticks_per_usec = (double)tick/(double)us;
fclose(fd);
}

View File

@ -2,7 +2,7 @@
SUBDIRS = lib
AM_CFLAGS = -Wall -I${top_srcdir}/include -D_GNU_SOURCE
AM_CPPFLAGS = -Wall -I${top_srcdir}/include -I${top_builddir}/include -D_GNU_SOURCE
AM_LDFLAGS = -L${top_builddir}/lib -L${top_builddir}/src/lib -lnl-cli
noinst_PROGRAMS = \
@ -21,6 +21,7 @@ noinst_PROGRAMS = \
nl-fib-lookup \
nl-list-caches nl-list-sockets \
nl-util-addr \
nl-pktloc-lookup \
dect-transceiver-bind dect-transceiver-list \
dect-cell-add dect-cell-delete dect-cell-list \
dect-cluster-add dect-cluster-delete dect-cluster-list \
@ -100,6 +101,9 @@ nl_list_sockets_LDADD = -lnl-route
nl_util_addr_SOURCES = nl-util-addr.c
nl_util_addr_LDADD = -lnl-route
nl_pktloc_lookup_SOURCES = nl-pktloc-lookup.c
nl_pktloc_lookup_LDADD = -lnl-route
dect_transceiver_bind_SOURCES = dect-transceiver-bind.c
dect_transceiver_bind_LDADD = -lnl-dect
dect_transceiver_list_SOURCES = dect-transceiver-list.c

View File

@ -1,7 +1,7 @@
# -*- Makefile -*-
AM_CFLAGS = -Wall -I${top_srcdir}/include -D_GNU_SOURCE -DPKGLIBDIR=\"$(pkglibdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -rdynamic
AM_LDFLAGS = -L${top_builddir}/lib -ldl
AM_CPPFLAGS = -Wall -I${top_srcdir}/include -I${top_builddir}/include -D_GNU_SOURCE -DPKGLIBDIR=\"$(pkglibdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -rdynamic
AM_LDFLAGS = -L${top_builddir}/lib -ldl -version-info 3:0:0
#nobase_pkglib_LTLIBRARIES = cls/basic.la cls/ematch/cmp.la
#cls_basic_la_LDFLAGS = -module -version-info 2:0:0
@ -28,8 +28,6 @@ AM_LDFLAGS = -L${top_builddir}/lib -ldl
lib_LTLIBRARIES = \
libnl-cli.la
libnl_cli_la_LDFLAGS = -version-info 2:0:0
libnl_cli_la_LIBADD = ${top_builddir}/lib/libnl.la \
${top_builddir}/lib/libnl-route.la \
${top_builddir}/lib/libnl-nf.la \

37
src/nl-pktloc-lookup.c Normal file
View File

@ -0,0 +1,37 @@
/*
* src/nl-pktloc-lookup.c Lookup packet location alias
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
*/
#include <netlink/cli/utils.h>
#include <netlink/route/pktloc.h>
static void print_usage(void)
{
printf("Usage: nl-pktloc-lookup <name>\n");
exit(0);
}
int main(int argc, char *argv[])
{
struct rtnl_pktloc *loc;
int err;
if (argc < 2)
print_usage();
if ((err = rtnl_pktloc_lookup(argv[1], &loc)) < 0)
nl_cli_fatal(err, "Unable to lookup packet location: %s",
nl_geterror(err));
printf("%s: %u %u+%u 0x%x %u\n", loc->name, loc->align,
loc->layer, loc->offset, loc->mask, loc->flags);
return 0;
}