Skip to content

Commit

Permalink
net/linux/addrs: fix point-to-point peer address bug
Browse files Browse the repository at this point in the history
On point-to-point networks IFA_ADDRESS points to the peer address
instead of the local address.

    /*
     * Important comment:
     * IFA_ADDRESS is prefix address, rather than local interface address.
     * It makes no difference for normally configured broadcast interfaces,
     * but for point-to-point IFA_ADDRESS is DESTINATION address,
     * local address is supplied in IFA_LOCAL attribute.
    */
  • Loading branch information
sreimers committed Dec 23, 2024
1 parent db05533 commit a54a490
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions src/net/linux/addrs.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ static bool parse_msg_addr(struct nlmsghdr *msg, ssize_t len,
for (nlh = msg; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
struct sa sa;
uint32_t flags;
void *addr;
char if_name[IF_NAMESIZE];

if (nlh->nlmsg_type == NLMSG_DONE) {
Expand Down Expand Up @@ -109,13 +110,19 @@ static bool parse_msg_addr(struct nlmsghdr *msg, ssize_t len,
continue;
}

if (rta_tb[IFA_LOCAL])
/* looks like point-to-point network, use local
* address, instead of peer */
addr = RTA_DATA(rta_tb[IFA_LOCAL]);
else
addr = RTA_DATA(rta_tb[IFA_ADDRESS]);

if (ifa->ifa_family == AF_INET) {
sa_init(&sa, AF_INET);
sa.u.in.sin_addr.s_addr =
*(uint32_t *)RTA_DATA(rta_tb[IFA_ADDRESS]);
sa.u.in.sin_addr.s_addr = *(uint32_t *)addr;
}
else if (ifa->ifa_family == AF_INET6) {
sa_set_in6(&sa, RTA_DATA(rta_tb[IFA_ADDRESS]), 0);
sa_set_in6(&sa, addr, 0);
sa_set_scopeid(&sa, ifa->ifa_index);
}
else
Expand Down

0 comments on commit a54a490

Please sign in to comment.