2525#include "dns-domain.h"
2626#include "resolved-bus.h"
2727#include "resolved-def.h"
28+ #include "resolved-link-bus.h"
2829
2930static int reply_query_state (DnsQuery * q ) {
3031
@@ -1116,17 +1117,23 @@ static int bus_method_resolve_service(sd_bus_message *message, void *userdata, s
11161117 return r ;
11171118}
11181119
1119- static int append_dns_server (sd_bus_message * reply , DnsServer * s ) {
1120+ int bus_dns_server_append (sd_bus_message * reply , DnsServer * s , bool with_ifindex ) {
11201121 int r ;
11211122
11221123 assert (reply );
11231124 assert (s );
11241125
1125- r = sd_bus_message_open_container (reply , 'r' , "iiay" );
1126+ r = sd_bus_message_open_container (reply , 'r' , with_ifindex ? "iiay" : "iay " );
11261127 if (r < 0 )
11271128 return r ;
11281129
1129- r = sd_bus_message_append (reply , "ii" , s -> link ? s -> link -> ifindex : 0 , s -> family );
1130+ if (with_ifindex ) {
1131+ r = sd_bus_message_append (reply , "i" , s -> link ? s -> link -> ifindex : 0 );
1132+ if (r < 0 )
1133+ return r ;
1134+ }
1135+
1136+ r = sd_bus_message_append (reply , "i" , s -> family );
11301137 if (r < 0 )
11311138 return r ;
11321139
@@ -1161,7 +1168,7 @@ static int bus_property_get_dns_servers(
11611168 return r ;
11621169
11631170 LIST_FOREACH (servers , s , m -> dns_servers ) {
1164- r = append_dns_server (reply , s );
1171+ r = bus_dns_server_append (reply , s , true );
11651172 if (r < 0 )
11661173 return r ;
11671174
@@ -1170,7 +1177,7 @@ static int bus_property_get_dns_servers(
11701177
11711178 HASHMAP_FOREACH (l , m -> links , i ) {
11721179 LIST_FOREACH (servers , s , l -> dns_servers ) {
1173- r = append_dns_server (reply , s );
1180+ r = bus_dns_server_append (reply , s , true );
11741181 if (r < 0 )
11751182 return r ;
11761183 c ++ ;
@@ -1179,7 +1186,7 @@ static int bus_property_get_dns_servers(
11791186
11801187 if (c == 0 ) {
11811188 LIST_FOREACH (servers , s , m -> fallback_dns_servers ) {
1182- r = append_dns_server (reply , s );
1189+ r = bus_dns_server_append (reply , s , true );
11831190 if (r < 0 )
11841191 return r ;
11851192 }
@@ -1339,17 +1346,34 @@ static int bus_method_reset_statistics(sd_bus_message *message, void *userdata,
13391346 return sd_bus_reply_method_return (message , NULL );
13401347}
13411348
1342- static int get_unmanaged_link (Manager * m , int ifindex , Link * * ret , sd_bus_error * error ) {
1349+ static int get_any_link (Manager * m , int ifindex , Link * * ret , sd_bus_error * error ) {
13431350 Link * l ;
13441351
13451352 assert (m );
1353+ assert (ret );
13461354
13471355 if (ifindex <= 0 )
13481356 return sd_bus_error_setf (error , SD_BUS_ERROR_INVALID_ARGS , "Invalid interface index" );
13491357
13501358 l = hashmap_get (m -> links , INT_TO_PTR (ifindex ));
13511359 if (!l )
13521360 return sd_bus_error_setf (error , BUS_ERROR_NO_SUCH_LINK , "Link %i not known" , ifindex );
1361+
1362+ * ret = l ;
1363+ return 0 ;
1364+ }
1365+
1366+ static int get_unmanaged_link (Manager * m , int ifindex , Link * * ret , sd_bus_error * error ) {
1367+ Link * l ;
1368+ int r ;
1369+
1370+ assert (m );
1371+ assert (ret );
1372+
1373+ r = get_any_link (m , ifindex , & l , error );
1374+ if (r < 0 )
1375+ return r ;
1376+
13531377 if (l -> flags & IFF_LOOPBACK )
13541378 return sd_bus_error_setf (error , BUS_ERROR_LINK_BUSY , "Link %s is loopback device." , l -> name );
13551379 if (l -> is_managed )
@@ -1686,6 +1710,32 @@ static int bus_method_revert_link(sd_bus_message *message, void *userdata, sd_bu
16861710 return sd_bus_reply_method_return (message , NULL );
16871711}
16881712
1713+ static int bus_method_get_link (sd_bus_message * message , void * userdata , sd_bus_error * error ) {
1714+ _cleanup_free_ char * p = NULL ;
1715+ Manager * m = userdata ;
1716+ int r , ifindex ;
1717+ Link * l ;
1718+
1719+ assert (message );
1720+ assert (m );
1721+
1722+ assert_cc (sizeof (int ) == sizeof (int32_t ));
1723+
1724+ r = sd_bus_message_read (message , "i" , & ifindex );
1725+ if (r < 0 )
1726+ return r ;
1727+
1728+ r = get_any_link (m , ifindex , & l , error );
1729+ if (r < 0 )
1730+ return r ;
1731+
1732+ p = link_bus_path (l );
1733+ if (!p )
1734+ return - ENOMEM ;
1735+
1736+ return sd_bus_reply_method_return (message , "o" , p );
1737+ }
1738+
16891739static const sd_bus_vtable resolve_vtable [] = {
16901740 SD_BUS_VTABLE_START (0 ),
16911741 SD_BUS_PROPERTY ("LLMNRHostname" , "s" , NULL , offsetof(Manager , llmnr_hostname ), 0 ),
@@ -1701,6 +1751,7 @@ static const sd_bus_vtable resolve_vtable[] = {
17011751 SD_BUS_METHOD ("ResolveRecord" , "isqqt" , "a(iqqay)t" , bus_method_resolve_record , SD_BUS_VTABLE_UNPRIVILEGED ),
17021752 SD_BUS_METHOD ("ResolveService" , "isssit" , "a(qqqsa(iiay)s)aayssst" , bus_method_resolve_service , SD_BUS_VTABLE_UNPRIVILEGED ),
17031753 SD_BUS_METHOD ("ResetStatistics" , NULL , NULL , bus_method_reset_statistics , 0 ),
1754+ SD_BUS_METHOD ("GetLink" , "i" , "o" , bus_method_get_link , SD_BUS_VTABLE_UNPRIVILEGED ),
17041755 SD_BUS_METHOD ("SetLinkDNS" , "ia(iay)" , NULL , bus_method_set_link_dns_servers , 0 ),
17051756 SD_BUS_METHOD ("SetLinkDomains" , "ias" , NULL , bus_method_set_link_domains , 0 ),
17061757 SD_BUS_METHOD ("SetLinkLLMNR" , "is" , NULL , bus_method_set_link_llmnr , 0 ),
@@ -1774,6 +1825,14 @@ int manager_connect_bus(Manager *m) {
17741825 if (r < 0 )
17751826 return log_error_errno (r , "Failed to register object: %m" );
17761827
1828+ r = sd_bus_add_fallback_vtable (m -> bus , NULL , "/org/freedesktop/resolve1/link" , "org.freedesktop.resolve1.Link" , link_vtable , link_object_find , m );
1829+ if (r < 0 )
1830+ return log_error_errno (r , "Failed to register link objects: %m" );
1831+
1832+ r = sd_bus_add_node_enumerator (m -> bus , NULL , "/org/freedesktop/resolve1/link" , link_node_enumerator , m );
1833+ if (r < 0 )
1834+ return log_error_errno (r , "Failed to register link enumerator: %m" );
1835+
17771836 r = sd_bus_request_name (m -> bus , "org.freedesktop.resolve1" , 0 );
17781837 if (r < 0 )
17791838 return log_error_errno (r , "Failed to register name: %m" );
0 commit comments