mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
networkd: smooth transition from ipv4ll to dhcp address
Currently when both ipv4ll and dhcp are enabled, ipv4ll address (if one has been claimed) is removed when dhcp address is aquired. This is not the best thing to do since there might be clients unaware of the removal trying to communicate. This patch provides a smooth transition between ipv4ll and dhcp. If ipv4ll address was claimed [1] before dhcp, address is marked as deprecated. Deprecated address is still a valid address and packets can be received on it but address cannot be selected as a source address. If dhcp lease cannot be extended, then ipv4ll address is marked as valid again. [1] If there is no collision, claiming IPv4LL takes between 4 to 7 seconds.
This commit is contained in:
parent
3e790eae01
commit
aba496a58a
1
TODO
1
TODO
@ -665,7 +665,6 @@ Features:
|
||||
- add reduced [Link] support to .network files
|
||||
- add IPv4LL tests (inspire by DHCP)
|
||||
- add Scope= parsing option for [Network]
|
||||
- have smooth transition from LL to routable address, without disconnecting clients.
|
||||
|
||||
* sd-network:
|
||||
- make sure ipv4ll and dhcp clients can handle changing mac addresses while running
|
||||
|
@ -192,8 +192,9 @@
|
||||
<term><varname>IPv4LL=</varname></term>
|
||||
<listitem>
|
||||
<para>A boolean. When true, enables IPv4 link-local support.
|
||||
If <literal>DHCP=</literal> is also true, IPv4 link-local
|
||||
address will be removed upon acquiring a DHCP lease.
|
||||
If <literal>DHCP=</literal> is also true, acquiring DHCP address
|
||||
will deprecate previously acquired IPv4 link-local address or
|
||||
stop acquiring process if there hasn't been one acquired before.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -481,6 +481,12 @@ error:
|
||||
return r;
|
||||
}
|
||||
|
||||
bool sd_ipv4ll_is_running(sd_ipv4ll *ll) {
|
||||
assert_return(ll, -EINVAL);
|
||||
|
||||
return ll->state != IPV4LL_STATE_INIT;
|
||||
}
|
||||
|
||||
#define HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
|
||||
|
||||
int sd_ipv4ll_start (sd_ipv4ll *ll) {
|
||||
|
@ -286,6 +286,19 @@ int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret,
|
||||
int index, unsigned char family) {
|
||||
int r;
|
||||
|
||||
r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd_rtnl_message *sd_rtnl_message_ref(sd_rtnl_message *m) {
|
||||
if (m)
|
||||
assert_se(REFCNT_INC(m->n_ref) >= 2);
|
||||
@ -559,6 +572,24 @@ int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info) {
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(!m->sealed, -EPERM);
|
||||
assert_return(info, -EINVAL);
|
||||
|
||||
r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = add_rtattr(m, type, info, sizeof(struct ifa_cacheinfo));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type) {
|
||||
size_t size;
|
||||
int r;
|
||||
@ -741,6 +772,25 @@ int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, str
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info) {
|
||||
int r;
|
||||
void *attr_data;
|
||||
|
||||
r = message_attribute_has_type(m, type, NLA_CACHE_INFO);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = rtnl_message_read_internal(m, type, &attr_data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
else if ((size_t)r < sizeof(struct ifa_cacheinfo))
|
||||
return -EIO;
|
||||
|
||||
memcpy(info, attr_data, sizeof(struct ifa_cacheinfo));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data) {
|
||||
int r;
|
||||
void *attr_data;
|
||||
|
@ -216,9 +216,9 @@ static const NLType rtnl_address_types[IFA_MAX + 1] = {
|
||||
[IFA_LOCAL] = { .type = NLA_IN_ADDR },
|
||||
[IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 },
|
||||
[IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */
|
||||
[IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
|
||||
/*
|
||||
[IFA_ANYCAST],
|
||||
[IFA_CACHEINFO] = { .len = sizeof(struct ifa_cacheinfo) },
|
||||
[IFA_MULTICAST],
|
||||
*/
|
||||
#ifdef IFA_FLAGS
|
||||
|
@ -31,6 +31,7 @@ enum {
|
||||
NLA_STRING,
|
||||
NLA_IN_ADDR,
|
||||
NLA_ETHER_ADDR,
|
||||
NLA_CACHE_INFO,
|
||||
NLA_NESTED,
|
||||
NLA_UNION,
|
||||
};
|
||||
|
@ -106,6 +106,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) {
|
||||
sd_rtnl_message *m;
|
||||
sd_rtnl_message *r;
|
||||
struct in_addr in_data;
|
||||
struct ifa_cacheinfo cache;
|
||||
char *label;
|
||||
|
||||
assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0);
|
||||
@ -116,6 +117,7 @@ static void test_address_get(sd_rtnl *rtnl, int ifindex) {
|
||||
assert_se(sd_rtnl_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0);
|
||||
assert_se(sd_rtnl_message_read_in_addr(r, IFA_ADDRESS, &in_data) == 0);
|
||||
assert_se(sd_rtnl_message_read_string(r, IFA_LABEL, &label) == 0);
|
||||
assert_se(sd_rtnl_message_read_cache_info(r, IFA_CACHEINFO, &cache) == 0);
|
||||
|
||||
assert_se(sd_rtnl_flush(rtnl) >= 0);
|
||||
assert_se((m = sd_rtnl_message_unref(m)) == NULL);
|
||||
|
@ -28,6 +28,15 @@
|
||||
#include "conf-parser.h"
|
||||
#include "network-internal.h"
|
||||
|
||||
static void address_init(Address *address) {
|
||||
assert(address);
|
||||
|
||||
address->family = AF_UNSPEC;
|
||||
address->scope = RT_SCOPE_UNIVERSE;
|
||||
address->cinfo.ifa_prefered = CACHE_INFO_INFINITY_LIFE_TIME;
|
||||
address->cinfo.ifa_valid = CACHE_INFO_INFINITY_LIFE_TIME;
|
||||
}
|
||||
|
||||
int address_new_static(Network *network, unsigned section, Address **ret) {
|
||||
_cleanup_address_free_ Address *address = NULL;
|
||||
|
||||
@ -46,8 +55,7 @@ int address_new_static(Network *network, unsigned section, Address **ret) {
|
||||
if (!address)
|
||||
return -ENOMEM;
|
||||
|
||||
address->family = AF_UNSPEC;
|
||||
address->scope = RT_SCOPE_UNIVERSE;
|
||||
address_init(address);
|
||||
|
||||
address->network = network;
|
||||
|
||||
@ -71,8 +79,7 @@ int address_new_dynamic(Address **ret) {
|
||||
if (!address)
|
||||
return -ENOMEM;
|
||||
|
||||
address->family = AF_UNSPEC;
|
||||
address->scope = RT_SCOPE_UNIVERSE;
|
||||
address_init(address);
|
||||
|
||||
*ret = address;
|
||||
address = NULL;
|
||||
@ -140,6 +147,87 @@ int address_drop(Address *address, Link *link,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int address_update(Address *address, Link *link,
|
||||
sd_rtnl_message_handler_t callback) {
|
||||
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
|
||||
int r;
|
||||
|
||||
assert(address);
|
||||
assert(address->family == AF_INET || address->family == AF_INET6);
|
||||
assert(link->ifindex > 0);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
|
||||
r = sd_rtnl_message_new_addr_update(link->manager->rtnl, &req,
|
||||
link->ifindex, address->family);
|
||||
if (r < 0) {
|
||||
log_error("Could not allocate RTM_NEWADDR message: %s",
|
||||
strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
|
||||
if (r < 0) {
|
||||
log_error("Could not set prefixlen: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_addr_set_flags(req, IFA_F_PERMANENT);
|
||||
if (r < 0) {
|
||||
log_error("Could not set flags: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_addr_set_scope(req, address->scope);
|
||||
if (r < 0) {
|
||||
log_error("Could not set scope: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (address->family == AF_INET)
|
||||
r = sd_rtnl_message_append_in_addr(req, IFA_LOCAL, &address->in_addr.in);
|
||||
else if (address->family == AF_INET6)
|
||||
r = sd_rtnl_message_append_in6_addr(req, IFA_LOCAL, &address->in_addr.in6);
|
||||
if (r < 0) {
|
||||
log_error("Could not append IFA_LOCAL attribute: %s",
|
||||
strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
if (address->family == AF_INET) {
|
||||
r = sd_rtnl_message_append_in_addr(req, IFA_BROADCAST, &address->broadcast);
|
||||
if (r < 0) {
|
||||
log_error("Could not append IFA_BROADCAST attribute: %s",
|
||||
strerror(-r));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (address->label) {
|
||||
r = sd_rtnl_message_append_string(req, IFA_LABEL, address->label);
|
||||
if (r < 0) {
|
||||
log_error("Could not append IFA_LABEL attribute: %s",
|
||||
strerror(-r));
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_append_cache_info(req, IFA_CACHEINFO, &address->cinfo);
|
||||
if (r < 0) {
|
||||
log_error("Could not append IFA_CACHEINFO attribute: %s",
|
||||
strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_rtnl_call_async(link->manager->rtnl, req, callback, link, 0, NULL);
|
||||
if (r < 0) {
|
||||
log_error("Could not send rtnetlink message: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int address_configure(Address *address, Link *link,
|
||||
sd_rtnl_message_handler_t callback) {
|
||||
_cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL;
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
#include "dhcp-lease-internal.h"
|
||||
|
||||
static int ipv4ll_address_update(Link *link, bool deprecate);
|
||||
static bool ipv4ll_is_bound(sd_ipv4ll *ll);
|
||||
|
||||
int link_new(Manager *manager, struct udev_device *device, Link **ret) {
|
||||
_cleanup_link_free_ Link *link = NULL;
|
||||
const char *ifname;
|
||||
@ -168,7 +171,6 @@ static int route_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
|
||||
static int link_enter_set_routes(Link *link) {
|
||||
Route *rt;
|
||||
struct in_addr a;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -178,7 +180,7 @@ static int link_enter_set_routes(Link *link) {
|
||||
link->state = LINK_STATE_SETTING_ROUTES;
|
||||
|
||||
if (!link->network->static_routes && !link->dhcp_lease &&
|
||||
(!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
|
||||
(!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
|
||||
return link_enter_configured(link);
|
||||
|
||||
log_debug_link(link, "setting routes");
|
||||
@ -345,7 +347,6 @@ static int address_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
|
||||
static int link_enter_set_addresses(Link *link) {
|
||||
Address *ad;
|
||||
struct in_addr a;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -355,7 +356,7 @@ static int link_enter_set_addresses(Link *link) {
|
||||
link->state = LINK_STATE_SETTING_ADDRESSES;
|
||||
|
||||
if (!link->network->static_addresses && !link->dhcp_lease &&
|
||||
(!link->ipv4ll || sd_ipv4ll_get_address(link->ipv4ll, &a) < 0))
|
||||
(!link->ipv4ll || ipv4ll_is_bound(link->ipv4ll) == false))
|
||||
return link_enter_set_routes(link);
|
||||
|
||||
log_debug_link(link, "setting addresses");
|
||||
@ -456,6 +457,28 @@ static int link_enter_set_addresses(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int address_update_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
Link *link = userdata;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
|
||||
if (link->state == LINK_STATE_FAILED)
|
||||
return 1;
|
||||
|
||||
r = sd_rtnl_message_get_errno(m);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_struct_link(LOG_WARNING, link,
|
||||
"MESSAGE=%s: could not update address: %s",
|
||||
link->ifname, strerror(-r),
|
||||
"ERRNO=%d", -r,
|
||||
NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int address_drop_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
|
||||
Link *link = userdata;
|
||||
int r;
|
||||
@ -753,7 +776,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
|
||||
static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
Link *link = userdata;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
@ -792,7 +815,10 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
}
|
||||
|
||||
if (event == DHCP_EVENT_EXPIRED && link->network->ipv4ll) {
|
||||
r = sd_ipv4ll_start (link->ipv4ll);
|
||||
if (!sd_ipv4ll_is_running(link->ipv4ll))
|
||||
r = sd_ipv4ll_start(link->ipv4ll);
|
||||
else if (ipv4ll_is_bound(link->ipv4ll))
|
||||
r = ipv4ll_address_update(link, false);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
@ -807,7 +833,10 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
return;
|
||||
}
|
||||
if (link->ipv4ll) {
|
||||
r = sd_ipv4ll_stop(link->ipv4ll);
|
||||
if (ipv4ll_is_bound(link->ipv4ll))
|
||||
r = ipv4ll_address_update(link, true);
|
||||
else
|
||||
r = sd_ipv4ll_stop(link->ipv4ll);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
@ -825,11 +854,44 @@ static void dhcp_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
return;
|
||||
}
|
||||
|
||||
static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
|
||||
static int ipv4ll_address_update(Link *link, bool deprecate) {
|
||||
int r;
|
||||
struct in_addr addr;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
|
||||
if (r >= 0) {
|
||||
_cleanup_address_free_ Address *address = NULL;
|
||||
|
||||
log_debug_link(link, "IPv4 link-local %s %u.%u.%u.%u",
|
||||
deprecate ? "deprecate" : "approve",
|
||||
ADDRESS_FMT_VAL(addr));
|
||||
|
||||
r = address_new_dynamic(&address);
|
||||
if (r < 0) {
|
||||
log_error_link(link, "Could not allocate address: %s", strerror(-r));
|
||||
return r;
|
||||
}
|
||||
|
||||
address->family = AF_INET;
|
||||
address->in_addr.in = addr;
|
||||
address->prefixlen = 16;
|
||||
address->scope = RT_SCOPE_LINK;
|
||||
address->cinfo.ifa_prefered = deprecate ? 0 : CACHE_INFO_INFINITY_LIFE_TIME;
|
||||
address->broadcast.s_addr = address->in_addr.in.s_addr | htonl(0xfffffffflu >> address->prefixlen);
|
||||
|
||||
address_update(address, link, &address_update_handler);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int ipv4ll_address_lost(Link *link) {
|
||||
int r;
|
||||
struct in_addr addr;
|
||||
|
||||
assert(ll);
|
||||
assert(link);
|
||||
|
||||
r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
|
||||
@ -870,6 +932,18 @@ static int ipv4ll_address_lost(sd_ipv4ll *ll, Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ipv4ll_is_bound(sd_ipv4ll *ll) {
|
||||
int r;
|
||||
struct in_addr addr;
|
||||
|
||||
assert(ll);
|
||||
|
||||
r = sd_ipv4ll_get_address(ll, &addr);
|
||||
if (r < 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
|
||||
struct in_addr address;
|
||||
int r;
|
||||
@ -903,7 +977,7 @@ static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata){
|
||||
switch(event) {
|
||||
case IPV4LL_EVENT_STOP:
|
||||
case IPV4LL_EVENT_CONFLICT:
|
||||
r = ipv4ll_address_lost(ll, link);
|
||||
r = ipv4ll_address_lost(link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "set.h"
|
||||
#include "condition-util.h"
|
||||
|
||||
#define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||
|
||||
typedef struct NetDev NetDev;
|
||||
typedef struct Network Network;
|
||||
typedef struct Link Link;
|
||||
@ -150,6 +152,7 @@ struct Address {
|
||||
char *label;
|
||||
|
||||
struct in_addr broadcast;
|
||||
struct ifa_cacheinfo cinfo;
|
||||
|
||||
union {
|
||||
struct in_addr in;
|
||||
@ -335,6 +338,7 @@ int address_new_static(Network *network, unsigned section, Address **ret);
|
||||
int address_new_dynamic(Address **ret);
|
||||
void address_free(Address *address);
|
||||
int address_configure(Address *address, Link *link, sd_rtnl_message_handler_t callback);
|
||||
int address_update(Address *address, Link *link, sd_rtnl_message_handler_t callback);
|
||||
int address_drop(Address *address, Link *link, sd_rtnl_message_handler_t callback);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Address*, address_free);
|
||||
|
@ -22,6 +22,7 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
@ -42,10 +43,11 @@ int sd_ipv4ll_get_address(sd_ipv4ll *ll, struct in_addr *address);
|
||||
int sd_ipv4ll_set_callback(sd_ipv4ll *ll, sd_ipv4ll_cb_t cb, void *userdata);
|
||||
int sd_ipv4ll_set_mac(sd_ipv4ll *ll, const struct ether_addr *addr);
|
||||
int sd_ipv4ll_set_index(sd_ipv4ll *ll, int interface_index);
|
||||
int sd_ipv4ll_set_address_seed (sd_ipv4ll *ll, uint8_t seed[8]);
|
||||
int sd_ipv4ll_start (sd_ipv4ll *ll);
|
||||
int sd_ipv4ll_stop (sd_ipv4ll *ll);
|
||||
void sd_ipv4ll_free (sd_ipv4ll *ll);
|
||||
int sd_ipv4ll_new (sd_ipv4ll **ret);
|
||||
int sd_ipv4ll_set_address_seed(sd_ipv4ll *ll, uint8_t seed[8]);
|
||||
bool sd_ipv4ll_is_running(sd_ipv4ll *ll);
|
||||
int sd_ipv4ll_start(sd_ipv4ll *ll);
|
||||
int sd_ipv4ll_stop(sd_ipv4ll *ll);
|
||||
void sd_ipv4ll_free(sd_ipv4ll *ll);
|
||||
int sd_ipv4ll_new(sd_ipv4ll **ret);
|
||||
|
||||
#endif
|
||||
|
@ -68,6 +68,7 @@ int sd_rtnl_detach_event(sd_rtnl *nl);
|
||||
|
||||
/* messages */
|
||||
int sd_rtnl_message_new_link(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index);
|
||||
int sd_rtnl_message_new_addr_update(sd_rtnl *rtnl, sd_rtnl_message **ret, int index, unsigned char family);
|
||||
int sd_rtnl_message_new_addr(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t msg_type, int index,
|
||||
unsigned char family);
|
||||
int sd_rtnl_message_new_route(sd_rtnl *rtnl, sd_rtnl_message **ret, uint16_t nlmsg_type,
|
||||
@ -99,6 +100,7 @@ int sd_rtnl_message_append_u32(sd_rtnl_message *m, unsigned short type, uint32_t
|
||||
int sd_rtnl_message_append_in_addr(sd_rtnl_message *m, unsigned short type, const struct in_addr *data);
|
||||
int sd_rtnl_message_append_in6_addr(sd_rtnl_message *m, unsigned short type, const struct in6_addr *data);
|
||||
int sd_rtnl_message_append_ether_addr(sd_rtnl_message *m, unsigned short type, const struct ether_addr *data);
|
||||
int sd_rtnl_message_append_cache_info(sd_rtnl_message *m, unsigned short type, const struct ifa_cacheinfo *info);
|
||||
|
||||
int sd_rtnl_message_open_container(sd_rtnl_message *m, unsigned short type);
|
||||
int sd_rtnl_message_open_container_union(sd_rtnl_message *m, unsigned short type, const char *key);
|
||||
@ -109,6 +111,7 @@ int sd_rtnl_message_read_u8(sd_rtnl_message *m, unsigned short type, uint8_t *da
|
||||
int sd_rtnl_message_read_u16(sd_rtnl_message *m, unsigned short type, uint16_t *data);
|
||||
int sd_rtnl_message_read_u32(sd_rtnl_message *m, unsigned short type, uint32_t *data);
|
||||
int sd_rtnl_message_read_ether_addr(sd_rtnl_message *m, unsigned short type, struct ether_addr *data);
|
||||
int sd_rtnl_message_read_cache_info(sd_rtnl_message *m, unsigned short type, struct ifa_cacheinfo *info);
|
||||
int sd_rtnl_message_read_in_addr(sd_rtnl_message *m, unsigned short type, struct in_addr *data);
|
||||
int sd_rtnl_message_read_in6_addr(sd_rtnl_message *m, unsigned short type, struct in6_addr *data);
|
||||
int sd_rtnl_message_enter_container(sd_rtnl_message *m, unsigned short type);
|
||||
|
Loading…
Reference in New Issue
Block a user