When running 'top', I sometimes see RADVD consuming a lot of CPU (some times close to 50%). I put some debug statements into RADVD, and have found that RADVD listens to a netlink socket, and basically reloads the configuration file for every netlink message it receives, regardless of content. I have seen more than 60 reloads in a single second, which are generally triggered for Wireless Extension events for one of the wireless interfaces. There currently is a patch (feeds/packages/ipv6/radvd/patches/100-silent-netlink-config-reload.patch) that attempts to silence the logging of the reloads, but this is really just masking the problem, and poorly at that. It seems like RADVD should be filtering the netlink messages down to what it cares about, and only then triggering the reload.
I took a cut at a patch (attached) that seems reasonable to me; but since I have just a very basic understanding of RADVD and netlink, the patch is likely incomplete/wrong. Any feedback would be appreciated; or if someone would like to expand on this, feel free. Thanks, Nathan --- /dev/null 1982-12-26 14:57:26.236767395 -0800 +++ feeds/packages/ipv6/radvd/patches/101-reduce-netlink-config-reload.patch 2013-01-01 19:06:30.543780805 -0800 @@ -0,0 +1,48 @@ +--- a/netlink.c ++++ b/netlink.c +@@ -41,7 +41,10 @@ + struct msghdr msg = { (void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; + struct nlmsghdr *nh; + struct ifinfomsg * ifinfo; ++ struct rtattr *rta; ++ int rta_len; + char ifname[IF_NAMESIZE] = {""}; ++ int reloaded = 0; + + len = recvmsg (sock, &msg, 0); + if (len == -1) { +@@ -59,15 +62,26 @@ + } + + /* Continue with parsing payload. */ +- ifinfo = NLMSG_DATA(nh); +- if_indextoname(ifinfo->ifi_index, ifname); +- if (ifinfo->ifi_flags & IFF_RUNNING) { +- dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is running", ifname, ifinfo->ifi_index); ++ if (nh->nlmsg_type == RTM_NEWLINK || nh->nlmsg_type == RTM_DELLINK || nh->nlmsg_type == RTM_SETLINK) { ++ ifinfo = (struct ifinfomsg *)NLMSG_DATA(nh); ++ if_indextoname(ifinfo->ifi_index, ifname); ++ rta = IFLA_RTA(NLMSG_DATA(nh)); ++ rta_len = nh->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); ++ for (; RTA_OK(rta, rta_len); rta = RTA_NEXT(rta, rta_len)) { ++ if (rta->rta_type == IFLA_OPERSTATE || rta->rta_type == IFLA_LINKMODE) { ++ if (ifinfo->ifi_flags & IFF_RUNNING) { ++ dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is running", ifname, ifinfo->ifi_index); ++ } ++ else { ++ dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is *NOT* running", ifname, ifinfo->ifi_index); ++ } ++ if (!reloaded) { ++ reload_config(LOG_DEBUG); ++ reloaded = 1; ++ } ++ } ++ } + } +- else { +- dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is *NOT* running", ifname, ifinfo->ifi_index); +- } +- reload_config(LOG_DEBUG); + } + } + _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel