return 0;
}
-MultipathRoute *multipath_route_free(MultipathRoute *m) {
- if (!m)
- return NULL;
-
- free(m->ifname);
-
- return mfree(m);
-}
-
-int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret) {
- _cleanup_(multipath_route_freep) MultipathRoute *n = NULL;
- _cleanup_free_ char *ifname = NULL;
-
- assert(m);
- assert(ret);
-
- if (m->ifname) {
- ifname = strdup(m->ifname);
- if (!ifname)
- return -ENOMEM;
- }
-
- n = new(MultipathRoute, 1);
- if (!n)
- return -ENOMEM;
-
- *n = (MultipathRoute) {
- .gateway = m->gateway,
- .weight = m->weight,
- .ifindex = m->ifindex,
- .ifname = TAKE_PTR(ifname),
- };
-
- *ret = TAKE_PTR(n);
-
- 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_(multipath_route_freep) 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,
- };
-
- 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;
-}
-
bool netlink_pid_changed(sd_netlink *nl) {
/* We don't support people creating an nl connection and
* keeping it around over a fork(). Let's complain. */
union in_addr_union address;
} _packed_ RouteVia;
-typedef struct MultipathRoute {
- RouteVia gateway;
- uint32_t weight;
- int ifindex;
- char *ifname;
-} MultipathRoute;
-
-MultipathRoute *multipath_route_free(MultipathRoute *m);
-DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free);
-
-int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret);
-
int rtnl_rename_link(sd_netlink **rtnl, const char *orig_name, const char *new_name);
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name, char* const* alternative_names);
static inline int rtnl_append_link_alternative_names(sd_netlink **rtnl, int ifindex, char* const *alternative_names) {
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);
-
void netlink_seal_message(sd_netlink *nl, sd_netlink_message *m);
size_t netlink_get_reply_callback_count(sd_netlink *nl);