Initial import
This commit is contained in:
commit
44d362409d
188 changed files with 44556 additions and 0 deletions
461
COPYING
Normal file
461
COPYING
Normal file
|
@ -0,0 +1,461 @@
|
|||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations
|
||||
below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it
|
||||
becomes a de-facto standard. To achieve this, non-free programs must
|
||||
be allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control
|
||||
compilation and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at least
|
||||
three years, to give the same user the materials specified in
|
||||
Subsection 6a, above, for a charge no more than the cost of
|
||||
performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply, and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License
|
||||
may add an explicit geographical distribution limitation excluding those
|
||||
countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
333
ChangeLog
Normal file
333
ChangeLog
Normal file
|
@ -0,0 +1,333 @@
|
|||
Summary of Changes from 1.0-pre6 to HEAD
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Generic netlink support
|
||||
o Route Addition/Deletion
|
||||
o Added nl_cache_subset()
|
||||
o Have nl_object_clone() make real clones without
|
||||
sharing any data.
|
||||
o Remove old nl_object_alloc() not based on a object
|
||||
operations to avoid bugs due to missing init.
|
||||
o Added nl-list-caches utility
|
||||
o Removed nlmsg_build_no_hdr(), duplicate
|
||||
o Reworked message interface
|
||||
o Fixed nlmsg_put() and genlmsg_put() to correctly reserve
|
||||
tail room for user specific headers.
|
||||
o Added nl_cache_move()
|
||||
o Renamed nl_cache_delete() to nl_cache_remove() (no API break)
|
||||
o Fixed reference counting while objects stay in caches.
|
||||
o Object marking
|
||||
o Moved attribute mask for objects into generic structure
|
||||
o nl-list-caches: List available dump procedures
|
||||
o Use PAGE_SIZE as initial buffer size when reading from
|
||||
netlink socket
|
||||
o Double buffer size when recv() returns MSG_TRUNC
|
||||
o Replaced filter object operation with new compare operation
|
||||
capable of listing differences between two objects
|
||||
o Added nl_object_identical() to check if two objects are
|
||||
identical from a uniqueness point of view
|
||||
o Added nl_object_diff() returning a bitmask of differences in
|
||||
attributes
|
||||
o Added nl_object_attr_list() generating a list of attribute
|
||||
name the object has assigned
|
||||
o Cache updates based on event notifications, code based on
|
||||
Patrick McHardy's patches
|
||||
o Cache Manager
|
||||
o Added NL_AUTO_PID, NL_AUTO_SEQ for convenience
|
||||
o Disable MSG_PEEK by default and provide nl_socket_enable_msg_peek()
|
||||
o Fixed nl_recvmsgs() to return 0 when interrupted via NL_STOP or
|
||||
NL_SKIP
|
||||
o Fixed nl_recvmsgs() to stop reading after parsing if not in the
|
||||
middle of a multipart message.
|
||||
o Fixed nl_recvmsgs() to not stop after receving an ACK
|
||||
o Fixed nl_recvmsgs() to not blindly discard remaining messages
|
||||
if a NLMSG_DONE message is received.
|
||||
|
||||
Petr Gotthard <petr.gotthard@siemens.com>
|
||||
Siemens AG Oesterreich
|
||||
o Fix u32 to properly handle multiple keys
|
||||
o rtnl_htb_set_(r|c)buffer()
|
||||
o Fixed MTU handling in HTB class, problem pointed out
|
||||
by Edouard Thuleau
|
||||
|
||||
Zilvinas Valinskas <zilvinas@wilibox.com>
|
||||
o Fix wrong msg_namelen in nl_recv()
|
||||
o Fix memory leak in flnl_request_put()
|
||||
|
||||
Helmut Schaa <hschaa@suse.de>
|
||||
o Fix for using libnl from within C++
|
||||
|
||||
Patrick McHardy <kaber@trash.net>
|
||||
o *_alloc_cache(): Only refill cache if handle is provided
|
||||
|
||||
James Oakley <jfunk@funktronics.ca>
|
||||
o Fix rtnl_link_set_arptype() typo
|
||||
|
||||
Philip Craig <philipc@snapgear.com>
|
||||
o Change address family type from char to int
|
||||
o Fix the error handling when the build fails.
|
||||
o add nl_cache_mngr_get_fd()
|
||||
o add netfilter support
|
||||
o add netfilter conntrack support
|
||||
o add netfilter log support
|
||||
|
||||
Summary of Changes from 1.0-pre5 to 1.0-pre6
|
||||
================================================
|
||||
Christopher Aillon <caillon@redhat.com>
|
||||
o Use $(libdir) instead of $(prefix)/lib for 64bit awesomeness.
|
||||
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Extend nl_msg to include source address, destination address
|
||||
and the protocol being used.
|
||||
o Make nl_send*() take a nl_msg instead of a nlmsghdr (API BREAK)
|
||||
o Change callbacks to take a nl_msg instead of source address
|
||||
and nlmsghdr (API BREAK)
|
||||
o caches must specify the protocol they're hooked up from now on
|
||||
if they intend to be associated with message types.
|
||||
o cache_mngt_associate now takes the protocol besides the message
|
||||
type to allow for multiple protocols to be supported (API BREAK)
|
||||
o overwrite destination address in nl_send() when specified in the
|
||||
message itself, allows for unbound addressing.
|
||||
o Support for netlink based fib_lookup()
|
||||
o Documentation fixes
|
||||
o Fix double nlmsg_free() in nl_recvmsgs() while receiving
|
||||
a multipart message and the read was interrupted.
|
||||
o Change cache operations to store names for message types.
|
||||
o Provide interface to convert message type to character string.
|
||||
o Add dp_dump_msgtype to prefix each dumped element with a
|
||||
pretty printed message type.
|
||||
o netlink fib lookup support
|
||||
o nl_recvmsgs() debugging
|
||||
o use nl_cachemngt_type2name() when pretty printing netlink header
|
||||
o Routing protocol translations.
|
||||
o Routing metric translations.
|
||||
o Revised route dumping
|
||||
o Nexthop flag translations.
|
||||
o Add support for IFF_DORMANT
|
||||
|
||||
Petr Gotthard <petr.gotthard@siemens.com>
|
||||
Siemens AG Oesterreich
|
||||
o Fix access to obj after freeing it
|
||||
o Fix u32 selector access after realloc()
|
||||
o Fix missing out-of-memory error handling in various places
|
||||
o Enhance nl-monitor to have group selection selectable and
|
||||
demonstrate usage of select()
|
||||
o Don't ignore IFF_RUNNING any longer
|
||||
o fw classifier support
|
||||
|
||||
Patrick McHardy <kaber@trash.net>
|
||||
o Fix conflicting types for __u64
|
||||
o Fix printf format string warnings
|
||||
o Fix object cloning
|
||||
o Deal with structure padding in nl_object_clone
|
||||
o Fix nl_addr leak
|
||||
o Set ce_msgtype in all parsed objects
|
||||
o Fix addr flag filter
|
||||
o Fix RTNLGRP definitions (was based on broken kernel version)
|
||||
o Export nl_get_errno()
|
||||
o Add function to get/set peer pid
|
||||
o Add IFF_LOWER_UP
|
||||
o Add/export some missing accessor functions
|
||||
o print /0 prefix in nl_addr2str()
|
||||
o Fix invalid free in nl_addr_parse for AF_UNSPEC addresses
|
||||
o Use __str2flags instead of __str2type in rtnl_link_str2flags()
|
||||
o Make sure object and filter types match in nl_object_match()
|
||||
o Add support for credential passing over netlink sockets (API BREAK)
|
||||
o Add support for custom dump callbacks
|
||||
o Add NL_DUMP_ENV format
|
||||
|
||||
Michael Biebl <biebl@teco.edu>
|
||||
"Alex V. Myltsev" <avm@altlinux.ru>
|
||||
o Makefile fixes
|
||||
|
||||
|
||||
Summary of Changes from 1.0-pre4 to 1.0-pre5
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Use minimized local copies for <linux/if.h>, <linux/if_arp.h>,
|
||||
and <linux/if_ether.h> to avoid compile troubles with
|
||||
applications including <net/if*.h>
|
||||
Reported by Christopher Aillon.
|
||||
|
||||
Summary of Changes from 1.0-pre3 to 1.0-pre4
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Fix wrong rtnl_addr_set_prefixlen() external declaration,
|
||||
reported by Dan Williams.
|
||||
o Fix nl_addr_parse() to not change the original string
|
||||
for prefixes.
|
||||
o Do not build documentation per default, but have the user
|
||||
issue 'make gendoc'
|
||||
o Assume neighbours to be permanent, set NUD_PERMANENT if not
|
||||
specified otherwise.
|
||||
|
||||
Summary of Changes from 1.0-pre2 to 1.0-pre3
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Fix SFQ parser to allocate qdisc options.
|
||||
o Fix rule statistics dumping to not call itself.
|
||||
o Complete Netem qdisc interface.
|
||||
o Add rtnl_*_put() and rtnl_*_free() to increase readability.
|
||||
o Cleanup of nl-* tools
|
||||
o Fix inclusion guards of route/neightbl.h
|
||||
o Fix nl_connect() to only modify rx/tx socket buffers if not
|
||||
already modified by the user.
|
||||
o Fix wrong nl_handle_alloc() prototype.
|
||||
o Fix typo in route/addr.c causing label to be marked as
|
||||
local address.
|
||||
o Use ~0UL as default prefix length instead of 0.
|
||||
o Fix neighbour message parser to correctly store core.
|
||||
attributes and provide them again.
|
||||
o Fix neighbour message parser to correctly guess address family.
|
||||
to make it compatible with nl_addr_parse() and ether llc
|
||||
addresses.
|
||||
o Add rtnl_route_table2str(), rtnl_route_str2table().
|
||||
o Add nl_cache_nitems_filter() to find out if a filter produces
|
||||
any matches.
|
||||
o Remove rtnl_rule_set_(dst|src)_str() (obsolete).
|
||||
o Remove scope and protocol field of routing rule.
|
||||
o Complete routing rules module.
|
||||
o Move realms translations from route to rtnl module.
|
||||
|
||||
Summary of Changes from 1.0-pre1 to 1.0-pre2
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o More API documentation
|
||||
o Added flags argument to rtnl_addr_(add|build_add_request)().
|
||||
o Added rtnl_addr_(set|get)_multicast().
|
||||
o Moved scope translations routines from route/route.c to
|
||||
route/rtnl.c, required by other modules as well.
|
||||
o Removed old rtattr bits from rtnetlink-kernel.h
|
||||
o Customized libnl.css for doxygen documentation
|
||||
o Removed non-reentrant translation routines, only bloating
|
||||
the code and too risky.
|
||||
o Fixed wrong version number from 1.0-pre1.
|
||||
o Reenabled unfinished policer module.
|
||||
o Reworked TBF module, automatic caluclation of transmit times,
|
||||
limit setable via latency, automatic cell size calculation,
|
||||
options TLV generation. (untested)
|
||||
o Renamed nl_xmittime() to rtnl_tc_calc_txtime().
|
||||
o Renamde nl_build_rtable() to rtnl_tc_build_rate_table()
|
||||
|
||||
Petr Gotthard <petr.gotthard@siemens.com>,
|
||||
Siemens AG Oesterreich
|
||||
o Fix symlinks to libnl library files to be moveable
|
||||
o Fix extern struct prototypes meant to be static.
|
||||
o Add empty install target to src/Makefile
|
||||
|
||||
Simon Stelling <blubb@gentoo.org>
|
||||
o Use LIBDIR instead of $(prefix)/lib for users to alllow librariers
|
||||
into $(prefix)/lib64.
|
||||
|
||||
Summary of Changes from 0.5.0 to 1.0-pre1
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o Uncountable number of changes, rewrite of certain modules,
|
||||
several major API breakages
|
||||
|
||||
Petr Gotthard <petr.gotthard@siemens.com>,
|
||||
Siemens AG Oesterreich
|
||||
o added class_build, rtnl_class_build_add_request, rtnl_class_add
|
||||
o added HTB (Hierachical Token Bucket) class support
|
||||
o added nl_xmittime, nl_build_rtable
|
||||
o added nl_data_append to realloc a nl_data structure
|
||||
o added rtnl_rcopy_ratespec as reverse to rtnl_copy_ratespec
|
||||
o fixed byte order conversion of rtnl_filter.protocol
|
||||
o SuSE and Fedora Linux compile fixes
|
||||
o fixed u32 classifier support
|
||||
o added rtnl_u32_set_handle, rtnl_u32_set_classid, rtnl_u32_set_flags
|
||||
and several rtnl_u32_add_key_... operations to u32 classifier
|
||||
|
||||
Summary of Changes from 0.4.4 to 0.5.0
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
o API documentation
|
||||
o nl_cache_filter to manually filter on a object
|
||||
o partial routing support
|
||||
o routing rules support
|
||||
o Propely set address family when setting addresses
|
||||
o debug flag and some rare messages, more to come
|
||||
o make error mesage verboseness configureable
|
||||
o tc fixes to wait for ack
|
||||
o cleanup and adaption of address code to latest internal API
|
||||
o various cleanups
|
||||
o dozens of API breakages (better now than later)
|
||||
|
||||
Daniel Hottinger <hotti@hotti.ch>
|
||||
o arch 64bit printf length modifier fixes
|
||||
|
||||
Baruch Even <baruch@ev-en.org>,
|
||||
Mediatrix Telecom, inc. <ericb@mediatrix.com>
|
||||
o address support
|
||||
|
||||
Summary of changes from 0.4.3 to 0.4.4
|
||||
================================================
|
||||
Thomas Graf <tgraf@suug.ch>:
|
||||
o overall cleanups for better code quality
|
||||
o replace dump_(brief|full|with_stats) ops with
|
||||
dump[NL_DUMP_MAX] array to allow further additions without
|
||||
breaking the ABI.
|
||||
o add of send_ack callback, called whenever when oppenent
|
||||
asks for an ACK.
|
||||
o make nl_parse_rtattr initialize the tb buffer like in the
|
||||
kernel, caller must no longer take care of it.
|
||||
o remove nl_addrnattr (obsolete)
|
||||
o fixed nl_msg_append_raw to correctly calculate length
|
||||
for raw data not aligned to NLMSG_ALIGN
|
||||
o fix memory leak in nl_recv in case of errors
|
||||
o correctly check sequence numbers if more than one message
|
||||
was sent out before the answer is being received.
|
||||
o add workaround for buggy netlink applications not properly
|
||||
setting NLM_F_MULTI.
|
||||
|
||||
Summary of changes from 0.4.2 to 0.4.3
|
||||
================================================
|
||||
|
||||
Thomas Graf <tgraf@suug.ch>:
|
||||
o use parser_param in nl_cache_parse
|
||||
o EGP: dump nfilters attribute
|
||||
o allow retrieving of filters attached to classes via
|
||||
FILTER_CACHE_PARENT(C) cache argument
|
||||
o filter message building API
|
||||
|
||||
Summary of changes from 0.4.1 to 0.4.2
|
||||
================================================
|
||||
|
||||
Baruch Even <baruch@ev-en.org>:
|
||||
o memory leak fix in nl_parse_rtattr
|
||||
o reset padding to 0 when appending raw data to a nl_msg
|
||||
o avoid overwriting nlmsg ptr when buffer extending fails
|
||||
o typo fixes
|
||||
o create symlinks libnl.so.0 and libnl.so
|
||||
|
||||
Thomas Graf <tgraf@suug.ch>:
|
||||
o EGP classifier support
|
||||
o avoid null pointer in printf call
|
||||
o added nl_cache_parse to put nl_msg's into a cache
|
||||
o added rtnl_filter_build to build a nl_msg filter message
|
||||
o correctly install header files
|
||||
o nl_msg_payload/nl_msg_payloadlen to access nl_msg payload
|
||||
o nl_parse_nested macro to simplify nested TLV parsing
|
||||
o NL_ERROR_ASSERT compile flag to assert(0) on errors
|
||||
o rta alignment fix in nl_msg_append_tlv
|
||||
o added nl_msg_parse_rtattr as shortcut for nl_parse_rtattr
|
||||
for nl_msg API
|
||||
o added nl_parse_nested for nested TLVs
|
||||
o added RTA_ARRAY_ELEMS macro to calculate array length
|
||||
for array TLVs
|
||||
o added nl_wait_for_ack to wait for the next ack
|
||||
o added rtnl_link_build_change_request(...)
|
||||
o added rtnl_neigh_build_*_request
|
||||
o converted neighbour code to use nl_wait_for_ack
|
||||
o cb_recvmsgs_ow callback to overwrite internal calls to
|
||||
nl_recvmsgs_def
|
||||
o cb_seq_check callback to overwrite default sequence checking
|
||||
o added nl_parser_param as argument for message parsers including
|
||||
a callback to be called upon successful parsing of a message.
|
||||
Removes the requirement of having all parsed messages to be added
|
||||
to a cache.
|
||||
o added cb_recv_ow and nl_send_ow callbacks to overwrite internal
|
||||
calls to nl_recv and nl_send.
|
||||
|
||||
Jamal Hadi Salim <hadi@cyberus.ca>
|
||||
o Linux 2.4 compile fixes
|
64
Makefile
Normal file
64
Makefile
Normal file
|
@ -0,0 +1,64 @@
|
|||
#
|
||||
# Makefile
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
ifeq ($(shell [ ! -r Makefile.opts ] && echo 1),)
|
||||
include Makefile.opts
|
||||
endif
|
||||
|
||||
SUBDIRS := lib include doc src tests
|
||||
.PHONY: all clean distclean install gendoc $(SUBDIRS)
|
||||
|
||||
all: Makefile.opts
|
||||
@for dir in $(SUBDIRS); do \
|
||||
echo "Entering $$dir" && $(MAKE) -C $$dir || exit $$?; \
|
||||
done
|
||||
|
||||
clean: Makefile.opts
|
||||
rm -f cscope.*
|
||||
@for dir in $(SUBDIRS); do \
|
||||
echo "Entering $$dir" && $(MAKE) -C $$dir clean || exit $$?; \
|
||||
done
|
||||
|
||||
distclean: clean
|
||||
@$(RM) -rf Makefile.opts autom4te.cache config.log config.status
|
||||
@for dir in $(SUBDIRS); do \
|
||||
echo "Entering $$dir" && $(MAKE) -C $$dir distclean || exit $$?; \
|
||||
done
|
||||
|
||||
install: Makefile.opts
|
||||
@for dir in $(SUBDIRS); do \
|
||||
echo "Entering $$dir" && cd $$dir && $(MAKE) install && cd ..; \
|
||||
done
|
||||
mkdir -p $(DESTDIR)$(libdir)/pkgconfig/
|
||||
install -m 0644 libnl-1.pc $(DESTDIR)$(libdir)/pkgconfig/
|
||||
|
||||
gendoc:
|
||||
$(MAKE) -C doc gendoc
|
||||
|
||||
show: Makefile.opts
|
||||
@echo "CC: $(CC)"
|
||||
@echo "RM: $(RM)"
|
||||
@echo "CFLAGS: $(CFLAGS)"
|
||||
@echo "DEPFLAGS: $(DEPFLAGS)"
|
||||
@echo "LDFLAGS: $(LDFLAGS)"
|
||||
@echo "DESTDIR: $(DESTDIR)"
|
||||
@echo "prefix: $(prefix)"
|
||||
@echo "libdir: $(libdir)"
|
||||
@echo "includedir: $(includedir)"
|
||||
|
||||
cscope:
|
||||
cscope -b -q -R -Iinclude -slib -ssrc
|
||||
|
||||
|
||||
$(SUBDIRS):
|
||||
cd $@ && $(MAKE)
|
||||
|
||||
-include Makefile.rules
|
39
Makefile.opts.in
Normal file
39
Makefile.opts.in
Normal file
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Makefile.opts.in
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
CC := @CC@
|
||||
CFLAGS := @CFLAGS@
|
||||
LDFLAGS := @LDFLAGS@
|
||||
CPPFLAGS := @CPPFLAGS@
|
||||
PACKAGE_NAME := @PACKAGE_NAME@
|
||||
PACKAGE_VERSION := @PACKAGE_VERSION@
|
||||
|
||||
LIBNL_LIB := @LIBNL_LIB@
|
||||
|
||||
prefix := @prefix@
|
||||
exec_prefix := @exec_prefix@
|
||||
libdir := @libdir@
|
||||
includedir := @includedir@
|
||||
mandir := @mandir@
|
||||
sysconfdir := @sysconfdir@
|
||||
|
||||
AR := ar
|
||||
RM := rm
|
||||
LN := ln
|
||||
|
||||
DEPFLAGS += -M -I../include/ -I. $(CPPFLAGS)
|
||||
CFLAGS += -g -I./include -I../include -I. $(CPPFLAGS) -D_GNU_SOURCE
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
ifeq ($(CC),gcc)
|
||||
CFLAGS += -Wall -ggdb
|
||||
endif
|
||||
|
37
Makefile.rules
Normal file
37
Makefile.rules
Normal file
|
@ -0,0 +1,37 @@
|
|||
#
|
||||
# Makefile.rules
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .d .c
|
||||
|
||||
%.o: %.c
|
||||
@echo " CC $<"; \
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
%.d: %.c
|
||||
@echo " DEP $<"; \
|
||||
$(CC) $(DEPFLAGS) $< > $@.tmp; \
|
||||
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.tmp > $@; \
|
||||
rm -f $@.tmp
|
||||
|
||||
Makefile.opts:
|
||||
@echo "***"
|
||||
@echo "*** No configuration found, please run ./configure"
|
||||
@echo "***"
|
||||
@exit 1
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),distclean)
|
||||
ifneq ($(DEPS),)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
endif
|
||||
endif
|
831
aclocal.m4
vendored
Normal file
831
aclocal.m4
vendored
Normal file
|
@ -0,0 +1,831 @@
|
|||
dnl aclocal.m4 generated automatically by aclocal 1.4-p6
|
||||
|
||||
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
dnl PARTICULAR PURPOSE.
|
||||
|
||||
# lib-prefix.m4 serial 4 (gettext-0.14.2)
|
||||
dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
|
||||
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
|
||||
dnl require excessive bracketing.
|
||||
ifdef([AC_HELP_STRING],
|
||||
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
|
||||
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
|
||||
|
||||
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
|
||||
dnl to access previously installed libraries. The basic assumption is that
|
||||
dnl a user will want packages to use other packages he previously installed
|
||||
dnl with the same --prefix option.
|
||||
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
|
||||
dnl libraries, but is otherwise very convenient.
|
||||
AC_DEFUN([AC_LIB_PREFIX],
|
||||
[
|
||||
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
dnl By default, look in $includedir and $libdir.
|
||||
use_additional=yes
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
AC_LIB_ARG_WITH([lib-prefix],
|
||||
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
|
||||
--without-lib-prefix don't search for libraries in includedir and libdir],
|
||||
[
|
||||
if test "X$withval" = "Xno"; then
|
||||
use_additional=no
|
||||
else
|
||||
if test "X$withval" = "X"; then
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
else
|
||||
additional_includedir="$withval/include"
|
||||
additional_libdir="$withval/lib"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
if test $use_additional = yes; then
|
||||
dnl Potentially add $additional_includedir to $CPPFLAGS.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/include,
|
||||
dnl 2. if it's already present in $CPPFLAGS,
|
||||
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_includedir" != "X/usr/include"; then
|
||||
haveit=
|
||||
for x in $CPPFLAGS; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-I$additional_includedir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test "X$additional_includedir" = "X/usr/local/include"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
dnl Really add $additional_includedir to $CPPFLAGS.
|
||||
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Potentially add $additional_libdir to $LDFLAGS.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/lib,
|
||||
dnl 2. if it's already present in $LDFLAGS,
|
||||
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_libdir" != "X/usr/lib"; then
|
||||
haveit=
|
||||
for x in $LDFLAGS; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test "X$additional_libdir" = "X/usr/local/lib"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux*) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LDFLAGS.
|
||||
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
|
||||
dnl acl_final_exec_prefix, containing the values to which $prefix and
|
||||
dnl $exec_prefix will expand at the end of the configure script.
|
||||
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
|
||||
[
|
||||
dnl Unfortunately, prefix and exec_prefix get only finally determined
|
||||
dnl at the end of configure.
|
||||
if test "X$prefix" = "XNONE"; then
|
||||
acl_final_prefix="$ac_default_prefix"
|
||||
else
|
||||
acl_final_prefix="$prefix"
|
||||
fi
|
||||
if test "X$exec_prefix" = "XNONE"; then
|
||||
acl_final_exec_prefix='${prefix}'
|
||||
else
|
||||
acl_final_exec_prefix="$exec_prefix"
|
||||
fi
|
||||
acl_save_prefix="$prefix"
|
||||
prefix="$acl_final_prefix"
|
||||
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
|
||||
prefix="$acl_save_prefix"
|
||||
])
|
||||
|
||||
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
|
||||
dnl variables prefix and exec_prefix bound to the values they will have
|
||||
dnl at the end of the configure script.
|
||||
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
|
||||
[
|
||||
acl_save_prefix="$prefix"
|
||||
prefix="$acl_final_prefix"
|
||||
acl_save_exec_prefix="$exec_prefix"
|
||||
exec_prefix="$acl_final_exec_prefix"
|
||||
$1
|
||||
exec_prefix="$acl_save_exec_prefix"
|
||||
prefix="$acl_save_prefix"
|
||||
])
|
||||
|
||||
# lib-link.m4 serial 6 (gettext-0.14.3)
|
||||
dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl From Bruno Haible.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
|
||||
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
|
||||
dnl the libraries corresponding to explicit and implicit dependencies.
|
||||
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
|
||||
dnl augments the CPPFLAGS variable.
|
||||
AC_DEFUN([AC_LIB_LINKFLAGS],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
define([Name],[translit([$1],[./-], [___])])
|
||||
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
|
||||
AC_LIB_LINKFLAGS_BODY([$1], [$2])
|
||||
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
|
||||
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
|
||||
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
|
||||
])
|
||||
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
|
||||
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
|
||||
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
|
||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
|
||||
AC_SUBST([LIB]NAME)
|
||||
AC_SUBST([LTLIB]NAME)
|
||||
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
|
||||
dnl results of this search when this library appears as a dependency.
|
||||
HAVE_LIB[]NAME=yes
|
||||
undefine([Name])
|
||||
undefine([NAME])
|
||||
])
|
||||
|
||||
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
|
||||
dnl searches for libname and the libraries corresponding to explicit and
|
||||
dnl implicit dependencies, together with the specified include files and
|
||||
dnl the ability to compile and link the specified testcode. If found, it
|
||||
dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
|
||||
dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
|
||||
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
|
||||
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
|
||||
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
|
||||
[
|
||||
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
|
||||
AC_REQUIRE([AC_LIB_RPATH])
|
||||
define([Name],[translit([$1],[./-], [___])])
|
||||
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
|
||||
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
|
||||
dnl accordingly.
|
||||
AC_LIB_LINKFLAGS_BODY([$1], [$2])
|
||||
|
||||
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
|
||||
dnl because if the user has installed lib[]Name and not disabled its use
|
||||
dnl via --without-lib[]Name-prefix, he wants to use it.
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
|
||||
|
||||
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
|
||||
ac_save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $LIB[]NAME"
|
||||
AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
|
||||
LIBS="$ac_save_LIBS"
|
||||
])
|
||||
if test "$ac_cv_lib[]Name" = yes; then
|
||||
HAVE_LIB[]NAME=yes
|
||||
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
|
||||
AC_MSG_CHECKING([how to link with lib[]$1])
|
||||
AC_MSG_RESULT([$LIB[]NAME])
|
||||
else
|
||||
HAVE_LIB[]NAME=no
|
||||
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
|
||||
dnl $INC[]NAME either.
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIB[]NAME=
|
||||
LTLIB[]NAME=
|
||||
fi
|
||||
AC_SUBST([HAVE_LIB]NAME)
|
||||
AC_SUBST([LIB]NAME)
|
||||
AC_SUBST([LTLIB]NAME)
|
||||
undefine([Name])
|
||||
undefine([NAME])
|
||||
])
|
||||
|
||||
dnl Determine the platform dependent parameters needed to use rpath:
|
||||
dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator,
|
||||
dnl hardcode_direct, hardcode_minus_L.
|
||||
AC_DEFUN([AC_LIB_RPATH],
|
||||
[
|
||||
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
|
||||
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
|
||||
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
|
||||
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
|
||||
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
|
||||
AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
|
||||
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
|
||||
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
|
||||
. ./conftest.sh
|
||||
rm -f ./conftest.sh
|
||||
acl_cv_rpath=done
|
||||
])
|
||||
wl="$acl_cv_wl"
|
||||
libext="$acl_cv_libext"
|
||||
shlibext="$acl_cv_shlibext"
|
||||
hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
|
||||
hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
|
||||
hardcode_direct="$acl_cv_hardcode_direct"
|
||||
hardcode_minus_L="$acl_cv_hardcode_minus_L"
|
||||
dnl Determine whether the user wants rpath handling at all.
|
||||
AC_ARG_ENABLE(rpath,
|
||||
[ --disable-rpath do not hardcode runtime library paths],
|
||||
:, enable_rpath=yes)
|
||||
])
|
||||
|
||||
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
|
||||
dnl the libraries corresponding to explicit and implicit dependencies.
|
||||
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
|
||||
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
|
||||
[
|
||||
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
|
||||
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
|
||||
dnl By default, look in $includedir and $libdir.
|
||||
use_additional=yes
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
AC_LIB_ARG_WITH([lib$1-prefix],
|
||||
[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
|
||||
--without-lib$1-prefix don't search for lib$1 in includedir and libdir],
|
||||
[
|
||||
if test "X$withval" = "Xno"; then
|
||||
use_additional=no
|
||||
else
|
||||
if test "X$withval" = "X"; then
|
||||
AC_LIB_WITH_FINAL_PREFIX([
|
||||
eval additional_includedir=\"$includedir\"
|
||||
eval additional_libdir=\"$libdir\"
|
||||
])
|
||||
else
|
||||
additional_includedir="$withval/include"
|
||||
additional_libdir="$withval/lib"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
dnl Search the library and its dependencies in $additional_libdir and
|
||||
dnl $LDFLAGS. Using breadth-first-seach.
|
||||
LIB[]NAME=
|
||||
LTLIB[]NAME=
|
||||
INC[]NAME=
|
||||
rpathdirs=
|
||||
ltrpathdirs=
|
||||
names_already_handled=
|
||||
names_next_round='$1 $2'
|
||||
while test -n "$names_next_round"; do
|
||||
names_this_round="$names_next_round"
|
||||
names_next_round=
|
||||
for name in $names_this_round; do
|
||||
already_handled=
|
||||
for n in $names_already_handled; do
|
||||
if test "$n" = "$name"; then
|
||||
already_handled=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$already_handled"; then
|
||||
names_already_handled="$names_already_handled $name"
|
||||
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
|
||||
dnl or AC_LIB_HAVE_LINKFLAGS call.
|
||||
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
|
||||
eval value=\"\$HAVE_LIB$uppername\"
|
||||
if test -n "$value"; then
|
||||
if test "$value" = yes; then
|
||||
eval value=\"\$LIB$uppername\"
|
||||
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
|
||||
eval value=\"\$LTLIB$uppername\"
|
||||
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
|
||||
else
|
||||
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
|
||||
dnl that this library doesn't exist. So just drop it.
|
||||
:
|
||||
fi
|
||||
else
|
||||
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
|
||||
dnl and the already constructed $LIBNAME/$LTLIBNAME.
|
||||
found_dir=
|
||||
found_la=
|
||||
found_so=
|
||||
found_a=
|
||||
if test $use_additional = yes; then
|
||||
if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then
|
||||
found_dir="$additional_libdir"
|
||||
found_so="$additional_libdir/lib$name.$shlibext"
|
||||
if test -f "$additional_libdir/lib$name.la"; then
|
||||
found_la="$additional_libdir/lib$name.la"
|
||||
fi
|
||||
else
|
||||
if test -f "$additional_libdir/lib$name.$libext"; then
|
||||
found_dir="$additional_libdir"
|
||||
found_a="$additional_libdir/lib$name.$libext"
|
||||
if test -f "$additional_libdir/lib$name.la"; then
|
||||
found_la="$additional_libdir/lib$name.la"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "X$found_dir" = "X"; then
|
||||
for x in $LDFLAGS $LTLIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
case "$x" in
|
||||
-L*)
|
||||
dir=`echo "X$x" | sed -e 's/^X-L//'`
|
||||
if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then
|
||||
found_dir="$dir"
|
||||
found_so="$dir/lib$name.$shlibext"
|
||||
if test -f "$dir/lib$name.la"; then
|
||||
found_la="$dir/lib$name.la"
|
||||
fi
|
||||
else
|
||||
if test -f "$dir/lib$name.$libext"; then
|
||||
found_dir="$dir"
|
||||
found_a="$dir/lib$name.$libext"
|
||||
if test -f "$dir/lib$name.la"; then
|
||||
found_la="$dir/lib$name.la"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
if test "X$found_dir" != "X"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test "X$found_dir" != "X"; then
|
||||
dnl Found the library.
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
|
||||
if test "X$found_so" != "X"; then
|
||||
dnl Linking with a shared library. We attempt to hardcode its
|
||||
dnl directory into the executable's runpath, unless it's the
|
||||
dnl standard /usr/lib.
|
||||
if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then
|
||||
dnl No hardcoding is needed.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
dnl Use an explicit option to hardcode DIR into the resulting
|
||||
dnl binary.
|
||||
dnl Potentially add DIR to ltrpathdirs.
|
||||
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
|
||||
haveit=
|
||||
for x in $ltrpathdirs; do
|
||||
if test "X$x" = "X$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
ltrpathdirs="$ltrpathdirs $found_dir"
|
||||
fi
|
||||
dnl The hardcoding into $LIBNAME is system dependent.
|
||||
if test "$hardcode_direct" = yes; then
|
||||
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
|
||||
dnl resulting binary.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then
|
||||
dnl Use an explicit option to hardcode DIR into the resulting
|
||||
dnl binary.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
dnl Potentially add DIR to rpathdirs.
|
||||
dnl The rpathdirs will be appended to $LIBNAME at the end.
|
||||
haveit=
|
||||
for x in $rpathdirs; do
|
||||
if test "X$x" = "X$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
rpathdirs="$rpathdirs $found_dir"
|
||||
fi
|
||||
else
|
||||
dnl Rely on "-L$found_dir".
|
||||
dnl But don't add it if it's already contained in the LDFLAGS
|
||||
dnl or the already constructed $LIBNAME
|
||||
haveit=
|
||||
for x in $LDFLAGS $LIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$found_dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
|
||||
fi
|
||||
if test "$hardcode_minus_L" != no; then
|
||||
dnl FIXME: Not sure whether we should use
|
||||
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
|
||||
dnl here.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
|
||||
else
|
||||
dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH
|
||||
dnl here, because this doesn't fit in flags passed to the
|
||||
dnl compiler. So give up. No hardcoding. This affects only
|
||||
dnl very old systems.
|
||||
dnl FIXME: Not sure whether we should use
|
||||
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
|
||||
dnl here.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if test "X$found_a" != "X"; then
|
||||
dnl Linking with a static library.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
|
||||
else
|
||||
dnl We shouldn't come here, but anyway it's good to have a
|
||||
dnl fallback.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
|
||||
fi
|
||||
fi
|
||||
dnl Assume the include files are nearby.
|
||||
additional_includedir=
|
||||
case "$found_dir" in
|
||||
*/lib | */lib/)
|
||||
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'`
|
||||
additional_includedir="$basedir/include"
|
||||
;;
|
||||
esac
|
||||
if test "X$additional_includedir" != "X"; then
|
||||
dnl Potentially add $additional_includedir to $INCNAME.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/include,
|
||||
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
|
||||
dnl 3. if it's already present in $CPPFLAGS or the already
|
||||
dnl constructed $INCNAME,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_includedir" != "X/usr/include"; then
|
||||
haveit=
|
||||
if test "X$additional_includedir" = "X/usr/local/include"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
for x in $CPPFLAGS $INC[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-I$additional_includedir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_includedir"; then
|
||||
dnl Really add $additional_includedir to $INCNAME.
|
||||
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl Look for dependencies.
|
||||
if test -n "$found_la"; then
|
||||
dnl Read the .la file. It defines the variables
|
||||
dnl dlname, library_names, old_library, dependency_libs, current,
|
||||
dnl age, revision, installed, dlopen, dlpreopen, libdir.
|
||||
save_libdir="$libdir"
|
||||
case "$found_la" in
|
||||
*/* | *\\*) . "$found_la" ;;
|
||||
*) . "./$found_la" ;;
|
||||
esac
|
||||
libdir="$save_libdir"
|
||||
dnl We use only dependency_libs.
|
||||
for dep in $dependency_libs; do
|
||||
case "$dep" in
|
||||
-L*)
|
||||
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
|
||||
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
|
||||
dnl But don't add it
|
||||
dnl 1. if it's the standard /usr/lib,
|
||||
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
|
||||
dnl 3. if it's already present in $LDFLAGS or the already
|
||||
dnl constructed $LIBNAME,
|
||||
dnl 4. if it doesn't exist as a directory.
|
||||
if test "X$additional_libdir" != "X/usr/lib"; then
|
||||
haveit=
|
||||
if test "X$additional_libdir" = "X/usr/local/lib"; then
|
||||
if test -n "$GCC"; then
|
||||
case $host_os in
|
||||
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
if test -z "$haveit"; then
|
||||
haveit=
|
||||
for x in $LDFLAGS $LIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LIBNAME.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
haveit=
|
||||
for x in $LDFLAGS $LTLIB[]NAME; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X-L$additional_libdir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
if test -d "$additional_libdir"; then
|
||||
dnl Really add $additional_libdir to $LTLIBNAME.
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
-R*)
|
||||
dir=`echo "X$dep" | sed -e 's/^X-R//'`
|
||||
if test "$enable_rpath" != no; then
|
||||
dnl Potentially add DIR to rpathdirs.
|
||||
dnl The rpathdirs will be appended to $LIBNAME at the end.
|
||||
haveit=
|
||||
for x in $rpathdirs; do
|
||||
if test "X$x" = "X$dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
rpathdirs="$rpathdirs $dir"
|
||||
fi
|
||||
dnl Potentially add DIR to ltrpathdirs.
|
||||
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
|
||||
haveit=
|
||||
for x in $ltrpathdirs; do
|
||||
if test "X$x" = "X$dir"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
ltrpathdirs="$ltrpathdirs $dir"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
-l*)
|
||||
dnl Handle this in the next round.
|
||||
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
|
||||
;;
|
||||
*.la)
|
||||
dnl Handle this in the next round. Throw away the .la's
|
||||
dnl directory; it is already contained in a preceding -L
|
||||
dnl option.
|
||||
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
|
||||
;;
|
||||
*)
|
||||
dnl Most likely an immediate library name.
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
else
|
||||
dnl Didn't find the library; assume it is in the system directories
|
||||
dnl known to the linker and runtime loader. (All the system
|
||||
dnl directories known to the linker should also be known to the
|
||||
dnl runtime loader, otherwise the system is severely misconfigured.)
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
if test "X$rpathdirs" != "X"; then
|
||||
if test -n "$hardcode_libdir_separator"; then
|
||||
dnl Weird platform: only the last -rpath option counts, the user must
|
||||
dnl pass all path elements in one option. We can arrange that for a
|
||||
dnl single library, but not when more than one $LIBNAMEs are used.
|
||||
alldirs=
|
||||
for found_dir in $rpathdirs; do
|
||||
alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir"
|
||||
done
|
||||
dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl.
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$alldirs"
|
||||
eval flag=\"$hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
|
||||
else
|
||||
dnl The -rpath options are cumulative.
|
||||
for found_dir in $rpathdirs; do
|
||||
acl_save_libdir="$libdir"
|
||||
libdir="$found_dir"
|
||||
eval flag=\"$hardcode_libdir_flag_spec\"
|
||||
libdir="$acl_save_libdir"
|
||||
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
if test "X$ltrpathdirs" != "X"; then
|
||||
dnl When using libtool, the option that works for both libraries and
|
||||
dnl executables is -R. The -R options are cumulative.
|
||||
for found_dir in $ltrpathdirs; do
|
||||
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
|
||||
done
|
||||
fi
|
||||
])
|
||||
|
||||
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
|
||||
dnl unless already present in VAR.
|
||||
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
|
||||
dnl contains two or three consecutive elements that belong together.
|
||||
AC_DEFUN([AC_LIB_APPENDTOVAR],
|
||||
[
|
||||
for element in [$2]; do
|
||||
haveit=
|
||||
for x in $[$1]; do
|
||||
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
|
||||
if test "X$x" = "X$element"; then
|
||||
haveit=yes
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test -z "$haveit"; then
|
||||
[$1]="${[$1]}${[$1]:+ }$element"
|
||||
fi
|
||||
done
|
||||
])
|
||||
|
||||
# lib-ld.m4 serial 3 (gettext-0.13)
|
||||
dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl Subroutines of libtool.m4,
|
||||
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
|
||||
dnl with libtool.m4.
|
||||
|
||||
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
|
||||
AC_DEFUN([AC_LIB_PROG_LD_GNU],
|
||||
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
|
||||
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
|
||||
case `$LD -v 2>&1 </dev/null` in
|
||||
*GNU* | *'with BFD'*)
|
||||
acl_cv_prog_gnu_ld=yes ;;
|
||||
*)
|
||||
acl_cv_prog_gnu_ld=no ;;
|
||||
esac])
|
||||
with_gnu_ld=$acl_cv_prog_gnu_ld
|
||||
])
|
||||
|
||||
dnl From libtool-1.4. Sets the variable LD.
|
||||
AC_DEFUN([AC_LIB_PROG_LD],
|
||||
[AC_ARG_WITH(gnu-ld,
|
||||
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
|
||||
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||
# Prepare PATH_SEPARATOR.
|
||||
# The user is always right.
|
||||
if test "${PATH_SEPARATOR+set}" != set; then
|
||||
echo "#! /bin/sh" >conf$$.sh
|
||||
echo "exit 0" >>conf$$.sh
|
||||
chmod +x conf$$.sh
|
||||
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
|
||||
PATH_SEPARATOR=';'
|
||||
else
|
||||
PATH_SEPARATOR=:
|
||||
fi
|
||||
rm -f conf$$.sh
|
||||
fi
|
||||
ac_prog=ld
|
||||
if test "$GCC" = yes; then
|
||||
# Check if gcc -print-prog-name=ld gives a path.
|
||||
AC_MSG_CHECKING([for ld used by GCC])
|
||||
case $host in
|
||||
*-*-mingw*)
|
||||
# gcc leaves a trailing carriage return which upsets mingw
|
||||
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
|
||||
*)
|
||||
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
|
||||
esac
|
||||
case $ac_prog in
|
||||
# Accept absolute paths.
|
||||
[[\\/]* | [A-Za-z]:[\\/]*)]
|
||||
[re_direlt='/[^/][^/]*/\.\./']
|
||||
# Canonicalize the path of ld
|
||||
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
|
||||
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
|
||||
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
|
||||
done
|
||||
test -z "$LD" && LD="$ac_prog"
|
||||
;;
|
||||
"")
|
||||
# If it fails, then pretend we aren't using GCC.
|
||||
ac_prog=ld
|
||||
;;
|
||||
*)
|
||||
# If it is relative, then search for the first ld in PATH.
|
||||
with_gnu_ld=unknown
|
||||
;;
|
||||
esac
|
||||
elif test "$with_gnu_ld" = yes; then
|
||||
AC_MSG_CHECKING([for GNU ld])
|
||||
else
|
||||
AC_MSG_CHECKING([for non-GNU ld])
|
||||
fi
|
||||
AC_CACHE_VAL(acl_cv_path_LD,
|
||||
[if test -z "$LD"; then
|
||||
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
|
||||
for ac_dir in $PATH; do
|
||||
test -z "$ac_dir" && ac_dir=.
|
||||
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
|
||||
acl_cv_path_LD="$ac_dir/$ac_prog"
|
||||
# Check to see if the program is GNU ld. I'd rather use --version,
|
||||
# but apparently some GNU ld's only accept -v.
|
||||
# Break only if it was the GNU/non-GNU ld that we prefer.
|
||||
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
|
||||
*GNU* | *'with BFD'*)
|
||||
test "$with_gnu_ld" != no && break ;;
|
||||
*)
|
||||
test "$with_gnu_ld" != yes && break ;;
|
||||
esac
|
||||
fi
|
||||
done
|
||||
IFS="$ac_save_ifs"
|
||||
else
|
||||
acl_cv_path_LD="$LD" # Let the user override the test with a path.
|
||||
fi])
|
||||
LD="$acl_cv_path_LD"
|
||||
if test -n "$LD"; then
|
||||
AC_MSG_RESULT($LD)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
|
||||
AC_LIB_PROG_LD_GNU
|
||||
])
|
||||
|
80
configure.in
Normal file
80
configure.in
Normal file
|
@ -0,0 +1,80 @@
|
|||
#
|
||||
# configure.in
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
AC_INIT(libnl, 1.0-pre6, tgraf@suug.ch)
|
||||
AC_CONFIG_HEADER(lib/defs.h)
|
||||
|
||||
save_CFLAGS="${CFLAGS}"
|
||||
save_LDFLAGS="${LDFLAGS}"
|
||||
save_CPPFLAGS="${CPPFLAGS}"
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
#####################################################################
|
||||
##
|
||||
## libm check
|
||||
##
|
||||
#####################################################################
|
||||
M="No "
|
||||
AC_CHECK_LIB(m, pow,
|
||||
[
|
||||
LIBM="-lm"
|
||||
M="Yes"
|
||||
],[
|
||||
echo
|
||||
echo "*** Error: libm required ***"
|
||||
echo
|
||||
exit
|
||||
])
|
||||
|
||||
#####################################################################
|
||||
##
|
||||
## verbose error strings
|
||||
##
|
||||
#####################################################################
|
||||
AC_ARG_ENABLE(verbose-errors,
|
||||
[ --enable-verbose-errors enable verbose errors (debugging)],[
|
||||
if test x$enableval = xyes; then
|
||||
AC_DEFINE_UNQUOTED(VERBOSE_ERRORS,"1",[verbose errors])
|
||||
fi
|
||||
])
|
||||
|
||||
#####################################################################
|
||||
##
|
||||
## compile decisions
|
||||
##
|
||||
#####################################################################
|
||||
COMPILE_LIBNL="Yes "
|
||||
LIBNL_LIB="$LIBM"
|
||||
|
||||
AC_SUBST(LIBNL_LIB)
|
||||
|
||||
AC_OUTPUT([Makefile.opts libnl-1.pc])
|
||||
|
||||
#####################################################################
|
||||
##
|
||||
## status report
|
||||
##
|
||||
#####################################################################
|
||||
echo "
|
||||
----------------------------------------------------------------------
|
||||
SUMMARY:
|
||||
|
||||
Included in Compilation:
|
||||
libnl: $COMPILE_LIBNL $LIBNL_LIB
|
||||
|
||||
Dependencies:
|
||||
bmon:
|
||||
libm $M (required)"
|
1259
doc/Doxyfile
Normal file
1259
doc/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
35
doc/Makefile
Normal file
35
doc/Makefile
Normal file
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# doc/Makefile
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
ifeq ($(shell [ ! -r ../Makefile.opts ] && echo 1),)
|
||||
include ../Makefile.opts
|
||||
endif
|
||||
|
||||
export
|
||||
|
||||
.PHONY: all gendoc clean distclean install
|
||||
|
||||
all:
|
||||
@true
|
||||
|
||||
gendoc:
|
||||
doxygen Doxyfile
|
||||
|
||||
clean:
|
||||
@true
|
||||
|
||||
distclean:
|
||||
$(RM) -f html/*
|
||||
|
||||
install:
|
||||
@true
|
||||
|
||||
$(DEPS): ../Makefile.opts
|
310
doc/libnl.css
Normal file
310
doc/libnl.css
Normal file
|
@ -0,0 +1,310 @@
|
|||
BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
BODY,TD {
|
||||
font-size: 90%;
|
||||
}
|
||||
H1 {
|
||||
text-align: center;
|
||||
font-size: 160%;
|
||||
}
|
||||
H2 {
|
||||
font-size: 120%;
|
||||
}
|
||||
H3 {
|
||||
font-size: 100%;
|
||||
}
|
||||
CAPTION { font-weight: bold }
|
||||
DIV.qindex {
|
||||
width: 100%;
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.nav {
|
||||
width: 100%;
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
line-height: 140%;
|
||||
}
|
||||
DIV.navtab {
|
||||
background-color: #eeeeff;
|
||||
border: 1px solid #b0b0b0;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
}
|
||||
TD.navtab {
|
||||
font-size: 70%;
|
||||
}
|
||||
A.qindex {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D;
|
||||
}
|
||||
A.qindex:visited {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: #1A419D
|
||||
}
|
||||
A.qindex:hover {
|
||||
text-decoration: none;
|
||||
background-color: #ddddff;
|
||||
}
|
||||
A.qindexHL {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
A.qindexHL:hover {
|
||||
text-decoration: none;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
}
|
||||
A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff }
|
||||
A.el { text-decoration: none; font-weight: bold }
|
||||
A.elRef { font-weight: bold }
|
||||
A.code:link { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||
A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF}
|
||||
A.codeRef:link { font-weight: normal; color: #0000FF}
|
||||
A.codeRef:visited { font-weight: normal; color: #0000FF}
|
||||
A:hover { text-decoration: none; background-color: #f2f2ff }
|
||||
DL.el { margin-left: -1cm }
|
||||
.fragment {
|
||||
font-family: Fixed, monospace;
|
||||
font-size: 95%;
|
||||
}
|
||||
PRE.fragment {
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 2px;
|
||||
margin-right: 8px;
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
|
||||
TD.md { background-color: #F4F4FB; font-weight: bold; }
|
||||
TD.mdPrefix {
|
||||
background-color: #F4F4FB;
|
||||
color: #606060;
|
||||
font-size: 80%;
|
||||
}
|
||||
TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; }
|
||||
TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; }
|
||||
DIV.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% }
|
||||
BODY {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
TD.indexkey {
|
||||
background-color: #eeeeff;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TD.indexvalue {
|
||||
background-color: #eeeeff;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px;
|
||||
border: 1px solid #CCCCCC;
|
||||
}
|
||||
TR.memlist {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
P.formulaDsp { text-align: center; }
|
||||
IMG.formulaDsp { }
|
||||
IMG.formulaInl { vertical-align: middle; }
|
||||
SPAN.keyword { color: #008000 }
|
||||
SPAN.keywordtype { color: #604020 }
|
||||
SPAN.keywordflow { color: #e08000 }
|
||||
SPAN.comment { color: #800000 }
|
||||
SPAN.preprocessor { color: #806020 }
|
||||
SPAN.stringliteral { color: #002080 }
|
||||
SPAN.charliteral { color: #008080 }
|
||||
.mdTable {
|
||||
border: 1px solid #868686;
|
||||
background-color: #F4F4FB;
|
||||
width: 100%;
|
||||
}
|
||||
.mdRow {
|
||||
padding: 8px 10px;
|
||||
}
|
||||
.mdescLeft {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
font-size: 80%;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
.memItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplItemRight {
|
||||
padding: 1px 8px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: none;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.memTemplParams {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-top-style: solid;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
color: #606060;
|
||||
background-color: #FAFAFA;
|
||||
font-size: 80%;
|
||||
}
|
||||
.search { color: #003399;
|
||||
font-weight: bold;
|
||||
}
|
||||
FORM.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
INPUT.search { font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
TD.tiny { font-size: 75%;
|
||||
}
|
||||
a {
|
||||
color: #252E78;
|
||||
}
|
||||
a:visited {
|
||||
color: #3D2185;
|
||||
}
|
||||
.dirtab { padding: 4px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #b0b0b0;
|
||||
}
|
||||
TH.dirtab { background: #eeeeff;
|
||||
font-weight: bold;
|
||||
}
|
||||
HR { height: 1px;
|
||||
border: none;
|
||||
border-top: 1px solid black;
|
||||
}
|
38
include/Makefile
Normal file
38
include/Makefile
Normal file
|
@ -0,0 +1,38 @@
|
|||
#
|
||||
# include/Makefile
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
ifeq ($(shell [ ! -r ../Makefile.opts ] && echo 1),)
|
||||
include ../Makefile.opts
|
||||
endif
|
||||
|
||||
.PHONY: all clean install
|
||||
|
||||
all:
|
||||
@true
|
||||
|
||||
clean:
|
||||
@true
|
||||
|
||||
distclean:
|
||||
@true
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)$(includedir)/netlink/route/sch/
|
||||
mkdir -p $(DESTDIR)$(includedir)/netlink/route/cls/
|
||||
mkdir -p $(DESTDIR)$(includedir)/netlink/genl/
|
||||
mkdir -p $(DESTDIR)$(includedir)/netlink/fib_lookup/
|
||||
install -m 0644 netlink/*.h $(DESTDIR)$(includedir)/netlink/
|
||||
install -m 0644 netlink/route/*.h $(DESTDIR)$(includedir)/netlink/route/
|
||||
install -m 0644 netlink/route/sch/*.h $(DESTDIR)$(includedir)/netlink/route/sch/
|
||||
install -m 0644 netlink/route/cls/*.h $(DESTDIR)$(includedir)/netlink/route/cls/
|
||||
install -m 0644 netlink/genl/*.h $(DESTDIR)$(includedir)/netlink/genl/
|
||||
install -m 0644 netlink/fib_lookup/*.h $(DESTDIR)$(includedir)/netlink/fib_lookup/
|
||||
|
60
include/linux/gen_stats.h
Normal file
60
include/linux/gen_stats.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef __LINUX_GEN_STATS_H
|
||||
#define __LINUX_GEN_STATS_H
|
||||
|
||||
enum {
|
||||
TCA_STATS_UNSPEC,
|
||||
TCA_STATS_BASIC,
|
||||
TCA_STATS_RATE_EST,
|
||||
TCA_STATS_QUEUE,
|
||||
TCA_STATS_APP,
|
||||
__TCA_STATS_MAX,
|
||||
};
|
||||
#define TCA_STATS_MAX (__TCA_STATS_MAX - 1)
|
||||
|
||||
/**
|
||||
* @bytes: number of seen bytes
|
||||
* @packets: number of seen packets
|
||||
*/
|
||||
struct gnet_stats_basic
|
||||
{
|
||||
__u64 bytes;
|
||||
__u32 packets;
|
||||
};
|
||||
|
||||
/**
|
||||
* @bps: current byte rate
|
||||
* @pps: current packet rate
|
||||
*/
|
||||
struct gnet_stats_rate_est
|
||||
{
|
||||
__u32 bps;
|
||||
__u32 pps;
|
||||
};
|
||||
|
||||
/**
|
||||
* @qlen: queue length
|
||||
* @backlog: backlog size of queue
|
||||
* @drops: number of dropped packets
|
||||
* @requeues: number of requeues
|
||||
*/
|
||||
struct gnet_stats_queue
|
||||
{
|
||||
__u32 qlen;
|
||||
__u32 backlog;
|
||||
__u32 drops;
|
||||
__u32 requeues;
|
||||
__u32 overlimits;
|
||||
};
|
||||
|
||||
/**
|
||||
* @interval: sampling period
|
||||
* @ewma_log: the log of measurement window weight
|
||||
*/
|
||||
struct gnet_estimator
|
||||
{
|
||||
signed char interval;
|
||||
unsigned char ewma_log;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __LINUX_GEN_STATS_H */
|
69
include/linux/genetlink.h
Normal file
69
include/linux/genetlink.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef __LINUX_GENERIC_NETLINK_H
|
||||
#define __LINUX_GENERIC_NETLINK_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
#define GENL_NAMSIZ 16 /* length of family name */
|
||||
|
||||
#define GENL_MIN_ID NLMSG_MIN_TYPE
|
||||
#define GENL_MAX_ID 1023
|
||||
|
||||
struct genlmsghdr {
|
||||
__u8 cmd;
|
||||
__u8 version;
|
||||
__u16 reserved;
|
||||
};
|
||||
|
||||
#define GENL_HDRLEN NLMSG_ALIGN(sizeof(struct genlmsghdr))
|
||||
|
||||
#define GENL_ADMIN_PERM 0x01
|
||||
#define GENL_CMD_CAP_DO 0x02
|
||||
#define GENL_CMD_CAP_DUMP 0x04
|
||||
#define GENL_CMD_CAP_HASPOL 0x08
|
||||
|
||||
/*
|
||||
* List of reserved static generic netlink identifiers:
|
||||
*/
|
||||
#define GENL_ID_GENERATE 0
|
||||
#define GENL_ID_CTRL NLMSG_MIN_TYPE
|
||||
|
||||
/**************************************************************************
|
||||
* Controller
|
||||
**************************************************************************/
|
||||
|
||||
enum {
|
||||
CTRL_CMD_UNSPEC,
|
||||
CTRL_CMD_NEWFAMILY,
|
||||
CTRL_CMD_DELFAMILY,
|
||||
CTRL_CMD_GETFAMILY,
|
||||
CTRL_CMD_NEWOPS,
|
||||
CTRL_CMD_DELOPS,
|
||||
CTRL_CMD_GETOPS,
|
||||
__CTRL_CMD_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_CMD_MAX (__CTRL_CMD_MAX - 1)
|
||||
|
||||
enum {
|
||||
CTRL_ATTR_UNSPEC,
|
||||
CTRL_ATTR_FAMILY_ID,
|
||||
CTRL_ATTR_FAMILY_NAME,
|
||||
CTRL_ATTR_VERSION,
|
||||
CTRL_ATTR_HDRSIZE,
|
||||
CTRL_ATTR_MAXATTR,
|
||||
CTRL_ATTR_OPS,
|
||||
__CTRL_ATTR_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_ATTR_MAX (__CTRL_ATTR_MAX - 1)
|
||||
|
||||
enum {
|
||||
CTRL_ATTR_OP_UNSPEC,
|
||||
CTRL_ATTR_OP_ID,
|
||||
CTRL_ATTR_OP_FLAGS,
|
||||
__CTRL_ATTR_OP_MAX,
|
||||
};
|
||||
|
||||
#define CTRL_ATTR_OP_MAX (__CTRL_ATTR_OP_MAX - 1)
|
||||
|
||||
#endif /* __LINUX_GENERIC_NETLINK_H */
|
102
include/linux/if.h
Normal file
102
include/linux/if.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* Global definitions for the INET interface module.
|
||||
*
|
||||
* Version: @(#)if.h 1.0.2 04/18/93
|
||||
*
|
||||
* Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988
|
||||
* Ross Biro
|
||||
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.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 _LINUX_IF_H
|
||||
#define _LINUX_IF_H
|
||||
|
||||
#define IFNAMSIZ 16
|
||||
|
||||
/* Standard interface flags (netdevice->flags). */
|
||||
#define IFF_UP 0x1 /* interface is up */
|
||||
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
|
||||
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
|
||||
#define IFF_RUNNING 0x40 /* interface running and carrier ok */
|
||||
#define IFF_NOARP 0x80 /* no ARP protocol */
|
||||
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
|
||||
|
||||
#define IFF_MASTER 0x400 /* master of a load balancer */
|
||||
#define IFF_SLAVE 0x800 /* slave of a load balancer */
|
||||
|
||||
#define IFF_MULTICAST 0x1000 /* Supports multicast */
|
||||
|
||||
#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING)
|
||||
|
||||
#define IFF_PORTSEL 0x2000 /* can set media type */
|
||||
#define IFF_AUTOMEDIA 0x4000 /* auto media select active */
|
||||
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/
|
||||
#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
|
||||
#define IFF_DORMANT 0x20000 /* driver signals dormant */
|
||||
|
||||
/* Private (from user) interface flags (netdevice->priv_flags). */
|
||||
#define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */
|
||||
#define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */
|
||||
|
||||
#define IF_GET_IFACE 0x0001 /* for querying only */
|
||||
#define IF_GET_PROTO 0x0002
|
||||
|
||||
/* For definitions see hdlc.h */
|
||||
#define IF_IFACE_V35 0x1000 /* V.35 serial interface */
|
||||
#define IF_IFACE_V24 0x1001 /* V.24 serial interface */
|
||||
#define IF_IFACE_X21 0x1002 /* X.21 serial interface */
|
||||
#define IF_IFACE_T1 0x1003 /* T1 telco serial interface */
|
||||
#define IF_IFACE_E1 0x1004 /* E1 telco serial interface */
|
||||
#define IF_IFACE_SYNC_SERIAL 0x1005 /* can't be set by software */
|
||||
#define IF_IFACE_X21D 0x1006 /* X.21 Dual Clocking (FarSite) */
|
||||
|
||||
/* For definitions see hdlc.h */
|
||||
#define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */
|
||||
#define IF_PROTO_PPP 0x2001 /* PPP protocol */
|
||||
#define IF_PROTO_CISCO 0x2002 /* Cisco HDLC protocol */
|
||||
#define IF_PROTO_FR 0x2003 /* Frame Relay protocol */
|
||||
#define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */
|
||||
#define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */
|
||||
#define IF_PROTO_X25 0x2006 /* X.25 */
|
||||
#define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */
|
||||
#define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */
|
||||
#define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */
|
||||
#define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */
|
||||
#define IF_PROTO_FR_ETH_PVC 0x200B
|
||||
#define IF_PROTO_RAW 0x200C /* RAW Socket */
|
||||
|
||||
|
||||
/*
|
||||
* Device mapping structure. I'd just gone off and designed a
|
||||
* beautiful scheme using only loadable modules with arguments
|
||||
* for driver options and along come the PCMCIA people 8)
|
||||
*
|
||||
* Ah well. The get() side of this is good for WDSETUP, and it'll
|
||||
* be handy for debugging things. The set side is fine for now and
|
||||
* being very small might be worth keeping for clean configuration.
|
||||
*/
|
||||
|
||||
struct ifmap
|
||||
{
|
||||
unsigned long mem_start;
|
||||
unsigned long mem_end;
|
||||
unsigned short base_addr;
|
||||
unsigned char irq;
|
||||
unsigned char dma;
|
||||
unsigned char port;
|
||||
/* 3 bytes spare */
|
||||
};
|
||||
|
||||
#endif /* _LINUX_IF_H */
|
62
include/linux/if_addr.h
Normal file
62
include/linux/if_addr.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#ifndef __LINUX_IF_ADDR_H
|
||||
#define __LINUX_IF_ADDR_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
struct ifaddrmsg
|
||||
{
|
||||
__u8 ifa_family;
|
||||
__u8 ifa_prefixlen; /* The prefix length */
|
||||
__u8 ifa_flags; /* Flags */
|
||||
__u8 ifa_scope; /* Address scope */
|
||||
__u32 ifa_index; /* Link index */
|
||||
};
|
||||
|
||||
/*
|
||||
* Important comment:
|
||||
* IFA_ADDRESS is prefix address, rather than local interface address.
|
||||
* It makes no difference for normally configured broadcast interfaces,
|
||||
* but for point-to-point IFA_ADDRESS is DESTINATION address,
|
||||
* local address is supplied in IFA_LOCAL attribute.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
IFA_UNSPEC,
|
||||
IFA_ADDRESS,
|
||||
IFA_LOCAL,
|
||||
IFA_LABEL,
|
||||
IFA_BROADCAST,
|
||||
IFA_ANYCAST,
|
||||
IFA_CACHEINFO,
|
||||
IFA_MULTICAST,
|
||||
__IFA_MAX,
|
||||
};
|
||||
|
||||
#define IFA_MAX (__IFA_MAX - 1)
|
||||
|
||||
/* ifa_flags */
|
||||
#define IFA_F_SECONDARY 0x01
|
||||
#define IFA_F_TEMPORARY IFA_F_SECONDARY
|
||||
|
||||
#define IFA_F_NODAD 0x02
|
||||
#define IFA_F_OPTIMISTIC 0x04
|
||||
#define IFA_F_HOMEADDRESS 0x10
|
||||
#define IFA_F_DEPRECATED 0x20
|
||||
#define IFA_F_TENTATIVE 0x40
|
||||
#define IFA_F_PERMANENT 0x80
|
||||
|
||||
struct ifa_cacheinfo
|
||||
{
|
||||
__u32 ifa_prefered;
|
||||
__u32 ifa_valid;
|
||||
__u32 cstamp; /* created timestamp, hundredths of seconds */
|
||||
__u32 tstamp; /* updated timestamp, hundredths of seconds */
|
||||
};
|
||||
|
||||
/* backwards compatibility for userspace */
|
||||
#ifndef __KERNEL__
|
||||
#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
|
||||
#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
|
||||
#endif
|
||||
|
||||
#endif
|
149
include/linux/if_arp.h
Normal file
149
include/linux/if_arp.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* Global definitions for the ARP (RFC 826) protocol.
|
||||
*
|
||||
* Version: @(#)if_arp.h 1.0.1 04/16/93
|
||||
*
|
||||
* Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
|
||||
* Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
|
||||
* Ross Biro
|
||||
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
|
||||
* Florian La Roche,
|
||||
* Jonathan Layes <layes@loran.com>
|
||||
* Arnaldo Carvalho de Melo <acme@conectiva.com.br> ARPHRD_HWX25
|
||||
*
|
||||
* 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 _LINUX_IF_ARP_H
|
||||
#define _LINUX_IF_ARP_H
|
||||
|
||||
/* ARP protocol HARDWARE identifiers. */
|
||||
#define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */
|
||||
#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
|
||||
#define ARPHRD_EETHER 2 /* Experimental Ethernet */
|
||||
#define ARPHRD_AX25 3 /* AX.25 Level 2 */
|
||||
#define ARPHRD_PRONET 4 /* PROnet token ring */
|
||||
#define ARPHRD_CHAOS 5 /* Chaosnet */
|
||||
#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
|
||||
#define ARPHRD_ARCNET 7 /* ARCnet */
|
||||
#define ARPHRD_APPLETLK 8 /* APPLEtalk */
|
||||
#define ARPHRD_DLCI 15 /* Frame Relay DLCI */
|
||||
#define ARPHRD_ATM 19 /* ATM */
|
||||
#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */
|
||||
#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */
|
||||
#define ARPHRD_EUI64 27 /* EUI-64 */
|
||||
#define ARPHRD_INFINIBAND 32 /* InfiniBand */
|
||||
|
||||
/* Dummy types for non ARP hardware */
|
||||
#define ARPHRD_SLIP 256
|
||||
#define ARPHRD_CSLIP 257
|
||||
#define ARPHRD_SLIP6 258
|
||||
#define ARPHRD_CSLIP6 259
|
||||
#define ARPHRD_RSRVD 260 /* Notional KISS type */
|
||||
#define ARPHRD_ADAPT 264
|
||||
#define ARPHRD_ROSE 270
|
||||
#define ARPHRD_X25 271 /* CCITT X.25 */
|
||||
#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
|
||||
#define ARPHRD_PPP 512
|
||||
#define ARPHRD_CISCO 513 /* Cisco HDLC */
|
||||
#define ARPHRD_HDLC ARPHRD_CISCO
|
||||
#define ARPHRD_LAPB 516 /* LAPB */
|
||||
#define ARPHRD_DDCMP 517 /* Digital's DDCMP protocol */
|
||||
#define ARPHRD_RAWHDLC 518 /* Raw HDLC */
|
||||
|
||||
#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
|
||||
#define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */
|
||||
#define ARPHRD_FRAD 770 /* Frame Relay Access Device */
|
||||
#define ARPHRD_SKIP 771 /* SKIP vif */
|
||||
#define ARPHRD_LOOPBACK 772 /* Loopback device */
|
||||
#define ARPHRD_LOCALTLK 773 /* Localtalk device */
|
||||
#define ARPHRD_FDDI 774 /* Fiber Distributed Data Interface */
|
||||
#define ARPHRD_BIF 775 /* AP1000 BIF */
|
||||
#define ARPHRD_SIT 776 /* sit0 device - IPv6-in-IPv4 */
|
||||
#define ARPHRD_IPDDP 777 /* IP over DDP tunneller */
|
||||
#define ARPHRD_IPGRE 778 /* GRE over IP */
|
||||
#define ARPHRD_PIMREG 779 /* PIMSM register interface */
|
||||
#define ARPHRD_HIPPI 780 /* High Performance Parallel Interface */
|
||||
#define ARPHRD_ASH 781 /* Nexus 64Mbps Ash */
|
||||
#define ARPHRD_ECONET 782 /* Acorn Econet */
|
||||
#define ARPHRD_IRDA 783 /* Linux-IrDA */
|
||||
/* ARP works differently on different FC media .. so */
|
||||
#define ARPHRD_FCPP 784 /* Point to point fibrechannel */
|
||||
#define ARPHRD_FCAL 785 /* Fibrechannel arbitrated loop */
|
||||
#define ARPHRD_FCPL 786 /* Fibrechannel public loop */
|
||||
#define ARPHRD_FCFABRIC 787 /* Fibrechannel fabric */
|
||||
/* 787->799 reserved for fibrechannel media types */
|
||||
#define ARPHRD_IEEE802_TR 800 /* Magic type ident for TR */
|
||||
#define ARPHRD_IEEE80211 801 /* IEEE 802.11 */
|
||||
#define ARPHRD_IEEE80211_PRISM 802 /* IEEE 802.11 + Prism2 header */
|
||||
#define ARPHRD_IEEE80211_RADIOTAP 803 /* IEEE 802.11 + radiotap header */
|
||||
|
||||
#define ARPHRD_VOID 0xFFFF /* Void type, nothing is known */
|
||||
#define ARPHRD_NONE 0xFFFE /* zero header length */
|
||||
|
||||
/* ARP protocol opcodes. */
|
||||
#define ARPOP_REQUEST 1 /* ARP request */
|
||||
#define ARPOP_REPLY 2 /* ARP reply */
|
||||
#define ARPOP_RREQUEST 3 /* RARP request */
|
||||
#define ARPOP_RREPLY 4 /* RARP reply */
|
||||
#define ARPOP_InREQUEST 8 /* InARP request */
|
||||
#define ARPOP_InREPLY 9 /* InARP reply */
|
||||
#define ARPOP_NAK 10 /* (ATM)ARP NAK */
|
||||
|
||||
|
||||
/* ARP ioctl request. */
|
||||
struct arpreq {
|
||||
struct sockaddr arp_pa; /* protocol address */
|
||||
struct sockaddr arp_ha; /* hardware address */
|
||||
int arp_flags; /* flags */
|
||||
struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
|
||||
char arp_dev[16];
|
||||
};
|
||||
|
||||
struct arpreq_old {
|
||||
struct sockaddr arp_pa; /* protocol address */
|
||||
struct sockaddr arp_ha; /* hardware address */
|
||||
int arp_flags; /* flags */
|
||||
struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
|
||||
};
|
||||
|
||||
/* ARP Flag values. */
|
||||
#define ATF_COM 0x02 /* completed entry (ha valid) */
|
||||
#define ATF_PERM 0x04 /* permanent entry */
|
||||
#define ATF_PUBL 0x08 /* publish entry */
|
||||
#define ATF_USETRAILERS 0x10 /* has requested trailers */
|
||||
#define ATF_NETMASK 0x20 /* want to use a netmask (only
|
||||
for proxy entries) */
|
||||
#define ATF_DONTPUB 0x40 /* don't answer this addresses */
|
||||
|
||||
/*
|
||||
* This structure defines an ethernet arp header.
|
||||
*/
|
||||
|
||||
struct arphdr
|
||||
{
|
||||
unsigned short ar_hrd; /* format of hardware address */
|
||||
unsigned short ar_pro; /* format of protocol address */
|
||||
unsigned char ar_hln; /* length of hardware address */
|
||||
unsigned char ar_pln; /* length of protocol address */
|
||||
unsigned short ar_op; /* ARP opcode (command) */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Ethernet looks like this : This bit is variable sized however...
|
||||
*/
|
||||
unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
|
||||
unsigned char ar_sip[4]; /* sender IP address */
|
||||
unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
|
||||
unsigned char ar_tip[4]; /* target IP address */
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif /* _LINUX_IF_ARP_H */
|
106
include/linux/if_ether.h
Normal file
106
include/linux/if_ether.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* INET An implementation of the TCP/IP protocol suite for the LINUX
|
||||
* operating system. INET is implemented using the BSD Socket
|
||||
* interface as the means of communication with the user level.
|
||||
*
|
||||
* Global definitions for the Ethernet IEEE 802.3 interface.
|
||||
*
|
||||
* Version: @(#)if_ether.h 1.0.1a 02/08/94
|
||||
*
|
||||
* Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
|
||||
* Donald Becker, <becker@super.org>
|
||||
* Alan Cox, <alan@redhat.com>
|
||||
* Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
|
||||
*
|
||||
* 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 _LINUX_IF_ETHER_H
|
||||
#define _LINUX_IF_ETHER_H
|
||||
|
||||
/*
|
||||
* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
|
||||
* and FCS/CRC (frame check sequence).
|
||||
*/
|
||||
|
||||
#define ETH_ALEN 6 /* Octets in one ethernet addr */
|
||||
#define ETH_HLEN 14 /* Total octets in header. */
|
||||
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
|
||||
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
|
||||
#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
|
||||
|
||||
/*
|
||||
* These are the defined Ethernet Protocol ID's.
|
||||
*/
|
||||
|
||||
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
|
||||
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
|
||||
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
|
||||
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
|
||||
#define ETH_P_X25 0x0805 /* CCITT X.25 */
|
||||
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
|
||||
#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
|
||||
#define ETH_P_IEEEPUP 0x0a00 /* Xerox IEEE802.3 PUP packet */
|
||||
#define ETH_P_IEEEPUPAT 0x0a01 /* Xerox IEEE802.3 PUP Addr Trans packet */
|
||||
#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
|
||||
#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
|
||||
#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
|
||||
#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
|
||||
#define ETH_P_LAT 0x6004 /* DEC LAT */
|
||||
#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
|
||||
#define ETH_P_CUST 0x6006 /* DEC Customer use */
|
||||
#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
|
||||
#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
|
||||
#define ETH_P_ATALK 0x809B /* Appletalk DDP */
|
||||
#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
|
||||
#define ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */
|
||||
#define ETH_P_IPX 0x8137 /* IPX over DIX */
|
||||
#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
|
||||
#define ETH_P_WCCP 0x883E /* Web-cache coordination protocol
|
||||
* defined in draft-wilson-wrec-wccp-v2-00.txt */
|
||||
#define ETH_P_PPP_DISC 0x8863 /* PPPoE discovery messages */
|
||||
#define ETH_P_PPP_SES 0x8864 /* PPPoE session messages */
|
||||
#define ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */
|
||||
#define ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */
|
||||
#define ETH_P_ATMMPOA 0x884c /* MultiProtocol Over ATM */
|
||||
#define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport
|
||||
* over Ethernet
|
||||
*/
|
||||
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
|
||||
|
||||
/*
|
||||
* Non DIX types. Won't clash for 1500 types.
|
||||
*/
|
||||
|
||||
#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
|
||||
#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
|
||||
#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
|
||||
#define ETH_P_802_2 0x0004 /* 802.2 frames */
|
||||
#define ETH_P_SNAP 0x0005 /* Internal only */
|
||||
#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
|
||||
#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
|
||||
#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
|
||||
#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */
|
||||
#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/
|
||||
#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */
|
||||
#define ETH_P_MOBITEX 0x0015 /* Mobitex (kaz@cafe.net) */
|
||||
#define ETH_P_CONTROL 0x0016 /* Card specific control frames */
|
||||
#define ETH_P_IRDA 0x0017 /* Linux-IrDA */
|
||||
#define ETH_P_ECONET 0x0018 /* Acorn Econet */
|
||||
#define ETH_P_HDLC 0x0019 /* HDLC frames */
|
||||
#define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */
|
||||
|
||||
/*
|
||||
* This is an Ethernet frame header.
|
||||
*/
|
||||
|
||||
struct ethhdr {
|
||||
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
|
||||
unsigned char h_source[ETH_ALEN]; /* source ether addr */
|
||||
unsigned short h_proto; /* packet type ID field */
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _LINUX_IF_ETHER_H */
|
143
include/linux/if_link.h
Normal file
143
include/linux/if_link.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
#ifndef _LINUX_IF_LINK_H
|
||||
#define _LINUX_IF_LINK_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
/* The struct should be in sync with struct net_device_stats */
|
||||
struct rtnl_link_stats
|
||||
{
|
||||
__u32 rx_packets; /* total packets received */
|
||||
__u32 tx_packets; /* total packets transmitted */
|
||||
__u32 rx_bytes; /* total bytes received */
|
||||
__u32 tx_bytes; /* total bytes transmitted */
|
||||
__u32 rx_errors; /* bad packets received */
|
||||
__u32 tx_errors; /* packet transmit problems */
|
||||
__u32 rx_dropped; /* no space in linux buffers */
|
||||
__u32 tx_dropped; /* no space available in linux */
|
||||
__u32 multicast; /* multicast packets received */
|
||||
__u32 collisions;
|
||||
|
||||
/* detailed rx_errors: */
|
||||
__u32 rx_length_errors;
|
||||
__u32 rx_over_errors; /* receiver ring buff overflow */
|
||||
__u32 rx_crc_errors; /* recved pkt with crc error */
|
||||
__u32 rx_frame_errors; /* recv'd frame alignment error */
|
||||
__u32 rx_fifo_errors; /* recv'r fifo overrun */
|
||||
__u32 rx_missed_errors; /* receiver missed packet */
|
||||
|
||||
/* detailed tx_errors */
|
||||
__u32 tx_aborted_errors;
|
||||
__u32 tx_carrier_errors;
|
||||
__u32 tx_fifo_errors;
|
||||
__u32 tx_heartbeat_errors;
|
||||
__u32 tx_window_errors;
|
||||
|
||||
/* for cslip etc */
|
||||
__u32 rx_compressed;
|
||||
__u32 tx_compressed;
|
||||
};
|
||||
|
||||
/* The struct should be in sync with struct ifmap */
|
||||
struct rtnl_link_ifmap
|
||||
{
|
||||
__u64 mem_start;
|
||||
__u64 mem_end;
|
||||
__u64 base_addr;
|
||||
__u16 irq;
|
||||
__u8 dma;
|
||||
__u8 port;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
IFLA_UNSPEC,
|
||||
IFLA_ADDRESS,
|
||||
IFLA_BROADCAST,
|
||||
IFLA_IFNAME,
|
||||
IFLA_MTU,
|
||||
IFLA_LINK,
|
||||
IFLA_QDISC,
|
||||
IFLA_STATS,
|
||||
IFLA_COST,
|
||||
#define IFLA_COST IFLA_COST
|
||||
IFLA_PRIORITY,
|
||||
#define IFLA_PRIORITY IFLA_PRIORITY
|
||||
IFLA_MASTER,
|
||||
#define IFLA_MASTER IFLA_MASTER
|
||||
IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
|
||||
#define IFLA_WIRELESS IFLA_WIRELESS
|
||||
IFLA_PROTINFO, /* Protocol specific information for a link */
|
||||
#define IFLA_PROTINFO IFLA_PROTINFO
|
||||
IFLA_TXQLEN,
|
||||
#define IFLA_TXQLEN IFLA_TXQLEN
|
||||
IFLA_MAP,
|
||||
#define IFLA_MAP IFLA_MAP
|
||||
IFLA_WEIGHT,
|
||||
#define IFLA_WEIGHT IFLA_WEIGHT
|
||||
IFLA_OPERSTATE,
|
||||
IFLA_LINKMODE,
|
||||
__IFLA_MAX
|
||||
};
|
||||
|
||||
|
||||
#define IFLA_MAX (__IFLA_MAX - 1)
|
||||
|
||||
/* backwards compatibility for userspace */
|
||||
#ifndef __KERNEL__
|
||||
#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
|
||||
#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
|
||||
#endif
|
||||
|
||||
/* ifi_flags.
|
||||
|
||||
IFF_* flags.
|
||||
|
||||
The only change is:
|
||||
IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
|
||||
more not changeable by user. They describe link media
|
||||
characteristics and set by device driver.
|
||||
|
||||
Comments:
|
||||
- Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
|
||||
- If neither of these three flags are set;
|
||||
the interface is NBMA.
|
||||
|
||||
- IFF_MULTICAST does not mean anything special:
|
||||
multicasts can be used on all not-NBMA links.
|
||||
IFF_MULTICAST means that this media uses special encapsulation
|
||||
for multicast frames. Apparently, all IFF_POINTOPOINT and
|
||||
IFF_BROADCAST devices are able to use multicasts too.
|
||||
*/
|
||||
|
||||
/* IFLA_LINK.
|
||||
For usual devices it is equal ifi_index.
|
||||
If it is a "virtual interface" (f.e. tunnel), ifi_link
|
||||
can point to real physical interface (f.e. for bandwidth calculations),
|
||||
or maybe 0, what means, that real media is unknown (usual
|
||||
for IPIP tunnels, when route to endpoint is allowed to change)
|
||||
*/
|
||||
|
||||
/* Subtype attributes for IFLA_PROTINFO */
|
||||
enum
|
||||
{
|
||||
IFLA_INET6_UNSPEC,
|
||||
IFLA_INET6_FLAGS, /* link flags */
|
||||
IFLA_INET6_CONF, /* sysctl parameters */
|
||||
IFLA_INET6_STATS, /* statistics */
|
||||
IFLA_INET6_MCAST, /* MC things. What of them? */
|
||||
IFLA_INET6_CACHEINFO, /* time values and max reasm size */
|
||||
IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
|
||||
__IFLA_INET6_MAX
|
||||
};
|
||||
|
||||
#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
|
||||
|
||||
struct ifla_cacheinfo
|
||||
{
|
||||
__u32 max_reasm_len;
|
||||
__u32 tstamp; /* ipv6InterfaceTable updated timestamp */
|
||||
__u32 reachable_time;
|
||||
__u32 retrans_time;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_IF_LINK_H */
|
22
include/linux/ip_mp_alg.h
Normal file
22
include/linux/ip_mp_alg.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* ip_mp_alg.h: IPV4 multipath algorithm support, user-visible values.
|
||||
*
|
||||
* Copyright (C) 2004, 2005 Einar Lueck <elueck@de.ibm.com>
|
||||
* Copyright (C) 2005 David S. Miller <davem@davemloft.net>
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_IP_MP_ALG_H
|
||||
#define _LINUX_IP_MP_ALG_H
|
||||
|
||||
enum ip_mp_alg {
|
||||
IP_MP_ALG_NONE,
|
||||
IP_MP_ALG_RR,
|
||||
IP_MP_ALG_DRR,
|
||||
IP_MP_ALG_RANDOM,
|
||||
IP_MP_ALG_WRANDOM,
|
||||
__IP_MP_ALG_MAX
|
||||
};
|
||||
|
||||
#define IP_MP_ALG_MAX (__IP_MP_ALG_MAX - 1)
|
||||
|
||||
#endif /* _LINUX_IP_MP_ALG_H */
|
||||
|
159
include/linux/neighbour.h
Normal file
159
include/linux/neighbour.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
#ifndef __LINUX_NEIGHBOUR_H
|
||||
#define __LINUX_NEIGHBOUR_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
|
||||
struct ndmsg
|
||||
{
|
||||
__u8 ndm_family;
|
||||
__u8 ndm_pad1;
|
||||
__u16 ndm_pad2;
|
||||
__s32 ndm_ifindex;
|
||||
__u16 ndm_state;
|
||||
__u8 ndm_flags;
|
||||
__u8 ndm_type;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NDA_UNSPEC,
|
||||
NDA_DST,
|
||||
NDA_LLADDR,
|
||||
NDA_CACHEINFO,
|
||||
NDA_PROBES,
|
||||
__NDA_MAX
|
||||
};
|
||||
|
||||
#define NDA_MAX (__NDA_MAX - 1)
|
||||
|
||||
/*
|
||||
* Neighbor Cache Entry Flags
|
||||
*/
|
||||
|
||||
#define NTF_PROXY 0x08 /* == ATF_PUBL */
|
||||
#define NTF_ROUTER 0x80
|
||||
|
||||
/*
|
||||
* Neighbor Cache Entry States.
|
||||
*/
|
||||
|
||||
#define NUD_INCOMPLETE 0x01
|
||||
#define NUD_REACHABLE 0x02
|
||||
#define NUD_STALE 0x04
|
||||
#define NUD_DELAY 0x08
|
||||
#define NUD_PROBE 0x10
|
||||
#define NUD_FAILED 0x20
|
||||
|
||||
/* Dummy states */
|
||||
#define NUD_NOARP 0x40
|
||||
#define NUD_PERMANENT 0x80
|
||||
#define NUD_NONE 0x00
|
||||
|
||||
/* NUD_NOARP & NUD_PERMANENT are pseudostates, they never change
|
||||
and make no address resolution or NUD.
|
||||
NUD_PERMANENT is also cannot be deleted by garbage collectors.
|
||||
*/
|
||||
|
||||
struct nda_cacheinfo
|
||||
{
|
||||
__u32 ndm_confirmed;
|
||||
__u32 ndm_used;
|
||||
__u32 ndm_updated;
|
||||
__u32 ndm_refcnt;
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
* Neighbour tables specific messages.
|
||||
*
|
||||
* To retrieve the neighbour tables send RTM_GETNEIGHTBL with the
|
||||
* NLM_F_DUMP flag set. Every neighbour table configuration is
|
||||
* spread over multiple messages to avoid running into message
|
||||
* size limits on systems with many interfaces. The first message
|
||||
* in the sequence transports all not device specific data such as
|
||||
* statistics, configuration, and the default parameter set.
|
||||
* This message is followed by 0..n messages carrying device
|
||||
* specific parameter sets.
|
||||
* Although the ordering should be sufficient, NDTA_NAME can be
|
||||
* used to identify sequences. The initial message can be identified
|
||||
* by checking for NDTA_CONFIG. The device specific messages do
|
||||
* not contain this TLV but have NDTPA_IFINDEX set to the
|
||||
* corresponding interface index.
|
||||
*
|
||||
* To change neighbour table attributes, send RTM_SETNEIGHTBL
|
||||
* with NDTA_NAME set. Changeable attribute include NDTA_THRESH[1-3],
|
||||
* NDTA_GC_INTERVAL, and all TLVs in NDTA_PARMS unless marked
|
||||
* otherwise. Device specific parameter sets can be changed by
|
||||
* setting NDTPA_IFINDEX to the interface index of the corresponding
|
||||
* device.
|
||||
****/
|
||||
|
||||
struct ndt_stats
|
||||
{
|
||||
__u64 ndts_allocs;
|
||||
__u64 ndts_destroys;
|
||||
__u64 ndts_hash_grows;
|
||||
__u64 ndts_res_failed;
|
||||
__u64 ndts_lookups;
|
||||
__u64 ndts_hits;
|
||||
__u64 ndts_rcv_probes_mcast;
|
||||
__u64 ndts_rcv_probes_ucast;
|
||||
__u64 ndts_periodic_gc_runs;
|
||||
__u64 ndts_forced_gc_runs;
|
||||
};
|
||||
|
||||
enum {
|
||||
NDTPA_UNSPEC,
|
||||
NDTPA_IFINDEX, /* u32, unchangeable */
|
||||
NDTPA_REFCNT, /* u32, read-only */
|
||||
NDTPA_REACHABLE_TIME, /* u64, read-only, msecs */
|
||||
NDTPA_BASE_REACHABLE_TIME, /* u64, msecs */
|
||||
NDTPA_RETRANS_TIME, /* u64, msecs */
|
||||
NDTPA_GC_STALETIME, /* u64, msecs */
|
||||
NDTPA_DELAY_PROBE_TIME, /* u64, msecs */
|
||||
NDTPA_QUEUE_LEN, /* u32 */
|
||||
NDTPA_APP_PROBES, /* u32 */
|
||||
NDTPA_UCAST_PROBES, /* u32 */
|
||||
NDTPA_MCAST_PROBES, /* u32 */
|
||||
NDTPA_ANYCAST_DELAY, /* u64, msecs */
|
||||
NDTPA_PROXY_DELAY, /* u64, msecs */
|
||||
NDTPA_PROXY_QLEN, /* u32 */
|
||||
NDTPA_LOCKTIME, /* u64, msecs */
|
||||
__NDTPA_MAX
|
||||
};
|
||||
#define NDTPA_MAX (__NDTPA_MAX - 1)
|
||||
|
||||
struct ndtmsg
|
||||
{
|
||||
__u8 ndtm_family;
|
||||
__u8 ndtm_pad1;
|
||||
__u16 ndtm_pad2;
|
||||
};
|
||||
|
||||
struct ndt_config
|
||||
{
|
||||
__u16 ndtc_key_len;
|
||||
__u16 ndtc_entry_size;
|
||||
__u32 ndtc_entries;
|
||||
__u32 ndtc_last_flush; /* delta to now in msecs */
|
||||
__u32 ndtc_last_rand; /* delta to now in msecs */
|
||||
__u32 ndtc_hash_rnd;
|
||||
__u32 ndtc_hash_mask;
|
||||
__u32 ndtc_hash_chain_gc;
|
||||
__u32 ndtc_proxy_qlen;
|
||||
};
|
||||
|
||||
enum {
|
||||
NDTA_UNSPEC,
|
||||
NDTA_NAME, /* char *, unchangeable */
|
||||
NDTA_THRESH1, /* u32 */
|
||||
NDTA_THRESH2, /* u32 */
|
||||
NDTA_THRESH3, /* u32 */
|
||||
NDTA_CONFIG, /* struct ndt_config, read-only */
|
||||
NDTA_PARMS, /* nested TLV NDTPA_* */
|
||||
NDTA_STATS, /* struct ndt_stats, read-only */
|
||||
NDTA_GC_INTERVAL, /* u64, msecs */
|
||||
__NDTA_MAX
|
||||
};
|
||||
#define NDTA_MAX (__NDTA_MAX - 1)
|
||||
|
||||
#endif
|
60
include/linux/netfilter/nfnetlink.h
Normal file
60
include/linux/netfilter/nfnetlink.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef _NFNETLINK_H
|
||||
#define _NFNETLINK_H
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/* nfnetlink groups: Up to 32 maximum - backwards compatibility for userspace */
|
||||
#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
|
||||
#endif
|
||||
|
||||
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,
|
||||
};
|
||||
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
|
||||
|
||||
/* General form of address family dependent message.
|
||||
*/
|
||||
struct nfgenmsg {
|
||||
u_int8_t nfgen_family; /* AF_xxx */
|
||||
u_int8_t version; /* nfnetlink version */
|
||||
__be16 res_id; /* resource id */
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
/* 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_COUNT 5
|
||||
|
||||
#endif /* _NFNETLINK_H */
|
140
include/linux/netfilter/nfnetlink_conntrack.h
Normal file
140
include/linux/netfilter/nfnetlink_conntrack.h
Normal file
|
@ -0,0 +1,140 @@
|
|||
#ifndef _IPCONNTRACK_NETLINK_H
|
||||
#define _IPCONNTRACK_NETLINK_H
|
||||
#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_MAX
|
||||
};
|
||||
|
||||
enum ctnl_exp_msg_types {
|
||||
IPCTNL_MSG_EXP_NEW,
|
||||
IPCTNL_MSG_EXP_GET,
|
||||
IPCTNL_MSG_EXP_DELETE,
|
||||
|
||||
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_MAX
|
||||
};
|
||||
#define CTA_MAX (__CTA_MAX - 1)
|
||||
|
||||
enum ctattr_tuple {
|
||||
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
|
||||
};
|
||||
#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
|
||||
};
|
||||
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
|
||||
|
||||
enum ctattr_protoinfo {
|
||||
CTA_PROTOINFO_UNSPEC,
|
||||
CTA_PROTOINFO_TCP,
|
||||
__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
|
||||
};
|
||||
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
|
||||
|
||||
enum ctattr_counters {
|
||||
CTA_COUNTERS_UNSPEC,
|
||||
CTA_COUNTERS_PACKETS, /* old 64bit counters */
|
||||
CTA_COUNTERS_BYTES, /* old 64bit counters */
|
||||
CTA_COUNTERS32_PACKETS,
|
||||
CTA_COUNTERS32_BYTES,
|
||||
__CTA_COUNTERS_MAX
|
||||
};
|
||||
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||
|
||||
enum ctattr_nat {
|
||||
CTA_NAT_UNSPEC,
|
||||
CTA_NAT_MINIP,
|
||||
CTA_NAT_MAXIP,
|
||||
CTA_NAT_PROTO,
|
||||
__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
|
||||
};
|
||||
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_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_MAX
|
||||
};
|
||||
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
|
||||
|
||||
enum ctattr_help {
|
||||
CTA_HELP_UNSPEC,
|
||||
CTA_HELP_NAME,
|
||||
__CTA_HELP_MAX
|
||||
};
|
||||
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
|
||||
|
||||
#endif /* _IPCONNTRACK_NETLINK_H */
|
96
include/linux/netfilter/nfnetlink_log.h
Normal file
96
include/linux/netfilter/nfnetlink_log.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
#ifndef _NFNETLINK_LOG_H
|
||||
#define _NFNETLINK_LOG_H
|
||||
|
||||
/* This file describes the netlink messages (i.e. 'protocol packets'),
|
||||
* 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>
|
||||
|
||||
enum nfulnl_msg_types {
|
||||
NFULNL_MSG_PACKET, /* packet from kernel to userspace */
|
||||
NFULNL_MSG_CONFIG, /* connect to a particular queue */
|
||||
|
||||
NFULNL_MSG_MAX
|
||||
};
|
||||
|
||||
struct nfulnl_msg_packet_hdr {
|
||||
__be16 hw_protocol; /* hw protocol (network order) */
|
||||
u_int8_t hook; /* netfilter hook */
|
||||
u_int8_t _pad;
|
||||
};
|
||||
|
||||
struct nfulnl_msg_packet_hw {
|
||||
__be16 hw_addrlen;
|
||||
u_int16_t _pad;
|
||||
u_int8_t hw_addr[8];
|
||||
};
|
||||
|
||||
struct nfulnl_msg_packet_timestamp {
|
||||
aligned_be64 sec;
|
||||
aligned_be64 usec;
|
||||
};
|
||||
|
||||
enum nfulnl_attr_type {
|
||||
NFULA_UNSPEC,
|
||||
NFULA_PACKET_HDR,
|
||||
NFULA_MARK, /* u_int32_t nfmark */
|
||||
NFULA_TIMESTAMP, /* nfulnl_msg_packet_timestamp */
|
||||
NFULA_IFINDEX_INDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_OUTDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_PHYSINDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_PHYSOUTDEV, /* u_int32_t ifindex */
|
||||
NFULA_HWADDR, /* nfulnl_msg_packet_hw */
|
||||
NFULA_PAYLOAD, /* opaque data payload */
|
||||
NFULA_PREFIX, /* string prefix */
|
||||
NFULA_UID, /* user id of socket */
|
||||
NFULA_SEQ, /* instance-local sequence number */
|
||||
NFULA_SEQ_GLOBAL, /* global sequence number */
|
||||
|
||||
__NFULA_MAX
|
||||
};
|
||||
#define NFULA_MAX (__NFULA_MAX - 1)
|
||||
|
||||
enum nfulnl_msg_config_cmds {
|
||||
NFULNL_CFG_CMD_NONE,
|
||||
NFULNL_CFG_CMD_BIND,
|
||||
NFULNL_CFG_CMD_UNBIND,
|
||||
NFULNL_CFG_CMD_PF_BIND,
|
||||
NFULNL_CFG_CMD_PF_UNBIND,
|
||||
};
|
||||
|
||||
struct nfulnl_msg_config_cmd {
|
||||
u_int8_t command; /* nfulnl_msg_config_cmds */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfulnl_msg_config_mode {
|
||||
__be32 copy_range;
|
||||
u_int8_t copy_mode;
|
||||
u_int8_t _pad;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum nfulnl_attr_config {
|
||||
NFULA_CFG_UNSPEC,
|
||||
NFULA_CFG_CMD, /* nfulnl_msg_config_cmd */
|
||||
NFULA_CFG_MODE, /* nfulnl_msg_config_mode */
|
||||
NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */
|
||||
NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */
|
||||
NFULA_CFG_QTHRESH, /* u_int32_t */
|
||||
NFULA_CFG_FLAGS, /* u_int16_t */
|
||||
__NFULA_CFG_MAX
|
||||
};
|
||||
#define NFULA_CFG_MAX (__NFULA_CFG_MAX -1)
|
||||
|
||||
#define NFULNL_COPY_NONE 0x00
|
||||
#define NFULNL_COPY_META 0x01
|
||||
#define NFULNL_COPY_PACKET 0x02
|
||||
|
||||
#define NFULNL_CFG_F_SEQ 0x0001
|
||||
#define NFULNL_CFG_F_SEQ_GLOBAL 0x0002
|
||||
|
||||
#endif /* _NFNETLINK_LOG_H */
|
150
include/linux/netlink.h
Normal file
150
include/linux/netlink.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
#ifndef __LINUX_NETLINK_H
|
||||
#define __LINUX_NETLINK_H
|
||||
|
||||
#include <linux/socket.h> /* for sa_family_t */
|
||||
#include <linux/types.h>
|
||||
|
||||
#define NETLINK_ROUTE 0 /* Routing/device hook */
|
||||
#define NETLINK_UNUSED 1 /* Unused number */
|
||||
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
|
||||
#define NETLINK_FIREWALL 3 /* Firewalling hook */
|
||||
#define NETLINK_INET_DIAG 4 /* INET socket monitoring */
|
||||
#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
|
||||
#define NETLINK_XFRM 6 /* ipsec */
|
||||
#define NETLINK_SELINUX 7 /* SELinux event notifications */
|
||||
#define NETLINK_ISCSI 8 /* Open-iSCSI */
|
||||
#define NETLINK_AUDIT 9 /* auditing */
|
||||
#define NETLINK_FIB_LOOKUP 10
|
||||
#define NETLINK_CONNECTOR 11
|
||||
#define NETLINK_NETFILTER 12 /* netfilter subsystem */
|
||||
#define NETLINK_IP6_FW 13
|
||||
#define NETLINK_DNRTMSG 14 /* DECnet routing messages */
|
||||
#define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */
|
||||
#define NETLINK_GENERIC 16
|
||||
/* leave room for NETLINK_DM (DM Events) */
|
||||
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
|
||||
#define NETLINK_ECRYPTFS 19
|
||||
|
||||
#define MAX_LINKS 32
|
||||
|
||||
struct sockaddr_nl
|
||||
{
|
||||
sa_family_t nl_family; /* AF_NETLINK */
|
||||
unsigned short nl_pad; /* zero */
|
||||
__u32 nl_pid; /* port ID */
|
||||
__u32 nl_groups; /* multicast groups mask */
|
||||
};
|
||||
|
||||
struct nlmsghdr
|
||||
{
|
||||
__u32 nlmsg_len; /* Length of message including header */
|
||||
__u16 nlmsg_type; /* Message content */
|
||||
__u16 nlmsg_flags; /* Additional flags */
|
||||
__u32 nlmsg_seq; /* Sequence number */
|
||||
__u32 nlmsg_pid; /* Sending process port ID */
|
||||
};
|
||||
|
||||
/* Flags values */
|
||||
|
||||
#define NLM_F_REQUEST 1 /* It is request message. */
|
||||
#define NLM_F_MULTI 2 /* Multipart message, terminated by NLMSG_DONE */
|
||||
#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
|
||||
#define NLM_F_ECHO 8 /* Echo this request */
|
||||
|
||||
/* Modifiers to GET request */
|
||||
#define NLM_F_ROOT 0x100 /* specify tree root */
|
||||
#define NLM_F_MATCH 0x200 /* return all matching */
|
||||
#define NLM_F_ATOMIC 0x400 /* atomic GET */
|
||||
#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
|
||||
|
||||
/* Modifiers to NEW request */
|
||||
#define NLM_F_REPLACE 0x100 /* Override existing */
|
||||
#define NLM_F_EXCL 0x200 /* Do not touch, if it exists */
|
||||
#define NLM_F_CREATE 0x400 /* Create, if it does not exist */
|
||||
#define NLM_F_APPEND 0x800 /* Add to end of list */
|
||||
|
||||
/*
|
||||
4.4BSD ADD NLM_F_CREATE|NLM_F_EXCL
|
||||
4.4BSD CHANGE NLM_F_REPLACE
|
||||
|
||||
True CHANGE NLM_F_CREATE|NLM_F_REPLACE
|
||||
Append NLM_F_CREATE
|
||||
Check NLM_F_EXCL
|
||||
*/
|
||||
|
||||
#define NLMSG_ALIGNTO 4
|
||||
#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
|
||||
#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
|
||||
#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
|
||||
#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
|
||||
#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
|
||||
#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
|
||||
(struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
|
||||
#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) && \
|
||||
(nlh)->nlmsg_len >= sizeof(struct nlmsghdr) && \
|
||||
(nlh)->nlmsg_len <= (len))
|
||||
#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
|
||||
|
||||
#define NLMSG_NOOP 0x1 /* Nothing. */
|
||||
#define NLMSG_ERROR 0x2 /* Error */
|
||||
#define NLMSG_DONE 0x3 /* End of a dump */
|
||||
#define NLMSG_OVERRUN 0x4 /* Data lost */
|
||||
|
||||
#define NLMSG_MIN_TYPE 0x10 /* < 0x10: reserved control messages */
|
||||
|
||||
struct nlmsgerr
|
||||
{
|
||||
int error;
|
||||
struct nlmsghdr msg;
|
||||
};
|
||||
|
||||
#define NETLINK_ADD_MEMBERSHIP 1
|
||||
#define NETLINK_DROP_MEMBERSHIP 2
|
||||
#define NETLINK_PKTINFO 3
|
||||
|
||||
struct nl_pktinfo
|
||||
{
|
||||
__u32 group;
|
||||
};
|
||||
|
||||
#define NET_MAJOR 36 /* Major 36 is reserved for networking */
|
||||
|
||||
enum {
|
||||
NETLINK_UNCONNECTED = 0,
|
||||
NETLINK_CONNECTED,
|
||||
};
|
||||
|
||||
/*
|
||||
* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* | Header | Pad | Payload | Pad |
|
||||
* | (struct nlattr) | ing | | ing |
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* <-------------- nlattr->nla_len -------------->
|
||||
*/
|
||||
|
||||
struct nlattr
|
||||
{
|
||||
__u16 nla_len;
|
||||
__u16 nla_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* nla_type (16 bits)
|
||||
* +---+---+-------------------------------+
|
||||
* | N | O | Attribute Type |
|
||||
* +---+---+-------------------------------+
|
||||
* N := Carries nested attributes
|
||||
* O := Payload stored in network byte order
|
||||
*
|
||||
* Note: The N and O flag are mutually exclusive.
|
||||
*/
|
||||
#define NLA_F_NESTED (1 << 15)
|
||||
#define NLA_F_NET_BYTEORDER (1 << 14)
|
||||
#define NLA_TYPE_MASK ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
|
||||
|
||||
#define NLA_ALIGNTO 4
|
||||
#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
|
||||
#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
|
||||
|
||||
#endif /* __LINUX_NETLINK_H */
|
426
include/linux/pkt_cls.h
Normal file
426
include/linux/pkt_cls.h
Normal file
|
@ -0,0 +1,426 @@
|
|||
#ifndef __LINUX_PKT_CLS_H
|
||||
#define __LINUX_PKT_CLS_H
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
/* I think i could have done better macros ; for now this is stolen from
|
||||
* some arch/mips code - jhs
|
||||
*/
|
||||
#define _TC_MAKE32(x) ((x))
|
||||
|
||||
#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n))
|
||||
#define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n))
|
||||
#define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n))
|
||||
#define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n))
|
||||
|
||||
/* verdict bit breakdown
|
||||
*
|
||||
bit 0: when set -> this packet has been munged already
|
||||
|
||||
bit 1: when set -> It is ok to munge this packet
|
||||
|
||||
bit 2,3,4,5: Reclassify counter - sort of reverse TTL - if exceeded
|
||||
assume loop
|
||||
|
||||
bit 6,7: Where this packet was last seen
|
||||
0: Above the transmit example at the socket level
|
||||
1: on the Ingress
|
||||
2: on the Egress
|
||||
|
||||
bit 8: when set --> Request not to classify on ingress.
|
||||
|
||||
bits 9,10,11: redirect counter - redirect TTL. Loop avoidance
|
||||
|
||||
*
|
||||
* */
|
||||
|
||||
#define TC_MUNGED _TC_MAKEMASK1(0)
|
||||
#define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED))
|
||||
#define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED)
|
||||
|
||||
#define TC_OK2MUNGE _TC_MAKEMASK1(1)
|
||||
#define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE))
|
||||
#define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE)
|
||||
|
||||
#define S_TC_VERD _TC_MAKE32(2)
|
||||
#define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD)
|
||||
#define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD)
|
||||
#define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD)
|
||||
#define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD))
|
||||
|
||||
#define S_TC_FROM _TC_MAKE32(6)
|
||||
#define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM)
|
||||
#define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM)
|
||||
#define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM)
|
||||
#define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM))
|
||||
#define AT_STACK 0x0
|
||||
#define AT_INGRESS 0x1
|
||||
#define AT_EGRESS 0x2
|
||||
|
||||
#define TC_NCLS _TC_MAKEMASK1(8)
|
||||
#define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS))
|
||||
#define CLR_TC_NCLS(v) ( v & ~TC_NCLS)
|
||||
|
||||
#define S_TC_RTTL _TC_MAKE32(9)
|
||||
#define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL)
|
||||
#define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL)
|
||||
#define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL)
|
||||
#define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL))
|
||||
|
||||
#define S_TC_AT _TC_MAKE32(12)
|
||||
#define M_TC_AT _TC_MAKEMASK(2,S_TC_AT)
|
||||
#define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT)
|
||||
#define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT)
|
||||
#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT))
|
||||
|
||||
/* Action attributes */
|
||||
enum
|
||||
{
|
||||
TCA_ACT_UNSPEC,
|
||||
TCA_ACT_KIND,
|
||||
TCA_ACT_OPTIONS,
|
||||
TCA_ACT_INDEX,
|
||||
TCA_ACT_STATS,
|
||||
__TCA_ACT_MAX
|
||||
};
|
||||
|
||||
#define TCA_ACT_MAX __TCA_ACT_MAX
|
||||
#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
|
||||
#define TCA_ACT_MAX_PRIO 32
|
||||
#define TCA_ACT_BIND 1
|
||||
#define TCA_ACT_NOBIND 0
|
||||
#define TCA_ACT_UNBIND 1
|
||||
#define TCA_ACT_NOUNBIND 0
|
||||
#define TCA_ACT_REPLACE 1
|
||||
#define TCA_ACT_NOREPLACE 0
|
||||
#define MAX_REC_LOOP 4
|
||||
#define MAX_RED_LOOP 4
|
||||
|
||||
#define TC_ACT_UNSPEC (-1)
|
||||
#define TC_ACT_OK 0
|
||||
#define TC_ACT_RECLASSIFY 1
|
||||
#define TC_ACT_SHOT 2
|
||||
#define TC_ACT_PIPE 3
|
||||
#define TC_ACT_STOLEN 4
|
||||
#define TC_ACT_QUEUED 5
|
||||
#define TC_ACT_REPEAT 6
|
||||
#define TC_ACT_JUMP 0x10000000
|
||||
|
||||
/* Action type identifiers*/
|
||||
enum
|
||||
{
|
||||
TCA_ID_UNSPEC=0,
|
||||
TCA_ID_POLICE=1,
|
||||
/* other actions go here */
|
||||
__TCA_ID_MAX=255
|
||||
};
|
||||
|
||||
#define TCA_ID_MAX __TCA_ID_MAX
|
||||
|
||||
struct tc_police
|
||||
{
|
||||
__u32 index;
|
||||
int action;
|
||||
#define TC_POLICE_UNSPEC TC_ACT_UNSPEC
|
||||
#define TC_POLICE_OK TC_ACT_OK
|
||||
#define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY
|
||||
#define TC_POLICE_SHOT TC_ACT_SHOT
|
||||
#define TC_POLICE_PIPE TC_ACT_PIPE
|
||||
|
||||
__u32 limit;
|
||||
__u32 burst;
|
||||
__u32 mtu;
|
||||
struct tc_ratespec rate;
|
||||
struct tc_ratespec peakrate;
|
||||
int refcnt;
|
||||
int bindcnt;
|
||||
__u32 capab;
|
||||
};
|
||||
|
||||
struct tcf_t
|
||||
{
|
||||
__u64 install;
|
||||
__u64 lastuse;
|
||||
__u64 expires;
|
||||
};
|
||||
|
||||
struct tc_cnt
|
||||
{
|
||||
int refcnt;
|
||||
int bindcnt;
|
||||
};
|
||||
|
||||
#define tc_gen \
|
||||
__u32 index; \
|
||||
__u32 capab; \
|
||||
int action; \
|
||||
int refcnt; \
|
||||
int bindcnt
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_POLICE_UNSPEC,
|
||||
TCA_POLICE_TBF,
|
||||
TCA_POLICE_RATE,
|
||||
TCA_POLICE_PEAKRATE,
|
||||
TCA_POLICE_AVRATE,
|
||||
TCA_POLICE_RESULT,
|
||||
__TCA_POLICE_MAX
|
||||
#define TCA_POLICE_RESULT TCA_POLICE_RESULT
|
||||
};
|
||||
|
||||
#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
|
||||
|
||||
/* U32 filters */
|
||||
|
||||
#define TC_U32_HTID(h) ((h)&0xFFF00000)
|
||||
#define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20)
|
||||
#define TC_U32_HASH(h) (((h)>>12)&0xFF)
|
||||
#define TC_U32_NODE(h) ((h)&0xFFF)
|
||||
#define TC_U32_KEY(h) ((h)&0xFFFFF)
|
||||
#define TC_U32_UNSPEC 0
|
||||
#define TC_U32_ROOT (0xFFF00000)
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_U32_UNSPEC,
|
||||
TCA_U32_CLASSID,
|
||||
TCA_U32_HASH,
|
||||
TCA_U32_LINK,
|
||||
TCA_U32_DIVISOR,
|
||||
TCA_U32_SEL,
|
||||
TCA_U32_POLICE,
|
||||
TCA_U32_ACT,
|
||||
TCA_U32_INDEV,
|
||||
TCA_U32_PCNT,
|
||||
TCA_U32_MARK,
|
||||
__TCA_U32_MAX
|
||||
};
|
||||
|
||||
#define TCA_U32_MAX (__TCA_U32_MAX - 1)
|
||||
|
||||
struct tc_u32_key
|
||||
{
|
||||
__u32 mask;
|
||||
__u32 val;
|
||||
int off;
|
||||
int offmask;
|
||||
};
|
||||
|
||||
struct tc_u32_sel
|
||||
{
|
||||
unsigned char flags;
|
||||
unsigned char offshift;
|
||||
unsigned char nkeys;
|
||||
|
||||
__u16 offmask;
|
||||
__u16 off;
|
||||
short offoff;
|
||||
|
||||
short hoff;
|
||||
__u32 hmask;
|
||||
struct tc_u32_key keys[0];
|
||||
};
|
||||
|
||||
struct tc_u32_mark
|
||||
{
|
||||
__u32 val;
|
||||
__u32 mask;
|
||||
__u32 success;
|
||||
};
|
||||
|
||||
struct tc_u32_pcnt
|
||||
{
|
||||
__u64 rcnt;
|
||||
__u64 rhit;
|
||||
__u64 kcnts[0];
|
||||
};
|
||||
|
||||
/* Flags */
|
||||
|
||||
#define TC_U32_TERMINAL 1
|
||||
#define TC_U32_OFFSET 2
|
||||
#define TC_U32_VAROFFSET 4
|
||||
#define TC_U32_EAT 8
|
||||
|
||||
#define TC_U32_MAXDEPTH 8
|
||||
|
||||
|
||||
/* RSVP filter */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_RSVP_UNSPEC,
|
||||
TCA_RSVP_CLASSID,
|
||||
TCA_RSVP_DST,
|
||||
TCA_RSVP_SRC,
|
||||
TCA_RSVP_PINFO,
|
||||
TCA_RSVP_POLICE,
|
||||
TCA_RSVP_ACT,
|
||||
__TCA_RSVP_MAX
|
||||
};
|
||||
|
||||
#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 )
|
||||
|
||||
struct tc_rsvp_gpi
|
||||
{
|
||||
__u32 key;
|
||||
__u32 mask;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct tc_rsvp_pinfo
|
||||
{
|
||||
struct tc_rsvp_gpi dpi;
|
||||
struct tc_rsvp_gpi spi;
|
||||
__u8 protocol;
|
||||
__u8 tunnelid;
|
||||
__u8 tunnelhdr;
|
||||
__u8 pad;
|
||||
};
|
||||
|
||||
/* ROUTE filter */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_ROUTE4_UNSPEC,
|
||||
TCA_ROUTE4_CLASSID,
|
||||
TCA_ROUTE4_TO,
|
||||
TCA_ROUTE4_FROM,
|
||||
TCA_ROUTE4_IIF,
|
||||
TCA_ROUTE4_POLICE,
|
||||
TCA_ROUTE4_ACT,
|
||||
__TCA_ROUTE4_MAX
|
||||
};
|
||||
|
||||
#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
|
||||
|
||||
|
||||
/* FW filter */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_FW_UNSPEC,
|
||||
TCA_FW_CLASSID,
|
||||
TCA_FW_POLICE,
|
||||
TCA_FW_INDEV, /* used by CONFIG_NET_CLS_IND */
|
||||
TCA_FW_ACT, /* used by CONFIG_NET_CLS_ACT */
|
||||
TCA_FW_MASK,
|
||||
__TCA_FW_MAX
|
||||
};
|
||||
|
||||
#define TCA_FW_MAX (__TCA_FW_MAX - 1)
|
||||
|
||||
/* TC index filter */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_TCINDEX_UNSPEC,
|
||||
TCA_TCINDEX_HASH,
|
||||
TCA_TCINDEX_MASK,
|
||||
TCA_TCINDEX_SHIFT,
|
||||
TCA_TCINDEX_FALL_THROUGH,
|
||||
TCA_TCINDEX_CLASSID,
|
||||
TCA_TCINDEX_POLICE,
|
||||
TCA_TCINDEX_ACT,
|
||||
__TCA_TCINDEX_MAX
|
||||
};
|
||||
|
||||
#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
|
||||
|
||||
/* Basic filter */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_BASIC_UNSPEC,
|
||||
TCA_BASIC_CLASSID,
|
||||
TCA_BASIC_EMATCHES,
|
||||
TCA_BASIC_ACT,
|
||||
TCA_BASIC_POLICE,
|
||||
__TCA_BASIC_MAX
|
||||
};
|
||||
|
||||
#define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
|
||||
|
||||
/* Extended Matches */
|
||||
|
||||
struct tcf_ematch_tree_hdr
|
||||
{
|
||||
__u16 nmatches;
|
||||
__u16 progid;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_EMATCH_TREE_UNSPEC,
|
||||
TCA_EMATCH_TREE_HDR,
|
||||
TCA_EMATCH_TREE_LIST,
|
||||
__TCA_EMATCH_TREE_MAX
|
||||
};
|
||||
#define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1)
|
||||
|
||||
struct tcf_ematch_hdr
|
||||
{
|
||||
__u16 matchid;
|
||||
__u16 kind;
|
||||
__u16 flags;
|
||||
__u16 pad; /* currently unused */
|
||||
};
|
||||
|
||||
/* 0 1
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
* +-----------------------+-+-+---+
|
||||
* | Unused |S|I| R |
|
||||
* +-----------------------+-+-+---+
|
||||
*
|
||||
* R(2) ::= relation to next ematch
|
||||
* where: 0 0 END (last ematch)
|
||||
* 0 1 AND
|
||||
* 1 0 OR
|
||||
* 1 1 Unused (invalid)
|
||||
* I(1) ::= invert result
|
||||
* S(1) ::= simple payload
|
||||
*/
|
||||
#define TCF_EM_REL_END 0
|
||||
#define TCF_EM_REL_AND (1<<0)
|
||||
#define TCF_EM_REL_OR (1<<1)
|
||||
#define TCF_EM_INVERT (1<<2)
|
||||
#define TCF_EM_SIMPLE (1<<3)
|
||||
|
||||
#define TCF_EM_REL_MASK 3
|
||||
#define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK)
|
||||
|
||||
enum
|
||||
{
|
||||
TCF_LAYER_LINK,
|
||||
TCF_LAYER_NETWORK,
|
||||
TCF_LAYER_TRANSPORT,
|
||||
__TCF_LAYER_MAX
|
||||
};
|
||||
#define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1)
|
||||
|
||||
/* Ematch type assignments
|
||||
* 1..32767 Reserved for ematches inside kernel tree
|
||||
* 32768..65535 Free to use, not reliable
|
||||
*/
|
||||
#define TCF_EM_CONTAINER 0
|
||||
#define TCF_EM_CMP 1
|
||||
#define TCF_EM_NBYTE 2
|
||||
#define TCF_EM_U32 3
|
||||
#define TCF_EM_META 4
|
||||
#define TCF_EM_TEXT 5
|
||||
#define TCF_EM_MAX 5
|
||||
|
||||
enum
|
||||
{
|
||||
TCF_EM_PROG_TC
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCF_EM_OPND_EQ,
|
||||
TCF_EM_OPND_GT,
|
||||
TCF_EM_OPND_LT
|
||||
};
|
||||
|
||||
#endif
|
478
include/linux/pkt_sched.h
Normal file
478
include/linux/pkt_sched.h
Normal file
|
@ -0,0 +1,478 @@
|
|||
#ifndef __LINUX_PKT_SCHED_H
|
||||
#define __LINUX_PKT_SCHED_H
|
||||
|
||||
/* Logical priority bands not depending on specific packet scheduler.
|
||||
Every scheduler will map them to real traffic classes, if it has
|
||||
no more precise mechanism to classify packets.
|
||||
|
||||
These numbers have no special meaning, though their coincidence
|
||||
with obsolete IPv6 values is not occasional :-). New IPv6 drafts
|
||||
preferred full anarchy inspired by diffserv group.
|
||||
|
||||
Note: TC_PRIO_BESTEFFORT does not mean that it is the most unhappy
|
||||
class, actually, as rule it will be handled with more care than
|
||||
filler or even bulk.
|
||||
*/
|
||||
|
||||
#define TC_PRIO_BESTEFFORT 0
|
||||
#define TC_PRIO_FILLER 1
|
||||
#define TC_PRIO_BULK 2
|
||||
#define TC_PRIO_INTERACTIVE_BULK 4
|
||||
#define TC_PRIO_INTERACTIVE 6
|
||||
#define TC_PRIO_CONTROL 7
|
||||
|
||||
#define TC_PRIO_MAX 15
|
||||
|
||||
/* Generic queue statistics, available for all the elements.
|
||||
Particular schedulers may have also their private records.
|
||||
*/
|
||||
|
||||
struct tc_stats
|
||||
{
|
||||
__u64 bytes; /* NUmber of enqueues bytes */
|
||||
__u32 packets; /* Number of enqueued packets */
|
||||
__u32 drops; /* Packets dropped because of lack of resources */
|
||||
__u32 overlimits; /* Number of throttle events when this
|
||||
* flow goes out of allocated bandwidth */
|
||||
__u32 bps; /* Current flow byte rate */
|
||||
__u32 pps; /* Current flow packet rate */
|
||||
__u32 qlen;
|
||||
__u32 backlog;
|
||||
};
|
||||
|
||||
struct tc_estimator
|
||||
{
|
||||
signed char interval;
|
||||
unsigned char ewma_log;
|
||||
};
|
||||
|
||||
/* "Handles"
|
||||
---------
|
||||
|
||||
All the traffic control objects have 32bit identifiers, or "handles".
|
||||
|
||||
They can be considered as opaque numbers from user API viewpoint,
|
||||
but actually they always consist of two fields: major and
|
||||
minor numbers, which are interpreted by kernel specially,
|
||||
that may be used by applications, though not recommended.
|
||||
|
||||
F.e. qdisc handles always have minor number equal to zero,
|
||||
classes (or flows) have major equal to parent qdisc major, and
|
||||
minor uniquely identifying class inside qdisc.
|
||||
|
||||
Macros to manipulate handles:
|
||||
*/
|
||||
|
||||
#define TC_H_MAJ_MASK (0xFFFF0000U)
|
||||
#define TC_H_MIN_MASK (0x0000FFFFU)
|
||||
#define TC_H_MAJ(h) ((h)&TC_H_MAJ_MASK)
|
||||
#define TC_H_MIN(h) ((h)&TC_H_MIN_MASK)
|
||||
#define TC_H_MAKE(maj,min) (((maj)&TC_H_MAJ_MASK)|((min)&TC_H_MIN_MASK))
|
||||
|
||||
#define TC_H_UNSPEC (0U)
|
||||
#define TC_H_ROOT (0xFFFFFFFFU)
|
||||
#define TC_H_INGRESS (0xFFFFFFF1U)
|
||||
|
||||
struct tc_ratespec
|
||||
{
|
||||
unsigned char cell_log;
|
||||
unsigned char __reserved;
|
||||
unsigned short feature;
|
||||
short addend;
|
||||
unsigned short mpu;
|
||||
__u32 rate;
|
||||
};
|
||||
|
||||
/* FIFO section */
|
||||
|
||||
struct tc_fifo_qopt
|
||||
{
|
||||
__u32 limit; /* Queue length: bytes for bfifo, packets for pfifo */
|
||||
};
|
||||
|
||||
/* PRIO section */
|
||||
|
||||
#define TCQ_PRIO_BANDS 16
|
||||
#define TCQ_MIN_PRIO_BANDS 2
|
||||
|
||||
struct tc_prio_qopt
|
||||
{
|
||||
int bands; /* Number of bands */
|
||||
__u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_PRIO_UNSPEC,
|
||||
TCA_PRIO_MQ,
|
||||
__TCA_PRIO_MAX
|
||||
};
|
||||
|
||||
#define TCA_PRIO_MAX (__TCA_PRIO_MAX - 1)
|
||||
|
||||
/* TBF section */
|
||||
|
||||
struct tc_tbf_qopt
|
||||
{
|
||||
struct tc_ratespec rate;
|
||||
struct tc_ratespec peakrate;
|
||||
__u32 limit;
|
||||
__u32 buffer;
|
||||
__u32 mtu;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_TBF_UNSPEC,
|
||||
TCA_TBF_PARMS,
|
||||
TCA_TBF_RTAB,
|
||||
TCA_TBF_PTAB,
|
||||
__TCA_TBF_MAX,
|
||||
};
|
||||
|
||||
#define TCA_TBF_MAX (__TCA_TBF_MAX - 1)
|
||||
|
||||
|
||||
/* TEQL section */
|
||||
|
||||
/* TEQL does not require any parameters */
|
||||
|
||||
/* SFQ section */
|
||||
|
||||
struct tc_sfq_qopt
|
||||
{
|
||||
unsigned quantum; /* Bytes per round allocated to flow */
|
||||
int perturb_period; /* Period of hash perturbation */
|
||||
__u32 limit; /* Maximal packets in queue */
|
||||
unsigned divisor; /* Hash divisor */
|
||||
unsigned flows; /* Maximal number of flows */
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: limit, divisor and flows are hardwired to code at the moment.
|
||||
*
|
||||
* limit=flows=128, divisor=1024;
|
||||
*
|
||||
* The only reason for this is efficiency, it is possible
|
||||
* to change these parameters in compile time.
|
||||
*/
|
||||
|
||||
/* RED section */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_RED_UNSPEC,
|
||||
TCA_RED_PARMS,
|
||||
TCA_RED_STAB,
|
||||
__TCA_RED_MAX,
|
||||
};
|
||||
|
||||
#define TCA_RED_MAX (__TCA_RED_MAX - 1)
|
||||
|
||||
struct tc_red_qopt
|
||||
{
|
||||
__u32 limit; /* HARD maximal queue length (bytes) */
|
||||
__u32 qth_min; /* Min average length threshold (bytes) */
|
||||
__u32 qth_max; /* Max average length threshold (bytes) */
|
||||
unsigned char Wlog; /* log(W) */
|
||||
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
|
||||
unsigned char Scell_log; /* cell size for idle damping */
|
||||
unsigned char flags;
|
||||
#define TC_RED_ECN 1
|
||||
#define TC_RED_HARDDROP 2
|
||||
};
|
||||
|
||||
struct tc_red_xstats
|
||||
{
|
||||
__u32 early; /* Early drops */
|
||||
__u32 pdrop; /* Drops due to queue limits */
|
||||
__u32 other; /* Drops due to drop() calls */
|
||||
__u32 marked; /* Marked packets */
|
||||
};
|
||||
|
||||
/* GRED section */
|
||||
|
||||
#define MAX_DPs 16
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_GRED_UNSPEC,
|
||||
TCA_GRED_PARMS,
|
||||
TCA_GRED_STAB,
|
||||
TCA_GRED_DPS,
|
||||
__TCA_GRED_MAX,
|
||||
};
|
||||
|
||||
#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
|
||||
|
||||
struct tc_gred_qopt
|
||||
{
|
||||
__u32 limit; /* HARD maximal queue length (bytes) */
|
||||
__u32 qth_min; /* Min average length threshold (bytes) */
|
||||
__u32 qth_max; /* Max average length threshold (bytes) */
|
||||
__u32 DP; /* upto 2^32 DPs */
|
||||
__u32 backlog;
|
||||
__u32 qave;
|
||||
__u32 forced;
|
||||
__u32 early;
|
||||
__u32 other;
|
||||
__u32 pdrop;
|
||||
__u8 Wlog; /* log(W) */
|
||||
__u8 Plog; /* log(P_max/(qth_max-qth_min)) */
|
||||
__u8 Scell_log; /* cell size for idle damping */
|
||||
__u8 prio; /* prio of this VQ */
|
||||
__u32 packets;
|
||||
__u32 bytesin;
|
||||
};
|
||||
|
||||
/* gred setup */
|
||||
struct tc_gred_sopt
|
||||
{
|
||||
__u32 DPs;
|
||||
__u32 def_DP;
|
||||
__u8 grio;
|
||||
__u8 flags;
|
||||
__u16 pad1;
|
||||
};
|
||||
|
||||
/* HTB section */
|
||||
#define TC_HTB_NUMPRIO 8
|
||||
#define TC_HTB_MAXDEPTH 8
|
||||
#define TC_HTB_PROTOVER 3 /* the same as HTB and TC's major */
|
||||
|
||||
struct tc_htb_opt
|
||||
{
|
||||
struct tc_ratespec rate;
|
||||
struct tc_ratespec ceil;
|
||||
__u32 buffer;
|
||||
__u32 cbuffer;
|
||||
__u32 quantum;
|
||||
__u32 level; /* out only */
|
||||
__u32 prio;
|
||||
};
|
||||
struct tc_htb_glob
|
||||
{
|
||||
__u32 version; /* to match HTB/TC */
|
||||
__u32 rate2quantum; /* bps->quantum divisor */
|
||||
__u32 defcls; /* default class number */
|
||||
__u32 debug; /* debug flags */
|
||||
|
||||
/* stats */
|
||||
__u32 direct_pkts; /* count of non shapped packets */
|
||||
};
|
||||
enum
|
||||
{
|
||||
TCA_HTB_UNSPEC,
|
||||
TCA_HTB_PARMS,
|
||||
TCA_HTB_INIT,
|
||||
TCA_HTB_CTAB,
|
||||
TCA_HTB_RTAB,
|
||||
__TCA_HTB_MAX,
|
||||
};
|
||||
|
||||
#define TCA_HTB_MAX (__TCA_HTB_MAX - 1)
|
||||
|
||||
struct tc_htb_xstats
|
||||
{
|
||||
__u32 lends;
|
||||
__u32 borrows;
|
||||
__u32 giants; /* too big packets (rate will not be accurate) */
|
||||
__u32 tokens;
|
||||
__u32 ctokens;
|
||||
};
|
||||
|
||||
/* HFSC section */
|
||||
|
||||
struct tc_hfsc_qopt
|
||||
{
|
||||
__u16 defcls; /* default class */
|
||||
};
|
||||
|
||||
struct tc_service_curve
|
||||
{
|
||||
__u32 m1; /* slope of the first segment in bps */
|
||||
__u32 d; /* x-projection of the first segment in us */
|
||||
__u32 m2; /* slope of the second segment in bps */
|
||||
};
|
||||
|
||||
struct tc_hfsc_stats
|
||||
{
|
||||
__u64 work; /* total work done */
|
||||
__u64 rtwork; /* work done by real-time criteria */
|
||||
__u32 period; /* current period */
|
||||
__u32 level; /* class level in hierarchy */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_HFSC_UNSPEC,
|
||||
TCA_HFSC_RSC,
|
||||
TCA_HFSC_FSC,
|
||||
TCA_HFSC_USC,
|
||||
__TCA_HFSC_MAX,
|
||||
};
|
||||
|
||||
#define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1)
|
||||
|
||||
|
||||
/* CBQ section */
|
||||
|
||||
#define TC_CBQ_MAXPRIO 8
|
||||
#define TC_CBQ_MAXLEVEL 8
|
||||
#define TC_CBQ_DEF_EWMA 5
|
||||
|
||||
struct tc_cbq_lssopt
|
||||
{
|
||||
unsigned char change;
|
||||
unsigned char flags;
|
||||
#define TCF_CBQ_LSS_BOUNDED 1
|
||||
#define TCF_CBQ_LSS_ISOLATED 2
|
||||
unsigned char ewma_log;
|
||||
unsigned char level;
|
||||
#define TCF_CBQ_LSS_FLAGS 1
|
||||
#define TCF_CBQ_LSS_EWMA 2
|
||||
#define TCF_CBQ_LSS_MAXIDLE 4
|
||||
#define TCF_CBQ_LSS_MINIDLE 8
|
||||
#define TCF_CBQ_LSS_OFFTIME 0x10
|
||||
#define TCF_CBQ_LSS_AVPKT 0x20
|
||||
__u32 maxidle;
|
||||
__u32 minidle;
|
||||
__u32 offtime;
|
||||
__u32 avpkt;
|
||||
};
|
||||
|
||||
struct tc_cbq_wrropt
|
||||
{
|
||||
unsigned char flags;
|
||||
unsigned char priority;
|
||||
unsigned char cpriority;
|
||||
unsigned char __reserved;
|
||||
__u32 allot;
|
||||
__u32 weight;
|
||||
};
|
||||
|
||||
struct tc_cbq_ovl
|
||||
{
|
||||
unsigned char strategy;
|
||||
#define TC_CBQ_OVL_CLASSIC 0
|
||||
#define TC_CBQ_OVL_DELAY 1
|
||||
#define TC_CBQ_OVL_LOWPRIO 2
|
||||
#define TC_CBQ_OVL_DROP 3
|
||||
#define TC_CBQ_OVL_RCLASSIC 4
|
||||
unsigned char priority2;
|
||||
__u16 pad;
|
||||
__u32 penalty;
|
||||
};
|
||||
|
||||
struct tc_cbq_police
|
||||
{
|
||||
unsigned char police;
|
||||
unsigned char __res1;
|
||||
unsigned short __res2;
|
||||
};
|
||||
|
||||
struct tc_cbq_fopt
|
||||
{
|
||||
__u32 split;
|
||||
__u32 defmap;
|
||||
__u32 defchange;
|
||||
};
|
||||
|
||||
struct tc_cbq_xstats
|
||||
{
|
||||
__u32 borrows;
|
||||
__u32 overactions;
|
||||
__s32 avgidle;
|
||||
__s32 undertime;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_CBQ_UNSPEC,
|
||||
TCA_CBQ_LSSOPT,
|
||||
TCA_CBQ_WRROPT,
|
||||
TCA_CBQ_FOPT,
|
||||
TCA_CBQ_OVL_STRATEGY,
|
||||
TCA_CBQ_RATE,
|
||||
TCA_CBQ_RTAB,
|
||||
TCA_CBQ_POLICE,
|
||||
__TCA_CBQ_MAX,
|
||||
};
|
||||
|
||||
#define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1)
|
||||
|
||||
/* dsmark section */
|
||||
|
||||
enum {
|
||||
TCA_DSMARK_UNSPEC,
|
||||
TCA_DSMARK_INDICES,
|
||||
TCA_DSMARK_DEFAULT_INDEX,
|
||||
TCA_DSMARK_SET_TC_INDEX,
|
||||
TCA_DSMARK_MASK,
|
||||
TCA_DSMARK_VALUE,
|
||||
__TCA_DSMARK_MAX,
|
||||
};
|
||||
|
||||
#define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1)
|
||||
|
||||
/* ATM section */
|
||||
|
||||
enum {
|
||||
TCA_ATM_UNSPEC,
|
||||
TCA_ATM_FD, /* file/socket descriptor */
|
||||
TCA_ATM_PTR, /* pointer to descriptor - later */
|
||||
TCA_ATM_HDR, /* LL header */
|
||||
TCA_ATM_EXCESS, /* excess traffic class (0 for CLP) */
|
||||
TCA_ATM_ADDR, /* PVC address (for output only) */
|
||||
TCA_ATM_STATE, /* VC state (ATM_VS_*; for output only) */
|
||||
__TCA_ATM_MAX,
|
||||
};
|
||||
|
||||
#define TCA_ATM_MAX (__TCA_ATM_MAX - 1)
|
||||
|
||||
/* Network emulator */
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_NETEM_UNSPEC,
|
||||
TCA_NETEM_CORR,
|
||||
TCA_NETEM_DELAY_DIST,
|
||||
TCA_NETEM_REORDER,
|
||||
TCA_NETEM_CORRUPT,
|
||||
__TCA_NETEM_MAX,
|
||||
};
|
||||
|
||||
#define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
|
||||
|
||||
struct tc_netem_qopt
|
||||
{
|
||||
__u32 latency; /* added delay (us) */
|
||||
__u32 limit; /* fifo limit (packets) */
|
||||
__u32 loss; /* random packet loss (0=none ~0=100%) */
|
||||
__u32 gap; /* re-ordering gap (0 for none) */
|
||||
__u32 duplicate; /* random packet dup (0=none ~0=100%) */
|
||||
__u32 jitter; /* random jitter in latency (us) */
|
||||
};
|
||||
|
||||
struct tc_netem_corr
|
||||
{
|
||||
__u32 delay_corr; /* delay correlation */
|
||||
__u32 loss_corr; /* packet loss correlation */
|
||||
__u32 dup_corr; /* duplicate correlation */
|
||||
};
|
||||
|
||||
struct tc_netem_reorder
|
||||
{
|
||||
__u32 probability;
|
||||
__u32 correlation;
|
||||
};
|
||||
|
||||
struct tc_netem_corrupt
|
||||
{
|
||||
__u32 probability;
|
||||
__u32 correlation;
|
||||
};
|
||||
|
||||
#define NETEM_DIST_SCALE 8192
|
||||
|
||||
#endif
|
559
include/linux/rtnetlink.h
Normal file
559
include/linux/rtnetlink.h
Normal file
|
@ -0,0 +1,559 @@
|
|||
#ifndef __LINUX_RTNETLINK_H
|
||||
#define __LINUX_RTNETLINK_H
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/if_link.h>
|
||||
#include <linux/if_addr.h>
|
||||
#include <linux/neighbour.h>
|
||||
|
||||
/****
|
||||
* Routing/neighbour discovery messages.
|
||||
****/
|
||||
|
||||
/* Types of messages */
|
||||
|
||||
enum {
|
||||
RTM_BASE = 16,
|
||||
#define RTM_BASE RTM_BASE
|
||||
|
||||
RTM_NEWLINK = 16,
|
||||
#define RTM_NEWLINK RTM_NEWLINK
|
||||
RTM_DELLINK,
|
||||
#define RTM_DELLINK RTM_DELLINK
|
||||
RTM_GETLINK,
|
||||
#define RTM_GETLINK RTM_GETLINK
|
||||
RTM_SETLINK,
|
||||
#define RTM_SETLINK RTM_SETLINK
|
||||
|
||||
RTM_NEWADDR = 20,
|
||||
#define RTM_NEWADDR RTM_NEWADDR
|
||||
RTM_DELADDR,
|
||||
#define RTM_DELADDR RTM_DELADDR
|
||||
RTM_GETADDR,
|
||||
#define RTM_GETADDR RTM_GETADDR
|
||||
|
||||
RTM_NEWROUTE = 24,
|
||||
#define RTM_NEWROUTE RTM_NEWROUTE
|
||||
RTM_DELROUTE,
|
||||
#define RTM_DELROUTE RTM_DELROUTE
|
||||
RTM_GETROUTE,
|
||||
#define RTM_GETROUTE RTM_GETROUTE
|
||||
|
||||
RTM_NEWNEIGH = 28,
|
||||
#define RTM_NEWNEIGH RTM_NEWNEIGH
|
||||
RTM_DELNEIGH,
|
||||
#define RTM_DELNEIGH RTM_DELNEIGH
|
||||
RTM_GETNEIGH,
|
||||
#define RTM_GETNEIGH RTM_GETNEIGH
|
||||
|
||||
RTM_NEWRULE = 32,
|
||||
#define RTM_NEWRULE RTM_NEWRULE
|
||||
RTM_DELRULE,
|
||||
#define RTM_DELRULE RTM_DELRULE
|
||||
RTM_GETRULE,
|
||||
#define RTM_GETRULE RTM_GETRULE
|
||||
|
||||
RTM_NEWQDISC = 36,
|
||||
#define RTM_NEWQDISC RTM_NEWQDISC
|
||||
RTM_DELQDISC,
|
||||
#define RTM_DELQDISC RTM_DELQDISC
|
||||
RTM_GETQDISC,
|
||||
#define RTM_GETQDISC RTM_GETQDISC
|
||||
|
||||
RTM_NEWTCLASS = 40,
|
||||
#define RTM_NEWTCLASS RTM_NEWTCLASS
|
||||
RTM_DELTCLASS,
|
||||
#define RTM_DELTCLASS RTM_DELTCLASS
|
||||
RTM_GETTCLASS,
|
||||
#define RTM_GETTCLASS RTM_GETTCLASS
|
||||
|
||||
RTM_NEWTFILTER = 44,
|
||||
#define RTM_NEWTFILTER RTM_NEWTFILTER
|
||||
RTM_DELTFILTER,
|
||||
#define RTM_DELTFILTER RTM_DELTFILTER
|
||||
RTM_GETTFILTER,
|
||||
#define RTM_GETTFILTER RTM_GETTFILTER
|
||||
|
||||
RTM_NEWACTION = 48,
|
||||
#define RTM_NEWACTION RTM_NEWACTION
|
||||
RTM_DELACTION,
|
||||
#define RTM_DELACTION RTM_DELACTION
|
||||
RTM_GETACTION,
|
||||
#define RTM_GETACTION RTM_GETACTION
|
||||
|
||||
RTM_NEWPREFIX = 52,
|
||||
#define RTM_NEWPREFIX RTM_NEWPREFIX
|
||||
|
||||
RTM_GETMULTICAST = 58,
|
||||
#define RTM_GETMULTICAST RTM_GETMULTICAST
|
||||
|
||||
RTM_GETANYCAST = 62,
|
||||
#define RTM_GETANYCAST RTM_GETANYCAST
|
||||
|
||||
RTM_NEWNEIGHTBL = 64,
|
||||
#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
|
||||
RTM_GETNEIGHTBL = 66,
|
||||
#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
|
||||
RTM_SETNEIGHTBL,
|
||||
#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
|
||||
|
||||
__RTM_MAX,
|
||||
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
|
||||
};
|
||||
|
||||
#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
|
||||
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
|
||||
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
|
||||
|
||||
/*
|
||||
Generic structure for encapsulation of optional route information.
|
||||
It is reminiscent of sockaddr, but with sa_family replaced
|
||||
with attribute type.
|
||||
*/
|
||||
|
||||
struct rtattr
|
||||
{
|
||||
unsigned short rta_len;
|
||||
unsigned short rta_type;
|
||||
};
|
||||
|
||||
/* Macros to handle rtattributes */
|
||||
|
||||
#define RTA_ALIGNTO 4
|
||||
#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
|
||||
#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
|
||||
(rta)->rta_len >= sizeof(struct rtattr) && \
|
||||
(rta)->rta_len <= (len))
|
||||
#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
|
||||
(struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
|
||||
#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
|
||||
#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
|
||||
#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
|
||||
#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Definitions used in routing table administration.
|
||||
****/
|
||||
|
||||
struct rtmsg
|
||||
{
|
||||
unsigned char rtm_family;
|
||||
unsigned char rtm_dst_len;
|
||||
unsigned char rtm_src_len;
|
||||
unsigned char rtm_tos;
|
||||
|
||||
unsigned char rtm_table; /* Routing table id */
|
||||
unsigned char rtm_protocol; /* Routing protocol; see below */
|
||||
unsigned char rtm_scope; /* See below */
|
||||
unsigned char rtm_type; /* See below */
|
||||
|
||||
unsigned rtm_flags;
|
||||
};
|
||||
|
||||
/* rtm_type */
|
||||
|
||||
enum
|
||||
{
|
||||
RTN_UNSPEC,
|
||||
RTN_UNICAST, /* Gateway or direct route */
|
||||
RTN_LOCAL, /* Accept locally */
|
||||
RTN_BROADCAST, /* Accept locally as broadcast,
|
||||
send as broadcast */
|
||||
RTN_ANYCAST, /* Accept locally as broadcast,
|
||||
but send as unicast */
|
||||
RTN_MULTICAST, /* Multicast route */
|
||||
RTN_BLACKHOLE, /* Drop */
|
||||
RTN_UNREACHABLE, /* Destination is unreachable */
|
||||
RTN_PROHIBIT, /* Administratively prohibited */
|
||||
RTN_THROW, /* Not in this table */
|
||||
RTN_NAT, /* Translate this address */
|
||||
RTN_XRESOLVE, /* Use external resolver */
|
||||
__RTN_MAX
|
||||
};
|
||||
|
||||
#define RTN_MAX (__RTN_MAX - 1)
|
||||
|
||||
|
||||
/* rtm_protocol */
|
||||
|
||||
#define RTPROT_UNSPEC 0
|
||||
#define RTPROT_REDIRECT 1 /* Route installed by ICMP redirects;
|
||||
not used by current IPv4 */
|
||||
#define RTPROT_KERNEL 2 /* Route installed by kernel */
|
||||
#define RTPROT_BOOT 3 /* Route installed during boot */
|
||||
#define RTPROT_STATIC 4 /* Route installed by administrator */
|
||||
|
||||
/* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
|
||||
they are just passed from user and back as is.
|
||||
It will be used by hypothetical multiple routing daemons.
|
||||
Note that protocol values should be standardized in order to
|
||||
avoid conflicts.
|
||||
*/
|
||||
|
||||
#define RTPROT_GATED 8 /* Apparently, GateD */
|
||||
#define RTPROT_RA 9 /* RDISC/ND router advertisements */
|
||||
#define RTPROT_MRT 10 /* Merit MRT */
|
||||
#define RTPROT_ZEBRA 11 /* Zebra */
|
||||
#define RTPROT_BIRD 12 /* BIRD */
|
||||
#define RTPROT_DNROUTED 13 /* DECnet routing daemon */
|
||||
#define RTPROT_XORP 14 /* XORP */
|
||||
#define RTPROT_NTK 15 /* Netsukuku */
|
||||
|
||||
/* rtm_scope
|
||||
|
||||
Really it is not scope, but sort of distance to the destination.
|
||||
NOWHERE are reserved for not existing destinations, HOST is our
|
||||
local addresses, LINK are destinations, located on directly attached
|
||||
link and UNIVERSE is everywhere in the Universe.
|
||||
|
||||
Intermediate values are also possible f.e. interior routes
|
||||
could be assigned a value between UNIVERSE and LINK.
|
||||
*/
|
||||
|
||||
enum rt_scope_t
|
||||
{
|
||||
RT_SCOPE_UNIVERSE=0,
|
||||
/* User defined values */
|
||||
RT_SCOPE_SITE=200,
|
||||
RT_SCOPE_LINK=253,
|
||||
RT_SCOPE_HOST=254,
|
||||
RT_SCOPE_NOWHERE=255
|
||||
};
|
||||
|
||||
/* rtm_flags */
|
||||
|
||||
#define RTM_F_NOTIFY 0x100 /* Notify user of route change */
|
||||
#define RTM_F_CLONED 0x200 /* This route is cloned */
|
||||
#define RTM_F_EQUALIZE 0x400 /* Multipath equalizer: NI */
|
||||
#define RTM_F_PREFIX 0x800 /* Prefix addresses */
|
||||
|
||||
/* Reserved table identifiers */
|
||||
|
||||
enum rt_class_t
|
||||
{
|
||||
RT_TABLE_UNSPEC=0,
|
||||
/* User defined values */
|
||||
RT_TABLE_DEFAULT=253,
|
||||
RT_TABLE_MAIN=254,
|
||||
RT_TABLE_LOCAL=255,
|
||||
RT_TABLE_MAX=0xFFFFFFFF
|
||||
};
|
||||
|
||||
|
||||
/* Routing message attributes */
|
||||
|
||||
enum rtattr_type_t
|
||||
{
|
||||
RTA_UNSPEC,
|
||||
RTA_DST,
|
||||
RTA_SRC,
|
||||
RTA_IIF,
|
||||
RTA_OIF,
|
||||
RTA_GATEWAY,
|
||||
RTA_PRIORITY,
|
||||
RTA_PREFSRC,
|
||||
RTA_METRICS,
|
||||
RTA_MULTIPATH,
|
||||
RTA_PROTOINFO,
|
||||
RTA_FLOW,
|
||||
RTA_CACHEINFO,
|
||||
RTA_SESSION,
|
||||
RTA_MP_ALGO,
|
||||
RTA_TABLE,
|
||||
__RTA_MAX
|
||||
};
|
||||
|
||||
#define RTA_MAX (__RTA_MAX - 1)
|
||||
|
||||
#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
|
||||
#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
|
||||
|
||||
/* RTM_MULTIPATH --- array of struct rtnexthop.
|
||||
*
|
||||
* "struct rtnexthop" describes all necessary nexthop information,
|
||||
* i.e. parameters of path to a destination via this nexthop.
|
||||
*
|
||||
* At the moment it is impossible to set different prefsrc, mtu, window
|
||||
* and rtt for different paths from multipath.
|
||||
*/
|
||||
|
||||
struct rtnexthop
|
||||
{
|
||||
unsigned short rtnh_len;
|
||||
unsigned char rtnh_flags;
|
||||
unsigned char rtnh_hops;
|
||||
int rtnh_ifindex;
|
||||
};
|
||||
|
||||
/* rtnh_flags */
|
||||
|
||||
#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
|
||||
#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
|
||||
#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
|
||||
|
||||
/* Macros to handle hexthops */
|
||||
|
||||
#define RTNH_ALIGNTO 4
|
||||
#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
|
||||
#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
|
||||
((int)(rtnh)->rtnh_len) <= (len))
|
||||
#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
|
||||
#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
|
||||
#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
|
||||
#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
|
||||
|
||||
/* RTM_CACHEINFO */
|
||||
|
||||
struct rta_cacheinfo
|
||||
{
|
||||
__u32 rta_clntref;
|
||||
__u32 rta_lastuse;
|
||||
__s32 rta_expires;
|
||||
__u32 rta_error;
|
||||
__u32 rta_used;
|
||||
|
||||
#define RTNETLINK_HAVE_PEERINFO 1
|
||||
__u32 rta_id;
|
||||
__u32 rta_ts;
|
||||
__u32 rta_tsage;
|
||||
};
|
||||
|
||||
/* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
|
||||
|
||||
enum
|
||||
{
|
||||
RTAX_UNSPEC,
|
||||
#define RTAX_UNSPEC RTAX_UNSPEC
|
||||
RTAX_LOCK,
|
||||
#define RTAX_LOCK RTAX_LOCK
|
||||
RTAX_MTU,
|
||||
#define RTAX_MTU RTAX_MTU
|
||||
RTAX_WINDOW,
|
||||
#define RTAX_WINDOW RTAX_WINDOW
|
||||
RTAX_RTT,
|
||||
#define RTAX_RTT RTAX_RTT
|
||||
RTAX_RTTVAR,
|
||||
#define RTAX_RTTVAR RTAX_RTTVAR
|
||||
RTAX_SSTHRESH,
|
||||
#define RTAX_SSTHRESH RTAX_SSTHRESH
|
||||
RTAX_CWND,
|
||||
#define RTAX_CWND RTAX_CWND
|
||||
RTAX_ADVMSS,
|
||||
#define RTAX_ADVMSS RTAX_ADVMSS
|
||||
RTAX_REORDERING,
|
||||
#define RTAX_REORDERING RTAX_REORDERING
|
||||
RTAX_HOPLIMIT,
|
||||
#define RTAX_HOPLIMIT RTAX_HOPLIMIT
|
||||
RTAX_INITCWND,
|
||||
#define RTAX_INITCWND RTAX_INITCWND
|
||||
RTAX_FEATURES,
|
||||
#define RTAX_FEATURES RTAX_FEATURES
|
||||
__RTAX_MAX
|
||||
};
|
||||
|
||||
#define RTAX_MAX (__RTAX_MAX - 1)
|
||||
|
||||
#define RTAX_FEATURE_ECN 0x00000001
|
||||
#define RTAX_FEATURE_SACK 0x00000002
|
||||
#define RTAX_FEATURE_TIMESTAMP 0x00000004
|
||||
#define RTAX_FEATURE_ALLFRAG 0x00000008
|
||||
|
||||
struct rta_session
|
||||
{
|
||||
__u8 proto;
|
||||
__u8 pad1;
|
||||
__u16 pad2;
|
||||
|
||||
union {
|
||||
struct {
|
||||
__u16 sport;
|
||||
__u16 dport;
|
||||
} ports;
|
||||
|
||||
struct {
|
||||
__u8 type;
|
||||
__u8 code;
|
||||
__u16 ident;
|
||||
} icmpt;
|
||||
|
||||
__u32 spi;
|
||||
} u;
|
||||
};
|
||||
|
||||
/****
|
||||
* General form of address family dependent message.
|
||||
****/
|
||||
|
||||
struct rtgenmsg
|
||||
{
|
||||
unsigned char rtgen_family;
|
||||
};
|
||||
|
||||
/*****************************************************************
|
||||
* Link layer specific messages.
|
||||
****/
|
||||
|
||||
/* struct ifinfomsg
|
||||
* passes link level specific information, not dependent
|
||||
* on network protocol.
|
||||
*/
|
||||
|
||||
struct ifinfomsg
|
||||
{
|
||||
unsigned char ifi_family;
|
||||
unsigned char __ifi_pad;
|
||||
unsigned short ifi_type; /* ARPHRD_* */
|
||||
int ifi_index; /* Link index */
|
||||
unsigned ifi_flags; /* IFF_* flags */
|
||||
unsigned ifi_change; /* IFF_* change mask */
|
||||
};
|
||||
|
||||
/********************************************************************
|
||||
* prefix information
|
||||
****/
|
||||
|
||||
struct prefixmsg
|
||||
{
|
||||
unsigned char prefix_family;
|
||||
unsigned char prefix_pad1;
|
||||
unsigned short prefix_pad2;
|
||||
int prefix_ifindex;
|
||||
unsigned char prefix_type;
|
||||
unsigned char prefix_len;
|
||||
unsigned char prefix_flags;
|
||||
unsigned char prefix_pad3;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PREFIX_UNSPEC,
|
||||
PREFIX_ADDRESS,
|
||||
PREFIX_CACHEINFO,
|
||||
__PREFIX_MAX
|
||||
};
|
||||
|
||||
#define PREFIX_MAX (__PREFIX_MAX - 1)
|
||||
|
||||
struct prefix_cacheinfo
|
||||
{
|
||||
__u32 preferred_time;
|
||||
__u32 valid_time;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* Traffic control messages.
|
||||
****/
|
||||
|
||||
struct tcmsg
|
||||
{
|
||||
unsigned char tcm_family;
|
||||
unsigned char tcm__pad1;
|
||||
unsigned short tcm__pad2;
|
||||
int tcm_ifindex;
|
||||
__u32 tcm_handle;
|
||||
__u32 tcm_parent;
|
||||
__u32 tcm_info;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
TCA_UNSPEC,
|
||||
TCA_KIND,
|
||||
TCA_OPTIONS,
|
||||
TCA_STATS,
|
||||
TCA_XSTATS,
|
||||
TCA_RATE,
|
||||
TCA_FCNT,
|
||||
TCA_STATS2,
|
||||
__TCA_MAX
|
||||
};
|
||||
|
||||
#define TCA_MAX (__TCA_MAX - 1)
|
||||
|
||||
#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
|
||||
#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/* RTnetlink multicast groups - backwards compatibility for userspace */
|
||||
#define RTMGRP_LINK 1
|
||||
#define RTMGRP_NOTIFY 2
|
||||
#define RTMGRP_NEIGH 4
|
||||
#define RTMGRP_TC 8
|
||||
|
||||
#define RTMGRP_IPV4_IFADDR 0x10
|
||||
#define RTMGRP_IPV4_MROUTE 0x20
|
||||
#define RTMGRP_IPV4_ROUTE 0x40
|
||||
#define RTMGRP_IPV4_RULE 0x80
|
||||
|
||||
#define RTMGRP_IPV6_IFADDR 0x100
|
||||
#define RTMGRP_IPV6_MROUTE 0x200
|
||||
#define RTMGRP_IPV6_ROUTE 0x400
|
||||
#define RTMGRP_IPV6_IFINFO 0x800
|
||||
|
||||
#define RTMGRP_DECnet_IFADDR 0x1000
|
||||
#define RTMGRP_DECnet_ROUTE 0x4000
|
||||
|
||||
#define RTMGRP_IPV6_PREFIX 0x20000
|
||||
#endif
|
||||
|
||||
/* RTnetlink multicast groups */
|
||||
enum rtnetlink_groups {
|
||||
RTNLGRP_NONE,
|
||||
#define RTNLGRP_NONE RTNLGRP_NONE
|
||||
RTNLGRP_LINK,
|
||||
#define RTNLGRP_LINK RTNLGRP_LINK
|
||||
RTNLGRP_NOTIFY,
|
||||
#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
|
||||
RTNLGRP_NEIGH,
|
||||
#define RTNLGRP_NEIGH RTNLGRP_NEIGH
|
||||
RTNLGRP_TC,
|
||||
#define RTNLGRP_TC RTNLGRP_TC
|
||||
RTNLGRP_IPV4_IFADDR,
|
||||
#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
|
||||
RTNLGRP_IPV4_MROUTE,
|
||||
#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
|
||||
RTNLGRP_IPV4_ROUTE,
|
||||
#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
|
||||
RTNLGRP_IPV4_RULE,
|
||||
#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
|
||||
RTNLGRP_IPV6_IFADDR,
|
||||
#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
|
||||
RTNLGRP_IPV6_MROUTE,
|
||||
#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
|
||||
RTNLGRP_IPV6_ROUTE,
|
||||
#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
|
||||
RTNLGRP_IPV6_IFINFO,
|
||||
#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
|
||||
RTNLGRP_DECnet_IFADDR,
|
||||
#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
|
||||
RTNLGRP_NOP2,
|
||||
RTNLGRP_DECnet_ROUTE,
|
||||
#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
|
||||
RTNLGRP_DECnet_RULE,
|
||||
#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
|
||||
RTNLGRP_NOP4,
|
||||
RTNLGRP_IPV6_PREFIX,
|
||||
#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
|
||||
RTNLGRP_IPV6_RULE,
|
||||
#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
|
||||
__RTNLGRP_MAX
|
||||
};
|
||||
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
|
||||
|
||||
/* TC action piece */
|
||||
struct tcamsg
|
||||
{
|
||||
unsigned char tca_family;
|
||||
unsigned char tca__pad1;
|
||||
unsigned short tca__pad2;
|
||||
};
|
||||
#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
|
||||
#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
|
||||
#define TCA_ACT_TAB 1 /* attr type must be >=1 */
|
||||
#define TCAA_MAX 1
|
||||
|
||||
#endif /* __LINUX_RTNETLINK_H */
|
20
include/netlink-generic.h
Normal file
20
include/netlink-generic.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* netlink-generic.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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_GENL_PRIV_H_
|
||||
#define NETLINK_GENL_PRIV_H_
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#define GENL_HDRSIZE(hdrlen) (GENL_HDRLEN + (hdrlen))
|
||||
|
||||
#endif
|
436
include/netlink-local.h
Normal file
436
include/netlink-local.h
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* netlink-local.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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LOCAL_H_
|
||||
#define NETLINK_LOCAL_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifndef SOL_NETLINK
|
||||
#define SOL_NETLINK 270
|
||||
#endif
|
||||
|
||||
typedef uint8_t __u8;
|
||||
typedef uint16_t __u16;
|
||||
typedef int16_t __s16;
|
||||
typedef uint32_t __u32;
|
||||
typedef int32_t __s32;
|
||||
typedef uint64_t __u64;
|
||||
|
||||
/* local header copies */
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <linux/pkt_cls.h>
|
||||
#include <linux/gen_stats.h>
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/handlers.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/route/tc.h>
|
||||
#include <netlink-types.h>
|
||||
|
||||
struct trans_tbl {
|
||||
int i;
|
||||
const char *a;
|
||||
};
|
||||
|
||||
#define __ADD(id, name) { .i = id, .a = #name },
|
||||
|
||||
struct trans_list {
|
||||
int i;
|
||||
char *a;
|
||||
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); \
|
||||
} while (0)
|
||||
|
||||
#define BUG() \
|
||||
do { \
|
||||
fprintf(stderr, "BUG: %s:%d\n", \
|
||||
__FILE__, __LINE__); \
|
||||
assert(0); \
|
||||
} while (0)
|
||||
|
||||
#define RET_ERR(R, E) \
|
||||
do { \
|
||||
errno = E; \
|
||||
return -R; \
|
||||
} while (0)
|
||||
|
||||
extern int __nl_error(int, const char *, unsigned int,
|
||||
const char *, const char *, ...);
|
||||
|
||||
extern int __nl_read_num_str_file(const char *path,
|
||||
int (*cb)(long, const char *));
|
||||
|
||||
#ifdef NL_ERROR_ASSERT
|
||||
#include <assert.h>
|
||||
static inline int __assert_error(const char *file, int line, char *func,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
fprintf(stderr, "%s:%d:%s: ", file, line, func);
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
fprintf(stderr, "\n");
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
#define nl_error(E, FMT,ARG...) \
|
||||
__assert_error(__FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
|
||||
|
||||
#else
|
||||
#define nl_error(E, FMT,ARG...) \
|
||||
__nl_error(E, __FILE__, __LINE__, __FUNCTION__, FMT, ##ARG)
|
||||
|
||||
#endif
|
||||
|
||||
#define nl_errno(E) nl_error(E, NULL)
|
||||
|
||||
static inline int __trans_list_add(int i, const char *a,
|
||||
struct nl_list_head *head)
|
||||
{
|
||||
struct trans_list *tl;
|
||||
|
||||
tl = calloc(1, sizeof(*tl));
|
||||
if (!tl)
|
||||
return nl_errno(ENOMEM);
|
||||
|
||||
tl->i = i;
|
||||
tl->a = strdup(a);
|
||||
|
||||
nl_list_add_tail(&tl->list, head);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __trans_list_clear(struct nl_list_head *head)
|
||||
{
|
||||
struct trans_list *tl, *next;
|
||||
|
||||
nl_list_for_each_entry_safe(tl, next, head, list) {
|
||||
free(tl->a);
|
||||
free(tl);
|
||||
}
|
||||
}
|
||||
|
||||
static inline char *__type2str(int type, char *buf, size_t len,
|
||||
struct trans_tbl *tbl, size_t tbl_len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < tbl_len; i++) {
|
||||
if (tbl[i].i == type) {
|
||||
snprintf(buf, len, "%s", tbl[i].a);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, len, "0x%x", type);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline char *__list_type2str(int type, char *buf, size_t len,
|
||||
struct nl_list_head *head)
|
||||
{
|
||||
struct trans_list *tl;
|
||||
|
||||
nl_list_for_each_entry(tl, head, list) {
|
||||
if (tl->i == type) {
|
||||
snprintf(buf, len, "%s", tl->a);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, len, "0x%x", type);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline char *__flags2str(int flags, char *buf, size_t len,
|
||||
struct trans_tbl *tbl, size_t tbl_len)
|
||||
{
|
||||
int i;
|
||||
int tmp = flags;
|
||||
|
||||
memset(buf, 0, len);
|
||||
|
||||
for (i = 0; i < tbl_len; i++) {
|
||||
if (tbl[i].i & tmp) {
|
||||
tmp &= ~tbl[i].i;
|
||||
strncat(buf, tbl[i].a, len - strlen(buf) - 1);
|
||||
if ((tmp & flags))
|
||||
strncat(buf, ",", len - strlen(buf) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline int __str2type(const char *buf, struct trans_tbl *tbl,
|
||||
size_t tbl_len)
|
||||
{
|
||||
unsigned long l;
|
||||
char *end;
|
||||
int i;
|
||||
|
||||
if (*buf == '\0')
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < tbl_len; i++)
|
||||
if (!strcasecmp(tbl[i].a, buf))
|
||||
return tbl[i].i;
|
||||
|
||||
l = strtoul(buf, &end, 0);
|
||||
if (l == ULONG_MAX || *end != '\0')
|
||||
return -1;
|
||||
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
static inline int __list_str2type(const char *buf, struct nl_list_head *head)
|
||||
{
|
||||
struct trans_list *tl;
|
||||
unsigned long l;
|
||||
char *end;
|
||||
|
||||
if (*buf == '\0')
|
||||
return -1;
|
||||
|
||||
nl_list_for_each_entry(tl, head, list) {
|
||||
if (!strcasecmp(tl->a, buf))
|
||||
return tl->i;
|
||||
}
|
||||
|
||||
l = strtoul(buf, &end, 0);
|
||||
if (l == ULONG_MAX || *end != '\0')
|
||||
return -1;
|
||||
|
||||
return (int) l;
|
||||
}
|
||||
|
||||
static inline int __str2flags(const char *buf, struct trans_tbl *tbl,
|
||||
size_t tbl_len)
|
||||
{
|
||||
int i, flags = 0, len;
|
||||
char *p = (char *) buf, *t;
|
||||
|
||||
for (;;) {
|
||||
if (*p == ' ')
|
||||
p++;
|
||||
|
||||
t = strchr(p, ',');
|
||||
len = t ? t - p : strlen(p);
|
||||
for (i = 0; i < tbl_len; i++)
|
||||
if (!strncasecmp(tbl[i].a, p, len))
|
||||
flags |= tbl[i].i;
|
||||
|
||||
if (!t)
|
||||
return flags;
|
||||
|
||||
p = ++t;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void dp_new_line(struct nl_dump_params *params,
|
||||
int line_nr)
|
||||
{
|
||||
if (params->dp_prefix) {
|
||||
int i;
|
||||
for (i = 0; i < params->dp_prefix; i++) {
|
||||
if (params->dp_fd)
|
||||
fprintf(params->dp_fd, " ");
|
||||
else if (params->dp_buf)
|
||||
strncat(params->dp_buf, " ",
|
||||
params->dp_buflen -
|
||||
sizeof(params->dp_buf) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (params->dp_nl_cb)
|
||||
params->dp_nl_cb(params, line_nr);
|
||||
}
|
||||
|
||||
static inline void __dp_dump(struct nl_dump_params *parms, const char *fmt,
|
||||
va_list args)
|
||||
{
|
||||
if (parms->dp_fd)
|
||||
vfprintf(parms->dp_fd, fmt, args);
|
||||
else if (parms->dp_buf || parms->dp_cb) {
|
||||
char *buf = NULL;
|
||||
vasprintf(&buf, fmt, args);
|
||||
if (parms->dp_cb)
|
||||
parms->dp_cb(parms, buf);
|
||||
else
|
||||
strncat(parms->dp_buf, buf,
|
||||
parms->dp_buflen - strlen(parms->dp_buf) - 1);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dp_dump(struct nl_dump_params *parms, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
__dp_dump(parms, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static inline void dp_dump_line(struct nl_dump_params *parms, int line,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
dp_new_line(parms, line);
|
||||
|
||||
va_start(args, fmt);
|
||||
__dp_dump(parms, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static inline void dump_from_ops(struct nl_object *obj,
|
||||
struct nl_dump_params *params)
|
||||
{
|
||||
int type = params->dp_type;
|
||||
|
||||
if (type < 0 || type > NL_DUMP_MAX)
|
||||
BUG();
|
||||
|
||||
if (params->dp_dump_msgtype) {
|
||||
#if 0
|
||||
/* XXX */
|
||||
char buf[64];
|
||||
|
||||
dp_dump_line(params, 0, "%s ",
|
||||
nl_cache_mngt_type2name(obj->ce_ops,
|
||||
obj->ce_ops->co_protocol,
|
||||
obj->ce_msgtype,
|
||||
buf, sizeof(buf)));
|
||||
#endif
|
||||
params->dp_pre_dump = 1;
|
||||
} else
|
||||
dp_new_line(params, 0);
|
||||
|
||||
if (obj->ce_ops->oo_dump[type])
|
||||
obj->ce_ops->oo_dump[type](obj, params);
|
||||
}
|
||||
|
||||
static inline struct nl_cache *dp_cache(struct nl_object *obj)
|
||||
{
|
||||
if (obj->ce_cache == NULL)
|
||||
return nl_cache_mngt_require(obj->ce_ops->oo_name);
|
||||
|
||||
return obj->ce_cache;
|
||||
}
|
||||
|
||||
static inline int nl_cb_call(struct nl_cb *cb, int type, struct nl_msg *msg)
|
||||
{
|
||||
return cb->cb_set[type](msg, cb->cb_args[type]);
|
||||
}
|
||||
|
||||
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
|
||||
#define __init __attribute__ ((constructor))
|
||||
#define __exit __attribute__ ((destructor))
|
||||
|
||||
#define P_ACCEPT 0
|
||||
#define P_IGNORE 0
|
||||
|
||||
#define min(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x < _y ? _x : _y; })
|
||||
|
||||
#define max(x,y) ({ \
|
||||
typeof(x) _x = (x); \
|
||||
typeof(y) _y = (y); \
|
||||
(void) (&_x == &_y); \
|
||||
_x > _y ? _x : _y; })
|
||||
|
||||
#define min_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
|
||||
#define max_t(type,x,y) \
|
||||
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
|
||||
|
||||
extern int nl_cache_parse(struct nl_cache_ops *, struct sockaddr_nl *,
|
||||
struct nlmsghdr *, struct nl_parser_param *);
|
||||
|
||||
|
||||
static inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst,
|
||||
struct tc_ratespec *src)
|
||||
{
|
||||
dst->rs_cell_log = src->cell_log;
|
||||
dst->rs_feature = src->feature;
|
||||
dst->rs_addend = src->addend;
|
||||
dst->rs_mpu = src->mpu;
|
||||
dst->rs_rate = src->rate;
|
||||
}
|
||||
|
||||
static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst,
|
||||
struct rtnl_ratespec *src)
|
||||
{
|
||||
dst->cell_log = src->rs_cell_log;
|
||||
dst->feature = src->rs_feature;
|
||||
dst->addend = src->rs_addend;
|
||||
dst->mpu = src->rs_mpu;
|
||||
dst->rate = src->rs_rate;
|
||||
}
|
||||
|
||||
static inline char *nl_cache_name(struct nl_cache *cache)
|
||||
{
|
||||
return cache->c_ops ? cache->c_ops->co_name : "unknown";
|
||||
}
|
||||
|
||||
#define GENL_FAMILY(id, name) \
|
||||
{ \
|
||||
{ id, NL_ACT_UNSPEC, name }, \
|
||||
END_OF_MSGTYPES_LIST, \
|
||||
}
|
||||
|
||||
#define REQUESTED(LIST, ATTR) ((LIST) & (ATTR))
|
||||
#define AVAILABLE(A, B, ATTR) (((A)->ce_mask & (B)->ce_mask) & (ATTR))
|
||||
#define ATTR_MATCH(A, B, ATTR, EXPR) (!AVAILABLE(A, B, ATTR) || (EXPR))
|
||||
#define ATTR_DIFF(LIST, ATTR, A, B, EXPR) \
|
||||
({ int diff = 0; \
|
||||
if (REQUESTED(LIST, ATTR) && ATTR_MATCH(A, B, ATTR, EXPR)) \
|
||||
diff = ATTR; \
|
||||
diff; })
|
||||
|
||||
#endif
|
70
include/netlink-tc.h
Normal file
70
include/netlink-tc.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* netlink-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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_TC_PRIV_H_
|
||||
#define NETLINK_TC_PRIV_H_
|
||||
|
||||
#include <netlink-local.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TCA_ATTR_HANDLE 0x001
|
||||
#define TCA_ATTR_PARENT 0x002
|
||||
#define TCA_ATTR_IFINDEX 0x004
|
||||
#define TCA_ATTR_KIND 0x008
|
||||
#define TCA_ATTR_FAMILY 0x010
|
||||
#define TCA_ATTR_INFO 0x020
|
||||
#define TCA_ATTR_OPTS 0x040
|
||||
#define TCA_ATTR_STATS 0x080
|
||||
#define TCA_ATTR_XSTATS 0x100
|
||||
#define TCA_ATTR_MAX TCA_ATTR_XSTATS
|
||||
|
||||
extern int tca_parse(struct nlattr **, int, struct rtnl_tca *,
|
||||
struct nla_policy *);
|
||||
extern int tca_msg_parser(struct nlmsghdr *, struct rtnl_tca *);
|
||||
extern void tca_free_data(struct rtnl_tca *);
|
||||
extern int tca_clone(struct rtnl_tca *, struct rtnl_tca *);
|
||||
extern int tca_dump_brief(struct rtnl_tca *, const char *,
|
||||
struct nl_dump_params *, int);
|
||||
extern int tca_dump_full(struct rtnl_tca *, struct nl_dump_params *, int);
|
||||
extern int tca_dump_stats(struct rtnl_tca *,
|
||||
struct nl_dump_params *, int);
|
||||
extern int tca_compare(struct nl_object *, struct nl_object *, uint32_t, int);
|
||||
|
||||
extern void tca_set_ifindex(struct rtnl_tca *, int);
|
||||
extern int tca_get_ifindex(struct rtnl_tca *);
|
||||
extern void tca_set_handle(struct rtnl_tca *, uint32_t);
|
||||
extern uint32_t tca_get_handle(struct rtnl_tca *);
|
||||
extern void tca_set_parent(struct rtnl_tca *, uint32_t);
|
||||
extern uint32_t tca_get_parent(struct rtnl_tca *);
|
||||
extern void tca_set_kind(struct rtnl_tca *, const char *);
|
||||
extern char *tca_get_kind(struct rtnl_tca *);
|
||||
extern uint64_t tca_get_stat(struct rtnl_tca *, int );
|
||||
|
||||
extern struct nl_msg *tca_build_msg(struct rtnl_tca *tca, int type, int flags);
|
||||
|
||||
static inline void *tca_priv(struct rtnl_tca *tca)
|
||||
{
|
||||
return tca->tc_subdata;
|
||||
}
|
||||
|
||||
static inline void *tca_xstats(struct rtnl_tca *tca)
|
||||
{
|
||||
return tca->tc_xstats->d_data;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
865
include/netlink-types.h
Normal file
865
include/netlink-types.h
Normal file
|
@ -0,0 +1,865 @@
|
|||
/*
|
||||
* netlink-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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LOCAL_TYPES_H_
|
||||
#define NETLINK_LOCAL_TYPES_H_
|
||||
|
||||
#include <netlink/list.h>
|
||||
#include <netlink/route/link.h>
|
||||
#include <netlink/route/qdisc.h>
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#define NL_SOCK_BUFSIZE_SET (1<<0)
|
||||
#define NL_SOCK_PASSCRED (1<<1)
|
||||
#define NL_OWN_PORT (1<<2)
|
||||
#define NL_MSG_PEEK (1<<3)
|
||||
|
||||
#define NL_MSG_CRED_PRESENT 1
|
||||
|
||||
struct nl_cache_ops;
|
||||
struct nl_handle;
|
||||
struct nl_object;
|
||||
|
||||
struct nl_cb
|
||||
{
|
||||
nl_recvmsg_msg_cb_t cb_set[NL_CB_TYPE_MAX+1];
|
||||
void * cb_args[NL_CB_TYPE_MAX+1];
|
||||
|
||||
nl_recvmsg_err_cb_t cb_err;
|
||||
void * cb_err_arg;
|
||||
|
||||
/** May be used to replace nl_recvmsgs with your own implementation
|
||||
* in all internal calls to nl_recvmsgs. */
|
||||
int (*cb_recvmsgs_ow)(struct nl_handle *,
|
||||
struct nl_cb *);
|
||||
|
||||
/** Overwrite internal calls to nl_recv, must return the number of
|
||||
* octets read and allocate a buffer for the received data. */
|
||||
int (*cb_recv_ow)(struct nl_handle *,
|
||||
struct sockaddr_nl *,
|
||||
unsigned char **,
|
||||
struct ucred **);
|
||||
|
||||
/** Overwrites internal calls to nl_send, must send the netlink
|
||||
* message. */
|
||||
int (*cb_send_ow)(struct nl_handle *,
|
||||
struct nl_msg *);
|
||||
|
||||
int cb_refcnt;
|
||||
};
|
||||
|
||||
struct nl_handle
|
||||
{
|
||||
struct sockaddr_nl h_local;
|
||||
struct sockaddr_nl h_peer;
|
||||
int h_fd;
|
||||
int h_proto;
|
||||
unsigned int h_seq_next;
|
||||
unsigned int h_seq_expect;
|
||||
int h_flags;
|
||||
struct nl_cb * h_cb;
|
||||
};
|
||||
|
||||
struct nl_cache
|
||||
{
|
||||
struct nl_list_head c_items;
|
||||
int c_nitems;
|
||||
int c_iarg1;
|
||||
int c_iarg2;
|
||||
struct nl_cache_ops * c_ops;
|
||||
};
|
||||
|
||||
struct nl_cache_assoc
|
||||
{
|
||||
struct nl_cache * ca_cache;
|
||||
change_func_t ca_change;
|
||||
};
|
||||
|
||||
struct nl_cache_mngr
|
||||
{
|
||||
int cm_protocol;
|
||||
int cm_flags;
|
||||
int cm_nassocs;
|
||||
struct nl_handle * cm_handle;
|
||||
struct nl_cache_assoc * cm_assocs;
|
||||
};
|
||||
|
||||
struct nl_parser_param;
|
||||
|
||||
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 }
|
||||
|
||||
struct nl_msgtype
|
||||
{
|
||||
int mt_id;
|
||||
int mt_act;
|
||||
char * mt_name;
|
||||
};
|
||||
|
||||
struct genl_info
|
||||
{
|
||||
struct sockaddr_nl * who;
|
||||
struct nlmsghdr * nlh;
|
||||
struct genlmsghdr * genlhdr;
|
||||
void * userhdr;
|
||||
struct nlattr ** attrs;
|
||||
};
|
||||
|
||||
#define LOOSE_FLAG_COMPARISON 1
|
||||
|
||||
struct nl_object_ops
|
||||
{
|
||||
/* Name of object */
|
||||
char * oo_name;
|
||||
|
||||
/* Size of object structure */
|
||||
size_t oo_size;
|
||||
|
||||
/* List of attributes needed to uniquely identify the object */
|
||||
uint32_t oo_id_attrs;
|
||||
|
||||
/**
|
||||
* Called whenever a new object was allocated
|
||||
*/
|
||||
void (*oo_constructor)(struct nl_object *);
|
||||
|
||||
/**
|
||||
* Called whenever a object in the cache gets destroyed, must
|
||||
* free the type specific memory allocations
|
||||
*/
|
||||
void (*oo_free_data)(struct nl_object *);
|
||||
|
||||
/**
|
||||
* Callened whenever an object needs to be cloned
|
||||
*/
|
||||
int (*oo_clone)(struct nl_object *, struct nl_object *);
|
||||
|
||||
/**
|
||||
* Called whenever a dump of a cache object is requested. Must
|
||||
* dump the specified object to the specified file descriptor
|
||||
*/
|
||||
int (*oo_dump[NL_DUMP_MAX+1])(struct nl_object *,
|
||||
struct nl_dump_params *);
|
||||
|
||||
int (*oo_compare)(struct nl_object *, struct nl_object *,
|
||||
uint32_t, int);
|
||||
|
||||
|
||||
char *(*oo_attrs2str)(int, char *, size_t);
|
||||
};
|
||||
|
||||
struct nl_af_group
|
||||
{
|
||||
int ag_family;
|
||||
int ag_group;
|
||||
};
|
||||
|
||||
#define END_OF_GROUP_LIST AF_UNSPEC, 0
|
||||
|
||||
struct nl_cache_ops
|
||||
{
|
||||
char * co_name;
|
||||
int co_hdrsize;
|
||||
int co_protocol;
|
||||
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_handle *);
|
||||
|
||||
/**
|
||||
* 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 *, void *);
|
||||
|
||||
struct nl_object_ops * co_obj_ops;
|
||||
|
||||
struct nl_cache_ops *co_next;
|
||||
struct nl_cache *co_major_cache;
|
||||
struct genl_ops * co_genl;
|
||||
struct nl_msgtype co_msgtypes[];
|
||||
};
|
||||
|
||||
#define NL_OBJ_MARK 1
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
struct nl_parser_param
|
||||
{
|
||||
int (*pp_cb)(struct nl_object *, struct nl_parser_param *);
|
||||
void * pp_arg;
|
||||
};
|
||||
|
||||
struct nl_data
|
||||
{
|
||||
size_t d_size;
|
||||
void * d_data;
|
||||
};
|
||||
|
||||
struct nl_addr
|
||||
{
|
||||
int a_family;
|
||||
unsigned int a_maxsize;
|
||||
unsigned int a_len;
|
||||
int a_prefixlen;
|
||||
int a_refcnt;
|
||||
char a_addr[0];
|
||||
};
|
||||
|
||||
struct nl_msg
|
||||
{
|
||||
int nm_protocol;
|
||||
int nm_flags;
|
||||
struct sockaddr_nl nm_src;
|
||||
struct sockaddr_nl nm_dst;
|
||||
struct ucred nm_creds;
|
||||
struct nlmsghdr * nm_nlh;
|
||||
};
|
||||
|
||||
struct rtnl_link_map
|
||||
{
|
||||
uint64_t lm_mem_start;
|
||||
uint64_t lm_mem_end;
|
||||
uint64_t lm_base_addr;
|
||||
uint16_t lm_irq;
|
||||
uint8_t lm_dma;
|
||||
uint8_t lm_port;
|
||||
};
|
||||
|
||||
#define IFQDISCSIZ 32
|
||||
|
||||
struct rtnl_link
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
char l_name[IFNAMSIZ];
|
||||
|
||||
uint32_t l_family;
|
||||
uint32_t l_arptype;
|
||||
uint32_t l_index;
|
||||
uint32_t l_flags;
|
||||
uint32_t l_change;
|
||||
uint32_t l_mtu;
|
||||
uint32_t l_link;
|
||||
uint32_t l_txqlen;
|
||||
uint32_t l_weight;
|
||||
uint32_t l_master;
|
||||
struct nl_addr *l_addr;
|
||||
struct nl_addr *l_bcast;
|
||||
char l_qdisc[IFQDISCSIZ];
|
||||
struct rtnl_link_map l_map;
|
||||
uint64_t l_stats[RTNL_LINK_STATS_MAX+1];
|
||||
uint32_t l_flag_mask;
|
||||
};
|
||||
|
||||
struct rtnl_ncacheinfo
|
||||
{
|
||||
uint32_t nci_confirmed; /**< Time since neighbour validty was last confirmed */
|
||||
uint32_t nci_used; /**< Time since neighbour entry was last ued */
|
||||
uint32_t nci_updated; /**< Time since last update */
|
||||
uint32_t nci_refcnt; /**< Reference counter */
|
||||
};
|
||||
|
||||
|
||||
struct rtnl_neigh
|
||||
{
|
||||
NLHDR_COMMON
|
||||
uint32_t n_family;
|
||||
uint32_t n_ifindex;
|
||||
uint16_t n_state;
|
||||
uint8_t n_flags;
|
||||
uint8_t n_type;
|
||||
struct nl_addr *n_lladdr;
|
||||
struct nl_addr *n_dst;
|
||||
uint32_t n_probes;
|
||||
struct rtnl_ncacheinfo n_cacheinfo;
|
||||
uint32_t n_state_mask;
|
||||
uint32_t n_flag_mask;
|
||||
};
|
||||
|
||||
|
||||
struct rtnl_addr_cacheinfo
|
||||
{
|
||||
/* Preferred lifetime in seconds */
|
||||
uint32_t aci_prefered;
|
||||
|
||||
/* Valid lifetime in seconds */
|
||||
uint32_t aci_valid;
|
||||
|
||||
/* Timestamp of creation in 1/100s seince boottime */
|
||||
uint32_t aci_cstamp;
|
||||
|
||||
/* Timestamp of last update in 1/100s since boottime */
|
||||
uint32_t aci_tstamp;
|
||||
};
|
||||
|
||||
struct rtnl_addr
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
uint8_t a_family;
|
||||
uint8_t a_prefixlen;
|
||||
uint8_t a_flags;
|
||||
uint8_t a_scope;
|
||||
uint32_t a_ifindex;
|
||||
|
||||
struct nl_addr *a_peer;
|
||||
struct nl_addr *a_local;
|
||||
struct nl_addr *a_bcast;
|
||||
struct nl_addr *a_anycast;
|
||||
struct nl_addr *a_multicast;
|
||||
|
||||
struct rtnl_addr_cacheinfo a_cacheinfo;
|
||||
|
||||
char a_label[IFNAMSIZ];
|
||||
uint32_t a_flag_mask;
|
||||
};
|
||||
|
||||
#define NEXTHOP_HAS_FLAGS 0x000001
|
||||
#define NEXTHOP_HAS_WEIGHT 0x000002
|
||||
#define NEXTHOP_HAS_IFINDEX 0x000004
|
||||
#define NEXTHOP_HAS_GATEWAY 0x000008
|
||||
|
||||
struct rtnl_nexthop
|
||||
{
|
||||
uint8_t rtnh_flags;
|
||||
uint8_t rtnh_flag_mask;
|
||||
uint8_t rtnh_weight;
|
||||
/* 1 byte spare */
|
||||
uint32_t rtnh_ifindex;
|
||||
struct nl_addr * rtnh_gateway;
|
||||
uint32_t rtnh_mask;
|
||||
|
||||
struct nl_list_head rtnh_list;
|
||||
};
|
||||
|
||||
struct rtnl_route
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
uint8_t rt_family;
|
||||
uint8_t rt_dst_len;
|
||||
uint8_t rt_src_len;
|
||||
uint8_t rt_tos;
|
||||
uint8_t rt_table;
|
||||
uint8_t rt_protocol;
|
||||
uint8_t rt_scope;
|
||||
uint8_t rt_type;
|
||||
uint32_t rt_flags;
|
||||
struct nl_addr * rt_dst;
|
||||
struct nl_addr * rt_src;
|
||||
char rt_iif[IFNAMSIZ];
|
||||
uint32_t rt_oif;
|
||||
struct nl_addr * rt_gateway;
|
||||
uint32_t rt_prio;
|
||||
uint32_t rt_metrics[RTAX_MAX];
|
||||
uint32_t rt_metrics_mask;
|
||||
struct nl_addr * rt_pref_src;
|
||||
struct nl_list_head rt_nexthops;
|
||||
realm_t rt_realms;
|
||||
struct rtnl_rtcacheinfo rt_cacheinfo;
|
||||
uint32_t rt_mp_algo;
|
||||
uint32_t rt_flag_mask;
|
||||
};
|
||||
|
||||
struct rtnl_rule
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
uint64_t r_mark;
|
||||
uint32_t r_prio;
|
||||
uint32_t r_realms;
|
||||
uint32_t r_table;
|
||||
uint8_t r_dsfield;
|
||||
uint8_t r_type;
|
||||
uint8_t r_family;
|
||||
uint8_t r_src_len;
|
||||
uint8_t r_dst_len;
|
||||
char r_iif[IFNAMSIZ];
|
||||
struct nl_addr *r_src;
|
||||
struct nl_addr *r_dst;
|
||||
struct nl_addr *r_srcmap;
|
||||
};
|
||||
|
||||
struct rtnl_neightbl_parms
|
||||
{
|
||||
/**
|
||||
* Interface index of the device this parameter set is assigned
|
||||
* to or 0 for the default set.
|
||||
*/
|
||||
uint32_t ntp_ifindex;
|
||||
|
||||
/**
|
||||
* Number of references to this parameter set.
|
||||
*/
|
||||
uint32_t ntp_refcnt;
|
||||
|
||||
/**
|
||||
* Queue length for pending arp requests, i.e. the number of
|
||||
* packets which are accepted from other layers while the
|
||||
* neighbour address is still being resolved
|
||||
*/
|
||||
uint32_t ntp_queue_len;
|
||||
|
||||
/**
|
||||
* Number of requests to send to the user level ARP daemon.
|
||||
* Specify 0 to disable.
|
||||
*/
|
||||
uint32_t ntp_app_probes;
|
||||
|
||||
/**
|
||||
* Maximum number of retries for unicast solicitation.
|
||||
*/
|
||||
uint32_t ntp_ucast_probes;
|
||||
|
||||
/**
|
||||
* Maximum number of retries for multicast solicitation.
|
||||
*/
|
||||
uint32_t ntp_mcast_probes;
|
||||
|
||||
/**
|
||||
* Base value in milliseconds to ompute reachable time, see RFC2461.
|
||||
*/
|
||||
uint64_t ntp_base_reachable_time;
|
||||
|
||||
/**
|
||||
* Actual reachable time (read-only)
|
||||
*/
|
||||
uint64_t ntp_reachable_time; /* secs */
|
||||
|
||||
/**
|
||||
* The time in milliseconds between retransmitted Neighbor
|
||||
* Solicitation messages.
|
||||
*/
|
||||
uint64_t ntp_retrans_time;
|
||||
|
||||
/**
|
||||
* Interval in milliseconds to check for stale neighbour
|
||||
* entries.
|
||||
*/
|
||||
uint64_t ntp_gc_stale_time; /* secs */
|
||||
|
||||
/**
|
||||
* Delay in milliseconds for the first time probe if
|
||||
* the neighbour is reachable.
|
||||
*/
|
||||
uint64_t ntp_probe_delay; /* secs */
|
||||
|
||||
/**
|
||||
* Maximum delay in milliseconds of an answer to a neighbour
|
||||
* solicitation message.
|
||||
*/
|
||||
uint64_t ntp_anycast_delay;
|
||||
|
||||
/**
|
||||
* Minimum age in milliseconds before a neighbour entry
|
||||
* may be replaced.
|
||||
*/
|
||||
uint64_t ntp_locktime;
|
||||
|
||||
/**
|
||||
* Delay in milliseconds before answering to an ARP request
|
||||
* for which a proxy ARP entry exists.
|
||||
*/
|
||||
uint64_t ntp_proxy_delay;
|
||||
|
||||
/**
|
||||
* Queue length for the delayed proxy arp requests.
|
||||
*/
|
||||
uint32_t ntp_proxy_qlen;
|
||||
|
||||
/**
|
||||
* Mask of available parameter attributes
|
||||
*/
|
||||
uint32_t ntp_mask;
|
||||
};
|
||||
|
||||
#define NTBLNAMSIZ 32
|
||||
|
||||
/**
|
||||
* Neighbour table
|
||||
* @ingroup neightbl
|
||||
*/
|
||||
struct rtnl_neightbl
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
char nt_name[NTBLNAMSIZ];
|
||||
uint32_t nt_family;
|
||||
uint32_t nt_gc_thresh1;
|
||||
uint32_t nt_gc_thresh2;
|
||||
uint32_t nt_gc_thresh3;
|
||||
uint64_t nt_gc_interval;
|
||||
struct ndt_config nt_config;
|
||||
struct rtnl_neightbl_parms nt_parms;
|
||||
struct ndt_stats nt_stats;
|
||||
};
|
||||
|
||||
struct rtnl_ratespec
|
||||
{
|
||||
uint8_t rs_cell_log;
|
||||
uint16_t rs_feature;
|
||||
uint16_t rs_addend;
|
||||
uint16_t rs_mpu;
|
||||
uint32_t rs_rate;
|
||||
};
|
||||
|
||||
struct rtnl_tstats
|
||||
{
|
||||
struct {
|
||||
uint64_t bytes;
|
||||
uint64_t packets;
|
||||
} tcs_basic;
|
||||
|
||||
struct {
|
||||
uint32_t bps;
|
||||
uint32_t pps;
|
||||
} tcs_rate_est;
|
||||
|
||||
struct {
|
||||
uint32_t qlen;
|
||||
uint32_t backlog;
|
||||
uint32_t drops;
|
||||
uint32_t requeues;
|
||||
uint32_t overlimits;
|
||||
} tcs_queue;
|
||||
};
|
||||
|
||||
#define TCKINDSIZ 32
|
||||
|
||||
#define NL_TCA_GENERIC(pre) \
|
||||
NLHDR_COMMON \
|
||||
uint32_t pre ##_family; \
|
||||
uint32_t pre ##_ifindex; \
|
||||
uint32_t pre ##_handle; \
|
||||
uint32_t pre ##_parent; \
|
||||
uint32_t pre ##_info; \
|
||||
char pre ##_kind[TCKINDSIZ]; \
|
||||
struct nl_data * pre ##_opts; \
|
||||
uint64_t pre ##_stats[RTNL_TC_STATS_MAX+1]; \
|
||||
struct nl_data * pre ##_xstats; \
|
||||
void * pre ##_subdata; \
|
||||
|
||||
|
||||
struct rtnl_tca
|
||||
{
|
||||
NL_TCA_GENERIC(tc);
|
||||
};
|
||||
|
||||
struct rtnl_qdisc
|
||||
{
|
||||
NL_TCA_GENERIC(q);
|
||||
struct rtnl_qdisc_ops *q_ops;
|
||||
};
|
||||
|
||||
struct rtnl_class
|
||||
{
|
||||
NL_TCA_GENERIC(c);
|
||||
struct rtnl_class_ops *c_ops;
|
||||
};
|
||||
|
||||
struct rtnl_cls
|
||||
{
|
||||
NL_TCA_GENERIC(c);
|
||||
uint32_t c_prio;
|
||||
uint32_t c_protocol;
|
||||
struct rtnl_cls_ops *c_ops;
|
||||
};
|
||||
|
||||
struct rtnl_u32
|
||||
{
|
||||
uint32_t cu_divisor;
|
||||
uint32_t cu_hash;
|
||||
uint32_t cu_classid;
|
||||
uint32_t cu_link;
|
||||
struct nl_data * cu_pcnt;
|
||||
struct nl_data * cu_selector;
|
||||
struct nl_data * cu_act;
|
||||
struct nl_data * cu_police;
|
||||
char cu_indev[IFNAMSIZ];
|
||||
int cu_mask;
|
||||
};
|
||||
|
||||
struct rtnl_fw
|
||||
{
|
||||
uint32_t cf_classid;
|
||||
struct nl_data * cf_act;
|
||||
struct nl_data * cf_police;
|
||||
char cf_indev[IFNAMSIZ];
|
||||
int cf_mask;
|
||||
};
|
||||
|
||||
struct rtnl_dsmark_qdisc
|
||||
{
|
||||
uint16_t qdm_indices;
|
||||
uint16_t qdm_default_index;
|
||||
uint32_t qdm_set_tc_index;
|
||||
uint32_t qdm_mask;
|
||||
};
|
||||
|
||||
struct rtnl_dsmark_class
|
||||
{
|
||||
uint8_t cdm_bmask;
|
||||
uint8_t cdm_value;
|
||||
uint32_t cdm_mask;
|
||||
};
|
||||
|
||||
struct rtnl_fifo
|
||||
{
|
||||
uint32_t qf_limit;
|
||||
uint32_t qf_mask;
|
||||
};
|
||||
|
||||
struct rtnl_prio
|
||||
{
|
||||
uint32_t qp_bands;
|
||||
uint8_t qp_priomap[TC_PRIO_MAX+1];
|
||||
uint32_t qp_mask;
|
||||
};
|
||||
|
||||
struct rtnl_tbf
|
||||
{
|
||||
uint32_t qt_limit;
|
||||
uint32_t qt_mpu;
|
||||
struct rtnl_ratespec qt_rate;
|
||||
uint32_t qt_rate_bucket;
|
||||
uint32_t qt_rate_txtime;
|
||||
struct rtnl_ratespec qt_peakrate;
|
||||
uint32_t qt_peakrate_bucket;
|
||||
uint32_t qt_peakrate_txtime;
|
||||
uint32_t qt_mask;
|
||||
};
|
||||
|
||||
struct rtnl_sfq
|
||||
{
|
||||
uint32_t qs_quantum;
|
||||
uint32_t qs_perturb;
|
||||
uint32_t qs_limit;
|
||||
uint32_t qs_divisor;
|
||||
uint32_t qs_flows;
|
||||
uint32_t qs_mask;
|
||||
};
|
||||
|
||||
struct rtnl_netem_corr
|
||||
{
|
||||
uint32_t nmc_delay;
|
||||
uint32_t nmc_loss;
|
||||
uint32_t nmc_duplicate;
|
||||
};
|
||||
|
||||
struct rtnl_netem_reo
|
||||
{
|
||||
uint32_t nmro_probability;
|
||||
uint32_t nmro_correlation;
|
||||
};
|
||||
|
||||
struct rtnl_netem
|
||||
{
|
||||
uint32_t qnm_latency;
|
||||
uint32_t qnm_limit;
|
||||
uint32_t qnm_loss;
|
||||
uint32_t qnm_gap;
|
||||
uint32_t qnm_duplicate;
|
||||
uint32_t qnm_jitter;
|
||||
uint32_t qnm_mask;
|
||||
struct rtnl_netem_corr qnm_corr;
|
||||
struct rtnl_netem_reo qnm_ro;
|
||||
};
|
||||
|
||||
struct rtnl_htb_qdisc
|
||||
{
|
||||
uint32_t qh_rate2quantum;
|
||||
uint32_t qh_defcls;
|
||||
uint32_t qh_mask;
|
||||
};
|
||||
|
||||
struct rtnl_htb_class
|
||||
{
|
||||
uint32_t ch_prio;
|
||||
uint32_t ch_mtu;
|
||||
struct rtnl_ratespec ch_rate;
|
||||
struct rtnl_ratespec ch_ceil;
|
||||
uint32_t ch_rbuffer;
|
||||
uint32_t ch_cbuffer;
|
||||
uint32_t ch_quantum;
|
||||
uint8_t ch_overhead;
|
||||
uint8_t ch_mpu;
|
||||
uint32_t ch_mask;
|
||||
};
|
||||
|
||||
struct rtnl_cbq
|
||||
{
|
||||
struct tc_cbq_lssopt cbq_lss;
|
||||
struct tc_ratespec cbq_rate;
|
||||
struct tc_cbq_wrropt cbq_wrr;
|
||||
struct tc_cbq_ovl cbq_ovl;
|
||||
struct tc_cbq_fopt cbq_fopt;
|
||||
struct tc_cbq_police cbq_police;
|
||||
};
|
||||
|
||||
struct rtnl_red
|
||||
{
|
||||
uint32_t qr_limit;
|
||||
uint32_t qr_qth_min;
|
||||
uint32_t qr_qth_max;
|
||||
uint8_t qr_flags;
|
||||
uint8_t qr_wlog;
|
||||
uint8_t qr_plog;
|
||||
uint8_t qr_scell_log;
|
||||
uint32_t qr_mask;
|
||||
};
|
||||
|
||||
struct flnl_request
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
struct nl_addr * lr_addr;
|
||||
uint32_t lr_fwmark;
|
||||
uint8_t lr_tos;
|
||||
uint8_t lr_scope;
|
||||
uint8_t lr_table;
|
||||
};
|
||||
|
||||
|
||||
struct flnl_result
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
struct flnl_request * fr_req;
|
||||
uint8_t fr_table_id;
|
||||
uint8_t fr_prefixlen;
|
||||
uint8_t fr_nh_sel;
|
||||
uint8_t fr_type;
|
||||
uint8_t fr_scope;
|
||||
uint32_t fr_error;
|
||||
};
|
||||
|
||||
#define GENL_OP_HAS_POLICY 1
|
||||
#define GENL_OP_HAS_DOIT 2
|
||||
#define GENL_OP_HAS_DUMPIT 4
|
||||
|
||||
struct genl_family_op
|
||||
{
|
||||
uint32_t o_id;
|
||||
uint32_t o_flags;
|
||||
|
||||
struct nl_list_head o_list;
|
||||
};
|
||||
|
||||
struct genl_family
|
||||
{
|
||||
NLHDR_COMMON
|
||||
|
||||
uint16_t gf_id;
|
||||
char gf_name[GENL_NAMSIZ];
|
||||
uint32_t gf_version;
|
||||
uint32_t gf_hdrsize;
|
||||
uint32_t gf_maxattr;
|
||||
|
||||
struct nl_list_head gf_ops;
|
||||
};
|
||||
|
||||
union nfnl_ct_proto
|
||||
{
|
||||
struct {
|
||||
uint16_t src;
|
||||
uint16_t dst;
|
||||
} port;
|
||||
struct {
|
||||
uint16_t id;
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
} icmp;
|
||||
};
|
||||
|
||||
struct nfnl_ct_dir {
|
||||
struct nl_addr * src;
|
||||
struct nl_addr * dst;
|
||||
union nfnl_ct_proto proto;
|
||||
uint64_t packets;
|
||||
uint64_t bytes;
|
||||
};
|
||||
|
||||
union nfnl_ct_protoinfo {
|
||||
struct {
|
||||
uint8_t state;
|
||||
} tcp;
|
||||
};
|
||||
|
||||
struct nfnl_ct {
|
||||
NLHDR_COMMON
|
||||
|
||||
uint8_t ct_family;
|
||||
uint8_t ct_proto;
|
||||
union nfnl_ct_protoinfo ct_protoinfo;
|
||||
|
||||
uint32_t ct_status;
|
||||
uint32_t ct_timeout;
|
||||
uint32_t ct_mark;
|
||||
uint32_t ct_use;
|
||||
uint32_t ct_id;
|
||||
|
||||
struct nfnl_ct_dir ct_orig;
|
||||
struct nfnl_ct_dir ct_repl;
|
||||
};
|
||||
|
||||
struct nfnl_log {
|
||||
NLHDR_COMMON
|
||||
|
||||
uint8_t log_family;
|
||||
uint8_t log_hook;
|
||||
uint16_t log_hwproto;
|
||||
uint32_t log_mark;
|
||||
struct timeval log_timestamp;
|
||||
uint32_t log_indev;
|
||||
uint32_t log_outdev;
|
||||
uint32_t log_physindev;
|
||||
uint32_t log_physoutdev;
|
||||
uint8_t log_hwaddr[8];
|
||||
int log_hwaddr_len;
|
||||
void * log_payload;
|
||||
int log_payload_len;
|
||||
char * log_prefix;
|
||||
uint32_t log_uid;
|
||||
uint32_t log_seq;
|
||||
uint32_t log_seq_global;
|
||||
};
|
||||
|
||||
#endif
|
67
include/netlink/addr.h
Normal file
67
include/netlink/addr.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* netlink/addr.h Abstract Address
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_ADDR_H_
|
||||
#define NETLINK_ADDR_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_addr;
|
||||
|
||||
/* Creation */
|
||||
extern struct nl_addr * nl_addr_alloc(size_t);
|
||||
extern struct nl_addr * nl_addr_build(int, void *, size_t);
|
||||
extern struct nl_addr * nl_addr_parse(const char *, int);
|
||||
extern struct nl_addr * nl_addr_clone(struct nl_addr *);
|
||||
|
||||
/* Destroyage */
|
||||
extern void nl_addr_destroy(struct nl_addr *);
|
||||
|
||||
/* Usage Management */
|
||||
extern struct nl_addr * nl_addr_get(struct nl_addr *);
|
||||
extern void nl_addr_put(struct nl_addr *);
|
||||
extern int nl_addr_shared(struct nl_addr *);
|
||||
|
||||
extern int nl_addr_cmp(struct nl_addr *, struct nl_addr *);
|
||||
extern int nl_addr_cmp_prefix(struct nl_addr *, struct nl_addr *);
|
||||
extern int nl_addr_valid(char *, int);
|
||||
extern int nl_addr_guess_family(struct nl_addr *);
|
||||
extern int nl_addr_fill_sockaddr(struct nl_addr *,
|
||||
struct sockaddr *, socklen_t *);
|
||||
extern struct addrinfo *nl_addr_info(struct nl_addr *addr);
|
||||
extern int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen);
|
||||
|
||||
/* Access Functions */
|
||||
extern void nl_addr_set_family(struct nl_addr *, int);
|
||||
extern int nl_addr_get_family(struct nl_addr *);
|
||||
extern int nl_addr_set_binary_addr(struct nl_addr *, void *,
|
||||
size_t);
|
||||
extern void * nl_addr_get_binary_addr(struct nl_addr *);
|
||||
extern unsigned int nl_addr_get_len(struct nl_addr *);
|
||||
extern void nl_addr_set_prefixlen(struct nl_addr *, int);
|
||||
extern unsigned int nl_addr_get_prefixlen(struct nl_addr *);
|
||||
|
||||
/* Address Family Translations */
|
||||
extern char * nl_af2str(int, char *, size_t);
|
||||
extern int nl_str2af(const char *);
|
||||
|
||||
/* Translations to Strings */
|
||||
extern char * nl_addr2str(struct nl_addr *, char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
287
include/netlink/attr.h
Normal file
287
include/netlink/attr.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* netlink/attr.h Netlink Attributes
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_ATTR_H_
|
||||
#define NETLINK_ATTR_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/data.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_msg;
|
||||
|
||||
/**
|
||||
* @name Validation Policy Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* Standard attribute types to specify validation policy
|
||||
*/
|
||||
enum {
|
||||
NLA_UNSPEC, /**< Unspecified type */
|
||||
NLA_U8, /**< 8bit integer */
|
||||
NLA_U16, /**< 16bit integer */
|
||||
NLA_U32, /**< 32bit integer */
|
||||
NLA_U64, /**< 64bit integer */
|
||||
NLA_STRING, /**< character string */
|
||||
NLA_FLAG, /**< flag */
|
||||
NLA_MSECS, /**< micro seconds (64bit) */
|
||||
NLA_NESTED, /**< nested attributes */
|
||||
__NLA_TYPE_MAX,
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* Maximum netlink validation policy type
|
||||
*/
|
||||
#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* attribute validation policy
|
||||
*
|
||||
* Policies are defined as arrays of this struct, the array must
|
||||
* be accessible by attribute type up to the highest identifier
|
||||
* to be expected.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* static struct nla_policy my_policy[ATTR_MAX+1] __read_mostly = {
|
||||
* [ATTR_FOO] = { .type = NLA_U16 },
|
||||
* [ATTR_BAR] = { .type = NLA_STRING },
|
||||
* [ATTR_BAZ] = { .minlen = sizeof(struct mystruct) },
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
struct nla_policy {
|
||||
/** Type of attribute or NLA_UNSPEC */
|
||||
uint16_t type;
|
||||
|
||||
/** Minimal length of payload required to be available */
|
||||
uint16_t minlen;
|
||||
|
||||
/** Maximal length of payload required to be available */
|
||||
uint16_t maxlen;
|
||||
};
|
||||
|
||||
/* size calculations */
|
||||
extern int nla_attr_size(int payload);
|
||||
extern int nla_total_size(int payload);
|
||||
extern int nla_padlen(int payload);
|
||||
|
||||
/* payload access */
|
||||
extern int nla_type(const struct nlattr *);
|
||||
extern void * nla_data(const struct nlattr *);
|
||||
extern int nla_len(const struct nlattr *);
|
||||
|
||||
/* attribute parsing */
|
||||
extern int nla_ok(const struct nlattr *, int);
|
||||
extern struct nlattr * nla_next(const struct nlattr *, int *);
|
||||
extern int nla_parse(struct nlattr **, int, struct nlattr *,
|
||||
int, struct nla_policy *);
|
||||
extern int nla_parse_nested(struct nlattr **, int, struct nlattr *,
|
||||
struct nla_policy *);
|
||||
extern int nla_validate(struct nlattr *, int, int,
|
||||
struct nla_policy *);
|
||||
extern struct nlattr * nla_find(struct nlattr *, int, int);
|
||||
|
||||
/* utilities */
|
||||
extern int nla_memcpy(void *, struct nlattr *, int);
|
||||
extern size_t nla_strlcpy(char *, const struct nlattr *, size_t);
|
||||
extern int nla_memcmp(const struct nlattr *, const void *, size_t);
|
||||
extern int nla_strcmp(const struct nlattr *, const char *);
|
||||
|
||||
/* attribute construction */
|
||||
extern struct nlattr * nla_reserve(struct nl_msg *, int, int);
|
||||
extern int nla_put(struct nl_msg *, int, int, const void *);
|
||||
extern int nla_put_nested(struct nl_msg *, int, struct nl_msg *);
|
||||
extern int nla_put_u8(struct nl_msg *, int, uint8_t);
|
||||
extern int nla_put_u16(struct nl_msg *, int, uint16_t);
|
||||
extern int nla_put_u32(struct nl_msg *, int, uint32_t);
|
||||
extern int nla_put_u64(struct nl_msg *, int, uint64_t);
|
||||
extern int nla_put_string(struct nl_msg *, int, const char *);
|
||||
extern int nla_put_flag(struct nl_msg *, int);
|
||||
extern int nla_put_msecs(struct nl_msg *, int, unsigned long);
|
||||
extern int nla_put_data(struct nl_msg *, int, struct nl_data *);
|
||||
extern int nla_put_addr(struct nl_msg *, int, struct nl_addr *);
|
||||
|
||||
/* attribute nesting */
|
||||
extern struct nlattr * nla_nest_start(struct nl_msg *, int);
|
||||
extern int nla_nest_end(struct nl_msg *, struct nlattr *);
|
||||
|
||||
/* attribute reading */
|
||||
extern uint8_t nla_get_u8(struct nlattr *);
|
||||
extern uint16_t nla_get_u16(struct nlattr *);
|
||||
extern uint32_t nla_get_u32(struct nlattr *);
|
||||
extern uint64_t nla_get_u64(struct nlattr *);
|
||||
extern char * nla_get_string(struct nlattr *);
|
||||
extern int nla_get_flag(struct nlattr *);
|
||||
extern unsigned long nla_get_msecs(struct nlattr *);
|
||||
extern struct nl_data * nla_get_data(struct nlattr *);
|
||||
extern struct nl_addr * nla_get_addr(struct nlattr *, int);
|
||||
|
||||
/**
|
||||
* @name Attribute Construction (Exception Based)
|
||||
*
|
||||
* All these functions jump to nla_put_failure in case of a failure
|
||||
* instead of returning an error code.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* Add a netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg attrlen length of attribute payload
|
||||
* @arg data head of attribute payload
|
||||
*/
|
||||
#define NLA_PUT(n, attrtype, attrlen, data) \
|
||||
do { \
|
||||
if (nla_put(n, attrtype, attrlen, data) < 0) \
|
||||
goto nla_put_failure; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* Add a basic netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg type atomic type
|
||||
* @arg attrtype attribute type
|
||||
* @arg value head of attribute payload
|
||||
*/
|
||||
#define NLA_PUT_TYPE(n, type, attrtype, value) \
|
||||
do { \
|
||||
type __tmp = value; \
|
||||
NLA_PUT(n, attrtype, sizeof(type), &__tmp); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Add a u8 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
#define NLA_PUT_U8(n, attrtype, value) \
|
||||
NLA_PUT_TYPE(n, uint8_t, attrtype, value)
|
||||
|
||||
/**
|
||||
* Add a u16 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
#define NLA_PUT_U16(n, attrtype, value) \
|
||||
NLA_PUT_TYPE(n, uint16_t, attrtype, value)
|
||||
|
||||
/**
|
||||
* Add a u32 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
#define NLA_PUT_U32(n, attrtype, value) \
|
||||
NLA_PUT_TYPE(n, uint32_t, attrtype, value)
|
||||
|
||||
/**
|
||||
* Add a u64 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
#define NLA_PUT_U64(n, attrtype, value) \
|
||||
NLA_PUT_TYPE(n, uint64_t, attrtype, value)
|
||||
|
||||
/**
|
||||
* Add a character string netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value character string
|
||||
*/
|
||||
#define NLA_PUT_STRING(n, attrtype, value) \
|
||||
NLA_PUT(n, attrtype, strlen(value) + 1, value)
|
||||
|
||||
/**
|
||||
* Add a flag netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
*/
|
||||
#define NLA_PUT_FLAG(n, attrtype) \
|
||||
NLA_PUT(n, attrtype, 0, NULL)
|
||||
|
||||
/**
|
||||
* Add a msecs netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg msecs numeric value in micro seconds
|
||||
*/
|
||||
#define NLA_PUT_MSECS(n, attrtype, msecs) \
|
||||
NLA_PUT_U64(n, attrtype, msecs)
|
||||
|
||||
/**
|
||||
* Add a address attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg addr abstract address object
|
||||
*/
|
||||
#define NLA_PUT_ADDR(n, attrtype, addr) \
|
||||
NLA_PUT(n, attrtype, nl_addr_get_len(addr), \
|
||||
nl_addr_get_binary_addr(addr))
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Iterators
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* iterate over a stream of attributes
|
||||
* @arg pos loop counter, set to current attribute
|
||||
* @arg head head of attribute stream
|
||||
* @arg len length of attribute stream
|
||||
* @arg rem initialized to len, holds bytes currently remaining in stream
|
||||
*/
|
||||
#define nla_for_each_attr(pos, head, len, rem) \
|
||||
for (pos = head, rem = len; \
|
||||
nla_ok(pos, rem); \
|
||||
pos = nla_next(pos, &(rem)))
|
||||
|
||||
/**
|
||||
* @ingroup attr
|
||||
* iterate over a stream of nested attributes
|
||||
* @arg pos loop counter, set to current attribute
|
||||
* @arg nla attribute containing the nested attributes
|
||||
* @arg rem initialized to len, holds bytes currently remaining in stream
|
||||
*/
|
||||
#define nla_for_each_nested(pos, nla, rem) \
|
||||
for (pos = nla_data(nla), rem = nla_len(nla); \
|
||||
nla_ok(pos, rem); \
|
||||
pos = nla_next(pos, &(rem)))
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
123
include/netlink/cache.h
Normal file
123
include/netlink/cache.h
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* netlink/cache.h Caching Module
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CACHE_H_
|
||||
#define NETLINK_CACHE_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/msg.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/object.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_cache;
|
||||
struct nl_cache_ops;
|
||||
|
||||
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int);
|
||||
|
||||
/* Access Functions */
|
||||
extern int nl_cache_nitems(struct nl_cache *);
|
||||
extern int nl_cache_nitems_filter(struct nl_cache *,
|
||||
struct nl_object *);
|
||||
extern struct nl_cache_ops * nl_cache_get_ops(struct nl_cache *);
|
||||
extern struct nl_object * nl_cache_get_first(struct nl_cache *);
|
||||
extern struct nl_object * nl_cache_get_last(struct nl_cache *);
|
||||
extern struct nl_object * nl_cache_get_next(struct nl_object *);
|
||||
extern struct nl_object * nl_cache_get_prev(struct nl_object *);
|
||||
|
||||
/* Cache creation/deletion */
|
||||
#define nl_cache_alloc_from_ops(ptr) nl_cache_alloc(ptr)
|
||||
extern struct nl_cache * nl_cache_alloc(struct nl_cache_ops *);
|
||||
extern struct nl_cache * nl_cache_alloc_name(const char *);
|
||||
extern struct nl_cache * nl_cache_subset(struct nl_cache *,
|
||||
struct nl_object *);
|
||||
extern void nl_cache_clear(struct nl_cache *);
|
||||
extern void nl_cache_free(struct nl_cache *);
|
||||
|
||||
/* Cache modification */
|
||||
extern int nl_cache_add(struct nl_cache *,
|
||||
struct nl_object *);
|
||||
extern int nl_cache_parse_and_add(struct nl_cache *,
|
||||
struct nl_msg *);
|
||||
#define nl_cache_delete(a, b) nl_cache_remove(b)
|
||||
extern void nl_cache_remove(struct nl_object *);
|
||||
#define nl_cache_update(a, b) nl_cache_refill(a, b)
|
||||
extern int nl_cache_refill(struct nl_handle *,
|
||||
struct nl_cache *);
|
||||
extern int nl_cache_pickup(struct nl_handle *,
|
||||
struct nl_cache *);
|
||||
extern int nl_cache_resync(struct nl_handle *,
|
||||
struct nl_cache *,
|
||||
change_func_t);
|
||||
extern int nl_cache_include(struct nl_cache *,
|
||||
struct nl_object *,
|
||||
change_func_t);
|
||||
|
||||
/* General */
|
||||
extern int nl_cache_is_empty(struct nl_cache *);
|
||||
extern void nl_cache_mark_all(struct nl_cache *);
|
||||
|
||||
/* Dumping */
|
||||
extern void nl_cache_dump(struct nl_cache *,
|
||||
struct nl_dump_params *);
|
||||
extern void nl_cache_dump_filter(struct nl_cache *,
|
||||
struct nl_dump_params *,
|
||||
struct nl_object *);
|
||||
|
||||
/* Iterators */
|
||||
extern void nl_cache_foreach(struct nl_cache *,
|
||||
void (*cb)(struct nl_object *,
|
||||
void *),
|
||||
void *arg);
|
||||
extern void nl_cache_foreach_filter(struct nl_cache *,
|
||||
struct nl_object *,
|
||||
void (*cb)(struct
|
||||
nl_object *,
|
||||
void *),
|
||||
void *arg);
|
||||
|
||||
/* --- cache management --- */
|
||||
|
||||
/* Cache type management */
|
||||
extern struct nl_cache_ops * nl_cache_ops_lookup(const char *);
|
||||
extern struct nl_cache_ops * nl_cache_ops_lookup_for_obj(struct nl_object_ops *);
|
||||
extern void nl_cache_mngt_foreach(void (*cb)(struct nl_cache_ops *, void *), void *);
|
||||
extern int nl_cache_mngt_register(struct nl_cache_ops *);
|
||||
extern int nl_cache_mngt_unregister(struct nl_cache_ops *);
|
||||
|
||||
/* Global cache provisioning/requiring */
|
||||
extern void nl_cache_mngt_provide(struct nl_cache *);
|
||||
extern void nl_cache_mngt_unprovide(struct nl_cache *);
|
||||
extern struct nl_cache * nl_cache_mngt_require(const char *);
|
||||
|
||||
struct nl_cache_mngr;
|
||||
|
||||
#define NL_AUTO_PROVIDE 1
|
||||
|
||||
extern struct nl_cache_mngr * nl_cache_mngr_alloc(struct nl_handle *,
|
||||
int, int);
|
||||
extern struct nl_cache * nl_cache_mngr_add(struct nl_cache_mngr *,
|
||||
const char *,
|
||||
change_func_t);
|
||||
extern int nl_cache_mngr_get_fd(struct nl_cache_mngr *);
|
||||
extern int nl_cache_mngr_poll(struct nl_cache_mngr *,
|
||||
int);
|
||||
extern int nl_cache_mngr_data_ready(struct nl_cache_mngr *);
|
||||
extern void nl_cache_mngr_free(struct nl_cache_mngr *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
40
include/netlink/data.h
Normal file
40
include/netlink/data.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* netlink/data.h Abstract Data
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_DATA_H_
|
||||
#define NETLINK_DATA_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_data;
|
||||
|
||||
/* General */
|
||||
extern struct nl_data * nl_data_alloc(void *, size_t);
|
||||
extern struct nl_data * nl_data_clone(struct nl_data *);
|
||||
extern int nl_data_append(struct nl_data *, void *, size_t);
|
||||
extern void nl_data_free(struct nl_data *);
|
||||
|
||||
/* Access Functions */
|
||||
extern void * nl_data_get(struct nl_data *);
|
||||
extern size_t nl_data_get_size(struct nl_data *);
|
||||
|
||||
/* Misc */
|
||||
extern int nl_data_cmp(struct nl_data *, struct nl_data *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
41
include/netlink/fib_lookup/lookup.h
Normal file
41
include/netlink/fib_lookup/lookup.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* netlink/fib_lookup/fib_lookup.h FIB Lookup
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_FIB_LOOKUP_H_
|
||||
#define NETLINK_FIB_LOOKUP_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/fib_lookup/request.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct flnl_result;
|
||||
|
||||
extern struct flnl_result * flnl_result_alloc(void);
|
||||
extern void flnl_result_put(struct flnl_result *);
|
||||
|
||||
extern struct nl_cache * flnl_result_alloc_cache(void);
|
||||
|
||||
extern struct nl_msg * flnl_lookup_build_request(struct flnl_request *,
|
||||
int);
|
||||
extern int flnl_lookup(struct nl_handle *,
|
||||
struct flnl_request *,
|
||||
struct nl_cache *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
51
include/netlink/fib_lookup/request.h
Normal file
51
include/netlink/fib_lookup/request.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* netlink/fib_lookup/request.h FIB Lookup Request
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_FIB_LOOKUP_REQUEST_H_
|
||||
#define NETLINK_FIB_LOOKUP_REQUEST_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct flnl_request;
|
||||
|
||||
#define REQUEST_CAST(ptr) ((struct flnl_request *) (ptr))
|
||||
|
||||
extern struct flnl_request * flnl_request_alloc(void);
|
||||
|
||||
extern void flnl_request_set_fwmark(struct flnl_request *,
|
||||
uint64_t);
|
||||
extern uint64_t flnl_request_get_fwmark(struct flnl_request *);
|
||||
extern void flnl_request_set_tos(struct flnl_request *,
|
||||
int);
|
||||
extern int flnl_request_get_tos(struct flnl_request *);
|
||||
extern void flnl_request_set_scope(struct flnl_request *,
|
||||
int);
|
||||
extern int flnl_request_get_scope(struct flnl_request *);
|
||||
extern void flnl_request_set_table(struct flnl_request *,
|
||||
int);
|
||||
extern int flnl_request_get_table(struct flnl_request *);
|
||||
extern int flnl_request_set_addr(struct flnl_request *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * flnl_request_get_addr(struct flnl_request *);
|
||||
|
||||
extern int flnl_request_cmp(struct flnl_request *,
|
||||
struct flnl_request *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
36
include/netlink/genl/ctrl.h
Normal file
36
include/netlink/genl/ctrl.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* netlink/genl/ctrl.h Generic Netlink Controller
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_GENL_CTRL_H_
|
||||
#define NETLINK_GENL_CTRL_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct genl_family;
|
||||
|
||||
extern struct nl_cache * genl_ctrl_alloc_cache(struct nl_handle *);
|
||||
extern struct genl_family * genl_ctrl_search(struct nl_cache *, int);
|
||||
extern struct genl_family * genl_ctrl_search_by_name(struct nl_cache *,
|
||||
const char *);
|
||||
extern int genl_ctrl_resolve(struct nl_handle *,
|
||||
const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
50
include/netlink/genl/family.h
Normal file
50
include/netlink/genl/family.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* netlink/genl/family.h Generic Netlink Family
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_GENL_FAMILY_H_
|
||||
#define NETLINK_GENL_FAMILY_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct genl_family;
|
||||
|
||||
extern struct genl_family * genl_family_alloc(void);
|
||||
extern void genl_family_put(struct genl_family *);
|
||||
|
||||
extern unsigned int genl_family_get_id(struct genl_family *);
|
||||
extern void genl_family_set_id(struct genl_family *,
|
||||
unsigned int);
|
||||
extern char * genl_family_get_name(struct genl_family *);
|
||||
extern void genl_family_set_name(struct genl_family *,
|
||||
const char *name);
|
||||
extern uint8_t genl_family_get_version(struct genl_family *);
|
||||
extern void genl_family_set_version(struct genl_family *,
|
||||
uint8_t);
|
||||
extern uint32_t genl_family_get_hdrsize(struct genl_family *);
|
||||
extern void genl_family_set_hdrsize(struct genl_family *,
|
||||
uint32_t);
|
||||
extern uint32_t genl_family_get_maxattr(struct genl_family *);
|
||||
extern void genl_family_set_maxattr(struct genl_family *,
|
||||
uint32_t);
|
||||
|
||||
extern int genl_family_add_op(struct genl_family *,
|
||||
int, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
37
include/netlink/genl/genl.h
Normal file
37
include/netlink/genl/genl.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* netlink/genl/genl.h Generic Netlink
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_GENL_H_
|
||||
#define NETLINK_GENL_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int genl_connect(struct nl_handle *);
|
||||
|
||||
extern int genl_send_simple(struct nl_handle *, int, int,
|
||||
int, int);
|
||||
|
||||
extern void * genlmsg_put(struct nl_msg *, uint32_t, uint32_t,
|
||||
int, int, int, uint8_t, uint8_t);
|
||||
extern void * genlmsg_data(const struct genlmsghdr *);
|
||||
extern int genlmsg_len(const struct genlmsghdr *);
|
||||
|
||||
extern char * genl_op2name(int, int, char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
78
include/netlink/genl/mngt.h
Normal file
78
include/netlink/genl/mngt.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* netlink/genl/mngt.h Generic Netlink Management
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_GENL_MNGT_H_
|
||||
#define NETLINK_GENL_MNGT_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <netlink/list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_cache_ops;
|
||||
|
||||
/**
|
||||
* @ingroup genl_mngt
|
||||
* Generic Netlink Command
|
||||
*/
|
||||
struct genl_cmd
|
||||
{
|
||||
/** Unique command identifier */
|
||||
int c_id;
|
||||
|
||||
/** Name/description of command */
|
||||
char * c_name;
|
||||
|
||||
/**
|
||||
* Maximum attribute identifier, must be provided if
|
||||
* a message parser is available.
|
||||
*/
|
||||
int c_maxattr;
|
||||
|
||||
int (*c_msg_parser)(struct nl_cache_ops *,
|
||||
struct genl_cmd *,
|
||||
struct genl_info *, void *);
|
||||
|
||||
/**
|
||||
* Attribute validation policy (optional)
|
||||
*/
|
||||
struct nla_policy * c_attr_policy;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup genl_mngt
|
||||
* Generic Netlink Operations
|
||||
*/
|
||||
struct genl_ops
|
||||
{
|
||||
int o_family;
|
||||
int o_id;
|
||||
char * o_name;
|
||||
struct nl_cache_ops * o_cache_ops;
|
||||
struct genl_cmd * o_cmds;
|
||||
int o_ncmds;
|
||||
|
||||
/* linked list of all genl cache operations */
|
||||
struct nl_list_head o_list;
|
||||
};
|
||||
|
||||
|
||||
extern int genl_register(struct nl_cache_ops *);
|
||||
extern void genl_unregister(struct nl_cache_ops *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
147
include/netlink/handlers.h
Normal file
147
include/netlink/handlers.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* netlink/handlers.c default netlink message handlers
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_HANDLERS_H_
|
||||
#define NETLINK_HANDLERS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <netlink/netlink-compat.h>
|
||||
#include <netlink/netlink-kernel.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_cb;
|
||||
struct nl_handle;
|
||||
struct nl_msg;
|
||||
|
||||
/**
|
||||
* @name Callback Typedefs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* nl_recvmsgs() callback for message processing customization
|
||||
* @ingroup cb
|
||||
* @arg msg netlink message being processed
|
||||
* @arg arg argument passwd on through caller
|
||||
*/
|
||||
typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg);
|
||||
|
||||
/**
|
||||
* nl_recvmsgs() callback for error message processing customization
|
||||
* @ingroup cb
|
||||
* @arg nla netlink address of the peer
|
||||
* @arg nlerr netlink error message being processed
|
||||
* @arg arg argument passed on through caller
|
||||
*/
|
||||
typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla,
|
||||
struct nlmsgerr *nlerr, void *arg);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Callback actions
|
||||
* @ingroup cb
|
||||
*/
|
||||
enum nl_cb_action {
|
||||
/** Proceed with wathever would come next */
|
||||
NL_OK,
|
||||
/** Skip this message */
|
||||
NL_SKIP,
|
||||
/** Stop parsing altogether and discard remaining messages */
|
||||
NL_STOP,
|
||||
};
|
||||
|
||||
/* backwards compatibility */
|
||||
#define NL_PROCEED NL_OK
|
||||
#define NL_EXIT NL_STOP
|
||||
|
||||
/**
|
||||
* Callback kinds
|
||||
* @ingroup cb
|
||||
*/
|
||||
enum nl_cb_kind {
|
||||
/** Default handlers (quiet) */
|
||||
NL_CB_DEFAULT,
|
||||
/** Verbose default handlers (error messages printed) */
|
||||
NL_CB_VERBOSE,
|
||||
/** Debug handlers for debugging */
|
||||
NL_CB_DEBUG,
|
||||
/** Customized handler specified by the user */
|
||||
NL_CB_CUSTOM,
|
||||
__NL_CB_KIND_MAX,
|
||||
};
|
||||
|
||||
#define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1)
|
||||
|
||||
/**
|
||||
* Callback types
|
||||
* @ingroup cb
|
||||
*/
|
||||
enum nl_cb_type {
|
||||
/** Message is valid */
|
||||
NL_CB_VALID,
|
||||
/** Last message in a series of multi part messages received */
|
||||
NL_CB_FINISH,
|
||||
/** Report received that data was lost */
|
||||
NL_CB_OVERRUN,
|
||||
/** Message wants to be skipped */
|
||||
NL_CB_SKIPPED,
|
||||
/** Message is an acknowledge */
|
||||
NL_CB_ACK,
|
||||
/** Called for every message received */
|
||||
NL_CB_MSG_IN,
|
||||
/** Called for every message sent out except for nl_sendto() */
|
||||
NL_CB_MSG_OUT,
|
||||
/** Message is malformed and invalid */
|
||||
NL_CB_INVALID,
|
||||
/** Called instead of internal sequence number checking */
|
||||
NL_CB_SEQ_CHECK,
|
||||
/** Sending of an acknowledge message has been requested */
|
||||
NL_CB_SEND_ACK,
|
||||
__NL_CB_TYPE_MAX,
|
||||
};
|
||||
|
||||
#define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1)
|
||||
|
||||
extern struct nl_cb * nl_cb_alloc(enum nl_cb_kind);
|
||||
extern struct nl_cb * nl_cb_clone(struct nl_cb *);
|
||||
extern struct nl_cb * nl_cb_get(struct nl_cb *);
|
||||
extern void nl_cb_put(struct nl_cb *);
|
||||
|
||||
extern int nl_cb_set(struct nl_cb *, enum nl_cb_type, enum nl_cb_kind,
|
||||
nl_recvmsg_msg_cb_t, void *);
|
||||
extern int nl_cb_set_all(struct nl_cb *, enum nl_cb_kind,
|
||||
nl_recvmsg_msg_cb_t, void *);
|
||||
extern int nl_cb_err(struct nl_cb *, enum nl_cb_kind, nl_recvmsg_err_cb_t,
|
||||
void *);
|
||||
|
||||
extern void nl_cb_overwrite_recvmsgs(struct nl_cb *,
|
||||
int (*func)(struct nl_handle *,
|
||||
struct nl_cb *));
|
||||
extern void nl_cb_overwrite_recv(struct nl_cb *,
|
||||
int (*func)(struct nl_handle *,
|
||||
struct sockaddr_nl *,
|
||||
unsigned char **,
|
||||
struct ucred **));
|
||||
extern void nl_cb_overwrite_send(struct nl_cb *,
|
||||
int (*func)(struct nl_handle *,
|
||||
struct nl_msg *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
85
include/netlink/list.h
Normal file
85
include/netlink/list.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* netlink/list.h Netlink List Utilities
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LIST_H_
|
||||
#define NETLINK_LIST_H_
|
||||
|
||||
struct nl_list_head
|
||||
{
|
||||
struct nl_list_head * next;
|
||||
struct nl_list_head * prev;
|
||||
};
|
||||
|
||||
|
||||
static inline void __nl_list_add(struct nl_list_head *obj,
|
||||
struct nl_list_head *prev,
|
||||
struct nl_list_head *next)
|
||||
{
|
||||
prev->next = obj;
|
||||
obj->prev = prev;
|
||||
next->prev = obj;
|
||||
obj->next = next;
|
||||
}
|
||||
|
||||
static inline void nl_list_add_tail(struct nl_list_head *obj,
|
||||
struct nl_list_head *head)
|
||||
{
|
||||
__nl_list_add(obj, head->prev, head);
|
||||
}
|
||||
|
||||
static inline void nl_list_add_head(struct nl_list_head *obj,
|
||||
struct nl_list_head *head)
|
||||
{
|
||||
__nl_list_add(obj, head, head->next);
|
||||
}
|
||||
|
||||
static inline void nl_list_del(struct nl_list_head *obj)
|
||||
{
|
||||
obj->next->prev = obj->prev;
|
||||
obj->prev->next = obj->next;
|
||||
}
|
||||
|
||||
static inline int nl_list_empty(struct nl_list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
#define nl_container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - ((size_t) &((type *)0)->member));})
|
||||
|
||||
#define nl_list_entry(ptr, type, member) \
|
||||
nl_container_of(ptr, type, member)
|
||||
|
||||
#define nl_list_at_tail(pos, head, member) \
|
||||
((pos)->member.next == (head))
|
||||
|
||||
#define nl_list_at_head(pos, head, member) \
|
||||
((pos)->member.prev == (head))
|
||||
|
||||
#define NL_LIST_HEAD(name) \
|
||||
struct nl_list_head name = { &(name), &(name) }
|
||||
|
||||
#define nl_list_for_each_entry(pos, head, member) \
|
||||
for (pos = nl_list_entry((head)->next, typeof(*pos), member); \
|
||||
&(pos)->member != (head); \
|
||||
(pos) = nl_list_entry((pos)->member.next, typeof(*(pos)), member))
|
||||
|
||||
#define nl_list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = nl_list_entry((head)->next, typeof(*pos), member), \
|
||||
n = nl_list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&(pos)->member != (head); \
|
||||
pos = n, n = nl_list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
#define nl_init_list_head(head) \
|
||||
do { (head)->next = (head); (head)->prev = (head); } while (0)
|
||||
|
||||
#endif
|
143
include/netlink/msg.h
Normal file
143
include/netlink/msg.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* netlink/msg.c Netlink Messages 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_MSG_H_
|
||||
#define NETLINK_MSG_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/attr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NL_DONTPAD 0
|
||||
|
||||
/**
|
||||
* @ingroup msg
|
||||
* @brief
|
||||
* Will cause the netlink pid to be set to the pid assigned to
|
||||
* the netlink handle (socket) just before sending the message off.
|
||||
* @note Requires the use of nl_send_auto_complete()!
|
||||
*/
|
||||
#define NL_AUTO_PID 0
|
||||
|
||||
/**
|
||||
* @ingroup msg
|
||||
* @brief
|
||||
* May be used to refer to a sequence number which should be
|
||||
* automatically set just before sending the message off.
|
||||
* @note Requires the use of nl_send_auto_complete()!
|
||||
*/
|
||||
#define NL_AUTO_SEQ 0
|
||||
|
||||
struct nl_msg;
|
||||
struct nl_tree;
|
||||
struct ucred;
|
||||
|
||||
/* size calculations */
|
||||
extern int nlmsg_msg_size(int);
|
||||
extern int nlmsg_total_size(int);
|
||||
extern int nlmsg_padlen(int);
|
||||
|
||||
/* payload access */
|
||||
extern void * nlmsg_data(const struct nlmsghdr *);
|
||||
extern int nlmsg_len(const struct nlmsghdr *);
|
||||
extern void * nlmsg_tail(const struct nlmsghdr *);
|
||||
|
||||
/* attribute access */
|
||||
extern struct nlattr * nlmsg_attrdata(const struct nlmsghdr *, int);
|
||||
extern int nlmsg_attrlen(const struct nlmsghdr *, int);
|
||||
|
||||
/* message parsing */
|
||||
extern int nlmsg_ok(const struct nlmsghdr *, int);
|
||||
extern struct nlmsghdr * nlmsg_next(struct nlmsghdr *, int *);
|
||||
extern int nlmsg_parse(struct nlmsghdr *, int, struct nlattr **,
|
||||
int, struct nla_policy *);
|
||||
extern struct nlattr * nlmsg_find_attr(struct nlmsghdr *, int, int);
|
||||
extern int nlmsg_validate(struct nlmsghdr *, int, int,
|
||||
struct nla_policy *);
|
||||
|
||||
/* Backward compatibility */
|
||||
#define nlmsg_new() nlmsg_alloc()
|
||||
#define nlmsg_build_simple(a, b) nlmsg_alloc_simple(a, b)
|
||||
#define nlmsg_build(ptr) nlmsg_inherit(ptr)
|
||||
|
||||
extern struct nl_msg * nlmsg_alloc(void);
|
||||
extern struct nl_msg * nlmsg_alloc_simple(int, int);
|
||||
extern struct nl_msg * nlmsg_inherit(struct nlmsghdr *);
|
||||
extern struct nl_msg * nlmsg_convert(struct nlmsghdr *);
|
||||
extern void * nlmsg_reserve(struct nl_msg *, size_t, int);
|
||||
extern int nlmsg_append(struct nl_msg *, void *, size_t, int);
|
||||
|
||||
extern struct nlmsghdr * nlmsg_put(struct nl_msg *, uint32_t, uint32_t,
|
||||
int, int, int);
|
||||
extern struct nlmsghdr * nlmsg_hdr(struct nl_msg *);
|
||||
extern void nlmsg_free(struct nl_msg *);
|
||||
|
||||
/* attribute modification */
|
||||
extern void nlmsg_set_proto(struct nl_msg *, int);
|
||||
extern int nlmsg_get_proto(struct nl_msg *);
|
||||
extern void nlmsg_set_src(struct nl_msg *, struct sockaddr_nl *);
|
||||
extern struct sockaddr_nl *nlmsg_get_src(struct nl_msg *);
|
||||
extern void nlmsg_set_dst(struct nl_msg *, struct sockaddr_nl *);
|
||||
extern struct sockaddr_nl *nlmsg_get_dst(struct nl_msg *);
|
||||
extern void nlmsg_set_creds(struct nl_msg *, struct ucred *);
|
||||
extern struct ucred * nlmsg_get_creds(struct nl_msg *);
|
||||
|
||||
extern char * nl_nlmsgtype2str(int, char *, size_t);
|
||||
extern int nl_str2nlmsgtype(const char *);
|
||||
|
||||
extern char * nl_nlmsg_flags2str(int, char *, size_t);
|
||||
|
||||
extern int nl_msg_parse(struct nl_msg *,
|
||||
void (*cb)(struct nl_object *, void *),
|
||||
void *);
|
||||
|
||||
extern void nl_msg_dump(struct nl_msg *, FILE *);
|
||||
|
||||
/**
|
||||
* @name Iterators
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup msg
|
||||
* Iterate over a stream of attributes in a message
|
||||
* @arg pos loop counter, set to current attribute
|
||||
* @arg nlh netlink message header
|
||||
* @arg hdrlen length of family header
|
||||
* @arg rem initialized to len, holds bytes currently remaining in stream
|
||||
*/
|
||||
#define nlmsg_for_each_attr(pos, nlh, hdrlen, rem) \
|
||||
nla_for_each_attr(pos, nlmsg_attrdata(nlh, hdrlen), \
|
||||
nlmsg_attrlen(nlh, hdrlen), rem)
|
||||
|
||||
/**
|
||||
* Iterate over a stream of messages
|
||||
* @arg pos loop counter, set to current message
|
||||
* @arg head head of message stream
|
||||
* @arg len length of message stream
|
||||
* @arg rem initialized to len, holds bytes currently remaining in stream
|
||||
*/
|
||||
#define nlmsg_for_each_msg(pos, head, len, rem) \
|
||||
for (pos = head, rem = len; \
|
||||
nlmsg_ok(pos, rem); \
|
||||
pos = nlmsg_next(pos, &(rem)))
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
115
include/netlink/netfilter/ct.h
Normal file
115
include/netlink/netfilter/ct.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* netlink/netfilter/ct.h Conntrack
|
||||
*
|
||||
* 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) 2007 Philip Craig <philipc@snapgear.com>
|
||||
* Copyright (c) 2007 Secure Computing Corporation
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CT_H_
|
||||
#define NETLINK_CT_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/msg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nfnl_ct;
|
||||
|
||||
extern struct nl_object_ops ct_obj_ops;
|
||||
|
||||
/* General */
|
||||
extern struct nfnl_ct * nfnl_ct_alloc(void);
|
||||
extern struct nl_cache *nfnl_ct_alloc_cache(struct nl_handle *);
|
||||
|
||||
extern int nfnlmsg_ct_group(struct nlmsghdr *);
|
||||
extern struct nfnl_ct * nfnlmsg_ct_parse(struct nlmsghdr *);
|
||||
|
||||
extern void nfnl_ct_get(struct nfnl_ct *);
|
||||
extern void nfnl_ct_put(struct nfnl_ct *);
|
||||
|
||||
extern int nfnl_ct_dump_request(struct nl_handle *);
|
||||
|
||||
extern void nfnl_ct_set_family(struct nfnl_ct *, uint8_t);
|
||||
extern uint8_t nfnl_ct_get_family(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_proto(struct nfnl_ct *, uint8_t);
|
||||
extern int nfnl_ct_test_proto(const struct nfnl_ct *);
|
||||
extern uint8_t nfnl_ct_get_proto(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_tcp_state(struct nfnl_ct *, uint8_t);
|
||||
extern int nfnl_ct_test_tcp_state(const struct nfnl_ct *);
|
||||
extern uint8_t nfnl_ct_get_tcp_state(const struct nfnl_ct *);
|
||||
extern char * nfnl_ct_tcp_state2str(uint8_t, char *, size_t);
|
||||
extern int nfnl_ct_str2tcp_state(const char *name);
|
||||
|
||||
extern void nfnl_ct_set_status(struct nfnl_ct *, uint32_t);
|
||||
extern int nfnl_ct_test_status(const struct nfnl_ct *);
|
||||
extern uint32_t nfnl_ct_get_status(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_timeout(struct nfnl_ct *, uint32_t);
|
||||
extern int nfnl_ct_test_timeout(const struct nfnl_ct *);
|
||||
extern uint32_t nfnl_ct_get_timeout(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_mark(struct nfnl_ct *, uint32_t);
|
||||
extern int nfnl_ct_test_mark(const struct nfnl_ct *);
|
||||
extern uint32_t nfnl_ct_get_mark(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_use(struct nfnl_ct *, uint32_t);
|
||||
extern int nfnl_ct_test_use(const struct nfnl_ct *);
|
||||
extern uint32_t nfnl_ct_get_use(const struct nfnl_ct *);
|
||||
|
||||
extern void nfnl_ct_set_id(struct nfnl_ct *, uint32_t);
|
||||
extern int nfnl_ct_test_id(const struct nfnl_ct *);
|
||||
extern uint32_t nfnl_ct_get_id(const struct nfnl_ct *);
|
||||
|
||||
extern int nfnl_ct_set_src(struct nfnl_ct *, int,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * nfnl_ct_get_src(const struct nfnl_ct *, int);
|
||||
|
||||
extern int nfnl_ct_set_dst(struct nfnl_ct *, int,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * nfnl_ct_get_dst(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_src_port(struct nfnl_ct *, int, uint16_t);
|
||||
extern int nfnl_ct_test_src_port(const struct nfnl_ct *, int);
|
||||
extern uint16_t nfnl_ct_get_src_port(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_dst_port(struct nfnl_ct *, int, uint16_t);
|
||||
extern int nfnl_ct_test_dst_port(const struct nfnl_ct *, int);
|
||||
extern uint16_t nfnl_ct_get_dst_port(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_icmp_id(struct nfnl_ct *, int, uint16_t);
|
||||
extern int nfnl_ct_test_icmp_id(const struct nfnl_ct *, int);
|
||||
extern uint16_t nfnl_ct_get_icmp_id(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_icmp_type(struct nfnl_ct *, int, uint8_t);
|
||||
extern int nfnl_ct_test_icmp_type(const struct nfnl_ct *, int);
|
||||
extern uint8_t nfnl_ct_get_icmp_type(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_icmp_code(struct nfnl_ct *, int, uint8_t);
|
||||
extern int nfnl_ct_test_icmp_code(const struct nfnl_ct *, int);
|
||||
extern uint8_t nfnl_ct_get_icmp_code(const struct nfnl_ct *, int);
|
||||
|
||||
extern void nfnl_ct_set_packets(struct nfnl_ct *, int, uint64_t);
|
||||
extern int nfnl_ct_test_packets(const struct nfnl_ct *, int);
|
||||
extern uint64_t nfnl_ct_get_packets(const struct nfnl_ct *,int);
|
||||
|
||||
extern void nfnl_ct_set_bytes(struct nfnl_ct *, int, uint64_t);
|
||||
extern int nfnl_ct_test_bytes(const struct nfnl_ct *, int);
|
||||
extern uint64_t nfnl_ct_get_bytes(const struct nfnl_ct *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
105
include/netlink/netfilter/log.h
Normal file
105
include/netlink/netfilter/log.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* netlink/netfilter/log.h Netfilter Log
|
||||
*
|
||||
* 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) 2007 Philip Craig <philipc@snapgear.com>
|
||||
* Copyright (c) 2007 Secure Computing Corporation
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LOG_H_
|
||||
#define NETLINK_LOG_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_handle;
|
||||
struct nlmsghdr;
|
||||
struct nfnl_log;
|
||||
|
||||
extern struct nl_object_ops log_obj_ops;
|
||||
|
||||
/* General */
|
||||
extern struct nfnl_log *nfnl_log_alloc(void);
|
||||
extern struct nfnl_log *nfnlmsg_log_parse(struct nlmsghdr *);
|
||||
|
||||
extern void nfnl_log_get(struct nfnl_log *);
|
||||
extern void nfnl_log_put(struct nfnl_log *);
|
||||
|
||||
extern struct nl_msg * nfnl_log_build_bind(uint16_t);;
|
||||
extern int nfnl_log_bind(struct nl_handle *, uint16_t);
|
||||
extern struct nl_msg * nfnl_log_build_unbind(uint16_t);
|
||||
extern int nfnl_log_unbind(struct nl_handle *, uint16_t);
|
||||
extern struct nl_msg * nfnl_log_build_pf_bind(uint8_t);
|
||||
extern int nfnl_log_pf_bind(struct nl_handle *, uint8_t);
|
||||
extern struct nl_msg * nfnl_log_build_pf_unbind(uint8_t);
|
||||
extern int nfnl_log_pf_unbind(struct nl_handle *, uint8_t);
|
||||
extern struct nl_msg * nfnl_log_build_mode(uint16_t, uint8_t, uint32_t);
|
||||
extern int nfnl_log_set_mode(struct nl_handle *, uint16_t,
|
||||
uint8_t, uint32_t);
|
||||
|
||||
extern void nfnl_log_set_family(struct nfnl_log *, uint8_t);
|
||||
extern uint8_t nfnl_log_get_family(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_hwproto(struct nfnl_log *, uint16_t);
|
||||
extern int nfnl_log_test_hwproto(const struct nfnl_log *);
|
||||
extern uint16_t nfnl_log_get_hwproto(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_hook(struct nfnl_log *, uint8_t);
|
||||
extern int nfnl_log_test_hook(const struct nfnl_log *);
|
||||
extern uint8_t nfnl_log_get_hook(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_mark(struct nfnl_log *, uint32_t);
|
||||
extern int nfnl_log_test_mark(const struct nfnl_log *);
|
||||
extern uint32_t nfnl_log_get_mark(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_timestamp(struct nfnl_log *,
|
||||
struct timeval *);
|
||||
extern const struct timeval *nfnl_log_get_timestamp(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_indev(struct nfnl_log *, uint32_t);
|
||||
extern uint32_t nfnl_log_get_indev(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_outdev(struct nfnl_log *, uint32_t);
|
||||
extern uint32_t nfnl_log_get_outdev(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_physindev(struct nfnl_log *, uint32_t);
|
||||
extern uint32_t nfnl_log_get_physindev(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_physoutdev(struct nfnl_log *, uint32_t);
|
||||
extern uint32_t nfnl_log_get_physoutdev(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_hwaddr(struct nfnl_log *, uint8_t *, int);
|
||||
extern const uint8_t * nfnl_log_get_hwaddr(const struct nfnl_log *, int *);
|
||||
|
||||
extern int nfnl_log_set_payload(struct nfnl_log *, uint8_t *, int);
|
||||
extern const void * nfnl_log_get_payload(const struct nfnl_log *, int *);
|
||||
|
||||
extern int nfnl_log_set_prefix(struct nfnl_log *, void *);
|
||||
extern const char * nfnl_log_get_prefix(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_uid(struct nfnl_log *, uint32_t);
|
||||
extern int nfnl_log_test_uid(const struct nfnl_log *);
|
||||
extern uint32_t nfnl_log_get_uid(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_seq(struct nfnl_log *, uint32_t);
|
||||
extern int nfnl_log_test_seq(const struct nfnl_log *);
|
||||
extern uint32_t nfnl_log_get_seq(const struct nfnl_log *);
|
||||
|
||||
extern void nfnl_log_set_seq_global(struct nfnl_log *, uint32_t);
|
||||
extern int nfnl_log_test_seq_global(const struct nfnl_log *);
|
||||
extern uint32_t nfnl_log_get_seq_global(const struct nfnl_log *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
44
include/netlink/netfilter/nfnl.h
Normal file
44
include/netlink/netfilter/nfnl.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* netlink/nfnl/nfnl.h Netfilter Netlink
|
||||
*
|
||||
* 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) 2007 Philip Craig <philipc@snapgear.com>
|
||||
* Copyright (c) 2007 Secure Computing Corporation
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_NFNL_H_
|
||||
#define NETLINK_NFNL_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NFNL_HDRLEN NLMSG_ALIGN(sizeof(struct nfgenmsg))
|
||||
#define NFNLMSG_TYPE(subsys, subtype) (((subsys) << 8) | (subtype))
|
||||
|
||||
extern int nfnl_connect(struct nl_handle *);
|
||||
|
||||
extern uint8_t nfnlmsg_subsys(struct nlmsghdr *);
|
||||
extern uint8_t nfnlmsg_subtype(struct nlmsghdr *);
|
||||
extern uint8_t nfnlmsg_family(struct nlmsghdr *);
|
||||
extern uint16_t nfnlmsg_res_id(struct nlmsghdr *);
|
||||
|
||||
extern int nfnl_send_simple(struct nl_handle *, uint8_t, uint8_t,
|
||||
int, uint8_t, uint16_t);
|
||||
extern struct nl_msg * nfnlmsg_alloc_simple(uint8_t, uint8_t, int,
|
||||
uint8_t, uint16_t);
|
||||
extern int nfnlmsg_put(struct nl_msg *, uint32_t, uint32_t,
|
||||
uint8_t, uint8_t, int, uint8_t, uint16_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
50
include/netlink/netlink-compat.h
Normal file
50
include/netlink/netlink-compat.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* netlink/netlink-compat.h Netlink Compatability
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_COMPAT_H_
|
||||
#define NETLINK_COMPAT_H_
|
||||
|
||||
#if !defined _LINUX_SOCKET_H && !defined _BITS_SOCKADDR_H
|
||||
typedef unsigned short sa_family_t;
|
||||
#endif
|
||||
|
||||
#ifndef IFNAMSIZ
|
||||
/** Maximum length of a interface name */
|
||||
#define IFNAMSIZ 16
|
||||
#endif
|
||||
|
||||
/* patch 2.4.x if_arp */
|
||||
#ifndef ARPHRD_INFINIBAND
|
||||
#define ARPHRD_INFINIBAND 32
|
||||
#endif
|
||||
|
||||
/* patch 2.4.x eth header file */
|
||||
#ifndef ETH_P_MPLS_UC
|
||||
#define ETH_P_MPLS_UC 0x8847
|
||||
#endif
|
||||
|
||||
#ifndef ETH_P_MPLS_MC
|
||||
#define ETH_P_MPLS_MC 0x8848
|
||||
#endif
|
||||
|
||||
#ifndef ETH_P_EDP2
|
||||
#define ETH_P_EDP2 0x88A2
|
||||
#endif
|
||||
|
||||
#ifndef ETH_P_HDLC
|
||||
#define ETH_P_HDLC 0x0019
|
||||
#endif
|
||||
|
||||
#ifndef AF_LLC
|
||||
#define AF_LLC 26
|
||||
#endif
|
||||
|
||||
#endif
|
196
include/netlink/netlink-kernel.h
Normal file
196
include/netlink/netlink-kernel.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
#ifndef __LINUX_NETLINK_H
|
||||
#define __LINUX_NETLINK_H
|
||||
|
||||
/**
|
||||
* Netlink socket address
|
||||
* @ingroup nl
|
||||
*/
|
||||
struct sockaddr_nl
|
||||
{
|
||||
/** socket family (AF_NETLINK) */
|
||||
sa_family_t nl_family;
|
||||
|
||||
/** Padding (unused) */
|
||||
unsigned short nl_pad;
|
||||
|
||||
/** Unique process ID */
|
||||
uint32_t nl_pid;
|
||||
|
||||
/** Multicast group subscriptions */
|
||||
uint32_t nl_groups;
|
||||
};
|
||||
|
||||
/**
|
||||
* Netlink message header
|
||||
* @ingroup msg
|
||||
*/
|
||||
struct nlmsghdr
|
||||
{
|
||||
/**
|
||||
* Length of message including header.
|
||||
*/
|
||||
uint32_t nlmsg_len;
|
||||
|
||||
/**
|
||||
* Message type (content type)
|
||||
*/
|
||||
uint16_t nlmsg_type;
|
||||
|
||||
/**
|
||||
* Message flags
|
||||
*/
|
||||
uint16_t nlmsg_flags;
|
||||
|
||||
/**
|
||||
* Sequence number
|
||||
*/
|
||||
uint32_t nlmsg_seq;
|
||||
|
||||
/**
|
||||
* Netlink PID of the proccess sending the message.
|
||||
*/
|
||||
uint32_t nlmsg_pid;
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Standard message flags
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Must be set on all request messages (typically from user space to
|
||||
* kernel space).
|
||||
* @ingroup msg
|
||||
*/
|
||||
#define NLM_F_REQUEST 1
|
||||
|
||||
/**
|
||||
* Indicates the message is part of a multipart message terminated
|
||||
* by NLMSG_DONE.
|
||||
*/
|
||||
#define NLM_F_MULTI 2
|
||||
|
||||
/**
|
||||
* Request for an acknowledgment on success.
|
||||
*/
|
||||
#define NLM_F_ACK 4
|
||||
|
||||
/**
|
||||
* Echo this request
|
||||
*/
|
||||
#define NLM_F_ECHO 8
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Additional message flags for GET requests
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the complete table instead of a single entry.
|
||||
* @ingroup msg
|
||||
*/
|
||||
#define NLM_F_ROOT 0x100
|
||||
|
||||
/**
|
||||
* Return all entries matching criteria passed in message content.
|
||||
*/
|
||||
#define NLM_F_MATCH 0x200
|
||||
|
||||
/**
|
||||
* Return an atomic snapshot of the table being referenced. This
|
||||
* may require special privileges because it has the potential to
|
||||
* interrupt service in the FE for a longer time.
|
||||
*/
|
||||
#define NLM_F_ATOMIC 0x400
|
||||
|
||||
/**
|
||||
* Dump all entries
|
||||
*/
|
||||
#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Additional messsage flags for NEW requests
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Replace existing matching config object with this request.
|
||||
* @ingroup msg
|
||||
*/
|
||||
#define NLM_F_REPLACE 0x100
|
||||
|
||||
/**
|
||||
* Don't replace the config object if it already exists.
|
||||
*/
|
||||
#define NLM_F_EXCL 0x200
|
||||
|
||||
/**
|
||||
* Create config object if it doesn't already exist.
|
||||
*/
|
||||
#define NLM_F_CREATE 0x400
|
||||
|
||||
/**
|
||||
* Add to the end of the object list.
|
||||
*/
|
||||
#define NLM_F_APPEND 0x800
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Standard Message types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* No operation, message must be ignored
|
||||
* @ingroup msg
|
||||
*/
|
||||
#define NLMSG_NOOP 0x1
|
||||
|
||||
/**
|
||||
* The message signals an error and the payload contains a nlmsgerr
|
||||
* structure. This can be looked at as a NACK and typically it is
|
||||
* from FEC to CPC.
|
||||
*/
|
||||
#define NLMSG_ERROR 0x2
|
||||
|
||||
/**
|
||||
* Message terminates a multipart message.
|
||||
*/
|
||||
#define NLMSG_DONE 0x3
|
||||
|
||||
/**
|
||||
* The message signals that data got lost
|
||||
*/
|
||||
#define NLMSG_OVERRUN 0x4
|
||||
|
||||
/**
|
||||
* Lower limit of reserved message types
|
||||
*/
|
||||
#define NLMSG_MIN_TYPE 0x10
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Netlink error message
|
||||
* @ingroup msg
|
||||
*/
|
||||
struct nlmsgerr
|
||||
{
|
||||
/** Error code (errno number) */
|
||||
int error;
|
||||
|
||||
/** Original netlink message causing the error */
|
||||
struct nlmsghdr msg;
|
||||
};
|
||||
|
||||
struct nl_pktinfo
|
||||
{
|
||||
__u32 group;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_NETLINK_H */
|
74
include/netlink/netlink.h
Normal file
74
include/netlink/netlink.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* netlink/netlink.h 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_NETLINK_H_
|
||||
#define NETLINK_NETLINK_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <netlink/netlink-compat.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/ip_mp_alg.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <netlink/types.h>
|
||||
#include <netlink/handlers.h>
|
||||
#include <netlink/socket.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int nl_debug;
|
||||
extern struct nl_dump_params nl_debug_dp;
|
||||
|
||||
/* Connection Management */
|
||||
extern int nl_connect(struct nl_handle *, int);
|
||||
extern void nl_close(struct nl_handle *);
|
||||
|
||||
/* Send */
|
||||
extern int nl_sendto(struct nl_handle *, void *, size_t);
|
||||
extern int nl_sendmsg(struct nl_handle *, struct nl_msg *,
|
||||
struct msghdr *);
|
||||
extern int nl_send(struct nl_handle *, struct nl_msg *);
|
||||
extern int nl_send_auto_complete(struct nl_handle *,
|
||||
struct nl_msg *);
|
||||
extern int nl_send_simple(struct nl_handle *, int, int,
|
||||
void *, size_t);
|
||||
|
||||
/* Receive */
|
||||
extern int nl_recv(struct nl_handle *,
|
||||
struct sockaddr_nl *, unsigned char **,
|
||||
struct ucred **);
|
||||
|
||||
extern int nl_recvmsgs(struct nl_handle *, struct nl_cb *);
|
||||
|
||||
#define nl_recvmsgs_def(handle) nl_recvmsgs_default(handle)
|
||||
extern int nl_recvmsgs_default(struct nl_handle *);
|
||||
|
||||
extern int nl_wait_for_ack(struct nl_handle *);
|
||||
|
||||
/* Netlink Family Translations */
|
||||
extern char * nl_nlfamily2str(int, char *, size_t);
|
||||
extern int nl_str2nlfamily(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
64
include/netlink/object.h
Normal file
64
include/netlink/object.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* netlink/object.c Generic Cacheable Object
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_OBJECT_H_
|
||||
#define NETLINK_OBJECT_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct nl_cache;
|
||||
struct nl_object;
|
||||
struct nl_object_ops;
|
||||
|
||||
#define OBJ_CAST(ptr) ((struct nl_object *) (ptr))
|
||||
|
||||
/* General */
|
||||
extern struct nl_object * nl_object_alloc(struct nl_object_ops *);
|
||||
extern struct nl_object * nl_object_alloc_name(const char *);
|
||||
extern void nl_object_free(struct nl_object *);
|
||||
extern struct nl_object * nl_object_clone(struct nl_object *obj);
|
||||
extern void nl_object_get(struct nl_object *);
|
||||
extern void nl_object_put(struct nl_object *);
|
||||
extern int nl_object_shared(struct nl_object *);
|
||||
extern void nl_object_dump(struct nl_object *,
|
||||
struct nl_dump_params *);
|
||||
extern int nl_object_identical(struct nl_object *,
|
||||
struct nl_object *);
|
||||
extern uint32_t nl_object_diff(struct nl_object *,
|
||||
struct nl_object *);
|
||||
extern int nl_object_match_filter(struct nl_object *,
|
||||
struct nl_object *);
|
||||
extern char * nl_object_attrs2str(struct nl_object *,
|
||||
uint32_t attrs, char *buf,
|
||||
size_t);
|
||||
extern char * nl_object_attr_list(struct nl_object *,
|
||||
char *, size_t);
|
||||
|
||||
/* Marks */
|
||||
extern void nl_object_mark(struct nl_object *);
|
||||
extern void nl_object_unmark(struct nl_object *);
|
||||
extern int nl_object_is_marked(struct nl_object *);
|
||||
|
||||
/* Access Functions */
|
||||
extern int nl_object_get_refcnt(struct nl_object *);
|
||||
extern struct nl_cache * nl_object_get_cache(struct nl_object *);
|
||||
extern inline void * nl_object_priv(struct nl_object *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
91
include/netlink/route/addr.h
Normal file
91
include/netlink/route/addr.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* netlink/route/addr.c rtnetlink addr layer
|
||||
*
|
||||
* 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>
|
||||
* Baruch Even <baruch@ev-en.org>,
|
||||
* Mediatrix Telecom, inc. <ericb@mediatrix.com>
|
||||
*/
|
||||
|
||||
#ifndef NETADDR_ADDR_H_
|
||||
#define NETADDR_ADDR_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_addr;
|
||||
|
||||
/* General */
|
||||
extern struct rtnl_addr *rtnl_addr_alloc(void);
|
||||
extern void rtnl_addr_put(struct rtnl_addr *);
|
||||
|
||||
extern struct nl_cache *rtnl_addr_alloc_cache(struct nl_handle *);
|
||||
|
||||
/* Address Addition */
|
||||
extern struct nl_msg * rtnl_addr_build_add_request(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_add(struct nl_handle *, struct rtnl_addr *,
|
||||
int);
|
||||
|
||||
/* Address Deletion */
|
||||
extern struct nl_msg * rtnl_addr_build_delete_request(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_delete(struct nl_handle *,
|
||||
struct rtnl_addr *, int);
|
||||
|
||||
/* Address Flags Translations */
|
||||
extern char * rtnl_addr_flags2str(int, char *, size_t);
|
||||
extern int rtnl_addr_str2flags(const char *);
|
||||
|
||||
/* Attribute Access */
|
||||
extern void rtnl_addr_set_label(struct rtnl_addr *, const char *);
|
||||
extern char * rtnl_addr_get_label(struct rtnl_addr *);
|
||||
|
||||
extern void rtnl_addr_set_ifindex(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_get_ifindex(struct rtnl_addr *);
|
||||
|
||||
extern void rtnl_addr_set_family(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_get_family(struct rtnl_addr *);
|
||||
|
||||
extern void rtnl_addr_set_prefixlen(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_get_prefixlen(struct rtnl_addr *);
|
||||
|
||||
extern void rtnl_addr_set_scope(struct rtnl_addr *, int);
|
||||
extern int rtnl_addr_get_scope(struct rtnl_addr *);
|
||||
|
||||
extern void rtnl_addr_set_flags(struct rtnl_addr *, unsigned int);
|
||||
extern void rtnl_addr_unset_flags(struct rtnl_addr *, unsigned int);
|
||||
extern unsigned int rtnl_addr_get_flags(struct rtnl_addr *);
|
||||
|
||||
extern int rtnl_addr_set_local(struct rtnl_addr *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_addr_get_local(struct rtnl_addr *);
|
||||
|
||||
extern int rtnl_addr_set_peer(struct rtnl_addr *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_addr_get_peer(struct rtnl_addr *);
|
||||
|
||||
extern int rtnl_addr_set_broadcast(struct rtnl_addr *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_addr_get_broadcast(struct rtnl_addr *);
|
||||
|
||||
extern int rtnl_addr_set_anycast(struct rtnl_addr *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_addr_get_anycast(struct rtnl_addr *);
|
||||
|
||||
extern int rtnl_addr_set_multicast(struct rtnl_addr *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_addr_get_multicast(struct rtnl_addr *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
73
include/netlink/route/class-modules.h
Normal file
73
include/netlink/route/class-modules.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* netlink/route/class-modules.h Class Module 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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CLASS_MODULES_H_
|
||||
#define NETLINK_CLASS_MODULES_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Class operations
|
||||
* @ingroup class_api
|
||||
*/
|
||||
struct rtnl_class_ops
|
||||
{
|
||||
/**
|
||||
* Kind/Name of class
|
||||
*/
|
||||
char co_kind[32];
|
||||
|
||||
/**
|
||||
* Dump callbacks
|
||||
*/
|
||||
int (*co_dump[NL_DUMP_MAX+1])(struct rtnl_class *,
|
||||
struct nl_dump_params *, int);
|
||||
|
||||
/**
|
||||
* Must return the contents supposed to be in TCA_OPTIONS
|
||||
*/
|
||||
struct nl_msg *(*co_get_opts)(struct rtnl_class *);
|
||||
|
||||
/**
|
||||
* TCA_OPTIONS message parser
|
||||
*/
|
||||
int (*co_msg_parser)(struct rtnl_class *);
|
||||
|
||||
/**
|
||||
* Called before a class object gets destroyed
|
||||
*/
|
||||
void (*co_free_data)(struct rtnl_class *);
|
||||
|
||||
/**
|
||||
* Called whenever a class object needs to be cloned
|
||||
*/
|
||||
int (*co_clone)(struct rtnl_class *, struct rtnl_class *);
|
||||
|
||||
/**
|
||||
* INTERNAL (Do not use)
|
||||
*/
|
||||
struct rtnl_class_ops *co_next;
|
||||
};
|
||||
|
||||
extern int rtnl_class_register(struct rtnl_class_ops *);
|
||||
extern int rtnl_class_unregister(struct rtnl_class_ops *);
|
||||
extern struct rtnl_class_ops * rtnl_class_lookup_ops(struct rtnl_class *);
|
||||
extern struct rtnl_class_ops * __rtnl_class_lookup_ops(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
68
include/netlink/route/class.h
Normal file
68
include/netlink/route/class.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* netlink/route/class.h Classes
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CLASS_H_
|
||||
#define NETLINK_CLASS_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/tc.h>
|
||||
#include <netlink/route/qdisc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_class;
|
||||
|
||||
extern struct nl_object_ops class_obj_ops;
|
||||
|
||||
/* General */
|
||||
extern struct rtnl_class * rtnl_class_alloc(void);
|
||||
extern void rtnl_class_put(struct rtnl_class *);
|
||||
extern struct nl_cache * rtnl_class_alloc_cache(struct nl_handle *, int);
|
||||
|
||||
/* leaf qdisc access */
|
||||
extern struct rtnl_qdisc * rtnl_class_leaf_qdisc(struct rtnl_class *,
|
||||
struct nl_cache *);
|
||||
|
||||
/* class addition */
|
||||
extern struct nl_msg * rtnl_class_build_add_request(struct rtnl_class *, int);
|
||||
extern int rtnl_class_add(struct nl_handle *, struct rtnl_class *, int);
|
||||
|
||||
/* attribute modification */
|
||||
extern void rtnl_class_set_ifindex(struct rtnl_class *, int);
|
||||
extern int rtnl_class_get_ifindex(struct rtnl_class *);
|
||||
extern void rtnl_class_set_handle(struct rtnl_class *, uint32_t);
|
||||
extern uint32_t rtnl_class_get_handle(struct rtnl_class *);
|
||||
extern void rtnl_class_set_parent(struct rtnl_class *, uint32_t);
|
||||
extern uint32_t rtnl_class_get_parent(struct rtnl_class *);
|
||||
extern void rtnl_class_set_kind(struct rtnl_class *, const char *);
|
||||
extern char * rtnl_class_get_kind(struct rtnl_class *);
|
||||
extern uint64_t rtnl_class_get_stat(struct rtnl_class *,
|
||||
enum rtnl_tc_stats_id);
|
||||
|
||||
/* iterators */
|
||||
extern void rtnl_class_foreach_child(struct rtnl_class *,
|
||||
struct nl_cache *,
|
||||
void (*cb)(struct nl_object *,
|
||||
void *),
|
||||
void *);
|
||||
extern void rtnl_class_foreach_cls(struct rtnl_class *,
|
||||
struct nl_cache *,
|
||||
void (*cb)(struct nl_object *,
|
||||
void *),
|
||||
void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
72
include/netlink/route/classifier-modules.h
Normal file
72
include/netlink/route/classifier-modules.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* netlink/route/classifier-modules.h Classifier Module 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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CLASS_MODULES_H_
|
||||
#define NETLINK_CLASS_MODULES_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Classifier operations
|
||||
* @ingroup cls_api
|
||||
*/
|
||||
struct rtnl_cls_ops
|
||||
{
|
||||
/**
|
||||
* Kind/Name of classifier
|
||||
*/
|
||||
char co_kind[32];
|
||||
|
||||
/**
|
||||
* Dump callbacks
|
||||
*/
|
||||
int (*co_dump[NL_DUMP_MAX+1])(struct rtnl_cls *,
|
||||
struct nl_dump_params *, int);
|
||||
/**
|
||||
* Must return the contents supposed to be in TCA_OPTIONS
|
||||
*/
|
||||
struct nl_msg *(*co_get_opts)(struct rtnl_cls *);
|
||||
|
||||
/**
|
||||
* TCA_OPTIONS message parser
|
||||
*/
|
||||
int (*co_msg_parser)(struct rtnl_cls *);
|
||||
|
||||
/**
|
||||
* Called before a class object gets destroyed
|
||||
*/
|
||||
void (*co_free_data)(struct rtnl_cls *);
|
||||
|
||||
/**
|
||||
* Called whenever a classifier object needs to be cloned
|
||||
*/
|
||||
int (*co_clone)(struct rtnl_cls *, struct rtnl_cls *);
|
||||
|
||||
/**
|
||||
* INTERNAL (Do not use)
|
||||
*/
|
||||
struct rtnl_cls_ops *co_next;
|
||||
};
|
||||
|
||||
extern int rtnl_cls_register(struct rtnl_cls_ops *);
|
||||
extern int rtnl_cls_unregister(struct rtnl_cls_ops *);
|
||||
extern struct rtnl_cls_ops * rtnl_cls_lookup_ops(struct rtnl_cls *);
|
||||
extern struct rtnl_cls_ops * __rtnl_cls_lookup_ops(const char *kind);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
56
include/netlink/route/classifier.h
Normal file
56
include/netlink/route/classifier.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* netlink/route/classifier.h Classifiers
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CLASSIFIER_H_
|
||||
#define NETLINK_CLASSIFIER_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/route/tc.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct nl_object_ops cls_obj_ops;
|
||||
|
||||
extern struct rtnl_cls *rtnl_cls_alloc(void);
|
||||
extern void rtnl_cls_put(struct rtnl_cls *);
|
||||
|
||||
extern struct nl_cache *rtnl_cls_alloc_cache(struct nl_handle *, int, uint32_t);
|
||||
|
||||
/* classifier addition */
|
||||
extern int rtnl_cls_add(struct nl_handle *, struct rtnl_cls *,
|
||||
int);
|
||||
extern struct nl_msg * rtnl_cls_build_add_request(struct rtnl_cls *, int);
|
||||
|
||||
extern struct nl_msg *rtnl_cls_build_change_request(struct rtnl_cls *, int);
|
||||
extern struct nl_msg *rtnl_cls_build_delete_request(struct rtnl_cls *, int);
|
||||
extern int rtnl_cls_delete(struct nl_handle *, struct rtnl_cls *, int);
|
||||
|
||||
/* attribute modification */
|
||||
extern void rtnl_cls_set_ifindex(struct rtnl_cls *, int);
|
||||
extern void rtnl_cls_set_handle(struct rtnl_cls *, uint32_t);
|
||||
extern void rtnl_cls_set_parent(struct rtnl_cls *, uint32_t);
|
||||
extern void rtnl_cls_set_kind(struct rtnl_cls *, const char *);
|
||||
|
||||
extern void rtnl_cls_set_prio(struct rtnl_cls *, int);
|
||||
extern int rtnl_cls_get_prio(struct rtnl_cls *);
|
||||
|
||||
extern void rtnl_cls_set_protocol(struct rtnl_cls *, int);
|
||||
extern int rtnl_cls_get_protocol(struct rtnl_cls *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
29
include/netlink/route/cls/fw.h
Normal file
29
include/netlink/route/cls/fw.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* netlink/route/cls/fw.h fw classifier
|
||||
*
|
||||
* 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) 2006 Petr Gotthard <petr.gotthard@siemens.com>
|
||||
* Copyright (c) 2006 Siemens AG Oesterreich
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_FW_H_
|
||||
#define NETLINK_FW_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_fw_set_classid(struct rtnl_cls *, uint32_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
29
include/netlink/route/cls/police.h
Normal file
29
include/netlink/route/cls/police.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* netlink/route/cls/police.h Policer
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CLS_POLICE_H_
|
||||
#define NETLINK_CLS_POLICE_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char * nl_police2str(int, char *, size_t);
|
||||
extern int nl_str2police(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
43
include/netlink/route/cls/u32.h
Normal file
43
include/netlink/route/cls/u32.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* netlink/route/cls/u32.h u32 classifier
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_U32_H_
|
||||
#define NETLINK_U32_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void rtnl_u32_set_handle(struct rtnl_cls *, int, int, int);
|
||||
extern int rtnl_u32_set_classid(struct rtnl_cls *, uint32_t);
|
||||
|
||||
extern int rtnl_u32_set_flags(struct rtnl_cls *, int);
|
||||
extern int rtnl_u32_add_key(struct rtnl_cls *, uint32_t, uint32_t,
|
||||
int, int);
|
||||
extern int rtnl_u32_add_key_uint8(struct rtnl_cls *, uint8_t, uint8_t,
|
||||
int, int);
|
||||
extern int rtnl_u32_add_key_uint16(struct rtnl_cls *, uint16_t, uint16_t,
|
||||
int, int);
|
||||
extern int rtnl_u32_add_key_uint32(struct rtnl_cls *, uint32_t, uint32_t,
|
||||
int, int);
|
||||
extern int rtnl_u32_add_key_in_addr(struct rtnl_cls *, struct in_addr *,
|
||||
uint8_t, int, int);
|
||||
extern int rtnl_u32_add_key_in6_addr(struct rtnl_cls *, struct in6_addr *,
|
||||
uint8_t, int, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
151
include/netlink/route/link.h
Normal file
151
include/netlink/route/link.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* netlink/route/link.h Links (Interfaces)
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_LINK_H_
|
||||
#define NETLINK_LINK_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_link;
|
||||
|
||||
enum rtnl_link_st {
|
||||
RTNL_LINK_RX_PACKETS,
|
||||
RTNL_LINK_TX_PACKETS,
|
||||
RTNL_LINK_RX_BYTES,
|
||||
RTNL_LINK_TX_BYTES,
|
||||
RTNL_LINK_RX_ERRORS,
|
||||
RTNL_LINK_TX_ERRORS,
|
||||
RTNL_LINK_RX_DROPPED,
|
||||
RTNL_LINK_TX_DROPPED,
|
||||
RTNL_LINK_RX_COMPRESSED,
|
||||
RTNL_LINK_TX_COMPRESSED,
|
||||
RTNL_LINK_RX_FIFO_ERR,
|
||||
RTNL_LINK_TX_FIFO_ERR,
|
||||
RTNL_LINK_RX_LEN_ERR,
|
||||
RTNL_LINK_RX_OVER_ERR,
|
||||
RTNL_LINK_RX_CRC_ERR,
|
||||
RTNL_LINK_RX_FRAME_ERR,
|
||||
RTNL_LINK_RX_MISSED_ERR,
|
||||
RTNL_LINK_TX_ABORT_ERR,
|
||||
RTNL_LINK_TX_CARRIER_ERR,
|
||||
RTNL_LINK_TX_HBEAT_ERR,
|
||||
RTNL_LINK_TX_WIN_ERR,
|
||||
RTNL_LINK_TX_COLLISIONS,
|
||||
RTNL_LINK_MULTICAST,
|
||||
__RTNL_LINK_STATS_MAX,
|
||||
};
|
||||
|
||||
#define RTNL_LINK_STATS_MAX (__RTNL_LINK_STATS_MAX - 1)
|
||||
|
||||
/**
|
||||
* Special interface index stating the link was not found.
|
||||
* @ingroup link
|
||||
*/
|
||||
#define RTNL_LINK_NOT_FOUND -1
|
||||
|
||||
/* link object allocation/freeage */
|
||||
extern struct rtnl_link * rtnl_link_alloc(void);
|
||||
extern void rtnl_link_put(struct rtnl_link *);
|
||||
extern void rtnl_link_free(struct rtnl_link *);
|
||||
|
||||
/* link cache management */
|
||||
extern struct nl_cache * rtnl_link_alloc_cache(struct nl_handle *);
|
||||
extern struct rtnl_link * rtnl_link_get(struct nl_cache *, int);
|
||||
extern struct rtnl_link * rtnl_link_get_by_name(struct nl_cache *,
|
||||
const char *);
|
||||
|
||||
|
||||
/* Link Modifications */
|
||||
extern struct nl_msg * rtnl_link_build_change_request(struct rtnl_link *,
|
||||
struct rtnl_link *,
|
||||
int);
|
||||
extern int rtnl_link_change(struct nl_handle *,
|
||||
struct rtnl_link *,
|
||||
struct rtnl_link *, int);
|
||||
|
||||
/* Name <-> Index Translations */
|
||||
extern char * rtnl_link_i2name(struct nl_cache *, int,
|
||||
char *, size_t);
|
||||
extern int rtnl_link_name2i(struct nl_cache *,
|
||||
const char *);
|
||||
|
||||
/* Name <-> Statistic Translations */
|
||||
extern char * rtnl_link_stat2str(int, char *, size_t);
|
||||
extern int rtnl_link_str2stat(const char *);
|
||||
|
||||
/* Link Flags Translations */
|
||||
extern char * rtnl_link_flags2str(int, char *, size_t);
|
||||
extern int rtnl_link_str2flags(const char *);
|
||||
|
||||
/* Access Functions */
|
||||
extern void rtnl_link_set_qdisc(struct rtnl_link *,
|
||||
const char *);
|
||||
extern char * rtnl_link_get_qdisc(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_name(struct rtnl_link *,
|
||||
const char *);
|
||||
extern char * rtnl_link_get_name(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_flags(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern void rtnl_link_unset_flags(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_link_get_flags(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_mtu(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_link_get_mtu(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_txqlen(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_link_get_txqlen(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_weight(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_link_get_weight(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_ifindex(struct rtnl_link *, int);
|
||||
extern int rtnl_link_get_ifindex(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_family(struct rtnl_link *, int);
|
||||
extern int rtnl_link_get_family(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_arptype(struct rtnl_link *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_link_get_arptype(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_addr(struct rtnl_link *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_link_get_addr(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_broadcast(struct rtnl_link *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_link_get_broadcast(struct rtnl_link *);
|
||||
|
||||
extern void rtnl_link_set_link(struct rtnl_link *, int);
|
||||
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 uint64_t rtnl_link_get_stat(struct rtnl_link *, int);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
91
include/netlink/route/neighbour.h
Normal file
91
include/netlink/route/neighbour.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* netlink/route/neighbour.h Neighbours
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_NEIGHBOUR_H_
|
||||
#define NETLINK_NEIGHBOUR_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_neigh;
|
||||
|
||||
/* neighbour object allocation/freeage */
|
||||
extern struct rtnl_neigh * rtnl_neigh_alloc(void);
|
||||
extern void rtnl_neigh_put(struct rtnl_neigh *);
|
||||
|
||||
/* neighbour cache management */
|
||||
extern struct nl_cache * rtnl_neigh_alloc_cache(struct nl_handle *);
|
||||
extern struct rtnl_neigh * rtnl_neigh_get(struct nl_cache *, int,
|
||||
struct nl_addr *);
|
||||
|
||||
/* Neigbour state translations */
|
||||
extern char * rtnl_neigh_state2str(int, char *, size_t);
|
||||
extern int rtnl_neigh_str2state(const char *);
|
||||
|
||||
/* Neighbour flags translations */
|
||||
extern char * rtnl_neigh_flags2str(int, char *, size_t);
|
||||
extern int rtnl_neigh_str2flag(const char *);
|
||||
|
||||
/* Neighbour Addition */
|
||||
extern int rtnl_neigh_add(struct nl_handle *,
|
||||
struct rtnl_neigh *, int);
|
||||
extern struct nl_msg * rtnl_neigh_build_add_request(struct rtnl_neigh *, int);
|
||||
|
||||
/* Neighbour Modification */
|
||||
extern int rtnl_neigh_change(struct nl_handle *,
|
||||
struct rtnl_neigh *, int);
|
||||
extern struct nl_msg * rtnl_neigh_build_change_request(struct rtnl_neigh *, int);
|
||||
|
||||
/* Neighbour Deletion */
|
||||
extern int rtnl_neigh_delete(struct nl_handle *,
|
||||
struct rtnl_neigh *, int);
|
||||
extern struct nl_msg * rtnl_neigh_build_delete_request(struct rtnl_neigh *, int);
|
||||
|
||||
/* Access functions */
|
||||
extern void rtnl_neigh_set_state(struct rtnl_neigh *, int);
|
||||
extern int rtnl_neigh_get_state(struct rtnl_neigh *);
|
||||
extern void rtnl_neigh_unset_state(struct rtnl_neigh *,
|
||||
int);
|
||||
|
||||
extern void rtnl_neigh_set_flags(struct rtnl_neigh *,
|
||||
unsigned int);
|
||||
extern void rtnl_neigh_unset_flags(struct rtnl_neigh *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_neigh_get_flags(struct rtnl_neigh *);
|
||||
|
||||
extern void rtnl_neigh_set_ifindex(struct rtnl_neigh *,
|
||||
int);
|
||||
extern int rtnl_neigh_get_ifindex(struct rtnl_neigh *);
|
||||
|
||||
extern void rtnl_neigh_set_lladdr(struct rtnl_neigh *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_neigh_get_lladdr(struct rtnl_neigh *);
|
||||
|
||||
extern int rtnl_neigh_set_dst(struct rtnl_neigh *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_neigh_get_dst(struct rtnl_neigh *);
|
||||
|
||||
extern void rtnl_neigh_set_type(struct rtnl_neigh *, int);
|
||||
extern int rtnl_neigh_get_type(struct rtnl_neigh *);
|
||||
|
||||
extern void rtnl_neigh_set_family(struct rtnl_neigh *, int);
|
||||
extern int rtnl_neigh_get_family(struct rtnl_neigh *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
64
include/netlink/route/neightbl.h
Normal file
64
include/netlink/route/neightbl.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* netlink/route/neightbl.h Neighbour Tables
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_NEIGHTBL_H_
|
||||
#define NETLINK_NEIGHTBL_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_neightbl;
|
||||
|
||||
extern struct rtnl_neightbl *rtnl_neightbl_alloc(void);
|
||||
extern void rtnl_neightbl_put(struct rtnl_neightbl *);
|
||||
extern void rtnl_neightbl_free(struct rtnl_neightbl *);
|
||||
extern struct nl_cache *rtnl_neightbl_alloc_cache(struct nl_handle *);
|
||||
extern struct rtnl_neightbl *rtnl_neightbl_get(struct nl_cache *,
|
||||
const char *, int);
|
||||
extern void rtnl_neightbl_dump(struct rtnl_neightbl *, FILE *,
|
||||
struct nl_dump_params *);
|
||||
|
||||
extern struct nl_msg *rtnl_neightbl_build_change_request(struct rtnl_neightbl *,
|
||||
struct rtnl_neightbl *);
|
||||
extern int rtnl_neightbl_change(struct nl_handle *, struct rtnl_neightbl *,
|
||||
struct rtnl_neightbl *);
|
||||
|
||||
extern void rtnl_neightbl_set_family(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_gc_tresh1(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_gc_tresh2(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_gc_tresh3(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_name(struct rtnl_neightbl *, const char *);
|
||||
extern void rtnl_neightbl_set_dev(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_queue_len(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_proxy_queue_len(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_app_probes(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_ucast_probes(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_mcast_probes(struct rtnl_neightbl *, int);
|
||||
extern void rtnl_neightbl_set_base_reachable_time(struct rtnl_neightbl *,
|
||||
uint64_t);
|
||||
extern void rtnl_neightbl_set_retrans_time(struct rtnl_neightbl *, uint64_t);
|
||||
extern void rtnl_neightbl_set_gc_stale_time(struct rtnl_neightbl *, uint64_t);
|
||||
extern void rtnl_neightbl_set_delay_probe_time(struct rtnl_neightbl *,
|
||||
uint64_t);
|
||||
extern void rtnl_neightbl_set_anycast_delay(struct rtnl_neightbl *, uint64_t);
|
||||
extern void rtnl_neightbl_set_proxy_delay(struct rtnl_neightbl *, uint64_t);
|
||||
extern void rtnl_neightbl_set_locktime(struct rtnl_neightbl *, uint64_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
41
include/netlink/route/nexthop.h
Normal file
41
include/netlink/route/nexthop.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* netlink/route/nexthop.h Routing Nexthop
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_ROUTE_NEXTHOP_H_
|
||||
#define NETLINK_ROUTE_NEXTHOP_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/addr.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_nexthop;
|
||||
|
||||
extern struct rtnl_nexthop * rtnl_route_nh_alloc(void);
|
||||
extern struct rtnl_nexthop * rtnl_route_nh_clone(struct rtnl_nexthop *);
|
||||
extern void rtnl_route_nh_free(struct rtnl_nexthop *);
|
||||
extern void rtnl_route_nh_set_weight(struct rtnl_nexthop *, int);
|
||||
extern void rtnl_route_nh_set_ifindex(struct rtnl_nexthop *, int);
|
||||
extern void rtnl_route_nh_set_gateway(struct rtnl_nexthop *,
|
||||
struct nl_addr *);
|
||||
extern void rtnl_route_nh_set_flags(struct rtnl_nexthop *,
|
||||
unsigned int);
|
||||
extern void rtnl_route_nh_unset_flags(struct rtnl_nexthop *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_route_nh_get_flags(struct rtnl_nexthop *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
73
include/netlink/route/qdisc-modules.h
Normal file
73
include/netlink/route/qdisc-modules.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* netlink/route/qdisc-modules.h Qdisc Module 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-2006 Thomas Graf <tgraf@suug.ch>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_QDISC_MODULES_H_
|
||||
#define NETLINK_QDISC_MODULES_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Qdisc Operations
|
||||
* @ingroup qdisc
|
||||
*/
|
||||
struct rtnl_qdisc_ops
|
||||
{
|
||||
/**
|
||||
* Kind/Name of Qdisc
|
||||
*/
|
||||
char qo_kind[32];
|
||||
|
||||
/**
|
||||
* Dump callbacks
|
||||
*/
|
||||
int (*qo_dump[NL_DUMP_MAX+1])(struct rtnl_qdisc *,
|
||||
struct nl_dump_params *, int);
|
||||
|
||||
/**
|
||||
* Must return the contents supposed to be in TCA_OPTIONS
|
||||
*/
|
||||
struct nl_msg *(*qo_get_opts)(struct rtnl_qdisc *);
|
||||
|
||||
/**
|
||||
* TCA_OPTIONS message parser
|
||||
*/
|
||||
int (*qo_msg_parser)(struct rtnl_qdisc *);
|
||||
|
||||
/**
|
||||
* Called before a Qdisc object gets destroyed
|
||||
*/
|
||||
void (*qo_free_data)(struct rtnl_qdisc *);
|
||||
|
||||
/**
|
||||
* Called whenever a qdisc object needs to be cloned
|
||||
*/
|
||||
int (*qo_clone)(struct rtnl_qdisc *, struct rtnl_qdisc *);
|
||||
|
||||
/**
|
||||
* INTERNAL (Do not use)
|
||||
*/
|
||||
struct rtnl_qdisc_ops *qo_next;
|
||||
};
|
||||
|
||||
extern int rtnl_qdisc_register(struct rtnl_qdisc_ops *);
|
||||
extern int rtnl_qdisc_unregister(struct rtnl_qdisc_ops *);
|
||||
extern struct rtnl_qdisc_ops * rtnl_qdisc_lookup_ops(struct rtnl_qdisc *);
|
||||
extern struct rtnl_qdisc_ops * __rtnl_qdisc_lookup_ops(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
87
include/netlink/route/qdisc.h
Normal file
87
include/netlink/route/qdisc.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* netlink/route/qdisc.h Queueing Disciplines
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_QDISC_H_
|
||||
#define NETLINK_QDISC_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/route/tc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_qdisc;
|
||||
|
||||
extern struct nl_object_ops qdisc_obj_ops;
|
||||
|
||||
/* General */
|
||||
extern struct rtnl_qdisc * rtnl_qdisc_alloc(void);
|
||||
extern void rtnl_qdisc_put(struct rtnl_qdisc *);
|
||||
|
||||
/* Cache Management */
|
||||
extern struct nl_cache * rtnl_qdisc_alloc_cache(struct nl_handle *);
|
||||
extern struct rtnl_qdisc * rtnl_qdisc_get(struct nl_cache *,
|
||||
int, uint32_t);
|
||||
extern struct rtnl_qdisc * rtnl_qdisc_get_by_parent(struct nl_cache *,
|
||||
int, uint32_t);
|
||||
|
||||
/* qdisc addition */
|
||||
extern struct nl_msg * rtnl_qdisc_build_add_request(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_add(struct nl_handle *, struct rtnl_qdisc *,
|
||||
int);
|
||||
|
||||
/* qdisc modification */
|
||||
extern struct nl_msg * rtnl_qdisc_build_change_request(struct rtnl_qdisc *,
|
||||
struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_change(struct nl_handle *,
|
||||
struct rtnl_qdisc *,
|
||||
struct rtnl_qdisc *);
|
||||
|
||||
/* qdisc deletion */
|
||||
extern struct nl_msg * rtnl_qdisc_build_delete_request(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_delete(struct nl_handle *,
|
||||
struct rtnl_qdisc *);
|
||||
|
||||
/* attribute modifications */
|
||||
extern void rtnl_qdisc_set_ifindex(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_get_ifindex(struct rtnl_qdisc *);
|
||||
extern void rtnl_qdisc_set_handle(struct rtnl_qdisc *, uint32_t);
|
||||
extern uint32_t rtnl_qdisc_get_handle(struct rtnl_qdisc *);
|
||||
extern void rtnl_qdisc_set_parent(struct rtnl_qdisc *, uint32_t);
|
||||
extern uint32_t rtnl_qdisc_get_parent(struct rtnl_qdisc *);
|
||||
extern void rtnl_qdisc_set_kind(struct rtnl_qdisc *, const char *);
|
||||
extern char * rtnl_qdisc_get_kind(struct rtnl_qdisc *);
|
||||
extern uint64_t rtnl_qdisc_get_stat(struct rtnl_qdisc *,
|
||||
enum rtnl_tc_stats_id);
|
||||
|
||||
/* iterators */
|
||||
extern void rtnl_qdisc_foreach_child(struct rtnl_qdisc *,
|
||||
struct nl_cache *,
|
||||
void (*cb)(struct nl_object *,
|
||||
void *),
|
||||
void *);
|
||||
|
||||
extern void rtnl_qdisc_foreach_cls(struct rtnl_qdisc *,
|
||||
struct nl_cache *,
|
||||
void (*cb)(struct nl_object *,
|
||||
void *),
|
||||
void *);
|
||||
|
||||
/* qdisc specific options */
|
||||
extern struct nl_msg * rtnl_qdisc_get_opts(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
125
include/netlink/route/route.h
Normal file
125
include/netlink/route/route.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* netlink/route/route.h Routes
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_ROUTE_H_
|
||||
#define NETLINK_ROUTE_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/data.h>
|
||||
#include <netlink/route/nexthop.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_route;
|
||||
|
||||
struct rtnl_rtcacheinfo
|
||||
{
|
||||
uint32_t rtci_clntref;
|
||||
uint32_t rtci_last_use;
|
||||
uint32_t rtci_expires;
|
||||
int32_t rtci_error;
|
||||
uint32_t rtci_used;
|
||||
uint32_t rtci_id;
|
||||
uint32_t rtci_ts;
|
||||
uint32_t rtci_tsage;
|
||||
};
|
||||
|
||||
extern struct nl_object_ops route_obj_ops;
|
||||
|
||||
/* General */
|
||||
extern struct rtnl_route * rtnl_route_alloc(void);
|
||||
extern void rtnl_route_put(struct rtnl_route *);
|
||||
extern struct nl_cache * rtnl_route_alloc_cache(struct nl_handle *);
|
||||
|
||||
extern void rtnl_route_get(struct rtnl_route *);
|
||||
extern void rtnl_route_put(struct rtnl_route *);
|
||||
|
||||
extern struct nl_msg *rtnl_route_build_add_request(struct rtnl_route *, int);
|
||||
extern int rtnl_route_add(struct nl_handle *, struct rtnl_route *, int);
|
||||
extern struct nl_msg *rtnl_route_build_del_request(struct rtnl_route *, int);
|
||||
extern int rtnl_route_del(struct nl_handle *, struct rtnl_route *, int);
|
||||
|
||||
extern void rtnl_route_set_table(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_table(struct rtnl_route *);
|
||||
extern void rtnl_route_set_scope(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_scope(struct rtnl_route *);
|
||||
extern void rtnl_route_set_tos(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_tos(struct rtnl_route *);
|
||||
extern void rtnl_route_set_realms(struct rtnl_route *, realm_t);
|
||||
extern realm_t rtnl_route_get_realms(struct rtnl_route *);
|
||||
extern void rtnl_route_set_protocol(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_protocol(struct rtnl_route *);
|
||||
extern void rtnl_route_set_prio(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_prio(struct rtnl_route *);
|
||||
extern void rtnl_route_set_family(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_family(struct rtnl_route *);
|
||||
extern void rtnl_route_set_type(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_type(struct rtnl_route *);
|
||||
extern void rtnl_route_set_flags(struct rtnl_route *,
|
||||
unsigned int);
|
||||
extern void rtnl_route_unset_flags(struct rtnl_route *,
|
||||
unsigned int);
|
||||
extern unsigned int rtnl_route_get_flags(struct rtnl_route *);
|
||||
extern int rtnl_route_set_metric(struct rtnl_route *, int,
|
||||
unsigned int);
|
||||
extern int rtnl_route_unset_metric(struct rtnl_route *, int);
|
||||
extern unsigned int rtnl_route_get_metric(struct rtnl_route *, int);
|
||||
extern int rtnl_route_set_dst(struct rtnl_route *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_route_get_dst(struct rtnl_route *);
|
||||
extern int rtnl_route_set_src(struct rtnl_route *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_route_get_src(struct rtnl_route *);
|
||||
extern int rtnl_route_set_gateway(struct rtnl_route *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_route_get_gateway(struct rtnl_route *);
|
||||
extern int rtnl_route_set_pref_src(struct rtnl_route *,
|
||||
struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_route_get_pref_src(struct rtnl_route *);
|
||||
extern void rtnl_route_set_oif(struct rtnl_route *, int);
|
||||
extern int rtnl_route_get_oif(struct rtnl_route *);
|
||||
extern void rtnl_route_set_iif(struct rtnl_route *, const char *);
|
||||
extern char * rtnl_route_get_iif(struct rtnl_route *);
|
||||
extern int rtnl_route_get_dst_len(struct rtnl_route *);
|
||||
extern int rtnl_route_get_src_len(struct rtnl_route *);
|
||||
|
||||
extern void rtnl_route_add_nexthop(struct rtnl_route *,
|
||||
struct rtnl_nexthop *);
|
||||
extern void rtnl_route_remove_nexthop(struct rtnl_nexthop *);
|
||||
extern struct nl_list_head * rtnl_route_get_nexthops(struct rtnl_route *);
|
||||
extern void rtnl_route_set_cacheinfo(struct rtnl_route *,
|
||||
struct rtnl_rtcacheinfo *);
|
||||
extern uint32_t rtnl_route_get_mp_algo(struct rtnl_route *);
|
||||
extern void rtnl_route_set_mp_algo(struct rtnl_route *, uint32_t);
|
||||
|
||||
extern char * rtnl_route_table2str(int, char *, size_t);
|
||||
extern int rtnl_route_str2table(const char *);
|
||||
extern int rtnl_route_read_table_names(const char *);
|
||||
|
||||
extern char * rtnl_route_proto2str(int, char *, size_t);
|
||||
extern int rtnl_route_str2proto(const char *);
|
||||
extern int rtnl_route_read_protocol_names(const char *);
|
||||
|
||||
extern char * rtnl_route_metric2str(int, char *, size_t);
|
||||
extern int rtnl_route_str2metric(const char *);
|
||||
|
||||
extern char * rtnl_route_nh_flags2str(int, char *, size_t);
|
||||
extern int rtnl_route_nh_str2flags(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
71
include/netlink/route/rtnl.h
Normal file
71
include/netlink/route/rtnl.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* netlink/route/rtnl.h Routing Netlink
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_RTNL_H_
|
||||
#define NETLINK_RTNL_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Realms
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef uint32_t realm_t;
|
||||
|
||||
/**
|
||||
* Mask specying the size of each realm part
|
||||
* @ingroup rtnl
|
||||
*/
|
||||
#define RTNL_REALM_MASK (0xFFFF)
|
||||
|
||||
/**
|
||||
* Extract FROM realm from a realms field
|
||||
*/
|
||||
#define RTNL_REALM_FROM(realm) ((realm) >> 16)
|
||||
|
||||
/**
|
||||
* Extract TO realm from a realms field
|
||||
*/
|
||||
#define RTNL_REALM_TO(realm) ((realm) & RTNL_REALM_MASK)
|
||||
|
||||
/**
|
||||
* Build a realms field
|
||||
*/
|
||||
#define RTNL_MAKE_REALM(from, to) \
|
||||
((RTNL_REALM_TO(from) << 16) & RTNL_REALM_TO(to))
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/* General */
|
||||
extern int nl_rtgen_request(struct nl_handle *, int, int, int);
|
||||
|
||||
/* Routing Type Translations */
|
||||
extern char * nl_rtntype2str(int, char *, size_t);
|
||||
extern int nl_str2rtntype(const char *);
|
||||
|
||||
/* Scope Translations */
|
||||
extern char * rtnl_scope2str(int, char *, size_t);
|
||||
extern int rtnl_str2scope(const char *);
|
||||
|
||||
/* Realms Translations */
|
||||
extern char * rtnl_realms2str(uint32_t, char *, size_t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
79
include/netlink/route/rule.h
Normal file
79
include/netlink/route/rule.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* netlink/route/rule.h Rules
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_RULE_H_
|
||||
#define NETLINK_RULE_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct rtnl_rule;
|
||||
|
||||
/* General */
|
||||
extern struct rtnl_rule * rtnl_rule_alloc(void);
|
||||
extern void rtnl_rule_put(struct rtnl_rule *);
|
||||
|
||||
extern struct nl_cache * rtnl_rule_alloc_cache(struct nl_handle *);
|
||||
extern struct nl_cache * rtnl_rule_alloc_cache_by_family(struct nl_handle *,
|
||||
int);
|
||||
extern void rtnl_rule_dump(struct rtnl_rule *, FILE *, struct nl_dump_params *);
|
||||
|
||||
extern struct nl_msg * rtnl_rule_build_add_request(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_add(struct nl_handle *, struct rtnl_rule *, int);
|
||||
extern struct nl_msg * rtnl_rule_build_delete_request(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_delete(struct nl_handle *, struct rtnl_rule *, int);
|
||||
|
||||
|
||||
/* attribute modification */
|
||||
extern void rtnl_rule_set_family(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_family(struct rtnl_rule *);
|
||||
extern void rtnl_rule_set_prio(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_prio(struct rtnl_rule *);
|
||||
#define rtnl_rule_set_fwmark(ptr, n) rtnl_rule_set_mark(ptr, n)
|
||||
extern void rtnl_rule_set_mark(struct rtnl_rule *, uint64_t);
|
||||
#define rtnl_rule_get_fwmark(ptr) rtnl_rule_get_mark(ptr)
|
||||
extern uint64_t rtnl_rule_get_mark(struct rtnl_rule *);
|
||||
extern void rtnl_rule_set_table(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_table(struct rtnl_rule *);
|
||||
extern void rtnl_rule_set_dsfield(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_dsfield(struct rtnl_rule *);
|
||||
extern int rtnl_rule_set_src(struct rtnl_rule *, struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_rule_get_src(struct rtnl_rule *);
|
||||
extern int rtnl_rule_set_dst(struct rtnl_rule *, struct nl_addr *);
|
||||
extern struct nl_addr * rtnl_rule_get_dst(struct rtnl_rule *);
|
||||
extern void rtnl_rule_set_src_len(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_src_len(struct rtnl_rule *);
|
||||
extern void rtnl_rule_set_dst_len(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_dst_len(struct rtnl_rule *);
|
||||
|
||||
extern void rtnl_rule_set_action(struct rtnl_rule *, int);
|
||||
extern int rtnl_rule_get_action(struct rtnl_rule *);
|
||||
|
||||
extern int rtnl_rule_set_iif(struct rtnl_rule *, const char *);
|
||||
extern char * rtnl_rule_get_iif(struct rtnl_rule *);
|
||||
|
||||
extern void rtnl_rule_set_classid(struct rtnl_rule *, uint32_t);
|
||||
extern uint32_t rtnl_rule_get_classid(struct rtnl_rule *);
|
||||
|
||||
extern void rtnl_rule_set_realms(struct rtnl_rule *, realm_t);
|
||||
extern realm_t rtnl_rule_get_realms(struct rtnl_rule *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
30
include/netlink/route/sch/cbq.h
Normal file
30
include/netlink/route/sch/cbq.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* netlink/route/sch/cbq.h Class Based Queueing
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_CBQ_H_
|
||||
#define NETLINK_CBQ_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/route/qdisc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char * nl_ovl_strategy2str(int, char *, size_t);
|
||||
extern int nl_str2ovl_strategy(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
41
include/netlink/route/sch/dsmark.h
Normal file
41
include/netlink/route/sch/dsmark.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* netlink/route/sch/dsmark.h DSMARK
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_DSMARK_H_
|
||||
#define NETLINK_DSMARK_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_class_dsmark_set_bmask(struct rtnl_class *, uint8_t);
|
||||
extern int rtnl_class_dsmark_get_bmask(struct rtnl_class *);
|
||||
|
||||
extern int rtnl_class_dsmark_set_value(struct rtnl_class *, uint8_t);
|
||||
extern int rtnl_class_dsmark_get_value(struct rtnl_class *);
|
||||
|
||||
extern int rtnl_qdisc_dsmark_set_indices(struct rtnl_qdisc *, uint16_t);
|
||||
extern int rtnl_qdisc_dsmark_get_indices(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_qdisc_dsmark_set_default_index(struct rtnl_qdisc *,
|
||||
uint16_t);
|
||||
extern int rtnl_qdisc_dsmark_get_default_index(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_qdisc_dsmark_set_set_tc_index(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_dsmark_get_set_tc_index(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
28
include/netlink/route/sch/fifo.h
Normal file
28
include/netlink/route/sch/fifo.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* netlink/route/sch/fifo.c FIFO Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_FIFO_H_
|
||||
#define NETLINK_FIFO_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_qdisc_fifo_set_limit(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_fifo_get_limit(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
41
include/netlink/route/sch/htb.h
Normal file
41
include/netlink/route/sch/htb.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* netlink/route/sch/htb.h HTB Qdisc
|
||||
*
|
||||
* 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) 2005 Petr Gotthard <petr.gotthard@siemens.com>
|
||||
* Copyright (c) 2005 Siemens AG Oesterreich
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_HTB_H_
|
||||
#define NETLINK_HTB_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/tc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void rtnl_htb_set_rate2quantum(struct rtnl_qdisc *, uint32_t);
|
||||
extern void rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t);
|
||||
|
||||
extern void rtnl_htb_set_prio(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_mtu(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_rate(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_ceil(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t);
|
||||
extern void rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum);
|
||||
extern void rtnl_htb_set_overhead(struct rtnl_class *class, uint8_t overhead);
|
||||
extern void rtnl_htb_set_mpu(struct rtnl_class *class, uint8_t mpu);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
62
include/netlink/route/sch/netem.h
Normal file
62
include/netlink/route/sch/netem.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* netlink/route/sch/netem.h Network Emulator Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_NETEM_H_
|
||||
#define NETLINK_NETEM_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_netem_set_limit(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_limit(struct rtnl_qdisc *);
|
||||
|
||||
/* Packet Re-ordering */
|
||||
extern int rtnl_netem_set_gap(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_gap(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_reorder_probability(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_reorder_probability(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_reorder_correlation(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_reorder_correlation(struct rtnl_qdisc *);
|
||||
|
||||
/* Packet Loss */
|
||||
extern int rtnl_netem_set_loss(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_loss(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_loss_correlation(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_loss_correlation(struct rtnl_qdisc *);
|
||||
|
||||
/* Packet Duplication */
|
||||
extern int rtnl_netem_set_duplicate(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_duplicate(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_duplicate_correlation(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_duplicate_correlation(struct rtnl_qdisc *);
|
||||
|
||||
/* Packet Delay */
|
||||
extern int rtnl_netem_set_delay(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_delay(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_jitter(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_jitter(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_netem_set_delay_correlation(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_netem_get_delay_correlation(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
53
include/netlink/route/sch/prio.h
Normal file
53
include/netlink/route/sch/prio.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* netlink/route/sch/prio.c PRIO Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_PRIO_H_
|
||||
#define NETLINK_PRIO_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Default Values
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default number of bands.
|
||||
* @ingroup prio
|
||||
*/
|
||||
#define QDISC_PRIO_DEFAULT_BANDS 3
|
||||
|
||||
/**
|
||||
* Default priority mapping.
|
||||
* @ingroup prio
|
||||
*/
|
||||
#define QDISC_PRIO_DEFAULT_PRIOMAP \
|
||||
{ 1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }
|
||||
|
||||
/** @} */
|
||||
|
||||
extern int rtnl_qdisc_prio_set_bands(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_prio_get_bands(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_prio_set_priomap(struct rtnl_qdisc *, uint8_t[], int);
|
||||
extern uint8_t *rtnl_qdisc_prio_get_priomap(struct rtnl_qdisc *);
|
||||
|
||||
extern char * rtnl_prio2str(int, char *, size_t);
|
||||
extern int rtnl_str2prio(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
17
include/netlink/route/sch/red.h
Normal file
17
include/netlink/route/sch/red.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* netlink/route/sch/red.h RED Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_RED_H_
|
||||
#define NETLINK_RED_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#endif
|
36
include/netlink/route/sch/sfq.h
Normal file
36
include/netlink/route/sch/sfq.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* netlink/route/sch/sfq.c SFQ Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_SFQ_H_
|
||||
#define NETLINK_SFQ_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_sfq_set_quantum(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_sfq_get_quantum(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_sfq_set_limit(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_sfq_get_limit(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_sfq_set_perturb(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_sfq_get_perturb(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_sfq_get_divisor(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
43
include/netlink/route/sch/tbf.h
Normal file
43
include/netlink/route/sch/tbf.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* netlink/route/sch/tbf.h TBF Qdisc
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_TBF_H_
|
||||
#define NETLINK_TBF_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/tc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_qdisc_tbf_set_limit(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_tbf_set_limit_by_latency(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_tbf_get_limit(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_qdisc_tbf_set_mpu(struct rtnl_qdisc *, int);
|
||||
extern int rtnl_qdisc_tbf_get_mpu(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *, int, int, int);
|
||||
extern int rtnl_qdisc_tbf_get_rate(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_tbf_get_rate_bucket(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_tbf_get_rate_cell(struct rtnl_qdisc *);
|
||||
|
||||
extern int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *, int, int, int);
|
||||
extern int rtnl_qdisc_tbf_get_peakrate(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_tbf_get_peakrate_bucket(struct rtnl_qdisc *);
|
||||
extern int rtnl_qdisc_tbf_get_peakrate_cell(struct rtnl_qdisc *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
63
include/netlink/route/tc.h
Normal file
63
include/netlink/route/tc.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* netlink/route/tc.h Traffic Control
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_TC_H_
|
||||
#define NETLINK_TC_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/data.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* TC statistics identifiers
|
||||
* @ingroup tc
|
||||
*/
|
||||
enum rtnl_tc_stats_id {
|
||||
RTNL_TC_PACKETS, /**< Packets seen */
|
||||
RTNL_TC_BYTES, /**< Bytes seen */
|
||||
RTNL_TC_RATE_BPS, /**< Current bits/s (rate estimator) */
|
||||
RTNL_TC_RATE_PPS, /**< Current packet/s (rate estimator) */
|
||||
RTNL_TC_QLEN, /**< Queue length */
|
||||
RTNL_TC_BACKLOG, /**< Backlog length */
|
||||
RTNL_TC_DROPS, /**< Packets dropped */
|
||||
RTNL_TC_REQUEUES, /**< Number of requeues */
|
||||
RTNL_TC_OVERLIMITS, /**< Number of overlimits */
|
||||
__RTNL_TC_STATS_MAX,
|
||||
};
|
||||
|
||||
#define RTNL_TC_STATS_MAX (__RTNL_TC_STATS_MAX - 1)
|
||||
|
||||
extern int rtnl_tc_calc_txtime(int, int);
|
||||
extern int rtnl_tc_calc_bufsize(int, int);
|
||||
extern int rtnl_tc_calc_cell_log(int);
|
||||
|
||||
/**
|
||||
* Number of entries in a transmission time lookup table
|
||||
* @ingroup tc
|
||||
*/
|
||||
#define RTNL_TC_RTABLE_SIZE 256
|
||||
|
||||
extern int rtnl_tc_build_rate_table(uint32_t *, uint8_t, uint8_t, int, int);
|
||||
|
||||
|
||||
/* TC Handle Translations */
|
||||
extern char * rtnl_tc_handle2str(uint32_t, char *, size_t);
|
||||
extern int rtnl_tc_str2handle(const char *, uint32_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
66
include/netlink/socket.h
Normal file
66
include/netlink/socket.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* netlink/socket.h Netlink Socket
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_SOCKET_H_
|
||||
#define NETLINK_SOCKET_H_
|
||||
|
||||
#include <netlink/types.h>
|
||||
#include <netlink/handlers.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct nl_handle * nl_handle_alloc(void);
|
||||
extern struct nl_handle * nl_handle_alloc_cb(struct nl_cb *);
|
||||
extern void nl_handle_destroy(struct nl_handle *);
|
||||
|
||||
extern uint32_t nl_socket_get_local_port(struct nl_handle *);
|
||||
extern void nl_socket_set_local_port(struct nl_handle *,
|
||||
uint32_t);
|
||||
|
||||
extern int nl_socket_add_membership(struct nl_handle *,
|
||||
int);
|
||||
extern int nl_socket_drop_membership(struct nl_handle *,
|
||||
int);
|
||||
extern void nl_join_groups(struct nl_handle *, int);
|
||||
|
||||
extern uint32_t nl_socket_get_peer_port(struct nl_handle *);
|
||||
extern void nl_socket_set_peer_port(struct nl_handle *,
|
||||
uint32_t);
|
||||
|
||||
extern struct nl_cb * nl_socket_get_cb(struct nl_handle *);
|
||||
extern void nl_socket_set_cb(struct nl_handle *,
|
||||
struct nl_cb *);
|
||||
extern int nl_socket_modify_cb(struct nl_handle *,
|
||||
enum nl_cb_type,
|
||||
enum nl_cb_kind,
|
||||
nl_recvmsg_msg_cb_t,
|
||||
void *);
|
||||
|
||||
extern int nl_set_buffer_size(struct nl_handle *,
|
||||
int, int);
|
||||
extern int nl_set_passcred(struct nl_handle *, int);
|
||||
extern int nl_socket_recv_pktinfo(struct nl_handle *, int);
|
||||
|
||||
extern void nl_disable_sequence_check(struct nl_handle *);
|
||||
extern unsigned int nl_socket_use_seq(struct nl_handle *);
|
||||
|
||||
extern int nl_socket_get_fd(struct nl_handle *);
|
||||
extern int nl_socket_set_nonblocking(struct nl_handle *);
|
||||
extern void nl_socket_enable_msg_peek(struct nl_handle *);
|
||||
extern void nl_socket_disable_msg_peek(struct nl_handle *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
105
include/netlink/types.h
Normal file
105
include/netlink/types.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* netlink/netlink-types.h Netlink Types
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef __NETLINK_TYPES_H_
|
||||
#define __NETLINK_TYPES_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* Dumping types (dp_type)
|
||||
* @ingroup utils
|
||||
*/
|
||||
enum nl_dump_type {
|
||||
NL_DUMP_BRIEF, /**< Dump object in a brief one-liner */
|
||||
NL_DUMP_FULL, /**< Dump all attributes but no statistics */
|
||||
NL_DUMP_STATS, /**< Dump all attributes including statistics */
|
||||
NL_DUMP_XML, /**< Dump all attribtes in XML format */
|
||||
NL_DUMP_ENV, /**< Dump all attribtues as env variables */
|
||||
NL_DUMP_EVENTS, /**< Dump event */
|
||||
__NL_DUMP_MAX,
|
||||
};
|
||||
#define NL_DUMP_MAX (__NL_DUMP_MAX - 1)
|
||||
|
||||
/**
|
||||
* Dumping parameters
|
||||
* @ingroup utils
|
||||
*/
|
||||
struct nl_dump_params
|
||||
{
|
||||
/**
|
||||
* Specifies the type of dump that is requested.
|
||||
*/
|
||||
enum nl_dump_type dp_type;
|
||||
|
||||
/**
|
||||
* Specifies the number of whitespaces to be put in front
|
||||
* of every new line (indentation).
|
||||
*/
|
||||
int dp_prefix;
|
||||
|
||||
/**
|
||||
* Causes the cache index to be printed for each element.
|
||||
*/
|
||||
int dp_print_index;
|
||||
|
||||
/**
|
||||
* Causes each element to be prefixed with the message type.
|
||||
*/
|
||||
int dp_dump_msgtype;
|
||||
|
||||
/**
|
||||
* A callback invoked for output
|
||||
*
|
||||
* Passed arguments are:
|
||||
* - dumping parameters
|
||||
* - string to append to the output
|
||||
*/
|
||||
void (*dp_cb)(struct nl_dump_params *, char *);
|
||||
|
||||
/**
|
||||
* A callback invoked for every new line, can be used to
|
||||
* customize the indentation.
|
||||
*
|
||||
* Passed arguments are:
|
||||
* - dumping parameters
|
||||
* - line number starting from 0
|
||||
*/
|
||||
void (*dp_nl_cb)(struct nl_dump_params *, int);
|
||||
|
||||
/**
|
||||
* User data pointer, can be used to pass data to callbacks.
|
||||
*/
|
||||
void *dp_data;
|
||||
|
||||
/**
|
||||
* File descriptor the dumping output should go to
|
||||
*/
|
||||
FILE * dp_fd;
|
||||
|
||||
/**
|
||||
* Alternatively the output may be redirected into a buffer
|
||||
*/
|
||||
char * dp_buf;
|
||||
|
||||
/**
|
||||
* Length of the buffer dp_buf
|
||||
*/
|
||||
size_t dp_buflen;
|
||||
|
||||
/**
|
||||
* PRIVATE
|
||||
* Set if a dump was performed prior to the actual dump handler.
|
||||
*/
|
||||
int dp_pre_dump;
|
||||
};
|
||||
|
||||
#endif
|
76
include/netlink/utils.h
Normal file
76
include/netlink/utils.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* netlink/utils.h Utility Functions
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_UTILS_H_
|
||||
#define NETLINK_UTILS_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/list.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Probability Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lower probability limit
|
||||
* @ingroup utils
|
||||
*/
|
||||
#define NL_PROB_MIN 0x0
|
||||
|
||||
/**
|
||||
* Upper probability limit
|
||||
* @ingroup utils
|
||||
*/
|
||||
#define NL_PROB_MAX 0xffffffff
|
||||
|
||||
/** @} */
|
||||
|
||||
extern char * nl_geterror(void);
|
||||
extern int nl_get_errno(void);
|
||||
extern void nl_perror(const char *);
|
||||
|
||||
/* unit pretty-printing */
|
||||
extern double nl_cancel_down_bytes(unsigned long long, char **);
|
||||
extern double nl_cancel_down_bits(unsigned long long, char **);
|
||||
extern double nl_cancel_down_us(uint32_t, char **);
|
||||
|
||||
/* generic unit translations */
|
||||
extern long nl_size2int(const char *);
|
||||
extern long nl_prob2int(const char *);
|
||||
|
||||
/* time translations */
|
||||
extern int nl_get_hz(void);
|
||||
extern uint32_t nl_us2ticks(uint32_t);
|
||||
extern uint32_t nl_ticks2us(uint32_t);
|
||||
extern char * nl_msec2str(uint64_t, char *, size_t);
|
||||
|
||||
/* link layer protocol translations */
|
||||
extern char * nl_llproto2str(int, char *, size_t);
|
||||
extern int nl_str2llproto(const char *);
|
||||
|
||||
/* ethernet protocol translations */
|
||||
extern char * nl_ether_proto2str(int, char *, size_t);
|
||||
extern int nl_str2ether_proto(const char *);
|
||||
|
||||
/* IP protocol translations */
|
||||
extern char * nl_ip_proto2str(int, char *, size_t);
|
||||
extern int nl_str2ip_proto(const char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
294
install-sh
Executable file
294
install-sh
Executable file
|
@ -0,0 +1,294 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
#
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch. It can only install one file at a time, a restriction
|
||||
# shared with many OS's install programs.
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
transformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd=$cpprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd=$stripprog
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "$0: no input file specified" >&2
|
||||
exit 1
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d "$dst" ]; then
|
||||
instcmd=:
|
||||
chmodcmd=""
|
||||
else
|
||||
instcmd=$mkdirprog
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f "$src" ] || [ -d "$src" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
echo "$0: $src does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "$0: no destination specified" >&2
|
||||
exit 1
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d "$dst" ]
|
||||
then
|
||||
dst=$dst/`basename "$src"`
|
||||
else
|
||||
:
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-$defaultIFS}"
|
||||
|
||||
oIFS=$IFS
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS=$oIFS
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp=$pathcomp$1
|
||||
shift
|
||||
|
||||
if [ ! -d "$pathcomp" ] ;
|
||||
then
|
||||
$mkdirprog "$pathcomp"
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
pathcomp=$pathcomp/
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd "$dst" &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename "$dst"`
|
||||
else
|
||||
dstfile=`basename "$dst" $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename "$dst"`
|
||||
else
|
||||
:
|
||||
fi
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up temp files at exit.
|
||||
|
||||
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
|
||||
trap '(exit $?); exit' 1 2 13 15
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd "$src" "$dsttmp" &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
|
||||
|
||||
# Now remove or move aside any old file at destination location. We try this
|
||||
# two ways since rm can't unlink itself on some systems and the destination
|
||||
# file might be busy for other reasons. In this case, the final cleanup
|
||||
# might fail but the new file should still install successfully.
|
||||
|
||||
{
|
||||
if [ -f "$dstdir/$dstfile" ]
|
||||
then
|
||||
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
|
||||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
|
||||
{
|
||||
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||
(exit 1); exit
|
||||
}
|
||||
else
|
||||
:
|
||||
fi
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||
|
||||
fi &&
|
||||
|
||||
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||
|
||||
{
|
||||
(exit 0); exit
|
||||
}
|
74
lib/Makefile
Normal file
74
lib/Makefile
Normal file
|
@ -0,0 +1,74 @@
|
|||
#
|
||||
# lib/Makefile
|
||||
#
|
||||
# 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>
|
||||
#
|
||||
|
||||
ifeq ($(shell [ ! -r ../Makefile.opts ] && echo 1),)
|
||||
include ../Makefile.opts
|
||||
endif
|
||||
|
||||
# Core
|
||||
CIN := $(wildcard *.c)
|
||||
# NETLINK_ROUTE
|
||||
CIN += $(wildcard route/*.c)
|
||||
# Schedulers
|
||||
CIN += $(wildcard route/sch/*.c)
|
||||
# Classifiers
|
||||
CIN += $(wildcard route/cls/*.c)
|
||||
# NETLINK_GENERIC
|
||||
CIN += $(wildcard genl/*.c)
|
||||
# fib lookup
|
||||
CIN += $(wildcard fib_lookup/*.c)
|
||||
# Netfilter
|
||||
CIN += $(wildcard netfilter/*.c)
|
||||
|
||||
DEPS := $(CIN:%.c=%.d)
|
||||
OBJ := $(CIN:%.c=%.o)
|
||||
CFLAGS += -fPIC
|
||||
OUT_SLIB := $(PACKAGE_NAME).so.$(PACKAGE_VERSION)
|
||||
LN_SLIB := $(PACKAGE_NAME).so
|
||||
LN1_SLIB := $(LN_SLIB).1
|
||||
|
||||
export
|
||||
|
||||
.PHONY: all clean install librtn.a $(OUT_SLIB)
|
||||
|
||||
|
||||
all:
|
||||
@echo " MAKE $(OUT_SLIB)"; \
|
||||
$(MAKE) $(OUT_SLIB)
|
||||
|
||||
$(OUT_SLIB): ../Makefile.opts $(OBJ)
|
||||
@echo " LD $(OUT_SLIB)"; \
|
||||
$(CC) -shared -Wl,-soname,libnl.so.1 -o $(OUT_SLIB) $(OBJ) $(LIBNL_LIB) -lc
|
||||
@echo " LN $(OUT_SLIB) $(LN1_SLIB)"; \
|
||||
rm -f $(LN1_SLIB) ; $(LN) -s $(OUT_SLIB) $(LN1_SLIB)
|
||||
@echo " LN $(LN1_SLIB) $(LN_SLIB)"; \
|
||||
rm -f $(LN_SLIB) ; $(LN) -s $(LN1_SLIB) $(LN_SLIB)
|
||||
|
||||
clean:
|
||||
@echo " CLEAN lib"; \
|
||||
$(RM) -f $(OBJ) $(OUT_SLIB) $(LN_SLIB) $(LN1_SLIB); \
|
||||
$(RM) -f $(DEPS) $(OUT_SLIB) $(LN_SLIB) $(LN1_SLIB)
|
||||
|
||||
distclean:
|
||||
@echo " DISTCLEAN lib"; \
|
||||
$(RM) -f $(DEPS)
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)$(libdir)/
|
||||
install -m 0644 $(OUT_SLIB) $(DESTDIR)$(libdir)
|
||||
rm -f $(DESTDIR)$(libdir)/$(LN1_SLIB)
|
||||
$(LN) -s $(OUT_SLIB) $(DESTDIR)$(libdir)/$(LN1_SLIB)
|
||||
rm -f $(DESTDIR)$(libdir)/$(LN_SLIB)
|
||||
$(LN) -s $(LN1_SLIB) $(DESTDIR)$(libdir)/$(LN_SLIB)
|
||||
|
||||
$(DEPS): ../Makefile.opts
|
||||
|
||||
include ../Makefile.rules
|
883
lib/addr.c
Normal file
883
lib/addr.c
Normal file
|
@ -0,0 +1,883 @@
|
|||
/*
|
||||
* lib/addr.c Abstract Address
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup utils
|
||||
* @defgroup addr Abstract Address
|
||||
*
|
||||
* @par 1) Transform character string to abstract address
|
||||
* @code
|
||||
* struct nl_addr *a = nl_addr_parse("::1", AF_UNSPEC);
|
||||
* printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
|
||||
* nl_addr_put(a);
|
||||
* a = nl_addr_parse("11:22:33:44:55:66", AF_UNSPEC);
|
||||
* printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
|
||||
* nl_addr_put(a);
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
/* All this DECnet stuff is stolen from iproute2, thanks to whoever wrote
|
||||
* this, probably Alexey. */
|
||||
static inline uint16_t dn_ntohs(uint16_t addr)
|
||||
{
|
||||
union {
|
||||
uint8_t byte[2];
|
||||
uint16_t word;
|
||||
} u = {
|
||||
.word = addr,
|
||||
};
|
||||
|
||||
return ((uint16_t) u.byte[0]) | (((uint16_t) u.byte[1]) << 8);
|
||||
}
|
||||
|
||||
static inline int do_digit(char *str, uint16_t *addr, uint16_t scale,
|
||||
size_t *pos, size_t len, int *started)
|
||||
{
|
||||
uint16_t tmp = *addr / scale;
|
||||
|
||||
if (*pos == len)
|
||||
return 1;
|
||||
|
||||
if (((tmp) > 0) || *started || (scale == 1)) {
|
||||
*str = tmp + '0';
|
||||
*started = 1;
|
||||
(*pos)++;
|
||||
*addr -= (tmp * scale);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *dnet_ntop(char *addrbuf, size_t addrlen, char *str,
|
||||
size_t len)
|
||||
{
|
||||
uint16_t addr = dn_ntohs(*(uint16_t *)addrbuf);
|
||||
uint16_t area = addr >> 10;
|
||||
size_t pos = 0;
|
||||
int started = 0;
|
||||
|
||||
if (addrlen != 2)
|
||||
return NULL;
|
||||
|
||||
addr &= 0x03ff;
|
||||
|
||||
if (len == 0)
|
||||
return str;
|
||||
|
||||
if (do_digit(str + pos, &area, 10, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (do_digit(str + pos, &area, 1, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (pos == len)
|
||||
return str;
|
||||
|
||||
*(str + pos) = '.';
|
||||
pos++;
|
||||
started = 0;
|
||||
|
||||
if (do_digit(str + pos, &addr, 1000, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (do_digit(str + pos, &addr, 100, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (do_digit(str + pos, &addr, 10, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (do_digit(str + pos, &addr, 1, &pos, len, &started))
|
||||
return str;
|
||||
|
||||
if (pos == len)
|
||||
return str;
|
||||
|
||||
*(str + pos) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static int dnet_num(const char *src, uint16_t * dst)
|
||||
{
|
||||
int rv = 0;
|
||||
int tmp;
|
||||
*dst = 0;
|
||||
|
||||
while ((tmp = *src++) != 0) {
|
||||
tmp -= '0';
|
||||
if ((tmp < 0) || (tmp > 9))
|
||||
return rv;
|
||||
|
||||
rv++;
|
||||
(*dst) *= 10;
|
||||
(*dst) += tmp;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static inline int dnet_pton(const char *src, char *addrbuf)
|
||||
{
|
||||
uint16_t area = 0;
|
||||
uint16_t node = 0;
|
||||
int pos;
|
||||
|
||||
pos = dnet_num(src, &area);
|
||||
if ((pos == 0) || (area > 63) ||
|
||||
((*(src + pos) != '.') && (*(src + pos) != ',')))
|
||||
return -EINVAL;
|
||||
|
||||
pos = dnet_num(src + pos + 1, &node);
|
||||
if ((pos == 0) || (node > 1023))
|
||||
return -EINVAL;
|
||||
|
||||
*(uint16_t *)addrbuf = dn_ntohs((area << 10) | node);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Creating Abstract Addresses
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate new abstract address object.
|
||||
* @arg maxsize Maximum size of the binary address.
|
||||
* @return Newly allocated address object or NULL
|
||||
*/
|
||||
struct nl_addr *nl_addr_alloc(size_t maxsize)
|
||||
{
|
||||
struct nl_addr *addr;
|
||||
|
||||
addr = calloc(1, sizeof(*addr) + maxsize);
|
||||
if (!addr) {
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr->a_refcnt = 1;
|
||||
addr->a_maxsize = maxsize;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
struct nl_addr *nl_addr_build(int family, void *buf, size_t size)
|
||||
{
|
||||
struct nl_addr *addr;
|
||||
|
||||
addr = nl_addr_alloc(size);
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
addr->a_family = family;
|
||||
addr->a_len = size;
|
||||
addr->a_prefixlen = size*8;
|
||||
|
||||
if (size)
|
||||
memcpy(addr->a_addr, buf, size);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate abstract address object based on a character string
|
||||
* @arg addrstr Address represented as character string.
|
||||
* @arg hint Address family hint or AF_UNSPEC.
|
||||
*
|
||||
* Regognizes the following address formats:
|
||||
*@code
|
||||
* Format Len Family
|
||||
* ----------------------------------------------------------------
|
||||
* IPv6 address format 16 AF_INET6
|
||||
* ddd.ddd.ddd.ddd 4 AF_INET
|
||||
* HH:HH:HH:HH:HH:HH 6 AF_LLC
|
||||
* AA{.|,}NNNN 2 AF_DECnet
|
||||
* HH:HH:HH:... variable AF_UNSPEC
|
||||
* @endcode
|
||||
*
|
||||
* Special values:
|
||||
* - none: All bits and length set to 0.
|
||||
* - {default|all|any}: All bits set to 0, length based on hint or
|
||||
* AF_INET if no hint is given.
|
||||
*
|
||||
* The prefix length may be appened at the end prefixed with a
|
||||
* slash, e.g. 10.0.0.0/8.
|
||||
*
|
||||
* @return Newly allocated abstract address object or NULL.
|
||||
*/
|
||||
struct nl_addr *nl_addr_parse(const char *addrstr, int hint)
|
||||
{
|
||||
int err, copy = 0, len = 0, family = AF_UNSPEC;
|
||||
char *str, *prefix, buf[32];
|
||||
struct nl_addr *addr = NULL; /* gcc ain't that smart */
|
||||
|
||||
str = strdup(addrstr);
|
||||
if (!str) {
|
||||
err = nl_errno(ENOMEM);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
prefix = strchr(str, '/');
|
||||
if (prefix)
|
||||
*prefix = '\0';
|
||||
|
||||
if (!strcasecmp(str, "none")) {
|
||||
family = hint;
|
||||
goto prefix;
|
||||
}
|
||||
|
||||
if (!strcasecmp(str, "default") ||
|
||||
!strcasecmp(str, "all") ||
|
||||
!strcasecmp(str, "any")) {
|
||||
|
||||
switch (hint) {
|
||||
case AF_INET:
|
||||
case AF_UNSPEC:
|
||||
/* Kind of a hack, we assume that if there is
|
||||
* no hint given the user wants to have a IPv4
|
||||
* address given back. */
|
||||
family = AF_INET;
|
||||
len = 4;
|
||||
goto prefix;
|
||||
|
||||
case AF_INET6:
|
||||
family = AF_INET6;
|
||||
len = 16;
|
||||
goto prefix;
|
||||
|
||||
case AF_LLC:
|
||||
family = AF_LLC;
|
||||
len = 6;
|
||||
goto prefix;
|
||||
|
||||
default:
|
||||
err = nl_error(EINVAL, "Unsuported address" \
|
||||
"family for default address");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
copy = 1;
|
||||
|
||||
if (hint == AF_INET || hint == AF_UNSPEC) {
|
||||
if (inet_pton(AF_INET, str, buf) > 0) {
|
||||
family = AF_INET;
|
||||
len = 4;
|
||||
goto prefix;
|
||||
}
|
||||
if (hint == AF_INET) {
|
||||
err = nl_error(EINVAL, "Invalid IPv4 address");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
if (hint == AF_INET6 || hint == AF_UNSPEC) {
|
||||
if (inet_pton(AF_INET6, str, buf) > 0) {
|
||||
family = AF_INET6;
|
||||
len = 16;
|
||||
goto prefix;
|
||||
}
|
||||
if (hint == AF_INET6) {
|
||||
err = nl_error(EINVAL, "Invalid IPv6 address");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hint == AF_LLC || hint == AF_UNSPEC) && strchr(str, ':')) {
|
||||
unsigned int a, b, c, d, e, f;
|
||||
|
||||
if (sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
&a, &b, &c, &d, &e, &f) == 6) {
|
||||
family = AF_LLC;
|
||||
len = 6;
|
||||
buf[0] = (unsigned char) a;
|
||||
buf[1] = (unsigned char) b;
|
||||
buf[2] = (unsigned char) c;
|
||||
buf[3] = (unsigned char) d;
|
||||
buf[4] = (unsigned char) e;
|
||||
buf[5] = (unsigned char) f;
|
||||
goto prefix;
|
||||
}
|
||||
|
||||
if (hint == AF_LLC) {
|
||||
err = nl_error(EINVAL, "Invalid link layer address");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hint == AF_DECnet || hint == AF_UNSPEC) &&
|
||||
(strchr(str, '.') || strchr(str, ','))) {
|
||||
if (dnet_pton(str, buf) > 0) {
|
||||
family = AF_DECnet;
|
||||
len = 2;
|
||||
goto prefix;
|
||||
}
|
||||
if (hint == AF_DECnet) {
|
||||
err = nl_error(EINVAL, "Invalid DECnet address");
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
if (hint == AF_UNSPEC && strchr(str, ':')) {
|
||||
int i = 0;
|
||||
char *s = str, *p;
|
||||
for (;;) {
|
||||
long l = strtol(s, &p, 16);
|
||||
|
||||
if (s == p || l > 0xff || i >= sizeof(buf)) {
|
||||
err = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
buf[i++] = (unsigned char) l;
|
||||
if (*p == '\0')
|
||||
break;
|
||||
s = ++p;
|
||||
}
|
||||
|
||||
len = i;
|
||||
family = AF_UNSPEC;
|
||||
goto prefix;
|
||||
}
|
||||
|
||||
err = nl_error(EINVAL, "Invalid address");
|
||||
goto errout;
|
||||
|
||||
prefix:
|
||||
addr = nl_addr_alloc(len);
|
||||
if (!addr) {
|
||||
err = nl_errno(ENOMEM);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
nl_addr_set_family(addr, family);
|
||||
|
||||
if (copy)
|
||||
nl_addr_set_binary_addr(addr, buf, len);
|
||||
|
||||
if (prefix) {
|
||||
char *p;
|
||||
long pl = strtol(++prefix, &p, 0);
|
||||
if (p == prefix) {
|
||||
nl_addr_destroy(addr);
|
||||
err = -EINVAL;
|
||||
goto errout;
|
||||
}
|
||||
nl_addr_set_prefixlen(addr, pl);
|
||||
} else
|
||||
nl_addr_set_prefixlen(addr, len * 8);
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
free(str);
|
||||
|
||||
return err ? NULL : addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
struct nl_addr *nl_addr_clone(struct nl_addr *addr)
|
||||
{
|
||||
struct nl_addr *new;
|
||||
|
||||
new = nl_addr_build(addr->a_family, addr->a_addr, addr->a_len);
|
||||
if (new)
|
||||
new->a_prefixlen = addr->a_prefixlen;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Destroying Abstract Addresses
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Destroy abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
*/
|
||||
void nl_addr_destroy(struct nl_addr *addr)
|
||||
{
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
if (addr->a_refcnt != 1)
|
||||
BUG();
|
||||
|
||||
free(addr);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Managing Usage References
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct nl_addr *nl_addr_get(struct nl_addr *addr)
|
||||
{
|
||||
addr->a_refcnt++;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void nl_addr_put(struct nl_addr *addr)
|
||||
{
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
if (addr->a_refcnt == 1)
|
||||
nl_addr_destroy(addr);
|
||||
else
|
||||
addr->a_refcnt--;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an abstract address object is shared.
|
||||
* @arg addr Abstract address object.
|
||||
* @return Non-zero if the abstract address object is shared, otherwise 0.
|
||||
*/
|
||||
int nl_addr_shared(struct nl_addr *addr)
|
||||
{
|
||||
return addr->a_refcnt > 1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Miscellaneous
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compares two abstract address objects.
|
||||
* @arg a A abstract address object.
|
||||
* @arg b Another abstract address object.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
int nl_addr_cmp(struct nl_addr *a, struct nl_addr *b)
|
||||
{
|
||||
int d = a->a_family - b->a_family;
|
||||
|
||||
if (d == 0) {
|
||||
d = a->a_len - b->a_len;
|
||||
|
||||
if (a->a_len && d == 0)
|
||||
return memcmp(a->a_addr, b->a_addr, a->a_len);
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the prefix of two abstract address objects.
|
||||
* @arg a A abstract address object.
|
||||
* @arg b Another abstract address object.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
int nl_addr_cmp_prefix(struct nl_addr *a, struct nl_addr *b)
|
||||
{
|
||||
int d = a->a_family - b->a_family;
|
||||
|
||||
if (d == 0) {
|
||||
int len = min(a->a_prefixlen, b->a_prefixlen);
|
||||
int bytes = len / 8;
|
||||
|
||||
d = memcmp(a->a_addr, b->a_addr, bytes);
|
||||
if (d == 0) {
|
||||
int mask = (1UL << (len % 8)) - 1UL;
|
||||
|
||||
d = (a->a_addr[bytes] & mask) -
|
||||
(b->a_addr[bytes] & mask);
|
||||
}
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an address matches a certain family.
|
||||
* @arg addr Address represented as character string.
|
||||
* @arg family Desired address family.
|
||||
*
|
||||
* @return 1 if the address is of the desired address family,
|
||||
* otherwise 0 is returned.
|
||||
*/
|
||||
int nl_addr_valid(char *addr, int family)
|
||||
{
|
||||
int ret;
|
||||
char buf[32];
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
ret = inet_pton(family, addr, buf);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case AF_DECnet:
|
||||
ret = dnet_pton(addr, buf);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case AF_LLC:
|
||||
if (sscanf(addr, "%*02x:%*02x:%*02x:%*02x:%*02x:%*02x") != 6)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess address family of an abstract address object based on address size.
|
||||
* @arg addr Abstract address object.
|
||||
* @return Address family or AF_UNSPEC if guessing wasn't successful.
|
||||
*/
|
||||
int nl_addr_guess_family(struct nl_addr *addr)
|
||||
{
|
||||
switch (addr->a_len) {
|
||||
case 4:
|
||||
return AF_INET;
|
||||
case 6:
|
||||
return AF_LLC;
|
||||
case 16:
|
||||
return AF_INET6;
|
||||
default:
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill out sockaddr structure with values from abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
* @arg sa Destination sockaddr structure buffer.
|
||||
* @arg salen Length of sockaddr structure buffer.
|
||||
*
|
||||
* Fills out the specified sockaddr structure with the data found in the
|
||||
* specified abstract address. The salen argument needs to be set to the
|
||||
* size of sa but will be modified to the actual size used during before
|
||||
* the function exits.
|
||||
*
|
||||
* @return 0 on success or a negative error code
|
||||
*/
|
||||
int nl_addr_fill_sockaddr(struct nl_addr *addr, struct sockaddr *sa,
|
||||
socklen_t *salen)
|
||||
{
|
||||
switch (addr->a_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *sai = (struct sockaddr_in *) sa;
|
||||
|
||||
if (*salen < sizeof(*sai))
|
||||
return -EINVAL;
|
||||
|
||||
sai->sin_family = addr->a_family;
|
||||
memcpy(&sai->sin_addr, addr->a_addr, 4);
|
||||
*salen = sizeof(*sai);
|
||||
}
|
||||
break;
|
||||
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) sa;
|
||||
|
||||
if (*salen < sizeof(*sa6))
|
||||
return -EINVAL;
|
||||
|
||||
sa6->sin6_family = addr->a_family;
|
||||
memcpy(&sa6->sin6_addr, addr->a_addr, 16);
|
||||
*salen = sizeof(*sa6);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Getting Information About Addresses
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Call getaddrinfo() for an abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
*
|
||||
* Calls getaddrinfo() for the specified abstract address in AI_NUMERICHOST
|
||||
* mode.
|
||||
*
|
||||
* @note The caller is responsible for freeing the linked list using the
|
||||
* interface provided by getaddrinfo(3).
|
||||
*
|
||||
* @return A linked list of addrinfo handles or NULL with an error message
|
||||
* associated.
|
||||
*/
|
||||
struct addrinfo *nl_addr_info(struct nl_addr *addr)
|
||||
{
|
||||
int err;
|
||||
struct addrinfo *res;
|
||||
char buf[INET6_ADDRSTRLEN+5];
|
||||
struct addrinfo hint = {
|
||||
.ai_flags = AI_NUMERICHOST,
|
||||
.ai_family = addr->a_family,
|
||||
};
|
||||
|
||||
nl_addr2str(addr, buf, sizeof(buf));
|
||||
|
||||
err = getaddrinfo(buf, NULL, &hint, &res);
|
||||
if (err != 0) {
|
||||
nl_error(err, gai_strerror(err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve abstract address object to a name using getnameinfo().
|
||||
* @arg addr Abstract address object.
|
||||
* @arg host Destination buffer for host name.
|
||||
* @arg hostlen Length of destination buffer.
|
||||
*
|
||||
* Resolves the abstract address to a name and writes the looked up result
|
||||
* into the host buffer. getnameinfo() is used to perform the lookup and
|
||||
* is put into NI_NAMEREQD mode so the function will fail if the lookup
|
||||
* couldn't be performed.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nl_addr_resolve(struct nl_addr *addr, char *host, size_t hostlen)
|
||||
{
|
||||
int err;
|
||||
struct sockaddr_in6 buf;
|
||||
socklen_t salen = sizeof(buf);
|
||||
|
||||
err = nl_addr_fill_sockaddr(addr, (struct sockaddr *) &buf, &salen);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return getnameinfo((struct sockaddr *) &buf, salen,
|
||||
host, hostlen, NULL, 0, NI_NAMEREQD);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
void nl_addr_set_family(struct nl_addr *addr, int family)
|
||||
{
|
||||
addr->a_family = family;
|
||||
}
|
||||
|
||||
int nl_addr_get_family(struct nl_addr *addr)
|
||||
{
|
||||
return addr->a_family;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set binary address of abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
* @arg buf Buffer containing binary address.
|
||||
* @arg len Length of buffer containing binary address.
|
||||
*/
|
||||
int nl_addr_set_binary_addr(struct nl_addr *addr, void *buf, size_t len)
|
||||
{
|
||||
if (len > addr->a_maxsize)
|
||||
return -ERANGE;
|
||||
|
||||
addr->a_len = len;
|
||||
memcpy(addr->a_addr, buf, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get binary address of abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
*/
|
||||
void *nl_addr_get_binary_addr(struct nl_addr *addr)
|
||||
{
|
||||
return addr->a_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length of binary address of abstract address object.
|
||||
* @arg addr Abstract address object.
|
||||
*/
|
||||
unsigned int nl_addr_get_len(struct nl_addr *addr)
|
||||
{
|
||||
return addr->a_len;
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
unsigned int nl_addr_get_prefixlen(struct nl_addr *addr)
|
||||
{
|
||||
return addr->a_prefixlen;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Translations to Strings
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert abstract address object to character string.
|
||||
* @arg addr Abstract address object.
|
||||
* @arg buf Destination buffer.
|
||||
* @arg size Size of destination buffer.
|
||||
*
|
||||
* Converts an abstract address to a character string and stores
|
||||
* the result in the specified destination buffer.
|
||||
*
|
||||
* @return Address represented in ASCII stored in destination buffer.
|
||||
*/
|
||||
char *nl_addr2str(struct nl_addr *addr, char *buf, size_t size)
|
||||
{
|
||||
int i;
|
||||
char tmp[16];
|
||||
|
||||
if (!addr->a_len) {
|
||||
snprintf(buf, size, "none");
|
||||
goto prefix;
|
||||
}
|
||||
|
||||
switch (addr->a_family) {
|
||||
case AF_INET:
|
||||
inet_ntop(AF_INET, addr->a_addr, buf, size);
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
inet_ntop(AF_INET6, addr->a_addr, buf, size);
|
||||
break;
|
||||
|
||||
case AF_DECnet:
|
||||
dnet_ntop(addr->a_addr, addr->a_len, buf, size);
|
||||
break;
|
||||
|
||||
case AF_LLC:
|
||||
default:
|
||||
snprintf(buf, size, "%02x",
|
||||
(unsigned char) addr->a_addr[0]);
|
||||
for (i = 1; i < addr->a_len; i++) {
|
||||
snprintf(tmp, sizeof(tmp), ":%02x",
|
||||
(unsigned char) addr->a_addr[i]);
|
||||
strncat(buf, tmp, size - strlen(buf) - 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
prefix:
|
||||
if (addr->a_prefixlen != (8 * addr->a_len)) {
|
||||
snprintf(tmp, sizeof(tmp), "/%u", addr->a_prefixlen);
|
||||
strncat(buf, tmp, size - strlen(buf) - 1);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Address Family Transformations
|
||||
* @{
|
||||
*/
|
||||
|
||||
static 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)
|
||||
__ADD(AF_APPLETALK,appletalk)
|
||||
__ADD(AF_NETROM,netrom)
|
||||
__ADD(AF_BRIDGE,bridge)
|
||||
__ADD(AF_ATMPVC,atmpvc)
|
||||
__ADD(AF_X25,x25)
|
||||
__ADD(AF_INET6,inet6)
|
||||
__ADD(AF_ROSE,rose)
|
||||
__ADD(AF_DECnet,decnet)
|
||||
__ADD(AF_NETBEUI,netbeui)
|
||||
__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_SNA,sna)
|
||||
__ADD(AF_IRDA,irda)
|
||||
__ADD(AF_PPPOX,pppox)
|
||||
__ADD(AF_WANPIPE,wanpipe)
|
||||
__ADD(AF_LLC,llc)
|
||||
__ADD(AF_BLUETOOTH,bluetooth)
|
||||
};
|
||||
|
||||
char *nl_af2str(int family, char *buf, size_t size)
|
||||
{
|
||||
return __type2str(family, buf, size, afs, ARRAY_SIZE(afs));
|
||||
}
|
||||
|
||||
int nl_str2af(const char *name)
|
||||
{
|
||||
int fam = __str2type(name, afs, ARRAY_SIZE(afs));
|
||||
return fam >= 0 ? fam : AF_UNSPEC;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
787
lib/attr.c
Normal file
787
lib/attr.c
Normal file
|
@ -0,0 +1,787 @@
|
|||
/*
|
||||
* lib/attr.c Netlink Attributes
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/addr.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <netlink/msg.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
/**
|
||||
* @ingroup msg
|
||||
* @defgroup attr Attributes
|
||||
* Netlink Attributes Construction/Parsing Interface
|
||||
* @par 0) Introduction
|
||||
* Netlink attributes are chained together following each other:
|
||||
* @code
|
||||
* <------- nla_total_size(payload) ------->
|
||||
* <---- nla_attr_size(payload) ----->
|
||||
* +----------+- - -+- - - - - - - - - +- - -+-------- - -
|
||||
* | Header | Pad | Payload | Pad | Header
|
||||
* +----------+- - -+- - - - - - - - - +- - -+-------- - -
|
||||
* <- nla_len(nla) -> ^
|
||||
* nla_data(nla)----^ |
|
||||
* nla_next(nla)-----------------------------'
|
||||
* @endcode
|
||||
*
|
||||
* @par
|
||||
* The attribute header and payload must be aligned properly:
|
||||
* @code
|
||||
* <------- NLA_HDRLEN ------> <-- NLA_ALIGN(payload)-->
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* | Header | Pad | Payload | Pad |
|
||||
* | (struct nlattr) | ing | | ing |
|
||||
* +---------------------+- - -+- - - - - - - - - -+- - -+
|
||||
* <-------------- nlattr->nla_len -------------->
|
||||
* @endcode
|
||||
*
|
||||
* @par Nested TLVs:
|
||||
* Nested TLVs are an array of TLVs nested into another TLV. This can be useful
|
||||
* to allow subsystems to have their own formatting rules without the need to
|
||||
* make the underlying layer be aware of it. It can also be useful to transfer
|
||||
* arrays, lists and flattened trees.
|
||||
* \code
|
||||
* <-------------------- NLA_ALIGN(...) ------------------->
|
||||
* +---------------+- - - - - - - - - - - - - - - - - -+- - -+
|
||||
* | |+---------+---------+- - -+-------+| |
|
||||
* | TLV Header || TLV 1 | TLV 2 | | TLV n || Pad |
|
||||
* | |+---------+---------+- - -+-------+| |
|
||||
* +---------------+- - - - - - - - - - - - - - - - - -+- - -+
|
||||
* <--------- nla_data(nla) --------->
|
||||
* \endcode
|
||||
*
|
||||
* @par 1) Constructing a message with attributes
|
||||
* @code
|
||||
* int param1 = 10;
|
||||
* char *param2 = "parameter text";
|
||||
* struct nlmsghdr hdr = {
|
||||
* .nlmsg_type = MY_ACTION,
|
||||
* };
|
||||
* struct nl_msg *m = nlmsg_build(&hdr);
|
||||
* nla_put_u32(m, 1, param1);
|
||||
* nla_put_string(m, 2, param2);
|
||||
*
|
||||
* nl_send_auto_complete(handle, nl_msg_get(m));
|
||||
* nlmsg_free(m);
|
||||
* @endcode
|
||||
*
|
||||
* @par 2) Constructing nested attributes
|
||||
* @code
|
||||
* struct nl_msg * nested_config(void)
|
||||
* {
|
||||
* int a = 5, int b = 10;
|
||||
* struct nl_msg *n = nlmsg_build(NULL);
|
||||
* nla_put_u32(n, 10, a);
|
||||
* nla_put_u32(n, 20, b);
|
||||
* return n;
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
* struct nl_msg *m = nlmsg_build(&hdr);
|
||||
* struct nl_msg *nest = nested_config();
|
||||
* nla_put_nested(m, 1, nest);
|
||||
*
|
||||
* nl_send_auto_complete(handle, nl_msg_get(m));
|
||||
* nlmsg_free(nest);
|
||||
* nlmsg_free(m);
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Size Calculations
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* length of attribute not including padding
|
||||
* @arg payload length of payload
|
||||
*/
|
||||
int nla_attr_size(int payload)
|
||||
{
|
||||
return NLA_HDRLEN + payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* total length of attribute including padding
|
||||
* @arg payload length of payload
|
||||
*/
|
||||
int nla_total_size(int payload)
|
||||
{
|
||||
return NLA_ALIGN(nla_attr_size(payload));
|
||||
}
|
||||
|
||||
/**
|
||||
* length of padding at the tail of the attribute
|
||||
* @arg payload length of payload
|
||||
*/
|
||||
int nla_padlen(int payload)
|
||||
{
|
||||
return nla_total_size(payload) - nla_attr_size(payload);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Payload Access
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* attribute type
|
||||
* @arg nla netlink attribute
|
||||
*/
|
||||
int nla_type(const struct nlattr *nla)
|
||||
{
|
||||
return nla->nla_type & NLA_TYPE_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* head of payload
|
||||
* @arg nla netlink attribute
|
||||
*/
|
||||
void *nla_data(const struct nlattr *nla)
|
||||
{
|
||||
return (char *) nla + NLA_HDRLEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* length of payload
|
||||
* @arg nla netlink attribute
|
||||
*/
|
||||
int nla_len(const struct nlattr *nla)
|
||||
{
|
||||
return nla->nla_len - NLA_HDRLEN;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Parsing
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* check if the netlink attribute fits into the remaining bytes
|
||||
* @arg nla netlink attribute
|
||||
* @arg remaining number of bytes remaining in attribute stream
|
||||
*/
|
||||
int nla_ok(const struct nlattr *nla, int remaining)
|
||||
{
|
||||
return remaining >= sizeof(*nla) &&
|
||||
nla->nla_len >= sizeof(*nla) &&
|
||||
nla->nla_len <= remaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* next netlink attribte in attribute stream
|
||||
* @arg nla netlink attribute
|
||||
* @arg remaining number of bytes remaining in attribute stream
|
||||
*
|
||||
* @return the next netlink attribute in the attribute stream and
|
||||
* decrements remaining by the size of the current attribute.
|
||||
*/
|
||||
struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
|
||||
{
|
||||
int totlen = NLA_ALIGN(nla->nla_len);
|
||||
|
||||
*remaining -= totlen;
|
||||
return (struct nlattr *) ((char *) nla + totlen);
|
||||
}
|
||||
|
||||
static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
|
||||
[NLA_U8] = sizeof(uint8_t),
|
||||
[NLA_U16] = sizeof(uint16_t),
|
||||
[NLA_U32] = sizeof(uint32_t),
|
||||
[NLA_U64] = sizeof(uint64_t),
|
||||
[NLA_STRING] = 1,
|
||||
[NLA_NESTED] = NLA_HDRLEN,
|
||||
};
|
||||
|
||||
static int validate_nla(struct nlattr *nla, int maxtype,
|
||||
struct nla_policy *policy)
|
||||
{
|
||||
struct nla_policy *pt;
|
||||
int minlen = 0, type = nla_type(nla);
|
||||
|
||||
if (type <= 0 || type > maxtype)
|
||||
return 0;
|
||||
|
||||
pt = &policy[type];
|
||||
|
||||
if (pt->type > NLA_TYPE_MAX)
|
||||
BUG();
|
||||
|
||||
if (pt->minlen)
|
||||
minlen = pt->minlen;
|
||||
else if (pt->type != NLA_UNSPEC)
|
||||
minlen = nla_attr_minlen[pt->type];
|
||||
|
||||
if (pt->type == NLA_FLAG && nla_len(nla) > 0)
|
||||
return nl_errno(ERANGE);
|
||||
|
||||
if (nla_len(nla) < minlen)
|
||||
return nl_errno(ERANGE);
|
||||
|
||||
if (pt->maxlen && nla_len(nla) > pt->maxlen)
|
||||
return nl_errno(ERANGE);
|
||||
|
||||
if (pt->type == NLA_STRING) {
|
||||
char *data = nla_data(nla);
|
||||
if (data[nla_len(nla) - 1] != '\0')
|
||||
return nl_errno(EINVAL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse a stream of attributes into a tb buffer
|
||||
* @arg tb destination array with maxtype+1 elements
|
||||
* @arg maxtype maximum attribute type to be expected
|
||||
* @arg head head of attribute stream
|
||||
* @arg len length of attribute stream
|
||||
* @arg policy validation policy
|
||||
*
|
||||
* Parses a stream of attributes and stores a pointer to each attribute in
|
||||
* the tb array accessable via the attribute type. Attributes with a type
|
||||
* exceeding maxtype will be silently ignored for backwards compatibility
|
||||
* reasons. policy may be set to NULL if no validation is required.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
|
||||
struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
int type = nla_type(nla);
|
||||
|
||||
if (type == 0) {
|
||||
fprintf(stderr, "Illegal nla->nla_type == 0\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type <= maxtype) {
|
||||
if (policy) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
tb[type] = nla;
|
||||
}
|
||||
}
|
||||
|
||||
if (rem > 0)
|
||||
fprintf(stderr, "netlink: %d bytes leftover after parsing "
|
||||
"attributes.\n", rem);
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parse nested attributes
|
||||
* @arg tb destination array with maxtype+1 elements
|
||||
* @arg maxtype maximum attribute type to be expected
|
||||
* @arg nla attribute containing the nested attributes
|
||||
* @arg policy validation policy
|
||||
*
|
||||
* @see nla_parse()
|
||||
*/
|
||||
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla,
|
||||
struct nla_policy *policy)
|
||||
{
|
||||
return nla_parse(tb, maxtype, nla_data(nla), nla_len(nla), policy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a stream of attributes
|
||||
* @arg head head of attribute stream
|
||||
* @arg len length of attribute stream
|
||||
* @arg maxtype maximum attribute type to be expected
|
||||
* @arg policy validation policy
|
||||
*
|
||||
* Validates all attributes in the specified attribute stream
|
||||
* against the specified policy. Attributes with a type exceeding
|
||||
* maxtype will be ignored. See documenation of struct nla_policy
|
||||
* for more details.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nla_validate(struct nlattr *head, int len, int maxtype,
|
||||
struct nla_policy *policy)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem, err;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem) {
|
||||
err = validate_nla(nla, maxtype, policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific attribute in a stream of attributes
|
||||
* @arg head head of attribute stream
|
||||
* @arg len length of attribute stream
|
||||
* @arg attrtype type of attribute to look for
|
||||
*
|
||||
* @return the first attribute in the stream matching the specified type.
|
||||
*/
|
||||
struct nlattr *nla_find(struct nlattr *head, int len, int attrtype)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int rem;
|
||||
|
||||
nla_for_each_attr(nla, head, len, rem)
|
||||
if (nla_type(nla) == attrtype)
|
||||
return nla;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Utilities
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Copy a netlink attribute into another memory area
|
||||
* @arg dest where to copy to memcpy
|
||||
* @arg src netlink attribute to copy from
|
||||
* @arg count size of the destination area
|
||||
*
|
||||
* Note: The number of bytes copied is limited by the length of
|
||||
* attribute's payload. memcpy
|
||||
*
|
||||
* @return the number of bytes copied.
|
||||
*/
|
||||
int nla_memcpy(void *dest, struct nlattr *src, int count)
|
||||
{
|
||||
int minlen;
|
||||
|
||||
if (!src)
|
||||
return 0;
|
||||
|
||||
minlen = min_t(int, count, nla_len(src));
|
||||
memcpy(dest, nla_data(src), minlen);
|
||||
|
||||
return minlen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy string attribute payload into a sized buffer
|
||||
* @arg dst where to copy the string to
|
||||
* @arg nla attribute to copy the string from
|
||||
* @arg dstsize size of destination buffer
|
||||
*
|
||||
* Copies at most dstsize - 1 bytes into the destination buffer.
|
||||
* The result is always a valid NUL-terminated string. Unlike
|
||||
* strlcpy the destination buffer is always padded out.
|
||||
*
|
||||
* @return the length of the source buffer.
|
||||
*/
|
||||
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
|
||||
{
|
||||
size_t srclen = nla_len(nla);
|
||||
char *src = nla_data(nla);
|
||||
|
||||
if (srclen > 0 && src[srclen - 1] == '\0')
|
||||
srclen--;
|
||||
|
||||
if (dstsize > 0) {
|
||||
size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
|
||||
|
||||
memset(dst, 0, dstsize);
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
return srclen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare an attribute with sized memory area
|
||||
* @arg nla netlink attribute
|
||||
* @arg data memory area
|
||||
* @arg size size of memory area
|
||||
*/
|
||||
int nla_memcmp(const struct nlattr *nla, const void *data,
|
||||
size_t size)
|
||||
{
|
||||
int d = nla_len(nla) - size;
|
||||
|
||||
if (d == 0)
|
||||
d = memcmp(nla_data(nla), data, size);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare a string attribute against a string
|
||||
* @arg nla netlink string attribute
|
||||
* @arg str another string
|
||||
*/
|
||||
int nla_strcmp(const struct nlattr *nla, const char *str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
int d = nla_len(nla) - len;
|
||||
|
||||
if (d == 0)
|
||||
d = memcmp(nla_data(nla), str, len);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Construction
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* reserve room for attribute on the skb
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg attrlen length of attribute payload
|
||||
*
|
||||
* Adds a netlink attribute header to a netlink message and reserves
|
||||
* room for the payload but does not copy it.
|
||||
*/
|
||||
struct nlattr *nla_reserve(struct nl_msg *n, int attrtype, int attrlen)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int tlen;
|
||||
|
||||
tlen = NLMSG_ALIGN(n->nm_nlh->nlmsg_len) + nla_total_size(attrlen);
|
||||
|
||||
n->nm_nlh = realloc(n->nm_nlh, tlen);
|
||||
if (!n->nm_nlh) {
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nla = (struct nlattr *) nlmsg_tail(n->nm_nlh);
|
||||
nla->nla_type = attrtype;
|
||||
nla->nla_len = nla_attr_size(attrlen);
|
||||
|
||||
memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen));
|
||||
n->nm_nlh->nlmsg_len = tlen;
|
||||
|
||||
NL_DBG(2, "msg %p: Reserved %d bytes at offset +%d for attr %d "
|
||||
"nlmsg_len=%d\n", n, attrlen,
|
||||
(void *) nla - nlmsg_data(n->nm_nlh),
|
||||
attrtype, n->nm_nlh->nlmsg_len);
|
||||
|
||||
return nla;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg attrlen length of attribute payload
|
||||
* @arg data head of attribute payload
|
||||
*
|
||||
* @return -1 if the tailroom of the skb is insufficient to store
|
||||
* the attribute header and payload.
|
||||
*/
|
||||
int nla_put(struct nl_msg *n, int attrtype, int attrlen, const void *data)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
|
||||
nla = nla_reserve(n, attrtype, attrlen);
|
||||
if (!nla)
|
||||
return nl_errno(ENOMEM);
|
||||
|
||||
memcpy(nla_data(nla), data, attrlen);
|
||||
NL_DBG(2, "msg %p: Wrote %d bytes at offset +%d for attr %d\n",
|
||||
n, attrlen, (void *) nla - nlmsg_data(n->nm_nlh), attrtype);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a nested netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg nested netlink attribute to nest
|
||||
*
|
||||
* @return -1 if the tailroom of the skb is insufficient to store
|
||||
* the attribute header and payload.
|
||||
*/
|
||||
int nla_put_nested(struct nl_msg *n, int attrtype, struct nl_msg *nested)
|
||||
{
|
||||
return nla_put(n, attrtype, nlmsg_len(nested->nm_nlh),
|
||||
nlmsg_data(nested->nm_nlh));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a u16 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
int nla_put_u8(struct nl_msg *n, int attrtype, uint8_t value)
|
||||
{
|
||||
return nla_put(n, attrtype, sizeof(uint8_t), &value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a u16 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
int nla_put_u16(struct nl_msg *n, int attrtype, uint16_t value)
|
||||
{
|
||||
return nla_put(n, attrtype, sizeof(uint16_t), &value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a u32 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
int nla_put_u32(struct nl_msg *n, int attrtype, uint32_t value)
|
||||
{
|
||||
return nla_put(n, attrtype, sizeof(uint32_t), &value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a u64 netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg value numeric value
|
||||
*/
|
||||
int nla_put_u64(struct nl_msg *n, int attrtype, uint64_t value)
|
||||
{
|
||||
return nla_put(n, attrtype, sizeof(uint64_t), &value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a string netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg str NUL terminated string
|
||||
*/
|
||||
int nla_put_string(struct nl_msg *n, int attrtype, const char *str)
|
||||
{
|
||||
return nla_put(n, attrtype, strlen(str) + 1, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a flag netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
*/
|
||||
int nla_put_flag(struct nl_msg *n, int attrtype)
|
||||
{
|
||||
return nla_put(n, attrtype, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a msecs netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg msecs number of msecs
|
||||
*/
|
||||
int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
|
||||
{
|
||||
return nla_put_u64(n, attrtype, msecs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an abstract data netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg data abstract data
|
||||
*/
|
||||
int nla_put_data(struct nl_msg *n, int attrtype, struct nl_data *data)
|
||||
{
|
||||
return nla_put(n, attrtype, nl_data_get_size(data),
|
||||
nl_data_get(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an abstract address netlink attribute to a netlink message
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type
|
||||
* @arg addr abstract address
|
||||
*/
|
||||
int nla_put_addr(struct nl_msg *n, int attrtype, struct nl_addr *addr)
|
||||
{
|
||||
return nla_put(n, attrtype, nl_addr_get_len(addr),
|
||||
nl_addr_get_binary_addr(addr));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Nesting
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Start a new level of nested attributes
|
||||
* @arg n netlink message
|
||||
* @arg attrtype attribute type of container
|
||||
*
|
||||
* @return the container attribute
|
||||
*/
|
||||
struct nlattr *nla_nest_start(struct nl_msg *n, int attrtype)
|
||||
{
|
||||
struct nlattr *start = (struct nlattr *) nlmsg_tail(n->nm_nlh);
|
||||
|
||||
if (nla_put(n, attrtype, 0, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize nesting of attributes
|
||||
* @arg n netlink message
|
||||
* @arg start container attribute
|
||||
*
|
||||
* Corrects the container attribute header to include the all
|
||||
* appeneded attributes.
|
||||
*
|
||||
* @return the total data length of the skb.
|
||||
*/
|
||||
int nla_nest_end(struct nl_msg *n, struct nlattr *start)
|
||||
{
|
||||
start->nla_len = (unsigned char *) nlmsg_tail(n->nm_nlh) -
|
||||
(unsigned char *) start;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Reading
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return payload of u32 attribute
|
||||
* @arg nla u32 netlink attribute
|
||||
*/
|
||||
uint32_t nla_get_u32(struct nlattr *nla)
|
||||
{
|
||||
return *(uint32_t *) nla_data(nla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of u16 attribute
|
||||
* @arg nla u16 netlink attribute
|
||||
*/
|
||||
uint16_t nla_get_u16(struct nlattr *nla)
|
||||
{
|
||||
return *(uint16_t *) nla_data(nla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of u8 attribute
|
||||
* @arg nla u8 netlink attribute
|
||||
*/
|
||||
uint8_t nla_get_u8(struct nlattr *nla)
|
||||
{
|
||||
return *(uint8_t *) nla_data(nla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of u64 attribute
|
||||
* @arg nla u64 netlink attribute
|
||||
*/
|
||||
uint64_t nla_get_u64(struct nlattr *nla)
|
||||
{
|
||||
uint64_t tmp;
|
||||
|
||||
nla_memcpy(&tmp, nla, sizeof(tmp));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* return payload of string attribute
|
||||
* @arg nla string netlink attribute
|
||||
*/
|
||||
char *nla_get_string(struct nlattr *nla)
|
||||
{
|
||||
return (char *) nla_data(nla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of flag attribute
|
||||
* @arg nla flag netlink attribute
|
||||
*/
|
||||
int nla_get_flag(struct nlattr *nla)
|
||||
{
|
||||
return !!nla;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of msecs attribute
|
||||
* @arg nla msecs netlink attribute
|
||||
*
|
||||
* @return the number of milliseconds.
|
||||
*/
|
||||
unsigned long nla_get_msecs(struct nlattr *nla)
|
||||
{
|
||||
return nla_get_u64(nla);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of address attribute
|
||||
* @arg nla address netlink attribute
|
||||
* @arg family address family
|
||||
*
|
||||
* @return Newly allocated address handle or NULL
|
||||
*/
|
||||
struct nl_addr *nla_get_addr(struct nlattr *nla, int family)
|
||||
{
|
||||
return nl_addr_build(family, nla_data(nla), nla_len(nla));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return payload of abstract data attribute
|
||||
* @arg nla abstract data netlink attribute
|
||||
*
|
||||
* @return Newly allocated abstract data handle or NULL
|
||||
*/
|
||||
struct nl_data *nla_get_data(struct nlattr *nla)
|
||||
{
|
||||
return nl_data_alloc(nla_data(nla), nla_len(nla));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
805
lib/cache.c
Normal file
805
lib/cache.c
Normal file
|
@ -0,0 +1,805 @@
|
|||
/*
|
||||
* lib/cache.c Caching Module
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cache_mngt
|
||||
* @defgroup cache Cache
|
||||
*
|
||||
* @code
|
||||
* Cache Management | | Type Specific Cache Operations
|
||||
*
|
||||
* | | +----------------+ +------------+
|
||||
* | request update | | msg_parser |
|
||||
* | | +----------------+ +------------+
|
||||
* +- - - - -^- - - - - - - -^- -|- - - -
|
||||
* nl_cache_update: | | | |
|
||||
* 1) --------- co_request_update ------+ | |
|
||||
* | | |
|
||||
* 2) destroy old cache +----------- pp_cb ---------|---+
|
||||
* | | |
|
||||
* 3) ---------- nl_recvmsgs ----------+ +- cb_valid -+
|
||||
* +--------------+ | | | |
|
||||
* | nl_cache_add |<-----+ + - - -v- -|- - - - - - - - - - -
|
||||
* +--------------+ | | +-------------+
|
||||
* | nl_recvmsgs |
|
||||
* | | +-----|-^-----+
|
||||
* +---v-|---+
|
||||
* | | | nl_recv |
|
||||
* +---------+
|
||||
* | | Core Netlink
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
/**
|
||||
* @name Access Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the number of items in the cache
|
||||
* @arg cache cache handle
|
||||
*/
|
||||
int nl_cache_nitems(struct nl_cache *cache)
|
||||
{
|
||||
return cache->c_nitems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of items matching a filter in the cache
|
||||
* @arg cache Cache object.
|
||||
* @arg filter Filter object.
|
||||
*/
|
||||
int nl_cache_nitems_filter(struct nl_cache *cache, struct nl_object *filter)
|
||||
{
|
||||
struct nl_object_ops *ops;
|
||||
struct nl_object *obj;
|
||||
int nitems = 0;
|
||||
|
||||
if (cache->c_ops == NULL)
|
||||
BUG();
|
||||
|
||||
ops = cache->c_ops->co_obj_ops;
|
||||
|
||||
nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
|
||||
if (filter && !nl_object_match_filter(obj, filter))
|
||||
continue;
|
||||
|
||||
nitems++;
|
||||
}
|
||||
|
||||
return nitems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns \b true if the cache is empty.
|
||||
* @arg cache Cache to check
|
||||
* @return \a true if the cache is empty, otherwise \b false is returned.
|
||||
*/
|
||||
int nl_cache_is_empty(struct nl_cache *cache)
|
||||
{
|
||||
return nl_list_empty(&cache->c_items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the operations set of the cache
|
||||
* @arg cache cache handle
|
||||
*/
|
||||
struct nl_cache_ops *nl_cache_get_ops(struct nl_cache *cache)
|
||||
{
|
||||
return cache->c_ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first element in the cache
|
||||
* @arg cache cache handle
|
||||
*/
|
||||
struct nl_object *nl_cache_get_first(struct nl_cache *cache)
|
||||
{
|
||||
if (nl_list_empty(&cache->c_items))
|
||||
return NULL;
|
||||
|
||||
return nl_list_entry(cache->c_items.next,
|
||||
struct nl_object, ce_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the last element in the cache
|
||||
* @arg cache cache handle
|
||||
*/
|
||||
struct nl_object *nl_cache_get_last(struct nl_cache *cache)
|
||||
{
|
||||
if (nl_list_empty(&cache->c_items))
|
||||
return NULL;
|
||||
|
||||
return nl_list_entry(cache->c_items.prev,
|
||||
struct nl_object, ce_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the next element in the cache
|
||||
* @arg obj current object
|
||||
*/
|
||||
struct nl_object *nl_cache_get_next(struct nl_object *obj)
|
||||
{
|
||||
if (nl_list_at_tail(obj, &obj->ce_cache->c_items, ce_list))
|
||||
return NULL;
|
||||
else
|
||||
return nl_list_entry(obj->ce_list.next,
|
||||
struct nl_object, ce_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the previous element in the cache
|
||||
* @arg obj current object
|
||||
*/
|
||||
struct nl_object *nl_cache_get_prev(struct nl_object *obj)
|
||||
{
|
||||
if (nl_list_at_head(obj, &obj->ce_cache->c_items, ce_list))
|
||||
return NULL;
|
||||
else
|
||||
return nl_list_entry(obj->ce_list.prev,
|
||||
struct nl_object, ce_list);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Cache Creation/Deletion
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate an empty cache
|
||||
* @arg ops cache operations to base the cache on
|
||||
*
|
||||
* @return A newly allocated and initialized cache.
|
||||
*/
|
||||
struct nl_cache *nl_cache_alloc(struct nl_cache_ops *ops)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
|
||||
cache = calloc(1, sizeof(*cache));
|
||||
if (!cache) {
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nl_init_list_head(&cache->c_items);
|
||||
cache->c_ops = ops;
|
||||
|
||||
NL_DBG(2, "Allocated cache %p <%s>.\n", cache, nl_cache_name(cache));
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate an empty cache based on type name
|
||||
* @arg kind Name of cache type
|
||||
* @return A newly allocated and initialized cache.
|
||||
*/
|
||||
struct nl_cache *nl_cache_alloc_name(const char *kind)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
ops = nl_cache_ops_lookup(kind);
|
||||
if (!ops) {
|
||||
nl_error(ENOENT, "Unable to lookup cache \"%s\"", kind);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return nl_cache_alloc(ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a new cache containing a subset of a cache
|
||||
* @arg orig Original cache to be based on
|
||||
* @arg filter Filter defining the subset to be filled into new cache
|
||||
* @return A newly allocated cache or NULL.
|
||||
*/
|
||||
struct nl_cache *nl_cache_subset(struct nl_cache *orig,
|
||||
struct nl_object *filter)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
struct nl_object_ops *ops;
|
||||
struct nl_object *obj;
|
||||
|
||||
if (!filter)
|
||||
BUG();
|
||||
|
||||
cache = nl_cache_alloc(orig->c_ops);
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
ops = orig->c_ops->co_obj_ops;
|
||||
|
||||
nl_list_for_each_entry(obj, &orig->c_items, ce_list) {
|
||||
if (!nl_object_match_filter(obj, filter))
|
||||
continue;
|
||||
|
||||
nl_cache_add(cache, obj);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear a cache.
|
||||
* @arg cache cache to clear
|
||||
*
|
||||
* Removes all elements of a cache.
|
||||
*/
|
||||
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_list_for_each_entry_safe(obj, tmp, &cache->c_items, ce_list)
|
||||
nl_cache_remove(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a cache.
|
||||
* @arg cache Cache to free.
|
||||
*
|
||||
* Removes all elements of a cache and frees all memory.
|
||||
*
|
||||
* @note Use this function if you are working with allocated caches.
|
||||
*/
|
||||
void nl_cache_free(struct nl_cache *cache)
|
||||
{
|
||||
nl_cache_clear(cache);
|
||||
NL_DBG(1, "Freeing cache %p <%s>...\n", cache, nl_cache_name(cache));
|
||||
free(cache);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Cache Modifications
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int __cache_add(struct nl_cache *cache, struct nl_object *obj)
|
||||
{
|
||||
obj->ce_cache = cache;
|
||||
|
||||
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));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add object to a cache.
|
||||
* @arg cache Cache to add object to
|
||||
* @arg obj Object to be added to the cache
|
||||
*
|
||||
* Adds the given object to the specified cache. The object is cloned
|
||||
* if it has been added to another cache already.
|
||||
*
|
||||
* @return 0 or a negative error code.
|
||||
*/
|
||||
int nl_cache_add(struct nl_cache *cache, struct nl_object *obj)
|
||||
{
|
||||
struct nl_object *new;
|
||||
|
||||
if (cache->c_ops->co_obj_ops != obj->ce_ops)
|
||||
return nl_error(EINVAL, "Object mismatches cache type");
|
||||
|
||||
if (!nl_list_empty(&obj->ce_list)) {
|
||||
new = nl_object_clone(obj);
|
||||
if (!new)
|
||||
return nl_errno(ENOMEM);
|
||||
} else {
|
||||
nl_object_get(obj);
|
||||
new = obj;
|
||||
}
|
||||
|
||||
return __cache_add(cache, new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move object from one cache to another
|
||||
* @arg cache Cache to move object to.
|
||||
* @arg obj Object subject to be moved
|
||||
*
|
||||
* Removes the given object from its associated cache if needed
|
||||
* and adds it to the new cache.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nl_cache_move(struct nl_cache *cache, struct nl_object *obj)
|
||||
{
|
||||
if (cache->c_ops->co_obj_ops != obj->ce_ops)
|
||||
return nl_error(EINVAL, "Object mismatches cache type");
|
||||
|
||||
NL_DBG(3, "Moving object %p to cache %p\n", obj, cache);
|
||||
|
||||
/* Acquire reference, if already in a cache this will be
|
||||
* reverted during removal */
|
||||
nl_object_get(obj);
|
||||
|
||||
if (!nl_list_empty(&obj->ce_list))
|
||||
nl_cache_remove(obj);
|
||||
|
||||
return __cache_add(cache, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an object from a cache.
|
||||
* @arg obj Object to remove from its cache
|
||||
*
|
||||
* Removes the object \c obj from the cache it is assigned to, since
|
||||
* an object can only be assigned to one cache at a time, the cache
|
||||
* must ne be passed along with it.
|
||||
*/
|
||||
void nl_cache_remove(struct nl_object *obj)
|
||||
{
|
||||
struct nl_cache *cache = obj->ce_cache;
|
||||
|
||||
if (cache == NULL)
|
||||
return;
|
||||
|
||||
nl_list_del(&obj->ce_list);
|
||||
obj->ce_cache = NULL;
|
||||
nl_object_put(obj);
|
||||
cache->c_nitems--;
|
||||
|
||||
NL_DBG(1, "Deleted %p from cache %p <%s>.\n",
|
||||
obj, cache, nl_cache_name(cache));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for an object in a cache
|
||||
* @arg cache Cache to search in.
|
||||
* @arg needle Object to look for.
|
||||
*
|
||||
* Iterates over the cache and looks for an object with identical
|
||||
* identifiers as the needle.
|
||||
*
|
||||
* @return Reference to object or NULL if not found.
|
||||
* @note The returned object must be returned via nl_object_put().
|
||||
*/
|
||||
struct nl_object *nl_cache_search(struct nl_cache *cache,
|
||||
struct nl_object *needle)
|
||||
{
|
||||
struct nl_object *obj;
|
||||
|
||||
nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
|
||||
if (nl_object_identical(obj, needle)) {
|
||||
nl_object_get(obj);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Synchronization
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Request a full dump from the kernel to fill a cache
|
||||
* @arg handle Netlink handle
|
||||
* @arg cache Cache subjected to be filled.
|
||||
*
|
||||
* Send a dumping request to the kernel causing it to dump all objects
|
||||
* related to the specified cache to the netlink socket.
|
||||
*
|
||||
* Use nl_cache_pickup() to read the objects from the socket and fill them
|
||||
* into a cache.
|
||||
*/
|
||||
int nl_cache_request_full_dump(struct nl_handle *handle, struct nl_cache *cache)
|
||||
{
|
||||
NL_DBG(2, "Requesting dump from kernel for cache %p <%s>...\n",
|
||||
cache, nl_cache_name(cache));
|
||||
|
||||
return cache->c_ops->co_request_update(cache, handle);
|
||||
}
|
||||
|
||||
/** @cond SKIP */
|
||||
struct update_xdata {
|
||||
struct nl_cache_ops *ops;
|
||||
struct nl_parser_param *params;
|
||||
};
|
||||
|
||||
static int update_msg_parser(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct update_xdata *x = arg;
|
||||
|
||||
return nl_cache_parse(x->ops, &msg->nm_src, msg->nm_nlh, x->params);
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
int __cache_pickup(struct nl_handle *handle, struct nl_cache *cache,
|
||||
struct nl_parser_param *param)
|
||||
{
|
||||
int err;
|
||||
struct nl_cb *cb;
|
||||
struct update_xdata x = {
|
||||
.ops = cache->c_ops,
|
||||
.params = param,
|
||||
};
|
||||
|
||||
NL_DBG(1, "Picking up answer for cache %p <%s>...\n",
|
||||
cache, nl_cache_name(cache));
|
||||
|
||||
cb = nl_cb_clone(handle->h_cb);
|
||||
if (cb == NULL)
|
||||
return nl_get_errno();
|
||||
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, update_msg_parser, &x);
|
||||
|
||||
err = nl_recvmsgs(handle, 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());
|
||||
|
||||
nl_cb_put(cb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int pickup_cb(struct nl_object *c, struct nl_parser_param *p)
|
||||
{
|
||||
return nl_cache_add((struct nl_cache *) p->pp_arg, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pickup a netlink dump response and put it into a cache.
|
||||
* @arg handle Netlink handle.
|
||||
* @arg cache Cache to put items into.
|
||||
*
|
||||
* Waits for netlink messages to arrive, parses them and puts them into
|
||||
* the specified cache.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nl_cache_pickup(struct nl_handle *handle, struct nl_cache *cache)
|
||||
{
|
||||
struct nl_parser_param p = {
|
||||
.pp_cb = pickup_cb,
|
||||
.pp_arg = cache,
|
||||
};
|
||||
|
||||
return __cache_pickup(handle, cache, &p);
|
||||
}
|
||||
|
||||
static int cache_include(struct nl_cache *cache, struct nl_object *obj,
|
||||
struct nl_msgtype *type, change_func_t cb)
|
||||
{
|
||||
struct nl_object *old;
|
||||
|
||||
switch (type->mt_act) {
|
||||
case NL_ACT_NEW:
|
||||
case NL_ACT_DEL:
|
||||
old = nl_cache_search(cache, obj);
|
||||
if (old) {
|
||||
nl_cache_remove(old);
|
||||
if (type->mt_act == NL_ACT_DEL && cb)
|
||||
cb(cache, old, NL_ACT_DEL);
|
||||
}
|
||||
|
||||
if (type->mt_act == NL_ACT_NEW) {
|
||||
nl_cache_move(cache, obj);
|
||||
if (old == NULL && cb)
|
||||
cb(cache, obj, NL_ACT_NEW);
|
||||
else if (old) {
|
||||
if (nl_object_diff(old, obj) && cb)
|
||||
cb(cache, obj, NL_ACT_CHANGE);
|
||||
|
||||
nl_object_put(old);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NL_DBG(2, "Unknown action associated to object %p\n", obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nl_cache_include(struct nl_cache *cache, struct nl_object *obj,
|
||||
change_func_t change_cb)
|
||||
{
|
||||
struct nl_cache_ops *ops = cache->c_ops;
|
||||
int i;
|
||||
|
||||
if (ops->co_obj_ops != obj->ce_ops)
|
||||
return nl_error(EINVAL, "Object mismatches cache type");
|
||||
|
||||
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
|
||||
if (ops->co_msgtypes[i].mt_id == obj->ce_msgtype)
|
||||
return cache_include(cache, obj, &ops->co_msgtypes[i],
|
||||
change_cb);
|
||||
|
||||
return nl_errno(EINVAL);
|
||||
}
|
||||
|
||||
static int resync_cb(struct nl_object *c, struct nl_parser_param *p)
|
||||
{
|
||||
struct nl_cache_assoc *ca = p->pp_arg;
|
||||
|
||||
return nl_cache_include(ca->ca_cache, c, ca->ca_change);
|
||||
}
|
||||
|
||||
int nl_cache_resync(struct nl_handle *handle, struct nl_cache *cache,
|
||||
change_func_t change_cb)
|
||||
{
|
||||
struct nl_object *obj, *next;
|
||||
struct nl_cache_assoc ca = {
|
||||
.ca_cache = cache,
|
||||
.ca_change = change_cb,
|
||||
};
|
||||
struct nl_parser_param p = {
|
||||
.pp_cb = resync_cb,
|
||||
.pp_arg = &ca,
|
||||
};
|
||||
int err;
|
||||
|
||||
NL_DBG(1, "Resyncing cache %p <%s>...\n", cache, nl_cache_name(cache));
|
||||
|
||||
/* Mark all objects so we can see if some of them are obsolete */
|
||||
nl_cache_mark_all(cache);
|
||||
|
||||
err = nl_cache_request_full_dump(handle, cache);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = __cache_pickup(handle, cache, &p);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
nl_list_for_each_entry_safe(obj, next, &cache->c_items, ce_list)
|
||||
if (nl_object_is_marked(obj))
|
||||
nl_cache_remove(obj);
|
||||
|
||||
NL_DBG(1, "Finished resyncing %p <%s>\n", cache, nl_cache_name(cache));
|
||||
|
||||
err = 0;
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Parsing
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @cond SKIP */
|
||||
int nl_cache_parse(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
||||
struct nlmsghdr *nlh, struct nl_parser_param *params)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
if (nlh->nlmsg_len < nlmsg_msg_size(ops->co_hdrsize)) {
|
||||
err = nl_error(EINVAL, "netlink message too short to be "
|
||||
"of kind %s", ops->co_name);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) {
|
||||
if (ops->co_msgtypes[i].mt_id == nlh->nlmsg_type) {
|
||||
err = ops->co_msg_parser(ops, who, nlh, params);
|
||||
if (err != -ENOENT)
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
err = nl_error(EINVAL, "Unsupported netlink message type %d",
|
||||
nlh->nlmsg_type);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* Parse a netlink message and add it to the cache.
|
||||
* @arg cache cache to add element to
|
||||
* @arg msg netlink message
|
||||
*
|
||||
* Parses a netlink message by calling the cache specific message parser
|
||||
* and adds the new element to the cache.
|
||||
*
|
||||
* @return 0 or a negative error code.
|
||||
*/
|
||||
int nl_cache_parse_and_add(struct nl_cache *cache, struct nl_msg *msg)
|
||||
{
|
||||
struct nl_parser_param p = {
|
||||
.pp_cb = pickup_cb,
|
||||
.pp_arg = cache,
|
||||
};
|
||||
|
||||
return nl_cache_parse(cache->c_ops, NULL, nlmsg_hdr(msg), &p);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)fill a cache with the contents in the kernel.
|
||||
* @arg handle netlink handle
|
||||
* @arg cache cache to update
|
||||
*
|
||||
* Clears the specified cache and fills it with the current state in
|
||||
* the kernel.
|
||||
*
|
||||
* @return 0 or a negative error code.
|
||||
*/
|
||||
int nl_cache_refill(struct nl_handle *handle, struct nl_cache *cache)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nl_cache_request_full_dump(handle, cache);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
NL_DBG(2, "Upading cache %p <%s>, request sent, waiting for dump...\n",
|
||||
cache, nl_cache_name(cache));
|
||||
nl_cache_clear(cache);
|
||||
|
||||
return nl_cache_pickup(handle, cache);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Utillities
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mark all objects in a cache
|
||||
* @arg cache Cache to mark all objects in
|
||||
*/
|
||||
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_list_for_each_entry(obj, &cache->c_items, ce_list)
|
||||
nl_object_mark(obj);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Dumping
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dump all elements of a cache.
|
||||
* @arg cache cache to dump
|
||||
* @arg params dumping parameters
|
||||
*
|
||||
* Dumps all elements of the \a cache to the file descriptor \a fd.
|
||||
*/
|
||||
void nl_cache_dump(struct nl_cache *cache, struct nl_dump_params *params)
|
||||
{
|
||||
nl_cache_dump_filter(cache, params, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump all elements of a cache (filtered).
|
||||
* @arg cache cache to dump
|
||||
* @arg params dumping parameters (optional)
|
||||
* @arg filter filter object
|
||||
*
|
||||
* Dumps all elements of the \a cache to the file descriptor \a fd
|
||||
* given they match the given filter \a filter.
|
||||
*/
|
||||
void nl_cache_dump_filter(struct nl_cache *cache,
|
||||
struct nl_dump_params *params,
|
||||
struct nl_object *filter)
|
||||
{
|
||||
int type = params ? params->dp_type : NL_DUMP_FULL;
|
||||
struct nl_object_ops *ops;
|
||||
struct nl_object *obj;
|
||||
|
||||
NL_DBG(2, "Dumping cache %p <%s> filter %p\n",
|
||||
cache, nl_cache_name(cache), filter);
|
||||
|
||||
if (type > NL_DUMP_MAX || type < 0)
|
||||
BUG();
|
||||
|
||||
if (cache->c_ops == NULL)
|
||||
BUG();
|
||||
|
||||
ops = cache->c_ops->co_obj_ops;
|
||||
if (!ops->oo_dump[type])
|
||||
return;
|
||||
|
||||
nl_list_for_each_entry(obj, &cache->c_items, ce_list) {
|
||||
if (filter && !nl_object_match_filter(obj, filter))
|
||||
continue;
|
||||
|
||||
NL_DBG(4, "Dumping object %p...\n", obj);
|
||||
dump_from_ops(obj, params);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Iterators
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Call a callback on each element of the cache.
|
||||
* @arg cache cache to iterate on
|
||||
* @arg cb callback function
|
||||
* @arg arg argument passed to callback function
|
||||
*
|
||||
* Calls a callback function \a cb on each element of the \a cache.
|
||||
* The argument \a arg is passed on the callback function.
|
||||
*/
|
||||
void nl_cache_foreach(struct nl_cache *cache,
|
||||
void (*cb)(struct nl_object *, void *), void *arg)
|
||||
{
|
||||
nl_cache_foreach_filter(cache, NULL, cb, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a callback on each element of the cache (filtered).
|
||||
* @arg cache cache to iterate on
|
||||
* @arg filter filter object
|
||||
* @arg cb callback function
|
||||
* @arg arg argument passed to callback function
|
||||
*
|
||||
* Calls a callback function \a cb on each element of the \a cache
|
||||
* that matches the \a filter. The argument \a arg is passed on
|
||||
* to the callback function.
|
||||
*/
|
||||
void nl_cache_foreach_filter(struct nl_cache *cache, struct nl_object *filter,
|
||||
void (*cb)(struct nl_object *, void *), void *arg)
|
||||
{
|
||||
struct nl_object *obj, *tmp;
|
||||
struct nl_object_ops *ops;
|
||||
|
||||
if (cache->c_ops == NULL)
|
||||
BUG();
|
||||
|
||||
ops = cache->c_ops->co_obj_ops;
|
||||
|
||||
nl_list_for_each_entry_safe(obj, tmp, &cache->c_items, ce_list) {
|
||||
if (filter && !nl_object_match_filter(obj, filter))
|
||||
continue;
|
||||
|
||||
cb(obj, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
392
lib/cache_mngr.c
Normal file
392
lib/cache_mngr.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*
|
||||
* lib/cache_mngr.c Cache Manager
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cache_mngt
|
||||
* @defgroup cache_mngr Manager
|
||||
* @brief Helps keeping caches up to date.
|
||||
*
|
||||
* The purpose of a cache manager is to keep track of caches and
|
||||
* automatically receive event notifications to keep the caches
|
||||
* up to date with the kernel state. Each manager has exactly one
|
||||
* netlink socket assigned which limits the scope of each manager
|
||||
* to exactly one netlink family. Therefore all caches committed
|
||||
* to a manager must be part of the same netlink family. Due to the
|
||||
* nature of a manager, it is not possible to have a cache maintain
|
||||
* two instances of the same cache type. The socket is subscribed
|
||||
* to the event notification group of each cache and also put into
|
||||
* non-blocking mode. Functions exist to poll() on the socket to
|
||||
* wait for new events to be received.
|
||||
*
|
||||
* @code
|
||||
* App libnl Kernel
|
||||
* | |
|
||||
* +-----------------+ [ notification, link change ]
|
||||
* | | Cache Manager | | [ (IFF_UP | IFF_RUNNING) ]
|
||||
* | | |
|
||||
* | | +------------+| | | [ notification, new addr ]
|
||||
* <-------|---| route/link |<-------(async)--+ [ 10.0.1.1/32 dev eth1 ]
|
||||
* | | +------------+| | |
|
||||
* | +------------+| |
|
||||
* <---|---|---| route/addr |<------|-(async)--------------+
|
||||
* | +------------+|
|
||||
* | | +------------+| |
|
||||
* <-------|---| ... ||
|
||||
* | | +------------+| |
|
||||
* +-----------------+
|
||||
* | |
|
||||
* @endcode
|
||||
*
|
||||
* @par 1) Creating a new cache manager
|
||||
* @code
|
||||
* struct nl_cache_mngr *mngr;
|
||||
*
|
||||
* // Allocate a new cache manager for RTNETLINK and automatically
|
||||
* // provide the caches added to the manager.
|
||||
* mngr = nl_cache_mngr_alloc(NETLINK_ROUTE, NL_AUTO_PROVIDE);
|
||||
* @endcode
|
||||
*
|
||||
* @par 2) Keep track of a cache
|
||||
* @code
|
||||
* struct nl_cache *cache;
|
||||
*
|
||||
* // Create a new cache for links/interfaces and ask the manager to
|
||||
* // keep it up to date for us. This will trigger a full dump request
|
||||
* // to initially fill the cache.
|
||||
* cache = nl_cache_mngr_add(mngr, "route/link");
|
||||
* @endcode
|
||||
*
|
||||
* @par 3) Make the manager receive updates
|
||||
* @code
|
||||
* // Give the manager the ability to receive updates, will call poll()
|
||||
* // with a timeout of 5 seconds.
|
||||
* if (nl_cache_mngr_poll(mngr, 5000) > 0) {
|
||||
* // Manager received at least one update, dump cache?
|
||||
* nl_cache_dump(cache, ...);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @par 4) Release cache manager
|
||||
* @code
|
||||
* nl_cache_mngr_free(mngr);
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
static int include_cb(struct nl_object *obj, struct nl_parser_param *p)
|
||||
{
|
||||
struct nl_cache_assoc *ca = p->pp_arg;
|
||||
int err;
|
||||
|
||||
NL_DBG(2, "Including object %p into cache %p\n", obj, ca->ca_cache);
|
||||
#ifdef NL_DEBUG
|
||||
if (nl_debug >= 4)
|
||||
nl_object_dump(obj, &nl_debug_dp);
|
||||
#endif
|
||||
err = nl_cache_include(ca->ca_cache, obj, ca->ca_change);
|
||||
|
||||
nl_object_put(obj);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int event_input(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct nl_cache_mngr *mngr = arg;
|
||||
int protocol = nlmsg_get_proto(msg);
|
||||
int type = nlmsg_hdr(msg)->nlmsg_type;
|
||||
struct nl_cache_ops *ops;
|
||||
int i, n;
|
||||
struct nl_parser_param p = {
|
||||
.pp_cb = include_cb,
|
||||
};
|
||||
|
||||
NL_DBG(2, "Cache manager %p, handling new message %p as event\n",
|
||||
mngr, msg);
|
||||
#ifdef NL_DEBUG
|
||||
if (nl_debug >= 4)
|
||||
nl_msg_dump(msg, stderr);
|
||||
#endif
|
||||
|
||||
if (mngr->cm_protocol != protocol)
|
||||
BUG();
|
||||
|
||||
for (i = 0; i < mngr->cm_nassocs; i++) {
|
||||
if (mngr->cm_assocs[i].ca_cache) {
|
||||
ops = mngr->cm_assocs[i].ca_cache->c_ops;
|
||||
for (n = 0; ops->co_msgtypes[n].mt_id >= 0; n++)
|
||||
if (ops->co_msgtypes[n].mt_id == type)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
return NL_SKIP;
|
||||
|
||||
found:
|
||||
NL_DBG(2, "Associated message %p to cache %p\n",
|
||||
msg, mngr->cm_assocs[i].ca_cache);
|
||||
p.pp_arg = &mngr->cm_assocs[i];
|
||||
|
||||
return nl_cache_parse(ops, NULL, nlmsg_hdr(msg), &p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate new cache manager
|
||||
* @arg protocol Netlink Protocol this manager is used for
|
||||
* @arg flags Flags
|
||||
*
|
||||
* @return Newly allocated cache manager or NULL on failure.
|
||||
*/
|
||||
struct nl_cache_mngr *nl_cache_mngr_alloc(struct nl_handle *handle,
|
||||
int protocol, int flags)
|
||||
{
|
||||
struct nl_cache_mngr *mngr;
|
||||
|
||||
if (handle == NULL)
|
||||
BUG();
|
||||
|
||||
mngr = calloc(1, sizeof(*mngr));
|
||||
if (!mngr)
|
||||
goto enomem;
|
||||
|
||||
mngr->cm_handle = handle;
|
||||
mngr->cm_nassocs = 32;
|
||||
mngr->cm_protocol = protocol;
|
||||
mngr->cm_flags = flags;
|
||||
mngr->cm_assocs = calloc(mngr->cm_nassocs,
|
||||
sizeof(struct nl_cache_assoc));
|
||||
if (!mngr->cm_assocs)
|
||||
goto enomem;
|
||||
|
||||
|
||||
nl_socket_modify_cb(mngr->cm_handle, NL_CB_VALID, NL_CB_CUSTOM,
|
||||
event_input, mngr);
|
||||
|
||||
/* Required to receive async event notifications */
|
||||
nl_disable_sequence_check(mngr->cm_handle);
|
||||
|
||||
if (nl_connect(mngr->cm_handle, protocol) < 0)
|
||||
goto errout;
|
||||
|
||||
if (nl_socket_set_nonblocking(mngr->cm_handle) < 0)
|
||||
goto errout;
|
||||
|
||||
NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
|
||||
mngr, protocol, mngr->cm_nassocs);
|
||||
|
||||
return mngr;
|
||||
|
||||
enomem:
|
||||
nl_errno(ENOMEM);
|
||||
errout:
|
||||
nl_cache_mngr_free(mngr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add cache responsibility to cache manager
|
||||
* @arg mngr Cache manager.
|
||||
* @arg name Name of cache to keep track of
|
||||
*
|
||||
* Allocates a new cache of the specified type and adds it to the manager.
|
||||
* The operation will trigger a full dump request from the kernel to
|
||||
* initially fill the contents of the cache. The manager will subscribe
|
||||
* to the notification group of the cache to keep track of any further
|
||||
* changes.
|
||||
*
|
||||
* @return The newly allocated cache or NULL on failure.
|
||||
*/
|
||||
struct nl_cache *nl_cache_mngr_add(struct nl_cache_mngr *mngr, const char *name,
|
||||
change_func_t cb)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
struct nl_cache *cache;
|
||||
struct nl_af_group *grp;
|
||||
int err, i;
|
||||
|
||||
ops = nl_cache_ops_lookup(name);
|
||||
if (!ops) {
|
||||
nl_error(ENOENT, "Unknown cache type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ops->co_protocol != mngr->cm_protocol) {
|
||||
nl_error(EINVAL, "Netlink protocol mismatch");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ops->co_groups == NULL) {
|
||||
nl_error(EOPNOTSUPP, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < mngr->cm_nassocs; i++) {
|
||||
if (mngr->cm_assocs[i].ca_cache &&
|
||||
mngr->cm_assocs[i].ca_cache->c_ops == ops) {
|
||||
nl_error(EEXIST, "Cache of this type already managed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
retry:
|
||||
for (i = 0; i < mngr->cm_nassocs; i++)
|
||||
if (!mngr->cm_assocs[i].ca_cache)
|
||||
break;
|
||||
|
||||
if (i >= mngr->cm_nassocs) {
|
||||
mngr->cm_nassocs += 16;
|
||||
mngr->cm_assocs = realloc(mngr->cm_assocs,
|
||||
mngr->cm_nassocs *
|
||||
sizeof(struct nl_cache_assoc));
|
||||
if (mngr->cm_assocs == NULL) {
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
} else {
|
||||
NL_DBG(1, "Increased capacity of cache manager %p " \
|
||||
"to %d\n", mngr, mngr->cm_nassocs);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
cache = nl_cache_alloc(ops);
|
||||
if (!cache) {
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (grp = ops->co_groups; grp->ag_group; grp++) {
|
||||
err = nl_socket_add_membership(mngr->cm_handle, grp->ag_group);
|
||||
if (err < 0)
|
||||
goto errout_free_cache;
|
||||
}
|
||||
|
||||
err = nl_cache_refill(mngr->cm_handle, cache);
|
||||
if (err < 0)
|
||||
goto errout_drop_membership;
|
||||
|
||||
mngr->cm_assocs[i].ca_cache = cache;
|
||||
mngr->cm_assocs[i].ca_change = cb;
|
||||
|
||||
if (mngr->cm_flags & NL_AUTO_PROVIDE)
|
||||
nl_cache_mngt_provide(cache);
|
||||
|
||||
NL_DBG(1, "Added cache %p <%s> to cache manager %p\n",
|
||||
cache, nl_cache_name(cache), mngr);
|
||||
|
||||
return cache;
|
||||
|
||||
errout_drop_membership:
|
||||
for (grp = ops->co_groups; grp->ag_group; grp++)
|
||||
nl_socket_drop_membership(mngr->cm_handle, grp->ag_group);
|
||||
errout_free_cache:
|
||||
nl_cache_free(cache);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file descriptor
|
||||
* @arg mngr Cache Manager
|
||||
*
|
||||
* Get the file descriptor of the socket associated to the manager.
|
||||
* This can be used to change socket options or monitor activity
|
||||
* using poll()/select().
|
||||
*/
|
||||
int nl_cache_mngr_get_fd(struct nl_cache_mngr *mngr)
|
||||
{
|
||||
return nl_socket_get_fd(mngr->cm_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for event notifications
|
||||
* @arg mngr Cache Manager
|
||||
* @arg timeout Upper limit poll() will block, in milliseconds.
|
||||
*
|
||||
* Causes poll() to be called to check for new event notifications
|
||||
* being available. Automatically receives and handles available
|
||||
* notifications.
|
||||
*
|
||||
* This functionally is ideally called regularly during an idle
|
||||
* period.
|
||||
*
|
||||
* @return A positive value if at least one update was handled, 0
|
||||
* for none, or a negative error code.
|
||||
*/
|
||||
int nl_cache_mngr_poll(struct nl_cache_mngr *mngr, int timeout)
|
||||
{
|
||||
int ret;
|
||||
struct pollfd fds = {
|
||||
.fd = nl_socket_get_fd(mngr->cm_handle),
|
||||
.events = POLLIN,
|
||||
};
|
||||
|
||||
NL_DBG(3, "Cache manager %p, poll() fd %d\n", mngr, fds.fd);
|
||||
ret = poll(&fds, 1, timeout);
|
||||
NL_DBG(3, "Cache manager %p, poll() returned %d\n", mngr, ret);
|
||||
if (ret < 0)
|
||||
return nl_errno(errno);
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
return nl_cache_mngr_data_ready(mngr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive available event notifications
|
||||
* @arg mngr Cache manager
|
||||
*
|
||||
* This function can be called if the socket associated to the manager
|
||||
* contains updates to be received. This function should not be used
|
||||
* if nl_cache_mngr_poll() is used.
|
||||
*
|
||||
* @return A positive value if at least one update was handled, 0
|
||||
* for none, or a negative error code.
|
||||
*/
|
||||
int nl_cache_mngr_data_ready(struct nl_cache_mngr *mngr)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nl_recvmsgs_default(mngr->cm_handle);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free cache manager
|
||||
* @arg mngr Cache manager
|
||||
*
|
||||
* Release all resources after usage of a cache manager.
|
||||
*/
|
||||
void nl_cache_mngr_free(struct nl_cache_mngr *mngr)
|
||||
{
|
||||
if (!mngr)
|
||||
return;
|
||||
|
||||
if (mngr->cm_handle) {
|
||||
nl_close(mngr->cm_handle);
|
||||
nl_handle_destroy(mngr->cm_handle);
|
||||
}
|
||||
|
||||
free(mngr->cm_assocs);
|
||||
free(mngr);
|
||||
|
||||
NL_DBG(1, "Cache manager %p freed\n", mngr);
|
||||
}
|
||||
|
||||
/** @} */
|
266
lib/cache_mngt.c
Normal file
266
lib/cache_mngt.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* lib/cache_mngt.c Cache Management
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cache_mngt Caching
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/cache.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
static struct nl_cache_ops *cache_ops;
|
||||
|
||||
/**
|
||||
* Associate a message type to a set of cache operations
|
||||
* @arg protocol netlink protocol
|
||||
* @arg message_type netlink message type
|
||||
*
|
||||
* Associates the specified netlink message type with
|
||||
* a registered set of cache operations.
|
||||
*
|
||||
* @return The cache operations or NULL if no association
|
||||
* could be made.
|
||||
*/
|
||||
struct nl_cache_ops *nl_cache_mngt_associate(int protocol, int message_type)
|
||||
{
|
||||
int i;
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
for (ops = cache_ops; ops; ops = ops->co_next)
|
||||
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
|
||||
if (ops->co_msgtypes[i].mt_id == message_type &&
|
||||
ops->co_protocol == protocol)
|
||||
return ops;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert message type to character string.
|
||||
* @arg ops Cache operations.
|
||||
* @arg protocol Netlink Protocol.
|
||||
* @arg msgtype Message type.
|
||||
* @arg buf Destination buffer.
|
||||
* @arg len Size of destination buffer.
|
||||
*
|
||||
* Converts a message type to a character string and stores it in the
|
||||
* provided buffer.
|
||||
*
|
||||
* @return The destination buffer or the message type encoded in
|
||||
* hexidecimal form if no match was found.
|
||||
*/
|
||||
char *nl_cache_mngt_type2name(struct nl_cache_ops *ops, int protocol,
|
||||
int msgtype, char *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) {
|
||||
if (ops->co_msgtypes[i].mt_id == msgtype &&
|
||||
ops->co_protocol == protocol) {
|
||||
snprintf(buf, len, "%s::%s",
|
||||
ops->co_name,
|
||||
ops->co_msgtypes[i].mt_name);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(buf, len, "%d:%s->0x%x()", protocol, ops->co_name, msgtype);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cache Type Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lookup the set cache operations of a certain cache type
|
||||
* @arg name name of the cache type
|
||||
*
|
||||
* @return The cache operations or NULL if no operations
|
||||
* have been registered under the specified name.
|
||||
*/
|
||||
struct nl_cache_ops *nl_cache_ops_lookup(const char *name)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
for (ops = cache_ops; ops; ops = ops->co_next)
|
||||
if (!strcmp(ops->co_name, name))
|
||||
return ops;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookupt the set of cache operations responsible for a type of object
|
||||
* @arg obj_ops Object operations
|
||||
*
|
||||
* @return The cache operations or NULL if not found.
|
||||
*/
|
||||
struct nl_cache_ops *nl_cache_ops_lookup_for_obj(struct nl_object_ops *obj_ops)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
for (ops = cache_ops; ops; ops = ops->co_next)
|
||||
if (ops->co_obj_ops == obj_ops)
|
||||
return ops;
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a function for each registered cache operation
|
||||
* @arg cb Callback function to be called
|
||||
* @arg arg User specific argument.
|
||||
*/
|
||||
void nl_cache_mngt_foreach(void (*cb)(struct nl_cache_ops *, void *), void *arg)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
for (ops = cache_ops; ops; ops = ops->co_next)
|
||||
cb(ops, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a set of cache operations
|
||||
* @arg ops cache operations
|
||||
*
|
||||
* Called by users of caches to announce the avaibility of
|
||||
* a certain cache type.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int nl_cache_mngt_register(struct nl_cache_ops *ops)
|
||||
{
|
||||
if (!ops->co_name)
|
||||
return nl_error(EINVAL, "No cache name specified");
|
||||
|
||||
if (!ops->co_obj_ops)
|
||||
return nl_error(EINVAL, "No obj cache ops specified");
|
||||
|
||||
if (nl_cache_ops_lookup(ops->co_name))
|
||||
return nl_error(EEXIST, "Cache operations already exist");
|
||||
|
||||
ops->co_next = cache_ops;
|
||||
cache_ops = ops;
|
||||
|
||||
NL_DBG(1, "Registered cache operations %s\n", ops->co_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a set of cache operations
|
||||
* @arg ops cache operations
|
||||
*
|
||||
* Called by users of caches to announce a set of
|
||||
* cache operations is no longer available. The
|
||||
* specified cache operations must have been registered
|
||||
* previously using nl_cache_mngt_register()
|
||||
*
|
||||
* @return 0 on success or a negative error code
|
||||
*/
|
||||
int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
|
||||
{
|
||||
struct nl_cache_ops *t, **tp;
|
||||
|
||||
for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next)
|
||||
if (t == ops)
|
||||
break;
|
||||
|
||||
if (!t)
|
||||
return nl_error(ENOENT, "No such cache operations");
|
||||
|
||||
NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name);
|
||||
|
||||
*tp = t->co_next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Global Cache Provisioning/Requiring
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provide a cache for global use
|
||||
* @arg cache cache to provide
|
||||
*
|
||||
* Offers the specified cache to be used by other modules.
|
||||
* Only one cache per type may be shared at a time,
|
||||
* a previsouly provided caches will be overwritten.
|
||||
*/
|
||||
void nl_cache_mngt_provide(struct nl_cache *cache)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
ops = nl_cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
|
||||
if (!ops)
|
||||
BUG();
|
||||
else
|
||||
ops->co_major_cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unprovide a cache for global use
|
||||
* @arg cache cache to unprovide
|
||||
*
|
||||
* Cancels the offer to use a cache globally. The
|
||||
* cache will no longer be returned via lookups but
|
||||
* may still be in use.
|
||||
*/
|
||||
void nl_cache_mngt_unprovide(struct nl_cache *cache)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
ops = nl_cache_ops_lookup_for_obj(cache->c_ops->co_obj_ops);
|
||||
if (!ops)
|
||||
BUG();
|
||||
else if (ops->co_major_cache == cache)
|
||||
ops->co_major_cache = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Demand the use of a global cache
|
||||
* @arg name name of the required object type
|
||||
*
|
||||
* Trys to find a cache of the specified type for global
|
||||
* use.
|
||||
*
|
||||
* @return A cache provided by another subsystem of the
|
||||
* specified type marked to be available.
|
||||
*/
|
||||
struct nl_cache *nl_cache_mngt_require(const char *name)
|
||||
{
|
||||
struct nl_cache_ops *ops;
|
||||
|
||||
ops = nl_cache_ops_lookup(name);
|
||||
if (!ops || !ops->co_major_cache) {
|
||||
fprintf(stderr, "Application BUG: Your application must "
|
||||
"call nl_cache_mngt_provide() and\nprovide a valid "
|
||||
"%s cache to be used for internal lookups.\nSee the "
|
||||
" API documentation for more details.\n", name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ops->co_major_cache;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
172
lib/data.c
Normal file
172
lib/data.c
Normal file
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* lib/data.c Abstract Data
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup utils
|
||||
* @defgroup data Abstract Data
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
/**
|
||||
* @name General
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate a new abstract data object.
|
||||
* @arg buf Data buffer containing the actual data.
|
||||
* @arg size Size of data buffer.
|
||||
*
|
||||
* Allocates a new abstract data and copies the specified data
|
||||
* buffer into the new handle.
|
||||
*
|
||||
* @return Newly allocated data handle or NULL
|
||||
*/
|
||||
struct nl_data *nl_data_alloc(void *buf, size_t size)
|
||||
{
|
||||
struct nl_data *data;
|
||||
|
||||
data = calloc(1, sizeof(*data));
|
||||
if (!data)
|
||||
goto errout;
|
||||
|
||||
data->d_data = calloc(1, size);
|
||||
if (!data->d_data) {
|
||||
free(data);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
data->d_size = size;
|
||||
|
||||
if (buf)
|
||||
memcpy(data->d_data, buf, size);
|
||||
|
||||
return data;
|
||||
errout:
|
||||
nl_errno(ENOMEM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone an abstract data object.
|
||||
* @arg src Abstract data object
|
||||
*
|
||||
* @return Cloned object or NULL
|
||||
*/
|
||||
struct nl_data *nl_data_clone(struct nl_data *src)
|
||||
{
|
||||
return nl_data_alloc(src->d_data, src->d_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to an abstract data object.
|
||||
* @arg data Abstract data object.
|
||||
* @arg buf Data buffer containing the data to be appended.
|
||||
* @arg size Size of data to be apppended.
|
||||
*
|
||||
* Reallocates an abstract data and copies the specified data
|
||||
* buffer into the new handle.
|
||||
*
|
||||
* @return 0 on success or a negative error code
|
||||
*/
|
||||
int nl_data_append(struct nl_data *data, void *buf, size_t size)
|
||||
{
|
||||
if (size < 0)
|
||||
BUG();
|
||||
|
||||
if (size > 0) {
|
||||
data->d_data = realloc(data->d_data, data->d_size + size);
|
||||
if (!data->d_data)
|
||||
return nl_errno(ENOMEM);
|
||||
|
||||
if (buf)
|
||||
memcpy(data->d_data + data->d_size, buf, size);
|
||||
else
|
||||
memset(data->d_data + data->d_size, 0, size);
|
||||
|
||||
data->d_size += size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an abstract data object.
|
||||
* @arg data Abstract data object.
|
||||
*/
|
||||
void nl_data_free(struct nl_data *data)
|
||||
{
|
||||
if (data)
|
||||
free(data->d_data);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Access
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get data buffer of abstract data object.
|
||||
* @arg data Abstract data object.
|
||||
* @return Data buffer or NULL if empty.
|
||||
*/
|
||||
void *nl_data_get(struct nl_data *data)
|
||||
{
|
||||
return data->d_size > 0 ? data->d_data : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get size of data buffer of abstract data object.
|
||||
* @arg data Abstract data object.
|
||||
* @return Size of data buffer.
|
||||
*/
|
||||
size_t nl_data_get_size(struct nl_data *data)
|
||||
{
|
||||
return data->d_size;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compare two abstract data objects.
|
||||
* @arg a Abstract data object.
|
||||
* @arg b Another abstract data object.
|
||||
* @return An integer less than, equal to, or greater than zero if
|
||||
* a is found, respectively, to be less than, to match, or
|
||||
* be greater than b.
|
||||
*/
|
||||
int nl_data_cmp(struct nl_data *a, struct nl_data *b)
|
||||
{
|
||||
void *a_ = nl_data_get(a);
|
||||
void *b_ = nl_data_get(b);
|
||||
|
||||
if (a_ && b_)
|
||||
return memcmp(a_, b_, nl_data_get_size(a));
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
29
lib/defs.h
Normal file
29
lib/defs.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* lib/defs.h. Generated by configure. */
|
||||
/* lib/defs.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "tgraf@suug.ch"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libnl"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libnl 1.0-pre6"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libnl"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.0-pre6"
|
||||
|
||||
/* verbose errors */
|
||||
/* #undef VERBOSE_ERRORS */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
28
lib/defs.h.in
Normal file
28
lib/defs.h.in
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* lib/defs.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* verbose errors */
|
||||
#undef VERBOSE_ERRORS
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
106
lib/doc.c
Normal file
106
lib/doc.c
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* lib/doc.c Documentation Purpose
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage
|
||||
*
|
||||
* @section remarks Remarks
|
||||
*
|
||||
* @subsection cache_alloc Allocation of Caches
|
||||
*
|
||||
* Almost all subsystem provide a function to allocate a new cache
|
||||
* of some form. The function usually looks like this:
|
||||
* @code
|
||||
* struct nl_cache *<object name>_alloc_cache(struct nl_handle *handle)
|
||||
* @endcode
|
||||
*
|
||||
* These functions allocate a new cache for the own object type,
|
||||
* initializes it properly and updates it to represent the current
|
||||
* state of their master, e.g. a link cache would include all
|
||||
* links currently configured in the kernel.
|
||||
*
|
||||
* Some of the allocation functions may take additional arguments
|
||||
* to further specify what will be part of the cache.
|
||||
*
|
||||
* All such functions return a newly allocated cache or NULL
|
||||
* in case of an error.
|
||||
*
|
||||
* @subsection addr Setting of Addresses
|
||||
* @code
|
||||
* int <object name>_set_addr(struct nl_object *, struct nl_addr *)
|
||||
* @endcode
|
||||
*
|
||||
* All attribute functions avaiable for assigning addresses to objects
|
||||
* take a struct nl_addr argument. The provided address object is
|
||||
* validated against the address family of the object if known already.
|
||||
* The assignment fails if the address families mismatch. In case the
|
||||
* address family has not been specified yet, the address family of
|
||||
* the new address is elected to be the new requirement.
|
||||
*
|
||||
* The function will acquire a new reference on the address object
|
||||
* before assignment, the caller is NOT responsible for this.
|
||||
*
|
||||
* All functions return 0 on success or a negative error code.
|
||||
*
|
||||
* @subsection flags Flags to Character StringTranslations
|
||||
* All functions converting a set of flags to a character string follow
|
||||
* the same principles, therefore, the following information applies
|
||||
* to all functions convertings flags to a character string and vice versa.
|
||||
*
|
||||
* @subsubsection flags2str Flags to Character String
|
||||
* @code
|
||||
* char *<object name>_flags2str(int flags, char *buf, size_t len)
|
||||
* @endcode
|
||||
* @arg flags Flags.
|
||||
* @arg buf Destination buffer.
|
||||
* @arg len Buffer length.
|
||||
*
|
||||
* Converts the specified flags to a character string separated by
|
||||
* commas and stores it in the specified destination buffer.
|
||||
*
|
||||
* @return The destination buffer
|
||||
*
|
||||
* @subsubsection str2flags Character String to Flags
|
||||
* @code
|
||||
* int <object name>_str2flags(const char *name)
|
||||
* @endcode
|
||||
* @arg name Name of flag.
|
||||
*
|
||||
* Converts the provided character string specifying a flag
|
||||
* to the corresponding numeric value.
|
||||
*
|
||||
* @return Link flag or a negative value if none was found.
|
||||
*
|
||||
* @subsubsection type2str Type to Character String
|
||||
* @code
|
||||
* char *<object name>_<type>2str(int type, char *buf, size_t len)
|
||||
* @endcode
|
||||
* @arg type Type as numeric value
|
||||
* @arg buf Destination buffer.
|
||||
* @arg len Buffer length.
|
||||
*
|
||||
* Converts an identifier (type) to a character string and stores
|
||||
* it in the specified destination buffer.
|
||||
*
|
||||
* @return The destination buffer or the type encoded in hexidecimal
|
||||
* form if the identifier is unknown.
|
||||
*
|
||||
* @subsubsection str2type Character String to Type
|
||||
* @code
|
||||
* int <object name>_str2<type>(const char *name)
|
||||
* @endcode
|
||||
* @arg name Name of identifier (type).
|
||||
*
|
||||
* Converts the provided character string specifying a identifier
|
||||
* to the corresponding numeric value.
|
||||
*
|
||||
* @return Identifier as numeric value or a negative value if none was found.
|
||||
*/
|
62
lib/family.c
Normal file
62
lib/family.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* lib/family.c Netlink Family
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup nlfam Netlink Families
|
||||
* @brief
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
/**
|
||||
* @name Netlink Family Name Translation
|
||||
* @{
|
||||
*/
|
||||
|
||||
static struct trans_tbl nlfamilies[] = {
|
||||
__ADD(NETLINK_ROUTE,route)
|
||||
__ADD(NETLINK_USERSOCK,usersock)
|
||||
__ADD(NETLINK_FIREWALL,firewall)
|
||||
__ADD(NETLINK_INET_DIAG,inetdiag)
|
||||
__ADD(NETLINK_NFLOG,nflog)
|
||||
__ADD(NETLINK_XFRM,xfrm)
|
||||
__ADD(NETLINK_SELINUX,selinux)
|
||||
__ADD(NETLINK_ISCSI,iscsi)
|
||||
__ADD(NETLINK_AUDIT,audit)
|
||||
__ADD(NETLINK_FIB_LOOKUP,fib_lookup)
|
||||
__ADD(NETLINK_CONNECTOR,connector)
|
||||
__ADD(NETLINK_NETFILTER,netfilter)
|
||||
__ADD(NETLINK_IP6_FW,ip6_fw)
|
||||
__ADD(NETLINK_DNRTMSG,dnrtmsg)
|
||||
__ADD(NETLINK_KOBJECT_UEVENT,kobject_uevent)
|
||||
__ADD(NETLINK_GENERIC,generic)
|
||||
__ADD(NETLINK_SCSITRANSPORT,scsitransport)
|
||||
__ADD(NETLINK_ECRYPTFS,ecryptfs)
|
||||
};
|
||||
|
||||
char * nl_nlfamily2str(int family, char *buf, size_t size)
|
||||
{
|
||||
return __type2str(family, buf, size, nlfamilies,
|
||||
ARRAY_SIZE(nlfamilies));
|
||||
}
|
||||
|
||||
int nl_str2nlfamily(const char *name)
|
||||
{
|
||||
return __str2type(name, nlfamilies, ARRAY_SIZE(nlfamilies));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
353
lib/fib_lookup/lookup.c
Normal file
353
lib/fib_lookup/lookup.c
Normal file
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* lib/fib_lookup/lookup.c FIB Lookup
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup nlfam
|
||||
* @defgroup fib_lookup FIB Lookup
|
||||
* @brief
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/route.h>
|
||||
#include <netlink/fib_lookup/request.h>
|
||||
#include <netlink/fib_lookup/lookup.h>
|
||||
|
||||
/** @cond SKIP */
|
||||
static struct nl_cache_ops fib_lookup_ops;
|
||||
static struct nl_object_ops result_obj_ops;
|
||||
|
||||
/* not exported so far */
|
||||
struct fib_result_nl {
|
||||
uint32_t fl_addr; /* To be looked up*/
|
||||
uint32_t fl_fwmark;
|
||||
unsigned char fl_tos;
|
||||
unsigned char fl_scope;
|
||||
unsigned char tb_id_in;
|
||||
|
||||
unsigned char tb_id; /* Results */
|
||||
unsigned char prefixlen;
|
||||
unsigned char nh_sel;
|
||||
unsigned char type;
|
||||
unsigned char scope;
|
||||
int err;
|
||||
};
|
||||
/** @endcond */
|
||||
|
||||
static void result_free_data(struct nl_object *obj)
|
||||
{
|
||||
struct flnl_result *res = nl_object_priv(obj);
|
||||
|
||||
if (res && res->fr_req)
|
||||
nl_object_put(OBJ_CAST(res->fr_req));
|
||||
}
|
||||
|
||||
static int result_clone(struct nl_object *_dst, struct nl_object *_src)
|
||||
{
|
||||
struct flnl_result *dst = nl_object_priv(_dst);
|
||||
struct flnl_result *src = nl_object_priv(_src);
|
||||
|
||||
if (src->fr_req)
|
||||
if (!(dst->fr_req = (struct flnl_request *)
|
||||
nl_object_clone(OBJ_CAST(src->fr_req))))
|
||||
return nl_get_errno();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int result_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
||||
struct nlmsghdr *n, void *arg)
|
||||
{
|
||||
struct flnl_result *res;
|
||||
struct fib_result_nl *fr;
|
||||
struct nl_parser_param *pp = arg;
|
||||
struct nl_addr *addr;
|
||||
int err = -EINVAL;
|
||||
|
||||
res = flnl_result_alloc();
|
||||
if (!res)
|
||||
goto errout;
|
||||
|
||||
res->ce_msgtype = n->nlmsg_type;
|
||||
|
||||
res->fr_req = flnl_request_alloc();
|
||||
if (!res->fr_req)
|
||||
goto errout;
|
||||
|
||||
fr = nlmsg_data(n);
|
||||
addr = nl_addr_build(AF_INET, &fr->fl_addr, 4);
|
||||
if (!addr)
|
||||
goto errout;
|
||||
err = flnl_request_set_addr(res->fr_req, addr);
|
||||
nl_addr_put(addr);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
flnl_request_set_fwmark(res->fr_req, fr->fl_fwmark);
|
||||
flnl_request_set_tos(res->fr_req, fr->fl_tos);
|
||||
flnl_request_set_scope(res->fr_req, fr->fl_scope);
|
||||
flnl_request_set_table(res->fr_req, fr->tb_id_in);
|
||||
|
||||
res->fr_table_id = fr->tb_id;
|
||||
res->fr_prefixlen = fr->prefixlen;
|
||||
res->fr_nh_sel = fr->nh_sel;
|
||||
res->fr_type = fr->type;
|
||||
res->fr_scope = fr->scope;
|
||||
res->fr_error = fr->err;
|
||||
|
||||
err = pp->pp_cb((struct nl_object *) res, pp);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
/* REAL HACK, fib_lookup doesn't support ACK nor does it
|
||||
* send a DONE message, enforce end of message stream
|
||||
* after just the first message */
|
||||
return NL_STOP;
|
||||
|
||||
errout:
|
||||
flnl_result_put(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int result_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
struct flnl_result *res = (struct flnl_result *) obj;
|
||||
char buf[128];
|
||||
int line = 1;
|
||||
|
||||
dp_dump(p, "table %s prefixlen %u next-hop-selector %u\n",
|
||||
rtnl_route_table2str(res->fr_table_id, buf, sizeof(buf)),
|
||||
res->fr_prefixlen, res->fr_nh_sel);
|
||||
dp_dump_line(p, line++, "type %s ",
|
||||
nl_rtntype2str(res->fr_type, buf, sizeof(buf)));
|
||||
dp_dump(p, "scope %s error %s (%d)\n",
|
||||
rtnl_scope2str(res->fr_scope, buf, sizeof(buf)),
|
||||
strerror(-res->fr_error), res->fr_error);
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
static int result_dump_full(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
return result_dump_brief(obj, p);
|
||||
}
|
||||
|
||||
static int result_compare(struct nl_object *_a, struct nl_object *_b,
|
||||
uint32_t attrs, int flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Allocation/Freeing
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct flnl_result *flnl_result_alloc(void)
|
||||
{
|
||||
return (struct flnl_result *) nl_object_alloc(&result_obj_ops);
|
||||
}
|
||||
|
||||
void flnl_result_put(struct flnl_result *res)
|
||||
{
|
||||
nl_object_put((struct nl_object *) res);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Cache Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate lookup result cache.
|
||||
*
|
||||
* Allocates a new lookup result cache and initializes it properly.
|
||||
*
|
||||
* @note Free the memory after usage using nl_cache_destroy_and_free().
|
||||
* @return Newly allocated cache or NULL if an error occured.
|
||||
*/
|
||||
struct nl_cache *flnl_result_alloc_cache(void)
|
||||
{
|
||||
return nl_cache_alloc(&fib_lookup_ops);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Lookup
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Builds a netlink request message to do a lookup
|
||||
* @arg req Requested match.
|
||||
* @arg flags additional netlink message flags
|
||||
*
|
||||
* Builds a new netlink message requesting a change of link attributes.
|
||||
* The netlink message header isn't fully equipped with all relevant
|
||||
* fields and must be sent out via nl_send_auto_complete() or
|
||||
* supplemented as needed.
|
||||
* \a old must point to a link currently configured in the kernel
|
||||
* and \a tmpl must contain the attributes to be changed set via
|
||||
* \c rtnl_link_set_* functions.
|
||||
*
|
||||
* @return New netlink message
|
||||
* @note Not all attributes can be changed, see
|
||||
* \ref link_changeable "Changeable Attributes" for more details.
|
||||
*/
|
||||
struct nl_msg *flnl_lookup_build_request(struct flnl_request *req, int flags)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
struct nl_addr *addr;
|
||||
uint64_t fwmark;
|
||||
int tos, scope, table;
|
||||
struct fib_result_nl fr = {0};
|
||||
|
||||
fwmark = flnl_request_get_fwmark(req);
|
||||
tos = flnl_request_get_tos(req);
|
||||
scope = flnl_request_get_scope(req);
|
||||
table = flnl_request_get_table(req);
|
||||
|
||||
fr.fl_fwmark = fwmark != UINT_LEAST64_MAX ? fwmark : 0;
|
||||
fr.fl_tos = tos >= 0 ? tos : 0;
|
||||
fr.fl_scope = scope >= 0 ? scope : RT_SCOPE_UNIVERSE;
|
||||
fr.tb_id_in = table >= 0 ? table : RT_TABLE_UNSPEC;
|
||||
|
||||
addr = flnl_request_get_addr(req);
|
||||
if (!addr) {
|
||||
nl_error(EINVAL, "Request must specify the address");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fr.fl_addr = *(uint32_t *) nl_addr_get_binary_addr(addr);
|
||||
|
||||
msg = nlmsg_alloc_simple(0, flags);
|
||||
if (!msg)
|
||||
goto errout;
|
||||
|
||||
if (nlmsg_append(msg, &fr, sizeof(fr), NLMSG_ALIGNTO) < 0)
|
||||
goto errout;
|
||||
|
||||
return msg;
|
||||
|
||||
errout:
|
||||
nlmsg_free(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform FIB Lookup
|
||||
* @arg handle Netlink handle.
|
||||
* @arg req Lookup request object.
|
||||
* @arg cache Cache for result.
|
||||
*
|
||||
* Builds a netlink message to request a FIB lookup, waits for the
|
||||
* reply and adds the result to the specified cache.
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int flnl_lookup(struct nl_handle *handle, struct flnl_request *req,
|
||||
struct nl_cache *cache)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
msg = flnl_lookup_build_request(req, 0);
|
||||
if (!msg)
|
||||
return nl_errno(ENOMEM);
|
||||
|
||||
err = nl_send_auto_complete(handle, msg);
|
||||
nlmsg_free(msg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return nl_cache_pickup(handle, cache);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attribute Access
|
||||
* @{
|
||||
*/
|
||||
|
||||
int flnl_result_get_table_id(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_table_id;
|
||||
}
|
||||
|
||||
int flnl_result_get_prefixlen(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_prefixlen;
|
||||
}
|
||||
|
||||
int flnl_result_get_nexthop_sel(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_nh_sel;
|
||||
}
|
||||
|
||||
int flnl_result_get_type(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_type;
|
||||
}
|
||||
|
||||
int flnl_result_get_scope(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_scope;
|
||||
}
|
||||
|
||||
int flnl_result_get_error(struct flnl_result *res)
|
||||
{
|
||||
return res->fr_error;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
static struct nl_object_ops result_obj_ops = {
|
||||
.oo_name = "fib_lookup/result",
|
||||
.oo_size = sizeof(struct flnl_result),
|
||||
.oo_free_data = result_free_data,
|
||||
.oo_clone = result_clone,
|
||||
.oo_dump[NL_DUMP_BRIEF] = result_dump_brief,
|
||||
.oo_dump[NL_DUMP_FULL] = result_dump_full,
|
||||
.oo_compare = result_compare,
|
||||
};
|
||||
|
||||
static struct nl_cache_ops fib_lookup_ops = {
|
||||
.co_name = "fib_lookup/fib_lookup",
|
||||
.co_hdrsize = sizeof(struct fib_result_nl),
|
||||
.co_msgtypes = {
|
||||
{ 0, NL_ACT_UNSPEC, "any" },
|
||||
END_OF_MSGTYPES_LIST,
|
||||
},
|
||||
.co_protocol = NETLINK_FIB_LOOKUP,
|
||||
.co_msg_parser = result_msg_parser,
|
||||
.co_obj_ops = &result_obj_ops,
|
||||
};
|
||||
|
||||
static void __init fib_lookup_init(void)
|
||||
{
|
||||
nl_cache_mngt_register(&fib_lookup_ops);
|
||||
}
|
||||
|
||||
static void __exit fib_lookup_exit(void)
|
||||
{
|
||||
nl_cache_mngt_unregister(&fib_lookup_ops);
|
||||
}
|
||||
|
||||
/** @} */
|
187
lib/fib_lookup/request.c
Normal file
187
lib/fib_lookup/request.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* lib/fib_lookup/request.c FIB Lookup Request
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup fib_lookup
|
||||
* @defgroup flreq Request
|
||||
* @brief
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-local.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/object.h>
|
||||
#include <netlink/fib_lookup/request.h>
|
||||
|
||||
static struct nl_object_ops request_obj_ops;
|
||||
|
||||
/** @cond SKIP */
|
||||
#define REQUEST_ATTR_ADDR 0x01
|
||||
#define REQUEST_ATTR_FWMARK 0x02
|
||||
#define REQUEST_ATTR_TOS 0x04
|
||||
#define REQUEST_ATTR_SCOPE 0x08
|
||||
#define REQUEST_ATTR_TABLE 0x10
|
||||
/** @endcond */
|
||||
|
||||
static void request_free_data(struct nl_object *obj)
|
||||
{
|
||||
struct flnl_request *req = REQUEST_CAST(obj);
|
||||
|
||||
if (req)
|
||||
nl_addr_put(req->lr_addr);
|
||||
}
|
||||
|
||||
static int request_clone(struct nl_object *_dst, struct nl_object *_src)
|
||||
{
|
||||
struct flnl_request *dst = nl_object_priv(_dst);
|
||||
struct flnl_request *src = nl_object_priv(_src);
|
||||
|
||||
if (src->lr_addr)
|
||||
if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
|
||||
goto errout;
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
return nl_get_errno();
|
||||
}
|
||||
|
||||
static int request_compare(struct nl_object *_a, struct nl_object *_b,
|
||||
uint32_t attrs, int flags)
|
||||
{
|
||||
struct flnl_request *a = (struct flnl_request *) _a;
|
||||
struct flnl_request *b = (struct flnl_request *) _b;
|
||||
int diff = 0;
|
||||
|
||||
#define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR)
|
||||
|
||||
diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark);
|
||||
diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos);
|
||||
diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope);
|
||||
diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table);
|
||||
diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr));
|
||||
|
||||
#undef REQ_DIFF
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @name Lookup Request Creation/Deletion
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct flnl_request *flnl_request_alloc(void)
|
||||
{
|
||||
return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
|
||||
{
|
||||
req->lr_fwmark = fwmark;
|
||||
req->ce_mask |= REQUEST_ATTR_FWMARK;
|
||||
}
|
||||
|
||||
uint64_t flnl_request_get_fwmark(struct flnl_request *req)
|
||||
{
|
||||
if (req->ce_mask & REQUEST_ATTR_FWMARK)
|
||||
return req->lr_fwmark;
|
||||
else
|
||||
return UINT_LEAST64_MAX;
|
||||
}
|
||||
|
||||
void flnl_request_set_tos(struct flnl_request *req, int tos)
|
||||
{
|
||||
req->lr_tos = tos;
|
||||
req->ce_mask |= REQUEST_ATTR_TOS;
|
||||
}
|
||||
|
||||
int flnl_request_get_tos(struct flnl_request *req)
|
||||
{
|
||||
if (req->ce_mask & REQUEST_ATTR_TOS)
|
||||
return req->lr_tos;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void flnl_request_set_scope(struct flnl_request *req, int scope)
|
||||
{
|
||||
req->lr_scope = scope;
|
||||
req->ce_mask |= REQUEST_ATTR_SCOPE;
|
||||
}
|
||||
|
||||
int flnl_request_get_scope(struct flnl_request *req)
|
||||
{
|
||||
if (req->ce_mask & REQUEST_ATTR_SCOPE)
|
||||
return req->lr_scope;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void flnl_request_set_table(struct flnl_request *req, int table)
|
||||
{
|
||||
req->lr_table = table;
|
||||
req->ce_mask |= REQUEST_ATTR_TABLE;
|
||||
}
|
||||
|
||||
int flnl_request_get_table(struct flnl_request *req)
|
||||
{
|
||||
if (req->ce_mask & REQUEST_ATTR_TABLE)
|
||||
return req->lr_table;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
|
||||
{
|
||||
if (addr->a_family != AF_INET)
|
||||
return nl_error(EINVAL, "Address must be an IPv4 address");
|
||||
|
||||
if (req->lr_addr)
|
||||
nl_addr_put(req->lr_addr);
|
||||
|
||||
nl_addr_get(addr);
|
||||
req->lr_addr = addr;
|
||||
|
||||
req->ce_mask |= REQUEST_ATTR_ADDR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
|
||||
{
|
||||
if (req->ce_mask & REQUEST_ATTR_ADDR)
|
||||
return req->lr_addr;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
static struct nl_object_ops request_obj_ops = {
|
||||
.oo_name = "fib_lookup/request",
|
||||
.oo_size = sizeof(struct flnl_request),
|
||||
.oo_free_data = request_free_data,
|
||||
.oo_clone = request_clone,
|
||||
.oo_compare = request_compare,
|
||||
.oo_id_attrs = ~0,
|
||||
};
|
||||
|
||||
/** @} */
|
319
lib/genl/ctrl.c
Normal file
319
lib/genl/ctrl.c
Normal file
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* lib/genl/ctrl.c Generic Netlink Controller
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup genl_mngt
|
||||
* @defgroup ctrl Controller
|
||||
* @brief
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-generic.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/mngt.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
/** @cond SKIP */
|
||||
#define CTRL_VERSION 0x0001
|
||||
|
||||
static struct nl_cache_ops genl_ctrl_ops;
|
||||
/** @endcond */
|
||||
|
||||
static int ctrl_request_update(struct nl_cache *c, struct nl_handle *h)
|
||||
{
|
||||
return genl_send_simple(h, GENL_ID_CTRL, CTRL_CMD_GETFAMILY,
|
||||
CTRL_VERSION, NLM_F_DUMP);
|
||||
}
|
||||
|
||||
static struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
|
||||
[CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
|
||||
[CTRL_ATTR_FAMILY_NAME] = { .type = NLA_STRING,
|
||||
.maxlen = GENL_NAMSIZ },
|
||||
[CTRL_ATTR_VERSION] = { .type = NLA_U32 },
|
||||
[CTRL_ATTR_HDRSIZE] = { .type = NLA_U32 },
|
||||
[CTRL_ATTR_MAXATTR] = { .type = NLA_U32 },
|
||||
[CTRL_ATTR_OPS] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
static struct nla_policy family_op_policy[CTRL_ATTR_OP_MAX+1] = {
|
||||
[CTRL_ATTR_OP_ID] = { .type = NLA_U32 },
|
||||
[CTRL_ATTR_OP_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int ctrl_msg_parser(struct nl_cache_ops *ops, struct genl_cmd *cmd,
|
||||
struct genl_info *info, void *arg)
|
||||
{
|
||||
struct genl_family *family;
|
||||
struct nl_parser_param *pp = arg;
|
||||
int err;
|
||||
|
||||
family = genl_family_alloc();
|
||||
if (family == NULL) {
|
||||
err = nl_errno(ENOMEM);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_FAMILY_NAME] == NULL) {
|
||||
err = nl_error(EINVAL, "Missing family name TLV");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_FAMILY_ID] == NULL) {
|
||||
err = nl_error(EINVAL, "Missing family id TLV");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
family->ce_msgtype = info->nlh->nlmsg_type;
|
||||
genl_family_set_id(family,
|
||||
nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]));
|
||||
genl_family_set_name(family,
|
||||
nla_get_string(info->attrs[CTRL_ATTR_FAMILY_NAME]));
|
||||
|
||||
if (info->attrs[CTRL_ATTR_VERSION]) {
|
||||
uint32_t version = nla_get_u32(info->attrs[CTRL_ATTR_VERSION]);
|
||||
genl_family_set_version(family, version);
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_HDRSIZE]) {
|
||||
uint32_t hdrsize = nla_get_u32(info->attrs[CTRL_ATTR_HDRSIZE]);
|
||||
genl_family_set_hdrsize(family, hdrsize);
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_MAXATTR]) {
|
||||
uint32_t maxattr = nla_get_u32(info->attrs[CTRL_ATTR_MAXATTR]);
|
||||
genl_family_set_maxattr(family, maxattr);
|
||||
}
|
||||
|
||||
if (info->attrs[CTRL_ATTR_OPS]) {
|
||||
struct nlattr *nla, *nla_ops;
|
||||
int remaining;
|
||||
|
||||
nla_ops = info->attrs[CTRL_ATTR_OPS];
|
||||
nla_for_each_nested(nla, nla_ops, remaining) {
|
||||
struct nlattr *tb[CTRL_ATTR_OP_MAX+1];
|
||||
int flags = 0, id;
|
||||
|
||||
err = nla_parse_nested(tb, CTRL_ATTR_OP_MAX, nla,
|
||||
family_op_policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
if (tb[CTRL_ATTR_OP_ID] == NULL) {
|
||||
err = nl_errno(EINVAL);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
id = nla_get_u32(tb[CTRL_ATTR_OP_ID]);
|
||||
|
||||
if (tb[CTRL_ATTR_OP_FLAGS])
|
||||
flags = nla_get_u32(tb[CTRL_ATTR_OP_FLAGS]);
|
||||
|
||||
err = genl_family_add_op(family, id, flags);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err = pp->pp_cb((struct nl_object *) family, pp);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
return P_ACCEPT;
|
||||
|
||||
errout:
|
||||
genl_family_put(family);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Cache Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct nl_cache *genl_ctrl_alloc_cache(struct nl_handle *handle)
|
||||
{
|
||||
struct nl_cache * cache;
|
||||
|
||||
cache = nl_cache_alloc(&genl_ctrl_ops);
|
||||
if (cache == NULL)
|
||||
return NULL;
|
||||
|
||||
if (handle && nl_cache_refill(handle, cache) < 0) {
|
||||
nl_cache_free(cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up generic netlink family by id in the provided cache.
|
||||
* @arg cache Generic netlink family cache.
|
||||
* @arg id Family identifier.
|
||||
*
|
||||
* Searches through the cache looking for a registered family
|
||||
* matching the specified identifier. The caller will own a
|
||||
* reference on the returned object which needs to be given
|
||||
* back after usage using genl_family_put().
|
||||
*
|
||||
* @return Generic netlink family object or NULL if no match was found.
|
||||
*/
|
||||
struct genl_family *genl_ctrl_search(struct nl_cache *cache, int id)
|
||||
{
|
||||
struct genl_family *fam;
|
||||
|
||||
if (cache->c_ops != &genl_ctrl_ops)
|
||||
BUG();
|
||||
|
||||
nl_list_for_each_entry(fam, &cache->c_items, ce_list) {
|
||||
if (fam->gf_id == id) {
|
||||
nl_object_get((struct nl_object *) fam);
|
||||
return fam;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Resolver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Look up generic netlink family by family name in the provided cache.
|
||||
* @arg cache Generic netlink family cache.
|
||||
* @arg name Family name.
|
||||
*
|
||||
* Searches through the cache looking for a registered family
|
||||
* matching the specified name. The caller will own a reference
|
||||
* on the returned object which needs to be given back after
|
||||
* usage using genl_family_put().
|
||||
*
|
||||
* @return Generic netlink family object or NULL if no match was found.
|
||||
*/
|
||||
struct genl_family *genl_ctrl_search_by_name(struct nl_cache *cache,
|
||||
const char *name)
|
||||
{
|
||||
struct genl_family *fam;
|
||||
|
||||
if (cache->c_ops != &genl_ctrl_ops)
|
||||
BUG();
|
||||
|
||||
nl_list_for_each_entry(fam, &cache->c_items, ce_list) {
|
||||
if (!strcmp(name, fam->gf_name)) {
|
||||
nl_object_get((struct nl_object *) fam);
|
||||
return fam;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Resolve generic netlink family name to its identifier
|
||||
* @arg handle Netlink Handle
|
||||
* @arg name Name of generic netlink family
|
||||
*
|
||||
* Resolves the generic netlink family name to its identifer and returns
|
||||
* it.
|
||||
*
|
||||
* @return A positive identifier or a negative error code.
|
||||
*/
|
||||
int genl_ctrl_resolve(struct nl_handle *handle, const char *name)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
struct genl_family *family;
|
||||
int err;
|
||||
|
||||
cache = genl_ctrl_alloc_cache(handle);
|
||||
if (cache == NULL)
|
||||
return nl_get_errno();
|
||||
|
||||
family = genl_ctrl_search_by_name(cache, name);
|
||||
if (family == NULL) {
|
||||
err = nl_error(ENOENT, "Generic Netlink Family not found");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = genl_family_get_id(family);
|
||||
genl_family_put(family);
|
||||
errout:
|
||||
nl_cache_free(cache);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
static struct genl_cmd genl_cmds[] = {
|
||||
{
|
||||
.c_id = CTRL_CMD_NEWFAMILY,
|
||||
.c_name = "NEWFAMILY" ,
|
||||
.c_maxattr = CTRL_ATTR_MAX,
|
||||
.c_attr_policy = ctrl_policy,
|
||||
.c_msg_parser = ctrl_msg_parser,
|
||||
},
|
||||
{
|
||||
.c_id = CTRL_CMD_DELFAMILY,
|
||||
.c_name = "DELFAMILY" ,
|
||||
},
|
||||
{
|
||||
.c_id = CTRL_CMD_GETFAMILY,
|
||||
.c_name = "GETFAMILY" ,
|
||||
},
|
||||
{
|
||||
.c_id = CTRL_CMD_NEWOPS,
|
||||
.c_name = "NEWOPS" ,
|
||||
},
|
||||
{
|
||||
.c_id = CTRL_CMD_DELOPS,
|
||||
.c_name = "DELOPS" ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct genl_ops genl_ops = {
|
||||
.o_cmds = genl_cmds,
|
||||
.o_ncmds = ARRAY_SIZE(genl_cmds),
|
||||
};
|
||||
|
||||
/** @cond SKIP */
|
||||
extern struct nl_object_ops genl_family_ops;
|
||||
/** @endcond */
|
||||
|
||||
static struct nl_cache_ops genl_ctrl_ops = {
|
||||
.co_name = "genl/family",
|
||||
.co_hdrsize = GENL_HDRSIZE(0),
|
||||
.co_msgtypes = GENL_FAMILY(GENL_ID_CTRL, "nlctrl"),
|
||||
.co_genl = &genl_ops,
|
||||
.co_protocol = NETLINK_GENERIC,
|
||||
.co_request_update = ctrl_request_update,
|
||||
.co_obj_ops = &genl_family_ops,
|
||||
};
|
||||
|
||||
static void __init ctrl_init(void)
|
||||
{
|
||||
genl_register(&genl_ctrl_ops);
|
||||
}
|
||||
|
||||
static void __exit ctrl_exit(void)
|
||||
{
|
||||
genl_unregister(&genl_ctrl_ops);
|
||||
}
|
||||
|
||||
/** @} */
|
285
lib/genl/family.c
Normal file
285
lib/genl/family.c
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* lib/genl/family.c Generic Netlink Family
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup genl
|
||||
* @defgroup genl_family Generic Netlink Family
|
||||
* @brief
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-generic.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
/** @cond SKIP */
|
||||
#define FAMILY_ATTR_ID 0x01
|
||||
#define FAMILY_ATTR_NAME 0x02
|
||||
#define FAMILY_ATTR_VERSION 0x04
|
||||
#define FAMILY_ATTR_HDRSIZE 0x08
|
||||
#define FAMILY_ATTR_MAXATTR 0x10
|
||||
#define FAMILY_ATTR_OPS 0x20
|
||||
|
||||
struct nl_object_ops genl_family_ops;
|
||||
/** @endcond */
|
||||
|
||||
static void family_constructor(struct nl_object *c)
|
||||
{
|
||||
struct genl_family *family = (struct genl_family *) c;
|
||||
|
||||
nl_init_list_head(&family->gf_ops);
|
||||
}
|
||||
|
||||
static void family_free_data(struct nl_object *c)
|
||||
{
|
||||
struct genl_family *family = (struct genl_family *) c;
|
||||
struct genl_family_op *ops, *tmp;
|
||||
|
||||
if (family == NULL)
|
||||
return;
|
||||
|
||||
nl_list_for_each_entry_safe(ops, tmp, &family->gf_ops, o_list) {
|
||||
nl_list_del(&ops->o_list);
|
||||
free(ops);
|
||||
}
|
||||
}
|
||||
|
||||
static int family_clone(struct nl_object *_dst, struct nl_object *_src)
|
||||
{
|
||||
struct genl_family *dst = nl_object_priv(_dst);
|
||||
struct genl_family *src = nl_object_priv(_src);
|
||||
struct genl_family_op *ops;
|
||||
int err;
|
||||
|
||||
nl_list_for_each_entry(ops, &src->gf_ops, o_list) {
|
||||
err = genl_family_add_op(dst, ops->o_id, ops->o_flags);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int family_dump_brief(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
struct genl_family *family = (struct genl_family *) obj;
|
||||
|
||||
dp_dump(p, "0x%04x %s version %u\n",
|
||||
family->gf_id, family->gf_name, family->gf_version);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct trans_tbl ops_flags[] = {
|
||||
__ADD(GENL_ADMIN_PERM, admin-perm)
|
||||
__ADD(GENL_CMD_CAP_DO, has-doit)
|
||||
__ADD(GENL_CMD_CAP_DUMP, has-dump)
|
||||
__ADD(GENL_CMD_CAP_HASPOL, has-policy)
|
||||
};
|
||||
|
||||
static char *ops_flags2str(int flags, char *buf, size_t len)
|
||||
{
|
||||
return __flags2str(flags, buf, len, ops_flags, ARRAY_SIZE(ops_flags));
|
||||
}
|
||||
|
||||
static int family_dump_full(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
struct genl_family *family = (struct genl_family *) obj;
|
||||
int line;
|
||||
|
||||
line = family_dump_brief(obj, p);
|
||||
dp_dump_line(p, line++, " hdrsize %u maxattr %u\n",
|
||||
family->gf_hdrsize, family->gf_maxattr);
|
||||
|
||||
if (family->ce_mask & FAMILY_ATTR_OPS) {
|
||||
struct genl_family_op *op;
|
||||
char buf[64];
|
||||
|
||||
nl_list_for_each_entry(op, &family->gf_ops, o_list) {
|
||||
ops_flags2str(op->o_flags, buf, sizeof(buf));
|
||||
|
||||
genl_op2name(family->gf_id, op->o_id, buf, sizeof(buf));
|
||||
|
||||
dp_dump_line(p, line++, " op %s (0x%02x)",
|
||||
buf, op->o_id);
|
||||
|
||||
if (op->o_flags)
|
||||
dp_dump(p, " <%s>",
|
||||
ops_flags2str(op->o_flags, buf,
|
||||
sizeof(buf)));
|
||||
|
||||
dp_dump(p, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
static int family_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
|
||||
{
|
||||
return family_dump_full(obj, p);
|
||||
}
|
||||
|
||||
static int family_compare(struct nl_object *_a, struct nl_object *_b,
|
||||
uint32_t attrs, int flags)
|
||||
{
|
||||
struct genl_family *a = (struct genl_family *) _a;
|
||||
struct genl_family *b = (struct genl_family *) _b;
|
||||
int diff = 0;
|
||||
|
||||
#define FAM_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, FAMILY_ATTR_##ATTR, a, b, EXPR)
|
||||
|
||||
diff |= FAM_DIFF(ID, a->gf_id != b->gf_id);
|
||||
diff |= FAM_DIFF(VERSION, a->gf_version != b->gf_version);
|
||||
diff |= FAM_DIFF(HDRSIZE, a->gf_hdrsize != b->gf_hdrsize);
|
||||
diff |= FAM_DIFF(MAXATTR, a->gf_maxattr != b->gf_maxattr);
|
||||
diff |= FAM_DIFF(NAME, strcmp(a->gf_name, b->gf_name));
|
||||
|
||||
#undef FAM_DIFF
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @name Family Object
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct genl_family *genl_family_alloc(void)
|
||||
{
|
||||
return (struct genl_family *) nl_object_alloc(&genl_family_ops);
|
||||
}
|
||||
|
||||
void genl_family_put(struct genl_family *family)
|
||||
{
|
||||
nl_object_put((struct nl_object *) family);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Attributes
|
||||
* @{
|
||||
*/
|
||||
|
||||
unsigned int genl_family_get_id(struct genl_family *family)
|
||||
{
|
||||
if (family->ce_mask & FAMILY_ATTR_ID)
|
||||
return family->gf_id;
|
||||
else
|
||||
return GENL_ID_GENERATE;
|
||||
}
|
||||
|
||||
void genl_family_set_id(struct genl_family *family, unsigned int id)
|
||||
{
|
||||
family->gf_id = id;
|
||||
family->ce_mask |= FAMILY_ATTR_ID;
|
||||
}
|
||||
|
||||
char *genl_family_get_name(struct genl_family *family)
|
||||
{
|
||||
if (family->ce_mask & FAMILY_ATTR_NAME)
|
||||
return family->gf_name;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void genl_family_set_name(struct genl_family *family, const char *name)
|
||||
{
|
||||
strncpy(family->gf_name, name, GENL_NAMSIZ-1);
|
||||
family->ce_mask |= FAMILY_ATTR_NAME;
|
||||
}
|
||||
|
||||
uint8_t genl_family_get_version(struct genl_family *family)
|
||||
{
|
||||
if (family->ce_mask & FAMILY_ATTR_VERSION)
|
||||
return family->gf_version;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void genl_family_set_version(struct genl_family *family, uint8_t version)
|
||||
{
|
||||
family->gf_version = version;
|
||||
family->ce_mask |= FAMILY_ATTR_VERSION;
|
||||
}
|
||||
|
||||
uint32_t genl_family_get_hdrsize(struct genl_family *family)
|
||||
{
|
||||
if (family->ce_mask & FAMILY_ATTR_HDRSIZE)
|
||||
return family->gf_hdrsize;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void genl_family_set_hdrsize(struct genl_family *family, uint32_t hdrsize)
|
||||
{
|
||||
family->gf_hdrsize = hdrsize;
|
||||
family->ce_mask |= FAMILY_ATTR_HDRSIZE;
|
||||
}
|
||||
|
||||
uint32_t genl_family_get_maxattr(struct genl_family *family)
|
||||
{
|
||||
if (family->ce_mask & FAMILY_ATTR_MAXATTR)
|
||||
return family->gf_maxattr;
|
||||
else
|
||||
return family->gf_maxattr;
|
||||
}
|
||||
|
||||
void genl_family_set_maxattr(struct genl_family *family, uint32_t maxattr)
|
||||
{
|
||||
family->gf_maxattr = maxattr;
|
||||
family->ce_mask |= FAMILY_ATTR_MAXATTR;
|
||||
}
|
||||
|
||||
int genl_family_add_op(struct genl_family *family, int id, int flags)
|
||||
{
|
||||
struct genl_family_op *op;
|
||||
|
||||
op = calloc(1, sizeof(*op));
|
||||
if (op == NULL)
|
||||
return nl_errno(ENOMEM);
|
||||
|
||||
op->o_id = id;
|
||||
op->o_flags = flags;
|
||||
|
||||
nl_list_add_tail(&op->o_list, &family->gf_ops);
|
||||
family->ce_mask |= FAMILY_ATTR_OPS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @cond SKIP */
|
||||
struct nl_object_ops genl_family_ops = {
|
||||
.oo_name = "genl/family",
|
||||
.oo_size = sizeof(struct genl_family),
|
||||
.oo_constructor = family_constructor,
|
||||
.oo_free_data = family_free_data,
|
||||
.oo_clone = family_clone,
|
||||
.oo_dump[NL_DUMP_BRIEF] = family_dump_brief,
|
||||
.oo_dump[NL_DUMP_FULL] = family_dump_full,
|
||||
.oo_dump[NL_DUMP_STATS] = family_dump_stats,
|
||||
#if 0
|
||||
.oo_dump[NL_DUMP_XML] = addr_dump_xml,
|
||||
.oo_dump[NL_DUMP_ENV] = addr_dump_env,
|
||||
#endif
|
||||
.oo_compare = family_compare,
|
||||
.oo_id_attrs = FAMILY_ATTR_ID,
|
||||
};
|
||||
/** @endcond */
|
||||
|
||||
/** @} */
|
210
lib/genl/genl.c
Normal file
210
lib/genl/genl.c
Normal file
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* lib/genl/genl.c Generic Netlink
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup nlfam
|
||||
* @defgroup genl Generic Netlink
|
||||
*
|
||||
* @par Message Format
|
||||
* @code
|
||||
* <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
|
||||
* +----------------------------+- - -+- - - - - - - - - - -+- - -+
|
||||
* | Header | Pad | Payload | Pad |
|
||||
* | struct nlmsghdr | | | |
|
||||
* +----------------------------+- - -+- - - - - - - - - - -+- - -+
|
||||
* @endcode
|
||||
* @code
|
||||
* <-------- GENL_HDRLEN -------> <--- hdrlen -->
|
||||
* <------- genlmsg_len(ghdr) ------>
|
||||
* +------------------------+- - -+---------------+- - -+------------+
|
||||
* | Generic Netlink Header | Pad | Family Header | Pad | Attributes |
|
||||
* | struct genlmsghdr | | | | |
|
||||
* +------------------------+- - -+---------------+- - -+------------+
|
||||
* genlmsg_data(ghdr)--------------^ ^
|
||||
* genlmsg_attrdata(ghdr, hdrlen)-------------------------
|
||||
* @endcode
|
||||
*
|
||||
* @par 1) Creating a new generic netlink message
|
||||
* @code
|
||||
* struct nl_msg *msg;
|
||||
* struct myhdr {
|
||||
* int a;
|
||||
* int b;
|
||||
* } *hdr;
|
||||
*
|
||||
* // Create a new empty netlink message
|
||||
* msg = nlmsg_alloc();
|
||||
*
|
||||
* // Append the netlink and generic netlink message header, this
|
||||
* // operation also reserves room for the family specific header.
|
||||
* hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, sizeof(hdr),
|
||||
* NLM_F_ECHO, MYOP, VERSION);
|
||||
*
|
||||
* // Fill out your own family specific header.
|
||||
* hdr->a = 1;
|
||||
* hdr->b = 2;
|
||||
*
|
||||
* // Append the optional attributes.
|
||||
* nla_put_u32(msg, 1, 0x10);
|
||||
*
|
||||
* // Message is ready to be sent.
|
||||
* nl_send_auto_complete(nl_handle, msg);
|
||||
*
|
||||
* // All done? Free the message.
|
||||
* nlmsg_free(msg);
|
||||
* @endcode
|
||||
*
|
||||
* @par 2) Sending of trivial messages
|
||||
* @code
|
||||
* // For trivial messages not requiring any family specific header or
|
||||
* // attributes, genl_send_simple() may be used to send messages directly.
|
||||
* genl_send_simple(nl_handle, family, MY_SIMPLE_CMD, VERSION, 0);
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-generic.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
/**
|
||||
* @name Socket Creating
|
||||
* @{
|
||||
*/
|
||||
|
||||
int genl_connect(struct nl_handle *handle)
|
||||
{
|
||||
return nl_connect(handle, NETLINK_GENERIC);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Sending
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Send trivial generic netlink message
|
||||
* @arg handle Netlink handle.
|
||||
* @arg family Generic netlink family
|
||||
* @arg cmd Command
|
||||
* @arg version Version
|
||||
* @arg flags Additional netlink message flags.
|
||||
*
|
||||
* Fills out a routing netlink request message and sends it out
|
||||
* using nl_send_simple().
|
||||
*
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int genl_send_simple(struct nl_handle *handle, int family, int cmd,
|
||||
int version, int flags)
|
||||
{
|
||||
struct genlmsghdr hdr = {
|
||||
.cmd = cmd,
|
||||
.version = version,
|
||||
};
|
||||
|
||||
return nl_send_simple(handle, family, flags, &hdr, sizeof(hdr));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Message Parsing
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get head of message payload
|
||||
* @arg gnlh genetlink messsage header
|
||||
*/
|
||||
void *genlmsg_data(const struct genlmsghdr *gnlh)
|
||||
{
|
||||
return ((unsigned char *) gnlh + GENL_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lenght of message payload
|
||||
* @arg gnlh genetlink message header
|
||||
*/
|
||||
int genlmsg_len(const struct genlmsghdr *gnlh)
|
||||
{
|
||||
struct nlmsghdr *nlh = (struct nlmsghdr *)((unsigned char *)gnlh -
|
||||
NLMSG_HDRLEN);
|
||||
return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get head of attribute data
|
||||
* @arg gnlh generic netlink message header
|
||||
* @arg hdrlen length of family specific header
|
||||
*/
|
||||
struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen)
|
||||
{
|
||||
return genlmsg_data(gnlh) + NLMSG_ALIGN(hdrlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length of attribute data
|
||||
* @arg gnlh generic netlink message header
|
||||
* @arg hdrlen length of family specific header
|
||||
*/
|
||||
int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen)
|
||||
{
|
||||
return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Message Building
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Add generic netlink header to netlink message
|
||||
* @arg msg netlink message
|
||||
* @arg pid netlink process id or NL_AUTO_PID
|
||||
* @arg seq sequence number of message or NL_AUTO_SEQ
|
||||
* @arg family generic netlink family
|
||||
* @arg hdrlen length of user specific header
|
||||
* @arg flags message flags
|
||||
* @arg cmd generic netlink command
|
||||
* @arg version protocol version
|
||||
*
|
||||
* Returns pointer to user specific header.
|
||||
*/
|
||||
void *genlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, int family,
|
||||
int hdrlen, int flags, uint8_t cmd, uint8_t version)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct genlmsghdr hdr = {
|
||||
.cmd = cmd,
|
||||
.version = version,
|
||||
};
|
||||
|
||||
nlh = nlmsg_put(msg, pid, seq, family, GENL_HDRLEN + hdrlen, flags);
|
||||
if (nlh == NULL)
|
||||
return NULL;
|
||||
|
||||
memcpy(nlmsg_data(nlh), &hdr, sizeof(hdr));
|
||||
NL_DBG(2, "msg %p: Added generic netlink header cmd=%d version=%d\n",
|
||||
msg, cmd, version);
|
||||
|
||||
return nlmsg_data(nlh) + GENL_HDRLEN;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
285
lib/genl/mngt.c
Normal file
285
lib/genl/mngt.c
Normal file
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* lib/genl/mngt.c Generic Netlink Management
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup genl
|
||||
* @defgroup genl_mngt Management
|
||||
*
|
||||
* @par 1) Registering a generic netlink module
|
||||
* @code
|
||||
* #include <netlink/genl/mngt.h>
|
||||
*
|
||||
* // First step is to define all the commands being used in
|
||||
* // particular generic netlink family. The ID and name are
|
||||
* // mandatory to be filled out. A callback function and
|
||||
* // most the attribute policy that comes with it must be
|
||||
* // defined for commands expected to be issued towards
|
||||
* // userspace.
|
||||
* static struct genl_cmd foo_cmds[] = {
|
||||
* {
|
||||
* .c_id = FOO_CMD_NEW,
|
||||
* .c_name = "NEWFOO" ,
|
||||
* .c_maxattr = FOO_ATTR_MAX,
|
||||
* .c_attr_policy = foo_policy,
|
||||
* .c_msg_parser = foo_msg_parser,
|
||||
* },
|
||||
* {
|
||||
* .c_id = FOO_CMD_DEL,
|
||||
* .c_name = "DELFOO" ,
|
||||
* },
|
||||
* };
|
||||
*
|
||||
* // The list of commands must then be integrated into a
|
||||
* // struct genl_ops serving as handle for this particular
|
||||
* // family.
|
||||
* static struct genl_ops my_genl_ops = {
|
||||
* .o_cmds = foo_cmds,
|
||||
* .o_ncmds = ARRAY_SIZE(foo_cmds),
|
||||
* };
|
||||
*
|
||||
* // Using the above struct genl_ops an arbitary number of
|
||||
* // cache handles can be associated to it.
|
||||
* //
|
||||
* // The macro GENL_HDRSIZE() must be used to specify the
|
||||
* // length of the header to automatically take headers on
|
||||
* // generic layers into account.
|
||||
* //
|
||||
* // The macro GENL_FAMILY() is used to represent the generic
|
||||
* // netlink family id.
|
||||
* static struct nl_cache_ops genl_foo_ops = {
|
||||
* .co_name = "genl/foo",
|
||||
* .co_hdrsize = GENL_HDRSIZE(sizeof(struct my_hdr)),
|
||||
* .co_msgtypes = GENL_FAMILY(GENL_ID_GENERATE, "foo"),
|
||||
* .co_genl = &my_genl_ops,
|
||||
* .co_protocol = NETLINK_GENERIC,
|
||||
* .co_request_update = foo_request_update,
|
||||
* .co_obj_ops = &genl_foo_ops,
|
||||
* };
|
||||
*
|
||||
* // Finally each cache handle for a generic netlink family
|
||||
* // must be registered using genl_register().
|
||||
* static void __init foo_init(void)
|
||||
* {
|
||||
* genl_register(&genl_foo_ops);
|
||||
* }
|
||||
*
|
||||
* // ... respectively unregsted again.
|
||||
* static void __exit foo_exit(void)
|
||||
* {
|
||||
* genl_unregister(&genl_foo_ops);
|
||||
* }
|
||||
* @endcode
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <netlink-generic.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/mngt.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/utils.h>
|
||||
|
||||
static NL_LIST_HEAD(genl_ops_list);
|
||||
|
||||
static int genl_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
|
||||
struct nlmsghdr *nlh, void *arg)
|
||||
{
|
||||
int i, err;
|
||||
struct genlmsghdr *ghdr;
|
||||
struct genl_cmd *cmd;
|
||||
|
||||
ghdr = nlmsg_data(nlh);
|
||||
|
||||
if (ops->co_genl == NULL)
|
||||
BUG();
|
||||
|
||||
for (i = 0; i < ops->co_genl->o_ncmds; i++) {
|
||||
cmd = &ops->co_genl->o_cmds[i];
|
||||
if (cmd->c_id == ghdr->cmd)
|
||||
goto found;
|
||||
}
|
||||
|
||||
err = nl_errno(ENOENT);
|
||||
goto errout;
|
||||
|
||||
found:
|
||||
if (cmd->c_msg_parser == NULL)
|
||||
err = nl_error(EOPNOTSUPP, "No message parser found.");
|
||||
else {
|
||||
struct nlattr *tb[cmd->c_maxattr + 1];
|
||||
struct genl_info info = {
|
||||
.who = who,
|
||||
.nlh = nlh,
|
||||
.genlhdr = ghdr,
|
||||
.userhdr = genlmsg_data(ghdr),
|
||||
.attrs = tb,
|
||||
};
|
||||
|
||||
err = nlmsg_parse(nlh, ops->co_hdrsize, tb, cmd->c_maxattr,
|
||||
cmd->c_attr_policy);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
||||
err = cmd->c_msg_parser(ops, cmd, &info, arg);
|
||||
}
|
||||
errout:
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
char *genl_op2name(int family, int op, char *buf, size_t len)
|
||||
{
|
||||
struct genl_ops *ops;
|
||||
int i;
|
||||
|
||||
nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
|
||||
if (ops->o_family == family) {
|
||||
for (i = 0; i < ops->o_ncmds; i++) {
|
||||
struct genl_cmd *cmd;
|
||||
cmd = &ops->o_cmds[i];
|
||||
|
||||
if (cmd->c_id == op) {
|
||||
strncpy(buf, cmd->c_name, len - 1);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(buf, "unknown", len - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @name Register/Unregister
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register generic netlink operations
|
||||
* @arg ops cache operations
|
||||
*/
|
||||
int genl_register(struct nl_cache_ops *ops)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (ops->co_protocol != NETLINK_GENERIC) {
|
||||
err = nl_error(EINVAL, "cache operations not for protocol " \
|
||||
"NETLINK_GENERIC (protocol=%s)",
|
||||
ops->co_protocol);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ops->co_hdrsize < GENL_HDRSIZE(0)) {
|
||||
err = nl_error(EINVAL, "co_hdrsize too short, probably " \
|
||||
"not including genlmsghdr, minsize=%d",
|
||||
GENL_HDRSIZE(0));
|
||||
goto errout;
|
||||
}
|
||||
|
||||
if (ops->co_genl == NULL) {
|
||||
err = nl_error(EINVAL, "co_genl is NULL, must provide " \
|
||||
"valid genl operations");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ops->co_genl->o_cache_ops = ops;
|
||||
ops->co_genl->o_name = ops->co_msgtypes[0].mt_name;
|
||||
ops->co_genl->o_family = ops->co_msgtypes[0].mt_id;
|
||||
ops->co_msg_parser = genl_msg_parser;
|
||||
|
||||
/* FIXME: check for dup */
|
||||
|
||||
nl_list_add_tail(&ops->co_genl->o_list, &genl_ops_list);
|
||||
|
||||
err = nl_cache_mngt_register(ops);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister generic netlink operations
|
||||
* @arg ops cache operations
|
||||
*/
|
||||
void genl_unregister(struct nl_cache_ops *ops)
|
||||
{
|
||||
nl_cache_mngt_unregister(ops);
|
||||
nl_list_del(&ops->co_genl->o_list);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Resolving ID/Name
|
||||
* @{
|
||||
*/
|
||||
|
||||
static int __genl_ops_resolve(struct nl_cache *ctrl, struct genl_ops *ops)
|
||||
{
|
||||
struct genl_family *family;
|
||||
|
||||
family = genl_ctrl_search_by_name(ctrl, ops->o_name);
|
||||
if (family != NULL) {
|
||||
ops->o_id = genl_family_get_id(family);
|
||||
genl_family_put(family);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nl_error(ENOENT, "Unable to find generic netlink family \"%s\"",
|
||||
ops->o_name);
|
||||
}
|
||||
|
||||
int genl_ops_resolve(struct nl_handle *handle, struct genl_ops *ops)
|
||||
{
|
||||
struct nl_cache *ctrl;
|
||||
int err;
|
||||
|
||||
ctrl = genl_ctrl_alloc_cache(handle);
|
||||
if (ctrl == NULL) {
|
||||
err = nl_get_errno();
|
||||
goto errout;
|
||||
}
|
||||
|
||||
err = __genl_ops_resolve(ctrl, ops);
|
||||
|
||||
nl_cache_free(ctrl);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
int genl_mngt_resolve(struct nl_handle *handle)
|
||||
{
|
||||
struct nl_cache *ctrl;
|
||||
struct genl_ops *ops;
|
||||
int err = 0;
|
||||
|
||||
ctrl = genl_ctrl_alloc_cache(handle);
|
||||
if (ctrl == NULL) {
|
||||
err = nl_get_errno();
|
||||
goto errout;
|
||||
}
|
||||
|
||||
nl_list_for_each_entry(ops, &genl_ops_list, o_list) {
|
||||
err = __genl_ops_resolve(ctrl, ops);
|
||||
}
|
||||
|
||||
nl_cache_free(ctrl);
|
||||
errout:
|
||||
return err;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** @} */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue