Skip to content

Commit cc9a831

Browse files
committed
linux-user: netlink: add netlink neighbour emulation
Fixes various warnings in the testsuite while building gupnp: gssdp-net-DEBUG: Failed to send netlink message: Operation not supported gupnp-context-DEBUG: Mismatch between host header and host IP (example.com, expected: 127.0.0.1) gupnp-context-DEBUG: Mismatch between host header and host port (80, expected 4711) gupnp-context-DEBUG: Mismatch between host header and host IP (192.168.1.2, expected: 127.0.0.1) gupnp-context-DEBUG: Mismatch between host header and host IP (fe80::01, expected: 127.0.0.1) gupnp-context-DEBUG: Mismatch between host header and host port (80, expected 4711) gupnp-context-DEBUG: Failed to parse HOST header from request: Invalid IPv6 address ?[fe80::01%1]? in URI gupnp-context-DEBUG: Failed to parse HOST header from request: Invalid IPv6 address ?[fe80::01%eth0]? in URI gupnp-context-DEBUG: Failed to parse HOST header from request: Could not parse port ?:1? in URI gupnp-context-DEBUG: Mismatch between host header and host IP (example.com, expected: ::1) gupnp-context-DEBUG: Mismatch between host header and host port (80, expected 4711) gupnp-context-DEBUG: Mismatch between host header and host IP (example.com, expected: ::1) gupnp-context-DEBUG: Mismatch between host header and host port (80, expected 4711) gupnp-context-DEBUG: Mismatch between host header and host IP (example.com, expected: ::1) Signed-off-by: Helge Deller <deller@gmx.de> Reviewed-by: Laurent Vivier <laurent@vivier.eu>
1 parent f65464c commit cc9a831

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

linux-user/fd-trans.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,16 @@
2525
#ifdef CONFIG_RTNETLINK
2626
#include <linux/rtnetlink.h>
2727
#include <linux/if_bridge.h>
28+
#include <linux/neighbour.h>
2829
#endif
2930
#include "qemu.h"
3031
#include "user-internals.h"
3132
#include "fd-trans.h"
3233
#include "signal-common.h"
3334

35+
#define NDM_RTA(r) ((struct rtattr*)(((char*)(r)) + \
36+
NLMSG_ALIGN(sizeof(struct ndmsg))))
37+
3438
enum {
3539
QEMU_IFA_UNSPEC,
3640
QEMU_IFA_ADDRESS,
@@ -1226,6 +1230,35 @@ static abi_long host_to_target_data_route_rtattr(struct rtattr *rtattr)
12261230
return 0;
12271231
}
12281232

1233+
static abi_long host_to_target_data_neigh_rtattr(struct rtattr *rtattr)
1234+
{
1235+
struct nda_cacheinfo *ndac;
1236+
uint32_t *u32;
1237+
1238+
switch (rtattr->rta_type) {
1239+
case NDA_UNSPEC:
1240+
case NDA_DST:
1241+
case NDA_LLADDR:
1242+
break;
1243+
case NDA_PROBES:
1244+
u32 = RTA_DATA(rtattr);
1245+
*u32 = tswap32(*u32);
1246+
break;
1247+
case NDA_CACHEINFO:
1248+
ndac = RTA_DATA(rtattr);
1249+
ndac->ndm_confirmed = tswap32(ndac->ndm_confirmed);
1250+
ndac->ndm_used = tswap32(ndac->ndm_used);
1251+
ndac->ndm_updated = tswap32(ndac->ndm_updated);
1252+
ndac->ndm_refcnt = tswap32(ndac->ndm_refcnt);
1253+
break;
1254+
default:
1255+
qemu_log_mask(LOG_UNIMP, "Unknown host to target NEIGH type: %d\n",
1256+
rtattr->rta_type);
1257+
break;
1258+
}
1259+
return 0;
1260+
}
1261+
12291262
static abi_long host_to_target_link_rtattr(struct rtattr *rtattr,
12301263
uint32_t rtattr_len)
12311264
{
@@ -1247,12 +1280,20 @@ static abi_long host_to_target_route_rtattr(struct rtattr *rtattr,
12471280
host_to_target_data_route_rtattr);
12481281
}
12491282

