\input texinfo
@setfilename guile-netlink.info
@documentencoding UTF-8
@settitle guile-netlink
@include version.texi
@copying
Copyright @copyright{} 2020 Julien Lepiller
Copyright @copyright{} 2025 Dale Mellor
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the section entitled ``GNU Free
Documentation License''.
@end quotation
@end copying
@titlepage
@end titlepage
@contents
@node Top
@top guile-netlink
This document describes guile-netlink version @value{VERSION}, a guile
implementation of the netlink protocol.
@menu
* Introduction:: What is netlink?
* IP Library:: High-level procedures for network devices.
* ACPI API:: High-level procedures for receiving ACPI event notifications.
* API Reference:: Low-level procedure reference.
* Concept Index:: Concepts.
* Programming Index:: Data types, procedures, and variables.
@detailmenu
--- The Detailed Node Listing ---
IP Library
* Link::
* Addr::
* Route::
ACPI API
* ACPI example::
* ACPI reference::
Low-Level API Reference
* Common API::
* Netlink API::
* Rtnetlink API::
Common API
* Data Types::
* Constants::
* Netlink Connections::
Netlink API
* Netlink Headers::
* Standard Message Types::
Rtnetlink API
* Routing Attributes::
* Link Messages::
* Address Messages::
@end detailmenu
@end menu
@node Introduction
@chapter Introduction
@cindex netlink
@cindex routing protocol
@cindex ACPI protocol
@cindex contributions
@cindex high-level
@cindex intermediate-level
@cindex low-level
Netlink is an inter-process communication protocol that can be used for
communication between processes, or with the kernel. It is implemented by
Linux.
Many protocols exist on top of Netlink. For example, the @emph{routing}
protocol is used to configure network-related functions in the kernel, such as
firewall, route table or IP addresses of interfaces, and the @emph{ACPI}
protocol is used by the Linux kernel to send notifications of changes in
system power usage. (Deep down, these two protocols are very different beasts,
with the former being regarded as a @emph{classical} protocol with very fixed
message formats, and the latter being an example of a @emph{generic} protocol
which entails subscribing to a broadcast channel and deeply introspecting the
transmitted data.)
Lots of other protocols, or families, are provided by Linux, but this library
currently only services the two examples described above. Of course,
contributions of code which implements others are always welcome!
This library implements code at three levels: at high-level we have the
@ref{IP Library} and @ref{ACPI API} which give immediate access to the
protocols described above; at intermediate level there is the
@ref{Rtnetlink API} which defines special structures and functions used in the
routing protocol, and many of which are borrowed by the ACPI protocol; finally
the low-level details are outlined in the @ref{API Reference}.
@node IP Library
@chapter IP Library
This library comes with higher-level procedures that let you access and modify
the state of network on your computer.
@menu
* Link::
* Addr::
* Route::
@end menu
@node Link
@section Link
The @code{(ip link)} module introduces procedures to access and modify the
network links on your machine. They are equivalent to the @command{ip link}
family of commands, from @code{iproute2}.
@deffn {Datatype}
Datatype representing the status of a network link.
get-links
print-link
make-link link?
link-name link-id link-type link-flags link-mtu link-qdisc
link-state link-mode link-group link-qlen link-addr link-brd
@table @asis
@item @code{name}
Name of the link, such as @code{"enp1s0"}.
@item @code{id}
Index of the link, a unique number used to identify the link.
@item @code{type}
Type of the link, as an integer.
@item @code{flags}
Flags associated with the device, as a list of symbols, such as
@code{'(UP LOOPBACK)}.
@item @code{mtu}
MTU of the link, as an integer.
@item @code{qdisc}
Queuing discipline of the link, as a string, such as @code{"noqueue"}.
@item @code{state}
State of the link, as an integer. Use @code{int->operstate} from
@code{(netlink constant)} to get a symbol, such as @code{IF_OPER_UP}.
@item @code{mode}
Mode of the link. 0 means @code{DORMANT}, 1 means @code{DEFAULT}.
@item @code{group}
Identifier of the group it belongs to. 0 for @code{default}.
@item @code{qlen}
Size of the queue.
@item @code{addr}
Ethernet address of the link, as a string.
@item @code{brd}
Broadcast (ethernet) address of the link, as a string.
@end table
@end deffn
@deffn {Scheme Procedure} get-links
Returns the list of existing links in the system, as a list of @code{}
objects.
@end deffn
@deffn {Scheme Procedure} wait-for-link @var{name} [#:blocking? #t]
Wait until a link called @var{name} (a string such as @code{"ens3"}) shows
up.
When @var{blocking?} is false, use a non-blocking socket and cooperate via
@code{current-read-waiter}---useful when using Fibers.
@end deffn
@deffn {Sceme Procedure} print-link @var{link}
Display @var{link} on the standard output, using a format similar to
@command{ip link} from @code{iproute2}.
@end deffn
@deffn {Scheme Procedure} link-set @var{device} [#:up @code{#f}] @
[#:down @code{#f}] [#:type @code{#f}] [#:arp-on @code{#f}] @
[#:arp-off @code{#f}] [#:dynamic-on @code{#f}] [#:dynamic-off @code{#f}] @
[#:multicast-on @code{#f}] [#:multicast-off @code{#f}] @
[#:allmulticast-on @code{#f}] [#:allmulticast-off @code{#f}] @
[#:promisc-on @code{#f}] [#:promisc-off @code{#f}] [#:trailers-on @code{#f}] @
[#:trailers-off @code{#f}] [#:carrier-on @code{#f}] [#:carrier-off @code{#f}] @
[#:txqueuelen @code{#f}] [#:name @code{#f}] [#:address @code{#f}] @
[#:broadcast @code{#f}] [#:mtu @code{#f}] [#:netns @code{#f}]
Modify an existing link and set its flags and attributes to the ones specified
by the various keywords. When a keyword is omited, the corresponding attribute
is not changed.
@var{device} can be a device index (as a number) or a device name (as a string).
Do not set @code{#:up} and @code{#:down} at the same time. Do not set
@code{*-on} and @code{*-off} at the same time.
@end deffn
@deffn {Scheme Procedure} link-show [#:device @code{#f}] [#:group @code{#f}] @
[#:up @code{#f}] [#:master @code{#f}] [#:vrf @code{#f}] [#:type @code{#f}]
Print the set of devices on standard output. Setting any of the keyword to a
non-false value will filter the results to only show results that match the
corresponding value. You may set more than one keyword.
@end deffn
@deffn {Scheme Procedure} link-add @var{name} @var{type} [#:type-args @code{'()}]
Add a new link with given name and type. Additional arguments can be passed to
control the state of the link at creation. @var{type-args} is an association
list containing additional values for the given type.
When @var{type} is @code{"vlan"}, @var{type-args} can contain a number associated
with @code{'id}: the VLAN id to be created and a link name associated with
@code{"link"}: the name of the link on which the vlan is created.
The following is an example in which we create a new vlan link:
@example
;; same as "ip l add link eth0 name eth0.7 type vlan id 7"
(link-add "eth0.7" "vlan" #:type-args '((id . 7) (link . "eth0")))
@end example
When @var{type} is @code{"veth"}, @var{type-args} can contain a string associated
with @code{'peer}: the name of the peer.
The following is an example in which we create a new veth (virtual ethernet)
pair and give them a name:
@example
;; same as "ip l add v0p0 type veth peer v0p1"
(link-add "v0p0" "veth" #:type-args '((peer . "v0p1")))
@end example
@end deffn
@deffn {Scheme Procedure} link-del @var{device}
Delete a link. @var{device} can contain the name of the link, as a string,
or its index, as a number.
@end deffn
@node Addr
@section Addr
The @code{(ip addr)} module introduces procedures to access and modify the
network addresses on your machine. They are equivalent to the @command{ip addr}
family of commands, from @code{iproute2}.
@deffn {Scheme Procedure} addr-add @var{device} @var{cidr} [@var{#:ipv6?} #f] @
[@var{#:peer} @code{(cidr->addr cidr)}] [@var{#:broadcast} #f] @
[@var{#:anycast} #f] [@var{#:label} #f] [@var{#:scope} @code{'global}] @
[@var{#:metric} #f] [@var{#:home?} #f] [@var{#:mngtmpaddr?} #f] @
[@var{#:nodad?} #f] [@var{optimistic?} #f] [@var{noprefixroute?} #f] @
[@var{#:autojoin?} #f]
Add the address given in @var{cidr} to @var{device}. @var{device} can
contain the name of the link, as a string, or its index, as a number.
@var{cidr} must be a string containing the address and prefix length, in
CIDR notation (@code{addr/prefix}).
@example
(addr-add "enp1s0" "192.0.2.15/24")
@end example
If you wish to add an IPv6 address instead, set @code{#:ipv6} to @code{#t},
as in the following example.
@example
(addr-add "enp1s0" "2001:db8::1a4c/64" #:ipv6? #t)
@end example
Note that using the wrong ip type with the wrong value for the @code{#:ipv6?}
flag will result in a @code{Bad address} exception from inet-pton.
Additional flags are available; they follow the same semantics as Iproute2.
For pointopoint interfaces, you can specify the address of the remote endpoint
with @var{#:peer}. You can specify a broadcast or anycast address with
@var{#:broadcast} and @var{#:anycast}. All three require an IP address passed
as a string when specified.
You can specify a label for the address with @var{#:label}. The parameter must
be a string that is either the name of the device, or starts with the name of
the device, followed by a colon and must contain at most 15 characters.
You can specify a scope with @var{#:scope}, whose value is either @code{'global},
@code{'link}, @code{'host} or a numeric value.
You can specify the priority of the prefix route associated with this address
using @code{#:metric}, a number.
Finally, this procedures accepts address configuration flags, whose values are
booleans. They are unset by default. Some flags only work for IPv6 addresses,
those are @var{#:home?} to designate this address as the ``home address'',
@var{#:mngtmpaddr?}, @var{#:nodad?} and @var{#:optimistic?}. The flags
@var{#:noprefixroute?} and @var{#:autojoin?} can be set for IPv4 and IPv6
addresses.
@end deffn
@deffn {Scheme Procedure} addr-del @var{device} @var{cidr} [@var{#:ipv6?} #f] @
[@var{#:peer} @code{(cidr->addr cidr)}] [@var{#:broadcast} #f] @
[@var{#:anycast} #f] [@var{#:label} #f] [@var{#:scope} @code{'global}] @
[@var{#:metric} #f] [@var{#:home?} #f] [@var{#:mngtmpaddr?} #f] @
[@var{#:nodad?} #f] [@var{optimistic?} #f] [@var{noprefixroute?} #f] @
[@var{#:autojoin?} #f]
Delete the address given in @var{cidr} from @var{device}. @var{device} can
contain the name of the link, as a string, or its index, as a number.
@var{cidr} must be a string containing the address and prefix length, in
CIDR notation (@code{addr/prefix}).
@example
(addr-del "enp1s0" "192.0.2.15/24")
@end example
If you wish to remove an IPv6 address instead, set @code{#:ipv6} to @code{#t},
as in the following example.
@example
(addr-del "enp1s0" "2001:db8::1a4c/64" #:ipv6? #t)
@end example
Note that using the wrong ip type with the wrong value for the @code{#:ipv6?}
flag will result in a @code{Bad address} exception from inet-pton.
Additional flags are available, see the description in @code{addr-add} for more
details.
@end deffn
@deffn {Scheme Procedure} addr-show [@var{device}]
Print the list of addresses for each device on standard output. Setting
@code{device} to a link name or link identifier will restrict the output
to addresses of that device.
@end deffn
@node Route
@section Route
The @code{(ip route)} module introduces procedures to access and modify the
network routes on your machine. They are equivalent to the @command{ip route}
family of commands, from @code{iproute2}.
@deffn {Scheme Procedure} route-add @var{dest} [@var{#:ipv6?} #f] @
[@var{#:device} #f] [@var{#:table} RT_TABLE_MAIN] [@var{#:protocol} #f] @
[@var{#:scope} RT_SCOPE_LINK] [@var{#:type} RTN_UNICAST] @
[@var{#:priority} #f] [@var{#:src} #f] [@var{#:via} #f]
Add the route described by the argmuents. @var{dest} is the destination network,
in cidr notation (@code{addr/prefix}) or the string @code{"default"}.
@var{#:device} is the name or index of a network link. @var{#:table} is the
index of a routing table, one of @code{RT_TABLE_COMPAT}, @code{RT_TABLE_DEFAULT},
@code{RT_TABLE_MAIN} or @code{RT_TABLE_LOCAL}, as defined in
@code{(netlink constant)}.
If it is set, @var{#:protocol} must be the routing protocol, @code{RTPROT_*},
as defined in @code{(netlink constant)}.
@var{#:scope} must be the scope of the route, one of @code{RT_SCOPE_*}, as
defined in @code{(netlink constant)}.
@var{#:type} must be the type of route, one of @code{RTN_*}, as defined in
@code{(netlink constant)}.
If set, @var{#:priority} is a number specifying the priority of the rule
when the kernel is looking for a matching rule. This is also known as the
metric of the route.
If set, @var{#:src} is the source address in cidr notation, or as a single
address.
If set, @var{#:via} is the gateway address. This is not in cidr notation, as
the gateway is a single address, not a network.
@example
(route-add "default" #:device "enp1s0" #:via "192.0.2.1")
(route-add "192.0.2.0/24" #:device "enp1s0" #:src "192.0.2.15")
@end example
If you wish to add an IPv6 route instead, set @code{#:ipv6} to @code{#t},
as in the following example.
@example
(addr-add "2001:db8::/64" #:device "enp1s0" #:src "2001:db8::1a4c" #:ipv6? #t)
@end example
Note that using the wrong ip type with the wrong value for the @code{#:ipv6?}
flag will result in a @code{Bad address} exception from inet-pton.
@end deffn
@deffn {Scheme Procedure} route-del @var{dest} [@var{#:ipv6?} #f] @
[@var{#:device} #f] [@var{#:table} RT_TABLE_MAIN] [@var{#:protocol} #f] @
[@var{#:scope} #f] [@var{#:type} #f] [@var{#:priority} #f] @
[@var{#:src} #f] [@var{#:via} #f]
Delete the route given in arguments. The arguments follow the same structure
as @code{route-add}. By specifying more arguments, you can narrow down the
search for the rule to delete further. Each call will only remove one route,
so being more precise ensures you target the rule you wish to delete. It
is not clear which route is deleted if multiple routes match your query.
@end deffn
@deffn {Scheme Procedure} route-show [@var{#:table} RT_TABLE_MAIN] @
[@var{#:family} AF_UNSPEC]
Print the list of routes on standard output. Note that, contrary to
@command{ip route show}, we show both IPv4 and IPv6 routes. To narrow down the
number of routes displayed, you can specify the family as in this example.
@example
(route-show #:family AF_INET6)
@end example
@end deffn
@node ACPI API
@chapter ACPI API
@cindex high-level
@cindex read-selector procedure
@cindex process-data procedure
@cindex close-connection procedure
This chapter describes the high-level procedures contained in the
@code{(netlink acpi)} module that let you monitor the kernel for ACPI event
notifications. At top level, the requirement is to connect to the kernel's
netlink system, and then you receive three procedures for handling
notifications on the connection. The first, nominally called
@code{(read-selector)}, provides a file descriptor which you can use in a
@code{select} read-list to wait for a notification to become available on the
connection.
Once you know that data are there waiting to be read, you use the second
provided procedure: @code{(process-data @var{action})}, where the @var{action}
you supply must be a procedure which takes in an @code{event} object, and does
whatever the application needs to do. Data can be extracted from this object
with @code{event-device-class}, @code{event-bus-id}, @code{event-kind} and
@code{event-data}.
When all is done, the connection should be closed with a call to the third
provided function: @code{(close-connection)}.
@menu
* ACPI example::
* ACPI reference::
@end menu
@node ACPI example
@section acpi-listener example
@cindex acpi-listener application
@cindex ACPI example usage
The following code snippet is the heart of the acpi-listener application
distributed with guile-netlink. When you run the command at the command line
(it takes no arguments), it will sit there silently and forever, waiting for
an ACPI event to happen (perhaps you can put your computer to suspended sleep
and then re-awaken it), at which time a message will be printed with the data
of that event.
@lisp
;; Use guile-netlinkʼs ACPI interface. The use of a prefix is discretionary;
;; it is useful to have in example code.
(use-modules ((netlink acpi) #:prefix ACPI::))
(define (action event) ;; [1]
((@@ (ice-9 format) format)
#t
"device: ~20a, bus ID: ~15a, type: ~8,'0x, data: ~8,'0x\n"
(ACPI::event-device-class event)
(ACPI::event-bus-id event)
(ACPI::event-kind event)
(ACPI::event-data event)))
((@@ (ice-9 receive) receive)
(ACPI::read-selector ACPI::process-events ACPI::close-connection) ;; [3]
(ACPI::connect-events) ;; [2]
(let loop () ;; [4]
(select (list (ACPI::read-selector)) '() '())
(ACPI::process-events action)
(loop))
(ACPI::close-connection)) ;; [5]
@end lisp
The action we take on receiving events is defined as @code{action} [1], and
simply writes the data elements of the @var{event} to the command-line.
The connection to the kernel is made with the @code{ACPI::connect-events} [2]
procedure call, which gives us the @code{ACPI::read-selector},
@code{ACPI::process-events} and @code{ACPI::close-connection} [3] procedures
for managing the connection.
We then simply go into a tight loop [4] waiting for data, and processing that
when it comes in.
If, by some unattainable miracle, we get out of that loop and want to stop
monitoring for kernel events, we can call the @code{ACPI::close-connection}
procedure [5].
@node ACPI reference
@section ACPI reference
The following procedures are available in the @code{(netlink acpi)} module.
@deffn {Scheme Procedure} connect-events
Open a connection to the kernel, and set it up to listen for ACPI event
notifications. The procedure returns three new procedures for managing this
connection: @dfn{read-selector} which returns a file descriptor which can be
passed to the @code{select} procedure to wait for data from the kernel,
@dfn{process-data @var{action}} which reads and evaluates the data, and calls
@code{ACTION @var{event}} on it, and finally @dfn{close-connection} which will
terminate the connection with the kernel.
@end deffn
@deffn {Scheme Procedure} event-display-class @var{event}
Extract the display class from the @var{event}. This will be a string.
@end deffn
@deffn {Scheme Procedure} event-bus-id @var{event}
Extract the bus-id from the @var{event}, again a string.
@end deffn
@deffn {Scheme Procedure} event-kind @var{event}
Extract the type of the @var{event}, a number, nominally unsigned 32 bit.
@end deffn
@deffn {Scheme Procedure} event-data @var{event}
Extract the data from the @var{event}, a number, also nominally unsigned 32
bit.
@end deffn
@node API Reference
@chapter Low-Level API Reference
@menu
* Common API::
* Netlink API::
* Rtnetlink API::
@end menu
@node Common API
@section Common API
Guile-netlink implements a common API for expressing other protocols. This
section describes how to use this API to augment guile-netlink with additional
protocols.
@menu
* Data Types::
* Constants::
* Netlink Connections::
@end menu
@node Data Types
@subsection Data Types
Guile-netlink defines data types that are used in the various Netlink protocols.
We need to be able to serialize and deserialize data that guile-netlink
understands, but we also want to let users of guile-netlink extend this process
easily. This need has lead to the creating of the following data structure,
defined in @code{(netlink data}).
@deffn {Datatype} nl-data
@table @asis
@item @code{data}
The data that is held by this record.
@item @code{size-proc}
A procedure that takes a data (of the same type as the data recorded in the
@code{data} field) and returns the size of its serialization.
@item @code{serialization-proc}
A procedure that takes a data (of the same type as the data recorded in the
@code{data} field), the position at which to start serializing, and a
bytevector in which to serialize. This procedure should modify the bytevector
and its return value is ignored.
@end table
@end deffn
The module also defines the following function, that takes a @code{nl-data}
structure and provides its serialization in a bytevector:
@deffn {Scheme Procedure} serialize @var{data} @var{pos} @var{bv}
Takes a @code{nl-data} structure as @var{data}, a position @var{pos} in
the bytevector @var{bv}, and returns an unspecified value.
This function updates the bytevector and adds the serialization of @var{data}
into @var{bv} at @var{pos}.
@end deffn
By providing a @code{nl-data} structure, we defer the knowledge of how to
serialize the data to the structure itself, instead of the @code{serialize}
function. This allows for more flexibility and extensibility, as the user
of the procedure can pass any kind of data, even if it is not yet supported by
guile-netlink.
Similarly, we need to be able to deserialize netlink answers into a data
structure. To do so, we also defer the knowledge of the datastructure to
deserialize to, to a decoder structure that is passed to the deserialization
procedure. @code{(netlink data)} also defines the following procedures to
deserialize data:
@deffn {Scheme Procedure} deserialize @var{type} @var{decoder} @var{bv} @var{pos}
Takes a bytevector @var{bv} and starts deserializing the data starting at
position @var{pos}. To do so, it uses the @var{type} variable as the lookup
key in the @var{decoder}. @var{type} is a symbol that represents the type of
data to deserialize to.
The decoder is a structure that associates each known type to its deserializer
(a function that takes a decoder, a bytevector and a position and returns some
data) and an alist that associates a type (an integer, as returned by the
protocol in use) to the proper decoder of that type.
@end deffn
@deffn {Scheme Procedure} get-current-deserialize @var{decoder} @var{current-type}
Takes a decoder and a type, and returns the deserialization procedure associated
with the type (a symbol) in @var{decoder}.
@end deffn
@deffn {Scheme Procedure} get-next-deserialize @var{decoder} @var{current-type} @
@var{target-type}
Takes a decoder, a type (a symbol that represents the type of data being
deserialized) and another type (an integer as returned by the protocol), and
returns the deserialization procedure needed to continue decoding the data
associated with the currently being deserialized data.
For example, when decoding an answer in the netlink protocol, we first deserialize
the header into a @code{message} structure. That header contains a type field
that contains an integer constant representing the type of data of the body.
Similarly, when deserializing a routing attribute in the rtnetlink protocol,
we first find a header of the attribute that defines an integer constant
corresponding to the type of attribute in the body.
By knowing the context in which the type is declared, this procedure can return
the correct deserializing procedure. For instance, when deserializing a
@code{message}, type @code{16} means @code{RTM_NEWLINK} in the rtnetlink
protocol, whereas it means @code{IFLA_OPERSTATE} when deserializing a
@code{route-attribute}.
@end deffn
guile-netlink provides the following default decoder for the rtnetlink
protocol in @code{(netlink deserialize)}:
@deffn {Scheme Variable} %default-route-decoder
Contains the default decoder for the NETLINK_ROUTE protocol.
@end deffn
For convenience, guile-netlink defines the following structures that can be used
to create a custom decoder.
@deffn {Scheme Variable} %default-message-decoder
Contains the default association list for the common message types of netlink,
associating each of them to a deserialization procedure.
@end deffn
@deffn {Scheme Procedure} default-route-attr-decoder @var{deserialize-addr}
Creates the default association list for a route protocol, given the specified
address deserializer. This is useful because the @code{IFA_ADDRESS},
@code{IFA_BROADCAST}, etc, contain a different type of address depending on
the message type or its header. This is defined an @code{(netlink route attrs)}
and used by the following variables:
@end deffn
@deffn {Scheme Variable} %default-route-link-attr-decoder
Contains the default association list for the known types of routing attributes
for link messages. This list is defined in @code{(netlink route attrs)}.
@end deffn
@node Constants
@subsection Constants
Guile-netlink defines constants used by the Netlink protocols in the
@code{(netlink constant)} module. The constants are the ones present in the
kernel and are too numerous to list here. Please see the source for the
complete list.
The module also defines the following macro:
@deffn {Scheme Macro} define-enum @var{integer->symbol} @var{name-spec} ...
This macros defines an enumeration. @var{integer->symbol} is the name of
a procedure that is publicly defined, that takes an integer and returns the
associated symbol in the enumeration.
The macro also publicly defines variables whose names are in @var{name-spec}
to an integer.
A @var{name-spec} is either a single name, and the associated value is 0 for
the first @var{name-spec}, or one more than the previous @var{name-spec}.
It can also be a pair of a name and an integer, in which case the associated
value is that integer. For instance:
@example
(define-enum get-foo FOO0 FOO1 (FOO10 10) FOO11 FOO12)
(get-foo 9) -> #
(get-foo 0) -> FOO0
FOO11 -> 11
@end example
@end deffn
@node Netlink Connections
@subsection Netlink Connections
The @code{(netlink connection)} module defines the following procedures, used
to connect and communicate with another process or the kernel using a netlink
socket.
@deffn {Scheme Procedure} get-addr @var{family} @var{pid} @var{groups}
Return a bytevector that represents a netlink address. @var{family}
should be @code{AF_NETLINK}, @var{pid} is the PID of the process with which
to communicate or 0 for the kernel. @var{groups} is an integer representing
the set of broadcast groups to which the connection subscribes.
@end deffn
@cindex non-blocking socket
@deffn {Scheme Procedure} connect @var{proto} @var{addr} [#:flags 0]
Creates a netlink socket for @var{proto} and binds it to @var{addr}.
@var{proto} is the integer representing the protocol. For instance, rtnetlink
can be selected by usin @code{NETLINK_ROUTE} (defined in
@code{(netlink constant)}).
@var{addr} is a bytevector, as returned by @code{get-addr}.
@var{flags} is a set of additional flags to pass as the second argument
to the @code{socket} system call---e.g., @code{SOCK_NONBLOCK}.
@end deffn
@deffn {Scheme Procedure} connect-route [#:groups 0] [#:flags 0]
This procedure is a wrapper for @code{connect} that creates a socket for the
rtnetlink protocol, binds it to the kernel and returns it. By passing the
optional @var{groups} keyword, you can select broadcast groups to subscribe to.
@var{flags} is a set of additional flags to pass as the second argument
to the @code{socket} system call---e.g., @code{SOCK_NONBLOCK}.
@end deffn
@cindex subscribing, to an rtnetlink group
@deffn {Scheme Procedure} add-socket-membership @var{sock} @var{group}
Make @var{sock} a member of @var{group}, an @code{RTNLGRP_} constant,
meaning that it will be subscribed to events of that group.
For example, here is how you could create a netlink socket and subscribe
it to the ``link'' group so that it receives notifications for new and
removed links:
@lisp
(let ((sock (connect-route)))
(add-socket-membership sock RTNLGRP_LINK)
@dots{})
@end lisp
This procedure is implemented as a @code{setsockopt} call.
@end deffn
@deffn {Scheme Procedure} send-msg @var{msg} @var{sock} [#:@var{addr}]
Send @var{msg} (it must be of type message, @xref{Netlink Headers}) to
@var{addr} using @var{sock}. If not passed, @var{addr} is the address of
the kernel.
@end deffn
@deffn {Scheme Procedure} receive-msg @var{sock} [#:@var{addr}]
Receives a message from @var{sock} from @var{addr}. This procedure is blocking.
If not passed, @var{addr} defaults to the address of the kernel. This
procedure returns the message as a bytevector, that you can deserialize with
@code{deserialize} (@xref{Data Types})
@end deffn
@deffn {Scheme Procedure} receive-and-decode-msg @var{sock} @var{decoder} @
[#:@var{addr}]
Receives one or more messages from @var{sock} from @var{addr}. this procedure
is blocking. If not passed, @var{addr} defaults to the address of the kernel.
This procedure returns a list of messages that were decoded using @var{decoder}.
When the answer has the @code{NLM_F_MULTI} flag, this procedure decodes the next
message, until it receives a @code{NLMSG_DONE} message. It returns the list
of every netlink messages it received, including the @code{NLMSG_DONE}.
@end deffn
@node Netlink API
@section Netlink API
This section introduces the data structures used for all the netlink protocols.
First, we introduce the structure of a netlink message, then we present the
standard types of netlink messages, that can be used with every protocol.
@menu
* Netlink Headers::
* Standard Message Types::
@end menu
@node Netlink Headers
@subsection Netlink Headers
The @code{(netlink message)} module defines the message structure that contains
a netlink message. It is composed of a header and a body, and is the data
structure to pass to @code{send-msg} (@xref{Netlink Connections}).
This module defines the following data structure:
@deffn {Datatype} message
@table @asis
@item @code{type}
The type of data in the body of the message. For instance, @code{RTM_GETLINK}.
@item @code{flags}
The set of flags that are set in the header. For instance,
@code{(logior NLM_F_REQUEST NLM_F_DUMP)}.
@item @code{seq}
The sequence number of the message. If this message is an answer to a request,
it must keep the same sequence number. Otherwise, you must generate a new and
unique sequence number, to track the answers.
@item @code{pid}
The PID of the receiving process, or 0 for the kernel.
@item @code{data}
The actual body, as an @code{nl-data} structure.
@end table
@end deffn
@node Standard Message Types
@subsection Standard Message Types
The @code{(netlink standard)} module defines the set of standard message types
and their data type.
@deffn {Datatype} error-message
@table @asis
@item @code{err}
The error code, as a negative number.
@item @code{hdr}
The message on which this error applies.
@end table
@deffn {Scheme Variable} no-data
This variable defines the absence of data. This is useful when a structure
is expecting a body part, but the protocol specifically defines that it should
not take any data in some cases. For instance, a @code{NLMSG_NOOP} message
takes no data, so the @code{data} field of the message will contain this
@code{no-data} value.
@end deffn
@end deffn
@node Rtnetlink API
@section Rtnetlink API
@cindex rtnetlink
@cindex ROUTE_NETLINK
This section describes the support for rtnetlink in guile-netlink. Rtnetlink
is the protocol responsible for everything related to network routing. It
allows you to manage links, addresses, routing tables, neighbor chaces,
routing rules, queueing disciplines, traffic classes, traffic filters and
more.
@menu
* Routing Attributes::
* Link Messages::
* Address Messages::
@end menu
@node Routing Attributes
@subsection Routing Attributes
The @code{(netlink route attrs)} module defines the following data types:
@deffn {Datatype} route-attr
This defines a header structure for the attribute, as well as its body.
@table @asis
@item @code{type}
This is the type of the attribute, for instance @code{IFLA_ADDRESS}.
@item @code{data}
This is the body of the attribute, ie.@: its value.
@end table
@end deffn
The module also defines additional data types that are not represented as
a record, but by a simple type. For each of the following types, there is
a @code{make-*-route-attr} procedure to produce a @code{nl-data} value
for this type. There is also @code{deserialize-route-attr-data-*} procedure
to deserialize a value of this type.
@table @asis
@item @code{u8}
A one-byte unsigned integer
@item @code{u16}
A two-bytes unsigned integer
@item @code{u32}
A four-bytes unsigned integer
@item @code{s32}
A four-bytes signed integer
@item @code{string}
A string
@item @code{ethernet}
An ethernet address. Its value is a string that represents that address,
for instnace @code{"01:23:45:67:89:ab"}
@item @code{ipv4}
An IPv4 address. Its value is a string that represents that address,
for instnace @code{"192.0.2.152"}
@item @code{ipv6}
An IPv6 address. Its value is a string that represents that address,
for instnace @code{"2001:db8::0123:4567:89ab:cdef"}
@item @code{bv}
A bytevector. This is used by default when the type is not supported.
@end table
@node Link Messages
@subsection Link Messages
The @code{(netlink route link)} package defines the following data type:
@deffn {Datatype} link-message
This datatype represents a link message with its routing attributes. This type
of message is expected when using the @var{RTM_*LINK} message types.
@table @asis
@item @code{family}
The network family, defined as @code{AF_UNSPEC} in the rtnetlink documentation,
although it holds different values in practice.
@item @code{type}
The device type.
@item @code{index}
The index of the device. This is used to select a specific device by its index,
or 0 to not filter by device index.
@item @code{flags}
The device flags. See @code{man 7 netdevices} for a list.
@item @code{attrs}
A list of attributes. This field must contain a list of @code{nl-data}
structures, not a structure by itself.
@end table
@end deffn
@node Address Messages
@subsection Address Messages
The @code{(netlink route addr)} package defines the following data type:
@deffn {Datatype} addr-message
This datatype represents an address message with its routing attributes. This
type of message is expected when using the @var{RTM_*ADDR} message types.
@table @asis
@item @code{family}
The network family, either @code{AF_INET} for IPv4 addresses, or @code{AF_INET6}
for IPv6 addresses.
@item @code{prefix-len}
The prefix length, i.e.@: the length of the prefix mask, in bits, if defined
for the address family.
@item @code{flags}
Address flags. This can be a flag word of @code{IFA_F_SECONDARY} for secondary
address (old alias interface), @code{IFA_F_PERMANENT} for a permanent
address set by the user and other undocumented flags.
@item @code{scope}
The address scope.
@item @code{index}
The index of the device this address is for.
@item @code{attrs}
A list of attributes. This field must contain a list of @code{nl-data}
structures, not a structure by itself.
@end table
@end deffn
@c *********************************************************************
@node Concept Index
@unnumbered Concept Index
@printindex cp
@node Programming Index
@unnumbered Programming Index
@syncodeindex tp fn
@syncodeindex vr fn
@printindex fn
@bye