On Mon, Mar 13, 2017 at 4:32 PM, Nadav Har'El <[email protected]
<mailto:[email protected]>> wrote:
We need to understand how IFF_SLAVE and IFF_SIMPLEX came to have
the same bit... Did we get one from BSD and one from Linux?
Indeed this seems to be the case. The bits which Linux applications
expect are in /usr/include/net/if.h or in OSv, include/api/net/if.h
But the bits the internal BSD-based network stack uses are defined in
bsbsd/sys/net/if.h.
Those are not the same bits, as we noticed.
So, in bsd/sys/compat/linux/linux_ioctl.cc in case SIOCGIFFLAGS, we
call a function linux_gifflags() to translate the flags from the
internal BSD bits to the Linux bits.
But it appears that this function doesn't do all the necessary
translations - in particularly the thing with IFF_SLAVE vs IFF_SIMPLEX.
Can you please open an issue about it?
Signed-off-by: Justin Cinkelj <[email protected]
<mailto:[email protected]>>
---
tests/tst-ifaddrs.cc | 121
++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 120 insertions(+), 1 deletion(-)
diff --git a/tests/tst-ifaddrs.cc b/tests/tst-ifaddrs.cc
index bfb682c..983a466 100644
--- a/tests/tst-ifaddrs.cc
+++ b/tests/tst-ifaddrs.cc
@@ -22,6 +22,8 @@
#include <linux/if_packet.h> // for sockaddr_ll
+int main2(int argc, char *argv[]);
+
static int tests = 0, fails = 0;
template<typename T>
@@ -62,7 +64,7 @@ bool do_expectge(T actual, T expected, const
char *actuals, const char *expected
do_expectge(var, 0, #call, "0", __FILE__, __LINE__); \
do_expect(errno, 0, #call " errno", "0", __FILE__,
__LINE__);
-int main()
+int main(int argc, char *argv[])
{
// Start by testing if_nameindex() because Musl's
get_ifaddrs() actually
// uses that, and the second won't work if the first doesn't.
@@ -174,6 +176,123 @@ noni:
freeifaddrs(ifaddr);
+ main2(argc, argv);
+
std::cout << "SUMMARY: " << tests << " tests, " << fails
<< " failures\n";
return fails == 0 ? 0 : 1;
}
+
+
+//#include <stdio.h>
+//#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+//#include <sys/socket.h>
+#include <sys/ioctl.h>
+//#include <linux/if.h>
+//#include <netinet/in.h>
+//#include <arpa/inet.h>
+#include <net/if.h>
+
+#define print_flag(flags, IFF_X) { printf( " %d = " #IFF_X
" (0x%08x)\n", (flags & IFF_X) != 0, IFF_X); }
+void print_all_flags(uint32_t flags)
+{
+printf( " flags = 0x%08x\n", flags);
+
+print_flag(flags, IFF_UP);
+print_flag(flags, IFF_BROADCAST);
+print_flag(flags, IFF_DEBUG);
+print_flag(flags, IFF_LOOPBACK);
+print_flag(flags, IFF_POINTOPOINT);
+print_flag(flags, IFF_NOTRAILERS);
+print_flag(flags, IFF_RUNNING);
+print_flag(flags, IFF_NOARP);
+print_flag(flags, IFF_PROMISC);
+print_flag(flags, IFF_ALLMULTI);
+print_flag(flags, IFF_MASTER);
+print_flag(flags, IFF_SLAVE);
+print_flag(flags, IFF_MULTICAST);
+print_flag(flags, IFF_PORTSEL);
+print_flag(flags, IFF_AUTOMEDIA);
+print_flag(flags, IFF_DYNAMIC);
+}
+
+#define MAX_IFCONF_SIZE 1024
+#define DEFAULT_NUMBER_INTERFACES 10
+int main2(int argc, char *argv[])
+{
+ int sd;
+ struct ifconf ifconf;
+ int ifc_len;
+ struct ifreq *ifr;
+ const char* iface_name = nullptr;
+
+ printf("\n\n/* main2
------------------------------------------------*/\n");
+
+ if (argc >= 2) {
+ iface_name = argv[1];
+ }
+ else {
+ iface_name = "eth0";
+ }
+
+ fprintf(stderr, "DBG %s:%d %s: start iface_name=%s\n",
__FILE__,__LINE__,__FUNCTION__, iface_name);
+ sd = socket(AF_INET, SOCK_DGRAM, 0);
+ expectge(sd, 0);
+
+ ifc_len = sizeof(struct ifreq) * DEFAULT_NUMBER_INTERFACES;
+ ifconf.ifc_len = ifc_len;
+ ifconf.ifc_req = (ifreq*)malloc(ifc_len);
+ if (NULL == ifconf.ifc_req) {
+ close(sd);
+ return -1;
+ }
+
+ memset(ifconf.ifc_req, 0, ifconf.ifc_len);
+
+ if (ioctl(sd, SIOCGIFCONF, &ifconf) < 0) {
+ printf("opal_ifinit: ioctl(SIOCGIFCONF) \
+ failed with errno=%d\n",
+ errno);
+ free(ifconf.ifc_req);
+ close(sd);
+ return -1;
+ }
+
+ int ii;
+ printf("ifconf.ifc_len = %d, ifconf.ifc_req=%p, sz=%d\n",
ifconf.ifc_len, ifconf.ifc_req, sizeof(ifconf.ifc_req[0]));
+ for(ii=0; ii<ifconf.ifc_len; ii+=sizeof(ifreq)) {
+ ifr = (ifreq*) (((char*)ifconf.ifc_req) + ii);
+ printf("ii =%d/%d name=%s\n", ii, ifconf.ifc_len,
ifr->ifr_name);
+ if (AF_INET != ifr->ifr_addr.sa_family) {
+ fprintf(stderr, "DBG %s:%d %s: not AF_INET\n",
__FILE__,__LINE__,__FUNCTION__);
+ continue;
+ }
+ if (strcmp(iface_name, ifr->ifr_name) == 0) {
+ printf("iface %s found\n", iface_name);
+ break;
+ }
+ }
+ if (ii >= ifconf.ifc_len) {
+ printf("ifr == nullprt :/, dev %s not found\n",
iface_name);
+ return 0;
+ }
+
+ if (ioctl(sd, SIOCGIFFLAGS, ifr) < 0) {
+ printf("opal_ifinit: ioctl(SIOCGIFFLAGS) failed with
errno=%d\n", errno);
+ fprintf(stderr, "DBG %s:%d %s: SIOCGIFFLAGS
failed\n", __FILE__,__LINE__,__FUNCTION__);
+ }
+
+ print_all_flags(ifr->ifr_flags);
+ printf("%-8s : flags=0x%08x IFF_SLAVE=%d IFF_UP=%d
IFF_BROADCAST=%d\n", ifr->ifr_name,
+ ifr->ifr_flags, ifr->ifr_flags & IFF_SLAVE,
ifr->ifr_flags & IFF_UP, ifr->ifr_flags & IFF_BROADCAST);
+ if ((ifr->ifr_flags & IFF_UP) == 0) {
+ fprintf(stderr, "DBG %s:%d %s: not IFF_UP\n",
__FILE__,__LINE__,__FUNCTION__);
+ }
+ /* Is this a slave to a load balancer or bonded channel?
+ If so, don't use it -- pick up the master instead */
+ if ((ifr->ifr_flags & IFF_SLAVE) != 0) {
+ fprintf(stderr, "DBG %s:%d %s: is IFF_SLAVE\n",
__FILE__,__LINE__,__FUNCTION__);
+ }
+
+}
--
2.9.3
--
You received this message because you are subscribed to the
Google Groups "OSv Development" group.
To unsubscribe from this group and stop receiving emails from
it, send an email to [email protected]
<mailto:osv-dev%[email protected]>.
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.