Skip to content

Commit 368a00f

Browse files
authored
Merge pull request managarm#1705 from no92/if_nameindex
Implement if_nameindex
2 parents 4464ad3 + a0c572d commit 368a00f

20 files changed

Lines changed: 180 additions & 11 deletions

File tree

options/internal/include/mlibc/all-sysdeps.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <bits/ensure.h>
88
#include <errno.h>
99
#include <mlibc/sysdeps.hpp>
10+
#include <mlibc/sysdep-traits.hpp>
1011
#include <utility>
1112

1213
namespace mlibc {
@@ -85,6 +86,8 @@ static_assert(IsImplemented<VmUnmap>);
8586
static_assert(IsImplemented<TcbSet>);
8687
// ANCHOR_END: mandatory-sysdeps
8788

89+
static_assert(AllSysdepTraits<SysdepTraits>);
90+
8891
} // namespace mlibc
8992

9093
#endif /* MLIBC_ALL_SYSDEPS */

options/internal/include/mlibc/sysdep-signatures.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ SYSDEP_FUNC(SetRegid, gid_t rgid, gid_t egid);
235235
SYSDEP_FUNC(GetLoginR, char *name, size_t name_len);
236236
SYSDEP_FUNC(IfIndextoname, unsigned int index, char *name);
237237
SYSDEP_FUNC(IfNametoindex, const char *name, unsigned int *ret);
238+
SYSDEP_FUNC(IfNameindex, struct if_nameindex **out);
239+
SYSDEP_FUNC_RET(void, IfFreeNameindex, struct if_nameindex *ifn);
238240
SYSDEP_FUNC(Ptsname, int fd, char *buffer, size_t length);
239241
SYSDEP_FUNC(Unlockpt, int fd);
240242
SYSDEP_FUNC(ThreadSetname, void *tcb, const char *name);
@@ -309,6 +311,7 @@ SYSDEP_FUNC(Statfs, const char *path, struct statfs *buf);
309311
SYSDEP_FUNC(Fstatfs, int fd, struct statfs *buf);
310312
SYSDEP_FUNC(Statx, int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf);
311313
SYSDEP_FUNC(Getifaddrs, struct ifaddrs **);
314+
SYSDEP_FUNC_RET(void, Freeifaddrs, struct ifaddrs *ifa);
312315
SYSDEP_FUNC(Sendfile, int outfd, int infd, off_t *offset, size_t count, ssize_t *out);
313316
SYSDEP_FUNC(Syncfs, int fd);
314317
SYSDEP_FUNC(Unshare, int flags);

options/internal/include/mlibc/sysdep-tags.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ struct RiscvFlushIcache {};
195195
#include <fcntl.h>
196196
#include <mlibc/fsfd_target.hpp>
197197
#include <mqueue.h>
198+
#include <net/if.h>
198199
#include <poll.h>
199200
#include <sched.h>
200201
#include <stdarg.h>
@@ -495,6 +496,10 @@ struct GetLoginR {};
495496
struct IfIndextoname {};
496497
// int sys_if_nametoindex(const char *name, unsigned int *ret);
497498
struct IfNametoindex {};
499+
// int sys_if_nameindex(struct if_nameindex **out);
500+
struct IfNameindex {};
501+
// void sys_if_freenameindex(struct if_nameindex *ifn);
502+
struct IfFreeNameindex {};
498503
// int sys_ptsname(int fd, char *buffer, size_t length);
499504
struct Ptsname {};
500505
// int sys_unlockpt(int fd);
@@ -654,6 +659,8 @@ struct Fstatfs {};
654659
struct Statx {};
655660
// int sys_getifaddrs(struct ifaddrs **);
656661
struct Getifaddrs {};
662+
// void sys_freeifaddrs(struct ifaddrs *ifa);
663+
struct Freeifaddrs {};
657664
// int sys_sendfile(int outfd, int infd, off_t *offset, size_t count, ssize_t *out);
658665
struct Sendfile {};
659666
// int sys_syncfs(int fd);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
#include <type_traits>
4+
5+
template <typename T>
6+
concept AllSysdepTraits = requires {
7+
typename std::bool_constant<T::usesRtNetlink>;
8+
};

options/linux/generic/ifaddrs.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ int getifaddrs(struct ifaddrs **ifap) {
1313
}
1414

1515
void freeifaddrs(struct ifaddrs *ifa) {
16-
while (ifa != nullptr) {
17-
ifaddrs *current = ifa;
18-
ifa = ifa->ifa_next;
19-
getAllocator().free(current);
20-
}
16+
if constexpr (mlibc::IsImplemented<Freeifaddrs>)
17+
mlibc::sysdep_or_panic<Freeifaddrs>(ifa);
2118
}

options/posix/generic/net-if.cpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
#include <errno.h>
22
#include <net/if.h>
3-
#include <stdlib.h>
43

54
#include <bits/ensure.h>
5+
#include <frg/vector.hpp>
66
#include <mlibc/all-sysdeps.hpp>
7+
#include <mlibc/allocator.hpp>
78
#include <mlibc/debug.hpp>
89

