LCOV - code coverage report
Current view: top level - libsystemd/sd-netlink - rtnl-message.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 178 498 35.7 %
Date: 2019-08-22 15:41:25 Functions: 20 58 34.5 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include <netinet/in.h>
       4             : #include <linux/if_addrlabel.h>
       5             : #include <stdbool.h>
       6             : #include <unistd.h>
       7             : 
       8             : #include "sd-netlink.h"
       9             : 
      10             : #include "format-util.h"
      11             : #include "missing.h"
      12             : #include "netlink-internal.h"
      13             : #include "netlink-types.h"
      14             : #include "netlink-util.h"
      15             : #include "socket-util.h"
      16             : #include "util.h"
      17             : 
      18           0 : int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
      19             :         struct rtmsg *rtm;
      20             : 
      21           0 :         assert_return(m, -EINVAL);
      22           0 :         assert_return(m->hdr, -EINVAL);
      23           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
      24             : 
      25           0 :         rtm = NLMSG_DATA(m->hdr);
      26             : 
      27           0 :         if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
      28           0 :             (rtm->rtm_family == AF_INET6 && prefixlen > 128))
      29           0 :                 return -ERANGE;
      30             : 
      31           0 :         rtm->rtm_dst_len = prefixlen;
      32             : 
      33           0 :         return 0;
      34             : }
      35             : 
      36           0 : int sd_rtnl_message_route_set_src_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
      37             :         struct rtmsg *rtm;
      38             : 
      39           0 :         assert_return(m, -EINVAL);
      40           0 :         assert_return(m->hdr, -EINVAL);
      41           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
      42             : 
      43           0 :         rtm = NLMSG_DATA(m->hdr);
      44             : 
      45           0 :         if ((rtm->rtm_family == AF_INET && prefixlen > 32) ||
      46           0 :             (rtm->rtm_family == AF_INET6 && prefixlen > 128))
      47           0 :                 return -ERANGE;
      48             : 
      49           0 :         rtm->rtm_src_len = prefixlen;
      50             : 
      51           0 :         return 0;
      52             : }
      53             : 
      54           0 : int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope) {
      55             :         struct rtmsg *rtm;
      56             : 
      57           0 :         assert_return(m, -EINVAL);
      58           0 :         assert_return(m->hdr, -EINVAL);
      59           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
      60             : 
      61           0 :         rtm = NLMSG_DATA(m->hdr);
      62             : 
      63           0 :         rtm->rtm_scope = scope;
      64             : 
      65           0 :         return 0;
      66             : }
      67             : 
      68           0 : int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) {
      69             :         struct rtmsg *rtm;
      70             : 
      71           0 :         assert_return(m, -EINVAL);
      72           0 :         assert_return(m->hdr, -EINVAL);
      73           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
      74             : 
      75           0 :         rtm = NLMSG_DATA(m->hdr);
      76             : 
      77           0 :         rtm->rtm_flags = flags;
      78             : 
      79           0 :         return 0;
      80             : }
      81             : 
      82           0 : int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags) {
      83             :         struct rtmsg *rtm;
      84             : 
      85           0 :         assert_return(m, -EINVAL);
      86           0 :         assert_return(m->hdr, -EINVAL);
      87           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
      88           0 :         assert_return(flags, -EINVAL);
      89             : 
      90           0 :         rtm = NLMSG_DATA(m->hdr);
      91             : 
      92           0 :         *flags = rtm->rtm_flags;
      93             : 
      94           0 :         return 0;
      95             : }
      96             : 
      97           0 : int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table) {
      98             :         struct rtmsg *rtm;
      99             : 
     100           0 :         assert_return(m, -EINVAL);
     101           0 :         assert_return(m->hdr, -EINVAL);
     102           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     103             : 
     104           0 :         rtm = NLMSG_DATA(m->hdr);
     105             : 
     106           0 :         rtm->rtm_table = table;
     107             : 
     108           0 :         return 0;
     109             : }
     110             : 
     111           2 : int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
     112             :         struct rtmsg *rtm;
     113             : 
     114           2 :         assert_return(m, -EINVAL);
     115           2 :         assert_return(m->hdr, -EINVAL);
     116           2 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     117           2 :         assert_return(family, -EINVAL);
     118             : 
     119           2 :         rtm = NLMSG_DATA(m->hdr);
     120             : 
     121           2 :         *family = rtm->rtm_family;
     122             : 
     123           2 :         return 0;
     124             : }
     125             : 
     126           0 : int sd_rtnl_message_route_set_family(sd_netlink_message *m, int family) {
     127             :         struct rtmsg *rtm;
     128             : 
     129           0 :         assert_return(m, -EINVAL);
     130           0 :         assert_return(m->hdr, -EINVAL);
     131           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     132             : 
     133           0 :         rtm = NLMSG_DATA(m->hdr);
     134             : 
     135           0 :         rtm->rtm_family = family;
     136             : 
     137           0 :         return 0;
     138             : }
     139             : 
     140           0 : int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type) {
     141             :         struct rtmsg *rtm;
     142             : 
     143           0 :         assert_return(m, -EINVAL);
     144           0 :         assert_return(m->hdr, -EINVAL);
     145           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     146           0 :         assert_return(type, -EINVAL);
     147             : 
     148           0 :         rtm = NLMSG_DATA(m->hdr);
     149             : 
     150           0 :         *type = rtm->rtm_type;
     151             : 
     152           0 :         return 0;
     153             : }
     154             : 
     155           0 : int sd_rtnl_message_route_set_type(sd_netlink_message *m, unsigned char type) {
     156             :         struct rtmsg *rtm;
     157             : 
     158           0 :         assert_return(m, -EINVAL);
     159           0 :         assert_return(m->hdr, -EINVAL);
     160           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     161             : 
     162           0 :         rtm = NLMSG_DATA(m->hdr);
     163             : 
     164           0 :         rtm->rtm_type = type;
     165             : 
     166           0 :         return 0;
     167             : }
     168             : 
     169           0 : int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) {
     170             :         struct rtmsg *rtm;
     171             : 
     172           0 :         assert_return(m, -EINVAL);
     173           0 :         assert_return(m->hdr, -EINVAL);
     174           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     175           0 :         assert_return(protocol, -EINVAL);
     176             : 
     177           0 :         rtm = NLMSG_DATA(m->hdr);
     178             : 
     179           0 :         *protocol = rtm->rtm_protocol;
     180             : 
     181           0 :         return 0;
     182             : }
     183             : 
     184           0 : int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope) {
     185             :         struct rtmsg *rtm;
     186             : 
     187           0 :         assert_return(m, -EINVAL);
     188           0 :         assert_return(m->hdr, -EINVAL);
     189           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     190           0 :         assert_return(scope, -EINVAL);
     191             : 
     192           0 :         rtm = NLMSG_DATA(m->hdr);
     193             : 
     194           0 :         *scope = rtm->rtm_scope;
     195             : 
     196           0 :         return 0;
     197             : }
     198             : 
     199           0 : int sd_rtnl_message_route_get_tos(sd_netlink_message *m, unsigned char *tos) {
     200             :         struct rtmsg *rtm;
     201             : 
     202           0 :         assert_return(m, -EINVAL);
     203           0 :         assert_return(m->hdr, -EINVAL);
     204           0 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     205           0 :         assert_return(tos, -EINVAL);
     206             : 
     207           0 :         rtm = NLMSG_DATA(m->hdr);
     208             : 
     209           0 :         *tos = rtm->rtm_tos;
     210             : 
     211           0 :         return 0;
     212             : }
     213             : 
     214           2 : int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table) {
     215             :         struct rtmsg *rtm;
     216             : 
     217           2 :         assert_return(m, -EINVAL);
     218           2 :         assert_return(m->hdr, -EINVAL);
     219           2 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     220           2 :         assert_return(table, -EINVAL);
     221             : 
     222           2 :         rtm = NLMSG_DATA(m->hdr);
     223             : 
     224           2 :         *table = rtm->rtm_table;
     225             : 
     226           2 :         return 0;
     227             : }
     228             : 
     229          28 : int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char *dst_len) {
     230             :         struct rtmsg *rtm;
     231             : 
     232          28 :         assert_return(m, -EINVAL);
     233          28 :         assert_return(m->hdr, -EINVAL);
     234          28 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     235          28 :         assert_return(dst_len, -EINVAL);
     236             : 
     237          28 :         rtm = NLMSG_DATA(m->hdr);
     238             : 
     239          28 :         *dst_len = rtm->rtm_dst_len;
     240             : 
     241          28 :         return 0;
     242             : }
     243             : 
     244           2 : int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len) {
     245             :         struct rtmsg *rtm;
     246             : 
     247           2 :         assert_return(m, -EINVAL);
     248           2 :         assert_return(m->hdr, -EINVAL);
     249           2 :         assert_return(rtnl_message_type_is_route(m->hdr->nlmsg_type), -EINVAL);
     250           2 :         assert_return(src_len, -EINVAL);
     251             : 
     252           2 :         rtm = NLMSG_DATA(m->hdr);
     253             : 
     254           2 :         *src_len = rtm->rtm_src_len;
     255             : 
     256           2 :         return 0;
     257             : }
     258             : 
     259           2 : int sd_rtnl_message_new_route(sd_netlink *rtnl, sd_netlink_message **ret,
     260             :                               uint16_t nlmsg_type, int rtm_family,
     261             :                               unsigned char rtm_protocol) {
     262             :         struct rtmsg *rtm;
     263             :         int r;
     264             : 
     265           2 :         assert_return(rtnl_message_type_is_route(nlmsg_type), -EINVAL);
     266           2 :         assert_return((nlmsg_type == RTM_GETROUTE && rtm_family == AF_UNSPEC) ||
     267             :                       IN_SET(rtm_family, AF_INET, AF_INET6), -EINVAL);
     268           2 :         assert_return(ret, -EINVAL);
     269             : 
     270           2 :         r = message_new(rtnl, ret, nlmsg_type);
     271           2 :         if (r < 0)
     272           0 :                 return r;
     273             : 
     274           2 :         if (nlmsg_type == RTM_NEWROUTE)
     275           1 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
     276             : 
     277           2 :         rtm = NLMSG_DATA((*ret)->hdr);
     278             : 
     279           2 :         rtm->rtm_family = rtm_family;
     280           2 :         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
     281           2 :         rtm->rtm_type = RTN_UNICAST;
     282           2 :         rtm->rtm_table = RT_TABLE_MAIN;
     283           2 :         rtm->rtm_protocol = rtm_protocol;
     284             : 
     285           2 :         return 0;
     286             : }
     287             : 
     288           0 : int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags) {
     289             :         struct ndmsg *ndm;
     290             : 
     291           0 :         assert_return(m, -EINVAL);
     292           0 :         assert_return(m->hdr, -EINVAL);
     293           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     294             : 
     295           0 :         ndm = NLMSG_DATA(m->hdr);
     296           0 :         ndm->ndm_flags |= flags;
     297             : 
     298           0 :         return 0;
     299             : }
     300             : 
     301           0 : int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state) {
     302             :         struct ndmsg *ndm;
     303             : 
     304           0 :         assert_return(m, -EINVAL);
     305           0 :         assert_return(m->hdr, -EINVAL);
     306           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     307             : 
     308           0 :         ndm = NLMSG_DATA(m->hdr);
     309           0 :         ndm->ndm_state |= state;
     310             : 
     311           0 :         return 0;
     312             : }
     313             : 
     314           0 : int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags) {
     315             :         struct ndmsg *ndm;
     316             : 
     317           0 :         assert_return(m, -EINVAL);
     318           0 :         assert_return(m->hdr, -EINVAL);
     319           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     320             : 
     321           0 :         ndm = NLMSG_DATA(m->hdr);
     322           0 :         *flags = ndm->ndm_flags;
     323             : 
     324           0 :         return 0;
     325             : }
     326             : 
     327           0 : int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state) {
     328             :         struct ndmsg *ndm;
     329             : 
     330           0 :         assert_return(m, -EINVAL);
     331           0 :         assert_return(m->hdr, -EINVAL);
     332           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     333             : 
     334           0 :         ndm = NLMSG_DATA(m->hdr);
     335           0 :         *state = ndm->ndm_state;
     336             : 
     337           0 :         return 0;
     338             : }
     339             : 
     340           0 : int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family) {
     341             :         struct ndmsg *ndm;
     342             : 
     343           0 :         assert_return(m, -EINVAL);
     344           0 :         assert_return(m->hdr, -EINVAL);
     345           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     346           0 :         assert_return(family, -EINVAL);
     347             : 
     348           0 :         ndm = NLMSG_DATA(m->hdr);
     349             : 
     350           0 :         *family = ndm->ndm_family;
     351             : 
     352           0 :         return 0;
     353             : }
     354             : 
     355           0 : int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message *m, int *index) {
     356             :         struct ndmsg *ndm;
     357             : 
     358           0 :         assert_return(m, -EINVAL);
     359           0 :         assert_return(m->hdr, -EINVAL);
     360           0 :         assert_return(rtnl_message_type_is_neigh(m->hdr->nlmsg_type), -EINVAL);
     361           0 :         assert_return(index, -EINVAL);
     362             : 
     363           0 :         ndm = NLMSG_DATA(m->hdr);
     364             : 
     365           0 :         *index = ndm->ndm_ifindex;
     366             : 
     367           0 :         return 0;
     368             : }
     369             : 
     370           0 : int sd_rtnl_message_new_neigh(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int index, int ndm_family) {
     371             :         struct ndmsg *ndm;
     372             :         int r;
     373             : 
     374           0 :         assert_return(rtnl_message_type_is_neigh(nlmsg_type), -EINVAL);
     375           0 :         assert_return(IN_SET(ndm_family, AF_UNSPEC, AF_INET, AF_INET6, PF_BRIDGE), -EINVAL);
     376           0 :         assert_return(ret, -EINVAL);
     377             : 
     378           0 :         r = message_new(rtnl, ret, nlmsg_type);
     379           0 :         if (r < 0)
     380           0 :                 return r;
     381             : 
     382           0 :         if (nlmsg_type == RTM_NEWNEIGH)
     383           0 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_APPEND;
     384             : 
     385           0 :         ndm = NLMSG_DATA((*ret)->hdr);
     386             : 
     387           0 :         ndm->ndm_family = ndm_family;
     388           0 :         ndm->ndm_ifindex = index;
     389             : 
     390           0 :         return 0;
     391             : }
     392             : 
     393           1 : int sd_rtnl_message_link_set_flags(sd_netlink_message *m, unsigned flags, unsigned change) {
     394             :         struct ifinfomsg *ifi;
     395             : 
     396           1 :         assert_return(m, -EINVAL);
     397           1 :         assert_return(m->hdr, -EINVAL);
     398           1 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     399           1 :         assert_return(change, -EINVAL);
     400             : 
     401           1 :         ifi = NLMSG_DATA(m->hdr);
     402             : 
     403           1 :         ifi->ifi_flags = flags;
     404           1 :         ifi->ifi_change = change;
     405             : 
     406           1 :         return 0;
     407             : }
     408             : 
     409           0 : int sd_rtnl_message_link_set_type(sd_netlink_message *m, unsigned type) {
     410             :         struct ifinfomsg *ifi;
     411             : 
     412           0 :         assert_return(m, -EINVAL);
     413           0 :         assert_return(m->hdr, -EINVAL);
     414           0 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     415             : 
     416           0 :         ifi = NLMSG_DATA(m->hdr);
     417             : 
     418           0 :         ifi->ifi_type = type;
     419             : 
     420           0 :         return 0;
     421             : }
     422             : 
     423           1 : int sd_rtnl_message_link_set_family(sd_netlink_message *m, unsigned family) {
     424             :         struct ifinfomsg *ifi;
     425             : 
     426           1 :         assert_return(m, -EINVAL);
     427           1 :         assert_return(m->hdr, -EINVAL);
     428           1 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     429             : 
     430           1 :         ifi = NLMSG_DATA(m->hdr);
     431             : 
     432           1 :         ifi->ifi_family = family;
     433             : 
     434           1 :         return 0;
     435             : }
     436             : 
     437          22 : int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
     438             :                              uint16_t nlmsg_type, int index) {
     439             :         struct ifinfomsg *ifi;
     440             :         int r;
     441             : 
     442          22 :         assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
     443          22 :         assert_return(ret, -EINVAL);
     444             : 
     445          22 :         r = message_new(rtnl, ret, nlmsg_type);
     446          22 :         if (r < 0)
     447           0 :                 return r;
     448             : 
     449          22 :         if (nlmsg_type == RTM_NEWLINK)
     450           2 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
     451             : 
     452          22 :         ifi = NLMSG_DATA((*ret)->hdr);
     453             : 
     454          22 :         ifi->ifi_family = AF_UNSPEC;
     455          22 :         ifi->ifi_index = index;
     456             : 
     457          22 :         return 0;
     458             : }
     459             : 
     460           2 : int sd_rtnl_message_addr_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
     461             :         struct ifaddrmsg *ifa;
     462             : 
     463           2 :         assert_return(m, -EINVAL);
     464           2 :         assert_return(m->hdr, -EINVAL);
     465           2 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     466             : 
     467           2 :         ifa = NLMSG_DATA(m->hdr);
     468             : 
     469           2 :         if ((ifa->ifa_family == AF_INET && prefixlen > 32) ||
     470           2 :             (ifa->ifa_family == AF_INET6 && prefixlen > 128))
     471           0 :                 return -ERANGE;
     472             : 
     473           2 :         ifa->ifa_prefixlen = prefixlen;
     474             : 
     475           2 :         return 0;
     476             : }
     477             : 
     478           2 : int sd_rtnl_message_addr_set_flags(sd_netlink_message *m, unsigned char flags) {
     479             :         struct ifaddrmsg *ifa;
     480             : 
     481           2 :         assert_return(m, -EINVAL);
     482           2 :         assert_return(m->hdr, -EINVAL);
     483           2 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     484             : 
     485           2 :         ifa = NLMSG_DATA(m->hdr);
     486             : 
     487           2 :         ifa->ifa_flags = flags;
     488             : 
     489           2 :         return 0;
     490             : }
     491             : 
     492           2 : int sd_rtnl_message_addr_set_scope(sd_netlink_message *m, unsigned char scope) {
     493             :         struct ifaddrmsg *ifa;
     494             : 
     495           2 :         assert_return(m, -EINVAL);
     496           2 :         assert_return(m->hdr, -EINVAL);
     497           2 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     498             : 
     499           2 :         ifa = NLMSG_DATA(m->hdr);
     500             : 
     501           2 :         ifa->ifa_scope = scope;
     502             : 
     503           2 :         return 0;
     504             : }
     505             : 
     506          16 : int sd_rtnl_message_addr_get_family(sd_netlink_message *m, int *family) {
     507             :         struct ifaddrmsg *ifa;
     508             : 
     509          16 :         assert_return(m, -EINVAL);
     510          16 :         assert_return(m->hdr, -EINVAL);
     511          16 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     512          16 :         assert_return(family, -EINVAL);
     513             : 
     514          16 :         ifa = NLMSG_DATA(m->hdr);
     515             : 
     516          16 :         *family = ifa->ifa_family;
     517             : 
     518          16 :         return 0;
     519             : }
     520             : 
     521           0 : int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
     522             :         struct ifaddrmsg *ifa;
     523             : 
     524           0 :         assert_return(m, -EINVAL);
     525           0 :         assert_return(m->hdr, -EINVAL);
     526           0 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     527           0 :         assert_return(prefixlen, -EINVAL);
     528             : 
     529           0 :         ifa = NLMSG_DATA(m->hdr);
     530             : 
     531           0 :         *prefixlen = ifa->ifa_prefixlen;
     532             : 
     533           0 :         return 0;
     534             : }
     535             : 
     536          16 : int sd_rtnl_message_addr_get_scope(sd_netlink_message *m, unsigned char *scope) {
     537             :         struct ifaddrmsg *ifa;
     538             : 
     539          16 :         assert_return(m, -EINVAL);
     540          16 :         assert_return(m->hdr, -EINVAL);
     541          16 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     542          16 :         assert_return(scope, -EINVAL);
     543             : 
     544          16 :         ifa = NLMSG_DATA(m->hdr);
     545             : 
     546          16 :         *scope = ifa->ifa_scope;
     547             : 
     548          16 :         return 0;
     549             : }
     550             : 
     551          16 : int sd_rtnl_message_addr_get_flags(sd_netlink_message *m, unsigned char *flags) {
     552             :         struct ifaddrmsg *ifa;
     553             : 
     554          16 :         assert_return(m, -EINVAL);
     555          16 :         assert_return(m->hdr, -EINVAL);
     556          16 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     557          16 :         assert_return(flags, -EINVAL);
     558             : 
     559          16 :         ifa = NLMSG_DATA(m->hdr);
     560             : 
     561          16 :         *flags = ifa->ifa_flags;
     562             : 
     563          16 :         return 0;
     564             : }
     565             : 
     566          16 : int sd_rtnl_message_addr_get_ifindex(sd_netlink_message *m, int *ifindex) {
     567             :         struct ifaddrmsg *ifa;
     568             : 
     569          16 :         assert_return(m, -EINVAL);
     570          16 :         assert_return(m->hdr, -EINVAL);
     571          16 :         assert_return(rtnl_message_type_is_addr(m->hdr->nlmsg_type), -EINVAL);
     572          16 :         assert_return(ifindex, -EINVAL);
     573             : 
     574          16 :         ifa = NLMSG_DATA(m->hdr);
     575             : 
     576          16 :         *ifindex = ifa->ifa_index;
     577             : 
     578          16 :         return 0;
     579             : }
     580             : 
     581           5 : int sd_rtnl_message_new_addr(sd_netlink *rtnl, sd_netlink_message **ret,
     582             :                              uint16_t nlmsg_type, int index,
     583             :                              int family) {
     584             :         struct ifaddrmsg *ifa;
     585             :         int r;
     586             : 
     587           5 :         assert_return(rtnl_message_type_is_addr(nlmsg_type), -EINVAL);
     588           5 :         assert_return((nlmsg_type == RTM_GETADDR && index == 0) ||
     589             :                       index > 0, -EINVAL);
     590           5 :         assert_return((nlmsg_type == RTM_GETADDR && family == AF_UNSPEC) ||
     591             :                       IN_SET(family, AF_INET, AF_INET6), -EINVAL);
     592           5 :         assert_return(ret, -EINVAL);
     593             : 
     594           5 :         r = message_new(rtnl, ret, nlmsg_type);
     595           5 :         if (r < 0)
     596           0 :                 return r;
     597             : 
     598           5 :         if (nlmsg_type == RTM_GETADDR)
     599           3 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_DUMP;
     600             : 
     601           5 :         ifa = NLMSG_DATA((*ret)->hdr);
     602             : 
     603           5 :         ifa->ifa_index = index;
     604           5 :         ifa->ifa_family = family;
     605           5 :         if (family == AF_INET)
     606           2 :                 ifa->ifa_prefixlen = 32;
     607           3 :         else if (family == AF_INET6)
     608           1 :                 ifa->ifa_prefixlen = 128;
     609             : 
     610           5 :         return 0;
     611             : }
     612             : 
     613           0 : int sd_rtnl_message_new_addr_update(sd_netlink *rtnl, sd_netlink_message **ret,
     614             :                              int index, int family) {
     615             :         int r;
     616             : 
     617           0 :         r = sd_rtnl_message_new_addr(rtnl, ret, RTM_NEWADDR, index, family);
     618           0 :         if (r < 0)
     619           0 :                 return r;
     620             : 
     621           0 :         (*ret)->hdr->nlmsg_flags |= NLM_F_REPLACE;
     622             : 
     623           0 :         return 0;
     624             : }
     625             : 
     626          12 : int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex) {
     627             :         struct ifinfomsg *ifi;
     628             : 
     629          12 :         assert_return(m, -EINVAL);
     630          12 :         assert_return(m->hdr, -EINVAL);
     631          12 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     632          12 :         assert_return(ifindex, -EINVAL);
     633             : 
     634          12 :         ifi = NLMSG_DATA(m->hdr);
     635             : 
     636          12 :         *ifindex = ifi->ifi_index;
     637             : 
     638          12 :         return 0;
     639             : }
     640             : 
     641          13 : int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags) {
     642             :         struct ifinfomsg *ifi;
     643             : 
     644          13 :         assert_return(m, -EINVAL);
     645          13 :         assert_return(m->hdr, -EINVAL);
     646          13 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     647          13 :         assert_return(flags, -EINVAL);
     648             : 
     649          13 :         ifi = NLMSG_DATA(m->hdr);
     650             : 
     651          13 :         *flags = ifi->ifi_flags;
     652             : 
     653          13 :         return 0;
     654             : }
     655             : 
     656           6 : int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type) {
     657             :         struct ifinfomsg *ifi;
     658             : 
     659           6 :         assert_return(m, -EINVAL);
     660           6 :         assert_return(m->hdr, -EINVAL);
     661           6 :         assert_return(rtnl_message_type_is_link(m->hdr->nlmsg_type), -EINVAL);
     662           6 :         assert_return(type, -EINVAL);
     663             : 
     664           6 :         ifi = NLMSG_DATA(m->hdr);
     665             : 
     666           6 :         *type = ifi->ifi_type;
     667             : 
     668           6 :         return 0;
     669             : }
     670             : 
     671           2 : int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
     672           2 :         assert_return(m, -EINVAL);
     673           2 :         assert_return(family, -EINVAL);
     674             : 
     675           2 :         assert(m->hdr);
     676             : 
     677           2 :         if (rtnl_message_type_is_link(m->hdr->nlmsg_type)) {
     678             :                 struct ifinfomsg *ifi;
     679             : 
     680           2 :                 ifi = NLMSG_DATA(m->hdr);
     681             : 
     682           2 :                 *family = ifi->ifi_family;
     683             : 
     684           2 :                 return 0;
     685           0 :         } else if (rtnl_message_type_is_route(m->hdr->nlmsg_type)) {
     686             :                 struct rtmsg *rtm;
     687             : 
     688           0 :                 rtm = NLMSG_DATA(m->hdr);
     689             : 
     690           0 :                 *family = rtm->rtm_family;
     691             : 
     692           0 :                 return 0;
     693           0 :         } else if (rtnl_message_type_is_neigh(m->hdr->nlmsg_type)) {
     694             :                 struct ndmsg *ndm;
     695             : 
     696           0 :                 ndm = NLMSG_DATA(m->hdr);
     697             : 
     698           0 :                 *family = ndm->ndm_family;
     699             : 
     700           0 :                 return 0;
     701           0 :         } else if (rtnl_message_type_is_addr(m->hdr->nlmsg_type)) {
     702             :                 struct ifaddrmsg *ifa;
     703             : 
     704           0 :                 ifa = NLMSG_DATA(m->hdr);
     705             : 
     706           0 :                 *family = ifa->ifa_family;
     707             : 
     708           0 :                 return 0;
     709           0 :         } else if (rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type)) {
     710             :                 struct rtmsg *rtm;
     711             : 
     712           0 :                 rtm = NLMSG_DATA(m->hdr);
     713             : 
     714           0 :                 *family = rtm->rtm_family;
     715             : 
     716           0 :                 return 0;
     717             :         }
     718             : 
     719           0 :         return -EOPNOTSUPP;
     720             : }
     721             : 
     722           0 : int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family) {
     723             :         struct ifaddrlblmsg *addrlabel;
     724             :         int r;
     725             : 
     726           0 :         assert_return(rtnl_message_type_is_addrlabel(nlmsg_type), -EINVAL);
     727           0 :         assert_return(ret, -EINVAL);
     728             : 
     729           0 :         r = message_new(rtnl, ret, nlmsg_type);
     730           0 :         if (r < 0)
     731           0 :                 return r;
     732             : 
     733           0 :         if (nlmsg_type == RTM_NEWADDRLABEL)
     734           0 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
     735             : 
     736           0 :         addrlabel = NLMSG_DATA((*ret)->hdr);
     737             : 
     738           0 :         addrlabel->ifal_family = ifal_family;
     739           0 :         addrlabel->ifal_index = ifindex;
     740             : 
     741           0 :         return 0;
     742             : }
     743             : 
     744           0 : int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen) {
     745             :         struct ifaddrlblmsg *addrlabel;
     746             : 
     747           0 :         assert_return(m, -EINVAL);
     748           0 :         assert_return(m->hdr, -EINVAL);
     749           0 :         assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
     750             : 
     751           0 :         addrlabel = NLMSG_DATA(m->hdr);
     752             : 
     753           0 :         if (prefixlen > 128)
     754           0 :                 return -ERANGE;
     755             : 
     756           0 :         addrlabel->ifal_prefixlen = prefixlen;
     757             : 
     758           0 :         return 0;
     759             : }
     760             : 
     761           0 : int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
     762             :         struct ifaddrlblmsg *addrlabel;
     763             : 
     764           0 :         assert_return(m, -EINVAL);
     765           0 :         assert_return(m->hdr, -EINVAL);
     766           0 :         assert_return(rtnl_message_type_is_addrlabel(m->hdr->nlmsg_type), -EINVAL);
     767             : 
     768           0 :         addrlabel = NLMSG_DATA(m->hdr);
     769             : 
     770           0 :         *prefixlen = addrlabel->ifal_prefixlen;
     771             : 
     772           0 :         return 0;
     773             : }
     774             : 
     775           0 : int sd_rtnl_message_new_routing_policy_rule(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifal_family) {
     776             :         struct rtmsg *rtm;
     777             :         int r;
     778             : 
     779           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(nlmsg_type), -EINVAL);
     780           0 :         assert_return(ret, -EINVAL);
     781             : 
     782           0 :         r = message_new(rtnl, ret, nlmsg_type);
     783           0 :         if (r < 0)
     784           0 :                 return r;
     785             : 
     786           0 :         if (nlmsg_type == RTM_NEWRULE)
     787           0 :                 (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
     788             : 
     789           0 :         rtm = NLMSG_DATA((*ret)->hdr);
     790           0 :         rtm->rtm_family = ifal_family;
     791           0 :         rtm->rtm_protocol = RTPROT_BOOT;
     792           0 :         rtm->rtm_scope = RT_SCOPE_UNIVERSE;
     793           0 :         rtm->rtm_type = RTN_UNICAST;
     794             : 
     795           0 :         return 0;
     796             : }
     797             : 
     798           0 : int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message *m, unsigned char tos) {
     799             :         struct rtmsg *routing_policy_rule;
     800             : 
     801           0 :         assert_return(m, -EINVAL);
     802           0 :         assert_return(m->hdr, -EINVAL);
     803           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     804             : 
     805           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     806             : 
     807           0 :         routing_policy_rule->rtm_tos = tos;
     808             : 
     809           0 :         return 0;
     810             : }
     811             : 
     812           0 : int sd_rtnl_message_routing_policy_rule_get_tos(sd_netlink_message *m, unsigned char *tos) {
     813             :         struct rtmsg *routing_policy_rule;
     814             : 
     815           0 :         assert_return(m, -EINVAL);
     816           0 :         assert_return(m->hdr, -EINVAL);
     817           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     818             : 
     819           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     820             : 
     821           0 :         *tos = routing_policy_rule->rtm_tos;
     822             : 
     823           0 :         return 0;
     824             : }
     825             : 
     826           0 : int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message *m, unsigned char table) {
     827             :         struct rtmsg *routing_policy_rule;
     828             : 
     829           0 :         assert_return(m, -EINVAL);
     830           0 :         assert_return(m->hdr, -EINVAL);
     831           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     832             : 
     833           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     834             : 
     835           0 :         routing_policy_rule->rtm_table = table;
     836             : 
     837           0 :         return 0;
     838             : }
     839             : 
     840           0 : int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, unsigned char *table) {
     841             :         struct rtmsg *routing_policy_rule;
     842             : 
     843           0 :         assert_return(m, -EINVAL);
     844           0 :         assert_return(m->hdr, -EINVAL);
     845           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     846             : 
     847           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     848             : 
     849           0 :         *table = routing_policy_rule->rtm_table;
     850             : 
     851           0 :         return 0;
     852             : }
     853             : 
     854           0 : int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, unsigned flags) {
     855             :         struct rtmsg *routing_policy_rule;
     856             : 
     857           0 :         assert_return(m, -EINVAL);
     858           0 :         assert_return(m->hdr, -EINVAL);
     859           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     860             : 
     861           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     862           0 :         routing_policy_rule->rtm_flags |= flags;
     863             : 
     864           0 :         return 0;
     865             : }
     866             : 
     867           0 : int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, unsigned *flags) {
     868             :         struct rtmsg *routing_policy_rule;
     869             : 
     870           0 :         assert_return(m, -EINVAL);
     871           0 :         assert_return(m->hdr, -EINVAL);
     872           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     873             : 
     874           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     875           0 :         *flags = routing_policy_rule->rtm_flags;
     876             : 
     877           0 :         return 0;
     878             : }
     879             : 
     880           0 : int sd_rtnl_message_routing_policy_rule_set_rtm_type(sd_netlink_message *m, unsigned char type) {
     881             :         struct rtmsg *routing_policy_rule;
     882             : 
     883           0 :         assert_return(m, -EINVAL);
     884           0 :         assert_return(m->hdr, -EINVAL);
     885           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     886             : 
     887           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     888             : 
     889           0 :         routing_policy_rule->rtm_type = type;
     890             : 
     891           0 :         return 0;
     892             : }
     893             : 
     894           0 : int sd_rtnl_message_routing_policy_rule_get_rtm_type(sd_netlink_message *m, unsigned char *type) {
     895             :         struct rtmsg *routing_policy_rule;
     896             : 
     897           0 :         assert_return(m, -EINVAL);
     898           0 :         assert_return(m->hdr, -EINVAL);
     899           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     900             : 
     901           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     902             : 
     903           0 :         *type =  routing_policy_rule->rtm_type;
     904             : 
     905           0 :         return 0;
     906             : }
     907             : 
     908           0 : int sd_rtnl_message_routing_policy_rule_set_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char len) {
     909             :         struct rtmsg *routing_policy_rule;
     910             : 
     911           0 :         assert_return(m, -EINVAL);
     912           0 :         assert_return(m->hdr, -EINVAL);
     913           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     914             : 
     915           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     916             : 
     917           0 :         routing_policy_rule->rtm_dst_len = len;
     918             : 
     919           0 :         return 0;
     920             : }
     921             : 
     922           0 : int sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(sd_netlink_message *m, unsigned char *len) {
     923             :         struct rtmsg *routing_policy_rule;
     924             : 
     925           0 :         assert_return(m, -EINVAL);
     926           0 :         assert_return(m->hdr, -EINVAL);
     927           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     928             : 
     929           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     930             : 
     931           0 :         *len = routing_policy_rule->rtm_dst_len;
     932             : 
     933           0 :         return 0;
     934             : }
     935             : 
     936           0 : int sd_rtnl_message_routing_policy_rule_set_rtm_src_prefixlen(sd_netlink_message *m, unsigned char len) {
     937             :         struct rtmsg *routing_policy_rule;
     938             : 
     939           0 :         assert_return(m, -EINVAL);
     940           0 :         assert_return(m->hdr, -EINVAL);
     941           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     942             : 
     943           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     944             : 
     945           0 :         routing_policy_rule->rtm_src_len = len;
     946             : 
     947           0 :         return 0;
     948             : }
     949             : 
     950           0 : int sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(sd_netlink_message *m, unsigned char *len) {
     951             :         struct rtmsg *routing_policy_rule;
     952             : 
     953           0 :         assert_return(m, -EINVAL);
     954           0 :         assert_return(m->hdr, -EINVAL);
     955           0 :         assert_return(rtnl_message_type_is_routing_policy_rule(m->hdr->nlmsg_type), -EINVAL);
     956             : 
     957           0 :         routing_policy_rule = NLMSG_DATA(m->hdr);
     958             : 
     959           0 :         *len = routing_policy_rule->rtm_src_len;
     960             : 
     961           0 :         return 0;
     962             : }

Generated by: LCOV version 1.14