mirror of
https://github.com/systemd/systemd.git
synced 2024-11-02 02:21:44 +03:00
sd-netlink: introduce rtattr_read_nexthop()
This commit is contained in:
parent
d6ad41e27d
commit
2fe1d557e5
@ -368,3 +368,80 @@ int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, OrderedSet **ret) {
|
||||
_cleanup_ordered_set_free_free_ OrderedSet *set = NULL;
|
||||
int r;
|
||||
|
||||
assert(rtnh);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
|
||||
if (size < sizeof(struct rtnexthop))
|
||||
return -EBADMSG;
|
||||
|
||||
for (; size >= sizeof(struct rtnexthop); ) {
|
||||
_cleanup_free_ MultipathRoute *m = NULL;
|
||||
|
||||
if (NLMSG_ALIGN(rtnh->rtnh_len) > size)
|
||||
return -EBADMSG;
|
||||
|
||||
if (rtnh->rtnh_len < sizeof(struct rtnexthop))
|
||||
return -EBADMSG;
|
||||
|
||||
m = new(MultipathRoute, 1);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
*m = (MultipathRoute) {
|
||||
.ifindex = rtnh->rtnh_ifindex,
|
||||
.weight = rtnh->rtnh_hops == 0 ? 0 : rtnh->rtnh_hops + 1,
|
||||
};
|
||||
|
||||
if (rtnh->rtnh_len > sizeof(struct rtnexthop)) {
|
||||
size_t len = rtnh->rtnh_len - sizeof(struct rtnexthop);
|
||||
|
||||
for (struct rtattr *attr = RTNH_DATA(rtnh); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
|
||||
if (attr->rta_type == RTA_GATEWAY) {
|
||||
if (attr->rta_len != RTA_LENGTH(FAMILY_ADDRESS_SIZE(family)))
|
||||
return -EBADMSG;
|
||||
|
||||
m->gateway.family = family;
|
||||
memcpy(&m->gateway.address, RTA_DATA(attr), FAMILY_ADDRESS_SIZE(family));
|
||||
break;
|
||||
} else if (attr->rta_type == RTA_VIA) {
|
||||
uint16_t gw_family;
|
||||
|
||||
if (family != AF_INET)
|
||||
return -EINVAL;
|
||||
|
||||
if (attr->rta_len < RTA_LENGTH(sizeof(uint16_t)))
|
||||
return -EBADMSG;
|
||||
|
||||
gw_family = *(uint16_t *) RTA_DATA(attr);
|
||||
|
||||
if (gw_family != AF_INET6)
|
||||
return -EBADMSG;
|
||||
|
||||
if (attr->rta_len != RTA_LENGTH(FAMILY_ADDRESS_SIZE(gw_family) + sizeof(gw_family)))
|
||||
return -EBADMSG;
|
||||
|
||||
memcpy(&m->gateway, RTA_DATA(attr), FAMILY_ADDRESS_SIZE(gw_family) + sizeof(gw_family));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = ordered_set_ensure_put(&set, NULL, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(m);
|
||||
|
||||
size -= NLMSG_ALIGN(rtnh->rtnh_len);
|
||||
rtnh = RTNH_NEXT(rtnh);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(set);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,9 +6,22 @@
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "in-addr-util.h"
|
||||
#include "ordered-set.h"
|
||||
#include "socket-util.h"
|
||||
#include "util.h"
|
||||
|
||||
/* See struct rtvia in rtnetlink.h */
|
||||
typedef struct RouteVia {
|
||||
uint16_t family;
|
||||
union in_addr_union address;
|
||||
} _packed_ RouteVia;
|
||||
|
||||
typedef struct MultipathRoute {
|
||||
RouteVia gateway;
|
||||
int ifindex;
|
||||
uint32_t weight;
|
||||
} MultipathRoute;
|
||||
|
||||
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret);
|
||||
uint32_t rtnl_message_get_serial(sd_netlink_message *m);
|
||||
void rtnl_message_seal(sd_netlink_message *m);
|
||||
@ -94,3 +107,5 @@ int netlink_message_read_in_addr_union(sd_netlink_message *m, unsigned short typ
|
||||
|
||||
void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length);
|
||||
int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void *data, size_t data_length);
|
||||
|
||||
int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, OrderedSet **ret);
|
||||
|
@ -15,18 +15,6 @@
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
|
||||
/* See struct rtvia in rtnetlink.h */
|
||||
typedef struct RouteVia {
|
||||
uint16_t family;
|
||||
union in_addr_union address;
|
||||
} _packed_ RouteVia;
|
||||
|
||||
typedef struct MultipathRoute {
|
||||
RouteVia gateway;
|
||||
int ifindex;
|
||||
uint32_t weight;
|
||||
} MultipathRoute;
|
||||
|
||||
typedef struct Route {
|
||||
Network *network;
|
||||
NetworkConfigSection *section;
|
||||
|
Loading…
Reference in New Issue
Block a user