dect
/
libnl
Archived
13
0
Fork 0

Compare commits

...

164 Commits

Author SHA1 Message Date
Patrick McHardy 6ae22c1b39 Merge /home/kaber/src/repos/libnl.git 2013-06-28 18:11:40 +02:00
Thomas Graf 01cfa9c1db msg: Avoid returning a negative value for nlmsg_attrlen()
If a hdrlen was provided that was greather than the actual
message length, a negative attributes length would result.

This was typically happening for RTM_GETLINK requests where
we can get a away with a 4 bytes header on the request side
but the response would use a 16 bytes header.

This resulted in strange -8 bytes leftover debug messages.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-06-27 18:29:17 +02:00
Holger Eitzenberger d612180cda netfilter/queue: introduce nfnl_queue_msg_send_verdict_batch()
The batched verdict implicitely ACKs all queue packet IDs up to the
one send back, which reduces the number of verdict messages send
to the kernel.

Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-06-27 01:16:15 +02:00
Holger Eitzenberger 34a96ba5c2 netfilter/queue: generalize nfnl_queue_msg_build_verdict()
Generalize netfilter/queue to allow sending batched verdicts
later.

Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-06-27 01:15:34 +02:00
Andrew Collins 53ac502a2b Handle -NLE_AGAIN in nl_cache_mngr_data_ready
Since commit "nl: Return -NLE_AGAIN if non-blocking socket would block",
nl_cache_mngr_data_ready returns -NLE_AGAIN to callers on non-blocking sockets.
Change it to consider -NLE_AGAIN as a non-error case as it is expected behavior
with the nl_recv changes.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-06-27 01:12:36 +02:00
Andrew Collins 87bbfb6b12 Default to comparing all attributes if no oo_id_attrs defined
Since commit: "cache pickup: Avoid duplicates during cache pickup",
nfnl_ct_alloc_cache no longer properly fills the cache, as it doesn't
define oo_id_attrs so all items are considered duplicates.

Instead of adding a ~0 oo_id_attrs to ct_obj, this changes
nl_object_identical to default to comparing all attributes if
neither oo_id_attrs_get or oo_id_attrs are provided.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-06-27 01:12:28 +02:00
Thomas Graf c1de0f3129 Merge branch 'master' of https://github.com/michael-dev/libnl 2013-05-24 14:37:02 +02:00
Michael Braun c76393e203 Add macvlan support
This patch add support for kernel macvlan interfaces.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
2013-05-16 17:04:08 +02:00
Thomas Graf c4d846f239 3.2.22 release 2013-05-14 14:09:07 +02:00
Thomas Graf 807fddc4cd nl: Increase receive buffer size to 4 pages
Assuming that the kernel does not send more than a page is no longer valid,
and enabling MSG_PEEK'ing by default to figure out the exact message buffer
requirements can have a negative influence on the performance of existing
applications. Bumping the default receive buffer space to 4 pages seems
a sane default.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-05-08 13:52:27 +02:00
Nathan Lynch 8983fa9914 rtnl_link_af_unregister: fix locking
rtnl_link_af_unregister() attempts to write-lock info_lock twice
instead of releasing it before returning.  It also will return with
info_lock write-locked if passed a NULL ops.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-05-08 13:48:24 +02:00
Thomas Graf 183052d047 Prepare for 3.2.22-rc1 release
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 12:52:26 +02:00
Thomas Graf ed1f4cba2c tests: Include util.h in dist
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 12:51:58 +02:00
Thomas Graf 4e9aa6a9a6 tests: Add basic attribute unit tests
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 12:31:52 +02:00
Thomas Graf ffc0ee3540 configure: Convert ENABLE_UNIT_TESTS to a mere AM conditional
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 11:41:15 +02:00
Emmanuel Thierry 979ea335b0 Wrong calcultation in nla_reserve
There seams to be an error in the calculation of needed space for the message in nla_reserve. The current size of the message is counted twice: Once in NLMSG_ALIGN, once in the condition below.
This causes nla_put_* calls to be rejected if the allocation size of the message has been strictly calculated by the caller.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 10:34:50 +02:00
Thomas Graf 3a6d256da5 attr: Fix typo in nla_is_nested()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 10:33:52 +02:00
Thomas Graf 37f788f391 Merge branch 'fixes' of https://github.com/socketpair/libnl 2013-04-28 10:25:47 +02:00
Thomas Graf c07a6a30c2 attr: nla_is_nested() must access nla_type directly
Can't used nla_type() as it applies NLA_TYPE_MASK first

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-28 10:23:28 +02:00
Коренберг Марк (дома) 33396faca5 Fix leak of cb if nl_socket_alloc_cb() failed to allocate socket
- each *_get() should have corresponding *_put(). That rule was broken in nl_socket_alloc()
- Also, check if cb is NULL in nl_socket_set_cb (calls BUG())
2013-04-28 02:08:50 +06:00
Thomas Graf ead4cdeb99 tests: Make unit test building optional
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-27 14:27:10 +02:00
Коренберг Марк (дома) 59db7fb35b dump_attrs: "NLA_F_NESTED" => nla_is_nested(nla) 2013-04-26 23:50:54 +06:00
Thomas Graf d505165f2b autoconf: Use PKG_CHECK_MODULES() instead of AM_PATH_CHECK()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-05 10:44:06 +02:00
Thomas Graf d3cf89ea94 addr: only translate more recent address family names and ARP types if defined
Helps making libnl compilable with older kernel headers

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-05 10:37:55 +02:00
Emmanuel Roullit ea436445ad Perform no operation on nl_object_free(NULL).
Passing a NULL pointer would cause a NULL pointer dereference within
nl_object_free().
Returning early on NULL pointer is the behavior free(3) and other
nl*_free() functions.

Signed-off-by: Emmanuel Roullit <emmanuel.roullit@gmail.com>
2013-04-03 21:17:33 +02:00
Thomas Graf 56eb22fa74 msg: Pretty print generic netlink header in nl_msg_dump()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-02 23:13:15 +02:00
Thomas Graf 375a6294a4 nl: Return -NLE_AGAIN if non-blocking socket would block
Previously 0 was returned which gave the caller no chance of detecting
when a non-blocking socket would block. If a caller intends to never
see an error message it should utilize poll()/select() to only read
when the socket has pending data or information.

Reported-by: Holger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-02 11:58:18 +02:00
Thomas Graf df66b0f267 genl: Fix cb reference leak in genl_ctrl_probe_by_name()
nl_socket_get_cb() bumps the cb reference counter

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-02 11:51:53 +02:00
Holger Eitzenberger 18152ca916 ct: add ICMPv6 type,code and ID
Add ICMPv6 type, code and ID (if set) by using the already available
conntrack atttributes.

Currently the ICMPv6 conntrack objects in libnl are without type, code
and ID.  This e. g. is the output of nl_object_dump() without the patch:

  ipv6-icmp ::1 <-> ::1
  id 0xdd0871f0 family inet6 timeout 30s <NOREPLY,SNAT_INIT,DNAT_INIT>

The attached patch tries to solve that.  It then looks like

  ipv6-icmp ::1 <-> ::1 icmp type 128 code 0 id 28253
  id 0xdf3a11f0 family inet6 timeout 30s <SNAT_INIT,DNAT_INIT>

It is the 'small' approach, because it reuses the existing ICMP
attributes of the conntrack object (currently only used for IPv4).
This way I can avoid to add new _icmp6_get_, _icmp6_set_ and
_icmp6_test_ functions.

Signed-off-by: Holger Eitzenberger <holger@eitzenberger.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-02 11:42:59 +02:00
Thomas Graf ff567100d6 nl: Print file:line:func in debugging messages and provide --disable-debug to disable debugging
Compiling libnl with --disable-debug will result in the ignorance
of the 'NLDBG' environment variable.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-02 11:39:30 +02:00
Thomas Graf f9241d57fe cache: Improve debugging messages of cache operations
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-01 11:46:30 +02:00
Patrick McHardy d2b5cbd88a Merge git://git.infradead.org/users/tgr/libnl
Signed-off-by: Patrick McHardy <kaber@trash.net>

Conflicts:
	include/linux/netlink.h
	lib/Makefile.am
	lib/error.c
	libnl-3.0.pc.in
	src/Makefile.am
2013-04-01 11:44:59 +02:00
Thomas Graf ad545f2854 genl: Update mt_id of cache ops when resolving genl id
The cache layer uses the message type array stored in the cache
ops to lookup which cache a message belongs to. Update to the
the message array with the resolved generic netlink id to make
it compatible with the caching API.

Allows to use nl_cache_refill() and others for generic netlink
based caches with dynamic generic netlink ids.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-01 11:21:22 +02:00
Thomas Graf aad041c46f genl: Provide internal function to resolve name to id
Like genl_ops_resolve() but uses its own socket.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-04-01 11:14:49 +02:00
roopa 6c9be5a316 nl-route-add: Add NLM_F_EXCL flag to route add
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-24 10:58:18 +01:00
Tony Cheneau 23e26e9e05 Remove rtnl_link_free() declaration from the header file.
Reason: there is no rtnl_link_free() definition anywhere in the code.

Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-17 17:31:53 +01:00
Tony Cheneau 4db11517fd Remove superfluous declaration of rtnl_route_put()
rtnl_route_put() is declared twice in the same header file

Signed-off-by: Tony Cheneau <tony.cheneau@amnesiak.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-17 17:31:45 +01:00
Thomas Graf b39c9f7a53 rtnl-addr: Fix invalid call to nl_addr_set_prefixlen() if neither local or peer address are present
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 18:57:15 +01:00
Thomas Graf 549d26dc87 rtnl-addr: Inherit prefix length to nl_addr objs in rtnl_addr_set_prefixlen()
Previously if using rtnl_addr_set_prefixlen() the new prefix length
was not forwarded to the corresponding 'struct nl_addr' objects
associated with address already and thus the comparison function
would fail.

This patch also clears the internal ADDR_ATTR_PREFIXLEN flag if
the prefix length has been reset.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 18:52:17 +01:00
Thomas Graf e09e7f1035 tests: Add check based unit test system
Introduces new unit tests based on `check`. Each subsystem/module can
have its own unit tests in tests/check-<name>.c that will be linked
together in tests/check-all.c.

Running 'make check' will compile and run the unit tests automatically.

A reference unit test implementation has been done for the abstract
address module.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 16:25:17 +01:00
Thomas Graf 780a0423dc addr: Update to latest address familiy definition for translation
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 16:09:19 +01:00
Thomas Graf 88527534ba addr: improve API reference documentation for nl_addr_*()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 15:37:46 +01:00
Thomas Graf f0f33c394b addr: Reset unused portion of binary address in nl_addr_set_binary_addr()
memset() the binary address before overwriting it with new data
to avoid leaving around old portions of the address.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 14:41:12 +01:00
Thomas Graf f72bfc7220 msg: Pretty print error message header even if incomplete
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:14 +01:00
Thomas Graf c608b4d151 msg: Pretty print padding attributes in nl_msg_dump()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:12 +01:00
Thomas Graf 1395c69901 attr: Warn application if nla_parse() observes same attribute multiple times
Use a debugging message to warn applications if an attribute is
found multiple times in the same message. It is perfectly valid
to rely on this behaviour but it is likely to indicate a bug.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:09 +01:00
Thomas Graf 64315f731c attr: No longer warn about attribute of type 0
The kernel will start using type 0 attributes for padding purposes.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:06 +01:00
Thomas Graf 60b370de8c attr: Do not enforce maximum length for NLA_FLAG attributes
Although wasteful, NLA_FLAG with non zero payload cause no harm
and should thus not be rejected.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:04 +01:00
Thomas Graf 9e6cdbf6fc attr: Add nla_nest_cancel() to remove partially added nested attributes
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-03-14 12:46:01 +01:00
Thomas Graf 4d7680c19c Use thread-safe strerror_r() instead of strerror()
We have only ever fed well known error codes into strerror()
so it should never have been a problem though.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-28 13:07:04 +01:00
roopa ded20487fd link: Fix rtnl_link_af_data_compare return value
This patch fixes a bug where because of the af_ops check
being first in the function, we were returning ~0 if af_ops
was null even if both objects really did not have af_data
and we should be returning 0.

Its better to have the af_data present check before anything else.

So, Rearranged some of the code in rtnl_link_af_data_compare.
Changes include:
	- Do the attribute present check before anything else
	- If ao_compare op not present, return ~0

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-24 17:11:36 +01:00
roopa 8f151fadda link: move af_data_compare to the end
In the current code if rtnl_link_af_data_compare returns value > 0
we mark PROTINFO attribute in the diff mask and return without
comparing flags.

This patch makes af_data to be the last thing we compare.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-24 17:06:54 +01:00
Thomas Graf 1ecf98a23e bond: Provide rtnl_link_bond_alloc()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-14 12:48:00 +01:00
Thomas Graf ee4122a12e vlan: Provide rtnl_link_vlan_alloc()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-14 12:42:22 +01:00
Thomas Graf bb9911b5a3 netlink: Forward declare frequent libnl types to ease inclusion deps
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-14 12:37:10 +01:00
Thomas Graf 5a5aa73158 bridge: Provide rtnl_link_bridge_alloc()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-14 12:34:57 +01:00
Thomas Graf fd19dae352 bridge: Support the new bridging attributes
This provides support for the new bridging attributes provided
in IFLA_PROTINFO while maintaining backwards compatibility
with older kernels.

A set of new API functions are exported to access the bridging
information. rtnl_link_bridge_has_ext_info() can be used to
check whether a bridge object has been constructed based on
the newly available attributes or the old message format.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-07 11:39:27 +01:00
Thomas Graf 9f8548b551 attr: Provide nla_is_nested() function
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 22:31:31 +01:00
Thomas Graf 8026fe2e3a link: Free and realloc af specific data upon rtnl_link_set_family()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 13:52:22 +01:00
Thomas Graf 4a793a4235 link: Hold af_ops reference for each AF_SPEC block during lifetime of link object
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 13:46:42 +01:00
Thomas Graf e5767684a6 link: Modify link policy on the stack
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 13:21:10 +01:00
Thomas Graf 2d36371aa1 link: Keep reference to af_ops during lifetime of link object
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 13:18:25 +01:00
Thomas Graf 8b8e26b333 link: Fix af_ops leak on ENOMEM
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-05 13:03:02 +01:00
Holger Dengler 506020ae99 can: Fix nested message creation in can_put_attrs()
Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Holger Dengler <dengler@linutronix.de>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-01 12:24:37 +01:00
Thomas Graf 1c24480180 can: Include "linux/can/netlink.h" in the distribution
Needed to compile if local kernel headers are outdated.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-01 10:51:33 +01:00
Thomas Graf 8571f58f23 neigh: Remove check for AF_UNSPEC in rtnl_neigh_get()
This check was introduces to not accidently return AF_BRIDGE objects
to unaware API users as they do differ in structure. However, such
objects are only available if explicitely requests using the
NL_CACHE_AF_ITER flag or by using arg1 == AF_BRIDGE for the cache.

Therefore remove this check and allow rtnl_neigh_get() to be used to
fetch any neighbor object of a cache.

Reported-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-01 10:45:01 +01:00
Thomas Graf 2005c2ecac cache: Make NL_ACT_* and nl_cache_ops_(get|put)() available
Move NL_ACT_* definition and the functions nl_cache_ops_get()
and nl_cache_ops_put() into the public facing API. They can
be considered stable.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-02-01 10:21:58 +01:00
Thomas Graf 87458abbd0 Fix mask calculation in nl_addr_cmp_prefix()
Signed-off-by: Malte Langermann <mlangermann@radiodata.biz>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-31 10:59:10 +01:00
Thomas Graf 73cb5f57ba Merge branch 'nattuple' of https://github.com/rmfought/libnl 2013-01-31 10:47:58 +01:00
roopa b06c23a9dd link cache: remove AF_UNSPEC check in rtnl_get_link and rtnl_get_link_by_name
This patch reverts back the AF_UNSPEC check introduced by AF_BRIDGE
changes at http://lists.infradead.org/pipermail/libnl/2012-November/000796.html

After the addition of AF_BRIDGE support, link cache can now contain objects of
type AF_BRIDGE. To make sure existing api's did not return AF_BRIDGE objects
and surprise existing callers, I introduced the check for AF_UNSPEC.

But from what Andy Wang reported, rtnl_link_get_by_name returns the first
link object with matching ifindex and that could have not only been AF_UNSPEC
but also of family AF_INET6. And his app always got an AF_INET6 object prior
to the patch that introduced the AF_UNSPEC check.

I could just add AF_INET6 family check along with AF_UNSPEC in the apis and that
should work well.

But thinking about it some more, removing the AF_UNSPEC change seems to be safer at
this point. That way this api will retain its semantics and return the first object
with matching ifindex. It could be of any supported family. The user will know if the
cache contains bridge objects, because they are available only with the cache flag
NL_CACHE_AF_ITER. Besides, if new users want to search for a specific object,
nl_cache_find is a better option.

Reported-by: Andy Wang <Andy.Wang@watchguard.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-31 10:09:12 +01:00
Rich Fought 4f088d38ae netfilter: correct error in construction of NAT tuple 2013-01-29 15:10:01 -08:00
Benedikt Spranger 6cc5fdc0e9 can: add helper function to get CAN bus state
Add a helper function to get the CAN bus state.

Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
2013-01-25 19:51:33 +01:00
Thomas Graf 4cb375a812 Merge pull request #29 from rmfought/natdir32
netfilter: expectation NAT direction is 32 bit attribute
2013-01-24 08:32:35 -08:00
Rich Fought 87244f739c netfilter: keep 8-bit API for 32-bit NAT dir attribute 2013-01-24 08:18:35 -08:00
Thomas Graf 83c762d7cf 3.2.21 release 2013-01-24 15:00:26 +01:00
Thomas Graf b6afd0bf1a Provide better help text when bumping CURRENT,AGE,REVISION
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 14:34:22 +01:00
Thomas Graf 776cde0a10 Remove obsolete warning from <netlink/object-api.h> as it breaks NM build
NM uses -Werror=cpp thus the build breaks if we emit #warning upon
inclusion of <netlink/object-api.h>

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 14:29:18 +01:00
Thomas Graf c4f803366e Fix build warnings of nl-(qdisc|class|cls)-add
Reported-by: Jeroen Roovers <jer@gentoo.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 14:10:33 +01:00
Thomas Graf c6abb44e38 Fix test-cache-mngr test
Needs to include <netlink-private/cache-api.h>

Reported-by: Jeroen Roovers <jer@gentoo.org>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 14:05:48 +01:00
Thomas Graf 1b9de9a49d Provide compat headers for removed private API
Some projects seem to have mistakenly included the private
API headers without actually needing them.

Provide dummy headers referring to the real headers to
provide backwards compatibility.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 14:03:52 +01:00
Thomas Graf 9680f910f4 Move private header files to <netlink-private/*>
This clarifies the seperation between public and private
header files.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-24 13:51:24 +01:00
Rich Fought 56352ab9f6 netfilter: expectation NAT direction is 32 bit attribute 2013-01-23 13:59:27 -08:00
Jiri Pirko 1419851eb4 fix includes after removing some headers
commit f20bbe1f07
Author: Thomas Graf <tgraf@suug.ch>
Date:   Tue Jan 22 19:10:38 2013 +0100

    No longer install module API headers

This commit causes a regression so no app using libnl can be compiled
against it. This patch fixes it by removing includes of no-longe
existing headers.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-23 13:37:29 +01:00
Thomas Graf 26e22d887e 3.2.20 release 2013-01-23 11:02:54 +01:00
roopa 1481f97d36 route cache: This patch adds route priority to route object oo_id_attrs
The kernel allows multiple entries in the main table which differ in the
priority value. In libnl currently, since priority is not part of the base
netlink route message, it is not used as part of the key. This patch
includes priority in the key/oo_id_attrs and defaults the value to zero
for messages where priority is not included.

One point to note is that the actual selection of route from multiple
options is done implicitly in the kernel by storing the routes in sort
priority order, but there is no explicit communication to a client of libnl
of that.

Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-23 11:02:51 +01:00
Thomas Graf 2b96c3381d Remove obsolete release notes at end of configure
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-23 11:02:49 +01:00
Thomas Graf f20bbe1f07 No longer install module API headers
Various header files providing an API to implement own cache and
object types or implement link types have been available in the
past. Their API is marked unstable in the documentation and nobody
is using them so far.

Technically they have been causing ABI breakages in at least two
3.2.x releases. In order to avoid future accidental breakage, no
longer install these and require module developers to clone the
git tree and build modules off the git tree directly to make sure
that the API is unstable at this point.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-23 11:02:44 +01:00
Thomas Graf 7559157f2d Undo soname bump
The soname was bumped before 3.2.18 was released to reflect
an ABI change in the cache and object API.

This caused a discussion with various distribution maintainers
involved as it prevented them from including the release in
their stable branches. This is especially unfortunate as the
corresponding API is unused outside of libnl as of now.

For this reason, I have decided to undo the soname bump and
instead remove the corresponding header files from the list of
installable headers and thus remove them from the public API.

This is a API break technically but since nobody is using
them it should not matter. If you are in fact using any of the
*-api.h headers please let me know and we are most likely to
start a new development branch.

If your application linked against 3.2.18 or 3.2.19 you will need
to relink if you want it to use >= 3.2.20.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-23 11:02:37 +01:00
Thomas Graf 5291af6fb5 link: fix reference leak in rtnl_link_af_data_compare()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-18 14:49:33 +01:00
roopa 5c3f2f015a link: Add af data compare to link objects
Today the link compare function does not
compare af data of a link. We have found a
need for this to get approriate change callbacks
when af_data of a link changes.

This patch adds support to compare af_data
to link_compare function. This patch today
only adds support to compare af_data set by
PROTINFO attributes. It can be extended to
support compares of af_data set by AF_SPEC
attributes

It has been tested for AF_BRIDGE objects.
In case of AF_BRIDGE objects, this helps with
bridge port change notification callbacks.

Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-18 14:42:18 +01:00
roopa 99399ca9c0 Add new rtnl_link_af_data_compare function to compare af_data
This patch adds a new api rtnl_linl_af_data_compare to
compare link af_data

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-18 14:41:58 +01:00
Thomas Graf 6b4a2cb634 3.2.19 release 2013-01-17 14:02:35 +01:00
roopa 310ec86b39 Add ao_compare support to bridge family af_data
This patch adds support for ao_compare operation
to bridge link af data operations.

Adds field ce_mask to struct bridge_data to work
with the ATTR attributes. I can submit separate
patches to introduce mask field to ATTR macros.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-12 11:38:35 +01:00
roopa 09213ee5ee link af ops: Add new ao_compare op to compare link af_data
This patch adds new operation to compare link af_data.
ao_compare is similar to object oo_compare operation.
This op can be used when two links are compared
 for their af data. It takes two link objects in
question, an object specific bitmask defining which
attributes should be compared and flags to control
the behaviour. The function must return a bitmask
with the relevant bit set for each attribute that mismatches.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-12 11:37:32 +01:00
roopa b1ebda9241 cache: Add new nl_cache_find api
This patch adds new cache find api

nl_cache_find api was suggested by Thomas.

Unlike nl_cache_search, this patch uses
nl_object_match_filter() to look for an
object match.

Am not sure this matches what was decided
on the list few weeks back. I will be happy
to make any changes.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-11 13:52:50 +01:00
Flavio Leitner 3540e44b15 link: add carrier support
Signed-off-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-11 13:44:47 +01:00
Thomas Graf f123795434 3.2.18 release 2013-01-08 14:47:03 +01:00
Thomas Graf 383ff943b4 fix include/Makefile.am
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-08 14:44:47 +01:00
Otavio Salvador de5744fb65 build: Fix distribution to include 'nfnetlink_conntrack.h'
The header has not been included in the headers list so it has been
been distributed in the tarball making it fail to build in old kernels.

Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-08 14:38:49 +01:00
mihai.dontu@gmail.com ba38f39198 cache: make sure the user has specified a callback
In cache_include(), the user callback is used even though one might not
have been specified, leading to a crash. This happens, for example, when
NetworkManager calls nl_cache_include() with the change_cb argument set
to NULL. Fix it by making sure the callback points to a valid address.

Signed-off-by: Mihai Dontu <mihai.dontu@gmail.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-06 14:22:15 +01:00
Thomas Graf 00a5879e6e Add <netlink/route/link/can.h> to dist target
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-04 17:44:43 +01:00
Thomas Graf 6369e1fdd9 3.2.17 release 2013-01-04 16:44:52 +01:00
Eric Paris 5d53626100 nlmsg_ok comparison between signed and unsigned
The nlmsg_ok macro has a comparison between an int and a size_t
(unsigned int).  The C spec says the int is cast to unsigned int before
the comparison.  This is a problem as the audit system will send skb's
with skb->len == nlhhdr->nlmsg_len which are NOT aligned.  Thus you can
end up with remaining being negative.  So the comparison becomes

(unsigned int)(-1) >= (unsigned int)16

Which turns out to be true!  It should clearly be false.  So if we cast
the size_t to an int we get a signed comparison and it works.  (This is
what linux/netlink.h and all of the kernel netlink headers do)

Signed-off-by: Eric Paris <eparis@redhat.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2013-01-04 00:35:18 +01:00
Thomas Jarosch 6971932254 Fix file descriptor leak on error
Detected by cppcheck

Signed-off-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-27 13:20:18 +01:00
Thomas Graf de213328f8 cache: Take cache_ops lock when modifying cache ops flags
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-27 13:19:04 +01:00
roopa 96bb7c9a4c cache pickup: Avoid duplicates during cache pickup
This patch adds search and replace/update functionality
to cache pickup_cb. This change is required to avoid
duplicates getting into the cache during pickup. Also
helps updating existing objects during cache pickup.
We have seen this in cases of ipv6 equal cost multipath
routes

changes v1 to v2:
	- Updated documentation

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2012-12-21 13:30:21 +01:00
Thomas Graf 91ab1bea5e make: automake provides a cscope target these days
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-21 13:30:21 +01:00
roopa 20a051237c Bug Fix: cache_include: Fix object ref release after successful object update
The current code does a rtnl_link_put on new object instead of
old object. This patch fixes it. None of the caches have support
for object update, so this should not have affected anyone yet.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
2012-12-17 16:46:58 +01:00
roopa 29b71371e7 route cache: Fix handling of ipv6 multipath routes
There are two ways kernel handles ipv6 equal cost multipath routes
depending on which kernel version you are looking at.

older kernels without ipv6 ECMP support, accept the below ECMP routes,
#ip -6 route add 2001::/16 nexthop via fe80:2::2 dev swp1
#ip -6 route add 2001::/16 nexthop via fe80:2::3 dev swp1

store them as separate routes and pick the last one during lookup.

Newer kernels, after the support for equal cost multipath routes
was added http://patchwork.ozlabs.org/patch/188562/,
now accept multipath routes added individually using the
above 'ip -6 route' format OR
sent using RTA_MULTIPATH with the below command
#ip -6 route add 2001::/16 nexthop via fe80:2::2 dev swp1 nexthop via fe80:2::3 dev swp1

And the kernel now stores and treats them as equal cost multipath routes
during lookups.

However in all cases above, netlink notifications to ipv6 ECMP route adds and deletes
come separately for each next hop.

Example libnl notification in the above case with both old and new kernels:
	inet6 2001::/16 table main type unicast
                scope global priority 0x400 protocol boot
                nexthop via fe80:2::2 dev swp1

        inet6 2001::/16 table main type unicast
                scope global priority 0x400 protocol boot
                nexthop via fe80:2::3 dev swp1

Since they are separate route notifications for objects with same key,
libnl replaces the existing ones and hence only the last route update sticks.

This patch uses the oo_update feature to not replace but update an
existing route if its a ipv6 equal cost multipath route.
The object after an update looks like the below (similar to ipv4 ECMP routes):

        inet6 2001::/16 table main type unicast
                scope global priority 0x400 protocol boot
                nexthop via fe80:2::2 dev swp1
                nexthop via fe80:2::3 dev swp1

Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-17 15:16:02 +01:00
Thomas Graf 52b635f1f7 Merge branch 'aligned_be64' of https://github.com/rmfought/libnl 2012-12-17 09:18:47 +01:00
Rich Fought 89e1b30256 Included defs.h so DISABLE_PTHREADS is visible. 2012-12-13 15:56:04 -08:00
Rich Fought 25c407c71f Re-adding #defines for __aligned_be64 for older kernels 2012-12-13 14:23:28 -08:00
Thomas Graf 7c85b8a53b netfilter: update local header files
Needed to NF_CT_EXPECT_PERMANENT etc.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-11 18:06:29 +01:00
Thomas Graf 913a689de3 can: provide local copy of <linux/can/netlink.h>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-11 17:59:30 +01:00
Gilles Espinasse de14136304 Fix make check when using --disable-cli
Signed-off-by: Gilles Espinasse <g.esp@free.fr>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-05 07:55:45 +01:00
Gilles Espinasse 68967eb10e Fix python detection code
Signed-off-by: Gilles Espinasse <g.esp@free.fr>

Compiling libnl versions that include doc or the git tree produce this
checking for python build information...
checking for python2.6... python2.6
checking for main in -lpython2.6... yes
checking python2.6/Python.h usability... yes
checking python2.6/Python.h presence... yes
checking for python2.6/Python.h... yes
./configure: line 4272: test: !=: unary operator expected
checking for python2.5... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
checking for python2.4... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
checking for python2.3... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
checking for python2.2... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
checking for python2.1... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
checking for python... (cached) python2.6
checking for main in -lpython2.6... (cached) yes
checking for python2.6/Python.h... (cached) yes
./configure: line 4272: test: !=: unary operator expected
  results of the Python check:
    Binary:      python2.6
    Library:     python2.6
    Include Dir: no

Fix the unary operator warning allow to break when one python version is found
Add the more recent python versions
Change send upstream as http://savannah.gnu.org/patch/index.php?7897
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-12-05 07:55:44 +01:00
Benedikt Spranger c86088ff01 link: socket-CAN helper functions
Add helper functions to make socket-CAN configuration easy.

Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-11-29 22:17:58 +01:00
Benedikt Spranger 5251188673 link: basic socket-CAN support
Controller Area Network (CAN) is a networking technology which has
widespread use in automation, embedded devices and automotive fields.
The socket-CAN package is an implementation of CAN protocols for Linux.

All socket-CAN related configurations are carried out through Netlink.
Add basic socket-CAN support to libnl to be able to configure CAN devices
with libnl.

Signed-off-by: Benedikt Spranger <b.spranger@linutronix.de>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-11-29 22:17:58 +01:00
Jan Engelhardt ab7f42e0bc build: resolve lex failure
This is an addendum to 0a9d5fcfa4,
which forgot to change ${LEX} to ${FLEX} in lib/Makefile.am.

On openSUSE, /usr/bin/lex is a wrapper that calls `flex -l ...`.
libnl however requires flex, not lex or a compat mode thereof,
so using ${FLEX} is the proper thing to do.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
2012-11-27 09:57:42 +01:00
Thomas Graf ffd051fc9a Merge branch 'master' of git://git.inai.de/libnl 2012-11-26 23:34:37 +01:00
Jan Engelhardt 0ba9e99381 build: use foreign mode
This is the magic trick to get rid of files like NEWS, INSTALL,
etc. that are unused in some projects, like libnl.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
2012-11-26 21:03:14 +01:00
Jan Engelhardt f3cd3fe950 build: use AC_CONFIG_AUX_DIR
Stash all those scripts into a separate directory and ignore that.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
2012-11-26 21:03:14 +01:00
Jan Engelhardt 9d92564566 build: resolve automake-1.12 warnings
/usr/share/automake-1.12/am/ltlibrary.am: warning: 'libnl-cli-3.la':
linking libtool libraries using a non-POSIX archiver requires
'AM_PROG_AR' in 'configure.ac'
(one for each .la file)

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
2012-11-26 21:03:13 +01:00
Jan Engelhardt a96a3b6828 build: rename configure.in -> .ac
"configure.in" is a very, very old, obsolete name. Newer automake
will reject it, so rename it now.

Signed-off-by: Jan Engelhardt <jengelh@inai.de>
2012-11-26 21:03:13 +01:00
Thomas Graf f535de36af 3.2.16 release 2012-11-26 17:43:12 +01:00
Thomas Graf 4149154c22 cache: only continue iterating over co_groups if it is available
A co_groups == NULL must enter the loop to trigger the initial
fill of the cache but may never bump the grp pointer as doing
so prevents the loop from being escaped correctly.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
2012-11-26 11:50:56 +01:00
Patrick McHardy 94cd080452 dect: transceiver: resync kernel header for P64 definitions
Signed-off-by: Patrick McHardy <kaber@trash.net>
2012-02-09 20:41:07 +01:00
Patrick McHardy c2fdebea42 libnl: resync netlink.h with kernel
Signed-off-by: Patrick McHardy <kaber@trash.net>
2012-02-09 20:37:20 +01:00
Patrick McHardy 4cec8d361c packet 2011-07-06 04:39:35 +02:00
Patrick McHardy 68915b1292 dect: add support for MBC statistics
Signed-off-by: Patrick McHardy <kaber@trash.net>
2011-06-18 06:04:58 +02:00
Patrick McHardy 450d03b24b headers: resync netlink.h
Signed-off-by: Patrick McHardy <kaber@trash.net>
2011-06-18 06:04:51 +02:00
Patrick McHardy 29abe5d86f dect: support transceiver features attribute
Signed-off-by: Patrick McHardy <kaber@trash.net>
2011-04-12 02:54:23 +02:00
Patrick McHardy 93a9e4dc6a Merge git://git.kernel.org/pub/scm/libs/netlink/libnl 2011-03-21 19:11:19 +01:00
Erik Tews 3c6622aeb8 dect: llme: implemented setting the multiframe number
Patch from Eric: "Implemented setting the multiframe number using
nl_dect_llme_mac_info_set_mfn".

Signed-off-by: Patrick McHardy <kaber@trash.net>
2011-03-19 02:26:40 +01:00
Patrick McHardy 2a591b7b2b Merge 192.168.0.100:/repos/git/libnl
Conflicts:
	include/netlink-types.h
	lib/Makefile.am
	src/.gitignore
	src/Makefile.am

Signed-off-by: Patrick McHardy <kaber@trash.net>
2011-03-19 00:47:14 +01:00
Patrick McHardy 56a447dffd dect: llme: add nl_dect_llme_mac_info_test_pari() function
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-11-14 19:34:38 +01:00
Patrick McHardy ac50c84f8c Merge branch 'master' of /repos/git/libnl
Conflicts:
	lib/Makefile.am
	src/Makefile.am

Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-10-15 04:16:08 +02:00
Patrick McHardy 2dc8bc1921 dect: show Z-CRC errors in transceiver statistics
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-09-10 16:49:00 +02:00
Patrick McHardy 432a1a31f2 unbind 2010-09-02 02:08:59 +02:00
Patrick McHardy edaf9cac24 dect: support monitor mode
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-08-19 18:41:56 +02:00
Patrick McHardy 2080dce45e package config: include nl-cli in Libs
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-08-19 18:39:38 +02:00
Patrick McHardy ac263675d1 dect: support DECT_LLME_MAC_RFP_PRELOAD
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-08-04 22:48:25 +02:00
Patrick McHardy a9886abe70 dect: rename DECT_HLC_ACCESS_RIGHT_REQUESTS to DECT_HLC_ACCESS_RIGHTS_REQUESTS
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-08-04 22:48:23 +02:00
Patrick McHardy 6ff91c4799 Merge branch 'master' of x2:/home/dect/git/libnl 2010-05-20 18:14:52 +02:00
Patrick McHardy 47a4c5a4c0 Merge branch 'master' of /repos/git/libnl 2010-05-20 17:20:12 +02:00
Patrick McHardy c17d47977e Merge branch 'master' of x2:/repos/git/libnl 2010-03-19 01:05:09 +01:00
Patrick McHardy 44fde8fcbb dect: adapt capability handling to latest kernel changes
Signed-off-by: Patrick McHardy <kaber@trash.net>
2010-03-08 04:02:53 +01:00
Patrick McHardy 2826c89a77 dect: transceiver: add missing DECT_DEL_TRANSCEIVER handling
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-30 00:57:56 +01:00
Patrick McHardy 17e2ac82ca dect: fixup example programs for latest library changes
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-17 17:30:24 +01:00
Patrick McHardy d9c446dd4f Merge branch 'master' of /repos/git/libnl
Conflicts:
	include/netlink/cli/utils.h

Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-17 17:21:30 +01:00
Patrick McHardy ff81f73c8a dect: support different ARI classes in dect-cluster-add
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-13 11:42:23 +01:00
Patrick McHardy accc75c463 libnl: dect: add cell slave mode support
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-04 11:04:51 +01:00
Patrick McHardy 71f3690295 libnl: dect: add DECT_SLOT_SYNC flag
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-12-04 09:57:22 +01:00
Patrick McHardy f5b6c85296 dect: support DECTA_SLOT_FLAGS attribute
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-11-26 03:21:30 +01:00
Patrick McHardy c335c58b68 dect: add X-crc statistic
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-11-26 03:21:28 +01:00
Patrick McHardy 464d806d27 dect: transceiver: show RF-band as 5 digit number
This is how the bands are officially numbered.

Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-11-12 14:38:34 +01:00
Patrick McHardy 9a8cbfdf5a Merge branch 'master' of x2:/repos/git/libnl
Conflicts:

	include/Makefile
	lib/Makefile
	src/Makefile

Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-11-12 13:36:05 +01:00
Patrick McHardy c60e16afd0 Merge branch 'master' of 192.168.0.100:/home/dect/git/libnl 2009-07-18 08:01:15 +02:00
Patrick McHardy d9cf87a0bc dect: add crc error statistic
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-07-18 08:00:12 +02:00
Patrick McHardy 1d25939936 dect: clarify error message
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-05-28 18:42:36 +02:00
Patrick McHardy 598dcf6c52 dect: resync netlink API with phase offset changes and display offset of each slot
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-05-10 15:10:12 +02:00
Patrick McHardy 85e8099cc4 dect: slightly more informative scan output
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-05-08 16:08:27 +02:00
Patrick McHardy be93d3d46c libnl: import DECT support
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-05-06 18:55:44 +02:00
Patrick McHardy b24d4fa5db libnl: add ENODEV to errno code table
Signed-off-by: Patrick McHardy <kaber@trash.net>
2009-05-06 18:53:39 +02:00
188 changed files with 10101 additions and 2084 deletions

6
.gitignore vendored
View File

@ -17,13 +17,9 @@ cscope.*
/aclocal.m4
/autom4te.cache
/compile
/build-aux/
/config.*
/configure
/depcomp
/libtool
/ltmain.sh
/install-sh
/missing
/*.pc

View File

@ -20,7 +20,3 @@ pkgsysconf_DATA = etc/pktloc etc/classid
EXTRA_DIST = \
$(pkgsysconf_DATA)
.PHONY: cscope
cscope:
cscope -b -q -R -Iinclude -slib -ssrc;

View File

@ -6,46 +6,48 @@
# License as published by the Free Software Foundation version 2.1
# of the License.
#
# Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
# Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
#
# copied from glib
m4_define([libnl_major_version], [3])
m4_define([libnl_minor_version], [2])
m4_define([libnl_micro_version], [15])
m4_define([libnl_micro_version], [22])
# If either revision or age are omitted, they default to 0. Also note that age
# must be less than or equal to the current interface number.
# The following explanation may help to understand the above rules a bit
# better: consider that there are three possible kinds of reactions from
# users of your library to changes in a shared library:
#
# Here are a set of rules to help you update your library version information:
# 1. Programs using the previous version may use the new version as drop-in
# replacement, and programs using the new version can also work with the
# previous one. In other words, no recompiling nor relinking is needed.
# In this case, bump revision only, don't touch current nor age.
#
# 1. Start with version information of `0:0:0' for each libtool library.
# 2. Update the version information only immediately before a public release
# of your software. More frequent updates are unnecessary, and only
# guarantee that the current interface number gets larger faster.
# 3. If the library source code has changed at all since the last update, then
# increment revision (`c:r:a' becomes `c:r+1:a').
# 4. If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0.
# 5. If any interfaces have been added since the last public release, then
# increment age.
# 6. If any interfaces have been removed since the last public release, then
# set age to 0.
# 2. Programs using the previous version may use the new version as drop-in
# replacement, but programs using the new version may use APIs not
# present in the previous one. In other words, a program linking against
# the new version may fail with “unresolved symbols” if linking against
# the old version at runtime: set revision to 0, bump current and age.
#
# 3. Programs may need to be changed, recompiled, relinked in order to use
# the new version. Bump current, set revision and age to 0.
m4_define([libnl_lt_current], [212])
m4_define([libnl_lt_current], [217])
m4_define([libnl_lt_revision], [0])
m4_define([libnl_lt_age], [12])
m4_define([libnl_lt_age], [17])
m4_define([libnl_version],
[libnl_major_version.libnl_minor_version.libnl_micro_version])
AC_INIT(libnl, [libnl_version], [], [], [http://www.infradead.org/~tgr/libnl/])
AC_CONFIG_HEADERS([lib/defs.h])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([-Wall foreign subdir-objects])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)], [])
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
MAJ_VERSION=libnl_major_version
AC_SUBST(MAJ_VERSION)
@ -73,6 +75,13 @@ AC_CHECK_PROGS(YACC, 'bison -y')
AC_C_CONST
AC_C_INLINE
PKG_CHECK_MODULES([CHECK], [check >= 0.9.0],
[enable_unit_tests="yes"],
[AC_MSG_WARN([*** Disabling building of unit tests])
enable_unit_tests="no"])
AM_CONDITIONAL([ENABLE_UNIT_TESTS], [test "$enable_unit_tests" = "yes"])
AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
@ -88,6 +97,11 @@ AC_ARG_ENABLE([pthreads],
[enable_pthreads="$enableval"], [enable_pthreads="yes"])
AM_CONDITIONAL([DISABLE_PTHREADS], [test "$enable_pthreads" = "no"])
AC_ARG_ENABLE([debug],
AS_HELP_STRING([--disable-debug], [Do not include debugging statements]),
[enable_debug="$enableval"], [enable_debug="yes"])
AM_CONDITIONAL([ENABLE_DEBUG], [test "$enable_debug" = "no" ])
AC_CHECK_LIB([m], [pow], [], AC_MSG_ERROR([libm is required]))
if test "x$enable_pthreads" = "xno"; then
@ -96,6 +110,10 @@ else
AC_CHECK_LIB([pthread], [pthread_mutex_lock], [], AC_MSG_ERROR([libpthread is required]))
fi
if test "x$enable_debug" = "xyes"; then
AC_DEFINE([NL_DEBUG], [1], [Define to 1 to enable debugging])
fi
AC_CONFIG_SUBDIRS([doc])
AC_CONFIG_FILES([
@ -104,6 +122,7 @@ libnl-3.0.pc
libnl-route-3.0.pc
libnl-genl-3.0.pc
libnl-nf-3.0.pc
libnl-dect-3.0.pc
libnl-cli-3.0.pc
lib/Makefile
include/Makefile
@ -147,10 +166,7 @@ echo " - The library basename was renamed to libnl-${MAJ_VERSION}, i.e. the S
echo " libnl-${MAJ_VERSION}.so., libnl-route-${MAJ_VERSION}.so, etc."
echo ""
echo " - libtool versioning was assumed, to ease detection of compatible library"
echo " versions. libnl-${MAJ_VERSION}.so.CURRENT.REVISION.AGE where."
echo " CURRENT := 100 * \$MINOR_VERSION + \$MICRO_VERSION"
echo " REVISION := nth revision if API was unchanged"
echo " AGE := nth revision that is backwards compatible."
echo " versions."
echo ""
echo " If you are using pkg-config for detecting and linking against the library "
echo " things will continue magically as if nothing every happened. If you are "

11
doc/.gitignore vendored
View File

@ -1,9 +1,8 @@
*.html
libnl.dict
Doxyfile
aclocal.m4
autom4te.cache
config.log
config.status
configure
missing
/aclocal.m4
/autom4te.cache/
/build-aux/
/config.*
/configure

View File

View File

@ -1,370 +0,0 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

View File

@ -6,12 +6,13 @@
# License as published by the Free Software Foundation version 2.1
# of the License.
#
# Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
# Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
#
AC_INIT(libnl-doc, [3.2.15], [http://www.infradead.org/~tgr/libnl/])
AC_INIT(libnl-doc, [3.2.22], [http://www.infradead.org/~tgr/libnl/])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(yes)], [])
m4_include([m4/ax_python.m4])

View File

@ -2316,6 +2316,7 @@ int put_opts(struct nl_msg *msg)
return 0;
nla_put_failure:
nla_nest_cancel(msg, opts);
return -EMSGSIZE;
}
--------

View File

@ -56,7 +56,7 @@
AC_DEFUN([AX_PYTHON],
[AC_MSG_CHECKING(for python build information)
AC_MSG_RESULT([])
for python in python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python; do
for python in python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python; do
AC_CHECK_PROGS(PYTHON_BIN, [$python])
ax_python_bin=$PYTHON_BIN
if test x$ax_python_bin != x; then
@ -64,8 +64,8 @@ if test x$ax_python_bin != x; then
AC_CHECK_HEADER([$ax_python_bin/Python.h],
[[ax_python_header=`locate $ax_python_bin/Python.h | sed -e s,/Python.h,,`]],
ax_python_header=no)
if test $ax_python_lib != no; then
if test $ax_python_header != no; then
if test x$ax_python_lib != xno; then
if test x$ax_python_header != xno; then
break;
fi
fi

View File

@ -645,9 +645,8 @@ This attribute is unused and obsoleted in all recent kernels.
struct rtnl_link *link;
link = rtnl_link_alloc();
link = rtnl_link_bond_alloc();
rtnl_link_set_name(link, "my_bond");
rtnl_link_set_type(link, "bond");
/* requires admin privileges */
if (rtnl_link_add(sk, link, NLM_F_CREATE) < 0)
@ -693,16 +692,70 @@ int master_index;
if (!(master_index = rtnl_link_name2i(link_cache, "eth0")))
/* error */
/* allocate new link object to configure the vlan device */
link = rtnl_link_alloc();
/* allocate new link object of type vlan */
link = rtnl_link_vlan_alloc();
/* set eth0 to be our master device */
rtnl_link_set_link(link, master_index);
if ((err = rtnl_link_set_type(link, "vlan")) < 0)
rtnl_link_vlan_set_id(link, 10);
if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
/* error */
rtnl_link_vlan_set_id(link, 10);
rtnl_link_put(link);
-----
[[link_macvlan]]
==== MACVLAN
[source,c]
-----
extern struct rtnl_link *rtnl_link_macvlan_alloc(void);
extern int rtnl_link_is_macvlan(struct rtnl_link *);
extern char * rtnl_link_macvlan_mode2str(int, char *, size_t);
extern int rtnl_link_macvlan_str2mode(const char *);
extern char * rtnl_link_macvlan_flags2str(int, char *, size_t);
extern int rtnl_link_macvlan_str2flags(const char *);
extern int rtnl_link_macvlan_set_mode(struct rtnl_link *,
uint32_t);
extern uint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *);
extern int rtnl_link_macvlan_set_flags(struct rtnl_link *,
uint16_t);
extern int rtnl_link_macvlan_unset_flags(struct rtnl_link *,
uint16_t);
extern uint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *);
-----
.Example: Add a MACVLAN device
[source,c]
-----
struct rtnl_link *link;
int master_index;
struct nl_addr* addr;
/* lookup interface index of eth0 */
if (!(master_index = rtnl_link_name2i(link_cache, "eth0")))
/* error */
/* allocate new link object of type macvlan */
link = rtnl_link_macvlan_alloc();
/* set eth0 to be our master device */
rtnl_link_set_link(link, master_index);
/* set address of virtual interface */
addr = nl_addr_build(AF_LLC, ether_aton("00:11:22:33:44:55"), ETH_ALEN);
rtnl_link_set_addr(link, addr);
nl_addr_put(addr);
/* set mode of virtual interface */
rtnl_link_macvlan_set_mode(link, rtnl_link_macvlan_str2mode("bridge"));
if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
/* error */

View File

@ -10,16 +10,21 @@ nobase_libnlinclude_HEADERS = \
netlink/genl/genl.h \
netlink/genl/mngt.h \
netlink/netfilter/ct.h \
netlink/netfilter/exp.h \
netlink/netfilter/log.h \
netlink/netfilter/log_msg.h \
netlink/netfilter/netfilter.h \
netlink/netfilter/nfnl.h \
netlink/netfilter/queue.h \
netlink/netfilter/queue_msg.h \
netlink/netfilter/exp.h \
netlink/dect/ari.h \
netlink/dect/cell.h \
netlink/dect/cluster.h \
netlink/dect/dect.h \
netlink/dect/llme.h \
netlink/dect/transceiver.h \
netlink/addr.h \
netlink/attr.h \
netlink/cache-api.h \
netlink/cache.h \
netlink/data.h \
netlink/errno.h \
@ -31,7 +36,6 @@ nobase_libnlinclude_HEADERS = \
netlink/netlink-compat.h \
netlink/netlink-kernel.h \
netlink/netlink.h \
netlink/object-api.h \
netlink/object.h \
netlink/route/cls/ematch/cmp.h \
netlink/route/cls/ematch/meta.h \
@ -43,11 +47,12 @@ nobase_libnlinclude_HEADERS = \
netlink/route/cls/fw.h \
netlink/route/cls/police.h \
netlink/route/cls/u32.h \
netlink/route/link/api.h \
netlink/route/link/bonding.h \
netlink/route/link/info-api.h \
netlink/route/link/bridge.h \
netlink/route/link/can.h \
netlink/route/link/inet.h \
netlink/route/link/vlan.h \
netlink/route/link/macvlan.h \
netlink/route/qdisc/cbq.h \
netlink/route/qdisc/dsmark.h \
netlink/route/qdisc/fifo.h \
@ -71,11 +76,16 @@ nobase_libnlinclude_HEADERS = \
netlink/route/rtnl.h \
netlink/route/rule.h \
netlink/route/tc.h \
netlink/route/tc-api.h \
netlink/socket.h \
netlink/types.h \
netlink/utils.h \
netlink/version.h
netlink/version.h \
netlink/cache-api.h \
netlink/object-api.h \
netlink/route/link/api.h \
netlink/route/link/info-api.h \
netlink/route/tc-api.h
if ENABLE_CLI
nobase_libnlinclude_HEADERS += \
@ -101,13 +111,17 @@ noinst_HEADERS = \
linux/if_arp.h \
linux/if_ether.h \
linux/if.h \
linux/if_bridge.h \
linux/if_link.h \
linux/if_vlan.h \
linux/inetdevice.h \
linux/ip_mp_alg.h \
linux/ipv6.h \
linux/can/netlink.h \
linux/neighbour.h \
linux/netfilter.h \
linux/netfilter/nf_conntrack_common.h \
linux/netfilter/nfnetlink_compat.h \
linux/netfilter/nfnetlink_conntrack.h \
linux/netfilter/nfnetlink.h \
linux/netfilter/nfnetlink_log.h \
@ -118,7 +132,11 @@ noinst_HEADERS = \
linux/rtnetlink.h \
linux/snmp.h \
linux/tc_ematch/tc_em_meta.h \
netlink-generic.h \
netlink-local.h \
netlink-tc.h \
netlink-types.h
netlink-private/genl.h \
netlink-private/netlink.h \
netlink-private/tc.h \
netlink-private/types.h \
netlink-private/cache-api.h \
netlink-private/object-api.h \
netlink-private/route/link/api.h \
netlink-private/route/tc-api.h

122
include/linux/can/netlink.h Normal file
View File

@ -0,0 +1,122 @@
/*
* linux/can/netlink.h
*
* Definitions for the CAN netlink interface
*
* Copyright (c) 2009 Wolfgang Grandegger <wg@grandegger.com>
*
*/
#ifndef CAN_NETLINK_H
#define CAN_NETLINK_H
#include <linux/types.h>
/*
* CAN bit-timing parameters
*
* For further information, please read chapter "8 BIT TIMING
* REQUIREMENTS" of the "Bosch CAN Specification version 2.0"
* at http://www.semiconductors.bosch.de/pdf/can2spec.pdf.
*/
struct can_bittiming {
__u32 bitrate; /* Bit-rate in bits/second */
__u32 sample_point; /* Sample point in one-tenth of a percent */
__u32 tq; /* Time quanta (TQ) in nanoseconds */
__u32 prop_seg; /* Propagation segment in TQs */
__u32 phase_seg1; /* Phase buffer segment 1 in TQs */
__u32 phase_seg2; /* Phase buffer segment 2 in TQs */
__u32 sjw; /* Synchronisation jump width in TQs */
__u32 brp; /* Bit-rate prescaler */
};
/*
* CAN harware-dependent bit-timing constant
*
* Used for calculating and checking bit-timing parameters
*/
struct can_bittiming_const {
char name[16]; /* Name of the CAN controller hardware */
__u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
__u32 tseg1_max;
__u32 tseg2_min; /* Time segement 2 = phase_seg2 */
__u32 tseg2_max;
__u32 sjw_max; /* Synchronisation jump width */
__u32 brp_min; /* Bit-rate prescaler */
__u32 brp_max;
__u32 brp_inc;
};
/*
* CAN clock parameters
*/
struct can_clock {
__u32 freq; /* CAN system clock frequency in Hz */
};
/*
* CAN operational and error states
*/
enum can_state {
CAN_STATE_ERROR_ACTIVE = 0, /* RX/TX error count < 96 */
CAN_STATE_ERROR_WARNING, /* RX/TX error count < 128 */
CAN_STATE_ERROR_PASSIVE, /* RX/TX error count < 256 */
CAN_STATE_BUS_OFF, /* RX/TX error count >= 256 */
CAN_STATE_STOPPED, /* Device is stopped */
CAN_STATE_SLEEPING, /* Device is sleeping */
CAN_STATE_MAX
};
/*
* CAN bus error counters
*/
struct can_berr_counter {
__u16 txerr;
__u16 rxerr;
};
/*
* CAN controller mode
*/
struct can_ctrlmode {
__u32 mask;
__u32 flags;
};
#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */
#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */
#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */
#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */
#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */
/*
* CAN device statistics
*/
struct can_device_stats {
__u32 bus_error; /* Bus errors */
__u32 error_warning; /* Changes to error warning state */
__u32 error_passive; /* Changes to error passive state */
__u32 bus_off; /* Changes to bus off state */
__u32 arbitration_lost; /* Arbitration lost errors */
__u32 restarts; /* CAN controller re-starts */
};
/*
* CAN netlink interface
*/
enum {
IFLA_CAN_UNSPEC,
IFLA_CAN_BITTIMING,
IFLA_CAN_BITTIMING_CONST,
IFLA_CAN_CLOCK,
IFLA_CAN_STATE,
IFLA_CAN_CTRLMODE,
IFLA_CAN_RESTART_MS,
IFLA_CAN_RESTART,
IFLA_CAN_BERR_COUNTER,
__IFLA_CAN_MAX
};
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
#endif /* CAN_NETLINK_H */

206
include/linux/dect.h Normal file
View File

@ -0,0 +1,206 @@
#ifndef _LINUX_DECT_H
#define _LINUX_DECT_H
#define DECTNAMSIZ 16
#include <linux/types.h>
#include <linux/socket.h>
/* these have to be macros in order to be usable for module aliases */
#define DECT_RAW 0 /* raw frames */
#define DECT_B_SAP 1 /* DLC Broadcast Service */
#define DECT_S_SAP 2 /* DLC Data Link Service */
#define DECT_LU1_SAP 3 /* LU1 sockets */
#define DECT_PROTO_NUM 4
/**
* struct sockaddr_dect
*
* @dect_family: address family (AF_DECT)
* @dect_index: cluster index
*/
struct sockaddr_dect {
sa_family_t dect_family;
int dect_index;
};
/* raw sockets */
#define DECT_RAW_AUXDATA 0
/**
* struct dect_raw_auxdata - raw socket auxiliary frame data
*
* @mfn: multi-frame number
* @frame: frame number
* @slot: slot numer
* @rssi: receive signal strength indicator
*/
struct dect_raw_auxdata {
__u32 mfn;
__u8 frame;
__u8 slot;
__u8 rssi;
};
#define DECT_BSAP_AUXDATA 0
/**
* struct dect_bsap_auxdata
*
* @long_page: message contains a long page
*/
struct dect_bsap_auxdata {
__u8 long_page;
};
/**
* enum dect_sapis - S SAP Identifier
*
* @DECT_SAPI_CO_SIGNALLING: connection oriented signalling
* @DECT_SAPI_CL_SIGNALLING: connectionless signalling
* @DECT_SAPI_ANY: wildcard
*/
enum dect_sapis {
DECT_SAPI_CO_SIGNALLING = 0,
DECT_SAPI_CL_SIGNALLING = 3,
DECT_SAPI_ANY = 7,
};
/**
* enum dect_llns - Logical Link Numbers
*
* @DECT_LLN_CLASS_U: Class U operation
* @DECT_LLN_CLASS_A: Class A operation
* @DECT_LLN_ASSIGNABLE*: Assignable LLN (class B operation)
* @DECT_LLN_UNASSIGNED: LLN unassigned (class B operation
* @DECT_LLN_ANY: wildcard
*/
enum dect_llns {
DECT_LLN_CLASS_U = 0,
DECT_LLN_CLASS_A = 1,
DECT_LLN_ASSIGNABLE_MIN = 2,
DECT_LLN_ASSIGNABLE_MAX = 6,
DECT_LLN_UNASSIGNED = 7,
DECT_LLN_ANY = 15,
};
/**
* struct sockaddr_dect_ssap
*
* @dect_family: family (AF_DECT)
* @dect_lln: logical link number
* @dect_sapi: service access point identifier
* @dect_class: class A/B
* @dect_index: cluster index
* @dect_ari: ARI
* @dect_pmid: PMID
* @dect_lcn: logical connection number
*/
struct sockaddr_dect_ssap {
sa_family_t dect_family;
__u8 dect_lln:4,
dect_sapi:3;
__u8 dect_class;
int dect_index;
__u64 dect_ari:40,
dect_pmid:20,
dect_lcn:3;
};
/* S-SAP primitives */
#define DECT_DL_ENC_KEY 1
#define DECT_DL_ENCRYPT 2
#define DECT_DL_MAC_CONN_PARAMS 3
enum dect_cipher_states {
DECT_CIPHER_DISABLED,
DECT_CIPHER_ENABLED,
};
/**
* enum dect_mac_connection_types - MAC Connection types
*
* @DECT_MAC_CONN_BASIC: Basic connection, always I_N_min_delay service
* @DECT_MAC_CONN_ADVANCED: Advanced connection
* @DECT_MAC_CONN_COMPLEMENT: Complementary connection
*/
enum dect_mac_connection_types {
DECT_MAC_CONN_BASIC,
DECT_MAC_CONN_ADVANCED,
DECT_MAC_CONN_COMPLEMENT,
};
enum dect_mac_service_types {
DECT_SERVICE_IN_MIN_DELAY = 0x0,
DECT_SERVICE_IPX_ENCODED_PROTECTED = 0x1,
DECT_SERVICE_IN_NORMAL_DELAY = 0x2,
DECT_SERVICE_UNKNOWN = 0x4,
DECT_SERVICE_C_CHANNEL_ONLY = 0x5,
DECT_SERVICE_IP_ERROR_DETECTION = 0x10,
DECT_SERVICE_IPQ_ERROR_DETECTION = 0x14,
/* Lifetime encoded in low three bits */
DECT_SERVICE_IP_ERROR_CORRECTION = 0x18,
DECT_SERVICE_IPQ_ERROR_CORRECTION = 0x38,
};
/**
* enum dect_slot_types - DECT slot types
*
* @DECT_FULL_SLOT: Full-slot format (480 bits)
* @DECT_HALF_SLOT: Half-slot format (240 bits)
* @DECT_DOUBLE_SLOT: Double-slot format (960 bits)
* @DECT_LONG_SLOT_j640: Long slot format j=640 (800 bits)
* @DECT_LONG_SLOT_j672: Long slot format j=672 (832 bits)
*
* The numeric values must match the MAC-layer attributes-T coding.
*/
enum dect_slot_types {
DECT_FULL_SLOT = 0x0,
DECT_HALF_SLOT = 0x1,
DECT_DOUBLE_SLOT = 0x2,
DECT_LONG_SLOT_640 = 0x3,
DECT_LONG_SLOT_672 = 0x4,
};
struct dect_mac_conn_params {
enum dect_mac_connection_types type;
enum dect_mac_service_types service;
enum dect_slot_types slot;
};
/**
* struct dect_dl_encrypt - DL_ENCRYPT primitive arguments
*
* @status: desired/achieved encryption status
*/
struct dect_dl_encrypt {
enum dect_cipher_states status;
};
/**
* struct sockaddr_dect_lu - DLC U-plane LUx service instance address
*
* @dect_family: address family (AF_DECT)
* @dect_mci: MAC Connection Identifier
*/
struct sockaddr_dect_lu {
sa_family_t dect_family;
int dect_index;
__u64 dect_ari:40,
dect_pmid:20,
dect_lcn:3;
};
/* LU1 SAP */
#define DECT_LU1_QUEUE_STATS 0
struct dect_lu1_queue_stats {
__u32 rx_bytes;
__u32 rx_underflow;
__u32 tx_bytes;
__u32 tx_underflow;
};
#endif /* _LINUX_DECT_H */

View File

@ -0,0 +1,397 @@
#ifndef _LINUX_DECT_NETLINK_H
#define _LINUX_DECT_NETLINK_H
struct dectmsg {
int dm_index;
};
enum dect_nlgroups {
DECTNLGRP_NONE,
DECTNLGRP_TRANSCEIVER,
DECTNLGRP_CELL,
DECTNLGRP_CLUSTER,
DECTNLGRP_LLME,
__DECTNLGRP_MAX
};
#define DECTNLGRP_MAX (__DECTNLGRP_MAX - 1)
enum dect_netlink_msg_types {
DECT_MSG_BASE = 0x10,
DECT_NEW_TRANSCEIVER,
DECT_DEL_TRANSCEIVER,
DECT_GET_TRANSCEIVER,
DECT_NEW_CELL,
DECT_DEL_CELL,
DECT_GET_CELL,
DECT_NEW_CLUSTER,
DECT_DEL_CLUSTER,
DECT_GET_CLUSTER,
DECT_LLME_MSG,
__DECT_MSG_MAX
};
#define DECT_MSG_MAX (__DECT_MSG_MAX - 1)
#define DECT_NR_MSGTYPES (DECT_MSG_MAX + 1 - DECT_MSG_BASE)
enum dect_list_attrs {
DECTA_LIST_UNSPEC,
DECTA_LIST_ELEM,
__DECTA_LIST_MAX
};
#define DECTA_LIST_MAX (__DECTA_LIST_MAX - 1)
enum dect_slot_states {
DECT_SLOT_IDLE,
DECT_SLOT_SCANNING,
DECT_SLOT_RX,
DECT_SLOT_TX,
};
enum dect_slot_flags {
DECT_SLOT_SYNC = 0x1,
DECT_SLOT_CIPHER = 0x2,
};
/**
* enum dect_packet_types - DECT Physical Packet Types
*
* @DECT_PACKET_P00: short physical packet P00, 96 bits, A-field only
* @DECT_PACKET_P08: low capacity physical packet P08j, 180 bits
* @DECT_PACKET_P32: basic physical packet P32, 420 bits
* @DECT_PACKET_P80: high capacity physical packet P80, 900 bits
* @DECT_PACKET_P640j: variable capacity packet P640j, 712 bits
* @DECT_PACKET_P672j: variable capacity packet P640j, 744 bits
*/
enum dect_packet_types {
DECT_PACKET_P00,
DECT_PACKET_P08,
DECT_PACKET_P32,
DECT_PACKET_P80,
DECT_PACKET_P640j,
DECT_PACKET_P672j,
__DECT_PACKET_MAX
};
#define DECT_PACKET_MAX (__DECT_PACKET_MAX - 1)
#define DECT_PHASE_OFFSET_SCALE 1024
enum dect_slot_attrs {
DECTA_SLOT_UNSPEC,
DECTA_SLOT_NUM,
DECTA_SLOT_STATE,
DECTA_SLOT_FLAGS,
DECTA_SLOT_PACKET,
DECTA_SLOT_CARRIER,
DECTA_SLOT_FREQUENCY,
DECTA_SLOT_PHASEOFF,
DECTA_SLOT_RSSI,
DECTA_SLOT_RX_PACKETS,
DECTA_SLOT_RX_BYTES,
DECTA_SLOT_RX_A_CRC_ERRORS,
DECTA_SLOT_RX_X_CRC_ERRORS,
DECTA_SLOT_RX_Z_CRC_ERRORS,
DECTA_SLOT_TX_PACKETS,
DECTA_SLOT_TX_BYTES,
__DECTA_SLOT_MAX
};
#define DECTA_SLOT_MAX (__DECTA_SLOT_MAX - 1)
enum dect_transceiver_stats_attrs {
DECTA_TRANSCEIVER_STATS_UNSPEC,
DECTA_TRANSCEIVER_STATS_EVENT_BUSY,
DECTA_TRANSCEIVER_STATS_EVENT_LATE,
__DECTA_TRANSCEIVER_STATS_MAX
};
#define DECTA_TRANSCEIVER_STATS_MAX (__DECTA_TRANSCEIVER_STATS_MAX - 1)
/**
* @DECT_TRANSCEIVER_SLOW_HOPPING: transceiver has slow hopping radio
* @DECT_TRANSCEIVER_PACKET_P64: transceiver supports packet P640j
*/
enum dect_transceiver_features {
DECT_TRANSCEIVER_SLOW_HOPPING = 0x1,
DECT_TRANSCEIVER_PACKET_P64 = 0x2,
};
enum dect_transceiver_attrs {
DECTA_TRANSCEIVER_UNSPEC,
DECTA_TRANSCEIVER_NAME,
DECTA_TRANSCEIVER_TYPE,
DECTA_TRANSCEIVER_FEATURES,
DECTA_TRANSCEIVER_LINK,
DECTA_TRANSCEIVER_STATS,
DECTA_TRANSCEIVER_BAND,
DECTA_TRANSCEIVER_SLOTS,
__DECTA_TRANSCEIVER_MAX
};
#define DECTA_TRANSCEIVER_MAX (__DECTA_TRANSCEIVER_MAX - 1)
enum dect_cell_flags {
DECT_CELL_CCP = (1 << 0),
DECT_CELL_SLAVE = (1 << 1),
DECT_CELL_MONITOR = (1 << 2),
};
enum dect_cell_attrs {
DECTA_CELL_UNSPEC,
DECTA_CELL_NAME,
DECTA_CELL_FLAGS,
DECTA_CELL_TRANSCEIVERS,
DECTA_CELL_CLUSTER,
__DECTA_CELL_MAX
};
#define DECTA_CELL_MAX (__DECTA_CELL_MAX - 1)
enum dect_mbc_state {
DECT_MBC_NONE,
DECT_MBC_INITIATED,
DECT_MBC_ESTABLISHED,
DECT_MBC_RELEASED,
};
enum dect_mbc_tb_attrs {
DECTA_MBC_TB_UNSPEC,
DECTA_MBC_TB_LBN,
DECTA_MBC_TB_ECN,
DECTA_MBC_TB_CELL,
DECTA_MBC_TB_RX_SLOT,
DECTA_MBC_TB_TX_SLOT,
__DECTA_MBC_TB_MAX,
};
#define DECTA_MBC_TB_MAX (__DECTA_MBC_TB_MAX - 1)
enum dect_mbc_stats_attrs {
DECTA_MBC_STATS_UNSPEC,
DECTA_MBC_STATS_CS_RX_BYTES,
DECTA_MBC_STATS_CS_TX_BYTES,
DECTA_MBC_STATS_I_RX_BYTES,
DECTA_MBC_STATS_I_TX_BYTES,
DECTA_MBC_STATS_HANDOVERS,
__DECTA_MBC_STATS_MAX,
};
#define DECTA_MBC_STATS_MAX (__DECTA_MBC_STATS_MAX - 1)
enum dect_mbc_attrs {
DECTA_MBC_UNSPEC,
DECTA_MBC_MCEI,
DECTA_MBC_SERVICE,
DECTA_MBC_STATE,
DECTA_MBC_CIPHER_STATE,
DECTA_MBC_STATS,
DECTA_MBC_TBS,
__DECTA_MBC_MAX,
};
#define DECTA_MBC_MAX (__DECTA_MBC_MAX - 1)
enum dect_cluster_attrs {
DECTA_CLUSTER_UNSPEC,
DECTA_CLUSTER_NAME,
DECTA_CLUSTER_MODE,
DECTA_CLUSTER_PARI,
DECTA_CLUSTER_CELLS,
DECTA_CLUSTER_MBCS,
__DECTA_CLUSTER_MAX
};
#define DECTA_CLUSTER_MAX (__DECTA_CLUSTER_MAX - 1)
enum dect_cluster_modes {
DECT_MODE_FP,
DECT_MODE_PP,
};
/**
* DECT ARI classes
*
* @DECT_ARC_A: Residential and private (PBX) single- and small multiple cell systems
* @DECT_ARC_B: Private (PABXs) multiple cell
* @DECT_ARC_C: Public single and multiple cell systems
* @DECT_ARC_D: Public DECT access to a GSM network
* @DECT_ARC_E: PP to PP direct communication (private)
*/
enum dect_ari_classes {
DECT_ARC_A,
DECT_ARC_B,
DECT_ARC_C,
DECT_ARC_D,
DECT_ARC_E,
};
enum dect_ari_attrs {
DECTA_ARI_UNSPEC,
DECTA_ARI_CLASS,
DECTA_ARI_FPN,
DECTA_ARI_FPS,
DECTA_ARI_EMC,
DECTA_ARI_EIC,
DECTA_ARI_POC,
DECTA_ARI_GOP,
DECTA_ARI_FIL,
__DECTA_ARI_MAX
};
#define DECTA_ARI_MAX (__DECTA_ARI_MAX - 1)
enum decta_sari_attrs {
DECTA_SARI_UNSPEC,
DECTA_SARI_ARI,
DECTA_SARI_BLACK,
DECTA_SARI_TARI,
__DECTA_SARI_MAX
};
#define DECTA_SARI_MAX (__DECTA_SARI_MAX - 1)
enum dect_fixed_part_capabilities {
DECT_FPC_EXTENDED_FP_INFO = 0x80000,
DECT_FPC_DOUBLE_DUPLEX_BEARER_CONNECTION= 0x40000,
DECT_FPC_RESERVED = 0x20000,
DECT_FPC_DOUBLE_SLOT = 0x10000,
DECT_FPC_HALF_SLOT = 0x08000,
DECT_FPC_FULL_SLOT = 0x04000,
DECT_FPC_FREQ_CONTROL = 0x02000,
DECT_FPC_PAGE_REPETITION = 0x01000,
DECT_FPC_CO_SETUP_ON_DUMMY = 0x00800,
DECT_FPC_CL_UPLINK = 0x00400,
DECT_FPC_CL_DOWNLINK = 0x00200,
DECT_FPC_BASIC_A_FIELD_SETUP = 0x00100,
DECT_FPC_ADV_A_FIELD_SETUP = 0x00080,
DECT_FPC_B_FIELD_SETUP = 0x00040,
DECT_FPC_CF_MESSAGES = 0x00020,
DECT_FPC_IN_MIN_DELAY = 0x00010,
DECT_FPC_IN_NORM_DELAY = 0x00008,
DECT_FPC_IP_ERROR_DETECTION = 0x00004,
DECT_FPC_IP_ERROR_CORRECTION = 0x00002,
DECT_FPC_MULTIBEARER_CONNECTIONS = 0x00001,
};
enum dect_higher_layer_capabilities {
DECT_HLC_ADPCM_G721_VOICE = 0x8000,
DECT_HLC_GAP_PAP_BASIC_SPEECH = 0x4000,
DECT_HLC_NON_VOICE_CIRCUIT_SWITCHED = 0x2000,
DECT_HLC_NON_VOICE_PACKET_SWITCHED = 0x1000,
DECT_HLC_STANDARD_AUTHENTICATION = 0x0800,
DECT_HLC_STANDARD_CIPHERING = 0x0400,
DECT_HLC_LOCATION_REGISTRATION = 0x0200,
DECT_HLC_SIM_SERVICES = 0x0100,
DECT_HLC_NON_STATIC_FIXED_PART = 0x0080,
DECT_HLC_CISS_SERVICE = 0x0040,
DECT_HLC_CLMS_SERVICE = 0x0020,
DECT_HLC_COMS_SERVICE = 0x0010,
DECT_HLC_ACCESS_RIGHTS_REQUESTS = 0x0008,
DECT_HLC_EXTERNAL_HANDOVER = 0x0004,
DECT_HLC_CONNECTION_HANDOVER = 0x0002,
DECT_HLC_RESERVED = 0x0001,
};
enum dect_extended_fixed_part_capabilities {
DECT_EFPC_WRS_MASK = 0x1f80,
DECT_EFPC_WRS_CRFP_HOPS_MASK = 0x1800,
DECT_EFPC_WRS_CRFP_HOPS_1 = 0x0000,
DECT_EFPC_WRS_CRFP_HOPS_2 = 0x0800,
DECT_EFPC_WRS_CRFP_HOPS_3 = 0x1000,
DECT_EFPC_WRS_CRFP_HOPS_NONE = 0x1800,
DECT_EFPC_WRS_CRFP_ENCRYPTION = 0x0400,
DECT_EFPC_WRS_REP_HOPS_MASK = 0x0300,
DECT_EFPC_WRS_REP_HOPS_NONE = 0x0000,
DECT_EFPC_WRS_REP_HOPS_1 = 0x0100,
DECT_EFPC_WRS_REP_HOPS_2 = 0x0200,
DECT_EFPC_WRS_REP_HOPS_3 = 0x0300,
DECT_EFPC_WRS_REP_INTERLACING = 0x0080,
DECT_EFPC_SYNC_MASK = 0x0060,
DECT_EFPC_SYNC_PROLONGED_PREAMBLE = 0x0020,
DECT_EFPC_SYNC_RESERVED1 = 0x0010,
DECT_EFPC_MAC_SUSPEND_RESUME = 0x0008,
DECT_EFPC_MAC_IP_Q_SERVICE = 0x0004,
DECT_EFPC_EXTENDED_FP_INFO2 = 0x0002,
DECT_EFPC_RESERVED2 = 0x0001,
};
enum dect_extended_higher_layer_capabilities {
DECT_EHLC_ISDN_DATA_SERVICE = 0x000001,
DECT_EHLC_DPRS_FREL = 0x000002,
DECT_EHLC_DPRS_STREAM = 0x000004,
DECT_EHLC_DATA_SERVICE_PROFILE_D = 0x000008,
DECT_EHLC_LRMS = 0x000010,
DECT_EHLC_ASYMETRIC_BEARERS = 0x000040,
DECT_EHLC_EMERGENCY_CALLS = 0x000080,
DECT_EHLC_TPUI_LOCATION_REGISTRATION = 0x000100,
DECT_EHLC_GPS_SYNCHRONIZED = 0x000200,
DECT_EHLC_ISDN_INTERMEDIATE_SYSTEM = 0x000400,
DECT_EHLC_RAP_PART_1_PROFILE = 0x000800,
DECT_EHLC_V_24 = 0x004000,
DECT_EHLC_PPP = 0x008000,
DECT_EHLC_IP = 0x010000,
DECT_EHLC_TOKEN_RING = 0x020000,
DECT_EHLC_ETHERNET = 0x040000,
DECT_EHLC_IP_ROAMING = 0x080000,
DECT_EHLC_GENERIC_MEDIA_ENCAPSULATION = 0x100000,
DECT_EHLC_BASIC_ODAP = 0x200000,
DECT_EHLC_F_MMS_INTERWORKING_PROFILE = 0x400000,
};
enum dect_extended_fixed_part_capabilities2 {
DECT_EFPC2_LONG_SLOT_J640 = 0x800,
DECT_EFPC2_LONG_SLOT_J672 = 0x400,
DECT_EFPC2_IP_F = 0x200,
DECT_EFPC2_SI_PF = 0x100,
DECT_EFPC2_GF = 0x080,
DECT_EFPC2_NO_EMISSION_CARRIER = 0x001,
};
enum dect_extended_higher_layer_capabilities2 {
DECT_EHLC2_NG_DECT_PERMANENT_CLIR = 0x000100,
DECT_EHLC2_NG_DECT_MULTIPLE_CALLS = 0x000200,
DECT_EHLC2_NG_DECT_MULTIPLE_LINES = 0x000400,
DECT_EHLC2_EASY_PAIRING = 0x000800,
DECT_EHLC2_LIST_ACCESS_FEATURES = 0x001000,
DECT_EHLC2_NO_EMISSION_MODE = 0x002000,
DECT_EHLC2_NG_DECT_CALL_DEFLECTION = 0x004000,
DECT_EHLC2_NG_DECT_INTRUSION_CALL = 0x008000,
DECT_EHLC2_NG_DECT_CONFERENCE_CALL = 0x010000,
DECT_EHLC2_NG_DECT_PARALLEL_CALLS = 0x020000,
DECT_EHLC2_NG_DECT_CALL_TRANSFER = 0x040000,
DECT_EHLC2_NG_DECT_EXTENDED_WIDEBAND = 0x080000,
DECT_EHLC2_PACKET_DATA_CATEGORY_MASK = 0x700000,
DECT_EHLC2_NG_DECT_WIDEBAND = 0x800000,
};
enum dect_mac_info_attrs {
DECTA_MAC_INFO_UNSPEC,
DECTA_MAC_INFO_PARI,
DECTA_MAC_INFO_RPN,
DECTA_MAC_INFO_RSSI,
DECTA_MAC_INFO_SARI_LIST,
DECTA_MAC_INFO_FPC,
DECTA_MAC_INFO_HLC,
DECTA_MAC_INFO_EFPC,
DECTA_MAC_INFO_EHLC,
DECTA_MAC_INFO_EFPC2,
DECTA_MAC_INFO_EHLC2,
DECTA_MAC_INFO_MFN,
__DECTA_MAC_INFO_MAX
};
#define DECTA_MAC_INFO_MAX (__DECTA_MAC_INFO_MAX - 1)
enum dect_llme_ops {
DECT_LLME_REQUEST,
DECT_LLME_INDICATE,
DECT_LLME_RESPONSE,
DECT_LLME_CONFIRM,
};
enum dect_llme_msg_types {
DECT_LLME_SCAN,
DECT_LLME_MAC_INFO,
DECT_LLME_MAC_RFP_PRELOAD,
__DECT_LLME_MAX
};
#define DECT_LLME_MAX (__DECT_LLME_MAX - 1)
enum dect_llme_msg_attrs {
DECTA_LLME_UNSPEC,
DECTA_LLME_OP,
DECTA_LLME_TYPE,
DECTA_LLME_DATA,
__DECTA_LLME_MAX
};
#define DECTA_LLME_MAX (__DECTA_LLME_MAX - 1)
#endif /* _LINUX_DECT_NETLINK_H */

View File

@ -117,6 +117,12 @@ enum {
IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */
};
/* carrier state */
enum {
IF_CARRIER_DOWN,
IF_CARRIER_UP
};
/*
* Device mapping structure. I'd just gone off and designed a
* beautiful scheme using only loadable modules with arguments

185
include/linux/if_bridge.h Normal file
View File

@ -0,0 +1,185 @@
/*
* Linux ethernet bridge
*
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
* This program 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; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _UAPI_LINUX_IF_BRIDGE_H
#define _UAPI_LINUX_IF_BRIDGE_H
#include <linux/types.h>
#define SYSFS_BRIDGE_ATTR "bridge"
#define SYSFS_BRIDGE_FDB "brforward"
#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
#define SYSFS_BRIDGE_PORT_ATTR "brport"
#define SYSFS_BRIDGE_PORT_LINK "bridge"
#define BRCTL_VERSION 1
#define BRCTL_GET_VERSION 0
#define BRCTL_GET_BRIDGES 1
#define BRCTL_ADD_BRIDGE 2
#define BRCTL_DEL_BRIDGE 3
#define BRCTL_ADD_IF 4
#define BRCTL_DEL_IF 5
#define BRCTL_GET_BRIDGE_INFO 6
#define BRCTL_GET_PORT_LIST 7
#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
#define BRCTL_SET_BRIDGE_HELLO_TIME 9
#define BRCTL_SET_BRIDGE_MAX_AGE 10
#define BRCTL_SET_AGEING_TIME 11
#define BRCTL_SET_GC_INTERVAL 12
#define BRCTL_GET_PORT_INFO 13
#define BRCTL_SET_BRIDGE_STP_STATE 14
#define BRCTL_SET_BRIDGE_PRIORITY 15
#define BRCTL_SET_PORT_PRIORITY 16
#define BRCTL_SET_PATH_COST 17
#define BRCTL_GET_FDB_ENTRIES 18
#define BR_STATE_DISABLED 0
#define BR_STATE_LISTENING 1
#define BR_STATE_LEARNING 2
#define BR_STATE_FORWARDING 3
#define BR_STATE_BLOCKING 4
struct __bridge_info {
__u64 designated_root;
__u64 bridge_id;
__u32 root_path_cost;
__u32 max_age;
__u32 hello_time;
__u32 forward_delay;
__u32 bridge_max_age;
__u32 bridge_hello_time;
__u32 bridge_forward_delay;
__u8 topology_change;
__u8 topology_change_detected;
__u8 root_port;
__u8 stp_enabled;
__u32 ageing_time;
__u32 gc_interval;
__u32 hello_timer_value;
__u32 tcn_timer_value;
__u32 topology_change_timer_value;
__u32 gc_timer_value;
};
struct __port_info {
__u64 designated_root;
__u64 designated_bridge;
__u16 port_id;
__u16 designated_port;
__u32 path_cost;
__u32 designated_cost;
__u8 state;
__u8 top_change_ack;
__u8 config_pending;
__u8 unused0;
__u32 message_age_timer_value;
__u32 forward_delay_timer_value;
__u32 hold_timer_value;
};
struct __fdb_entry {
__u8 mac_addr[6];
__u8 port_no;
__u8 is_local;
__u32 ageing_timer_value;
__u8 port_hi;
__u8 pad0;
__u16 unused;
};
/* Bridge Flags */
#define BRIDGE_FLAGS_MASTER 1 /* Bridge command to/from master */
#define BRIDGE_FLAGS_SELF 2 /* Bridge command to/from lowerdev */
#define BRIDGE_MODE_VEB 0 /* Default loopback mode */
#define BRIDGE_MODE_VEPA 1 /* 802.1Qbg defined VEPA mode */
/* Bridge management nested attributes
* [IFLA_AF_SPEC] = {
* [IFLA_BRIDGE_FLAGS]
* [IFLA_BRIDGE_MODE]
* }
*/
enum {
IFLA_BRIDGE_FLAGS,
IFLA_BRIDGE_MODE,
__IFLA_BRIDGE_MAX,
};
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
/* Bridge multicast database attributes
* [MDBA_MDB] = {
* [MDBA_MDB_ENTRY] = {
* [MDBA_MDB_ENTRY_INFO]
* }
* }
* [MDBA_ROUTER] = {
* [MDBA_ROUTER_PORT]
* }
*/
enum {
MDBA_UNSPEC,
MDBA_MDB,
MDBA_ROUTER,
__MDBA_MAX,
};
#define MDBA_MAX (__MDBA_MAX - 1)
enum {
MDBA_MDB_UNSPEC,
MDBA_MDB_ENTRY,
__MDBA_MDB_MAX,
};
#define MDBA_MDB_MAX (__MDBA_MDB_MAX - 1)
enum {
MDBA_MDB_ENTRY_UNSPEC,
MDBA_MDB_ENTRY_INFO,
__MDBA_MDB_ENTRY_MAX,
};
#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1)
enum {
MDBA_ROUTER_UNSPEC,
MDBA_ROUTER_PORT,
__MDBA_ROUTER_MAX,
};
#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
struct br_port_msg {
__u8 family;
__u32 ifindex;
};
struct br_mdb_entry {
__u32 ifindex;
#define MDB_TEMPORARY 0
#define MDB_PERMANENT 1
__u8 state;
struct {
union {
__be32 ip4;
struct in6_addr ip6;
} u;
__be16 proto;
} addr;
};
enum {
MDBA_SET_ENTRY_UNSPEC,
MDBA_SET_ENTRY,
__MDBA_SET_ENTRY_MAX,
};
#define MDBA_SET_ENTRY_MAX (__MDBA_SET_ENTRY_MAX - 1)
#endif /* _UAPI_LINUX_IF_BRIDGE_H */

View File

@ -1,5 +1,5 @@
#ifndef _LINUX_IF_LINK_H
#define _LINUX_IF_LINK_H
#ifndef _UAPI_LINUX_IF_LINK_H
#define _UAPI_LINUX_IF_LINK_H
#include <linux/types.h>
#include <linux/netlink.h>
@ -142,6 +142,7 @@ enum {
#define IFLA_PROMISCUITY IFLA_PROMISCUITY
IFLA_NUM_TX_QUEUES,
IFLA_NUM_RX_QUEUES,
IFLA_CARRIER,
__IFLA_MAX
};
@ -199,6 +200,24 @@ enum {
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
enum {
BRIDGE_MODE_UNSPEC,
BRIDGE_MODE_HAIRPIN,
};
enum {
IFLA_BRPORT_UNSPEC,
IFLA_BRPORT_STATE, /* Spanning tree state */
IFLA_BRPORT_PRIORITY, /* " priority */
IFLA_BRPORT_COST, /* " cost */
IFLA_BRPORT_MODE, /* mode (hairpin) */
IFLA_BRPORT_GUARD, /* bpdu guard */
IFLA_BRPORT_PROTECT, /* root port protection */
IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
struct ifla_cacheinfo {
__u32 max_reasm_len;
__u32 tstamp; /* ipv6InterfaceTable updated timestamp */
@ -266,6 +285,32 @@ enum macvlan_mode {
#define MACVLAN_FLAG_NOPROMISC 1
/* VXLAN section */
enum {
IFLA_VXLAN_UNSPEC,
IFLA_VXLAN_ID,
IFLA_VXLAN_GROUP,
IFLA_VXLAN_LINK,
IFLA_VXLAN_LOCAL,
IFLA_VXLAN_TTL,
IFLA_VXLAN_TOS,
IFLA_VXLAN_LEARNING,
IFLA_VXLAN_AGEING,
IFLA_VXLAN_LIMIT,
IFLA_VXLAN_PORT_RANGE,
IFLA_VXLAN_PROXY,
IFLA_VXLAN_RSC,
IFLA_VXLAN_L2MISS,
IFLA_VXLAN_L3MISS,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
struct ifla_vxlan_port_range {
__be16 low;
__be16 high;
};
/* SR-IOV virtual function management section */
enum {
@ -307,18 +352,6 @@ struct ifla_vf_spoofchk {
__u32 vf;
__u32 setting;
};
#ifdef __KERNEL__
/* We don't want this structure exposed to user space */
struct ifla_vf_info {
__u32 vf;
__u8 mac[32];
__u32 vlan;
__u32 qos;
__u32 tx_rate;
__u32 spoofchk;
};
#endif
/* VF ports management section
*
@ -392,4 +425,22 @@ struct ifla_port_vsi {
__u8 pad[3];
};
#endif /* _LINUX_IF_LINK_H */
/* IPoIB section */
enum {
IFLA_IPOIB_UNSPEC,
IFLA_IPOIB_PKEY,
IFLA_IPOIB_MODE,
IFLA_IPOIB_UMCAST,
__IFLA_IPOIB_MAX
};
enum {
IPOIB_MODE_DATAGRAM = 0, /* using unreliable datagram QPs */
IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
};
#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
#endif /* _UAPI_LINUX_IF_LINK_H */

View File

@ -0,0 +1,117 @@
#ifndef _UAPI_NF_CONNTRACK_COMMON_H
#define _UAPI_NF_CONNTRACK_COMMON_H
/* Connection state tracking for netfilter. This is separated from,
but required by, the NAT layer; it can also be used by an iptables
extension. */
enum ip_conntrack_info {
/* Part of an established connection (either direction). */
IP_CT_ESTABLISHED,
/* Like NEW, but related to an existing connection, or ICMP error
(in either direction). */
IP_CT_RELATED,
/* Started a new connection to track (only
IP_CT_DIR_ORIGINAL); may be a retransmission. */
IP_CT_NEW,
/* >= this indicates reply direction */
IP_CT_IS_REPLY,
IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,
/* Number of distinct IP_CT types (no NEW in reply dirn). */
IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
};
/* Bitset representing status of connection. */
enum ip_conntrack_status {
/* It's an expected connection: bit 0 set. This bit never changed */
IPS_EXPECTED_BIT = 0,
IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
/* We've seen packets both ways: bit 1 set. Can be set, not unset. */
IPS_SEEN_REPLY_BIT = 1,
IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
/* Conntrack should never be early-expired. */
IPS_ASSURED_BIT = 2,
IPS_ASSURED = (1 << IPS_ASSURED_BIT),
/* Connection is confirmed: originating packet has left box */
IPS_CONFIRMED_BIT = 3,
IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
/* Connection needs src nat in orig dir. This bit never changed. */
IPS_SRC_NAT_BIT = 4,
IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
/* Connection needs dst nat in orig dir. This bit never changed. */
IPS_DST_NAT_BIT = 5,
IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
/* Both together. */
IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
/* Connection needs TCP sequence adjusted. */
IPS_SEQ_ADJUST_BIT = 6,
IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
/* NAT initialization bits. */
IPS_SRC_NAT_DONE_BIT = 7,
IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
IPS_DST_NAT_DONE_BIT = 8,
IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
/* Both together */
IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
/* Connection is dying (removed from lists), can not be unset. */
IPS_DYING_BIT = 9,
IPS_DYING = (1 << IPS_DYING_BIT),
/* Connection has fixed timeout. */
IPS_FIXED_TIMEOUT_BIT = 10,
IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
/* Conntrack is a template */
IPS_TEMPLATE_BIT = 11,
IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
/* Conntrack is a fake untracked entry */
IPS_UNTRACKED_BIT = 12,
IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
/* Conntrack got a helper explicitly attached via CT target. */
IPS_HELPER_BIT = 13,
IPS_HELPER = (1 << IPS_HELPER_BIT),
};
/* Connection tracking event types */
enum ip_conntrack_events {
IPCT_NEW, /* new conntrack */
IPCT_RELATED, /* related conntrack */
IPCT_DESTROY, /* destroyed conntrack */
IPCT_REPLY, /* connection has seen two-way traffic */
IPCT_ASSURED, /* connection status has changed to assured */
IPCT_PROTOINFO, /* protocol information has changed */
IPCT_HELPER, /* new helper has been set */
IPCT_MARK, /* new mark has been set */
IPCT_NATSEQADJ, /* NAT is doing sequence adjustment */
IPCT_SECMARK, /* new security mark has been set */
};
enum ip_conntrack_expect_events {
IPEXP_NEW, /* new expectation */
IPEXP_DESTROY, /* destroyed expectation */
};
/* expectation flags */
#define NF_CT_EXPECT_PERMANENT 0x1
#define NF_CT_EXPECT_INACTIVE 0x2
#define NF_CT_EXPECT_USERSPACE 0x4
#endif /* _UAPI_NF_CONNTRACK_COMMON_H */

View File

@ -1,96 +1,56 @@
#ifndef _NFNETLINK_H
#define _NFNETLINK_H
#ifndef _UAPI_NFNETLINK_H
#define _UAPI_NFNETLINK_H
#include <linux/types.h>
#include <linux/netfilter/nfnetlink_compat.h>
enum nfnetlink_groups {
NFNLGRP_NONE,
#define NFNLGRP_NONE NFNLGRP_NONE
NFNLGRP_CONNTRACK_NEW,
#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
NFNLGRP_CONNTRACK_UPDATE,
#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
NFNLGRP_CONNTRACK_DESTROY,
#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
NFNLGRP_CONNTRACK_EXP_NEW,
#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
NFNLGRP_CONNTRACK_EXP_UPDATE,
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY,
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
__NFNLGRP_MAX,
NFNLGRP_NONE,
#define NFNLGRP_NONE NFNLGRP_NONE
NFNLGRP_CONNTRACK_NEW,
#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
NFNLGRP_CONNTRACK_UPDATE,
#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
NFNLGRP_CONNTRACK_DESTROY,
#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
NFNLGRP_CONNTRACK_EXP_NEW,
#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
NFNLGRP_CONNTRACK_EXP_UPDATE,
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY,
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
/* General form of address family dependent message.
*/
struct nfgenmsg {
__u8 nfgen_family; /* AF_xxx */
__u8 version; /* nfnetlink version */
__be16 res_id; /* resource id */
__u8 nfgen_family; /* AF_xxx */
__u8 version; /* nfnetlink version */
__be16 res_id; /* resource id */
};
#define NFNETLINK_V0 0
#define NFNETLINK_V0 0
/* netfilter netlink message types are split in two pieces:
* 8 bit subsystem, 8bit operation.
*/
#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
#define NFNL_MSG_TYPE(x) (x & 0x00ff)
#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
#define NFNL_MSG_TYPE(x) (x & 0x00ff)
/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
* won't work anymore */
#define NFNL_SUBSYS_NONE 0
#define NFNL_SUBSYS_CTNETLINK 1
#define NFNL_SUBSYS_CTNETLINK_EXP 2
#define NFNL_SUBSYS_QUEUE 3
#define NFNL_SUBSYS_ULOG 4
#define NFNL_SUBSYS_OSF 5
#define NFNL_SUBSYS_IPSET 6
#define NFNL_SUBSYS_ACCT 7
#define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8
#define NFNL_SUBSYS_CTHELPER 9
#define NFNL_SUBSYS_COUNT 10
#define NFNL_SUBSYS_NONE 0
#define NFNL_SUBSYS_CTNETLINK 1
#define NFNL_SUBSYS_CTNETLINK_EXP 2
#define NFNL_SUBSYS_QUEUE 3
#define NFNL_SUBSYS_ULOG 4
#define NFNL_SUBSYS_OSF 5
#define NFNL_SUBSYS_IPSET 6
#define NFNL_SUBSYS_ACCT 7
#define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8
#define NFNL_SUBSYS_CTHELPER 9
#define NFNL_SUBSYS_COUNT 10
#ifdef __KERNEL__
#include <linux/netlink.h>
#include <linux/capability.h>
#include <net/netlink.h>
struct nfnl_callback {
int (*call)(struct sock *nl, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const cda[]);
int (*call_rcu)(struct sock *nl, struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const cda[]);
const struct nla_policy *policy; /* netlink attribute policy */
const u_int16_t attr_count; /* number of nlattr's */
};
struct nfnetlink_subsystem {
const char *name;
__u8 subsys_id; /* nfnetlink subsystem ID */
__u8 cb_count; /* number of callbacks */
const struct nfnl_callback *cb; /* callback for individual types */
};
extern int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n);
extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
extern int nfnetlink_has_listeners(struct net *net, unsigned int group);
extern int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned int group,
int echo, gfp_t flags);
extern int nfnetlink_set_err(struct net *net, u32 pid, u32 group, int error);
extern int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u_int32_t pid, int flags);
extern void nfnl_lock(void);
extern void nfnl_unlock(void);
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
#endif /* __KERNEL__ */
#endif /* _NFNETLINK_H */
#endif /* _UAPI_NFNETLINK_H */

View File

@ -0,0 +1,63 @@
#ifndef _NFNETLINK_COMPAT_H
#define _NFNETLINK_COMPAT_H
#include <linux/types.h>
#ifndef __KERNEL__
/* Old nfnetlink macros for userspace */
/* nfnetlink groups: Up to 32 maximum */
#define NF_NETLINK_CONNTRACK_NEW 0x00000001
#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002
#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004
#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
/* Generic structure for encapsulation optional netfilter information.
* It is reminiscent of sockaddr, but with sa_family replaced
* with attribute type.
* ! This should someday be put somewhere generic as now rtnetlink and
* ! nfnetlink use the same attributes methods. - J. Schulist.
*/
struct nfattr {
__u16 nfa_len;
__u16 nfa_type; /* we use 15 bits for the type, and the highest
* bit to indicate whether the payload is nested */
};
/* FIXME: Apart from NFNL_NFA_NESTED shamelessly copy and pasted from
* rtnetlink.h, it's time to put this in a generic file */
#define NFNL_NFA_NEST 0x8000
#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
#define NFA_ALIGNTO 4
#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \
&& (nfa)->nfa_len <= (len))
#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \
(struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len)))
#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len))
#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len))
#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0)))
#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
#define NFA_NEST(skb, type) \
({ struct nfattr *__start = (struct nfattr *)skb_tail_pointer(skb); \
NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL); \
__start; })
#define NFA_NEST_END(skb, start) \
({ (start)->nfa_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
(skb)->len; })
#define NFA_NEST_CANCEL(skb, start) \
({ if (start) \
skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
-1; })
#define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \
+ NLMSG_ALIGN(sizeof(struct nfgenmsg))))
#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg))
#endif /* ! __KERNEL__ */
#endif /* _NFNETLINK_COMPAT_H */

View File

@ -3,241 +3,245 @@
#include <linux/netfilter/nfnetlink.h>
enum cntl_msg_types {
IPCTNL_MSG_CT_NEW,
IPCTNL_MSG_CT_GET,
IPCTNL_MSG_CT_DELETE,
IPCTNL_MSG_CT_GET_CTRZERO,
IPCTNL_MSG_CT_GET_STATS_CPU,
IPCTNL_MSG_CT_GET_STATS,
IPCTNL_MSG_CT_NEW,
IPCTNL_MSG_CT_GET,
IPCTNL_MSG_CT_DELETE,
IPCTNL_MSG_CT_GET_CTRZERO,
IPCTNL_MSG_CT_GET_STATS_CPU,
IPCTNL_MSG_CT_GET_STATS,
IPCTNL_MSG_MAX
IPCTNL_MSG_MAX
};
enum ctnl_exp_msg_types {
IPCTNL_MSG_EXP_NEW,
IPCTNL_MSG_EXP_GET,
IPCTNL_MSG_EXP_DELETE,
IPCTNL_MSG_EXP_GET_STATS_CPU,
IPCTNL_MSG_EXP_NEW,
IPCTNL_MSG_EXP_GET,
IPCTNL_MSG_EXP_DELETE,
IPCTNL_MSG_EXP_GET_STATS_CPU,
IPCTNL_MSG_EXP_MAX
IPCTNL_MSG_EXP_MAX
};
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_NAT_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_REPLY,
CTA_SECMARK, /* obsolete */
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
__CTA_MAX
CTA_UNSPEC,
CTA_TUPLE_ORIG,
CTA_TUPLE_REPLY,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT_SRC,
#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS_ORIG,
CTA_COUNTERS_REPLY,
CTA_USE,
CTA_ID,
CTA_NAT_DST,
CTA_TUPLE_MASTER,
CTA_NAT_SEQ_ADJ_ORIG,
CTA_NAT_SEQ_ADJ_REPLY,
CTA_SECMARK, /* obsolete */
CTA_ZONE,
CTA_SECCTX,
CTA_TIMESTAMP,
CTA_MARK_MASK,
__CTA_MAX
};
#define CTA_MAX (__CTA_MAX - 1)
enum ctattr_tuple {
CTA_TUPLE_UNSPEC,
CTA_TUPLE_IP,
CTA_TUPLE_PROTO,
__CTA_TUPLE_MAX
CTA_TUPLE_UNSPEC,
CTA_TUPLE_IP,
CTA_TUPLE_PROTO,
__CTA_TUPLE_MAX
};
#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
enum ctattr_ip {
CTA_IP_UNSPEC,
CTA_IP_V4_SRC,
CTA_IP_V4_DST,
CTA_IP_V6_SRC,
CTA_IP_V6_DST,
__CTA_IP_MAX
CTA_IP_UNSPEC,
CTA_IP_V4_SRC,
CTA_IP_V4_DST,
CTA_IP_V6_SRC,
CTA_IP_V6_DST,
__CTA_IP_MAX
};
#define CTA_IP_MAX (__CTA_IP_MAX - 1)
enum ctattr_l4proto {
CTA_PROTO_UNSPEC,
CTA_PROTO_NUM,
CTA_PROTO_SRC_PORT,
CTA_PROTO_DST_PORT,
CTA_PROTO_ICMP_ID,
CTA_PROTO_ICMP_TYPE,
CTA_PROTO_ICMP_CODE,
CTA_PROTO_ICMPV6_ID,
CTA_PROTO_ICMPV6_TYPE,
CTA_PROTO_ICMPV6_CODE,
__CTA_PROTO_MAX
CTA_PROTO_UNSPEC,
CTA_PROTO_NUM,
CTA_PROTO_SRC_PORT,
CTA_PROTO_DST_PORT,
CTA_PROTO_ICMP_ID,
CTA_PROTO_ICMP_TYPE,
CTA_PROTO_ICMP_CODE,
CTA_PROTO_ICMPV6_ID,
CTA_PROTO_ICMPV6_TYPE,
CTA_PROTO_ICMPV6_CODE,
__CTA_PROTO_MAX
};
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
enum ctattr_protoinfo {
CTA_PROTOINFO_UNSPEC,
CTA_PROTOINFO_TCP,
CTA_PROTOINFO_DCCP,
CTA_PROTOINFO_SCTP,
__CTA_PROTOINFO_MAX
CTA_PROTOINFO_UNSPEC,
CTA_PROTOINFO_TCP,
CTA_PROTOINFO_DCCP,
CTA_PROTOINFO_SCTP,
__CTA_PROTOINFO_MAX
};
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
enum ctattr_protoinfo_tcp {
CTA_PROTOINFO_TCP_UNSPEC,
CTA_PROTOINFO_TCP_STATE,
CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
CTA_PROTOINFO_TCP_WSCALE_REPLY,
CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
CTA_PROTOINFO_TCP_FLAGS_REPLY,
__CTA_PROTOINFO_TCP_MAX
CTA_PROTOINFO_TCP_UNSPEC,
CTA_PROTOINFO_TCP_STATE,
CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
CTA_PROTOINFO_TCP_WSCALE_REPLY,
CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
CTA_PROTOINFO_TCP_FLAGS_REPLY,
__CTA_PROTOINFO_TCP_MAX
};
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
enum ctattr_protoinfo_dccp {
CTA_PROTOINFO_DCCP_UNSPEC,
CTA_PROTOINFO_DCCP_STATE,
CTA_PROTOINFO_DCCP_ROLE,
CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
__CTA_PROTOINFO_DCCP_MAX,
CTA_PROTOINFO_DCCP_UNSPEC,
CTA_PROTOINFO_DCCP_STATE,
CTA_PROTOINFO_DCCP_ROLE,
CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
__CTA_PROTOINFO_DCCP_MAX,
};
#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
enum ctattr_protoinfo_sctp {
CTA_PROTOINFO_SCTP_UNSPEC,
CTA_PROTOINFO_SCTP_STATE,
CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
CTA_PROTOINFO_SCTP_VTAG_REPLY,
__CTA_PROTOINFO_SCTP_MAX
CTA_PROTOINFO_SCTP_UNSPEC,
CTA_PROTOINFO_SCTP_STATE,
CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
CTA_PROTOINFO_SCTP_VTAG_REPLY,
__CTA_PROTOINFO_SCTP_MAX
};
#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1)
enum ctattr_counters {
CTA_COUNTERS_UNSPEC,
CTA_COUNTERS_PACKETS, /* 64bit counters */
CTA_COUNTERS_BYTES, /* 64bit counters */
CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
__CTA_COUNTERS_MAX
CTA_COUNTERS_UNSPEC,
CTA_COUNTERS_PACKETS, /* 64bit counters */
CTA_COUNTERS_BYTES, /* 64bit counters */
CTA_COUNTERS32_PACKETS, /* old 32bit counters, unused */
CTA_COUNTERS32_BYTES, /* old 32bit counters, unused */
__CTA_COUNTERS_MAX
};
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
enum ctattr_tstamp {
CTA_TIMESTAMP_UNSPEC,
CTA_TIMESTAMP_START,
CTA_TIMESTAMP_STOP,
__CTA_TIMESTAMP_MAX
CTA_TIMESTAMP_UNSPEC,
CTA_TIMESTAMP_START,
CTA_TIMESTAMP_STOP,
__CTA_TIMESTAMP_MAX
};
#define CTA_TIMESTAMP_MAX (__CTA_TIMESTAMP_MAX - 1)
enum ctattr_nat {
CTA_NAT_UNSPEC,
CTA_NAT_MINIP,
CTA_NAT_MAXIP,
CTA_NAT_PROTO,
__CTA_NAT_MAX
CTA_NAT_UNSPEC,
CTA_NAT_V4_MINIP,
#define CTA_NAT_MINIP CTA_NAT_V4_MINIP
CTA_NAT_V4_MAXIP,
#define CTA_NAT_MAXIP CTA_NAT_V4_MAXIP
CTA_NAT_PROTO,
CTA_NAT_V6_MINIP,
CTA_NAT_V6_MAXIP,
__CTA_NAT_MAX
};
#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
enum ctattr_protonat {
CTA_PROTONAT_UNSPEC,
CTA_PROTONAT_PORT_MIN,
CTA_PROTONAT_PORT_MAX,
__CTA_PROTONAT_MAX
CTA_PROTONAT_UNSPEC,
CTA_PROTONAT_PORT_MIN,
CTA_PROTONAT_PORT_MAX,
__CTA_PROTONAT_MAX
};
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
enum ctattr_natseq {
CTA_NAT_SEQ_UNSPEC,
CTA_NAT_SEQ_CORRECTION_POS,
CTA_NAT_SEQ_OFFSET_BEFORE,
CTA_NAT_SEQ_OFFSET_AFTER,
__CTA_NAT_SEQ_MAX
CTA_NAT_SEQ_UNSPEC,
CTA_NAT_SEQ_CORRECTION_POS,
CTA_NAT_SEQ_OFFSET_BEFORE,
CTA_NAT_SEQ_OFFSET_AFTER,
__CTA_NAT_SEQ_MAX
};
#define CTA_NAT_SEQ_MAX (__CTA_NAT_SEQ_MAX - 1)
enum ctattr_expect {
CTA_EXPECT_UNSPEC,
CTA_EXPECT_MASTER,
CTA_EXPECT_TUPLE,
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
CTA_EXPECT_ZONE,
CTA_EXPECT_FLAGS,
CTA_EXPECT_CLASS,
CTA_EXPECT_NAT,
CTA_EXPECT_FN,
__CTA_EXPECT_MAX
CTA_EXPECT_UNSPEC,
CTA_EXPECT_MASTER,
CTA_EXPECT_TUPLE,
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
CTA_EXPECT_ID,
CTA_EXPECT_HELP_NAME,
CTA_EXPECT_ZONE,
CTA_EXPECT_FLAGS,
CTA_EXPECT_CLASS,
CTA_EXPECT_NAT,
CTA_EXPECT_FN,
__CTA_EXPECT_MAX
};
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
enum ctattr_expect_nat {
CTA_EXPECT_NAT_UNSPEC,
CTA_EXPECT_NAT_DIR,
CTA_EXPECT_NAT_TUPLE,
__CTA_EXPECT_NAT_MAX
CTA_EXPECT_NAT_UNSPEC,
CTA_EXPECT_NAT_DIR,
CTA_EXPECT_NAT_TUPLE,
__CTA_EXPECT_NAT_MAX
};
#define CTA_EXPECT_NAT_MAX (__CTA_EXPECT_NAT_MAX - 1)
enum ctattr_help {
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
CTA_HELP_INFO,
__CTA_HELP_MAX
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
CTA_HELP_INFO,
__CTA_HELP_MAX
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
enum ctattr_secctx {
CTA_SECCTX_UNSPEC,
CTA_SECCTX_NAME,
__CTA_SECCTX_MAX
CTA_SECCTX_UNSPEC,
CTA_SECCTX_NAME,
__CTA_SECCTX_MAX
};
#define CTA_SECCTX_MAX (__CTA_SECCTX_MAX - 1)
enum ctattr_stats_cpu {
CTA_STATS_UNSPEC,
CTA_STATS_SEARCHED,
CTA_STATS_FOUND,
CTA_STATS_NEW,
CTA_STATS_INVALID,
CTA_STATS_IGNORE,
CTA_STATS_DELETE,
CTA_STATS_DELETE_LIST,
CTA_STATS_INSERT,
CTA_STATS_INSERT_FAILED,
CTA_STATS_DROP,
CTA_STATS_EARLY_DROP,
CTA_STATS_ERROR,
CTA_STATS_SEARCH_RESTART,
__CTA_STATS_MAX,
CTA_STATS_UNSPEC,
CTA_STATS_SEARCHED,
CTA_STATS_FOUND,
CTA_STATS_NEW,
CTA_STATS_INVALID,
CTA_STATS_IGNORE,
CTA_STATS_DELETE,
CTA_STATS_DELETE_LIST,
CTA_STATS_INSERT,
CTA_STATS_INSERT_FAILED,
CTA_STATS_DROP,
CTA_STATS_EARLY_DROP,
CTA_STATS_ERROR,
CTA_STATS_SEARCH_RESTART,
__CTA_STATS_MAX,
};
#define CTA_STATS_MAX (__CTA_STATS_MAX - 1)
enum ctattr_stats_global {
CTA_STATS_GLOBAL_UNSPEC,
CTA_STATS_GLOBAL_ENTRIES,
__CTA_STATS_GLOBAL_MAX,
CTA_STATS_GLOBAL_UNSPEC,
CTA_STATS_GLOBAL_ENTRIES,
__CTA_STATS_GLOBAL_MAX,
};
#define CTA_STATS_GLOBAL_MAX (__CTA_STATS_GLOBAL_MAX - 1)
enum ctattr_expect_stats {
CTA_STATS_EXP_UNSPEC,
CTA_STATS_EXP_NEW,
CTA_STATS_EXP_CREATE,
CTA_STATS_EXP_DELETE,
__CTA_STATS_EXP_MAX,
CTA_STATS_EXP_UNSPEC,
CTA_STATS_EXP_NEW,
CTA_STATS_EXP_CREATE,
CTA_STATS_EXP_DELETE,
__CTA_STATS_EXP_MAX,
};
#define CTA_STATS_EXP_MAX (__CTA_STATS_EXP_MAX - 1)

View File

@ -5,6 +5,10 @@
* and not any kind of function definitions. It is shared between kernel and
* userspace. Don't put kernel specific stuff in here */
#ifndef __aligned_be64
#define __aligned_be64 u_int64_t __attribute__((aligned(8)))
#endif
#include <linux/types.h>
#include <linux/netfilter/nfnetlink.h>

View File

@ -4,97 +4,102 @@
#include <linux/types.h>
#include <linux/netfilter/nfnetlink.h>
enum nfqnl_msg_types {
NFQNL_MSG_PACKET, /* packet from kernel to userspace */
NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */
NFQNL_MSG_CONFIG, /* connect to a particular queue */
NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */
#ifndef __aligned_be64
#define __aligned_be64 u_int64_t __attribute__((aligned(8)))
#endif
NFQNL_MSG_MAX
enum nfqnl_msg_types {
NFQNL_MSG_PACKET, /* packet from kernel to userspace */
NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */
NFQNL_MSG_CONFIG, /* connect to a particular queue */
NFQNL_MSG_VERDICT_BATCH, /* batchv from userspace to kernel */
NFQNL_MSG_MAX
};
struct nfqnl_msg_packet_hdr {
__be32 packet_id; /* unique ID of packet in queue */
__be16 hw_protocol; /* hw protocol (network order) */
__u8 hook; /* netfilter hook */
__be32 packet_id; /* unique ID of packet in queue */
__be16 hw_protocol; /* hw protocol (network order) */
__u8 hook; /* netfilter hook */
} __attribute__ ((packed));
struct nfqnl_msg_packet_hw {
__be16 hw_addrlen;
__u16 _pad;
__u8 hw_addr[8];
__be16 hw_addrlen;
__u16 _pad;
__u8 hw_addr[8];
};
struct nfqnl_msg_packet_timestamp {
__aligned_be64 sec;
__aligned_be64 usec;
__aligned_be64 sec;
__aligned_be64 usec;
};
enum nfqnl_attr_type {
NFQA_UNSPEC,
NFQA_PACKET_HDR,
NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */
NFQA_MARK, /* __u32 nfmark */
NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */
NFQA_IFINDEX_INDEV, /* __u32 ifindex */
NFQA_IFINDEX_OUTDEV, /* __u32 ifindex */
NFQA_IFINDEX_PHYSINDEV, /* __u32 ifindex */
NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
NFQA_PAYLOAD, /* opaque data payload */
NFQA_CT, /* nf_conntrack_netlink.h */
NFQA_CT_INFO, /* enum ip_conntrack_info */
NFQA_UNSPEC,
NFQA_PACKET_HDR,
NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */
NFQA_MARK, /* __u32 nfmark */
NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */
NFQA_IFINDEX_INDEV, /* __u32 ifindex */
NFQA_IFINDEX_OUTDEV, /* __u32 ifindex */
NFQA_IFINDEX_PHYSINDEV, /* __u32 ifindex */
NFQA_IFINDEX_PHYSOUTDEV, /* __u32 ifindex */
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
NFQA_PAYLOAD, /* opaque data payload */
NFQA_CT, /* nf_conntrack_netlink.h */
NFQA_CT_INFO, /* enum ip_conntrack_info */
NFQA_CAP_LEN, /* __u32 length of captured packet */
__NFQA_MAX
__NFQA_MAX
};
#define NFQA_MAX (__NFQA_MAX - 1)
struct nfqnl_msg_verdict_hdr {
__be32 verdict;
__be32 id;
__be32 verdict;
__be32 id;
};
enum nfqnl_msg_config_cmds {
NFQNL_CFG_CMD_NONE,
NFQNL_CFG_CMD_BIND,
NFQNL_CFG_CMD_UNBIND,
NFQNL_CFG_CMD_PF_BIND,
NFQNL_CFG_CMD_PF_UNBIND,
NFQNL_CFG_CMD_NONE,
NFQNL_CFG_CMD_BIND,
NFQNL_CFG_CMD_UNBIND,
NFQNL_CFG_CMD_PF_BIND,
NFQNL_CFG_CMD_PF_UNBIND,
};
struct nfqnl_msg_config_cmd {
__u8 command; /* nfqnl_msg_config_cmds */
__u8 _pad;
__be16 pf; /* AF_xxx for PF_[UN]BIND */
__u8 command; /* nfqnl_msg_config_cmds */
__u8 _pad;
__be16 pf; /* AF_xxx for PF_[UN]BIND */
};
enum nfqnl_config_mode {
NFQNL_COPY_NONE,
NFQNL_COPY_META,
NFQNL_COPY_PACKET,
NFQNL_COPY_NONE,
NFQNL_COPY_META,
NFQNL_COPY_PACKET,
};
struct nfqnl_msg_config_params {
__be32 copy_range;
__u8 copy_mode; /* enum nfqnl_config_mode */
__be32 copy_range;
__u8 copy_mode; /* enum nfqnl_config_mode */
} __attribute__ ((packed));
enum nfqnl_attr_config {
NFQA_CFG_UNSPEC,
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
NFQA_CFG_QUEUE_MAXLEN, /* __u32 */
NFQA_CFG_MASK, /* identify which flags to change */
NFQA_CFG_FLAGS, /* value of these flags (__u32) */
__NFQA_CFG_MAX
NFQA_CFG_UNSPEC,
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
NFQA_CFG_QUEUE_MAXLEN, /* __u32 */
NFQA_CFG_MASK, /* identify which flags to change */
NFQA_CFG_FLAGS, /* value of these flags (__u32) */
__NFQA_CFG_MAX
};
#define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
/* Flags for NFQA_CFG_FLAGS */
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
#define NFQA_CFG_F_CONNTRACK (1 << 1)
#define NFQA_CFG_F_MAX (1 << 2)
#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
#define NFQA_CFG_F_CONNTRACK (1 << 1)
#define NFQA_CFG_F_MAX (1 << 2)
#endif /* _NFNETLINK_QUEUE_H */

View File

@ -25,6 +25,8 @@
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
#define NETLINK_ECRYPTFS 19
#define NETLINK_RDMA 20
#define NETLINK_CRYPTO 21 /* Crypto layer */
#define NETLINK_DECT 22 /* DECT */
#define MAX_LINKS 32

View File

@ -0,0 +1,270 @@
/*
* netlink-private/cache-api.h Caching API
*
* 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) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_CACHE_API_H_
#define NETLINK_CACHE_API_H_
#include <netlink/netlink.h>
#include <netlink/cache.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup cache
* @defgroup cache_api Cache Implementation
* @brief
*
* @par 1) Cache Definition
* @code
* struct nl_cache_ops my_cache_ops = {
* .co_name = "route/link",
* .co_protocol = NETLINK_ROUTE,
* .co_hdrsize = sizeof(struct ifinfomsg),
* .co_obj_ops = &my_obj_ops,
* };
* @endcode
*
* @par 2)
* @code
* // The simplest way to fill a cache is by providing a request-update
* // function which must trigger a complete dump on the kernel-side of
* // whatever the cache covers.
* static int my_request_update(struct nl_cache *cache,
* struct nl_sock *socket)
* {
* // In this example, we request a full dump of the interface table
* return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP);
* }
*
* // The resulting netlink messages sent back will be fed into a message
* // parser one at a time. The message parser has to extract all relevant
* // information from the message and create an object reflecting the
* // contents of the message and pass it on to the parser callback function
* // provide which will add the object to the cache.
* static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
* struct nlmsghdr *nlh, struct nl_parser_param *pp)
* {
* struct my_obj *obj;
*
* obj = my_obj_alloc();
* obj->ce_msgtype = nlh->nlmsg_type;
*
* // Parse the netlink message and continue creating the object.
*
* err = pp->pp_cb((struct nl_object *) obj, pp);
* if (err < 0)
* goto errout;
* }
*
* struct nl_cache_ops my_cache_ops = {
* ...
* .co_request_update = my_request_update,
* .co_msg_parser = my_msg_parser,
* };
* @endcode
*
* @par 3) Notification based Updates
* @code
* // Caches can be kept up-to-date based on notifications if the kernel
* // sends out notifications whenever an object is added/removed/changed.
* //
* // It is trivial to support this, first a list of groups needs to be
* // defined which are required to join in order to receive all necessary
* // notifications. The groups are separated by address family to support
* // the common situation where a separate group is used for each address
* // family. If there is only one group, simply specify AF_UNSPEC.
* static struct nl_af_group addr_groups[] = {
* { AF_INET, RTNLGRP_IPV4_IFADDR },
* { AF_INET6, RTNLGRP_IPV6_IFADDR },
* { END_OF_GROUP_LIST },
* };
*
* // In order for the caching system to know the meaning of each message
* // type it requires a table which maps each supported message type to
* // a cache action, e.g. RTM_NEWADDR means address has been added or
* // updated, RTM_DELADDR means address has been removed.
* static struct nl_cache_ops rtnl_addr_ops = {
* ...
* .co_msgtypes = {
* { RTM_NEWADDR, NL_ACT_NEW, "new" },
* { RTM_DELADDR, NL_ACT_DEL, "del" },
* { RTM_GETADDR, NL_ACT_GET, "get" },
* END_OF_MSGTYPES_LIST,
* },
* .co_groups = addr_groups,
* };
*
* // It is now possible to keep the cache up-to-date using the cache manager.
* @endcode
* @{
*/
#define END_OF_MSGTYPES_LIST { -1, -1, NULL }
/**
* Message type to cache action association
*/
struct nl_msgtype
{
/** Netlink message type */
int mt_id;
/** Cache action to take */
int mt_act;
/** Name of operation for human-readable printing */
char * mt_name;
};
/**
* Address family to netlink group association
*/
struct nl_af_group
{
/** Address family */
int ag_family;
/** Netlink group identifier */
int ag_group;
};
#define END_OF_GROUP_LIST AF_UNSPEC, 0
/**
* Parser parameters
*
* This structure is used to configure what kind of parser to use
* when parsing netlink messages to create objects.
*/
struct nl_parser_param
{
/** Function to parse netlink messages into objects */
int (*pp_cb)(struct nl_object *, struct nl_parser_param *);
/** Arbitary argument to be passed to the parser */
void * pp_arg;
};
/**
* Cache Operations
*
* This structure defines the characterstics of a cache type. It contains
* pointers to functions which implement the specifics of the object type
* the cache can hold.
*/
struct nl_cache_ops
{
/** Name of cache type (must be unique) */
char * co_name;
/** Size of family specific netlink header */
int co_hdrsize;
/** Netlink protocol */
int co_protocol;
/** cache object hash size **/
int co_hash_size;
/** cache flags */
unsigned int co_flags;
/** Reference counter */
unsigned int co_refcnt;
/** Group definition */
struct nl_af_group * co_groups;
/**
* Called whenever an update of the cache is required. Must send
* a request message to the kernel requesting a complete dump.
*/
int (*co_request_update)(struct nl_cache *, struct nl_sock *);
/**
* Called whenever a message was received that needs to be parsed.
* Must parse the message and call the paser callback function
* (nl_parser_param) provided via the argument.
*/
int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *,
struct nlmsghdr *, struct nl_parser_param *);
/**
* The function registered under this callback is called after a
* netlink notification associated with this cache type has been
* parsed into an object and is being considered for inclusio into
* the specified cache.
*
* The purpose of this function is to filter out notifications
* which should be ignored when updating caches.
*
* The function must return NL_SKIP to prevent the object from
* being included, or NL_OK to include it.
*
* @code
* int my_filter(struct nl_cache *cache, struct nl_object *obj)
* {
* if (reason_to_not_include_obj(obj))
* return NL_SKIP;
*
* return NL_OK;
* }
* @endcode
*/
int (*co_event_filter)(struct nl_cache *, struct nl_object *obj);
/**
* The function registered under this callback is called when an
* object formed from a notification event needs to be included in
* a cache.
*
* For each modified object, the change callback \c change_cb must
* be called with the \c data argument provided.
*
* If no function is registered, the function nl_cache_include()
* will be used for this purpose.
*
* @see nl_cache_include()
*/
int (*co_include_event)(struct nl_cache *cache, struct nl_object *obj,
change_func_t change_cb, void *data);
void (*reserved_1)(void);
void (*reserved_2)(void);
void (*reserved_3)(void);
void (*reserved_4)(void);
void (*reserved_5)(void);
void (*reserved_6)(void);
void (*reserved_7)(void);
void (*reserved_8)(void);
/** Object operations */
struct nl_object_ops * co_obj_ops;
/** Internal, do not touch! */
struct nl_cache_ops *co_next;
struct nl_cache *co_major_cache;
struct genl_ops * co_genl;
/* Message type definition */
struct nl_msgtype co_msgtypes[];
};
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,20 +1,22 @@
/*
* netlink-generic.h Local Generic Netlink Interface
* netlink-private/genl.h Local Generic Netlink Interface
*
* 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) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_GENL_PRIV_H_
#define NETLINK_GENL_PRIV_H_
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#define GENL_HDRSIZE(hdrlen) (GENL_HDRLEN + (hdrlen))
extern int genl_resolve_id(struct genl_ops *ops);
#endif

View File

@ -1,12 +1,12 @@
/*
* netlink-local.h Local Netlink Interface
* netlink-private/netlink.h Local Netlink Interface
*
* 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) 2003-2011 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LOCAL_H_
@ -33,6 +33,8 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <defs.h>
#ifndef SOL_NETLINK
#define SOL_NETLINK 270
#endif
@ -61,9 +63,9 @@
#include <netlink/handlers.h>
#include <netlink/cache.h>
#include <netlink/route/tc.h>
#include <netlink/object-api.h>
#include <netlink/cache-api.h>
#include <netlink-types.h>
#include <netlink-private/object-api.h>
#include <netlink-private/cache-api.h>
#include <netlink-private/types.h>
struct trans_tbl {
int i;
@ -78,24 +80,29 @@ struct trans_list {
struct nl_list_head list;
};
#define NL_DEBUG 1
#define NL_DBG(LVL,FMT,ARG...) \
do { \
if (LVL <= nl_debug) \
fprintf(stderr, "DBG<" #LVL ">: " FMT, ##ARG); \
#ifdef NL_DEBUG
#define NL_DBG(LVL,FMT,ARG...) \
do { \
if (LVL <= nl_debug) \
fprintf(stderr, \
"DBG<" #LVL ">%20s:%-4u %s: " FMT, \
__FILE__, __LINE__, \
__PRETTY_FUNCTION__, ##ARG); \
} while (0)
#else /* NL_DEBUG */
#define NL_DBG(LVL,FMT,ARG...) do { } while(0)
#endif /* NL_DEBUG */
#define BUG() \
do { \
NL_DBG(1, "BUG: %s:%d\n", \
__FILE__, __LINE__); \
fprintf(stderr, "BUG at file position %s:%d:%s\n", \
__FILE__, __LINE__, __PRETTY_FUNCTION__); \
assert(0); \
} while (0)
#define APPBUG(msg) \
do { \
NL_DBG(1, "APPLICATION BUG: %s:%d:%s: %s\n", \
fprintf(stderr, "APPLICATION BUG: %s:%d:%s: %s\n", \
__FILE__, __LINE__, __PRETTY_FUNCTION__, msg); \
assert(0); \
} while(0)

View File

@ -0,0 +1,376 @@
/*
* netlink-private/object-api.c Object API
*
* 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) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_OBJECT_API_H_
#define NETLINK_OBJECT_API_H_
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/object.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup object
* @defgroup object_api Object API
* @brief
*
* @par 1) Object Definition
* @code
* // Define your object starting with the common object header
* struct my_obj {
* NLHDR_COMMON
* int my_data;
* };
*
* // Fill out the object operations structure
* struct nl_object_ops my_ops = {
* .oo_name = "my_obj",
* .oo_size = sizeof(struct my_obj),
* };
*
* // At this point the object can be allocated, you may want to provide a
* // separate _alloc() function to ease allocting objects of this kind.
* struct nl_object *obj = nl_object_alloc(&my_ops);
*
* // And release it again...
* nl_object_put(obj);
* @endcode
*
* @par 2) Allocating additional data
* @code
* // You may require to allocate additional data and store it inside
* // object, f.e. assuming there is a field `ptr'.
* struct my_obj {
* NLHDR_COMMON
* void * ptr;
* };
*
* // And at some point you may assign allocated data to this field:
* my_obj->ptr = calloc(1, ...);
*
* // In order to not introduce any memory leaks you have to release
* // this data again when the last reference is given back.
* static void my_obj_free_data(struct nl_object *obj)
* {
* struct my_obj *my_obj = nl_object_priv(obj);
*
* free(my_obj->ptr);
* }
*
* // Also when the object is cloned, you must ensure for your pointer
* // stay valid even if one of the clones is freed by either making
* // a clone as well or increase the reference count.
* static int my_obj_clone(struct nl_object *src, struct nl_object *dst)
* {
* struct my_obj *my_src = nl_object_priv(src);
* struct my_obj *my_dst = nl_object_priv(dst);
*
* if (src->ptr) {
* dst->ptr = calloc(1, ...);
* memcpy(dst->ptr, src->ptr, ...);
* }
* }
*
* struct nl_object_ops my_ops = {
* ...
* .oo_free_data = my_obj_free_data,
* .oo_clone = my_obj_clone,
* };
* @endcode
*
* @par 3) Object Dumping
* @code
* static int my_obj_dump_detailed(struct nl_object *obj,
* struct nl_dump_params *params)
* {
* struct my_obj *my_obj = nl_object_priv(obj);
*
* // It is absolutely essential to use nl_dump() when printing
* // any text to make sure the dumping parameters are respected.
* nl_dump(params, "Obj Integer: %d\n", my_obj->my_int);
*
* // Before we can dump the next line, make sure to prefix
* // this line correctly.
* nl_new_line(params);
*
* // You may also split a line into multiple nl_dump() calls.
* nl_dump(params, "String: %s ", my_obj->my_string);
* nl_dump(params, "String-2: %s\n", my_obj->another_string);
* }
*
* struct nl_object_ops my_ops = {
* ...
* .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed,
* };
* @endcode
*
* @par 4) Object Attributes
* @code
* // The concept of object attributes is optional but can ease the typical
* // case of objects that have optional attributes, e.g. a route may have a
* // nexthop assigned but it is not required to.
*
* // The first step to define your object specific bitmask listing all
* // attributes
* #define MY_ATTR_FOO (1<<0)
* #define MY_ATTR_BAR (1<<1)
*
* // When assigning an optional attribute to the object, make sure
* // to mark its availability.
* my_obj->foo = 123123;
* my_obj->ce_mask |= MY_ATTR_FOO;
*
* // At any time you may use this mask to check for the availability
* // of the attribute, e.g. while dumping
* if (my_obj->ce_mask & MY_ATTR_FOO)
* nl_dump(params, "foo %d ", my_obj->foo);
*
* // One of the big advantages of this concept is that it allows for
* // standardized comparisons which make it trivial for caches to
* // identify unique objects by use of unified comparison functions.
* // In order for it to work, your object implementation must provide
* // a comparison function and define a list of attributes which
* // combined together make an object unique.
*
* static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
* uint32_t attrs, int flags)
* {
* struct my_obj *a = nl_object_priv(_a):
* struct my_obj *b = nl_object_priv(_b):
* int diff = 0;
*
* // We help ourselves in defining our own DIFF macro which will
* // call ATTR_DIFF() on both objects which will make sure to only
* // compare the attributes if required.
* #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
*
* // Call our own diff macro for each attribute to build a bitmask
* // representing the attributes which mismatch.
* diff |= MY_DIFF(FOO, a->foo != b->foo)
* diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
*
* return diff;
* }
*
* // In order to identify identical objects with differing attributes
* // you must specify the attributes required to uniquely identify
* // your object. Make sure to not include too many attributes, this
* // list is used when caches look for an old version of an object.
* struct nl_object_ops my_ops = {
* ...
* .oo_id_attrs = MY_ATTR_FOO,
* .oo_compare = my_obj_compare,
* };
* @endcode
* @{
*/
/**
* Common Object Header
*
* This macro must be included as first member in every object
* definition to allow objects to be cached.
*/
#define NLHDR_COMMON \
int ce_refcnt; \
struct nl_object_ops * ce_ops; \
struct nl_cache * ce_cache; \
struct nl_list_head ce_list; \
int ce_msgtype; \
int ce_flags; \
uint32_t ce_mask;
struct nl_object
{
NLHDR_COMMON
};
/**
* Return true if attribute is available in both objects
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
*
* @return True if the attribute is available, otherwise false is returned.
*/
#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
/**
* Return true if attribute is available in only one of both objects
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
*
* @return True if the attribute is available in only one of both objects,
* otherwise false is returned.
*/
#define AVAILABLE_MISMATCH(A, B, ATTR) (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))
/**
* Return true if attributes mismatch
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
* @arg EXPR Comparison expression
*
* This function will check if the attribute in question is available
* in both objects, if not this will count as a mismatch.
*
* If available the function will execute the expression which must
* return true if the attributes mismatch.
*
* @return True if the attribute mismatch, or false if they match.
*/
#define ATTR_MISMATCH(A, B, ATTR, EXPR) (AVAILABLE_MISMATCH(A, B, ATTR) || \
(AVAILABLE(A, B, ATTR) && (EXPR)))
/**
* Return attribute bit if attribute does not match
* @arg LIST list of attributes to be compared
* @arg ATTR attribute bit
* @arg A an object
* @arg B another object
* @arg EXPR Comparison expression
*
* This function will check if the attribute in question is available
* in both objects, if not this will count as a mismatch.
*
* If available the function will execute the expression which must
* return true if the attributes mismatch.
*
* In case the attributes mismatch, the attribute is returned, otherwise
* 0 is returned.
*
* @code
* diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);
* @endcode
*/
#define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
({ int diff = 0; \
if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
diff = ATTR; \
diff; })
/**
* Object Operations
*/
struct nl_object_ops
{
/**
* Unique name of object type
*
* Must be in the form family/name, e.g. "route/addr"
*/
char * oo_name;
/** Size of object including its header */
size_t oo_size;
/* List of attributes needed to uniquely identify the object */
uint32_t oo_id_attrs;
/**
* Constructor function
*
* Will be called when a new object of this type is allocated.
* Can be used to initialize members such as lists etc.
*/
void (*oo_constructor)(struct nl_object *);
/**
* Destructor function
*
* Will be called when an object is freed. Must free all
* resources which may have been allocated as part of this
* object.
*/
void (*oo_free_data)(struct nl_object *);
/**
* Cloning function
*
* Will be called when an object needs to be cloned. Please
* note that the generic object code will make an exact
* copy of the object first, therefore you only need to take
* care of members which require reference counting etc.
*
* May return a negative error code to abort cloning.
*/
int (*oo_clone)(struct nl_object *, struct nl_object *);
/**
* Dumping functions
*
* Will be called when an object is dumped. The implementations
* have to use nl_dump(), nl_dump_line(), and nl_new_line() to
* dump objects.
*
* The functions must return the number of lines printed.
*/
void (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *,
struct nl_dump_params *);
/**
* Comparison function
*
* Will be called when two objects of the same type are
* compared. It takes the two objects in question, an object
* specific bitmask defining which attributes should be
* compared and flags to control the behaviour.
*
* The function must return a bitmask with the relevant bit
* set for each attribute that mismatches.
*/
int (*oo_compare)(struct nl_object *, struct nl_object *,
uint32_t, int);
/**
* update function
*
* Will be called when the object given by first argument
* needs to be updated with the contents of the second object
*
* The function must return 0 for success and error for failure
* to update. In case of failure its assumed that the original
* object is not touched
*/
int (*oo_update)(struct nl_object *, struct nl_object *);
/**
* Hash Key generator function
*
* When called returns a hash key for the object being
* referenced. This key will be used by higher level hash functions
* to build association lists. Each object type gets to specify
* it's own key formulation
*/
void (*oo_keygen)(struct nl_object *, uint32_t *, uint32_t);
char *(*oo_attrs2str)(int, char *, size_t);
/**
* Get key attributes by family function
*/
uint32_t (*oo_id_attrs_get)(struct nl_object *);
};
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,153 @@
/*
* netlink-private/route/link/api.h Link Modules API
*
* 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) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_API_H_
#define NETLINK_LINK_API_H_
#include <netlink/netlink.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup link_api
*
* Available operations to modules implementing a link info type.
*/
struct rtnl_link_info_ops
{
/** Name of link info type, must match name on kernel side */
char * io_name;
/** Reference count, DO NOT MODIFY */
int io_refcnt;
/** Called to assign an info type to a link.
* Has to allocate enough resources to hold attributes. Can
* use link->l_info to store a pointer. */
int (*io_alloc)(struct rtnl_link *);
/** Called to parse the link info attribute.
* Must parse the attribute and assign all values to the link.
*/
int (*io_parse)(struct rtnl_link *,
struct nlattr *,
struct nlattr *);
/** Called when the link object is dumped.
* Must dump the info type specific attributes. */
void (*io_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
struct nl_dump_params *);
/** Called when a link object is cloned.
* Must clone all info type specific attributes. */
int (*io_clone)(struct rtnl_link *, struct rtnl_link *);
/** Called when construction a link netlink message.
* Must append all info type specific attributes to the message. */
int (*io_put_attrs)(struct nl_msg *, struct rtnl_link *);
/** Called to release all resources previously allocated
* in either io_alloc() or io_parse(). */
void (*io_free)(struct rtnl_link *);
struct nl_list_head io_list;
};
extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *);
extern void rtnl_link_info_ops_put(struct rtnl_link_info_ops *);
extern int rtnl_link_register_info(struct rtnl_link_info_ops *);
extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *);
/**
* @ingroup link_api
*
* Available operations to modules implementing a link address family.
*/
struct rtnl_link_af_ops
{
/** The address family this operations set implements */
const unsigned int ao_family;
/** Number of users of this operations, DO NOT MODIFY. */
int ao_refcnt;
/** Validation policy for IFLA_PROTINFO attribute. This pointer
* can be set to a nla_policy structure describing the minimal
* requirements the attribute must meet. Failure of meeting these
* requirements will result in a parsing error. */
const struct nla_policy *ao_protinfo_policy;
/** Called after address family has been assigned to link. Must
* allocate data buffer to hold address family specific data and
* store it in link->l_af_data. */
void * (*ao_alloc)(struct rtnl_link *);
/** Called when the link is cloned, must allocate a clone of the
* address family specific buffer and return it. */
void * (*ao_clone)(struct rtnl_link *, void *);
/** Called when the link gets freed. Must free all allocated data */
void (*ao_free)(struct rtnl_link *, void *);
/** Called if a IFLA_PROTINFO attribute needs to be parsed. Typically
* stores the parsed data in the address family specific buffer. */
int (*ao_parse_protinfo)(struct rtnl_link *,
struct nlattr *, void *);
/** Called if a IFLA_AF_SPEC attribute needs to be parsed. Typically
* stores the parsed data in the address family specific buffer. */
int (*ao_parse_af)(struct rtnl_link *,
struct nlattr *, void *);
/** Called if a link message is sent to the kernel. Must append the
* link address family specific attributes to the message. */
int (*ao_fill_af)(struct rtnl_link *,
struct nl_msg *msg, void *);
/** Dump address family specific link attributes */
void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
struct nl_dump_params *,
void *);
/** Comparison function
*
* Will be called when two links are compared for their af data. It
* takes two link objects in question, an object specific bitmask
* defining which attributes should be compared and flags to control
* the behaviour
*
* The function must return a bitmask with the relevant bit set for
* each attribute that mismatches
*/
int (*ao_compare)(struct rtnl_link *,
struct rtnl_link *, int, uint32_t, int);
};
extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int);
extern void rtnl_link_af_ops_put(struct rtnl_link_af_ops *);
extern void * rtnl_link_af_alloc(struct rtnl_link *,
const struct rtnl_link_af_ops *);
extern void * rtnl_link_af_data(const struct rtnl_link *,
const struct rtnl_link_af_ops *);
extern int rtnl_link_af_register(struct rtnl_link_af_ops *);
extern int rtnl_link_af_unregister(struct rtnl_link_af_ops *);
extern int rtnl_link_af_data_compare(struct rtnl_link *a,
struct rtnl_link *b,
int family);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,134 @@
/*
* netlink-private/route/tc-api.h Traffic Control API
*
* 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) 2011-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_TC_API_H_
#define NETLINK_TC_API_H_
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <netlink/route/tc.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Traffic control object operations
* @ingroup tc
*
* This structure holds function pointers and settings implementing
* the features of each traffic control object implementation.
*/
struct rtnl_tc_ops
{
/**
* Name of traffic control module
*/
char *to_kind;
/**
* Type of traffic control object
*/
enum rtnl_tc_type to_type;
/**
* Size of private data
*/
size_t to_size;
/**
* Dump callbacks
*/
void (*to_dump[NL_DUMP_MAX+1])(struct rtnl_tc *, void *,
struct nl_dump_params *);
/**
* Used to fill the contents of TCA_OPTIONS
*/
int (*to_msg_fill)(struct rtnl_tc *, void *, struct nl_msg *);
/**
* Uesd to to fill tc related messages, unlike with to_msg_fill,
* the contents is not encapsulated with a TCA_OPTIONS nested
* attribute.
*/
int (*to_msg_fill_raw)(struct rtnl_tc *, void *, struct nl_msg *);
/**
* TCA_OPTIONS message parser
*/
int (*to_msg_parser)(struct rtnl_tc *, void *);
/**
* Called before a tc object is destroyed
*/
void (*to_free_data)(struct rtnl_tc *, void *);
/**
* Called whenever a classifier object needs to be cloned
*/
int (*to_clone)(void *, void *);
/**
* Internal, don't touch
*/
struct nl_list_head to_list;
};
struct rtnl_tc_type_ops
{
enum rtnl_tc_type tt_type;
char *tt_dump_prefix;
/**
* Dump callbacks
*/
void (*tt_dump[NL_DUMP_MAX+1])(struct rtnl_tc *,
struct nl_dump_params *);
};
extern int rtnl_tc_msg_parse(struct nlmsghdr *,
struct rtnl_tc *);
extern int rtnl_tc_msg_build(struct rtnl_tc *, int,
int, struct nl_msg **);
extern void rtnl_tc_free_data(struct nl_object *);
extern int rtnl_tc_clone(struct nl_object *,
struct nl_object *);
extern void rtnl_tc_dump_line(struct nl_object *,
struct nl_dump_params *);
extern void rtnl_tc_dump_details(struct nl_object *,
struct nl_dump_params *);
extern void rtnl_tc_dump_stats(struct nl_object *,
struct nl_dump_params *);
extern int rtnl_tc_compare(struct nl_object *,
struct nl_object *,
uint32_t, int);
extern void * rtnl_tc_data(struct rtnl_tc *);
extern void * rtnl_tc_data_check(struct rtnl_tc *,
struct rtnl_tc_ops *);
extern struct rtnl_tc_ops * rtnl_tc_lookup_ops(enum rtnl_tc_type,
const char *);
extern struct rtnl_tc_ops * rtnl_tc_get_ops(struct rtnl_tc *);
extern int rtnl_tc_register(struct rtnl_tc_ops *);
extern void rtnl_tc_unregister(struct rtnl_tc_ops *);
extern void rtnl_tc_type_register(struct rtnl_tc_type_ops *);
extern void rtnl_tc_type_unregister(struct rtnl_tc_type_ops *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,18 +1,18 @@
/*
* netlink-tc.h Local Traffic Control Interface
* netlink-private/tc.h Local Traffic Control Interface
*
* 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) 2003-2010 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_TC_PRIV_H_
#define NETLINK_TC_PRIV_H_
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#ifdef __cplusplus
extern "C" {

View File

@ -1,12 +1,12 @@
/*
* netlink-types.h Netlink Types (Private)
* netlink-private/types.h Netlink Types (Private)
*
* 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) 2003-2012 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LOCAL_TYPES_H_
@ -17,7 +17,7 @@
#include <netlink/route/qdisc.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>
#include <netlink/route/tc-api.h>
#include <netlink-private/route/tc-api.h>
#define NL_SOCK_BUFSIZE_SET (1<<0)
#define NL_SOCK_PASSCRED (1<<1)
@ -182,6 +182,9 @@ struct rtnl_link
uint32_t l_num_tx_queues;
uint32_t l_num_rx_queues;
uint32_t l_group;
uint8_t l_carrier;
/* 3 byte hole */
struct rtnl_link_af_ops * l_af_ops;
};
struct rtnl_ncacheinfo
@ -900,6 +903,140 @@ struct nfnl_queue_msg {
uint32_t queue_msg_verdict;
};
struct nl_dect_transceiver_slot {
uint8_t dts_valid;
uint8_t dts_state;
uint32_t dts_flags;
uint8_t dts_packet;
uint8_t dts_carrier;
uint8_t dts_rssi;
uint32_t dts_frequency;
int32_t dts_phaseoff;
uint32_t dts_rx_bytes;
uint32_t dts_rx_packets;
uint32_t dts_rx_a_crc_errors;
uint32_t dts_rx_x_crc_errors;
uint32_t dts_rx_z_crc_errors;
uint32_t dts_tx_bytes;
uint32_t dts_tx_packets;
};
struct nl_dect_transceiver_stats {
uint32_t trx_event_busy;
uint32_t trx_event_late;
};
struct nl_dect_transceiver {
NLHDR_COMMON
char *trx_name;
char *trx_type;
uint32_t trx_features;
uint8_t trx_index;
uint8_t trx_link;
uint8_t trx_band;
struct nl_dect_transceiver_stats trx_stats;
struct nl_dect_transceiver_slot trx_slots[24];
};
struct nl_dect_ari {
uint32_t ari_flags;
uint8_t ari_class;
uint32_t ari_fpn;
uint32_t ari_fps;
union {
uint16_t emc;
uint16_t eic;
uint16_t poc;
uint32_t gop;
uint16_t fil;
} ari_u;
};
struct nl_dect_mbc_tb {
uint8_t mtb_lbn;
uint8_t mtb_ecn;
uint8_t mtb_cell;
uint8_t mtb_rx_slot;
uint8_t mtb_tx_slot;
};
struct nl_dect_mbc {
uint32_t mbc_mcei;
uint8_t mbc_state;
uint8_t mbc_service;
uint8_t mbc_cipher_state;
uint8_t mbc_ntbs;
struct nl_dect_mbc_tb mbc_tbs[8];
uint32_t mbc_cs_rx_bytes;
uint32_t mbc_cs_tx_bytes;
uint32_t mbc_i_rx_bytes;
uint32_t mbc_i_tx_bytes;
uint32_t mbc_handovers;
};
struct nl_dect_cluster {
NLHDR_COMMON
int cl_index;
char *cl_name;
uint8_t cl_mode;
struct nl_dect_ari cl_pari;
uint8_t cells[8];
struct nl_dect_mbc cl_mbcs[8];
uint8_t cl_nmbcs;
};
struct nl_dect_cell {
NLHDR_COMMON
int c_index;
char * c_name;
uint32_t c_flags;
char *c_transceiver[16];
int c_link;
};
struct nl_dect_llme_mac_info {
NLHDR_COMMON
struct nl_dect_ari mi_pari;
uint8_t mi_rpn;
uint8_t mi_rssi;
uint32_t mi_fpc;
uint16_t mi_hlc;
uint16_t mi_efpc;
uint32_t mi_ehlc;
uint16_t mi_efpc2;
uint32_t mi_ehlc2;
uint32_t mi_mfn;
};
struct nl_dect_llme_mac_con {
NLHDR_COMMON
uint32_t mc_mcei;
struct nl_dect_ari mc_ari;
uint32_t mc_pmid;
uint8_t mc_type;
uint8_t mc_ecn;
uint8_t mc_service;
};
struct nl_dect_llme_msg {
NLHDR_COMMON
int lm_index;
uint8_t lm_type;
uint8_t lm_op;
union {
struct nl_dect_llme_mac_info lm_mi;
struct nl_dect_llme_mac_con lm_mc;
};
};
struct ematch_quoted {
char * data;
size_t len;

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_ADDR_H_
@ -40,7 +40,7 @@ extern int nl_addr_guess_family(struct nl_addr *);
extern int nl_addr_fill_sockaddr(struct nl_addr *,
struct sockaddr *, socklen_t *);
extern int nl_addr_info(struct nl_addr *, struct addrinfo **);
extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen);
extern int nl_addr_resolve(struct nl_addr *, char *, size_t);
/* Access Functions */
extern void nl_addr_set_family(struct nl_addr *, int);

View File

@ -6,7 +6,7 @@
* 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-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_ATTR_H_
@ -124,8 +124,10 @@ extern int nla_put_msecs(struct nl_msg *, int, unsigned long);
extern int nla_put_nested(struct nl_msg *, int, struct nl_msg *);
extern struct nlattr * nla_nest_start(struct nl_msg *, int);
extern int nla_nest_end(struct nl_msg *, struct nlattr *);
extern void nla_nest_cancel(struct nl_msg *, struct nlattr *);
extern int nla_parse_nested(struct nlattr **, int, struct nlattr *,
struct nla_policy *);
extern int nla_is_nested(struct nlattr *);
/**
* @name Attribute Construction (Exception Based)

View File

@ -6,281 +6,15 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_CACHE_API_H_
#define NETLINK_CACHE_API_H_
#ifndef NETLINK_DUMMY_CACHE_API_H_
#define NETLINK_DUMMY_CACHE_API_H_
#include <netlink/netlink.h>
#include <netlink/cache.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
/**
* @ingroup cache
* @defgroup cache_api Cache Implementation
* @brief
*
* @par 1) Cache Definition
* @code
* struct nl_cache_ops my_cache_ops = {
* .co_name = "route/link",
* .co_protocol = NETLINK_ROUTE,
* .co_hdrsize = sizeof(struct ifinfomsg),
* .co_obj_ops = &my_obj_ops,
* };
* @endcode
*
* @par 2)
* @code
* // The simplest way to fill a cache is by providing a request-update
* // function which must trigger a complete dump on the kernel-side of
* // whatever the cache covers.
* static int my_request_update(struct nl_cache *cache,
* struct nl_sock *socket)
* {
* // In this example, we request a full dump of the interface table
* return nl_rtgen_request(socket, RTM_GETLINK, AF_UNSPEC, NLM_F_DUMP);
* }
*
* // The resulting netlink messages sent back will be fed into a message
* // parser one at a time. The message parser has to extract all relevant
* // information from the message and create an object reflecting the
* // contents of the message and pass it on to the parser callback function
* // provide which will add the object to the cache.
* static int my_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
* struct nlmsghdr *nlh, struct nl_parser_param *pp)
* {
* struct my_obj *obj;
*
* obj = my_obj_alloc();
* obj->ce_msgtype = nlh->nlmsg_type;
*
* // Parse the netlink message and continue creating the object.
*
* err = pp->pp_cb((struct nl_object *) obj, pp);
* if (err < 0)
* goto errout;
* }
*
* struct nl_cache_ops my_cache_ops = {
* ...
* .co_request_update = my_request_update,
* .co_msg_parser = my_msg_parser,
* };
* @endcode
*
* @par 3) Notification based Updates
* @code
* // Caches can be kept up-to-date based on notifications if the kernel
* // sends out notifications whenever an object is added/removed/changed.
* //
* // It is trivial to support this, first a list of groups needs to be
* // defined which are required to join in order to receive all necessary
* // notifications. The groups are separated by address family to support
* // the common situation where a separate group is used for each address
* // family. If there is only one group, simply specify AF_UNSPEC.
* static struct nl_af_group addr_groups[] = {
* { AF_INET, RTNLGRP_IPV4_IFADDR },
* { AF_INET6, RTNLGRP_IPV6_IFADDR },
* { END_OF_GROUP_LIST },
* };
*
* // In order for the caching system to know the meaning of each message
* // type it requires a table which maps each supported message type to
* // a cache action, e.g. RTM_NEWADDR means address has been added or
* // updated, RTM_DELADDR means address has been removed.
* static struct nl_cache_ops rtnl_addr_ops = {
* ...
* .co_msgtypes = {
* { RTM_NEWADDR, NL_ACT_NEW, "new" },
* { RTM_DELADDR, NL_ACT_DEL, "del" },
* { RTM_GETADDR, NL_ACT_GET, "get" },
* END_OF_MSGTYPES_LIST,
* },
* .co_groups = addr_groups,
* };
*
* // It is now possible to keep the cache up-to-date using the cache manager.
* @endcode
* @{
*/
enum {
NL_ACT_UNSPEC,
NL_ACT_NEW,
NL_ACT_DEL,
NL_ACT_GET,
NL_ACT_SET,
NL_ACT_CHANGE,
__NL_ACT_MAX,
};
#define NL_ACT_MAX (__NL_ACT_MAX - 1)
#define END_OF_MSGTYPES_LIST { -1, -1, NULL }
/**
* Message type to cache action association
*/
struct nl_msgtype
{
/** Netlink message type */
int mt_id;
/** Cache action to take */
int mt_act;
/** Name of operation for human-readable printing */
char * mt_name;
};
/**
* Address family to netlink group association
*/
struct nl_af_group
{
/** Address family */
int ag_family;
/** Netlink group identifier */
int ag_group;
};
#define END_OF_GROUP_LIST AF_UNSPEC, 0
/**
* Parser parameters
*
* This structure is used to configure what kind of parser to use
* when parsing netlink messages to create objects.
*/
struct nl_parser_param
{
/** Function to parse netlink messages into objects */
int (*pp_cb)(struct nl_object *, struct nl_parser_param *);
/** Arbitary argument to be passed to the parser */
void * pp_arg;
};
/**
* Cache Operations
*
* This structure defines the characterstics of a cache type. It contains
* pointers to functions which implement the specifics of the object type
* the cache can hold.
*/
struct nl_cache_ops
{
/** Name of cache type (must be unique) */
char * co_name;
/** Size of family specific netlink header */
int co_hdrsize;
/** Netlink protocol */
int co_protocol;
/** cache object hash size **/
int co_hash_size;
/** cache flags */
unsigned int co_flags;
/** Reference counter */
unsigned int co_refcnt;
/** Group definition */
struct nl_af_group * co_groups;
/**
* Called whenever an update of the cache is required. Must send
* a request message to the kernel requesting a complete dump.
*/
int (*co_request_update)(struct nl_cache *, struct nl_sock *);
/**
* Called whenever a message was received that needs to be parsed.
* Must parse the message and call the paser callback function
* (nl_parser_param) provided via the argument.
*/
int (*co_msg_parser)(struct nl_cache_ops *, struct sockaddr_nl *,
struct nlmsghdr *, struct nl_parser_param *);
/**
* The function registered under this callback is called after a
* netlink notification associated with this cache type has been
* parsed into an object and is being considered for inclusio into
* the specified cache.
*
* The purpose of this function is to filter out notifications
* which should be ignored when updating caches.
*
* The function must return NL_SKIP to prevent the object from
* being included, or NL_OK to include it.
*
* @code
* int my_filter(struct nl_cache *cache, struct nl_object *obj)
* {
* if (reason_to_not_include_obj(obj))
* return NL_SKIP;
*
* return NL_OK;
* }
* @endcode
*/
int (*co_event_filter)(struct nl_cache *, struct nl_object *obj);
/**
* The function registered under this callback is called when an
* object formed from a notification event needs to be included in
* a cache.
*
* For each modified object, the change callback \c change_cb must
* be called with the \c data argument provided.
*
* If no function is registered, the function nl_cache_include()
* will be used for this purpose.
*
* @see nl_cache_include()
*/
int (*co_include_event)(struct nl_cache *cache, struct nl_object *obj,
change_func_t change_cb, void *data);
void (*reserved_1)(void);
void (*reserved_2)(void);
void (*reserved_3)(void);
void (*reserved_4)(void);
void (*reserved_5)(void);
void (*reserved_6)(void);
void (*reserved_7)(void);
void (*reserved_8)(void);
/** Object operations */
struct nl_object_ops * co_obj_ops;
/** Internal, do not touch! */
struct nl_cache_ops *co_next;
struct nl_cache *co_major_cache;
struct genl_ops * co_genl;
/* Message type definition */
struct nl_msgtype co_msgtypes[];
};
extern void nl_cache_ops_get(struct nl_cache_ops *);
extern void nl_cache_ops_put(struct nl_cache_ops *);
/** @} */
#ifdef __cplusplus
}
#endif
#warning "You are including a deprecated header file, include <netlink/cache.h>."
#endif

View File

@ -16,13 +16,25 @@
#include <netlink/msg.h>
#include <netlink/utils.h>
#include <netlink/object.h>
#include <netlink/cache-api.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
NL_ACT_UNSPEC,
NL_ACT_NEW,
NL_ACT_DEL,
NL_ACT_GET,
NL_ACT_SET,
NL_ACT_CHANGE,
__NL_ACT_MAX,
};
#define NL_ACT_MAX (__NL_ACT_MAX - 1)
struct nl_cache;
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
/**
* @ingroup cache
@ -146,6 +158,9 @@ extern void nl_cache_mngr_info(struct nl_cache_mngr *,
struct nl_dump_params *);
extern void nl_cache_mngr_free(struct nl_cache_mngr *);
extern void nl_cache_ops_get(struct nl_cache_ops *);
extern void nl_cache_ops_put(struct nl_cache_ops *);
#ifdef __cplusplus
}
#endif

View File

@ -12,7 +12,9 @@
#ifndef __NETLINK_CLI_TC_H_
#define __NETLINK_CLI_TC_H_
#include <netlink/route/tc-api.h>
#include <netlink/route/tc.h>
struct rtnl_tc_ops;
extern void nl_cli_tc_parse_dev(struct rtnl_tc *, struct nl_cache *, char *);
extern void nl_cli_tc_parse_parent(struct rtnl_tc *, char *);

View File

@ -22,6 +22,7 @@
#include <stdint.h>
#include <ctype.h>
#include <getopt.h>
#include <limits.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -47,6 +48,11 @@
#include <netlink/genl/ctrl.h>
#include <netlink/genl/mngt.h>
#include <netlink/netfilter/ct.h>
#include <netlink/dect/transceiver.h>
#include <netlink/dect/cell.h>
#include <netlink/dect/cluster.h>
#include <netlink/dect/llme.h>
#include <netlink/dect/ari.h>
#ifdef __cplusplus
extern "C" {

View File

@ -0,0 +1,39 @@
#ifndef NETLINK_DECT_ARI_H
#define NETLINK_DECT_ARI_H
#include <stdbool.h>
struct nl_dect_ari;
extern int nl_dect_parse_ari(struct nl_dect_ari *,
struct nlattr *);
extern int nl_dect_fill_ari(struct nl_msg *,
const struct nl_dect_ari *,
int);
extern void nl_dect_dump_ari(const struct nl_dect_ari *,
struct nl_dump_params *);
extern const char * nl_dect_ari_class2str(enum dect_ari_classes,
char *buf, size_t len);
extern enum dect_ari_classes nl_dect_ari_str2class(const char *);
extern void nl_dect_ari_set_class(struct nl_dect_ari *,
enum dect_ari_classes);
extern enum dect_ari_classes nl_dect_ari_get_class(const struct nl_dect_ari *);
extern void nl_dect_ari_set_fpn(struct nl_dect_ari *, uint32_t);
extern uint32_t nl_dect_ari_get_fpn(const struct nl_dect_ari *);
extern void nl_dect_ari_set_fps(struct nl_dect_ari *, uint32_t);
extern uint32_t nl_dect_ari_get_fps(const struct nl_dect_ari *);
extern void nl_dect_ari_set_emc(struct nl_dect_ari *, uint16_t);
extern uint16_t nl_dect_ari_get_emc(const struct nl_dect_ari *);
extern void nl_dect_ari_set_eic(struct nl_dect_ari *, uint16_t);
extern uint16_t nl_dect_ari_get_eic(const struct nl_dect_ari *);
extern void nl_dect_ari_set_poc(struct nl_dect_ari *, uint16_t);
extern uint16_t nl_dect_ari_get_poc(const struct nl_dect_ari *);
extern void nl_dect_ari_set_gop(struct nl_dect_ari *, uint32_t);
extern uint32_t nl_dect_ari_get_gop(const struct nl_dect_ari *);
extern void nl_dect_ari_set_fil(struct nl_dect_ari *, uint16_t);
extern uint16_t nl_dect_ari_get_fil(const struct nl_dect_ari *);
#endif /* NETLINK_DECT_ARI_H */

View File

@ -0,0 +1,61 @@
#ifndef NETLINK_DECT_CELL_H
#define NETLINK_DECT_CELL_H
#include <stdbool.h>
struct nl_dect_cell;
struct nl_dect_ari;
extern struct nl_object_ops nl_dect_cell_obj_ops;
extern struct nl_dect_cell * nl_dect_cell_alloc(void);
extern void nl_dect_cell_get(struct nl_dect_cell *);
extern void nl_dect_cell_put(struct nl_dect_cell *);
extern void nl_dect_cell_set_index(struct nl_dect_cell *, int);
extern bool nl_dect_cell_test_index(const struct nl_dect_cell *);
extern int nl_dect_cell_get_index(const struct nl_dect_cell *);
extern void nl_dect_cell_set_name(struct nl_dect_cell *, const char *);
extern bool nl_dect_cell_test_name(const struct nl_dect_cell *);
extern const char * nl_dect_cell_get_name(const struct nl_dect_cell *);
extern void nl_dect_cell_set_flags(struct nl_dect_cell *, uint32_t);
extern bool nl_dect_cell_test_flags(const struct nl_dect_cell *);
extern uint32_t nl_dect_cell_get_flags(const struct nl_dect_cell *);
extern void nl_dect_cell_set_transceiver(struct nl_dect_cell *,
unsigned int,
const char *);
extern bool nl_dect_cell_test_transceiver(const struct nl_dect_cell *);
extern const char * nl_dect_cell_get_transceiver(const struct nl_dect_cell *,
unsigned int);
extern void nl_dect_cell_set_link(struct nl_dect_cell *, int);
extern bool nl_dect_cell_test_link(const struct nl_dect_cell *);
extern int nl_dect_cell_get_link(const struct nl_dect_cell *);
extern int nl_dect_cell_alloc_cache(struct nl_sock *,
struct nl_cache **);
extern int nl_dect_cell_build_msg(struct nl_msg *,
struct nl_dect_cell *);
extern int nl_dect_cell_build_add_request(struct nl_dect_cell *,
int, struct nl_msg **);
extern int nl_dect_cell_add(struct nl_sock *,
struct nl_dect_cell *, int);
extern int nl_dect_cell_build_del_request(struct nl_dect_cell *,
int, struct nl_msg **);
extern int nl_dect_cell_delete(struct nl_sock *,
struct nl_dect_cell *, int);
extern char * nl_dect_cell_i2name(struct nl_cache *, int, char *,
size_t);
extern int nl_dect_cell_name2i(struct nl_cache *, const char *);
extern char * nl_dect_cell_flags2str(uint32_t, char *, size_t);
extern uint32_t nl_dect_cell_str2flags(const char *);
#endif /* NETLINK_DECT_CELL_H */

View File

@ -0,0 +1,61 @@
#ifndef NETLINK_DECT_CLUSTER_H
#define NETLINK_DECT_CLUSTER_H
#include <stdbool.h>
struct nl_dect_cluster;
struct nl_dect_ari;
extern struct nl_object_ops nl_dect_cluster_obj_ops;
extern struct nl_dect_cluster * nl_dect_cluster_alloc(void);
extern void nl_dect_cluster_get(struct nl_dect_cluster *);
extern void nl_dect_cluster_put(struct nl_dect_cluster *);
extern unsigned int nl_dect_cluster_get_index(const struct nl_dect_cluster *);
extern void nl_dect_cluster_set_name(struct nl_dect_cluster *,
const char *);
extern bool nl_dect_cluster_test_name(const struct nl_dect_cluster *);
extern const char * nl_dect_cluster_get_name(const struct nl_dect_cluster *);
extern void nl_dect_cluster_set_mode(struct nl_dect_cluster *,
uint8_t mode);
extern bool nl_dect_cluster_test_mode(const struct nl_dect_cluster *);
extern uint8_t nl_dect_cluster_get_mode(const struct nl_dect_cluster *);
extern void nl_dect_cluster_set_pari(struct nl_dect_cluster *,
const struct nl_dect_ari *);
extern bool nl_dect_cluster_test_pari(const struct nl_dect_cluster *);
extern const struct nl_dect_ari *nl_dect_cluster_get_pari(const struct nl_dect_cluster *);
extern char * nl_dect_cluster_mode2str(enum dect_cluster_modes,
char *, size_t);
extern enum dect_cluster_modes nl_dect_cluster_str2mode(const char *);
extern int nl_dect_cluster_alloc_cache(struct nl_sock *,
struct nl_cache **);
extern int nl_dect_cluster_build_msg(struct nl_msg *,
struct nl_dect_cluster *);
extern int nl_dect_cluster_build_add_request(struct nl_dect_cluster *,
int, struct nl_msg **);
extern int nl_dect_cluster_add(struct nl_sock *,
struct nl_dect_cluster *, int);
extern int nl_dect_cluster_build_del_request(struct nl_dect_cluster *,
int, struct nl_msg **);
extern int nl_dect_cluster_delete(struct nl_sock *,
struct nl_dect_cluster *, int);
extern int nl_dect_cluster_build_query_request(struct nl_dect_cluster *,
int, struct nl_msg **);
extern int nl_dect_cluster_query(struct nl_sock *,
struct nl_dect_cluster *, int);
extern char * nl_dect_cluster_i2name(struct nl_cache *, int, char *,
size_t);
extern int nl_dect_cluster_name2i(struct nl_cache *, const char *);
#endif /* NETLINK_DECT_CLUSTER_H */

View File

@ -0,0 +1,6 @@
#ifndef _NETLINK_DECT_H
#define _NETLINK_DECT_H
extern double nl_dect_rssi_to_dbm(uint8_t);
#endif /* _NETLINK_DECT_H */

View File

@ -0,0 +1,94 @@
#ifndef NETLINK_DECT_LLME_H
#define NETLINK_DECT_LLME_H
#include <stdbool.h>
struct nl_dect_llme_msg;
struct nl_dect_ari;
extern struct nl_dect_llme_msg *nl_dect_llme_msg_alloc(void);
extern void nl_dect_llme_msg_get(struct nl_dect_llme_msg *);
extern void nl_dect_llme_msg_put(struct nl_dect_llme_msg *);
extern int nl_dect_llme_build_request(struct nl_dect_llme_msg *,
struct nl_msg **);
extern int nl_dect_llme_request(struct nl_sock *,
struct nl_dect_llme_msg *);
extern int nl_dect_llme_build_response(struct nl_dect_llme_msg *,
struct nl_msg **);
extern int nl_dect_llme_respond(struct nl_sock *, struct nl_dect_llme_msg *);
extern void nl_dect_llme_msg_set_index(struct nl_dect_llme_msg *, int);
extern void nl_dect_llme_msg_set_type(struct nl_dect_llme_msg *,
enum dect_llme_msg_types);
extern enum dect_llme_msg_types nl_dect_llme_msg_get_type(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_msg_set_op(struct nl_dect_llme_msg *,
enum dect_llme_ops);
extern enum dect_llme_ops nl_dect_llme_msg_get_op(const struct nl_dect_llme_msg *);
extern char * nl_dect_llme_msgtype2str(enum dect_llme_msg_types,
char *, size_t);
extern enum dect_llme_msg_types nl_dect_llme_str2msgtype(const char *);
extern char * nl_dect_llme_op2str(enum dect_llme_ops,
char *, size_t);
extern enum dect_llme_ops nl_dect_llme_str2op(const char *);
extern void nl_dect_llme_mac_info_set_pari(struct nl_dect_llme_msg *lmsg,
const struct nl_dect_ari *);
extern bool nl_dect_llme_mac_info_test_pari(const struct nl_dect_llme_msg *);
extern const struct nl_dect_ari *nl_dect_llme_mac_info_get_pari(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_rpn(struct nl_dect_llme_msg *,
uint8_t);
extern uint8_t nl_dect_llme_mac_info_get_rpn(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_rssi(struct nl_dect_llme_msg *,
uint8_t);
extern uint8_t nl_dect_llme_mac_info_get_rssi(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_fpc(struct nl_dect_llme_msg *,
uint32_t);
extern uint32_t nl_dect_llme_mac_info_get_fpc(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_hlc(struct nl_dect_llme_msg *,
uint16_t);
extern uint16_t nl_dect_llme_mac_info_get_hlc(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_efpc(struct nl_dect_llme_msg *,
uint16_t);
extern uint16_t nl_dect_llme_mac_info_get_efpc(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_ehlc(struct nl_dect_llme_msg *,
uint32_t);
extern uint32_t nl_dect_llme_mac_info_get_ehlc(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_efpc2(struct nl_dect_llme_msg *,
uint16_t);
extern uint16_t nl_dect_llme_mac_info_get_efpc2(const struct nl_dect_llme_msg *);
extern void nl_dect_llme_mac_info_set_ehlc2(struct nl_dect_llme_msg *,
uint32_t);
extern uint32_t nl_dect_llme_mac_info_get_ehlc2(const struct nl_dect_llme_msg *);
extern char * nl_dect_llme_fpc2str(uint32_t, char *, size_t);
extern uint32_t nl_dect_llme_str2fpc(const char *);
extern char * nl_dect_llme_hlc2str(uint16_t, char *, size_t);
extern uint16_t nl_dect_llme_str2hlc(const char *);
extern char * nl_dect_llme_efpc2str(uint16_t, char *, size_t);
extern uint16_t nl_dect_llme_str2efpc(const char *);
extern char * nl_dect_llme_ehlc2str(uint32_t, char *, size_t);
extern uint32_t nl_dect_llme_str2ehlc(const char *);
extern char * nl_dect_llme_efpc22str(uint16_t, char *, size_t);
extern uint16_t nl_dect_llme_str22efpc(const char *);
extern char * nl_dect_llme_ehlc22str(uint32_t, char *, size_t);
extern uint32_t nl_dect_llme_str22ehlc(const char *);
#endif /* NETLINK_DECT_LLME_H */

View File

@ -0,0 +1,57 @@
#ifndef NETLINK_DECT_TRANSCEIVER_H
#define NETLINK_DECT_TRANSCEIVER_H
#include <stdbool.h>
struct nl_dect_transceiver;
extern struct nl_object_ops nl_dect_transceiver_obj_ops;
extern struct nl_dect_transceiver *nl_dect_transceiver_alloc(void);
extern void nl_dect_transceiver_get(struct nl_dect_transceiver *);
extern void nl_dect_transceiver_put(struct nl_dect_transceiver *);
extern void nl_dect_transceiver_set_name(struct nl_dect_transceiver *,
const char *);
extern bool nl_dect_transceiver_test_name(const struct nl_dect_transceiver *);
extern const char * nl_dect_transceiver_get_name(const struct nl_dect_transceiver *);
extern void nl_dect_transceiver_set_type(struct nl_dect_transceiver *,
const char *);
extern bool nl_dect_transceiver_test_type(const struct nl_dect_transceiver *);
extern const char * nl_dect_transceiver_get_type(const struct nl_dect_transceiver *);
extern void nl_dect_transceiver_set_features(struct nl_dect_transceiver *,
uint32_t);
extern void nl_dect_transceiver_set_index(struct nl_dect_transceiver *,
int);
extern void nl_dect_transceiver_set_link(struct nl_dect_transceiver *,
uint8_t);
extern void nl_dect_transceiver_set_band(struct nl_dect_transceiver *,
uint8_t);
extern bool nl_dect_transceiver_test_band(const struct nl_dect_transceiver *);
extern uint8_t nl_dect_transceiver_get_band(const struct nl_dect_transceiver *);
extern int nl_dect_transceiver_build_msg(struct nl_msg *,
struct nl_dect_transceiver *);
extern int nl_dect_transceiver_build_change_request(struct nl_dect_transceiver *,
int, struct nl_msg **);
extern int nl_dect_transceiver_change(struct nl_sock *,
struct nl_dect_transceiver *, int flags);
extern const char * nl_dect_transceiver_features2str(uint32_t, char *, size_t);
extern const char * nl_dect_slot_state2str(uint8_t, char *, size_t);
extern uint8_t nl_dect_slot_str2state(const char *);
extern const char * nl_dect_slot_flags2str(uint32_t, char *, size_t);
extern uint32_t nl_dect_slot_str2flags(const char *);
extern const char * nl_dect_slot_packet2str(uint8_t, char *, size_t);
extern uint8_t nl_dect_slot_str2packet(const char *);
extern int nl_dect_transceiver_alloc_cache(struct nl_sock *,
struct nl_cache **);
#endif /* NETLINK_DECT_TRANSCEIVER_H */

View File

@ -93,6 +93,8 @@ extern unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *);
extern struct nl_msg * nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *);
extern int nfnl_queue_msg_send_verdict(struct nl_sock *,
const struct nfnl_queue_msg *);
extern int nfnl_queue_msg_send_verdict_batch(struct nl_sock *,
const struct nfnl_queue_msg *);
extern int nfnl_queue_msg_send_verdict_payload(struct nl_sock *,
const struct nfnl_queue_msg *,
const void *, unsigned );

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_NETLINK_H_
@ -26,19 +26,23 @@
#include <linux/rtnetlink.h>
#include <linux/genetlink.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/dect_netlink.h>
#include <netlink/version.h>
#include <netlink/errno.h>
#include <netlink/types.h>
#include <netlink/handlers.h>
#include <netlink/socket.h>
#include <netlink/object.h>
#include <netlink/cache-api.h>
#ifdef __cplusplus
extern "C" {
#endif
struct ucred;
struct nl_cache_ops;
struct nl_parser_param;
struct nl_object;
struct nl_sock;
extern int nl_debug;
extern struct nl_dump_params nl_debug_dp;

View File

@ -1,375 +1,19 @@
/*
* netlink/object-api.c Object API
* netlink/object-api.h Object API
*
* 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) 2003-2007 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_OBJECT_API_H_
#define NETLINK_OBJECT_API_H_
#ifndef NETLINK_DUMMY_OBJECT_API_H_
#define NETLINK_DUMMY_OBJECT_API_H_
#include <netlink/netlink.h>
#include <netlink/utils.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup object
* @defgroup object_api Object API
* @brief
*
* @par 1) Object Definition
* @code
* // Define your object starting with the common object header
* struct my_obj {
* NLHDR_COMMON
* int my_data;
* };
*
* // Fill out the object operations structure
* struct nl_object_ops my_ops = {
* .oo_name = "my_obj",
* .oo_size = sizeof(struct my_obj),
* };
*
* // At this point the object can be allocated, you may want to provide a
* // separate _alloc() function to ease allocting objects of this kind.
* struct nl_object *obj = nl_object_alloc(&my_ops);
*
* // And release it again...
* nl_object_put(obj);
* @endcode
*
* @par 2) Allocating additional data
* @code
* // You may require to allocate additional data and store it inside
* // object, f.e. assuming there is a field `ptr'.
* struct my_obj {
* NLHDR_COMMON
* void * ptr;
* };
*
* // And at some point you may assign allocated data to this field:
* my_obj->ptr = calloc(1, ...);
*
* // In order to not introduce any memory leaks you have to release
* // this data again when the last reference is given back.
* static void my_obj_free_data(struct nl_object *obj)
* {
* struct my_obj *my_obj = nl_object_priv(obj);
*
* free(my_obj->ptr);
* }
*
* // Also when the object is cloned, you must ensure for your pointer
* // stay valid even if one of the clones is freed by either making
* // a clone as well or increase the reference count.
* static int my_obj_clone(struct nl_object *src, struct nl_object *dst)
* {
* struct my_obj *my_src = nl_object_priv(src);
* struct my_obj *my_dst = nl_object_priv(dst);
*
* if (src->ptr) {
* dst->ptr = calloc(1, ...);
* memcpy(dst->ptr, src->ptr, ...);
* }
* }
*
* struct nl_object_ops my_ops = {
* ...
* .oo_free_data = my_obj_free_data,
* .oo_clone = my_obj_clone,
* };
* @endcode
*
* @par 3) Object Dumping
* @code
* static int my_obj_dump_detailed(struct nl_object *obj,
* struct nl_dump_params *params)
* {
* struct my_obj *my_obj = nl_object_priv(obj);
*
* // It is absolutely essential to use nl_dump() when printing
* // any text to make sure the dumping parameters are respected.
* nl_dump(params, "Obj Integer: %d\n", my_obj->my_int);
*
* // Before we can dump the next line, make sure to prefix
* // this line correctly.
* nl_new_line(params);
*
* // You may also split a line into multiple nl_dump() calls.
* nl_dump(params, "String: %s ", my_obj->my_string);
* nl_dump(params, "String-2: %s\n", my_obj->another_string);
* }
*
* struct nl_object_ops my_ops = {
* ...
* .oo_dump[NL_DUMP_FULL] = my_obj_dump_detailed,
* };
* @endcode
*
* @par 4) Object Attributes
* @code
* // The concept of object attributes is optional but can ease the typical
* // case of objects that have optional attributes, e.g. a route may have a
* // nexthop assigned but it is not required to.
*
* // The first step to define your object specific bitmask listing all
* // attributes
* #define MY_ATTR_FOO (1<<0)
* #define MY_ATTR_BAR (1<<1)
*
* // When assigning an optional attribute to the object, make sure
* // to mark its availability.
* my_obj->foo = 123123;
* my_obj->ce_mask |= MY_ATTR_FOO;
*
* // At any time you may use this mask to check for the availability
* // of the attribute, e.g. while dumping
* if (my_obj->ce_mask & MY_ATTR_FOO)
* nl_dump(params, "foo %d ", my_obj->foo);
*
* // One of the big advantages of this concept is that it allows for
* // standardized comparisons which make it trivial for caches to
* // identify unique objects by use of unified comparison functions.
* // In order for it to work, your object implementation must provide
* // a comparison function and define a list of attributes which
* // combined together make an object unique.
*
* static int my_obj_compare(struct nl_object *_a, struct nl_object *_b,
* uint32_t attrs, int flags)
* {
* struct my_obj *a = nl_object_priv(_a):
* struct my_obj *b = nl_object_priv(_b):
* int diff = 0;
*
* // We help ourselves in defining our own DIFF macro which will
* // call ATTR_DIFF() on both objects which will make sure to only
* // compare the attributes if required.
* #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)
*
* // Call our own diff macro for each attribute to build a bitmask
* // representing the attributes which mismatch.
* diff |= MY_DIFF(FOO, a->foo != b->foo)
* diff |= MY_DIFF(BAR, strcmp(a->bar, b->bar))
*
* return diff;
* }
*
* // In order to identify identical objects with differing attributes
* // you must specify the attributes required to uniquely identify
* // your object. Make sure to not include too many attributes, this
* // list is used when caches look for an old version of an object.
* struct nl_object_ops my_ops = {
* ...
* .oo_id_attrs = MY_ATTR_FOO,
* .oo_compare = my_obj_compare,
* };
* @endcode
* @{
*/
/**
* Common Object Header
*
* This macro must be included as first member in every object
* definition to allow objects to be cached.
*/
#define NLHDR_COMMON \
int ce_refcnt; \
struct nl_object_ops * ce_ops; \
struct nl_cache * ce_cache; \
struct nl_list_head ce_list; \
int ce_msgtype; \
int ce_flags; \
uint32_t ce_mask;
struct nl_object
{
NLHDR_COMMON
};
/**
* Return true if attribute is available in both objects
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
*
* @return True if the attribute is available, otherwise false is returned.
*/
#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
/**
* Return true if attribute is available in only one of both objects
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
*
* @return True if the attribute is available in only one of both objects,
* otherwise false is returned.
*/
#define AVAILABLE_MISMATCH(A, B, ATTR) (((A)->ce_mask ^ (B)->ce_mask) & (ATTR))
/**
* Return true if attributes mismatch
* @arg A an object
* @arg B another object
* @arg ATTR attribute bit
* @arg EXPR Comparison expression
*
* This function will check if the attribute in question is available
* in both objects, if not this will count as a mismatch.
*
* If available the function will execute the expression which must
* return true if the attributes mismatch.
*
* @return True if the attribute mismatch, or false if they match.
*/
#define ATTR_MISMATCH(A, B, ATTR, EXPR) (AVAILABLE_MISMATCH(A, B, ATTR) || \
(AVAILABLE(A, B, ATTR) && (EXPR)))
/**
* Return attribute bit if attribute does not match
* @arg LIST list of attributes to be compared
* @arg ATTR attribute bit
* @arg A an object
* @arg B another object
* @arg EXPR Comparison expression
*
* This function will check if the attribute in question is available
* in both objects, if not this will count as a mismatch.
*
* If available the function will execute the expression which must
* return true if the attributes mismatch.
*
* In case the attributes mismatch, the attribute is returned, otherwise
* 0 is returned.
*
* @code
* diff |= ATTR_DIFF(attrs, MY_ATTR_FOO, a, b, a->foo != b->foo);
* @endcode
*/
#define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
({ int diff = 0; \
if (((LIST) & (ATTR)) && ATTR_MISMATCH(A, B, ATTR, EXPR)) \
diff = ATTR; \
diff; })
/**
* Object Operations
*/
struct nl_object_ops
{
/**
* Unique name of object type
*
* Must be in the form family/name, e.g. "route/addr"
*/
char * oo_name;
/** Size of object including its header */
size_t oo_size;
/* List of attributes needed to uniquely identify the object */
uint32_t oo_id_attrs;
/**
* Constructor function
*
* Will be called when a new object of this type is allocated.
* Can be used to initialize members such as lists etc.
*/
void (*oo_constructor)(struct nl_object *);
/**
* Destructor function
*
* Will be called when an object is freed. Must free all
* resources which may have been allocated as part of this
* object.
*/
void (*oo_free_data)(struct nl_object *);
/**
* Cloning function
*
* Will be called when an object needs to be cloned. Please
* note that the generic object code will make an exact
* copy of the object first, therefore you only need to take
* care of members which require reference counting etc.
*
* May return a negative error code to abort cloning.
*/
int (*oo_clone)(struct nl_object *, struct nl_object *);
/**
* Dumping functions
*
* Will be called when an object is dumped. The implementations
* have to use nl_dump(), nl_dump_line(), and nl_new_line() to
* dump objects.
*
* The functions must return the number of lines printed.
*/
void (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *,
struct nl_dump_params *);
/**
* Comparison function
*
* Will be called when two objects of the same type are
* compared. It takes the two objects in question, an object
* specific bitmask defining which attributes should be
* compared and flags to control the behaviour.
*
* The function must return a bitmask with the relevant bit
* set for each attribute that mismatches.
*/
int (*oo_compare)(struct nl_object *, struct nl_object *,
uint32_t, int);
/**
* update function
*
* Will be called when the object given by first argument
* needs to be updated with the contents of the second object
*
* The function must return 0 for success and error for failure
* to update. In case of failure its assumed that the original
* object is not touched
*/
int (*oo_update)(struct nl_object *, struct nl_object *);
/**
* Hash Key generator function
*
* When called returns a hash key for the object being
* referenced. This key will be used by higher level hash functions
* to build association lists. Each object type gets to specify
* it's own key formulation
*/
void (*oo_keygen)(struct nl_object *, uint32_t *, uint32_t);
char *(*oo_attrs2str)(int, char *, size_t);
/**
* Get key attributes by family function
*/
uint32_t (*oo_id_attrs_get)(struct nl_object *);
};
/** @} */
#ifdef __cplusplus
}
#endif
#include <netlink/object.h>
#endif

View File

@ -64,6 +64,7 @@ extern struct nl_cache * nl_object_get_cache(struct nl_object *);
extern const char * nl_object_get_type(const struct nl_object *);
extern int nl_object_get_msgtype(const struct nl_object *);
struct nl_object_ops * nl_object_get_ops(const struct nl_object *);
uint32_t nl_object_get_id_attrs(struct nl_object *obj);
static inline void * nl_object_priv(struct nl_object *obj)

View File

@ -99,7 +99,6 @@ typedef enum {
extern struct rtnl_link *rtnl_link_alloc(void);
extern void rtnl_link_put(struct rtnl_link *);
extern void rtnl_link_free(struct rtnl_link *);
extern int rtnl_link_alloc_cache(struct nl_sock *, int, struct nl_cache **);
extern struct rtnl_link *rtnl_link_get(struct nl_cache *, int);
@ -141,6 +140,10 @@ extern int rtnl_link_str2operstate(const char *);
extern char * rtnl_link_mode2str(uint8_t, char *, size_t);
extern int rtnl_link_str2mode(const char *);
/* Carrier State Translations */
extern char * rtnl_link_carrier2str(uint8_t, char *, size_t);
extern int rtnl_link_str2carrier(const char *);
/* Access Functions */
extern void rtnl_link_set_qdisc(struct rtnl_link *, const char *);
extern char * rtnl_link_get_qdisc(struct rtnl_link *);
@ -182,6 +185,9 @@ extern int rtnl_link_get_link(struct rtnl_link *);
extern void rtnl_link_set_master(struct rtnl_link *, int);
extern int rtnl_link_get_master(struct rtnl_link *);
extern void rtnl_link_set_carrier(struct rtnl_link *, uint8_t);
extern uint8_t rtnl_link_get_carrier(struct rtnl_link *);
extern void rtnl_link_set_operstate(struct rtnl_link *, uint8_t);
extern uint8_t rtnl_link_get_operstate(struct rtnl_link *);

View File

@ -6,132 +6,15 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_API_H_
#define NETLINK_LINK_API_H_
#ifndef NETLINK_DUMMY_LINK_API_H_
#define NETLINK_DUMMY_LINK_API_H_
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup link_api
*
* Available operations to modules implementing a link info type.
*/
struct rtnl_link_info_ops
{
/** Name of link info type, must match name on kernel side */
char * io_name;
/** Reference count, DO NOT MODIFY */
int io_refcnt;
/** Called to assign an info type to a link.
* Has to allocate enough resources to hold attributes. Can
* use link->l_info to store a pointer. */
int (*io_alloc)(struct rtnl_link *);
/** Called to parse the link info attribute.
* Must parse the attribute and assign all values to the link.
*/
int (*io_parse)(struct rtnl_link *,
struct nlattr *,
struct nlattr *);
/** Called when the link object is dumped.
* Must dump the info type specific attributes. */
void (*io_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
struct nl_dump_params *);
/** Called when a link object is cloned.
* Must clone all info type specific attributes. */
int (*io_clone)(struct rtnl_link *, struct rtnl_link *);
/** Called when construction a link netlink message.
* Must append all info type specific attributes to the message. */
int (*io_put_attrs)(struct nl_msg *, struct rtnl_link *);
/** Called to release all resources previously allocated
* in either io_alloc() or io_parse(). */
void (*io_free)(struct rtnl_link *);
struct nl_list_head io_list;
};
extern struct rtnl_link_info_ops *rtnl_link_info_ops_lookup(const char *);
extern void rtnl_link_info_ops_put(struct rtnl_link_info_ops *);
extern int rtnl_link_register_info(struct rtnl_link_info_ops *);
extern int rtnl_link_unregister_info(struct rtnl_link_info_ops *);
/**
* @ingroup link_api
*
* Available operations to modules implementing a link address family.
*/
struct rtnl_link_af_ops
{
/** The address family this operations set implements */
const unsigned int ao_family;
/** Number of users of this operations, DO NOT MODIFY. */
int ao_refcnt;
/** Validation policy for IFLA_PROTINFO attribute. This pointer
* can be set to a nla_policy structure describing the minimal
* requirements the attribute must meet. Failure of meeting these
* requirements will result in a parsing error. */
const struct nla_policy *ao_protinfo_policy;
/** Called after address family has been assigned to link. Must
* allocate data buffer to hold address family specific data and
* store it in link->l_af_data. */
void * (*ao_alloc)(struct rtnl_link *);
/** Called when the link is cloned, must allocate a clone of the
* address family specific buffer and return it. */
void * (*ao_clone)(struct rtnl_link *, void *);
/** Called when the link gets freed. Must free all allocated data */
void (*ao_free)(struct rtnl_link *, void *);
/** Called if a IFLA_PROTINFO attribute needs to be parsed. Typically
* stores the parsed data in the address family specific buffer. */
int (*ao_parse_protinfo)(struct rtnl_link *,
struct nlattr *, void *);
/** Called if a IFLA_AF_SPEC attribute needs to be parsed. Typically
* stores the parsed data in the address family specific buffer. */
int (*ao_parse_af)(struct rtnl_link *,
struct nlattr *, void *);
/** Called if a link message is sent to the kernel. Must append the
* link address family specific attributes to the message. */
int (*ao_fill_af)(struct rtnl_link *,
struct nl_msg *msg, void *);
/** Dump address family specific link attributes */
void (*ao_dump[NL_DUMP_MAX+1])(struct rtnl_link *,
struct nl_dump_params *,
void *);
};
extern struct rtnl_link_af_ops *rtnl_link_af_ops_lookup(unsigned int);
extern void rtnl_link_af_ops_put(struct rtnl_link_af_ops *);
extern void * rtnl_link_af_alloc(struct rtnl_link *,
const struct rtnl_link_af_ops *);
extern void * rtnl_link_af_data(const struct rtnl_link *,
const struct rtnl_link_af_ops *);
extern int rtnl_link_af_register(struct rtnl_link_af_ops *);
extern int rtnl_link_af_unregister(struct rtnl_link_af_ops *);
#ifdef __cplusplus
}
#endif
#warning "You are including a deprecated header file, include <netlink/route/link.h>."
#endif

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2011-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_BONDING_H_
@ -19,6 +19,8 @@
extern "C" {
#endif
extern struct rtnl_link *rtnl_link_bond_alloc(void);
extern int rtnl_link_bond_add(struct nl_sock *, const char *,
struct rtnl_link *);

View File

@ -0,0 +1,56 @@
/*
* netlink/route/link/bridge.h Bridge
*
* 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) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_BRIDGE_H_
#define NETLINK_LINK_BRIDGE_H_
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Bridge flags
* @ingroup bridge
*/
enum rtnl_link_bridge_flags {
RTNL_BRIDGE_HAIRPIN_MODE = 0x0001,
RTNL_BRIDGE_BPDU_GUARD = 0x0002,
RTNL_BRIDGE_ROOT_BLOCK = 0x0004,
RTNL_BRIDGE_FAST_LEAVE = 0x0008,
};
extern struct rtnl_link *rtnl_link_bridge_alloc(void);
extern int rtnl_link_is_bridge(struct rtnl_link *);
extern int rtnl_link_bridge_has_ext_info(struct rtnl_link *);
extern int rtnl_link_bridge_set_port_state(struct rtnl_link *, uint8_t );
extern int rtnl_link_bridge_get_port_state(struct rtnl_link *);
extern int rtnl_link_bridge_set_priority(struct rtnl_link *, uint16_t);
extern int rtnl_link_bridge_get_priority(struct rtnl_link *);
extern int rtnl_link_bridge_set_cost(struct rtnl_link *, uint32_t);
extern int rtnl_link_bridge_get_cost(struct rtnl_link *, uint32_t *);
extern int rtnl_link_bridge_unset_flags(struct rtnl_link *, unsigned int);
extern int rtnl_link_bridge_set_flags(struct rtnl_link *, unsigned int);
extern int rtnl_link_bridge_get_flags(struct rtnl_link *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,60 @@
/*
* netlink/route/link/can.h CAN interface
*
* 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) 2012 Benedikt Spranger <b.spranger@linutronix.de>
*/
#ifndef NETLINK_LINK_CAN_H_
#define NETLINK_LINK_CAN_H_
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#include <linux/can/netlink.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int rtnl_link_is_can(struct rtnl_link *link);
extern char *rtnl_link_can_ctrlmode2str(int, char *, size_t);
extern int rtnl_link_can_str2ctrlmode(const char *);
extern int rtnl_link_can_restart(struct rtnl_link *);
extern int rtnl_link_can_freq(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_state(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_berr_rx(struct rtnl_link *);
extern int rtnl_link_can_berr_tx(struct rtnl_link *);
extern int rtnl_link_can_berr(struct rtnl_link *, struct can_berr_counter *);
extern int rtnl_link_can_get_bt_const(struct rtnl_link *,
struct can_bittiming_const *);
extern int rtnl_link_can_get_bittiming(struct rtnl_link *,
struct can_bittiming *);
extern int rtnl_link_can_set_bittiming(struct rtnl_link *,
struct can_bittiming *);
extern int rtnl_link_can_get_bitrate(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_set_bitrate(struct rtnl_link *, uint32_t);
extern int rtnl_link_can_get_sample_point(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_set_sample_point(struct rtnl_link *, uint32_t);
extern int rtnl_link_can_get_restart_ms(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_set_restart_ms(struct rtnl_link *, uint32_t);
extern int rtnl_link_can_get_ctrlmode(struct rtnl_link *, uint32_t *);
extern int rtnl_link_can_set_ctrlmode(struct rtnl_link *, uint32_t);
extern int rtnl_link_can_unset_ctrlmode(struct rtnl_link *, uint32_t);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,20 +1,20 @@
/*
* netlink/route/link/info-api.h Link Info API
* netlink/route/link/info-api.h Link Modules API
*
* 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) 2003-2010 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_INFO_API_H_
#define NETLINK_LINK_INFO_API_H_
#ifndef NETLINK_DUMMY_LINK_INFO_API_H_
#define NETLINK_DUMMY_LINK_INFO_API_H_
#warning "<netlink/route/link/info-api.h> is obsolete and may be removed in the future."
#warning "include <netlink/route/link/api.h> instead.
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#include <netlink/route/link/api.h>
#warning "You are including a deprecated header file, include <netlink/route/link.h>."
#endif

View File

@ -0,0 +1,46 @@
/*
* netlink/route/link/macvlan.h MACVLAN interface
*
* 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) 2013 Michael Braun <michael-dev@fami-braun.de>
*/
#ifndef NETLINK_LINK_MACVLAN_H_
#define NETLINK_LINK_MACVLAN_H_
#include <netlink/netlink.h>
#include <netlink/route/link.h>
#ifdef __cplusplus
extern "C" {
#endif
extern struct rtnl_link *rtnl_link_macvlan_alloc(void);
extern int rtnl_link_is_macvlan(struct rtnl_link *);
extern char * rtnl_link_macvlan_mode2str(int, char *, size_t);
extern int rtnl_link_macvlan_str2mode(const char *);
extern char * rtnl_link_macvlan_flags2str(int, char *, size_t);
extern int rtnl_link_macvlan_str2flags(const char *);
extern int rtnl_link_macvlan_set_mode(struct rtnl_link *,
uint32_t);
extern uint32_t rtnl_link_macvlan_get_mode(struct rtnl_link *);
extern int rtnl_link_macvlan_set_flags(struct rtnl_link *,
uint16_t);
extern int rtnl_link_macvlan_unset_flags(struct rtnl_link *,
uint16_t);
extern uint16_t rtnl_link_macvlan_get_flags(struct rtnl_link *);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -6,7 +6,7 @@
* 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-2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_LINK_VLAN_H_
@ -27,6 +27,8 @@ struct vlan_map
#define VLAN_PRIO_MAX 7
extern struct rtnl_link *rtnl_link_vlan_alloc(void);
extern int rtnl_link_is_vlan(struct rtnl_link *);
extern char * rtnl_link_vlan_flags2str(int, char *, size_t);

View File

@ -54,7 +54,6 @@ extern int rtnl_route_alloc_cache(struct nl_sock *, int, int,
struct nl_cache **);
extern void rtnl_route_get(struct rtnl_route *);
extern void rtnl_route_put(struct rtnl_route *);
extern int rtnl_route_parse(struct nlmsghdr *, struct rtnl_route **);
extern int rtnl_route_build_msg(struct nl_msg *, struct rtnl_route *);

View File

@ -6,138 +6,16 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2013 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_TC_API_H_
#define NETLINK_TC_API_H_
#ifndef NETLINK_DUMMY_TC_API_H_
#define NETLINK_DUMMY_TC_API_H_
#include <netlink/netlink.h>
#include <netlink/msg.h>
#include <netlink/route/tc.h>
#ifdef __cplusplus
extern "C" {
#endif
enum rtnl_tc_type {
RTNL_TC_TYPE_QDISC,
RTNL_TC_TYPE_CLASS,
RTNL_TC_TYPE_CLS,
__RTNL_TC_TYPE_MAX,
};
#define RTNL_TC_TYPE_MAX (__RTNL_TC_TYPE_MAX - 1)
/**
* Traffic control object operations
* @ingroup tc
*
* This structure holds function pointers and settings implementing
* the features of each traffic control object implementation.
*/
struct rtnl_tc_ops
{
/**
* Name of traffic control module
*/
char *to_kind;
/**
* Type of traffic control object
*/
enum rtnl_tc_type to_type;
/**
* Size of private data
*/
size_t to_size;
/**
* Dump callbacks
*/
void (*to_dump[NL_DUMP_MAX+1])(struct rtnl_tc *, void *,
struct nl_dump_params *);
/**
* Used to fill the contents of TCA_OPTIONS
*/
int (*to_msg_fill)(struct rtnl_tc *, void *, struct nl_msg *);
/**
* Uesd to to fill tc related messages, unlike with to_msg_fill,
* the contents is not encapsulated with a TCA_OPTIONS nested
* attribute.
*/
int (*to_msg_fill_raw)(struct rtnl_tc *, void *, struct nl_msg *);
/**
* TCA_OPTIONS message parser
*/
int (*to_msg_parser)(struct rtnl_tc *, void *);
/**
* Called before a tc object is destroyed
*/
void (*to_free_data)(struct rtnl_tc *, void *);
/**
* Called whenever a classifier object needs to be cloned
*/
int (*to_clone)(void *, void *);
/**
* Internal, don't touch
*/
struct nl_list_head to_list;
};
struct rtnl_tc_type_ops
{
enum rtnl_tc_type tt_type;
char *tt_dump_prefix;
/**
* Dump callbacks
*/
void (*tt_dump[NL_DUMP_MAX+1])(struct rtnl_tc *,
struct nl_dump_params *);
};
extern int rtnl_tc_msg_parse(struct nlmsghdr *,
struct rtnl_tc *);
extern int rtnl_tc_msg_build(struct rtnl_tc *, int,
int, struct nl_msg **);
extern void rtnl_tc_free_data(struct nl_object *);
extern int rtnl_tc_clone(struct nl_object *,
struct nl_object *);
extern void rtnl_tc_dump_line(struct nl_object *,
struct nl_dump_params *);
extern void rtnl_tc_dump_details(struct nl_object *,
struct nl_dump_params *);
extern void rtnl_tc_dump_stats(struct nl_object *,
struct nl_dump_params *);
extern int rtnl_tc_compare(struct nl_object *,
struct nl_object *,
uint32_t, int);
extern void * rtnl_tc_data(struct rtnl_tc *);
extern void * rtnl_tc_data_check(struct rtnl_tc *,
struct rtnl_tc_ops *);
extern struct rtnl_tc_ops * rtnl_tc_lookup_ops(enum rtnl_tc_type,
const char *);
extern struct rtnl_tc_ops * rtnl_tc_get_ops(struct rtnl_tc *);
extern int rtnl_tc_register(struct rtnl_tc_ops *);
extern void rtnl_tc_unregister(struct rtnl_tc_ops *);
extern void rtnl_tc_type_register(struct rtnl_tc_type_ops *);
extern void rtnl_tc_type_unregister(struct rtnl_tc_type_ops *);
#ifdef __cplusplus
}
#endif
#warning "You are including a deprecated header file, include <netlink/route/tc.h>."
#endif

View File

@ -23,6 +23,15 @@
extern "C" {
#endif
enum rtnl_tc_type {
RTNL_TC_TYPE_QDISC,
RTNL_TC_TYPE_CLASS,
RTNL_TC_TYPE_CLS,
__RTNL_TC_TYPE_MAX,
};
#define RTNL_TC_TYPE_MAX (__RTNL_TC_TYPE_MAX - 1)
/**
* Compute tc handle based on major and minor parts
* @ingroup tc

View File

@ -13,7 +13,7 @@ AM_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
lib_LTLIBRARIES = \
libnl-3.la libnl-genl-3.la libnl-route-3.la libnl-nf-3.la
libnl-3.la libnl-genl-3.la libnl-route-3.la libnl-nf-3.la libnl-dect-3.la
libnl_3_la_SOURCES = \
addr.c attr.c cache.c cache_mngr.c cache_mngt.c data.c \
@ -32,6 +32,12 @@ libnl_nf_3_la_SOURCES = \
netfilter/queue_msg.c netfilter/queue_msg_obj.c netfilter/queue_obj.c \
netfilter/exp.c netfilter/exp_obj.c
libnl_dect_3_la_LIBADD = libnl-3.la
libnl_dect_3_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
CLEANFILES = \
route/pktloc_grammar.c route/pktloc_grammar.h \
route/pktloc_syntax.c route/pktloc_syntax.h \
@ -41,13 +47,13 @@ CLEANFILES = \
# Hack to avoid using ylwrap. It does not function correctly in combination
# with --header-file=
route/pktloc_grammar.c: route/pktloc_grammar.l
$(AM_V_GEN) $(LEX) --header-file=route/pktloc_grammar.h $(LFLAGS) -o $@ $^
$(AM_V_GEN) $(FLEX) --header-file=route/pktloc_grammar.h $(LFLAGS) -o $@ $^
route/pktloc_syntax.c: route/pktloc_syntax.y
$(AM_V_GEN) $(YACC) -d $(YFLAGS) -o $@ $^
route/cls/ematch_grammar.c: route/cls/ematch_grammar.l
$(AM_V_GEN) $(LEX) --header-file=route/cls/ematch_grammar.h $(LFLAGS) -o $@ $^
$(AM_V_GEN) $(FLEX) --header-file=route/cls/ematch_grammar.h $(LFLAGS) -o $@ $^
route/cls/ematch_syntax.c: route/cls/ematch_syntax.y
$(AM_V_GEN) $(YACC) -d $(YFLAGS) -o $@ $^
@ -69,7 +75,7 @@ libnl_route_3_la_SOURCES = \
\
route/link/api.c route/link/vlan.c route/link/dummy.c \
route/link/bridge.c route/link/inet6.c route/link/inet.c \
route/link/bonding.c \
route/link/bonding.c route/link/can.c route/link/macvlan.c \
\
route/qdisc/blackhole.c route/qdisc/cbq.c route/qdisc/dsmark.c \
route/qdisc/fifo.c route/qdisc/htb.c route/qdisc/netem.c \

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
*/
/**
@ -27,7 +27,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/addr.h>
@ -170,9 +170,17 @@ static void addr_destroy(struct nl_addr *addr)
*/
/**
* Allocate new abstract address object.
* @arg maxsize Maximum size of the binary address.
* @return Newly allocated address object or NULL
* Allocate empty abstract address
* @arg maxsize Upper limit of the binary address to be stored
*
* The new address object will be empty with a prefix length of 0 and will
* be capable of holding binary addresses up to the specified limit.
*
* @see nl_addr_build()
* @see nl_addr_parse()
* @see nl_addr_put()
*
* @return Allocated address object or NULL upon failure.
*/
struct nl_addr *nl_addr_alloc(size_t maxsize)
{
@ -189,11 +197,21 @@ struct nl_addr *nl_addr_alloc(size_t maxsize)
}
/**
* Allocate new abstract address object based on a binary address.
* @arg family Address family.
* @arg buf Buffer containing the binary address.
* @arg size Length of binary address buffer.
* @return Newly allocated address handle or NULL
* Allocate abstract address based on a binary address.
* @arg family Address family
* @arg buf Binary address
* @arg size Length of binary address
*
* This function will allocate an abstract address capable of holding the
* binary address specified. The prefix length will be set to the full
* length of the binary address provided.
*
* @see nl_addr_alloc()
* @see nl_addr_alloc_attr()
* @see nl_addr_parse()
* @see nl_addr_put()
*
* @return Allocated address object or NULL upon failure.
*/
struct nl_addr *nl_addr_build(int family, void *buf, size_t size)
{
@ -214,14 +232,25 @@ struct nl_addr *nl_addr_build(int family, void *buf, size_t size)
}
/**
* Allocate abstract address based on netlink attribute.
* @arg nla Netlink attribute of unspecific type.
* Allocate abstract address based on Netlink attribute.
* @arg nla Netlink attribute
* @arg family Address family.
*
* Considers the netlink attribute payload a address of the specified
* family and allocates a new abstract address based on it.
* Allocates an abstract address based on the specified Netlink attribute
* by interpreting the payload of the Netlink attribute as the binary
* address.
*
* @return Newly allocated address handle or NULL.
* This function is identical to:
* @code
* nl_addr_build(family, nla_data(nla), nla_len(nla));
* @endcode
*
* @see nl_addr_alloc()
* @see nl_addr_build()
* @see nl_addr_parse()
* @see nl_addr_put()
*
* @return Allocated address object or NULL upon failure.
*/
struct nl_addr *nl_addr_alloc_attr(struct nlattr *nla, int family)
{
@ -229,13 +258,13 @@ struct nl_addr *nl_addr_alloc_attr(struct nlattr *nla, int family)
}
/**
* Allocate abstract address object based on a character string
* Allocate abstract address based on character string
* @arg addrstr Address represented as character string.
* @arg hint Address family hint or AF_UNSPEC.
* @arg result Pointer to store resulting address.
*
* Regognizes the following address formats:
*@code
* @code
* Format Len Family
* ----------------------------------------------------------------
* IPv6 address format 16 AF_INET6
@ -253,6 +282,10 @@ struct nl_addr *nl_addr_alloc_attr(struct nlattr *nla, int family)
* The prefix length may be appened at the end prefixed with a
* slash, e.g. 10.0.0.0/8.
*
* @see nl_addr_alloc()
* @see nl_addr_build()
* @see nl_addr_put()
*
* @return 0 on success or a negative error code.
*/
int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
@ -424,10 +457,16 @@ errout:
}
/**
* Clone existing abstract address object.
* @arg addr Abstract address object.
* @return Newly allocated abstract address object being a duplicate of the
* specified address object or NULL if a failure occured.
* Clone existing abstract address object
* @arg addr Abstract address object
*
* Allocates new abstract address representing an identical clone of an
* existing address.
*
* @see nl_addr_alloc()
* @see nl_addr_put()
*
* @return Allocated abstract address or NULL upon failure.
*/
struct nl_addr *nl_addr_clone(struct nl_addr *addr)
{
@ -447,6 +486,18 @@ struct nl_addr *nl_addr_clone(struct nl_addr *addr)
* @{
*/
/**
* Increase the reference counter of an abstract address
* @arg addr Abstract address
*
* Increases the reference counter of the address and thus prevents the
* release of the memory resources until the reference is given back
* using the function nl_addr_put().
*
* @see nl_addr_put()
*
* @return Pointer to the existing abstract address
*/
struct nl_addr *nl_addr_get(struct nl_addr *addr)
{
addr->a_refcnt++;
@ -454,6 +505,15 @@ struct nl_addr *nl_addr_get(struct nl_addr *addr)
return addr;
}
/**
* Decrease the reference counter of an abstract address
* @arg addr Abstract addr
*
* @note The resources of the abstract address will be freed after the
* last reference to the address has been returned.
*
* @see nl_addr_get()
*/
void nl_addr_put(struct nl_addr *addr)
{
if (!addr)
@ -466,9 +526,10 @@ void nl_addr_put(struct nl_addr *addr)
}
/**
* Check whether an abstract address object is shared.
* Check whether an abstract address is shared.
* @arg addr Abstract address object.
* @return Non-zero if the abstract address object is shared, otherwise 0.
*
* @return Non-zero if the abstract address is shared, otherwise 0.
*/
int nl_addr_shared(struct nl_addr *addr)
{
@ -483,12 +544,21 @@ int nl_addr_shared(struct nl_addr *addr)
*/
/**
* Compares two abstract address objects.
* @arg a A abstract address object.
* @arg b Another abstract address object.
* Compare abstract addresses
* @arg a An abstract address
* @arg b Another abstract address
*
* @return Integer less than, equal to or greather than zero if \c is found,
* respectively to be less than, to, or be greater than \c b.
* Verifies whether the address family, address length, prefix length, and
* binary addresses of two abstract addresses matches.
*
* @note This function will *not* respect the prefix length in the sense
* that only the actual prefix will be compared. Please refer to the
* nl_addr_cmp_prefix() function if you require this functionality.
*
* @see nl_addr_cmp_prefix()
*
* @return Integer less than, equal to or greather than zero if the two
* addresses match.
*/
int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
{
@ -509,12 +579,17 @@ int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
}
/**
* Compares the prefix of two abstract address objects.
* @arg a A abstract address object.
* @arg b Another abstract address object.
* Compare the prefix of two abstract addresses
* @arg a An abstract address
* @arg b Another abstract address
*
* @return Integer less than, equal to or greather than zero if \c is found,
* respectively to be less than, to, or be greater than \c b.
* Verifies whether the address family and the binary address covered by
* the smaller prefix length of the two abstract addresses matches.
*
* @see nl_addr_cmp()
*
* @return Integer less than, equal to or greather than zero if the two
* addresses match.
*/
int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
{
@ -525,8 +600,8 @@ int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
int bytes = len / 8;
d = memcmp(a->a_addr, b->a_addr, bytes);
if (d == 0) {
int mask = (1UL << (len % 8)) - 1UL;
if (d == 0 && (len % 8) != 0) {
int mask = (0xFF00 >> (len % 8)) & 0xFF;
d = (a->a_addr[bytes] & mask) -
(b->a_addr[bytes] & mask);
@ -538,7 +613,9 @@ int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
/**
* Returns true if the address consists of all zeros
* @arg addr Address to look at.
* @arg addr Abstract address
*
* @return 1 if the binary address consists of all zeros, 0 otherwise.
*/
int nl_addr_iszero(struct nl_addr *addr)
{
@ -552,11 +629,11 @@ int nl_addr_iszero(struct nl_addr *addr)
}
/**
* Check if an address matches a certain family.
* Check if address string is parseable for a specific address family
* @arg addr Address represented as character string.
* @arg family Desired address family.
*
* @return 1 if the address is of the desired address family,
* @return 1 if the address is parseable assuming the specified address family,
* otherwise 0 is returned.
*/
int nl_addr_valid(char *addr, int family)
@ -588,9 +665,10 @@ int nl_addr_valid(char *addr, int family)
}
/**
* Guess address family of an abstract address object based on address size.
* Guess address family of abstract address based on address size
* @arg addr Abstract address object.
* @return Address family or AF_UNSPEC if guessing wasn't successful.
*
* @return Numeric address family or AF_UNSPEC
*/
int nl_addr_guess_family(struct nl_addr *addr)
{
@ -666,7 +744,7 @@ int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa,
* Call getaddrinfo() for an abstract address object.
* @arg addr Abstract address object.
* @arg result Pointer to store resulting address list.
*
*
* Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
* mode.
*
@ -744,11 +822,26 @@ int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen)
* @{
*/
/**
* Set address family
* @arg addr Abstract address object
* @arg family Address family
*
* @see nl_addr_get_family()
*/
void nl_addr_set_family(struct nl_addr *addr, int family)
{
addr->a_family = family;
}
/**
* Return address family
* @arg addr Abstract address object
*
* @see nl_addr_set_family()
*
* @return The numeric address family or `AF_UNSPEC`
*/
int nl_addr_get_family(struct nl_addr *addr)
{
return addr->a_family;
@ -759,6 +852,20 @@ int nl_addr_get_family(struct nl_addr *addr)
* @arg addr Abstract address object.
* @arg buf Buffer containing binary address.
* @arg len Length of buffer containing binary address.
*
* Modifies the binary address portion of the abstract address. The
* abstract address must be capable of holding the required amount
* or this function will fail.
*
* @note This function will *not* modify the prefix length. It is within
* the responsibility of the caller to set the prefix length to the
* desirable length.
*
* @see nl_addr_alloc()
* @see nl_addr_get_binary_addr()
* @see nl_addr_get_len()
*
* @return 0 on success or a negative error code.
*/
int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
{
@ -766,7 +873,10 @@ int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
return -NLE_RANGE;
addr->a_len = len;
memcpy(addr->a_addr, buf, len);
memset(addr->a_addr, 0, addr->a_maxsize);
if (len)
memcpy(addr->a_addr, buf, len);
return 0;
}
@ -774,6 +884,11 @@ int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
/**
* Get binary address of abstract address object.
* @arg addr Abstract address object.
*
* @see nl_addr_set_binary_addr()
* @see nl_addr_get_len()
*
* @return Pointer to binary address of length nl_addr_get_len()
*/
void *nl_addr_get_binary_addr(struct nl_addr *addr)
{
@ -783,20 +898,32 @@ void *nl_addr_get_binary_addr(struct nl_addr *addr)
/**
* Get length of binary address of abstract address object.
* @arg addr Abstract address object.
*
* @see nl_addr_get_binary_addr()
* @see nl_addr_set_binary_addr()
*/
unsigned int nl_addr_get_len(struct nl_addr *addr)
{
return addr->a_len;
}
/**
* Set the prefix length of an abstract address
* @arg addr Abstract address object
* @arg prefixlen New prefix length
*
* @see nl_addr_get_prefixlen()
*/
void nl_addr_set_prefixlen(struct nl_addr *addr, int prefixlen)
{
addr->a_prefixlen = prefixlen;
}
/**
* Get prefix length of abstract address object.
* @arg addr Abstract address object.
* Return prefix length of abstract address object.
* @arg addr Abstract address object
*
* @see nl_addr_set_prefixlen()
*/
unsigned int nl_addr_get_prefixlen(struct nl_addr *addr)
{
@ -878,7 +1005,6 @@ prefix:
static const struct trans_tbl afs[] = {
__ADD(AF_UNSPEC,unspec)
__ADD(AF_UNIX,unix)
__ADD(AF_LOCAL,local)
__ADD(AF_INET,inet)
__ADD(AF_AX25,ax25)
__ADD(AF_IPX,ipx)
@ -894,17 +1020,35 @@ static const struct trans_tbl afs[] = {
__ADD(AF_SECURITY,security)
__ADD(AF_KEY,key)
__ADD(AF_NETLINK,netlink)
__ADD(AF_ROUTE,route)
__ADD(AF_PACKET,packet)
__ADD(AF_ASH,ash)
__ADD(AF_ECONET,econet)
__ADD(AF_ATMSVC,atmsvc)
__ADD(AF_RDS,rds)
__ADD(AF_SNA,sna)
__ADD(AF_IRDA,irda)
__ADD(AF_PPPOX,pppox)
__ADD(AF_WANPIPE,wanpipe)
__ADD(AF_LLC,llc)
__ADD(AF_CAN,can)
__ADD(AF_TIPC,tipc)
__ADD(AF_BLUETOOTH,bluetooth)
__ADD(AF_IUCV,iucv)
__ADD(AF_RXRPC,rxrpc)
__ADD(AF_ISDN,isdn)
__ADD(AF_PHONET,phonet)
#ifdef AF_IEEE802154
__ADD(AF_IEEE802154,ieee802154)
#endif
#ifdef AF_CAIF
__ADD(AF_CAIF,caif)
#endif
#ifdef AF_ALG
__ADD(AF_ALG,alg)
#endif
#ifdef AF_NFC
__ADD(AF_NFC,nfc)
#endif
};
char *nl_af2str(int family, char *buf, size_t size)

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-2013 Thomas Graf <tgraf@suug.ch>
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/addr.h>
@ -182,6 +182,7 @@ static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
[NLA_U32] = sizeof(uint32_t),
[NLA_U64] = sizeof(uint64_t),
[NLA_STRING] = 1,
[NLA_FLAG] = 0,
};
static int validate_nla(struct nlattr *nla, int maxtype,
@ -204,9 +205,6 @@ static int validate_nla(struct nlattr *nla, int maxtype,
else if (pt->type != NLA_UNSPEC)
minlen = nla_attr_minlen[pt->type];
if (pt->type == NLA_FLAG && nla_len(nla) > 0)
return -NLE_RANGE;
if (nla_len(nla) < minlen)
return -NLE_RANGE;
@ -252,20 +250,24 @@ int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
nla_for_each_attr(nla, head, len, rem) {
int type = nla_type(nla);
if (type == 0) {
NL_DBG(1, "Illegal nla->nla_type == 0\n");
/* Padding attributes */
if (type == 0)
continue;
if (type > maxtype)
continue;
if (policy) {
err = validate_nla(nla, maxtype, policy);
if (err < 0)
goto errout;
}
if (type <= maxtype) {
if (policy) {
err = validate_nla(nla, maxtype, policy);
if (err < 0)
goto errout;
}
if (tb[type])
NL_DBG(1, "Attribute of type %#x found multiple times in message, "
"previous attribute is being ignored.\n", type);
tb[type] = nla;
}
tb[type] = nla;
}
if (rem > 0)
@ -462,7 +464,7 @@ struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
if ((tlen + msg->nm_nlh->nlmsg_len) > msg->nm_size)
if (tlen > msg->nm_size)
return NULL;
nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh);
@ -820,8 +822,7 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
* Kernel can't handle empty nested attributes, trim the
* attribute header again
*/
msg->nm_nlh->nlmsg_len -= NLA_HDRLEN;
memset(nlmsg_tail(msg->nm_nlh), 0, NLA_HDRLEN);
nla_nest_cancel(msg, start);
return 0;
}
@ -849,6 +850,28 @@ int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
return 0;
}
/**
* Cancel the addition of a nested attribute
* @arg msg Netlink message
* @arg attr Nested netlink attribute
*
* Removes any partially added nested Netlink attribute from the message
* by resetting the message to the size before the call to nla_nest_start()
* and by overwriting any potentially touched message segments with 0.
*/
void nla_nest_cancel(struct nl_msg *msg, struct nlattr *attr)
{
ssize_t len;
len = (void *) nlmsg_tail(msg->nm_nlh) - (void *) attr;
if (len < 0)
BUG();
else if (len > 0) {
msg->nm_nlh->nlmsg_len -= len;
memset(nlmsg_tail(msg->nm_nlh), 0, len);
}
}
/**
* Create attribute index based on nested attribute
* @arg tb Index array to be filled (maxtype+1 elements).
@ -868,6 +891,17 @@ int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
}
/**
* Return true if attribute has NLA_F_NESTED flag set
* @arg attr Netlink attribute
*
* @return True if attribute has NLA_F_NESTED flag set, oterhwise False.
*/
int nla_is_nested(struct nlattr *attr)
{
return !!(attr->nla_type & NLA_F_NESTED);
}
/** @} */
/** @} */

View File

@ -49,7 +49,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/object.h>
@ -307,6 +307,9 @@ struct nl_cache *nl_cache_subset(struct nl_cache *orig,
if (!cache)
return NULL;
NL_DBG(2, "Filling subset of cache %p <%s> with filter %p into %p\n",
orig, nl_cache_name(orig), filter, cache);
nl_list_for_each_entry(obj, &orig->c_items, ce_list) {
if (!nl_object_match_filter(obj, filter))
continue;
@ -341,6 +344,8 @@ struct nl_cache *nl_cache_clone(struct nl_cache *cache)
if (!clone)
return NULL;
NL_DBG(2, "Cloning %p into %p\n", cache, clone);
nl_list_for_each_entry(obj, &cache->c_items, ce_list)
nl_cache_add(clone, obj);
@ -362,7 +367,7 @@ void nl_cache_clear(struct nl_cache *cache)
{
struct nl_object *obj, *tmp;
NL_DBG(1, "Clearing cache %p <%s>...\n", cache, nl_cache_name(cache));
NL_DBG(2, "Clearing cache %p <%s>...\n", cache, nl_cache_name(cache));
nl_list_for_each_entry_safe(obj, tmp, &cache->c_items, ce_list)
nl_cache_remove(obj);
@ -375,7 +380,7 @@ static void __nl_cache_free(struct nl_cache *cache)
if (cache->hashtable)
nl_hash_table_free(cache->hashtable);
NL_DBG(1, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache));
NL_DBG(2, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache));
free(cache);
}
@ -386,6 +391,9 @@ static void __nl_cache_free(struct nl_cache *cache)
void nl_cache_get(struct nl_cache *cache)
{
cache->c_refcnt++;
NL_DBG(3, "Incremented cache %p <%s> reference count to %d\n",
cache, nl_cache_name(cache), cache->c_refcnt);
}
/**
@ -403,8 +411,9 @@ void nl_cache_free(struct nl_cache *cache)
return;
cache->c_refcnt--;
NL_DBG(4, "Returned cache reference %p, %d remaining\n",
cache, cache->c_refcnt);
NL_DBG(3, "Decremented cache %p <%s> reference count, %d remaining\n",
cache, nl_cache_name(cache), cache->c_refcnt);
if (cache->c_refcnt <= 0)
__nl_cache_free(cache);
@ -439,8 +448,8 @@ static int __cache_add(struct nl_cache *cache, struct nl_object *obj)
nl_list_add_tail(&obj->ce_list, &cache->c_items);
cache->c_nitems++;
NL_DBG(1, "Added %p to cache %p <%s>.\n",
obj, cache, nl_cache_name(cache));
NL_DBG(3, "Added object %p to cache %p <%s>, nitems %d\n",
obj, cache, nl_cache_name(cache), cache->c_nitems);
return 0;
}
@ -476,6 +485,8 @@ int nl_cache_add(struct nl_cache *cache, struct nl_object *obj)
return -NLE_OBJ_MISMATCH;
if (!nl_list_empty(&obj->ce_list)) {
NL_DBG(3, "Object %p already in cache, cloning new object\n", obj);
new = nl_object_clone(obj);
if (!new)
return -NLE_NOMEM;
@ -514,7 +525,8 @@ int nl_cache_move(struct nl_cache *cache, struct nl_object *obj)
if (cache->c_ops->co_obj_ops != obj->ce_ops)
return -NLE_OBJ_MISMATCH;
NL_DBG(3, "Moving object %p to cache %p\n", obj, cache);
NL_DBG(3, "Moving object %p from cache %p to cache %p\n",
obj, obj->ce_cache, cache);
/* Acquire reference, if already in a cache this will be
* reverted during removal */
@ -547,7 +559,7 @@ void nl_cache_remove(struct nl_object *obj)
if (cache->hashtable) {
ret = nl_hash_table_del(cache->hashtable, obj);
if (ret < 0)
NL_DBG(3, "Failed to delete %p from cache %p <%s>.\n",
NL_DBG(2, "Failed to delete %p from cache %p <%s>.\n",
obj, cache, nl_cache_name(cache));
}
@ -556,7 +568,7 @@ void nl_cache_remove(struct nl_object *obj)
nl_object_put(obj);
cache->c_nitems--;
NL_DBG(1, "Deleted %p from cache %p <%s>.\n",
NL_DBG(2, "Deleted object %p from cache %p <%s>.\n",
obj, cache, nl_cache_name(cache));
}
@ -630,12 +642,12 @@ void nl_cache_set_flags(struct nl_cache *cache, unsigned int flags)
static int nl_cache_request_full_dump(struct nl_sock *sk,
struct nl_cache *cache)
{
NL_DBG(2, "Requesting dump from kernel for cache %p <%s>...\n",
cache, nl_cache_name(cache));
if (cache->c_ops->co_request_update == NULL)
return -NLE_OPNOTSUPP;
NL_DBG(2, "Requesting update from kernel for cache %p <%s>\n",
cache, nl_cache_name(cache));
return cache->c_ops->co_request_update(cache, sk);
}
@ -674,8 +686,8 @@ static int __cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
.params = param,
};
NL_DBG(1, "Picking up answer for cache %p <%s>...\n",
cache, nl_cache_name(cache));
NL_DBG(2, "Picking up answer for cache %p <%s>\n",
cache, nl_cache_name(cache));
cb = nl_cb_clone(sk->s_cb);
if (cb == NULL)
@ -685,9 +697,8 @@ static int __cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
err = nl_recvmsgs(sk, cb);
if (err < 0)
NL_DBG(2, "While picking up for %p <%s>, recvmsgs() returned " \
"%d: %s", cache, nl_cache_name(cache),
err, nl_geterror(err));
NL_DBG(2, "While picking up for %p <%s>, recvmsgs() returned %d: %s\n",
cache, nl_cache_name(cache), err, nl_geterror(err));
nl_cb_put(cb);
@ -696,7 +707,21 @@ static int __cache_pickup(struct nl_sock *sk, struct nl_cache *cache,
static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
{
return nl_cache_add((struct nl_cache *) p->pp_arg, c);
struct nl_cache *cache = (struct nl_cache *)p->pp_arg;
struct nl_object *old;
old = nl_cache_search(cache, c);
if (old) {
if (nl_object_update(old, c) == 0) {
nl_object_put(old);
return 0;
}
nl_cache_remove(old);
nl_object_put(old);
}
return nl_cache_add(cache, c);
}
/**
@ -705,7 +730,10 @@ static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
* @arg cache Cache to put items into.
*
* Waits for netlink messages to arrive, parses them and puts them into
* the specified cache.
* the specified cache. If an old object with same key attributes is
* present in the cache, it is replaced with the new object.
* If the old object type supports an update operation, an update is
* attempted before a replace.
*
* @return 0 on success or a negative error code.
*/
@ -735,8 +763,9 @@ static int cache_include(struct nl_cache *cache, struct nl_object *obj,
* Handle them first.
*/
if (nl_object_update(old, obj) == 0) {
cb(cache, old, NL_ACT_CHANGE, data);
nl_object_put(obj);
if (cb)
cb(cache, old, NL_ACT_CHANGE, data);
nl_object_put(old);
return 0;
}
@ -782,6 +811,9 @@ int nl_cache_include(struct nl_cache *cache, struct nl_object *obj,
return cache_include(cache, obj, &ops->co_msgtypes[i],
change_cb, data);
NL_DBG(3, "Object %p does not seem to belong to cache %p <%s>\n",
obj, cache, nl_cache_name(cache));
return -NLE_MSGTYPE_NOSUPPORT;
}
@ -829,7 +861,9 @@ restart:
goto restart;
else if (err < 0)
goto errout;
grp++;
if (grp)
grp++;
} while (grp && grp->ag_group &&
(cache->c_flags & NL_CACHE_AF_ITER));
@ -887,7 +921,10 @@ errout:
* @arg msg netlink message
*
* Parses a netlink message by calling the cache specific message parser
* and adds the new element to the cache.
* and adds the new element to the cache. If an old object with same key
* attributes is present in the cache, it is replaced with the new object.
* If the old object type supports an update operation, an update is
* attempted before a replace.
*
* @return 0 or a negative error code.
*/
@ -928,20 +965,21 @@ restart:
if (err < 0)
return err;
NL_DBG(2, "Updating cache %p <%s> for family %u, request sent, waiting for reply\n",
cache, nl_cache_name(cache), grp ? grp->ag_family : AF_UNSPEC);
err = nl_cache_pickup(sk, cache);
if (err == -NLE_DUMP_INTR) {
NL_DBG(1, "dump interrupted, restarting!\n");
NL_DBG(2, "Dump interrupted, restarting!\n");
goto restart;
} else if (err < 0)
break;
grp++;
if (grp)
grp++;
} while (grp && grp->ag_group &&
(cache->c_flags & NL_CACHE_AF_ITER));
NL_DBG(2, "Upading cache %p <%s>, request sent, waiting for dump...\n",
cache, nl_cache_name(cache));
return err;
}
@ -998,6 +1036,45 @@ struct nl_object *nl_cache_search(struct nl_cache *cache,
return NULL;
}
/**
* Find object in cache
* @arg cache Cache
* @arg filter object acting as a filter
*
* Searches the cache for an object which matches the object filter.
* If the filter attributes matches the object type id attributes,
* and the cache supports hash lookups, a faster hashtable lookup
* is used to return the object. Else, function nl_object_match_filter() is
* used to determine if the objects match. If a matching object is
* found, the reference counter is incremented and the object is returned.
*
* Therefore, if an object is returned, the reference to the object
* must be returned by calling nl_object_put() after usage.
*
* @return Reference to object or NULL if not found.
*/
struct nl_object *nl_cache_find(struct nl_cache *cache,
struct nl_object *filter)
{
struct nl_object *obj;
if (cache->c_ops == NULL)
BUG();
if ((nl_object_get_id_attrs(filter) == filter->ce_mask)
&& cache->hashtable)
return __cache_fast_lookup(cache, filter);
nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
if (nl_object_match_filter(obj, filter)) {
nl_object_get(obj);
return obj;
}
}
return NULL;
}
/**
* Mark all objects of a cache
* @arg cache Cache
@ -1009,8 +1086,8 @@ void nl_cache_mark_all(struct nl_cache *cache)
{
struct nl_object *obj;
NL_DBG(2, "Marking all objects in cache %p <%s>...\n",
cache, nl_cache_name(cache));
NL_DBG(2, "Marking all objects in cache %p <%s>\n",
cache, nl_cache_name(cache));
nl_list_for_each_entry(obj, &cache->c_items, ce_list)
nl_object_mark(obj);
@ -1052,7 +1129,7 @@ void nl_cache_dump_filter(struct nl_cache *cache,
struct nl_object_ops *ops;
struct nl_object *obj;
NL_DBG(2, "Dumping cache %p <%s> filter %p\n",
NL_DBG(2, "Dumping cache %p <%s> with filter %p\n",
cache, nl_cache_name(cache), filter);
if (type > NL_DUMP_MAX || type < 0)

View File

@ -32,7 +32,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
@ -435,7 +435,7 @@ int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
}
nl_cb_put(cb);
if (err < 0)
if (err < 0 && err != -NLE_AGAIN)
return err;
return nread;

View File

@ -25,7 +25,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
@ -235,7 +235,9 @@ void nl_cache_ops_foreach(void (*cb)(struct nl_cache_ops *, void *), void *arg)
*/
void nl_cache_ops_set_flags(struct nl_cache_ops *ops, unsigned int flags)
{
nl_write_lock(&cache_ops_lock);
ops->co_flags |= flags;
nl_write_unlock(&cache_ops_lock);
}
/**

View File

@ -27,7 +27,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <linux/socket.h>

245
lib/dect/ari.c Normal file
View File

@ -0,0 +1,245 @@
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/ari.h>
#include <linux/dect_netlink.h>
#define ARI_ATTR_CLASS 0x01
#define ARI_ATTR_FPN 0x02
#define ARI_ATTR_FPS 0x03
#define ARI_ATTR_EMC 0x04
#define ARI_ATTR_EIC 0x05
#define ARI_ATTR_POC 0x06
#define ARI_ATTR_GOP 0x07
#define ARI_ATTR_FIL 0x08
static struct nla_policy nl_dect_ari_policy[DECTA_ARI_MAX + 1] = {
[DECTA_ARI_CLASS] = { .type = NLA_U8 },
[DECTA_ARI_FPN] = { .type = NLA_U32 },
[DECTA_ARI_FPS] = { .type = NLA_U32 },
[DECTA_ARI_EMC] = { .type = NLA_U16 },
[DECTA_ARI_EIC] = { .type = NLA_U16 },
[DECTA_ARI_POC] = { .type = NLA_U16 },
[DECTA_ARI_GOP] = { .type = NLA_U32 },
[DECTA_ARI_FIL] = { .type = NLA_U32 },
};
int nl_dect_parse_ari(struct nl_dect_ari *ari, struct nlattr *nla)
{
struct nlattr *tb[DECTA_ARI_MAX + 1];
int err;
err = nla_parse_nested(tb, DECTA_ARI_MAX, nla, nl_dect_ari_policy);
if (err < 0)
return err;
if (tb[DECTA_ARI_CLASS] == NULL)
return -NLE_INVAL;
memset(ari, 0, sizeof(ari));
ari->ari_class = nla_get_u8(tb[DECTA_ARI_CLASS]);
if (tb[DECTA_ARI_FPN] != NULL)
ari->ari_fpn = nla_get_u32(tb[DECTA_ARI_FPN]);
switch (ari->ari_class) {
case DECT_ARC_A:
if (tb[DECTA_ARI_EMC] != NULL)
ari->ari_u.emc = nla_get_u16(tb[DECTA_ARI_EMC]);
break;
case DECT_ARC_B:
if (tb[DECTA_ARI_EIC] != NULL)
ari->ari_u.eic = nla_get_u16(tb[DECTA_ARI_EIC]);
if (tb[DECTA_ARI_FPS] != NULL)
ari->ari_fps = nla_get_u32(tb[DECTA_ARI_FPS]);
break;
case DECT_ARC_C:
if (tb[DECTA_ARI_POC] != NULL)
ari->ari_u.poc = nla_get_u16(tb[DECTA_ARI_POC]);
if (tb[DECTA_ARI_FPS] != NULL)
ari->ari_fps = nla_get_u32(tb[DECTA_ARI_FPS]);
break;
case DECT_ARC_D:
if (tb[DECTA_ARI_GOP] != NULL)
ari->ari_u.gop = nla_get_u32(tb[DECTA_ARI_GOP]);
break;
case DECT_ARC_E:
if (tb[DECTA_ARI_FIL] != NULL)
ari->ari_u.fil = nla_get_u16(tb[DECTA_ARI_FIL]);
break;
default:
return -NLE_INVAL;
}
return 0;
}
int nl_dect_fill_ari(struct nl_msg *msg, const struct nl_dect_ari *ari, int attr)
{
struct nlattr *nla;
nla = nla_nest_start(msg, attr);
if (nla == NULL)
goto nla_put_failure;
NLA_PUT_U8(msg, DECTA_ARI_CLASS, ari->ari_class);
NLA_PUT_U32(msg, DECTA_ARI_FPN, ari->ari_fpn);
switch (ari->ari_class) {
case DECT_ARC_A:
NLA_PUT_U16(msg, DECTA_ARI_EMC, ari->ari_u.emc);
break;
case DECT_ARC_B:
NLA_PUT_U16(msg, DECTA_ARI_EIC, ari->ari_u.eic);
NLA_PUT_U32(msg, DECTA_ARI_FPS, ari->ari_fps);
break;
case DECT_ARC_C:
NLA_PUT_U16(msg, DECTA_ARI_POC, ari->ari_u.poc);
NLA_PUT_U32(msg, DECTA_ARI_FPS, ari->ari_fps);
break;
case DECT_ARC_D:
NLA_PUT_U32(msg, DECTA_ARI_GOP, ari->ari_u.gop);
break;
case DECT_ARC_E:
NLA_PUT_U16(msg, DECTA_ARI_FIL, ari->ari_u.fil);
break;
}
nla_nest_end(msg, nla);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
void nl_dect_dump_ari(const struct nl_dect_ari *ari, struct nl_dump_params *p)
{
nl_dump(p, "class %c ", 'A' + ari->ari_class);
switch (ari->ari_class) {
case DECT_ARC_A:
nl_dump(p, "(residential) EMC: %.4x FPN: %.5x",
ari->ari_u.emc, ari->ari_fpn);
break;
case DECT_ARC_B:
nl_dump(p, "(private multiple cell) EIC: %.4x FPN: %.2x FPS: %x",
ari->ari_u.eic, ari->ari_fpn, ari->ari_fps);
break;
case DECT_ARC_C:
nl_dump(p, "(public) POC: %.4x FPN: %.2x FPS: %x",
ari->ari_u.poc, ari->ari_fpn, ari->ari_fps);
break;
case DECT_ARC_D:
nl_dump(p, "(public GSM) GOP: %.5x FPN: %.2x",
ari->ari_u.gop, ari->ari_fpn);
break;
case DECT_ARC_E:
nl_dump(p, "(PP to PP) FIL: %.4x FPN: %.3x",
ari->ari_u.fil, ari->ari_fpn);
}
}
static struct trans_tbl ari_classes[] = {
__ADD(DECT_ARC_A, a)
__ADD(DECT_ARC_B, b)
__ADD(DECT_ARC_C, c)
__ADD(DECT_ARC_D, d)
__ADD(DECT_ARC_E, e)
};
const char *nl_dect_ari_class2str(enum dect_ari_classes class, char *buf, size_t len)
{
return __type2str(class, buf, len, ari_classes, ARRAY_SIZE(ari_classes));
}
enum dect_ari_classes nl_dect_ari_str2class(const char *str)
{
return __str2type(str, ari_classes, ARRAY_SIZE(ari_classes));
}
void nl_dect_ari_set_class(struct nl_dect_ari *ari, enum dect_ari_classes class)
{
ari->ari_flags |= ARI_ATTR_CLASS;
ari->ari_class = class;
}
enum dect_ari_classes nl_dect_ari_get_class(const struct nl_dect_ari *ari)
{
return ari->ari_class;
}
void nl_dect_ari_set_fpn(struct nl_dect_ari *ari, uint32_t fpn)
{
ari->ari_flags |= ARI_ATTR_FPN;
ari->ari_fpn = fpn;
}
uint32_t nl_dect_ari_get_fpn(const struct nl_dect_ari *ari)
{
return ari->ari_fpn;
}
void nl_dect_ari_set_fps(struct nl_dect_ari *ari, uint32_t fps)
{
ari->ari_flags |= ARI_ATTR_FPS;
ari->ari_fps = fps;
}
uint32_t nl_dect_ari_get_fps(const struct nl_dect_ari *ari)
{
return ari->ari_fps;
}
void nl_dect_ari_set_emc(struct nl_dect_ari *ari, uint16_t emc)
{
ari->ari_flags |= ARI_ATTR_EMC;
ari->ari_u.emc = emc;
}
uint16_t nl_dect_ari_get_emc(const struct nl_dect_ari *ari)
{
return ari->ari_u.emc;
}
void nl_dect_ari_set_eic(struct nl_dect_ari *ari, uint16_t eic)
{
ari->ari_flags |= ARI_ATTR_EIC;
ari->ari_u.eic = eic;
}
uint16_t nl_dect_ari_get_eic(const struct nl_dect_ari *ari)
{
return ari->ari_u.eic;
}
void nl_dect_ari_set_poc(struct nl_dect_ari *ari, uint16_t poc)
{
ari->ari_flags |= ARI_ATTR_POC;
ari->ari_u.poc = poc;
}
uint16_t nl_dect_ari_get_poc(const struct nl_dect_ari *ari)
{
return ari->ari_u.poc;
}
void nl_dect_ari_set_gop(struct nl_dect_ari *ari, uint32_t gop)
{
ari->ari_flags |= ARI_ATTR_GOP;
ari->ari_u.gop = gop;
}
uint32_t nl_dect_ari_get_gop(const struct nl_dect_ari *ari)
{
return ari->ari_u.gop;
}
void nl_dect_ari_set_fil(struct nl_dect_ari *ari, uint16_t fil)
{
ari->ari_flags |= ARI_ATTR_FIL;
ari->ari_u.fil = fil;
}
uint16_t nl_dect_ari_get_fil(const struct nl_dect_ari *ari)
{
return ari->ari_u.fil;
}

267
lib/dect/cell.c Normal file
View File

@ -0,0 +1,267 @@
/*
* lib/nl_dect/cell.c DECT Cell objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
/**
* @ingroup nl_dect
* @defgroup nl_dect Transceivers
* @brief
* @{
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/cell.h>
#include <netlink/dect/ari.h>
#include <linux/dect_netlink.h>
/** @cond SKIP */
static struct nl_cache_ops nl_dect_cell_ops;
/** @endcond */
static struct nla_policy cell_policy[DECTA_CELL_MAX + 1] = {
[DECTA_CELL_NAME] = { .type = NLA_STRING, .maxlen = 16 },
[DECTA_CELL_FLAGS] = { .type = NLA_U32 },
[DECTA_CELL_TRANSCEIVERS] = { .type = NLA_NESTED },
[DECTA_CELL_CLUSTER] = { .type = NLA_U8 },
};
static int cell_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct dectmsg *dm = nlmsg_data(n);
struct nl_dect_cell *cell;
struct nlattr *tb[DECTA_CELL_MAX + 1], *nla;
int rem, err;
err = nlmsg_parse(n, sizeof(*dm), tb, DECTA_CELL_MAX, cell_policy);
if (err < 0)
return err;
cell = nl_dect_cell_alloc();
if (cell == NULL) {
err = -NLE_NOMEM;
goto errout;
}
cell->ce_msgtype = n->nlmsg_type;
cell->c_index = dm->dm_index;
if (tb[DECTA_CELL_NAME] != NULL)
nl_dect_cell_set_name(cell, nla_data(tb[DECTA_CELL_NAME]));
if (tb[DECTA_CELL_FLAGS] != NULL)
nl_dect_cell_set_flags(cell, nla_get_u32(tb[DECTA_CELL_FLAGS]));
if (tb[DECTA_CELL_TRANSCEIVERS] != NULL) {
unsigned int i = 0;
nla_for_each_nested(nla, tb[DECTA_CELL_TRANSCEIVERS], rem) {
char *id = nla_strdup(nla);
if (id == NULL) {
err = -NLE_NOMEM;
goto errout;
}
nl_dect_cell_set_transceiver(cell, i++, id);
}
}
if (tb[DECTA_CELL_CLUSTER] != NULL)
nl_dect_cell_set_link(cell, nla_get_u8(tb[DECTA_CELL_CLUSTER]));
err = pp->pp_cb((struct nl_object *)cell, pp);
errout:
nl_dect_cell_put(cell);
return err;
}
static int cell_request_update(struct nl_cache *c, struct nl_sock *h)
{
struct dectmsg dm;
memset(&dm, 0, sizeof(dm));
return nl_send_simple(h, DECT_GET_CELL, NLM_F_DUMP, &dm, sizeof(dm));
}
/**
* @name Cache Management
* @{
*/
int nl_dect_cell_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
{
struct nl_cache *cache;
int err;
cache = nl_cache_alloc(&nl_dect_cell_ops);
if (cache == NULL)
return -NLE_NOMEM;
if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
free(cache);
return err;
}
*result = cache;
return 0;
}
struct nl_dect_cell *nl_dect_cell_get_by_name(struct nl_cache *cache, const char *name)
{
struct nl_dect_cell *cell;
nl_list_for_each_entry(cell, &cache->c_items, ce_list) {
if (!strcmp(cell->c_name, name)) {
nl_object_get((struct nl_object *)cell);
return cell;
}
}
return NULL;
}
struct nl_dect_cell *nl_dect_cell_get_by_index(struct nl_cache *cache, int index)
{
struct nl_dect_cell *cell;
nl_list_for_each_entry(cell, &cache->c_items, ce_list) {
if (cell->c_index == index) {
nl_object_get((struct nl_object *)cell);
return cell;
}
}
return NULL;
}
/** @} */
/**
* @name Device creation
* @{
*/
static int build_cell_msg(struct nl_dect_cell *tmpl, int cmd, int flags,
struct nl_msg **result)
{
struct nl_msg *msg;
int err;
msg = nlmsg_alloc_simple(cmd, flags);
if (msg == NULL)
return -NLE_NOMEM;
err = nl_dect_cell_build_msg(msg, tmpl);
if (err < 0) {
nlmsg_free(msg);
return err;
}
*result = msg;
return 0;
}
int nl_dect_cell_build_add_request(struct nl_dect_cell *tmpl, int flags,
struct nl_msg **result)
{
return build_cell_msg(tmpl, DECT_NEW_CELL, NLM_F_CREATE | flags,
result);
}
int nl_dect_cell_add(struct nl_sock *sk, struct nl_dect_cell *cell, int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_cell_build_add_request(cell, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
int nl_dect_cell_build_del_request(struct nl_dect_cell *tmpl, int flags,
struct nl_msg **result)
{
return build_cell_msg(tmpl, DECT_DEL_CELL, flags, result);
}
int nl_dect_cell_delete(struct nl_sock *sk, struct nl_dect_cell *tmpl, int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_cell_build_del_request(tmpl, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
/** @} */
/**
* @name Name <-> Index Translations
* @{
*/
char *nl_dect_cell_i2name(struct nl_cache *cache, int index, char *buf, size_t len)
{
struct nl_dect_cell *cell = nl_dect_cell_get_by_index(cache, index);
if (cell != NULL) {
strncpy(buf, cell->c_name, len - 1);
buf[len - 1] = 0;
return buf;
}
return NULL;
}
int nl_dect_cell_name2i(struct nl_cache *cache, const char *name)
{
struct nl_dect_cell *cell = nl_dect_cell_get_by_name(cache, name);
if (cell != NULL)
return cell->c_index;
return 0;
}
/** @} */
static struct nl_cache_ops nl_dect_cell_ops = {
.co_name = "nl_dect/cell",
.co_hdrsize = 0,
.co_msgtypes = {
{ DECT_NEW_CELL, NL_ACT_NEW, "new" },
{ DECT_DEL_CELL, NL_ACT_NEW, "del" },
{ DECT_GET_CELL, NL_ACT_GET, "get" },
END_OF_MSGTYPES_LIST
},
.co_protocol = NETLINK_DECT,
.co_request_update = cell_request_update,
.co_msg_parser = cell_msg_parser,
.co_obj_ops = &nl_dect_cell_obj_ops,
};
static void __init cell_init(void)
{
nl_cache_mngt_register(&nl_dect_cell_ops);
}
static void __exit cell_exit(void)
{
nl_cache_mngt_unregister(&nl_dect_cell_ops);
}
/** @} */

234
lib/dect/cell_obj.c Normal file
View File

@ -0,0 +1,234 @@
/*
* lib/dect/cell.c DECT Cell objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
#include <netlink/data.h>
#include <netlink/dect/cluster.h>
#include <netlink/dect/cell.h>
#include <netlink/dect/ari.h>
#include <linux/dect_netlink.h>
/** @cond SKIP */
#define CELL_ATTR_INDEX 0x0001
#define CELL_ATTR_NAME 0x0002
#define CELL_ATTR_FLAGS 0x0004
#define CELL_ATTR_TRANSCEIVER 0x0008
#define CELL_ATTR_LINK 0x0010
/** @endcond */
static void cell_free_data(struct nl_object *obj)
{
struct nl_dect_cell *cell = nl_object_priv(obj);
unsigned int i;
if (cell == NULL)
return;
for (i = 0; i < 16; i++)
free(cell->c_transceiver[i]);
}
static void cell_dump(struct nl_object *obj, struct nl_dump_params *p)
{
struct nl_dect_cell *cell = nl_object_priv(obj);
struct nl_cache *cluster_cache;
unsigned int i;
char buf[64];
if (cell->ce_mask & CELL_ATTR_NAME)
nl_dump(p, "%u: DECT Cell %s", cell->c_index, cell->c_name);
if (cell->ce_mask & CELL_ATTR_LINK) {
cluster_cache = nl_cache_mngt_require("nl_dect/cluster");
if (cluster_cache != NULL) {
nl_dect_cluster_i2name(cluster_cache, cell->c_link, buf,
sizeof(buf));
nl_dump(p, "@%s", buf);
} else
nl_dump(p, "@%u", cell->c_link);
}
nl_dump(p, ":");
if (cell->ce_mask & CELL_ATTR_FLAGS) {
nl_dect_cell_flags2str(cell->c_flags, buf, sizeof(buf));
nl_dump(p, " <%s>", buf);
}
nl_dump(p, "\n");
if (cell->ce_mask & CELL_ATTR_TRANSCEIVER) {
for (i = 0; i < 16 && cell->c_transceiver[i] != NULL; i++)
nl_dump(p, "\tTransceiver: %s\n",
cell->c_transceiver[i]);
}
}
/**
* @name Allocation/Freeing
* @{
*/
struct nl_dect_cell *nl_dect_cell_alloc(void)
{
return (struct nl_dect_cell *)nl_object_alloc(&nl_dect_cell_obj_ops);
}
void nl_dect_cell_get(struct nl_dect_cell *cell)
{
nl_object_get((struct nl_object *)cell);
}
void nl_dect_cell_put(struct nl_dect_cell *cell)
{
nl_object_put((struct nl_object *)cell);
}
/** @} */
/**
* @name Attributes
* @{
*/
void nl_dect_cell_set_index(struct nl_dect_cell *cell, int index)
{
cell->c_index = index;
cell->ce_mask |= CELL_ATTR_INDEX;
}
bool nl_dect_cell_test_index(const struct nl_dect_cell *cell)
{
return !!(cell->ce_mask & CELL_ATTR_INDEX);
}
int nl_dect_cell_get_index(const struct nl_dect_cell *cell)
{
return cell->c_index;
}
void nl_dect_cell_set_name(struct nl_dect_cell *cell, const char *name)
{
cell->c_name = strdup(name);
cell->ce_mask |= CELL_ATTR_NAME;
}
bool nl_dect_cell_test_name(const struct nl_dect_cell *cell)
{
return !!(cell->ce_mask & CELL_ATTR_NAME);
}
const char *nl_dect_cell_get_name(const struct nl_dect_cell *cell)
{
return cell->c_name;
}
void nl_dect_cell_set_flags(struct nl_dect_cell *cell, uint32_t flags)
{
cell->c_flags = flags;
cell->ce_mask |= CELL_ATTR_FLAGS;
}
bool nl_dect_cell_test_flags(const struct nl_dect_cell *cell)
{
return !!(cell->ce_mask & CELL_ATTR_FLAGS);
}
uint32_t nl_dect_cell_get_flags(const struct nl_dect_cell *cell)
{
return cell->c_flags;
}
void nl_dect_cell_set_transceiver(struct nl_dect_cell *cell, unsigned int i,
const char *id)
{
cell->c_transceiver[i] = strdup(id);
cell->ce_mask |= CELL_ATTR_TRANSCEIVER;
}
bool nl_dect_cell_test_transceiver(const struct nl_dect_cell *cell)
{
return !!(cell->ce_mask & CELL_ATTR_TRANSCEIVER);
}
const char *nl_dect_cell_get_transceiver(const struct nl_dect_cell *cell,
unsigned int i)
{
return cell->c_transceiver[i];
}
void nl_dect_cell_set_link(struct nl_dect_cell *cell, int link)
{
cell->c_link = link;
cell->ce_mask |= CELL_ATTR_LINK;
}
bool nl_dect_cell_test_link(const struct nl_dect_cell *cell)
{
return !!(cell->ce_mask & CELL_ATTR_LINK);
}
int nl_dect_cell_get_link(const struct nl_dect_cell *cell)
{
return cell->c_link;
}
int nl_dect_cell_build_msg(struct nl_msg *msg, struct nl_dect_cell *cell)
{
struct dectmsg dm = {
.dm_index = cell->c_index,
};
if (nlmsg_append(msg, &dm, sizeof(dm), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
if (cell->ce_mask & CELL_ATTR_NAME)
NLA_PUT_STRING(msg, DECTA_CELL_NAME, cell->c_name);
if (cell->ce_mask & CELL_ATTR_FLAGS)
NLA_PUT_U32(msg, DECTA_CELL_FLAGS, cell->c_flags);
if (cell->ce_mask & CELL_ATTR_LINK)
NLA_PUT_U8(msg, DECTA_CELL_CLUSTER, cell->c_link);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
static struct trans_tbl cell_flags[] = {
__ADD(DECT_CELL_CCP, ccp)
__ADD(DECT_CELL_SLAVE, slave)
__ADD(DECT_CELL_MONITOR, monitor)
};
char *nl_dect_cell_flags2str(uint32_t flags, char *buf, size_t len)
{
return __flags2str(flags, buf, len, cell_flags, ARRAY_SIZE(cell_flags));
}
uint32_t nl_dect_cell_str2flags(const char *str)
{
return __str2flags(str, cell_flags, ARRAY_SIZE(cell_flags));
}
/** @cond SKIP */
struct nl_object_ops nl_dect_cell_obj_ops = {
.oo_name = "nl_dect/cell",
.oo_size = sizeof(struct nl_dect_cell),
.oo_free_data = cell_free_data,
.oo_dump = {
[NL_DUMP_LINE] = cell_dump,
},
.oo_id_attrs = CELL_ATTR_NAME,
};
/** @endcond */
/** @} */

417
lib/dect/cluster.c Normal file
View File

@ -0,0 +1,417 @@
/*
* lib/dect/cluster.c DECT Cluster objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
/**
* @ingroup nl_dect
* @defgroup nl_dect Transceivers
* @brief
* @{
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/cluster.h>
#include <netlink/dect/ari.h>
#include <linux/dect_netlink.h>
/** @cond SKIP */
static struct nl_cache_ops nl_dect_cluster_ops;
/** @endcond */
static struct nla_policy mbc_tb_policy[DECTA_MBC_TB_MAX + 1] = {
[DECTA_MBC_TB_LBN] = { .type = NLA_U8 },
[DECTA_MBC_TB_ECN] = { .type = NLA_U8 },
[DECTA_MBC_TB_CELL] = { .type = NLA_U8 },
[DECTA_MBC_TB_RX_SLOT] = { .type = NLA_U8 },
[DECTA_MBC_TB_TX_SLOT] = { .type = NLA_U8 },
};
static int tb_msg_parser(struct nlattr *nla, struct nl_dect_mbc *mbc)
{
struct nlattr *tb[DECTA_MBC_TB_MAX + 1];
struct nl_dect_mbc_tb *mtb;
int err;
if (nla_type(nla) != DECTA_LIST_ELEM)
return -NLE_INVAL;
err = nla_parse_nested(tb, DECTA_MBC_TB_MAX, nla, mbc_tb_policy);
if (err < 0)
return err;
mtb = &mbc->mbc_tbs[mbc->mbc_ntbs++];
if (tb[DECTA_MBC_TB_LBN] != NULL)
mtb->mtb_lbn = nla_get_u8(tb[DECTA_MBC_TB_LBN]);
if (tb[DECTA_MBC_TB_ECN] != NULL)
mtb->mtb_ecn = nla_get_u8(tb[DECTA_MBC_TB_ECN]);
if (tb[DECTA_MBC_TB_CELL] != NULL)
mtb->mtb_cell = nla_get_u8(tb[DECTA_MBC_TB_CELL]);
if (tb[DECTA_MBC_TB_RX_SLOT] != NULL)
mtb->mtb_rx_slot = nla_get_u8(tb[DECTA_MBC_TB_RX_SLOT]);
if (tb[DECTA_MBC_TB_TX_SLOT] != NULL)
mtb->mtb_tx_slot = nla_get_u8(tb[DECTA_MBC_TB_TX_SLOT]);
return 0;
}
static struct nla_policy mbc_stats_policy[DECTA_MBC_STATS_MAX + 1] = {
[DECTA_MBC_STATS_CS_RX_BYTES] = { .type = NLA_U32 },
[DECTA_MBC_STATS_CS_TX_BYTES] = { .type = NLA_U32 },
[DECTA_MBC_STATS_I_RX_BYTES] = { .type = NLA_U32 },
[DECTA_MBC_STATS_I_TX_BYTES] = { .type = NLA_U32 },
[DECTA_MBC_STATS_HANDOVERS] = { .type = NLA_U32 },
};
static int mbc_stats_msg_parser(struct nlattr *nla, struct nl_dect_mbc *mbc)
{
struct nlattr *tb[DECTA_MBC_STATS_MAX + 1];
int err;
err = nla_parse_nested(tb, DECTA_MBC_MAX, nla, mbc_stats_policy);
if (err < 0)
return err;
if (tb[DECTA_MBC_STATS_CS_RX_BYTES] != NULL)
mbc->mbc_cs_rx_bytes = nla_get_u32(tb[DECTA_MBC_STATS_CS_RX_BYTES]);
if (tb[DECTA_MBC_STATS_CS_TX_BYTES] != NULL)
mbc->mbc_cs_tx_bytes = nla_get_u32(tb[DECTA_MBC_STATS_CS_TX_BYTES]);
if (tb[DECTA_MBC_STATS_I_RX_BYTES] != NULL)
mbc->mbc_i_rx_bytes = nla_get_u32(tb[DECTA_MBC_STATS_I_RX_BYTES]);
if (tb[DECTA_MBC_STATS_I_TX_BYTES] != NULL)
mbc->mbc_i_tx_bytes = nla_get_u32(tb[DECTA_MBC_STATS_I_TX_BYTES]);
if (tb[DECTA_MBC_STATS_HANDOVERS] != NULL)
mbc->mbc_handovers = nla_get_u32(tb[DECTA_MBC_STATS_HANDOVERS]);
return 0;
}
static struct nla_policy mbc_policy[DECTA_MBC_MAX + 1] = {
[DECTA_MBC_MCEI] = { .type = NLA_U32 },
[DECTA_MBC_SERVICE] = { .type = NLA_U8 },
[DECTA_MBC_STATE] = { .type = NLA_U8 },
[DECTA_MBC_CIPHER_STATE] = { .type = NLA_U8 },
[DECTA_MBC_TBS] = { .type = NLA_NESTED },
};
static int mbc_msg_parser(struct nlattr *nla, struct nl_dect_cluster *cl)
{
struct nlattr *tb[DECTA_MBC_MAX + 1];
struct nl_dect_mbc *mbc;
int err, rem;
if (nla_type(nla) != DECTA_LIST_ELEM)
return -NLE_INVAL;
err = nla_parse_nested(tb, DECTA_MBC_MAX, nla, mbc_policy);
if (err < 0)
return err;
mbc = &cl->cl_mbcs[cl->cl_nmbcs++];
if (tb[DECTA_MBC_MCEI] != NULL)
mbc->mbc_mcei = nla_get_u32(tb[DECTA_MBC_MCEI]);
if (tb[DECTA_MBC_SERVICE] != NULL)
mbc->mbc_service = nla_get_u8(tb[DECTA_MBC_SERVICE]);
if (tb[DECTA_MBC_STATE] != NULL)
mbc->mbc_state = nla_get_u8(tb[DECTA_MBC_STATE]);
if (tb[DECTA_MBC_CIPHER_STATE] != NULL)
mbc->mbc_cipher_state = nla_get_u8(tb[DECTA_MBC_CIPHER_STATE]);
if (tb[DECTA_MBC_STATS] != NULL) {
err = mbc_stats_msg_parser(tb[DECTA_MBC_STATS], mbc);
if (err < 0)
return err;
}
if (tb[DECTA_MBC_TBS] != NULL) {
nla_for_each_nested(nla, tb[DECTA_MBC_TBS], rem) {
err = tb_msg_parser(nla, mbc);
if (err < 0)
return err;
}
}
return 0;
}
static struct nla_policy cluster_policy[DECTA_CLUSTER_MAX + 1] = {
[DECTA_CLUSTER_NAME] = { .type = NLA_STRING, .maxlen = 16 },
[DECTA_CLUSTER_MODE] = { .type = NLA_U8 },
[DECTA_CLUSTER_PARI] = { .type = NLA_NESTED },
[DECTA_CLUSTER_CELLS] = { .type = NLA_NESTED },
[DECTA_CLUSTER_MBCS] = { .type = NLA_NESTED },
};
static int cluster_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
struct dectmsg *dm = nlmsg_data(n);
struct nl_dect_cluster *cl;
struct nlattr *tb[DECTA_CLUSTER_MAX + 1], *nla;
int err, rem;
err = nlmsg_parse(n, sizeof(*dm), tb, DECTA_CLUSTER_MAX, cluster_policy);
if (err < 0)
return err;
cl = nl_dect_cluster_alloc();
if (cl == NULL) {
err = -NLE_NOMEM;
goto errout;
}
cl->ce_msgtype = n->nlmsg_type;
cl->cl_index = dm->dm_index;
if (tb[DECTA_CLUSTER_NAME] != NULL) {
char *name = nla_strdup(tb[DECTA_CLUSTER_NAME]);
if (name == NULL) {
err = -NLE_NOMEM;
goto errout;
}
nl_dect_cluster_set_name(cl, name);
free(name);
}
if (tb[DECTA_CLUSTER_MODE] != NULL)
nl_dect_cluster_set_mode(cl, nla_get_u8(tb[DECTA_CLUSTER_MODE]));
if (tb[DECTA_CLUSTER_PARI] != NULL) {
struct nl_dect_ari pari;
err = nl_dect_parse_ari(&pari, tb[DECTA_CLUSTER_PARI]);
if (err < 0)
goto errout;
nl_dect_cluster_set_pari(cl, &pari);
}
if (tb[DECTA_CLUSTER_MBCS] != NULL) {
nla_for_each_nested(nla, tb[DECTA_CLUSTER_MBCS], rem) {
err = mbc_msg_parser(nla, cl);
if (err < 0)
goto errout;
}
}
err = pp->pp_cb((struct nl_object *)cl, pp);
errout:
nl_dect_cluster_put(cl);
return err;
}
static int cluster_request_update(struct nl_cache *c, struct nl_sock *h)
{
struct dectmsg dm;
memset(&dm, 0, sizeof(dm));
return nl_send_simple(h, DECT_GET_CLUSTER, NLM_F_DUMP, &dm, sizeof(dm));
}
/**
* @name Cache Management
* @{
*/
int nl_dect_cluster_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
{
struct nl_cache *cache;
int err;
cache = nl_cache_alloc(&nl_dect_cluster_ops);
if (cache == NULL)
return -NLE_NOMEM;
if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
free(cache);
return err;
}
*result = cache;
return 0;
}
struct nl_dect_cluster *nl_dect_cluster_get_by_name(struct nl_cache *cache,
const char *name)
{
struct nl_dect_cluster *cl;
nl_list_for_each_entry(cl, &cache->c_items, ce_list) {
if (!strcmp(cl->cl_name, name)) {
nl_object_get((struct nl_object *)cl);
return cl;
}
}
return NULL;
}
struct nl_dect_cluster *nl_dect_cluster_get_by_index(struct nl_cache *cache, int index)
{
struct nl_dect_cluster *cl;
nl_list_for_each_entry(cl, &cache->c_items, ce_list) {
if (cl->cl_index == index) {
nl_object_get((struct nl_object *)cl);
return cl;
}
}
return NULL;
}
/** @} */
/**
* @name Device creation
* @{
*/
static int build_cluster_msg(struct nl_dect_cluster *tmpl, int cmd, int flags,
struct nl_msg **result)
{
struct nl_msg *msg;
int err;
msg = nlmsg_alloc_simple(cmd, flags);
if (msg == NULL)
return -NLE_NOMEM;
err = nl_dect_cluster_build_msg(msg, tmpl);
if (err < 0) {
nlmsg_free(msg);
return err;
}
*result = msg;
return 0;
}
int nl_dect_cluster_build_add_request(struct nl_dect_cluster *tmpl, int flags,
struct nl_msg **result)
{
return build_cluster_msg(tmpl, DECT_NEW_CLUSTER, NLM_F_CREATE | flags,
result);
}
int nl_dect_cluster_add(struct nl_sock *sk, struct nl_dect_cluster *cl, int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_cluster_build_add_request(cl, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
int nl_dect_cluster_build_del_request(struct nl_dect_cluster *tmpl, int flags,
struct nl_msg **result)
{
return build_cluster_msg(tmpl, DECT_DEL_CLUSTER, flags, result);
}
int nl_dect_cluster_delete(struct nl_sock *sk, struct nl_dect_cluster *tmpl, int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_cluster_build_del_request(tmpl, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
int nl_dect_cluster_build_query_request(struct nl_dect_cluster *tmpl, int flags,
struct nl_msg **result)
{
return build_cluster_msg(tmpl, DECT_GET_CLUSTER, flags, result);
}
int nl_dect_cluster_query(struct nl_sock *sk, struct nl_dect_cluster *cl, int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_cluster_build_query_request(cl, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
/** @} */
/**
* @name Name <-> Index Translations
* @{
*/
char *nl_dect_cluster_i2name(struct nl_cache *cache, int index,
char *buf, size_t len)
{
struct nl_dect_cluster *cl = nl_dect_cluster_get_by_index(cache, index);
if (cl != NULL) {
strncpy(buf, cl->cl_name, len - 1);
buf[len - 1] = 0;
return buf;
}
return NULL;
}
int nl_dect_cluster_name2i(struct nl_cache *cache, const char *name)
{
struct nl_dect_cluster *cl = nl_dect_cluster_get_by_name(cache, name);
if (cl != NULL)
return cl->cl_index;
return 0;
}
/** @} */
static struct nl_cache_ops nl_dect_cluster_ops = {
.co_name = "nl_dect/cluster",
.co_hdrsize = 0,
.co_msgtypes = {
{ DECT_NEW_CLUSTER, NL_ACT_NEW, "new" },
{ DECT_DEL_CLUSTER, NL_ACT_NEW, "del" },
{ DECT_GET_CLUSTER, NL_ACT_GET, "get" },
END_OF_MSGTYPES_LIST
},
.co_protocol = NETLINK_DECT,
.co_request_update = cluster_request_update,
.co_msg_parser = cluster_msg_parser,
.co_obj_ops = &nl_dect_cluster_obj_ops,
};
static void __init cluster_init(void)
{
nl_cache_mngt_register(&nl_dect_cluster_ops);
}
static void __exit cluster_exit(void)
{
nl_cache_mngt_unregister(&nl_dect_cluster_ops);
}
/** @} */

274
lib/dect/cluster_obj.c Normal file
View File

@ -0,0 +1,274 @@
/*
* lib/dect/cluster.c DECT Cluster objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
#include <netlink/data.h>
#include <netlink/dect/cluster.h>
#include <netlink/dect/ari.h>
#include <linux/dect_netlink.h>
#include <linux/dect.h>
/** @cond SKIP */
#define CL_ATTR_NAME 0x0001
#define CL_ATTR_MODE 0x0002
#define CL_ATTR_PARI 0x0004
/** @endcond */
char *nl_dect_mbc_state2string(enum dect_mbc_state state,
char *buf, size_t len);
char *nl_dect_mbc_service2string(enum dect_mac_service_types type,
char *buf, size_t len);
char *nl_dect_mbc_cipher2string(enum dect_cipher_states state,
char *buf, size_t len);
static void cluster_free_data(struct nl_object *obj)
{
struct nl_dect_cluster *cl = nl_object_priv(obj);
if (cl == NULL)
return;
free(cl->cl_name);
}
static void mbc_tb_dump(struct nl_dect_mbc_tb *mtb, struct nl_dump_params *p)
{
nl_dump(p, "\t TB: LBN: %u ECN: %u Cell: %u RX/TX-Slots: %u/%u\n",
mtb->mtb_lbn, mtb->mtb_ecn,
mtb->mtb_cell, mtb->mtb_rx_slot, mtb->mtb_tx_slot);
}
static void mbc_dump(struct nl_dect_mbc *mbc, struct nl_dump_params *p)
{
unsigned int i;
char buf[64];
nl_dump(p, "\tMBC: MCEI %u\n", mbc->mbc_mcei);
nl_dump(p, "\t State: %s\n",
nl_dect_mbc_state2string(mbc->mbc_state,
buf, sizeof(buf)));
nl_dump(p, "\t Service: %s\n",
nl_dect_mbc_service2string(mbc->mbc_service,
buf, sizeof(buf)));
nl_dump(p, "\t Cipher state: %s\n",
nl_dect_mbc_cipher2string(mbc->mbc_cipher_state,
buf, sizeof(buf)));
nl_dump(p, "\t Cs-channel RX-Bytes: %u TX-Bytes: %u\n",
mbc->mbc_cs_rx_bytes, mbc->mbc_cs_tx_bytes);
nl_dump(p, "\t I-channel RX-Bytes: %u TX-Bytes: %u\n",
mbc->mbc_i_rx_bytes, mbc->mbc_i_tx_bytes);
for (i = 0; i < mbc->mbc_ntbs; i++)
mbc_tb_dump(&mbc->mbc_tbs[i], p);
}
static void cluster_dump(struct nl_object *obj, struct nl_dump_params *p)
{
struct nl_dect_cluster *cl = nl_object_priv(obj);
unsigned int i;
char buf[64];
if (cl->ce_mask & CL_ATTR_NAME)
nl_dump_line(p, "%d: DECT Cluster %s:\n",
cl->cl_index, cl->cl_name);
if (cl->ce_mask & CL_ATTR_MODE)
nl_dump_line(p, "\tMode: %s\n",
nl_dect_cluster_mode2str(cl->cl_mode,
buf, sizeof(buf)));
if (cl->ce_mask & CL_ATTR_PARI) {
nl_dump(p, "\tPARI: ");
nl_dect_dump_ari(&cl->cl_pari, p);
nl_dump(p, "\n");
}
nl_dump(p, "\n");
for (i = 0; i < cl->cl_nmbcs; i++)
mbc_dump(&cl->cl_mbcs[i], p);
}
/**
* @name Allocation/Freeing
* @{
*/
struct nl_dect_cluster *nl_dect_cluster_alloc(void)
{
return (struct nl_dect_cluster *)nl_object_alloc(&nl_dect_cluster_obj_ops);
}
void nl_dect_cluster_get(struct nl_dect_cluster *cl)
{
nl_object_get((struct nl_object *)cl);
}
void nl_dect_cluster_put(struct nl_dect_cluster *cl)
{
nl_object_put((struct nl_object *)cl);
}
/** @} */
/**
* @name Attributes
* @{
*/
unsigned int nl_dect_cluster_get_index(const struct nl_dect_cluster *cl)
{
return cl->cl_index;
}
void nl_dect_cluster_set_name(struct nl_dect_cluster *cl, const char *name)
{
cl->cl_name = strdup(name);
cl->ce_mask |= CL_ATTR_NAME;
}
bool nl_dect_cluster_test_name(const struct nl_dect_cluster *cl)
{
return !!(cl->ce_mask & CL_ATTR_NAME);
}
const char *nl_dect_cluster_get_name(const struct nl_dect_cluster *cl)
{
return cl->cl_name;
}
void nl_dect_cluster_set_mode(struct nl_dect_cluster *cl, uint8_t mode)
{
cl->cl_mode = mode;
cl->ce_mask |= CL_ATTR_MODE;
}
bool nl_dect_cluster_test_mode(const struct nl_dect_cluster *cl)
{
return !!(cl->ce_mask & CL_ATTR_MODE);
}
uint8_t nl_dect_cluster_get_mode(const struct nl_dect_cluster *cl)
{
return cl->cl_mode;
}
void nl_dect_cluster_set_pari(struct nl_dect_cluster *cl, const struct nl_dect_ari *pari)
{
memcpy(&cl->cl_pari, pari, sizeof(cl->cl_pari));
cl->ce_mask |= CL_ATTR_PARI;
}
bool nl_dect_cluster_test_pari(const struct nl_dect_cluster *cl)
{
return !!(cl->ce_mask & CL_ATTR_PARI);
}
const struct nl_dect_ari *nl_dect_cluster_get_pari(const struct nl_dect_cluster *cl)
{
return &cl->cl_pari;
}
int nl_dect_cluster_build_msg(struct nl_msg *msg, struct nl_dect_cluster *cl)
{
struct dectmsg dm = {
.dm_index = cl->cl_index,
};
if (nlmsg_append(msg, &dm, sizeof(dm), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
if (cl->ce_mask & CL_ATTR_NAME)
NLA_PUT_STRING(msg, DECTA_CLUSTER_NAME, cl->cl_name);
if (nl_dect_fill_ari(msg, &cl->cl_pari, DECTA_CLUSTER_PARI) < 0)
goto nla_put_failure;
if (cl->ce_mask & CL_ATTR_MODE)
NLA_PUT_U8(msg, DECTA_CLUSTER_MODE, cl->cl_mode);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
static struct trans_tbl cluster_modes[] = {
__ADD(DECT_MODE_FP, FP)
__ADD(DECT_MODE_PP, PP)
};
char *nl_dect_cluster_mode2str(enum dect_cluster_modes mode, char *buf, size_t len)
{
return __type2str(mode, buf, len, cluster_modes,
ARRAY_SIZE(cluster_modes));
}
enum dect_cluster_modes nl_dect_cluster_str2mode(const char *str)
{
return __str2type(str, cluster_modes, ARRAY_SIZE(cluster_modes));
}
static struct trans_tbl mbc_states[] = {
__ADD(DECT_MBC_NONE, none)
__ADD(DECT_MBC_INITIATED, initiated)
__ADD(DECT_MBC_ESTABLISHED, established)
__ADD(DECT_MBC_RELEASED, released)
};
char *nl_dect_mbc_state2string(enum dect_mbc_state state,
char *buf, size_t len)
{
return __type2str(state, buf, len, mbc_states,
ARRAY_SIZE(mbc_states));
}
static struct trans_tbl mac_service_types[] = {
__ADD(DECT_SERVICE_IN_MIN_DELAY, IN_min_delay)
__ADD(DECT_SERVICE_IPX_ENCODED_PROTECTED, IPX_encoded_protected)
__ADD(DECT_SERVICE_IN_NORMAL_DELAY, IN_normal_delay)
__ADD(DECT_SERVICE_UNKNOWN, unknown)
__ADD(DECT_SERVICE_C_CHANNEL_ONLY, C_channel_only)
__ADD(DECT_SERVICE_IP_ERROR_DETECTION, IP_error_detection)
__ADD(DECT_SERVICE_IPQ_ERROR_DETECTION, IPQ_error_detection)
};
char *nl_dect_mbc_service2string(enum dect_mac_service_types type,
char *buf, size_t len)
{
return __type2str(type, buf, len, mac_service_types,
ARRAY_SIZE(mac_service_types));
}
static struct trans_tbl cipher_states[] = {
__ADD(DECT_CIPHER_DISABLED, disabled)
__ADD(DECT_CIPHER_ENABLED, enabled)
};
char *nl_dect_mbc_cipher2string(enum dect_cipher_states state,
char *buf, size_t len)
{
return __type2str(state, buf, len, cipher_states,
ARRAY_SIZE(cipher_states));
}
/** @cond SKIP */
struct nl_object_ops nl_dect_cluster_obj_ops = {
.oo_name = "nl_dect/cluster",
.oo_size = sizeof(struct nl_dect_cluster),
.oo_free_data = cluster_free_data,
.oo_dump = {
[NL_DUMP_LINE] = cluster_dump,
},
.oo_id_attrs = CL_ATTR_NAME,
};
/** @endcond */
/** @} */

22
lib/dect/dect.c Normal file
View File

@ -0,0 +1,22 @@
/*
* lib/dect/dect.c DECT
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/dect.h>
double nl_dect_rssi_to_dbm(uint8_t rssi)
{
if (rssi == 0)
return 0;
return -93 + (rssi * 60.0 / 255);
}

776
lib/dect/llme.c Normal file
View File

@ -0,0 +1,776 @@
/*
* lib/dect/llme.c DECT Lower Layer Management Entity Objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
/**
* @ingroup dect
* @defgroup dect LLME
* @brief
* @{
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/dect.h>
#include <netlink/dect/ari.h>
#include <netlink/dect/llme.h>
#include <linux/dect_netlink.h>
/** @cond SKIP */
static struct nl_object_ops llme_msg_obj_ops;
/** @endcond */
#define MAC_INFO_ATTR_PARI 0x0010000
#define MAC_INFO_ATTR_RPN 0x0020000
#define MAC_INFO_ATTR_RSSI 0x0040000
#define MAC_INFO_ATTR_FPC 0x0080000
#define MAC_INFO_ATTR_HLC 0x0100000
#define MAC_INFO_ATTR_EFPC 0x0200000
#define MAC_INFO_ATTR_EHLC 0x0400000
#define MAC_INFO_ATTR_EFPC2 0x0800000
#define MAC_INFO_ATTR_EHLC2 0x1000000
#define MAC_INFO_ATTR_MFN 0x2000000
static inline struct nl_dect_llme_mac_info *mac_info(const struct nl_dect_llme_msg *lmsg)
{
return (void *)&lmsg->lm_mi;
}
void nl_dect_llme_mac_info_set_pari(struct nl_dect_llme_msg *lmsg,
const struct nl_dect_ari *pari)
{
struct nl_dect_llme_mac_info *mi = mac_info(lmsg);
memcpy(&mi->mi_pari, pari, sizeof(mi->mi_pari));
lmsg->ce_mask |= MAC_INFO_ATTR_PARI;
}
bool nl_dect_llme_mac_info_test_pari(const struct nl_dect_llme_msg *lmsg)
{
return !!(lmsg->ce_mask & MAC_INFO_ATTR_PARI);
}
const struct nl_dect_ari *nl_dect_llme_mac_info_get_pari(const struct nl_dect_llme_msg *lmsg)
{
return &mac_info(lmsg)->mi_pari;
}
void nl_dect_llme_mac_info_set_rpn(struct nl_dect_llme_msg *lmsg, uint8_t rpn)
{
mac_info(lmsg)->mi_rpn = rpn;
lmsg->ce_mask |= MAC_INFO_ATTR_RPN;
}
uint8_t nl_dect_llme_mac_info_get_rpn(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_rpn;
}
void nl_dect_llme_mac_info_set_rssi(struct nl_dect_llme_msg *lmsg, uint8_t rssi)
{
mac_info(lmsg)->mi_rssi = rssi;
lmsg->ce_mask |= MAC_INFO_ATTR_RSSI;
}
uint8_t nl_dect_llme_mac_info_get_rssi(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_rssi;
}
void nl_dect_llme_mac_info_set_fpc(struct nl_dect_llme_msg *lmsg, uint32_t fpc)
{
mac_info(lmsg)->mi_fpc = fpc;
lmsg->ce_mask |= MAC_INFO_ATTR_FPC;
}
uint32_t nl_dect_llme_mac_info_get_fpc(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_fpc;
}
void nl_dect_llme_mac_info_set_hlc(struct nl_dect_llme_msg *lmsg, uint16_t hlc)
{
mac_info(lmsg)->mi_hlc = hlc;
lmsg->ce_mask |= MAC_INFO_ATTR_HLC;
}
uint16_t nl_dect_llme_mac_info_get_hlc(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_hlc;
}
void nl_dect_llme_mac_info_set_efpc(struct nl_dect_llme_msg *lmsg, uint16_t efpc)
{
mac_info(lmsg)->mi_efpc = efpc;
lmsg->ce_mask |= MAC_INFO_ATTR_EFPC;
}
uint16_t nl_dect_llme_mac_info_get_efpc(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_efpc;
}
void nl_dect_llme_mac_info_set_ehlc(struct nl_dect_llme_msg *lmsg, uint32_t ehlc)
{
mac_info(lmsg)->mi_ehlc = ehlc;
lmsg->ce_mask |= MAC_INFO_ATTR_EHLC;
}
uint32_t nl_dect_llme_mac_info_get_ehlc(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_ehlc;
}
void nl_dect_llme_mac_info_set_efpc2(struct nl_dect_llme_msg *lmsg, uint16_t efpc2)
{
mac_info(lmsg)->mi_efpc2 = efpc2;
lmsg->ce_mask |= MAC_INFO_ATTR_EFPC2;
}
uint16_t nl_dect_llme_mac_info_get_efpc2(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_efpc2;
}
void nl_dect_llme_mac_info_set_ehlc2(struct nl_dect_llme_msg *lmsg, uint32_t ehlc2)
{
mac_info(lmsg)->mi_ehlc2 = ehlc2;
lmsg->ce_mask |= MAC_INFO_ATTR_EHLC2;
}
uint32_t nl_dect_llme_mac_info_get_ehlc2(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_ehlc2;
}
void nl_dect_llme_mac_info_set_mfn(struct nl_dect_llme_msg *lmsg, uint32_t mfn)
{
mac_info(lmsg)->mi_mfn = mfn;
lmsg->ce_mask |= MAC_INFO_ATTR_MFN;
}
uint32_t nl_dect_llme_mac_info_get_mfn(const struct nl_dect_llme_msg *lmsg)
{
return mac_info(lmsg)->mi_mfn;
}
static struct trans_tbl fixed_part_capabilities[] = {
__ADD(DECT_FPC_EXTENDED_FP_INFO, extended_fp_info)
__ADD(DECT_FPC_DOUBLE_DUPLEX_BEARER_CONNECTION, double_duplex_bearer_connection)
__ADD(DECT_FPC_RESERVED, reserved)
__ADD(DECT_FPC_DOUBLE_SLOT, double_slot)
__ADD(DECT_FPC_HALF_SLOT, half_slot)
__ADD(DECT_FPC_FULL_SLOT, full_slot)
__ADD(DECT_FPC_FREQ_CONTROL, frequency_control)
__ADD(DECT_FPC_PAGE_REPETITION, page_repetition)
__ADD(DECT_FPC_CO_SETUP_ON_DUMMY, co_setup_on_dummy)
__ADD(DECT_FPC_CL_UPLINK, cl_uplink)
__ADD(DECT_FPC_CL_DOWNLINK, cl_downlink)
__ADD(DECT_FPC_BASIC_A_FIELD_SETUP, basic_a_field_setup)
__ADD(DECT_FPC_ADV_A_FIELD_SETUP, advanced_a_field_setup)
__ADD(DECT_FPC_B_FIELD_SETUP, b_field_setup)
__ADD(DECT_FPC_CF_MESSAGES, cf_messages)
__ADD(DECT_FPC_IN_MIN_DELAY, in_min_delay)
__ADD(DECT_FPC_IN_NORM_DELAY, in_normal_delay)
__ADD(DECT_FPC_IP_ERROR_DETECTION, ip_error_detection)
__ADD(DECT_FPC_IP_ERROR_CORRECTION, ip_error_correction)
__ADD(DECT_FPC_MULTIBEARER_CONNECTIONS, multibearer_connections)
};
char *nl_dect_llme_fpc2str(uint32_t fpc, char *buf, size_t len)
{
return __flags2str(fpc, buf, len, fixed_part_capabilities,
ARRAY_SIZE(fixed_part_capabilities));
}
uint32_t nl_dect_llme_str2fpc(const char *str)
{
return __str2flags(str, fixed_part_capabilities,
ARRAY_SIZE(fixed_part_capabilities));
}
static struct trans_tbl higher_layer_capabilities[] = {
__ADD(DECT_HLC_ADPCM_G721_VOICE, adpcm_g721_voice)
__ADD(DECT_HLC_GAP_PAP_BASIC_SPEECH, gap_pap_basic_speech)
__ADD(DECT_HLC_NON_VOICE_CIRCUIT_SWITCHED, non_voice_circuit_switched_service)
__ADD(DECT_HLC_NON_VOICE_PACKET_SWITCHED, non_voice_packet_switched_service)
__ADD(DECT_HLC_STANDARD_AUTHENTICATION, standard_authentication)
__ADD(DECT_HLC_STANDARD_CIPHERING, standard_ciphering)
__ADD(DECT_HLC_LOCATION_REGISTRATION, location_registration)
__ADD(DECT_HLC_SIM_SERVICES, sim_services)
__ADD(DECT_HLC_NON_STATIC_FIXED_PART, non_static_fixed_part)
__ADD(DECT_HLC_CISS_SERVICE, ciss_service)
__ADD(DECT_HLC_CLMS_SERVICE, clms_service)
__ADD(DECT_HLC_COMS_SERVICE, coms_service)
__ADD(DECT_HLC_ACCESS_RIGHTS_REQUESTS, access_rights_requests)
__ADD(DECT_HLC_EXTERNAL_HANDOVER, external_handover)
__ADD(DECT_HLC_CONNECTION_HANDOVER, connection_handover)
__ADD(DECT_HLC_RESERVED, reserved)
};
char *nl_dect_llme_hlc2str(uint16_t hlc, char *buf, size_t len)
{
return __flags2str(hlc, buf, len, higher_layer_capabilities,
ARRAY_SIZE(higher_layer_capabilities));
}
uint16_t nl_dect_llme_str2hlc(const char *str)
{
return __str2flags(str, higher_layer_capabilities,
ARRAY_SIZE(higher_layer_capabilities));
}
static struct trans_tbl extended_fixed_part_capabilities[] = {
__ADD(DECT_EFPC_SYNC_PROLONGED_PREAMBLE, prolonged_preamble)
__ADD(DECT_EFPC_MAC_SUSPEND_RESUME, suspend_resume)
__ADD(DECT_EFPC_MAC_IP_Q_SERVICE, ip_q_service)
__ADD(DECT_EFPC_EXTENDED_FP_INFO2, extended_fp_info2)
};
char *nl_dect_llme_efpc2str(uint16_t efpc, char *buf, size_t len)
{
return __flags2str(efpc, buf, len, extended_fixed_part_capabilities,
ARRAY_SIZE(extended_fixed_part_capabilities));
}
uint16_t nl_dect_llme_str2efpc(const char *str)
{
return __str2flags(str, extended_fixed_part_capabilities,
ARRAY_SIZE(extended_fixed_part_capabilities));
}
static struct trans_tbl extended_higher_layer_capabilities[] = {
__ADD(DECT_EHLC_ISDN_DATA_SERVICE, isdn_data_service)
__ADD(DECT_EHLC_DPRS_FREL, dprs_frel)
__ADD(DECT_EHLC_DPRS_STREAM, dprs_stream)
__ADD(DECT_EHLC_DATA_SERVICE_PROFILE_D, data_service_profile_d)
__ADD(DECT_EHLC_LRMS, lrms)
__ADD(DECT_EHLC_ASYMETRIC_BEARERS, asymetric_bearers)
__ADD(DECT_EHLC_EMERGENCY_CALLS, emergency_calls)
__ADD(DECT_EHLC_TPUI_LOCATION_REGISTRATION, tpui_location_registration)
__ADD(DECT_EHLC_GPS_SYNCHRONIZED, gps_synchronized)
__ADD(DECT_EHLC_ISDN_INTERMEDIATE_SYSTEM, isdn_intermediate_system)
__ADD(DECT_EHLC_RAP_PART_1_PROFILE, rap_1_profile)
__ADD(DECT_EHLC_V_24, v_24)
__ADD(DECT_EHLC_PPP, ppp)
__ADD(DECT_EHLC_IP, ip)
__ADD(DECT_EHLC_TOKEN_RING, token_ring)
__ADD(DECT_EHLC_ETHERNET, ethernet)
__ADD(DECT_EHLC_IP_ROAMING, ip_roaming)
__ADD(DECT_EHLC_GENERIC_MEDIA_ENCAPSULATION, generic_media_encapsulation)
__ADD(DECT_EHLC_BASIC_ODAP, basic_odap)
__ADD(DECT_EHLC_F_MMS_INTERWORKING_PROFILE, mms_interworking_profile)
};
char *nl_dect_llme_ehlc2str(uint32_t ehlc, char *buf, size_t len)
{
return __flags2str(ehlc, buf, len, extended_higher_layer_capabilities,
ARRAY_SIZE(extended_higher_layer_capabilities));
}
uint32_t nl_dect_llme_str2ehlc(const char *str)
{
return __str2flags(str, extended_higher_layer_capabilities,
ARRAY_SIZE(extended_higher_layer_capabilities));
}
static struct trans_tbl extended_fixed_part_capabilities2[] = {
__ADD(DECT_EFPC2_NO_EMISSION_CARRIER, no_emission_carrier)
__ADD(DECT_EFPC2_GF, gf_channel)
__ADD(DECT_EFPC2_SI_PF, si_pf_channel)
__ADD(DECT_EFPC2_IP_F, ip_f_channel)
__ADD(DECT_EFPC2_LONG_SLOT_J672, long_slot_j672)
__ADD(DECT_EFPC2_LONG_SLOT_J640, long_slot_j640)
};
char *nl_dect_llme_efpc22str(uint16_t efpc2, char *buf, size_t len)
{
return __flags2str(efpc2, buf, len, extended_fixed_part_capabilities2,
ARRAY_SIZE(extended_fixed_part_capabilities2));
}
uint16_t nl_dect_llme_str2efpc2(const char *str)
{
return __str2flags(str, extended_fixed_part_capabilities2,
ARRAY_SIZE(extended_fixed_part_capabilities2));
}
static struct trans_tbl extended_higher_layer_capabilities2[] = {
__ADD(DECT_EHLC2_NG_DECT_PERMANENT_CLIR, permanent_clir)
__ADD(DECT_EHLC2_NG_DECT_MULTIPLE_CALLS, multiple_calls)
__ADD(DECT_EHLC2_NG_DECT_MULTIPLE_LINES, multiple_lines)
__ADD(DECT_EHLC2_EASY_PAIRING, easy_pairing)
__ADD(DECT_EHLC2_LIST_ACCESS_FEATURES, list_access_features)
__ADD(DECT_EHLC2_NO_EMISSION_MODE, no_emission_mode)
__ADD(DECT_EHLC2_NG_DECT_CALL_DEFLECTION, call_deflection)
__ADD(DECT_EHLC2_NG_DECT_INTRUSION_CALL, intrusion_call)
__ADD(DECT_EHLC2_NG_DECT_CONFERENCE_CALL, conference_call)
__ADD(DECT_EHLC2_NG_DECT_PARALLEL_CALLS, parallel_calls)
__ADD(DECT_EHLC2_NG_DECT_CALL_TRANSFER, call_transfer)
__ADD(DECT_EHLC2_NG_DECT_EXTENDED_WIDEBAND, extended_wideband)
__ADD(DECT_EHLC2_PACKET_DATA_CATEGORY_MASK, packet_data)
__ADD(DECT_EHLC2_NG_DECT_WIDEBAND, wideband)
};
char *nl_dect_llme_ehlc22str(uint32_t ehlc2, char *buf, size_t len)
{
return __flags2str(ehlc2, buf, len, extended_higher_layer_capabilities2,
ARRAY_SIZE(extended_higher_layer_capabilities2));
}
uint32_t nl_dect_llme_str22ehlc(const char *str)
{
return __str2flags(str, extended_higher_layer_capabilities2,
ARRAY_SIZE(extended_higher_layer_capabilities2));
}
static void nl_dect_llme_mac_info_dump(const struct nl_dect_llme_msg *lmsg,
struct nl_dump_params *p)
{
const struct nl_dect_llme_mac_info *mi = mac_info(lmsg);
char buf[256];
if (lmsg->ce_mask & MAC_INFO_ATTR_PARI) {
nl_dump(p, "\n\tARI: ");
nl_dect_dump_ari(&mi->mi_pari, p);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_RPN)
nl_dump(p, " RPN: %x", mi->mi_rpn);
if (lmsg->ce_mask & MAC_INFO_ATTR_RSSI)
nl_dump(p, " signal level: %.2fdBm", nl_dect_rssi_to_dbm(mi->mi_rssi));
if (lmsg->ce_mask & MAC_INFO_ATTR_FPC && mi->mi_fpc) {
nl_dect_llme_fpc2str(mi->mi_fpc, buf, sizeof(buf));
nl_dump(p, "\n\tMAC layer capabilities: %s", buf);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_EFPC && mi->mi_efpc) {
nl_dect_llme_efpc2str(mi->mi_efpc, buf, sizeof(buf));
nl_dump(p, "\n\tExtended MAC layer capabilities: %s", buf);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_EFPC2 && mi->mi_efpc2) {
nl_dect_llme_efpc22str(mi->mi_efpc2, buf, sizeof(buf));
nl_dump(p, "\n\tExtended MAC layer capabilities 2: %s", buf);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_HLC && mi->mi_hlc) {
nl_dect_llme_hlc2str(mi->mi_hlc, buf, sizeof(buf));
nl_dump(p, "\n\tHigher layer capabilities: %s", buf);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_EHLC && mi->mi_ehlc) {
nl_dect_llme_ehlc2str(mi->mi_ehlc, buf, sizeof(buf));
nl_dump(p, "\n\tExtended higher layer capabilities: %s", buf);
}
if (lmsg->ce_mask & MAC_INFO_ATTR_EHLC2 && mi->mi_ehlc2) {
nl_dect_llme_ehlc22str(mi->mi_ehlc2, buf, sizeof(buf));
nl_dump(p, "\n\tExtended higher layer capabilities 2: %s", buf);
}
nl_dump(p, "\n");
}
static struct nla_policy nl_dect_mac_info_policy[DECTA_MAC_INFO_MAX + 1] = {
[DECTA_MAC_INFO_PARI] = { .type = NLA_NESTED },
[DECTA_MAC_INFO_RPN] = { .type = NLA_U8 },
[DECTA_MAC_INFO_RSSI] = { .type = NLA_U8 },
[DECTA_MAC_INFO_SARI_LIST] = { .type = NLA_NESTED },
[DECTA_MAC_INFO_FPC] = { .type = NLA_U32 },
[DECTA_MAC_INFO_HLC] = { .type = NLA_U16 },
[DECTA_MAC_INFO_EFPC] = { .type = NLA_U16 },
[DECTA_MAC_INFO_EHLC] = { .type = NLA_U32 },
[DECTA_MAC_INFO_EFPC2] = { .type = NLA_U16 },
[DECTA_MAC_INFO_EHLC2] = { .type = NLA_U32 },
[DECTA_MAC_INFO_MFN] = { .type = NLA_U32 },
};
static int nl_dect_llme_mac_info_parse(struct nl_dect_llme_msg *lmsg,
struct nlattr *tb[])
{
struct nl_dect_ari pari;
int err;
if (tb[DECTA_MAC_INFO_PARI] != NULL) {
err = nl_dect_parse_ari(&pari, tb[DECTA_MAC_INFO_PARI]);
if (err < 0)
return err;
nl_dect_llme_mac_info_set_pari(lmsg, &pari);
}
if (tb[DECTA_MAC_INFO_RPN] != NULL)
nl_dect_llme_mac_info_set_rpn(lmsg, nla_get_u8(tb[DECTA_MAC_INFO_RPN]));
if (tb[DECTA_MAC_INFO_RSSI] != NULL)
nl_dect_llme_mac_info_set_rssi(lmsg, nla_get_u8(tb[DECTA_MAC_INFO_RSSI]));
if (tb[DECTA_MAC_INFO_FPC] != NULL)
nl_dect_llme_mac_info_set_fpc(lmsg, nla_get_u32(tb[DECTA_MAC_INFO_FPC]));
if (tb[DECTA_MAC_INFO_HLC] != NULL)
nl_dect_llme_mac_info_set_hlc(lmsg, nla_get_u16(tb[DECTA_MAC_INFO_HLC]));
if (tb[DECTA_MAC_INFO_EFPC] != NULL)
nl_dect_llme_mac_info_set_efpc(lmsg, nla_get_u16(tb[DECTA_MAC_INFO_EFPC]));
if (tb[DECTA_MAC_INFO_EHLC] != NULL)
nl_dect_llme_mac_info_set_ehlc(lmsg, nla_get_u32(tb[DECTA_MAC_INFO_EHLC]));
if (tb[DECTA_MAC_INFO_EFPC2] != NULL)
nl_dect_llme_mac_info_set_efpc2(lmsg, nla_get_u16(tb[DECTA_MAC_INFO_EFPC2]));
if (tb[DECTA_MAC_INFO_EHLC2] != NULL)
nl_dect_llme_mac_info_set_ehlc2(lmsg, nla_get_u32(tb[DECTA_MAC_INFO_EHLC2]));
return 0;
}
static int nl_dect_llme_mac_info_build(struct nl_msg *msg,
struct nl_dect_llme_msg *lmsg)
{
struct nl_dect_llme_mac_info *mi = mac_info(lmsg);
int err;
if (lmsg->ce_mask & MAC_INFO_ATTR_PARI) {
err = nl_dect_fill_ari(msg, &mi->mi_pari, DECTA_MAC_INFO_PARI);
if (err < 0)
return err;
}
if (lmsg->ce_mask & MAC_INFO_ATTR_RPN)
NLA_PUT_U8(msg, DECTA_MAC_INFO_RPN, mi->mi_rpn);
if (lmsg->ce_mask & MAC_INFO_ATTR_FPC)
NLA_PUT_U32(msg, DECTA_MAC_INFO_FPC, mi->mi_fpc);
if (lmsg->ce_mask & MAC_INFO_ATTR_HLC)
NLA_PUT_U16(msg, DECTA_MAC_INFO_HLC, mi->mi_hlc);
if (lmsg->ce_mask & MAC_INFO_ATTR_EFPC)
NLA_PUT_U16(msg, DECTA_MAC_INFO_EFPC, mi->mi_efpc);
if (lmsg->ce_mask & MAC_INFO_ATTR_EHLC)
NLA_PUT_U32(msg, DECTA_MAC_INFO_EHLC, mi->mi_ehlc);
if (lmsg->ce_mask & MAC_INFO_ATTR_EFPC2)
NLA_PUT_U16(msg, DECTA_MAC_INFO_EFPC2, mi->mi_efpc2);
if (lmsg->ce_mask & MAC_INFO_ATTR_EHLC2)
NLA_PUT_U32(msg, DECTA_MAC_INFO_EHLC2, mi->mi_ehlc2);
if (lmsg->ce_mask & MAC_INFO_ATTR_MFN)
NLA_PUT_U32(msg, DECTA_MAC_INFO_MFN, mi->mi_mfn);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
static const struct nl_dect_llme_link {
int (*parse)(struct nl_dect_llme_msg *, struct nlattr *[]);
int (*build)(struct nl_msg *, struct nl_dect_llme_msg *);
void (*dump)(const struct nl_dect_llme_msg *, struct nl_dump_params *);
struct nla_policy *policy;
unsigned int maxtype;
} nl_dect_llme_dispatch[DECT_LLME_MAX + 1] = {
[DECT_LLME_SCAN] = {
.policy = nl_dect_mac_info_policy,
.maxtype = DECTA_MAC_INFO_MAX,
.parse = nl_dect_llme_mac_info_parse,
.build = nl_dect_llme_mac_info_build,
.dump = nl_dect_llme_mac_info_dump,
},
[DECT_LLME_MAC_INFO] = {
.policy = nl_dect_mac_info_policy,
.maxtype = DECTA_MAC_INFO_MAX,
.parse = nl_dect_llme_mac_info_parse,
.build = nl_dect_llme_mac_info_build,
.dump = nl_dect_llme_mac_info_dump,
},
[DECT_LLME_MAC_RFP_PRELOAD] = {
.policy = nl_dect_mac_info_policy,
.maxtype = DECTA_MAC_INFO_MAX,
.parse = nl_dect_llme_mac_info_parse,
.build = nl_dect_llme_mac_info_build,
.dump = nl_dect_llme_mac_info_dump,
},
};
static void llme_msg_dump(struct nl_object *obj, struct nl_dump_params *p)
{
struct nl_dect_llme_msg *lmsg = nl_object_priv(obj);
const struct nl_dect_llme_link *link;
char buf1[64], buf2[64];
nl_dect_llme_msgtype2str(lmsg->lm_type, buf1, sizeof(buf1));
nl_dect_llme_op2str(lmsg->lm_op, buf2, sizeof(buf2));
nl_dump(p, "%s-%s: ", buf1, buf2);
link = &nl_dect_llme_dispatch[lmsg->lm_type];
link->dump(lmsg, p);
}
static struct nla_policy nl_dect_llme_policy[DECTA_LLME_MAX + 1] = {
[DECTA_LLME_OP] = { .type = NLA_U8 },
[DECTA_LLME_TYPE] = { .type = NLA_U8 },
[DECTA_LLME_DATA] = { .type = NLA_NESTED },
};
static int llme_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
struct nlmsghdr *n, struct nl_parser_param *pp)
{
const struct nl_dect_llme_link *link;
struct dectmsg *dm = nlmsg_data(n);
struct nlattr *tb[DECTA_LLME_MAX + 1];
struct nl_dect_llme_msg *lmsg;
uint8_t op, type;
int err;
err = nlmsg_parse(n, sizeof(*dm), tb, DECTA_LLME_MAX, nl_dect_llme_policy);
if (err < 0)
return err;
if (tb[DECTA_LLME_OP] == NULL ||
tb[DECTA_LLME_TYPE] == NULL ||
tb[DECTA_LLME_DATA] == NULL)
return -NLE_INVAL;
type = nla_get_u8(tb[DECTA_LLME_TYPE]);
if (type > DECT_LLME_MAX)
return -NLE_INVAL;
link = &nl_dect_llme_dispatch[type];
op = nla_get_u8(tb[DECTA_LLME_OP]);
switch (op) {
case DECT_LLME_REQUEST:
case DECT_LLME_INDICATE:
case DECT_LLME_RESPONSE:
case DECT_LLME_CONFIRM:
if (link->parse == NULL)
return -NLE_OPNOTSUPP;
break;
default:
return -NLE_INVAL;
}
lmsg = nl_dect_llme_msg_alloc();
lmsg->ce_msgtype = n->nlmsg_type;
lmsg->lm_index = dm->dm_index;
nl_dect_llme_msg_set_type(lmsg, type);
nl_dect_llme_msg_set_op(lmsg, op);
if (1) {
struct nlattr *nla[link->maxtype + 1];
err = nla_parse_nested(nla, link->maxtype, tb[DECTA_LLME_DATA],
link->policy);
if (err < 0)
goto errout;
err = link->parse(lmsg, nla);
if (err < 0)
goto errout;
}
err = pp->pp_cb((struct nl_object *)lmsg, pp);
errout:
nl_dect_llme_msg_put(lmsg);
return err;
}
/**
* @name message creation
* @{
*/
static int nl_dect_llme_build_msg(struct nl_msg *msg, struct nl_dect_llme_msg *lmsg,
enum dect_llme_ops op)
{
const struct nl_dect_llme_link *link;
struct nlattr *nest;
struct dectmsg dm = {
.dm_index = lmsg->lm_index,
};
if (nlmsg_append(msg, &dm, sizeof(dm), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
NLA_PUT_U8(msg, DECTA_LLME_OP, op);
NLA_PUT_U8(msg, DECTA_LLME_TYPE, lmsg->lm_type);
link = &nl_dect_llme_dispatch[lmsg->lm_type];
nest = nla_nest_start(msg, DECTA_LLME_DATA);
if (nest == NULL)
goto nla_put_failure;
if (link->build(msg, lmsg) < 0)
goto nla_put_failure;
nla_nest_end(msg, nest);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
static int build_llme_msg(struct nl_dect_llme_msg *tmpl, enum dect_llme_ops op,
struct nl_msg **result)
{
struct nl_msg *msg;
int err;
if (!(msg = nlmsg_alloc_simple(DECT_LLME_MSG, 0)))
return -NLE_NOMEM;
if ((err = nl_dect_llme_build_msg(msg, tmpl, op)) < 0) {
nlmsg_free(msg);
return err;
}
*result = msg;
return 0;
}
int nl_dect_llme_build_request(struct nl_dect_llme_msg *tmpl,
struct nl_msg **result)
{
return build_llme_msg(tmpl, DECT_LLME_REQUEST, result);
}
int nl_dect_llme_request(struct nl_sock *sk, struct nl_dect_llme_msg *lmsg)
{
struct nl_msg *msg;
int err;
if ((err = nl_dect_llme_build_request(lmsg, &msg)) < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
int nl_dect_llme_build_response(struct nl_dect_llme_msg *tmpl,
struct nl_msg **result)
{
return build_llme_msg(tmpl, DECT_LLME_RESPONSE, result);
}
int nl_dect_llme_respond(struct nl_sock *sk, struct nl_dect_llme_msg *tmpl)
{
struct nl_msg *msg;
int err;
if ((err = nl_dect_llme_build_response(tmpl, &msg)) < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
void nl_dect_llme_msg_set_index(struct nl_dect_llme_msg *lmsg, int index)
{
lmsg->lm_index = index;
}
void nl_dect_llme_msg_set_type(struct nl_dect_llme_msg *lmsg,
enum dect_llme_msg_types type)
{
lmsg->lm_type = type;
}
enum dect_llme_msg_types nl_dect_llme_msg_get_type(const struct nl_dect_llme_msg *lmsg)
{
return lmsg->lm_type;
}
enum dect_llme_ops nl_dect_llme_msg_get_op(const struct nl_dect_llme_msg *lmsg)
{
return lmsg->lm_op;
}
void nl_dect_llme_msg_set_op(struct nl_dect_llme_msg *lmsg, enum dect_llme_ops op)
{
lmsg->lm_op = op;
}
/** @} */
/**
* @name Allocation/Freeing
* @{
*/
struct nl_dect_llme_msg *nl_dect_llme_msg_alloc(void)
{
return (struct nl_dect_llme_msg *)nl_object_alloc(&llme_msg_obj_ops);
}
void nl_dect_llme_msg_get(struct nl_dect_llme_msg *lmsg)
{
nl_object_get((struct nl_object *)lmsg);
}
void nl_dect_llme_msg_put(struct nl_dect_llme_msg *lmsg)
{
nl_object_put((struct nl_object *)lmsg);
}
/** @} */
static struct trans_tbl llme_types[] = {
__ADD(DECT_LLME_SCAN, SCAN)
__ADD(DECT_LLME_MAC_INFO, MAC_INFO)
};
char *nl_dect_llme_msgtype2str(enum dect_llme_msg_types type, char *buf, size_t len)
{
return __type2str(type, buf, len, llme_types, ARRAY_SIZE(llme_types));
}
enum dect_llme_msg_types nl_dect_llme_str2msgtype(const char *str)
{
return __str2type(str, llme_types, ARRAY_SIZE(llme_types));
}
static struct trans_tbl llme_ops[] = {
__ADD(DECT_LLME_REQUEST, req)
__ADD(DECT_LLME_INDICATE, ind)
__ADD(DECT_LLME_RESPONSE, res)
__ADD(DECT_LLME_CONFIRM, cfm)
};
char *nl_dect_llme_op2str(enum dect_llme_ops op, char *buf, size_t len)
{
return __type2str(op, buf, len, llme_ops, ARRAY_SIZE(llme_ops));
}
enum dect_llme_ops nl_dect_llme_str2op(const char *str)
{
return __str2type(str, llme_ops, ARRAY_SIZE(llme_ops));
}
/** @cond SKIP */
static struct nl_object_ops llme_msg_obj_ops = {
.oo_name = "nl_dect/llme_msg",
.oo_size = sizeof(struct nl_dect_llme_msg),
.oo_dump = {
[NL_DUMP_LINE] = llme_msg_dump,
},
};
static struct nl_cache_ops nl_dect_llme_msg_ops = {
.co_name = "nl_dect/llme_msg",
.co_protocol = NETLINK_DECT,
.co_msgtypes = {
{ DECT_LLME_MSG, NL_ACT_NEW, "new" },
END_OF_MSGTYPES_LIST,
},
.co_msg_parser = llme_msg_parser,
.co_obj_ops = &llme_msg_obj_ops,
};
/** @endcond */
static void __init llme_init(void)
{
nl_cache_mngt_register(&nl_dect_llme_msg_ops);
}
static void __exit llme_exit(void)
{
nl_cache_mngt_unregister(&nl_dect_llme_msg_ops);
}
/** @} */

307
lib/dect/transceiver.c Normal file
View File

@ -0,0 +1,307 @@
/*
* lib/dect/transceiver.c DECT Transceiver objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
/**
* @ingroup dect
* @defgroup dect Transceivers
* @brief
* @{
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/dect/transceiver.h>
/** @cond SKIP */
static struct nl_cache_ops nl_dect_transceiver_ops;
/** @endcond */
#define DECTNAMSIZ 16
static struct nla_policy transceiver_policy[DECTA_TRANSCEIVER_MAX + 1] = {
[DECTA_TRANSCEIVER_NAME] = { .type = NLA_STRING, .maxlen = DECTNAMSIZ },
[DECTA_TRANSCEIVER_TYPE] = { .type = NLA_STRING },
[DECTA_TRANSCEIVER_FEATURES] = { .type = NLA_U32 },
[DECTA_TRANSCEIVER_LINK] = { .type = NLA_U8 },
[DECTA_TRANSCEIVER_STATS] = { .type = NLA_NESTED },
[DECTA_TRANSCEIVER_BAND] = { .type = NLA_U8 },
[DECTA_TRANSCEIVER_SLOTS] = { .type = NLA_NESTED },
};
static struct nla_policy stats_policy[DECTA_TRANSCEIVER_STATS_MAX + 1] = {
[DECTA_TRANSCEIVER_STATS_EVENT_BUSY] = { .type = NLA_U32 },
[DECTA_TRANSCEIVER_STATS_EVENT_LATE] = { .type = NLA_U32 },
};
static struct nla_policy slot_policy[DECTA_SLOT_MAX + 1] = {
[DECTA_SLOT_NUM] = { .type = NLA_U8 },
[DECTA_SLOT_STATE] = { .type = NLA_U8 },
[DECTA_SLOT_FLAGS] = { .type = NLA_U32 },
[DECTA_SLOT_PACKET] = { .type = NLA_U8 },
[DECTA_SLOT_CARRIER] = { .type = NLA_U8 },
[DECTA_SLOT_FREQUENCY] = { .type = NLA_U32 },
[DECTA_SLOT_PHASEOFF] = { .type = NLA_U32 },
[DECTA_SLOT_RSSI] = { .type = NLA_U8 },
[DECTA_SLOT_RX_BYTES] = { .type = NLA_U32 },
[DECTA_SLOT_RX_PACKETS] = { .type = NLA_U32 },
[DECTA_SLOT_RX_A_CRC_ERRORS] = { .type = NLA_U32 },
[DECTA_SLOT_RX_X_CRC_ERRORS] = { .type = NLA_U32 },
[DECTA_SLOT_RX_Z_CRC_ERRORS] = { .type = NLA_U32 },
[DECTA_SLOT_TX_BYTES] = { .type = NLA_U32 },
[DECTA_SLOT_TX_PACKETS] = { .type = NLA_U32 },
};
static int slot_parser(struct nl_dect_transceiver *trx, struct nlattr *nla)
{
struct nlattr *tb[DECTA_SLOT_MAX + 1];
struct nl_dect_transceiver_slot *dts;
uint8_t slot;
int err;
err = nla_parse_nested(tb, DECTA_SLOT_MAX, nla, slot_policy);
if (err < 0)
return err;
if (tb[DECTA_SLOT_NUM] == NULL)
return -NLE_INVAL;
slot = nla_get_u8(tb[DECTA_SLOT_NUM]);
dts = &trx->trx_slots[slot];
dts->dts_valid = 1;
if (tb[DECTA_SLOT_STATE] != NULL)
dts->dts_state = nla_get_u8(tb[DECTA_SLOT_STATE]);
if (tb[DECTA_SLOT_FLAGS] != NULL)
dts->dts_flags = nla_get_u32(tb[DECTA_SLOT_FLAGS]);
if (tb[DECTA_SLOT_PACKET] != NULL)
dts->dts_packet = nla_get_u8(tb[DECTA_SLOT_PACKET]);
if (tb[DECTA_SLOT_CARRIER] != NULL)
dts->dts_carrier = nla_get_u8(tb[DECTA_SLOT_CARRIER]);
if (tb[DECTA_SLOT_FREQUENCY] != NULL)
dts->dts_frequency = nla_get_u32(tb[DECTA_SLOT_FREQUENCY]);
if (tb[DECTA_SLOT_PHASEOFF] != NULL)
dts->dts_phaseoff = nla_get_u32(tb[DECTA_SLOT_PHASEOFF]);
if (tb[DECTA_SLOT_RSSI] != NULL)
dts->dts_rssi = nla_get_u8(tb[DECTA_SLOT_RSSI]);
if (tb[DECTA_SLOT_RX_BYTES] != NULL)
dts->dts_rx_bytes = nla_get_u32(tb[DECTA_SLOT_RX_BYTES]);
if (tb[DECTA_SLOT_RX_PACKETS] != NULL)
dts->dts_rx_packets = nla_get_u32(tb[DECTA_SLOT_RX_PACKETS]);
if (tb[DECTA_SLOT_RX_A_CRC_ERRORS] != NULL)
dts->dts_rx_a_crc_errors = nla_get_u32(tb[DECTA_SLOT_RX_A_CRC_ERRORS]);
if (tb[DECTA_SLOT_RX_X_CRC_ERRORS] != NULL)
dts->dts_rx_x_crc_errors = nla_get_u32(tb[DECTA_SLOT_RX_X_CRC_ERRORS]);
if (tb[DECTA_SLOT_RX_Z_CRC_ERRORS] != NULL)
dts->dts_rx_z_crc_errors = nla_get_u32(tb[DECTA_SLOT_RX_Z_CRC_ERRORS]);
if (tb[DECTA_SLOT_TX_BYTES] != NULL)
dts->dts_tx_bytes = nla_get_u32(tb[DECTA_SLOT_TX_BYTES]);
if (tb[DECTA_SLOT_TX_PACKETS] != NULL)
dts->dts_tx_packets = nla_get_u32(tb[DECTA_SLOT_TX_PACKETS]);
return 0;
}
static int stats_parser(struct nl_dect_transceiver *trx, struct nlattr *nla)
{
struct nlattr *tb[DECTA_TRANSCEIVER_STATS_MAX + 1];
struct nl_dect_transceiver_stats *stats = &trx->trx_stats;
int err;
err = nla_parse_nested(tb, DECTA_TRANSCEIVER_STATS_MAX, nla, stats_policy);
if (err < 0)
return err;
if (tb[DECTA_TRANSCEIVER_STATS_EVENT_BUSY] != NULL)
stats->trx_event_busy =
nla_get_u32(tb[DECTA_TRANSCEIVER_STATS_EVENT_BUSY]);
if (tb[DECTA_TRANSCEIVER_STATS_EVENT_LATE] != NULL)
stats->trx_event_late =
nla_get_u32(tb[DECTA_TRANSCEIVER_STATS_EVENT_LATE]);
return 0;
}
static int transceiver_msg_parser(struct nl_cache_ops *ops,
struct sockaddr_nl *who,
struct nlmsghdr *n,
struct nl_parser_param *pp)
{
struct nlattr *tb[DECTA_TRANSCEIVER_MAX + 1], *nla;
struct nl_dect_transceiver *trx;
int err;
trx = nl_dect_transceiver_alloc();
if (trx == NULL) {
err = -NLE_NOMEM;
goto errout;
}
trx->ce_msgtype = n->nlmsg_type;
err = nlmsg_parse(n, sizeof(struct dectmsg), tb, DECTA_TRANSCEIVER_MAX,
transceiver_policy);
if (err < 0)
goto errout;
if (tb[DECTA_TRANSCEIVER_NAME] != NULL) {
char name[DECTNAMSIZ];
nla_strlcpy(name, tb[DECTA_TRANSCEIVER_NAME], sizeof(name));
nl_dect_transceiver_set_name(trx, name);
}
if (tb[DECTA_TRANSCEIVER_TYPE] != NULL) {
char *type = nla_strdup(tb[DECTA_TRANSCEIVER_TYPE]);
if (type == NULL) {
err = -NLE_NOMEM;
goto errout;
}
nl_dect_transceiver_set_type(trx, type);
free(type);
}
if (tb[DECTA_TRANSCEIVER_FEATURES] != NULL)
nl_dect_transceiver_set_features(trx, nla_get_u32(tb[DECTA_TRANSCEIVER_FEATURES]));
if (tb[DECTA_TRANSCEIVER_LINK] != NULL)
nl_dect_transceiver_set_link(trx, nla_get_u8(tb[DECTA_TRANSCEIVER_LINK]));
if (tb[DECTA_TRANSCEIVER_STATS] != NULL) {
err = stats_parser(trx, tb[DECTA_TRANSCEIVER_STATS]);
if (err < 0)
goto errout;
}
if (tb[DECTA_TRANSCEIVER_BAND] != NULL)
nl_dect_transceiver_set_band(trx, nla_get_u8(tb[DECTA_TRANSCEIVER_BAND]));
if (tb[DECTA_TRANSCEIVER_SLOTS] != NULL) {
int rem;
nla_for_each_nested(nla, tb[DECTA_TRANSCEIVER_SLOTS], rem) {
if (nla_type(nla) != DECTA_LIST_ELEM)
continue;
err = slot_parser(trx, nla);
if (err < 0)
goto errout;
}
}
err = pp->pp_cb((struct nl_object *)trx, pp);
errout:
nl_dect_transceiver_put(trx);
return err;
}
static int transceiver_request_update(struct nl_cache *c, struct nl_sock *h)
{
struct dectmsg dm;
memset(&dm, 0, sizeof(dm));
return nl_send_simple(h, DECT_GET_TRANSCEIVER, NLM_F_DUMP,
&dm, sizeof(dm));
}
/**
* @name Cache Management
* @{
*/
int nl_dect_transceiver_alloc_cache(struct nl_sock *sk, struct nl_cache **result)
{
struct nl_cache *cache;
int err;
cache = nl_cache_alloc(&nl_dect_transceiver_ops);
if (cache == NULL)
return -NLE_NOMEM;
if (sk && (err = nl_cache_refill(sk, cache)) < 0) {
free(cache);
return err;
}
*result = cache;
return 0;
}
/** @} */
/**
* @name Transceiver creation
* @{
*/
static int build_transceiver_msg(struct nl_dect_transceiver *tmpl, int cmd,
int flags, struct nl_msg **result)
{
struct nl_msg *msg;
int err;
msg = nlmsg_alloc_simple(cmd, flags);
if (msg == NULL)
return -NLE_NOMEM;
err = nl_dect_transceiver_build_msg(msg, tmpl);
if (err < 0) {
nlmsg_free(msg);
return err;
}
*result = msg;
return 0;
}
int nl_dect_transceiver_build_change_request(struct nl_dect_transceiver *tmpl,
int flags, struct nl_msg **result)
{
return build_transceiver_msg(tmpl, DECT_NEW_TRANSCEIVER, flags, result);
}
int nl_dect_transceiver_change(struct nl_sock *sk, struct nl_dect_transceiver *trx,
int flags)
{
struct nl_msg *msg;
int err;
err = nl_dect_transceiver_build_change_request(trx, flags, &msg);
if (err < 0)
return err;
err = nl_send_auto_complete(sk, msg);
nlmsg_free(msg);
if (err < 0)
return err;
return wait_for_ack(sk);
}
static struct nl_cache_ops nl_dect_transceiver_ops = {
.co_name = "nl_dect/transceiver",
.co_hdrsize = 0,
.co_msgtypes = {
{ DECT_NEW_TRANSCEIVER, NL_ACT_NEW, "new" },
{ DECT_GET_TRANSCEIVER, NL_ACT_GET, "get" },
{ DECT_DEL_TRANSCEIVER, NL_ACT_DEL, "del" },
END_OF_MSGTYPES_LIST
},
.co_protocol = NETLINK_DECT,
.co_request_update = transceiver_request_update,
.co_msg_parser = transceiver_msg_parser,
.co_obj_ops = &nl_dect_transceiver_obj_ops,
};
static void __init transceiver_init(void)
{
nl_cache_mngt_register(&nl_dect_transceiver_ops);
}
static void __exit transceiver_exit(void)
{
nl_cache_mngt_unregister(&nl_dect_transceiver_ops);
}
/** @} */

335
lib/dect/transceiver_obj.c Normal file
View File

@ -0,0 +1,335 @@
/*
* lib/dect/transceiver_obj.c DECT Transceiver objects
*
* 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) 2009 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/cache.h>
#include <netlink/utils.h>
#include <netlink/data.h>
#include <netlink/dect/dect.h>
#include <netlink/dect/cell.h>
#include <netlink/dect/transceiver.h>
/** @cond SKIP */
#define TRANSCEIVER_ATTR_NAME 0x0001
#define TRANSCEIVER_ATTR_TYPE 0x0002
#define TRANSCEIVER_ATTR_FEATURES 0x0004
#define TRANSCEIVER_ATTR_INDEX 0x0008
#define TRANSCEIVER_ATTR_LINK 0x0010
#define TRANSCEIVER_ATTR_BAND 0x0020
/** @endtsond */
static void transceiver_free_data(struct nl_object *obj)
{
struct nl_dect_transceiver *trx = nl_object_priv(obj);
if (trx == NULL)
return;
free(trx->trx_name);
free(trx->trx_type);
}
static void slot_dump(struct nl_dect_transceiver_slot *dts, unsigned int n,
struct nl_dump_params *p)
{
int64_t offset;
char buf[64];
nl_dect_slot_state2str(dts->dts_state, buf, sizeof(buf));
nl_dump(p, "\tslot %u: <%s", n, buf);
if (dts->dts_flags) {
nl_dect_slot_flags2str(dts->dts_flags, buf, sizeof(buf));
nl_dump(p, ",%s", buf);
}
nl_dump(p, "> ");
if (dts->dts_state != DECT_SLOT_IDLE) {
nl_dump(p, "packet: %s ",
nl_dect_slot_packet2str(dts->dts_packet, buf,
sizeof(buf)));
nl_dump(p, "carrier: %u (%u.%03u MHz", dts->dts_carrier,
dts->dts_frequency / 1000, dts->dts_frequency % 1000);
if (dts->dts_state == DECT_SLOT_RX) {
offset = (int64_t)dts->dts_frequency *
dts->dts_phaseoff /
DECT_PHASE_OFFSET_SCALE;
nl_dump(p, " %+" PRId64 ".%03" PRIu64 " kHz",
offset / 1000000,
llabs(offset) % 1000000 / 1000);
}
nl_dump(p, ")");
}
if (dts->dts_state == DECT_SLOT_RX)
nl_dump(p, " signal level: %.2fdBm",
nl_dect_rssi_to_dbm(dts->dts_rssi));
nl_dump(p, "\n");
nl_dump(p, "\t RX: bytes %u packets %u a-crc-errors %u "
"x-crc-errors %u z-crc-errors %u\n",
dts->dts_rx_bytes, dts->dts_rx_packets,
dts->dts_rx_a_crc_errors,
dts->dts_rx_x_crc_errors,
dts->dts_rx_z_crc_errors);
nl_dump(p, "\t TX: bytes %u packets %u\n",
dts->dts_tx_bytes, dts->dts_tx_packets);
}
static void transceiver_dump(struct nl_object *obj, struct nl_dump_params *p)
{
struct nl_dect_transceiver *trx = nl_object_priv(obj);
struct nl_dect_transceiver_stats *stats = &trx->trx_stats;
struct nl_dect_transceiver_slot *dts;
struct nl_cache *cell_cache;
char buf[64];
unsigned int n;
nl_dump(p, "DECT Transceiver ");
if (trx->trx_name != NULL)
nl_dump_line(p, "%s", trx->trx_name);
if (trx->trx_link) {
cell_cache = nl_cache_mngt_require("nl_dect/cell");
if (cell_cache != NULL) {
nl_dump(p, "@%s",
nl_dect_cell_i2name(cell_cache, trx->trx_link,
buf, sizeof(buf)));
} else
nl_dump(p, "@%d", trx->trx_link);
}
nl_dump(p, ":\n");
if (trx->trx_type != NULL)
nl_dump_line(p, "\tType: %s\n", trx->trx_type);
if (trx->trx_features != 0)
nl_dump_line(p, "\tFeatures: %s\n",
nl_dect_transceiver_features2str(trx->trx_features,
buf, sizeof(buf)));
nl_dump(p, "\tRF-band: %.5u\n", trx->trx_band);
nl_dump(p, "\tEvents: busy: %u late: %u\n",
stats->trx_event_busy, stats->trx_event_late);
nl_dump(p, "\n");
for (n = 0; n < 24; n++) {
dts = &trx->trx_slots[n];
if (!dts->dts_valid)
continue;
slot_dump(dts, n, p);
}
}
static int nl_dect_transceiver_compare(struct nl_object *_a, struct nl_object *_b,
uint32_t attrs, int flags)
{
struct nl_dect_transceiver *a = (struct nl_dect_transceiver *)_a;
struct nl_dect_transceiver *b = (struct nl_dect_transceiver *)_b;
int diff = 0;
#define TRX_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, TRANSCEIVER_ATTR_##ATTR, a, b, EXPR)
diff |= TRX_DIFF(NAME, strcmp(a->trx_name, b->trx_name));
diff |= TRX_DIFF(LINK, a->trx_link != b->trx_link);
#undef TRX_DIFF
return diff;
}
/**
* @name Allocation/Freeing
* @{
*/
struct nl_dect_transceiver *nl_dect_transceiver_alloc(void)
{
return (struct nl_dect_transceiver *)nl_object_alloc(&nl_dect_transceiver_obj_ops);
}
void nl_dect_transceiver_get(struct nl_dect_transceiver *trx)
{
nl_object_get((struct nl_object *)trx);
}
void nl_dect_transceiver_put(struct nl_dect_transceiver *trx)
{
nl_object_put((struct nl_object *)trx);
}
/** @} */
/**
* @name Attributes
* @{
*/
void nl_dect_transceiver_set_name(struct nl_dect_transceiver *trx, const char *name)
{
trx->trx_name = strdup(name);
trx->ce_mask |= TRANSCEIVER_ATTR_NAME;
}
bool nl_dect_transceiver_test_name(const struct nl_dect_transceiver *trx)
{
return !!(trx->ce_mask & TRANSCEIVER_ATTR_NAME);
}
const char *nl_dect_transceiver_get_name(const struct nl_dect_transceiver *trx)
{
return trx->trx_name;
}
void nl_dect_transceiver_set_type(struct nl_dect_transceiver *trx, const char *type)
{
trx->trx_type = strdup(type);
trx->ce_mask |= TRANSCEIVER_ATTR_TYPE;
}
bool nl_dect_transceiver_test_type(const struct nl_dect_transceiver *trx)
{
return !!(trx->ce_mask & TRANSCEIVER_ATTR_TYPE);
}
const char *nl_dect_transceiver_get_type(const struct nl_dect_transceiver *trx)
{
return trx->trx_type;
}
void nl_dect_transceiver_set_features(struct nl_dect_transceiver *trx, uint32_t features)
{
trx->trx_features = features;
trx->ce_mask |= TRANSCEIVER_ATTR_FEATURES;
}
void nl_dect_transceiver_set_index(struct nl_dect_transceiver *trx, int index)
{
trx->trx_index = index;
trx->ce_mask |= TRANSCEIVER_ATTR_INDEX;
}
void nl_dect_transceiver_set_link(struct nl_dect_transceiver *trx, uint8_t link)
{
trx->trx_link = link;
trx->ce_mask |= TRANSCEIVER_ATTR_LINK;
}
void nl_dect_transceiver_set_band(struct nl_dect_transceiver *trx, uint8_t band)
{
trx->trx_band = band;
trx->ce_mask |= TRANSCEIVER_ATTR_BAND;
}
bool nl_dect_transceiver_test_band(const struct nl_dect_transceiver *trx)
{
return !!(trx->ce_mask & TRANSCEIVER_ATTR_BAND);
}
uint8_t nl_dect_transceiver_get_band(const struct nl_dect_transceiver *trx)
{
return trx->trx_band;
}
static struct trans_tbl trx_features[] = {
__ADD(DECT_TRANSCEIVER_SLOW_HOPPING, slow-hopping)
__ADD(DECT_TRANSCEIVER_PACKET_P64, p64)
};
const char *nl_dect_transceiver_features2str(uint32_t features, char *buf, size_t len)
{
return __flags2str(features, buf, len, trx_features,
ARRAY_SIZE(trx_features));
}
static struct trans_tbl slot_states[] = {
__ADD(DECT_SLOT_IDLE, idle)
__ADD(DECT_SLOT_SCANNING, scanning)
__ADD(DECT_SLOT_RX, rx)
__ADD(DECT_SLOT_TX, tx)
};
const char *nl_dect_slot_state2str(uint8_t state, char *buf, size_t len)
{
return __type2str(state, buf, len, slot_states,
ARRAY_SIZE(slot_states));
}
uint8_t nl_dect_slot_str2state(const char *str)
{
return __str2type(str, slot_states, ARRAY_SIZE(slot_states));
}
static struct trans_tbl slot_flags[] = {
__ADD(DECT_SLOT_SYNC, sync)
__ADD(DECT_SLOT_CIPHER, cipher)
};
const char *nl_dect_slot_flags2str(uint32_t state, char *buf, size_t len)
{
return __flags2str(state, buf, len, slot_flags, ARRAY_SIZE(slot_flags));
}
uint32_t nl_dect_slot_str2flags(const char *str)
{
return __str2flags(str, slot_flags, ARRAY_SIZE(slot_flags));
}
static struct trans_tbl packet_types[] = {
__ADD(DECT_PACKET_P00, P00)
__ADD(DECT_PACKET_P08, P08)
__ADD(DECT_PACKET_P32, P32)
__ADD(DECT_PACKET_P80, P80)
__ADD(DECT_PACKET_P640j, P640j)
__ADD(DECT_PACKET_P640j, P672j)
};
const char *nl_dect_slot_packet2str(uint8_t pkt, char *buf, size_t len)
{
return __type2str(pkt, buf, len, packet_types, ARRAY_SIZE(packet_types));
}
uint8_t nl_dect_slot_str2packet(const char *str)
{
return __str2type(str, packet_types, ARRAY_SIZE(packet_types));
}
int nl_dect_transceiver_build_msg(struct nl_msg *msg, struct nl_dect_transceiver *trx)
{
struct dectmsg dm = {
.dm_index = trx->trx_index,
};
if (nlmsg_append(msg, &dm, sizeof(dm), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;
if (trx->ce_mask & TRANSCEIVER_ATTR_NAME)
NLA_PUT_STRING(msg, DECTA_TRANSCEIVER_NAME, trx->trx_name);
if (trx->ce_mask & TRANSCEIVER_ATTR_LINK)
NLA_PUT_U8(msg, DECTA_TRANSCEIVER_LINK, trx->trx_link);
return 0;
nla_put_failure:
return -NLE_MSGSIZE;
}
/** @cond SKIP */
struct nl_object_ops nl_dect_transceiver_obj_ops = {
.oo_name = "nl_dect/transceiver",
.oo_size = sizeof(struct nl_dect_transceiver),
.oo_free_data = transceiver_free_data,
.oo_dump = {
[NL_DUMP_LINE] = transceiver_dump,
},
.oo_compare = nl_dect_transceiver_compare,
.oo_id_attrs = TRANSCEIVER_ATTR_NAME,
};
/** @endcond */
/** @} */

View File

@ -9,7 +9,7 @@
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
static const char *errmsg[NLE_MAX+1] = {

View File

@ -16,7 +16,7 @@
* @{
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/utils.h>
@ -124,7 +124,7 @@ errout:
static void result_dump_line(struct nl_object *obj, struct nl_dump_params *p)
{
struct flnl_result *res = (struct flnl_result *) obj;
char buf[128];
char buf[256];
nl_dump_line(p, "table %s prefixlen %u next-hop-selector %u\n",
rtnl_route_table2str(res->fr_table_id, buf, sizeof(buf)),
@ -133,7 +133,7 @@ static void result_dump_line(struct nl_object *obj, struct nl_dump_params *p)
nl_rtntype2str(res->fr_type, buf, sizeof(buf)));
nl_dump(p, "scope %s error %s (%d)\n",
rtnl_scope2str(res->fr_scope, buf, sizeof(buf)),
strerror(-res->fr_error), res->fr_error);
strerror_r(-res->fr_error, buf, sizeof(buf)), res->fr_error);
}
static void result_dump_details(struct nl_object *obj, struct nl_dump_params *p)

View File

@ -16,7 +16,7 @@
* @{
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/attr.h>
#include <netlink/utils.h>

View File

@ -21,7 +21,7 @@
* @{
*/
#include <netlink-generic.h>
#include <netlink-private/genl.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
@ -239,7 +239,7 @@ static struct genl_family *genl_ctrl_probe_by_name(struct nl_sock *sk,
{
struct nl_msg *msg;
struct genl_family *ret;
struct nl_cb *cb;
struct nl_cb *cb, *orig;
int rc;
ret = genl_family_alloc();
@ -252,7 +252,12 @@ static struct genl_family *genl_ctrl_probe_by_name(struct nl_sock *sk,
if (!msg)
goto out_fam_free;
if (!(cb = nl_cb_clone(nl_socket_get_cb(sk))))
if (!(orig = nl_socket_get_cb(sk)))
goto out_msg_free;
cb = nl_cb_clone(orig);
nl_cb_put(orig);
if (!cb)
goto out_msg_free;
if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL,

View File

@ -18,7 +18,7 @@
* @{
*/
#include <netlink-generic.h>
#include <netlink-private/genl.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>

View File

@ -15,7 +15,7 @@
* @{
*/
#include <netlink-generic.h>
#include <netlink-private/genl.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/utils.h>

View File

@ -18,7 +18,7 @@
* @{
*/
#include <netlink-generic.h>
#include <netlink-private/genl.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/mngt.h>
@ -295,6 +295,10 @@ static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops)
family = genl_ctrl_search_by_name(ctrl, ops->o_name);
if (family != NULL) {
ops->o_id = genl_family_get_id(family);
if (ops->o_cache_ops)
ops->o_cache_ops->co_msgtypes[0].mt_id = ops->o_id;
genl_family_put(family);
return 0;
@ -302,6 +306,32 @@ static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops)
return -NLE_OBJ_NOTFOUND;
}
int genl_resolve_id(struct genl_ops *ops)
{
struct nl_sock *sk;
int err = 0;
/* Check if resolved already */
if (ops->o_id != GENL_ID_GENERATE)
return 0;
if (!ops->o_name)
return -NLE_INVAL;
if (!(sk = nl_socket_alloc()))
return -NLE_NOMEM;
if ((err = genl_connect(sk)) < 0)
goto errout_free;
err = genl_ops_resolve(sk, ops);
errout_free:
nl_socket_free(sk);
return err;
}
/** @endcond */
/**

View File

@ -25,7 +25,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/msg.h>
@ -79,9 +79,10 @@ static int nl_error_handler_verbose(struct sockaddr_nl *who,
struct nlmsgerr *e, void *arg)
{
FILE *ofd = arg ? arg : stderr;
char buf[256];
fprintf(ofd, "-- Error received: %s\n-- Original message: ",
strerror(-e->error));
strerror_r(-e->error, buf, sizeof(buf)));
print_header_content(ofd, &e->msg);
fprintf(ofd, "\n");

View File

@ -9,7 +9,7 @@
* Copyright (c) 2012 Cumulus Networks, Inc
*/
#include <string.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/object.h>
#include <netlink/hash.h>
#include <netlink/hashtable.h>

192
lib/msg.c
View File

@ -26,7 +26,7 @@
* ~~~~
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/cache.h>
@ -153,7 +153,7 @@ struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen)
*/
int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
{
return nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen);
return max_t(int, nlmsg_len(nlh) - NLMSG_ALIGN(hdrlen), 0);
}
/** @} */
@ -178,7 +178,7 @@ int nlmsg_valid_hdr(const struct nlmsghdr *nlh, int hdrlen)
*/
int nlmsg_ok(const struct nlmsghdr *nlh, int remaining)
{
return (remaining >= sizeof(struct nlmsghdr) &&
return (remaining >= (int)sizeof(struct nlmsghdr) &&
nlh->nlmsg_len >= sizeof(struct nlmsghdr) &&
nlh->nlmsg_len <= remaining);
}
@ -767,7 +767,7 @@ static inline void dump_hex(FILE *ofd, char *start, int len, int prefix)
int i, a, c, limit;
char ascii[21] = {0};
limit = 18 - (prefix * 2);
limit = 16 - (prefix * 2);
prefix_line(ofd, prefix);
fprintf(ofd, " ");
@ -777,7 +777,7 @@ static inline void dump_hex(FILE *ofd, char *start, int len, int prefix)
fprintf(ofd, "%02x ", v);
ascii[a++] = isprint(v) ? v : '.';
if (c == limit-1) {
if (++c >= limit) {
fprintf(ofd, "%s\n", ascii);
if (i < (len - 1)) {
prefix_line(ofd, prefix);
@ -785,8 +785,7 @@ static inline void dump_hex(FILE *ofd, char *start, int len, int prefix)
}
a = c = 0;
memset(ascii, 0, sizeof(ascii));
} else
c++;
}
}
if (c != 0) {
@ -816,14 +815,62 @@ static void print_hdr(FILE *ofd, struct nl_msg *msg)
} else
nl_nlmsgtype2str(nlh->nlmsg_type, buf, sizeof(buf));
fprintf(ofd, " .nlmsg_type = %d <%s>\n", nlh->nlmsg_type, buf);
fprintf(ofd, " .nlmsg_flags = %d <%s>\n", nlh->nlmsg_flags,
fprintf(ofd, " .type = %d <%s>\n", nlh->nlmsg_type, buf);
fprintf(ofd, " .flags = %d <%s>\n", nlh->nlmsg_flags,
nl_nlmsg_flags2str(nlh->nlmsg_flags, buf, sizeof(buf)));
fprintf(ofd, " .nlmsg_seq = %d\n", nlh->nlmsg_seq);
fprintf(ofd, " .nlmsg_pid = %d\n", nlh->nlmsg_pid);
fprintf(ofd, " .seq = %d\n", nlh->nlmsg_seq);
fprintf(ofd, " .port = %d\n", nlh->nlmsg_pid);
}
static void print_genl_hdr(FILE *ofd, void *start)
{
struct genlmsghdr *ghdr = start;
fprintf(ofd, " [GENERIC NETLINK HEADER] %zu octets\n", GENL_HDRLEN);
fprintf(ofd, " .cmd = %u\n", ghdr->cmd);
fprintf(ofd, " .version = %u\n", ghdr->version);
fprintf(ofd, " .unused = %#x\n", ghdr->reserved);
}
static void *print_genl_msg(struct nl_msg *msg, FILE *ofd, struct nlmsghdr *hdr,
struct nl_cache_ops *ops, int *payloadlen)
{
void *data = nlmsg_data(hdr);
if (*payloadlen < GENL_HDRLEN)
return data;
print_genl_hdr(ofd, data);
*payloadlen -= GENL_HDRLEN;
data += GENL_HDRLEN;
if (ops) {
int hdrsize = ops->co_hdrsize - GENL_HDRLEN;
if (hdrsize > 0) {
if (*payloadlen < hdrsize)
return data;
fprintf(ofd, " [HEADER] %d octets\n", hdrsize);
dump_hex(ofd, data, hdrsize, 0);
*payloadlen -= hdrsize;
data += hdrsize;
}
}
return data;
}
static void dump_attr(FILE *ofd, struct nlattr *attr, int prefix)
{
int len = nla_len(attr);
dump_hex(ofd, nla_data(attr), len, prefix);
}
static void dump_attrs(FILE *ofd, struct nlattr *attrs, int attrlen,
int prefix)
{
@ -834,14 +881,18 @@ static void dump_attrs(FILE *ofd, struct nlattr *attrs, int attrlen,
int padlen, alen = nla_len(nla);
prefix_line(ofd, prefix);
fprintf(ofd, " [ATTR %02d%s] %d octets\n", nla_type(nla),
nla->nla_type & NLA_F_NESTED ? " NESTED" : "",
alen);
if (nla->nla_type & NLA_F_NESTED)
if (nla->nla_type == 0)
fprintf(ofd, " [ATTR PADDING] %d octets\n", alen);
else
fprintf(ofd, " [ATTR %02d%s] %d octets\n", nla_type(nla),
nla_is_nested(nla) ? " NESTED" : "",
alen);
if (nla_is_nested(nla))
dump_attrs(ofd, nla_data(nla), alen, prefix+1);
else
dump_hex(ofd, nla_data(nla), alen, prefix);
dump_attr(ofd, nla, prefix);
padlen = nla_padlen(alen);
if (padlen > 0) {
@ -859,6 +910,63 @@ static void dump_attrs(FILE *ofd, struct nlattr *attrs, int attrlen,
}
}
static void dump_error_msg(struct nl_msg *msg, FILE *ofd)
{
struct nlmsghdr *hdr = nlmsg_hdr(msg);
struct nlmsgerr *err = nlmsg_data(hdr);
fprintf(ofd, " [ERRORMSG] %zu octets\n", sizeof(*err));
if (nlmsg_len(hdr) >= sizeof(*err)) {
char buf[256];
struct nl_msg *errmsg;
fprintf(ofd, " .error = %d \"%s\"\n", err->error,
strerror_r(-err->error, buf, sizeof(buf)));
fprintf(ofd, " [ORIGINAL MESSAGE] %zu octets\n", sizeof(*hdr));
errmsg = nlmsg_inherit(&err->msg);
print_hdr(ofd, errmsg);
nlmsg_free(errmsg);
}
}
static void print_msg(struct nl_msg *msg, FILE *ofd, struct nlmsghdr *hdr)
{
struct nl_cache_ops *ops;
int payloadlen = nlmsg_len(hdr);
int attrlen = 0;
void *data;
data = nlmsg_data(hdr);
ops = nl_cache_ops_associate_safe(nlmsg_get_proto(msg),
hdr->nlmsg_type);
if (ops) {
attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize);
payloadlen -= attrlen;
}
if (msg->nm_protocol == NETLINK_GENERIC)
data = print_genl_msg(msg, ofd, hdr, ops, &payloadlen);
if (payloadlen) {
fprintf(ofd, " [PAYLOAD] %d octets\n", payloadlen);
dump_hex(ofd, data, payloadlen, 0);
}
if (attrlen) {
struct nlattr *attrs;
int attrlen;
attrs = nlmsg_attrdata(hdr, ops->co_hdrsize);
attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize);
dump_attrs(ofd, attrs, attrlen, 0);
}
if (ops)
nl_cache_ops_put(ops);
}
/**
* Dump message in human readable format to file descriptor
* @arg msg Message to print
@ -869,56 +977,18 @@ void nl_msg_dump(struct nl_msg *msg, FILE *ofd)
struct nlmsghdr *hdr = nlmsg_hdr(msg);
fprintf(ofd,
"-------------------------- BEGIN NETLINK MESSAGE "
"---------------------------\n");
"-------------------------- BEGIN NETLINK MESSAGE ---------------------------\n");
fprintf(ofd, " [HEADER] %zu octets\n", sizeof(struct nlmsghdr));
fprintf(ofd, " [NETLINK HEADER] %zu octets\n", sizeof(struct nlmsghdr));
print_hdr(ofd, msg);
if (hdr->nlmsg_type == NLMSG_ERROR &&
hdr->nlmsg_len >= nlmsg_msg_size(sizeof(struct nlmsgerr))) {
struct nl_msg *errmsg;
struct nlmsgerr *err = nlmsg_data(hdr);
fprintf(ofd, " [ERRORMSG] %zu octets\n", sizeof(*err));
fprintf(ofd, " .error = %d \"%s\"\n", err->error,
strerror(-err->error));
fprintf(ofd, " [ORIGINAL MESSAGE] %zu octets\n", sizeof(*hdr));
errmsg = nlmsg_inherit(&err->msg);
print_hdr(ofd, errmsg);
nlmsg_free(errmsg);
} else if (nlmsg_len(hdr) > 0) {
struct nl_cache_ops *ops;
int payloadlen = nlmsg_len(hdr);
int attrlen = 0;
ops = nl_cache_ops_associate_safe(nlmsg_get_proto(msg),
hdr->nlmsg_type);
if (ops) {
attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize);
payloadlen -= attrlen;
}
fprintf(ofd, " [PAYLOAD] %d octets\n", payloadlen);
dump_hex(ofd, nlmsg_data(hdr), payloadlen, 0);
if (attrlen) {
struct nlattr *attrs;
int attrlen;
attrs = nlmsg_attrdata(hdr, ops->co_hdrsize);
attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize);
dump_attrs(ofd, attrs, attrlen, 0);
}
if (ops)
nl_cache_ops_put(ops);
}
if (hdr->nlmsg_type == NLMSG_ERROR)
dump_error_msg(msg, ofd);
else if (nlmsg_len(hdr) > 0)
print_msg(msg, ofd, hdr);
fprintf(ofd,
"--------------------------- END NETLINK MESSAGE "
"---------------------------\n");
"--------------------------- END NETLINK MESSAGE ---------------------------\n");
}
/** @} */

View File

@ -23,7 +23,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/ct.h>
@ -174,15 +174,28 @@ static int ct_parse_proto(struct nfnl_ct *ct, int repl, struct nlattr *attr)
if (tb[CTA_PROTO_DST_PORT])
nfnl_ct_set_dst_port(ct, repl,
ntohs(nla_get_u16(tb[CTA_PROTO_DST_PORT])));
if (tb[CTA_PROTO_ICMP_ID])
nfnl_ct_set_icmp_id(ct, repl,
ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
if (tb[CTA_PROTO_ICMP_TYPE])
nfnl_ct_set_icmp_type(ct, repl,
if (ct->ct_family == AF_INET) {
if (tb[CTA_PROTO_ICMP_ID])
nfnl_ct_set_icmp_id(ct, repl,
ntohs(nla_get_u16(tb[CTA_PROTO_ICMP_ID])));
if (tb[CTA_PROTO_ICMP_TYPE])
nfnl_ct_set_icmp_type(ct, repl,
nla_get_u8(tb[CTA_PROTO_ICMP_TYPE]));
if (tb[CTA_PROTO_ICMP_CODE])
nfnl_ct_set_icmp_code(ct, repl,
if (tb[CTA_PROTO_ICMP_CODE])
nfnl_ct_set_icmp_code(ct, repl,
nla_get_u8(tb[CTA_PROTO_ICMP_CODE]));
} else if (ct->ct_family == AF_INET6) {
if (tb[CTA_PROTO_ICMPV6_ID])
nfnl_ct_set_icmp_id(ct, repl,
ntohs(nla_get_u16(tb[CTA_PROTO_ICMPV6_ID])));
if (tb[CTA_PROTO_ICMPV6_TYPE])
nfnl_ct_set_icmp_type(ct, repl,
nla_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]));
if (tb[CTA_PROTO_ICMPV6_CODE])
nfnl_ct_set_icmp_code(ct, repl,
nla_get_u8(tb[CTA_PROTO_ICMPV6_CODE]));
}
return 0;
}
@ -426,17 +439,31 @@ static int nfnl_ct_build_tuple(struct nl_msg *msg, const struct nfnl_ct *ct,
NLA_PUT_U16(msg, CTA_PROTO_DST_PORT,
htons(nfnl_ct_get_dst_port(ct, repl)));
if (nfnl_ct_test_icmp_id(ct, repl))
NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
htons(nfnl_ct_get_icmp_id(ct, repl)));
if (family == AF_INET) {
if (nfnl_ct_test_icmp_id(ct, repl))
NLA_PUT_U16(msg, CTA_PROTO_ICMP_ID,
htons(nfnl_ct_get_icmp_id(ct, repl)));
if (nfnl_ct_test_icmp_type(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
nfnl_ct_get_icmp_type(ct, repl));
if (nfnl_ct_test_icmp_type(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMP_TYPE,
nfnl_ct_get_icmp_type(ct, repl));
if (nfnl_ct_test_icmp_code(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
nfnl_ct_get_icmp_code(ct, repl));
if (nfnl_ct_test_icmp_code(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMP_CODE,
nfnl_ct_get_icmp_code(ct, repl));
} else if (family == AF_INET6) {
if (nfnl_ct_test_icmp_id(ct, repl))
NLA_PUT_U16(msg, CTA_PROTO_ICMPV6_ID,
htons(nfnl_ct_get_icmp_id(ct, repl)));
if (nfnl_ct_test_icmp_type(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_TYPE,
nfnl_ct_get_icmp_type(ct, repl));
if (nfnl_ct_test_icmp_code(ct, repl))
NLA_PUT_U8(msg, CTA_PROTO_ICMPV6_CODE,
nfnl_ct_get_icmp_code(ct, repl));
}
nla_nest_end(msg, proto);

View File

@ -16,7 +16,7 @@
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/ct.h>

View File

@ -24,7 +24,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/exp.h>
@ -70,7 +70,7 @@ static struct nla_policy exp_proto_policy[CTA_PROTO_MAX+1] = {
};
static struct nla_policy exp_nat_policy[CTA_EXPECT_NAT_MAX+1] = {
[CTA_EXPECT_NAT_DIR] = { .type = NLA_U8 },
[CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 },
[CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED },
};
@ -195,7 +195,7 @@ static int exp_parse_nat(struct nfnl_exp *exp, struct nlattr *attr)
return err;
if (tb[CTA_EXPECT_NAT_DIR])
nfnl_exp_set_nat_dir(exp, nla_get_u8(tb[CTA_EXPECT_NAT_DIR]));
nfnl_exp_set_nat_dir(exp, nla_get_u32(tb[CTA_EXPECT_NAT_DIR]));
if (tb[CTA_EXPECT_NAT_TUPLE]) {
err = exp_parse_tuple(exp, NFNL_EXP_TUPLE_NAT, tb[CTA_EXPECT_NAT_TUPLE]);
@ -351,7 +351,11 @@ static int nfnl_exp_build_tuple(struct nl_msg *msg, const struct nfnl_exp *exp,
int type = exp_get_tuple_attr(cta);
tuple = nla_nest_start(msg, cta);
if (cta == CTA_EXPECT_NAT)
tuple = nla_nest_start(msg, CTA_EXPECT_NAT_TUPLE);
else
tuple = nla_nest_start(msg, cta);
if (!tuple)
goto nla_put_failure;
@ -416,11 +420,11 @@ static int nfnl_exp_build_nat(struct nl_msg *msg, const struct nfnl_exp *exp)
nat = nla_nest_start(msg, CTA_EXPECT_NAT);
if (nfnl_exp_test_nat_dir(exp)) {
NLA_PUT_U8(msg, CTA_EXPECT_NAT_DIR,
NLA_PUT_U32(msg, CTA_EXPECT_NAT_DIR,
nfnl_exp_get_nat_dir(exp));
}
if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT_TUPLE)) < 0)
if ((err = nfnl_exp_build_tuple(msg, exp, CTA_EXPECT_NAT)) < 0)
goto nla_put_failure;
nla_nest_end(msg, nat);

View File

@ -18,7 +18,7 @@
#include <linux/netfilter/nf_conntrack_common.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/exp.h>

View File

@ -21,7 +21,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_log.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/log.h>

View File

@ -22,7 +22,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_log.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/log_msg.h>

View File

@ -11,7 +11,7 @@
* Copyright (c) 2007 Secure Computing Corporation
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/netfilter.h>
#include <netlink/netfilter/log_msg.h>

View File

@ -12,7 +12,7 @@
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/log.h>

View File

@ -9,7 +9,7 @@
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/netfilter.h>
#include <linux/netfilter.h>

View File

@ -61,7 +61,7 @@
* @{
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netlink.h>
#include <netlink/netfilter/nfnl.h>

View File

@ -19,7 +19,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_queue.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue.h>

View File

@ -20,7 +20,7 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_queue.h>
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/attr.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue_msg.h>
@ -163,12 +163,14 @@ errout:
/** @} */
struct nl_msg *nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *msg)
static struct nl_msg *
__nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *msg,
uint8_t type)
{
struct nl_msg *nlmsg;
struct nfqnl_msg_verdict_hdr verdict;
nlmsg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, NFQNL_MSG_VERDICT, 0,
nlmsg = nfnlmsg_alloc_simple(NFNL_SUBSYS_QUEUE, type, 0,
nfnl_queue_msg_get_family(msg),
nfnl_queue_msg_get_group(msg));
if (nlmsg == NULL)
@ -191,6 +193,18 @@ nla_put_failure:
return NULL;
}
struct nl_msg *
nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *msg)
{
return __nfnl_queue_msg_build_verdict(msg, NFQNL_MSG_VERDICT);
}
struct nl_msg *
nfnl_queue_msg_build_verdict_batch(const struct nfnl_queue_msg *msg)
{
return __nfnl_queue_msg_build_verdict(msg, NFQNL_MSG_VERDICT_BATCH);
}
/**
* Send a message verdict/mark
* @arg nlh netlink messsage header
@ -214,6 +228,29 @@ int nfnl_queue_msg_send_verdict(struct nl_sock *nlh,
return wait_for_ack(nlh);
}
/**
* Send a message batched verdict/mark
* @arg nlh netlink messsage header
* @arg msg queue msg
* @return 0 on OK or error code
*/
int nfnl_queue_msg_send_verdict_batch(struct nl_sock *nlh,
const struct nfnl_queue_msg *msg)
{
struct nl_msg *nlmsg;
int err;
nlmsg = nfnl_queue_msg_build_verdict_batch(msg);
if (nlmsg == NULL)
return -NLE_NOMEM;
err = nl_send_auto_complete(nlh, nlmsg);
nlmsg_free(nlmsg);
if (err < 0)
return err;
return wait_for_ack(nlh);
}
/**
* Send a message verdict including the payload
* @arg nlh netlink messsage header

View File

@ -9,7 +9,7 @@
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/netfilter.h>
#include <netlink/netfilter/queue_msg.h>

View File

@ -16,7 +16,7 @@
* @{
*/
#include <netlink-local.h>
#include <netlink-private/netlink.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue.h>

Some files were not shown because too many files have changed in this diff Show More