int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int rtm_family, unsigned char rtm_protocol) { struct rtmsg *rtm; int r; assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL); assert_return((nlmsg_type == RTM_GETROUTE && rtm_family == AF_UNSPEC) || rtm_family == AF_INET || rtm_family == AF_INET6, -EINVAL); assert_return(ret, -EINVAL); r = message_new(rtnl, ret, nlmsg_type); if (r < 0) return r; if (nlmsg_type == RTM_NEWROUTE) (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND; rtm = NLMSG_DATA((*ret)->hdr); rtm->rtm_family = rtm_family; rtm->rtm_scope = RT_SCOPE_UNIVERSE; rtm->rtm_type = RTN_UNICAST; rtm->rtm_table = RT_TABLE_MAIN; rtm->rtm_protocol = rtm_protocol; return 0; }
int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); rtm = NLMSG_DATA(m->hdr); rtm->rtm_scope = scope; return 0; }
int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); rtm = NLMSG_DATA(m->hdr); rtm->rtm_flags = flags; return 0; }
int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); rtm = NLMSG_DATA(m->hdr); rtm->rtm_family = family; return 0; }
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); assert_return(src_len, -EINVAL); rtm = NLMSG_DATA(m->hdr); *src_len = rtm->rtm_src_len; return 0; }
int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); assert_return(table, -EINVAL); rtm = NLMSG_DATA(m->hdr); *table = rtm->rtm_table; return 0; }
int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); assert_return(protocol, -EINVAL); rtm = NLMSG_DATA(m->hdr); *protocol = rtm->rtm_protocol; return 0; }
int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) { assert_return(m, -EINVAL); assert_return(family, -EINVAL); assert(m->hdr); if (rtnl_message_type_is_link(m->hdr->nlmsg_type)) { struct ifinfomsg *ifi; ifi = NLMSG_DATA(m->hdr); *family = ifi->ifi_family; return 0; } else if (rtnl_message_type_is_route(m->hdr->nlmsg_type)) { struct rtmsg *rtm; rtm = NLMSG_DATA(m->hdr); *family = rtm->rtm_family; return 0; } else if (rtnl_message_type_is_neigh(m->hdr->nlmsg_type)) { struct ndmsg *ndm; ndm = NLMSG_DATA(m->hdr); *family = ndm->ndm_family; return 0; } else if (rtnl_message_type_is_addr(m->hdr->nlmsg_type)) { struct ifaddrmsg *ifa; ifa = NLMSG_DATA(m->hdr); *family = ifa->ifa_family; return 0; } else if (rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type)) { struct rtmsg *rtm; rtm = NLMSG_DATA(m->hdr); *family = rtm->rtm_family; return 0; } return -EOPNOTSUPP; }
int sd_rtnl_message_route_set_src_prefixlen(sd_netlink_message *m, unsigned char prefixlen) { struct rtmsg *rtm; assert_return(m, -EINVAL); assert_return(m->hdr, -EINVAL); assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL); rtm = NLMSG_DATA(m->hdr); if ((rtm->rtm_family == AF_INET && prefixlen > 32) || (rtm->rtm_family == AF_INET6 && prefixlen > 128)) return -ERANGE; rtm->rtm_src_len = prefixlen; return 0; }