0

I want to use the libnetlink library shipped with iproute2. I specified it's include dir with -I and it's lib dir with -L. However I still get some undefined reference errors.

test.c: In function ‘addqdisc’:
test.c:26:3: warning: ignoring return value of ‘rtnl_open’, declared with attribute warn_unused_result [-Wunused-result]
   26 |   rtnl_open(rth, 0);
      |   ^~~~~~~~~~~~~~~~~
test.c:27:3: warning: ignoring return value of ‘rtnl_talk’, declared with attribute warn_unused_result [-Wunused-result]
   27 |   rtnl_talk(rth, &req.n, NULL);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/ld: /tmp/ccCnXM9F.o: in function `addqdisc':
test.c:(.text+0x79): undefined reference to `rtnl_open'
/usr/bin/ld: test.c:(.text+0x97): undefined reference to `rtnl_talk'
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/types.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <libnetlink.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int addqdisc() {
  struct rtnl_handle *rth;
  struct {
    struct nlmsghdr n;
    struct tcmsg        t;
    char buf[64*1024];
  } req = {
    .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
    .n.nlmsg_flags = NLM_F_REQUEST | NLM_F_EXCL | NLM_F_CREATE,
    .n.nlmsg_type = RTM_NEWQDISC,
    .t.tcm_family = AF_UNSPEC,
  };

  rtnl_open(rth, 0);
  rtnl_talk(rth, &req.n, NULL);
}

int main() {
  addqdisc();
  return 0;
}

gcc test.c -o test -I/pwd/Downloads/linux-5.17/iproute2/include -l /pwd/Downloads/linux-5.17/iproute2/lib/libnetlink.a -lnetlink -static

Anyone knows why?

BitFriends
  • 379
  • 5
  • 18
  • 1
    You need to link with a specific library like in `-lnetlink` – Eugene Sh. Jun 21 '22 at 14:39
  • `-lnetlink` doesn't fix it. I don't even see why I would need it since the library is in `iproute2/lib` – BitFriends Jun 21 '22 at 14:41
  • 1
    `gcc` does not link automatically with whatever in the library path, you have to explicitly tell it. – Eugene Sh. Jun 21 '22 at 14:42
  • @EugeneSh. you mean I should use something like that `-l/pwd/Downloads/linux-5.17/iproute2/lib/libnetlink.a`? Because that isn't working too. It says `cannot find -l/pwd/Downloads/linux-5.17/iproute2/lib/libnetlink.a` – BitFriends Jun 21 '22 at 14:44
  • 3
    Add `-lnetlink` to the *end* of your command as in the original question (After `test.c`, as the order matters) – Eugene Sh. Jun 21 '22 at 14:46
  • @EugeneSh. no, it still says `cannot find -lnetlink` and `cannot find -l/pwd/Downloads/linux-5.17/iproute2/lib/libnetlink.a` – BitFriends Jun 21 '22 at 14:48
  • 2
    `gcc -I/pwd/Downloads/linux-5.17/iproute2/include -L/pwd/Downloads/linux-5.17/iproute2/lib test.c -lnetlink -o test -static` - try this command – Eugene Sh. Jun 21 '22 at 14:49
  • @EugeneSh. oh wow, that worked. I wasn't aware that the order is so important. Thanks – BitFriends Jun 21 '22 at 14:51
  • 1
    See this (for c++, but the same idea): https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc – Eugene Sh. Jun 21 '22 at 14:52

0 Answers0