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:
commit
ac50c84f8c
|
@ -5,6 +5,7 @@
|
|||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.swp
|
||||
Makefile
|
||||
/lib/stamp-h1
|
||||
|
||||
|
|
13
Makefile.am
13
Makefile.am
|
@ -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:
|
||||
|
|
13
configure.in
13
configure.in
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
19
lib/cache.c
19
lib/cache.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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 */
|
||||
|
|
4
lib/nl.c
4
lib/nl.c
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
pktloc_grammar.h
|
||||
pktloc_grammar.c
|
||||
pktloc_syntax.h
|
||||
pktloc_syntax.c
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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; }
|
||||
;
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
12
lib/socket.c
12
lib/socket.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
Reference in New Issue