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

Reply via email to