9-
void if_freenameindex(struct if_nameindex *) {
10-
mlibc::infoLogger() << "mlibc: if_freenameindex is a no-op" << frg::endlog;
10+
#if __MLIBC_LINUX_OPTION
11+
#include <generic-helpers/netlink.hpp>
12+
#endif // __MLIBC_LINUX_OPTION
13+
14+
void if_freenameindex(struct if_nameindex *p) {
15+
#if __MLIBC_LINUX_OPTION
16+
if constexpr (mlibc::SysdepTraits::usesRtNetlink) {
17+
if (!p)
18+
return;
19+
20+
for (auto c = p; c->if_index || c->if_name; c++) {
21+
if (c->if_name)
22+
getAllocator().free(c->if_name);
23+
}
24+
25+
getAllocator().free(p);
26+
return;
27+
}
28+
#endif
29+
30+
if constexpr (mlibc::IsImplemented<IfFreeNameindex>)
31+
mlibc::sysdep_or_panic<IfFreeNameindex>(p);
1132
}
1233

1334
char *if_indextoname(unsigned int index, char *name) {
@@ -20,9 +41,29 @@ char *if_indextoname(unsigned int index, char *name) {
2041
}
2142

2243
struct if_nameindex *if_nameindex(void) {
23-
mlibc::infoLogger() << "mlibc: if_nameindex() is a no-op" << frg::endlog;
24-
errno = ENOSYS;
25-
return nullptr;
44+
#if __MLIBC_LINUX_OPTION
45+
if constexpr (mlibc::SysdepTraits::usesRtNetlink) {
46+
NetlinkHelper nl;
47+
frg::vector<struct if_nameindex, MemoryAllocator> list{getAllocator()};
48+
49+
bool link_ret = nl.send_request(RTM_GETLINK) && nl.recv(&if_nameindex_callback, &list);
50+
__ensure(link_ret);
51+
52+
list.emplace_back(0, nullptr);
53+
auto ret = list.data();
54+
list.detach();
55+
56+
return ret;
57+
}
58+
#endif
59+
60+
struct if_nameindex *out = nullptr;
61+
if(int e = mlibc::sysdep_or_enosys<IfNameindex>(&out); e) {
62+
errno = e;
63+
return nullptr;
64+
}
65+
66+
return out;
2667
}
2768

2869
unsigned int if_nametoindex(const char *name) {

sysdeps/astral/include/mlibc/sysdeps.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,8 @@ struct AstralSysdepTags :
141141
template<typename Tag>
142142
using Sysdeps = SysdepOf<AstralSysdepTags, Tag>;
143143

144+
struct SysdepTraits {
145+
static constexpr bool usesRtNetlink = false;
146+
};
147+
144148
} // namespace mlibc

sysdeps/demo/include/mlibc/sysdeps.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,8 @@ struct DemoSysdepTags :
2727
template<typename Tag>
2828
using Sysdeps = SysdepOf<DemoSysdepTags, Tag>;
2929

30+
struct SysdepTraits {
31+
static constexpr bool usesRtNetlink = false;
32+
};
33+
3034
} // namespace mlibc

sysdeps/generic-helpers/include/generic-helpers/netlink.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <frg/allocation.hpp>
44
#include <frg/span.hpp>
5+
#include <frg/vector.hpp>
56
#include <ifaddrs.h>
67
#include <linux/rtnetlink.h>
78
#include <mlibc/all-sysdeps.hpp>
@@ -286,4 +287,28 @@ void getifaddrs_callback(void *context, const nlmsghdr *hdr) {
286287
}
287288
}
288289

290+
/**
291+
* Callback function to be used with NetlinkHelper for implementing `sys_if_nameindex` by using rtnetlink.
292+
*/
293+
void if_nameindex_callback(void *context, const nlmsghdr *hdr) {
294+
auto list = reinterpret_cast<frg::vector<struct if_nameindex, MemoryAllocator> *>(context);
295+
296+
if (hdr->nlmsg_type == RTM_NEWLINK) {
297+
ifinfomsg *ifi = reinterpret_cast<ifinfomsg *>(NLMSG_DATA(hdr));
298+
299+
rtattr *rta = IFLA_RTA(ifi);
300+
size_t rta_len = IFLA_PAYLOAD(hdr);
301+
302+
while (RTA_OK(rta, rta_len)) {
303+
if (rta->rta_type == IFLA_IFNAME) {
304+
auto name = strndup(reinterpret_cast<char *>(RTA_DATA(rta)), RTA_PAYLOAD(rta));
305+
list->emplace_back(ifi->ifi_index, name);
306+
return;
307+
}
308+
309+
rta = RTA_NEXT(rta, rta_len);
310+
}
311+
}
312+
}
313+
289314
} // namespace

sysdeps/ironclad/include/mlibc/sysdeps.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,8 @@ struct IroncladSysdepTags :
158158
template<typename Tag>
159159
using Sysdeps = SysdepOf<IroncladSysdepTags, Tag>;
160160

161+
struct SysdepTraits {
162+
static constexpr bool usesRtNetlink = false;
163+
};
164+
161165
} // namespace mlibc

0 commit comments

Comments
 (0)