Hello, we have a problem with ifstated detecting state change on multiple CARP interfaces.
After digging deeper, it seems that reading on the routing socket does not give us all the state changes that we'd expect. We tried with the latest snapshot kernel and got the same behavior. Our CARP interfaces are as follows: carp0 carp1 carp1010 (VLAN on carp1) carp1011 (Another VLAN on carp1) carp2 carp3 The condition we'd like to test is: carp_up = 'carp0.link.up \ && carp1.link.up \ && carp1010.link.up \ && carp1011.link.up \ && carp2.link.up \ && carp3.link.up' Doing a little check using a quick C program (see below), and playing with the demote counter, we can clearly see why the condition is not always met as it should: # ./getifinfo & [1] 20942 # ifconfig -g carp carpdemote 50 carp0 -> LINK_STATE_DOWN carp2 -> LINK_STATE_DOWN carp3 -> LINK_STATE_DOWN carp1010 -> LINK_STATE_DOWN carp1011 -> LINK_STATE_DOWN # ifconfig -g carp -carpdemote 50 carp1 -> LINK_STATE_UP carp1010 -> LINK_STATE_UP carp0 -> LINK_STATE_UP carp2 -> LINK_STATE_UP carp1011 -> LINK_STATE_UP carp3 -> LINK_STATE_UP # ifconfig -g carp carpdemote 50 carp0 -> LINK_STATE_DOWN carp1 -> LINK_STATE_DOWN carp2 -> LINK_STATE_DOWN carp3 -> LINK_STATE_DOWN carp1010 -> LINK_STATE_DOWN # ifconfig -g carp -carpdemote 50 carp0 -> LINK_STATE_UP carp1 -> LINK_STATE_UP carp1010 -> LINK_STATE_UP carp1011 -> LINK_STATE_UP # Question is, is it normal that the routing socket doesn't report all changes? Anyone else having similar issues? Thanks in advance, -- Pascal getifinfo.c: ---- #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> #include <net/route.h> #include <ifaddrs.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <err.h> char *if_states[] = { "LINK_STATE_UNKNOWN", "LINK_STATE_DOWN", "LINK_STATE_UP", "LINK_STATE_HALF_DUPLEX", "LINK_STATE_FULL_DUPLEX" }; int main(int argc, char **argv) { int rt_fd; char msg[2048]; struct ifaddrs *ifap, *ifa; struct rt_msghdr *rtm = (struct rt_msghdr *)&msg; struct if_msghdr *ifm = (struct if_msghdr *)&msg; int len; char ifs[64][16]; if (getifaddrs(&ifap)) err(1, "getifaddrs"); for (ifa = ifap; ifa->ifa_next != NULL; ifa = ifa->ifa_next) { strlcpy(ifs[if_nametoindex(ifa->ifa_name)], ifa->ifa_name, 16); } freeifaddrs(ifap); if ((rt_fd = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) err(1, "no routing socket"); while ((len = read(rt_fd, msg, sizeof(msg)))) { if (len < sizeof(struct rt_msghdr)) { warnx("len < sizeof(struct rt_msghdr)"); continue; } if (rtm->rtm_version != RTM_VERSION) continue; if (rtm->rtm_type != RTM_IFINFO) continue; printf("%s -> %s\n", ifs[ifm->ifm_index], if_states[ifm->ifm_data.ifi_link_state]); } return 0; }