1283+
static abi_long host_to_target_neigh_rtattr(struct rtattr *rtattr,
1284+
uint32_t rtattr_len)
1285+
{
1286+
return host_to_target_for_each_rtattr(rtattr, rtattr_len,
1287+
host_to_target_data_neigh_rtattr);
1288+
}
1289+
12501290
static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
12511291
{
12521292
uint32_t nlmsg_len;
12531293
struct ifinfomsg *ifi;
12541294
struct ifaddrmsg *ifa;
12551295
struct rtmsg *rtm;
1296+
struct ndmsg *ndm;
12561297

12571298
nlmsg_len = nlh->nlmsg_len;
12581299
switch (nlh->nlmsg_type) {
@@ -1279,6 +1320,17 @@ static abi_long host_to_target_data_route(struct nlmsghdr *nlh)
12791320
nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
12801321
}
12811322
break;
1323+
case RTM_NEWNEIGH:
1324+
case RTM_DELNEIGH:
1325+
case RTM_GETNEIGH:
1326+
if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ndm))) {
1327+
ndm = NLMSG_DATA(nlh);
1328+
ndm->ndm_ifindex = tswap32(ndm->ndm_ifindex);
1329+
ndm->ndm_state = tswap16(ndm->ndm_state);
1330+
host_to_target_neigh_rtattr(NDM_RTA(ndm),
1331+
nlmsg_len - NLMSG_LENGTH(sizeof(*ndm)));
1332+
}
1333+
break;
12821334
case RTM_NEWROUTE:
12831335
case RTM_DELROUTE:
12841336
case RTM_GETROUTE:
@@ -1426,6 +1478,35 @@ static abi_long target_to_host_data_addr_rtattr(struct rtattr *rtattr)
14261478
return 0;
14271479
}
14281480

1481+
static abi_long target_to_host_data_neigh_rtattr(struct rtattr *rtattr)
1482+
{
1483+
struct nda_cacheinfo *ndac;
1484+
uint32_t *u32;
1485+
1486+
switch (rtattr->rta_type) {
1487+
case NDA_UNSPEC:
1488+
case NDA_DST:
1489+
case NDA_LLADDR:
1490+
break;
1491+
case NDA_PROBES:
1492+
u32 = RTA_DATA(rtattr);
1493+
*u32 = tswap32(*u32);
1494+
break;
1495+
case NDA_CACHEINFO:
1496+
ndac = RTA_DATA(rtattr);
1497+
ndac->ndm_confirmed = tswap32(ndac->ndm_confirmed);
1498+
ndac->ndm_used = tswap32(ndac->ndm_used);
1499+
ndac->ndm_updated = tswap32(ndac->ndm_updated);
1500+
ndac->ndm_refcnt = tswap32(ndac->ndm_refcnt);
1501+
break;
1502+
default:
1503+
qemu_log_mask(LOG_UNIMP, "Unknown target NEIGH type: %d\n",
1504+
rtattr->rta_type);
1505+
break;
1506+
}
1507+
return 0;
1508+
}
1509+
14291510
static abi_long target_to_host_data_route_rtattr(struct rtattr *rtattr)
14301511
{
14311512
uint32_t *u32;
@@ -1464,6 +1545,13 @@ static void target_to_host_addr_rtattr(struct rtattr *rtattr,
14641545
target_to_host_data_addr_rtattr);
14651546
}
14661547

1548+
static void target_to_host_neigh_rtattr(struct rtattr *rtattr,
1549+
uint32_t rtattr_len)
1550+
{
1551+
target_to_host_for_each_rtattr(rtattr, rtattr_len,
1552+
target_to_host_data_neigh_rtattr);
1553+
}
1554+
14671555
static void target_to_host_route_rtattr(struct rtattr *rtattr,
14681556
uint32_t rtattr_len)
14691557
{
@@ -1476,6 +1564,7 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
14761564
struct ifinfomsg *ifi;
14771565
struct ifaddrmsg *ifa;
14781566
struct rtmsg *rtm;
1567+
struct ndmsg *ndm;
14791568

14801569
switch (nlh->nlmsg_type) {
14811570
case RTM_NEWLINK:
@@ -1502,6 +1591,17 @@ static abi_long target_to_host_data_route(struct nlmsghdr *nlh)
15021591
NLMSG_LENGTH(sizeof(*ifa)));
15031592
}
15041593
break;
1594+
case RTM_NEWNEIGH:
1595+
case RTM_DELNEIGH:
1596+
case RTM_GETNEIGH:
1597+
if (nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(*ndm))) {
1598+
ndm = NLMSG_DATA(nlh);
1599+
ndm->ndm_ifindex = tswap32(ndm->ndm_ifindex);
1600+
ndm->ndm_state = tswap16(ndm->ndm_state);
1601+
target_to_host_neigh_rtattr(NDM_RTA(ndm), nlh->nlmsg_len -
1602+
NLMSG_LENGTH(sizeof(*ndm)));
1603+
}
1604+
break;
15051605
case RTM_NEWROUTE:
15061606
case RTM_DELROUTE:
15071607
case RTM_GETROUTE:

0 commit comments

Comments
 (0)