android: fix the path of the tunnel node in the /dev tree
[olsrd.git] / lib / bmf / src / NetworkInterfaces.c
index efbaaff..27251c9 100644 (file)
 #include "ipcalc.h"
 #include "defs.h" /* olsr_cnf */
 #include "link_set.h" /* get_link_set() */
-#include "lq_route.h" /* MIN_LINK_QUALITY */
 #include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
 #include "net_olsr.h" /* ipequal */
 #include "lq_plugin.h"
+#include "kernel_tunnel.h"
 
 /* Plugin includes */
 #include "Packet.h" /* IFHWADDRLEN */
@@ -109,6 +109,9 @@ u_int32_t EtherTunTapIpMask = 0xFFFFFFFF;
  * May be overruled by setting the plugin parameter "BmfinterfaceIp". */
 u_int32_t EtherTunTapIpBroadcast = ETHERTUNTAPIPNOTSET;
 
+/* Whether or not the BMF network interface must be marked as persistent */
+int EtherTunTapPersistent = 1;
+
 /* Whether or not the configuration has overruled the default IP
  * configuration of the EtherTunTap interface */
 int TunTapIpOverruled = 0;
@@ -213,6 +216,32 @@ int SetBmfInterfaceIp(
   return 0;
 } /* SetBmfInterfaceIp */
 
+/* -------------------------------------------------------------------------
+ * Function   : SetBmfInterfacePersistent
+ * Description: Determine if the EtherTunTap interface must be marked
+ *              persistent or not
+ * Input      : value - yes/true/1  or no/false/0
+ *              data  - not used
+ *              addon - not used
+ * Output     : none
+ * Return     : success (0) or fail (1)
+ * Data Used  : EtherTunTapPersistent
+ * ------------------------------------------------------------------------- */
+int SetBmfInterfacePersistent(
+  const char* value,
+  void* data __attribute__((unused)),
+  set_plugin_parameter_addon addon __attribute__((unused)))
+{
+       if (strcasecmp(value, "yes") == 0 || strcasecmp(value, "true") == 0 || strcasecmp(value, "1") == 0) {
+               EtherTunTapPersistent = 1;
+       } else if (strcasecmp(value, "no") == 0 || strcasecmp(value, "false") == 0 || strcasecmp(value, "0") == 0) {
+               EtherTunTapPersistent = 0;
+       } else {
+               return 1;
+       }
+       return 0;
+} /* SetBmfInterfacePersistent */
+
 /* -------------------------------------------------------------------------
  * Function   : SetCapturePacketsOnOlsrInterfaces
  * Description: Overrule the default setting, enabling or disabling the
@@ -334,7 +363,7 @@ int DeactivateSpoofFilter(void)
     return 0;
   }
 
-  EthTapSpoofState = fgetc(procSpoof);
+  EthTapSpoofState = (char)fgetc(procSpoof);
   fclose(procSpoof);
 
   /* Open procfile for writing */
@@ -395,11 +424,12 @@ void RestoreSpoofFilter(void)
  * Description: Find the neighbors on a network interface to forward a BMF
  *              packet to
  * Input      : intf - the network interface
- *              source - the source IP address of the BMF packet 
+ *              source - the source IP address of the BMF packet, or NULL if
+ *                unknown or not applicable
  *              forwardedBy - the IP address of the node that forwarded the BMF
- *                packet
+ *                packet, or NULL if unknown or not applicable
  *              forwardedTo - the IP address of the node to which the BMF packet
- *                was directed
+ *                was directed, or NULL if unknown or not applicable
  * Output     : neighbors - list of (up to a number of 'FanOutLimit') neighbors.
  *              bestNeighbor - the best neighbor (in terms of lowest cost or ETX
  *                value)
@@ -415,6 +445,9 @@ void FindNeighbors(
   union olsr_ip_addr* forwardedTo,
   int* nPossibleNeighbors)
 {
+#ifndef NODEBUG
+  struct ipaddr_str buf;
+#endif /* NODEBUG */
   int i;
 
   /* Initialize */
@@ -432,9 +465,6 @@ void FindNeighbors(
     struct link_entry* walker;
 
     OLSR_FOR_ALL_LINK_ENTRIES(walker) {
-#ifndef NODEBUG
-      struct ipaddr_str buf;
-#endif
       union olsr_ip_addr* neighborMainIp;
 
       /* Consider only links from the specified interface */
@@ -445,7 +475,7 @@ void FindNeighbors(
 
       OLSR_PRINTF(
         8,
-        "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
+        "%s: ----> considering forwarding pkt on \"%s\" to %s\n",
         PLUGIN_NAME_SHORT,
         intf->ifName,
         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
@@ -456,12 +486,9 @@ void FindNeighbors(
        * passed IP addresses (if passed). Rely on short-circuit boolean evaluation. */
       if (source != NULL && ipequal(neighborMainIp, MainAddressOf(source)))
       {
-#ifndef NODEBUG
-        struct ipaddr_str buf;
-#endif
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is source of pkt\n",
+          "%s: ----> not forwarding to %s: is source of pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -471,12 +498,9 @@ void FindNeighbors(
       /* Rely on short-circuit boolean evaluation */
       if (forwardedBy != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedBy)))
       {
-#ifndef NODEBUG
-        struct ipaddr_str buf;
-#endif
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
+          "%s: ----> not forwarding to %s: is the node that forwarded the pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -486,12 +510,9 @@ void FindNeighbors(
       /* Rely on short-circuit boolean evaluation */
       if (forwardedTo != NULL && ipequal(neighborMainIp, MainAddressOf(forwardedTo)))
       {
-#ifndef NODEBUG
-        struct ipaddr_str buf;
-#endif
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
+          "%s: ----> not forwarding to %s: is the node to which the pkt was forwarded\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -540,12 +561,8 @@ void FindNeighbors(
       }
     }
 
-    /* TODO: get_link_set() is not thread-safe! */
     for (walker = get_link_set(); walker != NULL; walker = walker->next) 
     {
-#ifndef NODEBUG
-      struct ipaddr_str buf;
-#endif
       union olsr_ip_addr* neighborMainIp;
       struct link_entry* bestLinkToNeighbor;
       struct tc_entry* tcLastHop;
@@ -558,7 +575,7 @@ void FindNeighbors(
 
       OLSR_PRINTF(
         9,
-        "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
+        "%s: ----> considering forwarding pkt on \"%s\" to %s\n",
         PLUGIN_NAME_SHORT,
         intf->ifName,
         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
@@ -571,7 +588,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is source of pkt\n",
+          "%s: ----> not forwarding to %s: is source of pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -583,7 +600,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
+          "%s: ----> not forwarding to %s: is the node that forwarded the pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -595,7 +612,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
+          "%s: ----> not forwarding to %s: is the node to which the pkt was forwarded\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -608,7 +625,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: link is timing out\n",
+          "%s: ----> not forwarding to %s: link is timing out\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -618,15 +635,14 @@ void FindNeighbors(
       /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
       OLSR_PRINTF(
         9,
-        "%s: ----> Forwarding pkt to %s will cost %5.2f\n",
+        "%s: ----> forwarding pkt to %s will cost %5.2f\n",
         PLUGIN_NAME_SHORT,
         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
         walker->link_cost);
 
       /* If the candidate neighbor is best reached via another interface, then skip 
        * the candidate neighbor; the candidate neighbor has been / will be selected via that
-       * other interface.
-       * TODO: get_best_link_to_neighbor() is not thread-safe. */
+       * other interface. */
       bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
 
       if (walker != bestLinkToNeighbor)
@@ -635,7 +651,7 @@ void FindNeighbors(
         {
           OLSR_PRINTF(
             9,
-            "%s: ----> Not forwarding to %s: no link found\n",
+            "%s: ----> not forwarding to %s: no link found\n",
             PLUGIN_NAME_SHORT,
             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
         }
@@ -645,7 +661,7 @@ void FindNeighbors(
 
           OLSR_PRINTF(
             9,
-            "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %5.2f\n",
+            "%s: ----> not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %5.2f\n",
             PLUGIN_NAME_SHORT,
             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
             bestIntf->int_name,
@@ -657,9 +673,6 @@ void FindNeighbors(
 
       if (forwardedBy != NULL)
       {
-#ifndef NODEBUG
-        struct ipaddr_str forwardedByBuf, niaBuf;
-#endif
         OLSR_PRINTF(
           9,
           "%s: ----> 2-hop path from %s via me to %s will cost %5.2f\n",
@@ -675,13 +688,11 @@ void FindNeighbors(
        * neighbor, because the 'forwardedBy' node will forward the packet. */
       if (forwardedBy != NULL)
       {
-        /* TODO: olsr_lookup_tc_entry() is not thread-safe. */
         tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
         if (tcLastHop != NULL)
         {
           struct tc_edge_entry* tc_edge;
 
-          /* TODO: olsr_lookup_tc_edge() is not thread-safe. */
           tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
           
           /* We are not interested in dead-end or dying edges. */
@@ -692,10 +703,10 @@ void FindNeighbors(
 #ifndef NODEBUG
               struct ipaddr_str neighbor_iface_buf, forw_buf;
               olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
-#endif
+#endif /* NODEBUG */
               OLSR_PRINTF(
                 9,
-                "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %5.2f\n",
+                "%s: ----> not forwarding to %s: I am not an MPR between %s and %s, direct link costs %5.2f\n",
                 PLUGIN_NAME_SHORT,
                 neighbor_iface_buf.buf,
                 olsr_ip_to_string(&forw_buf, forwardedBy),
@@ -744,9 +755,6 @@ void FindNeighbors(
     }
 
     OLSR_FOR_ALL_LINK_ENTRIES(walker) {
-#ifndef NODEBUG
-      struct ipaddr_str buf;
-#endif
       union olsr_ip_addr* neighborMainIp;
       struct link_entry* bestLinkToNeighbor;
       struct tc_entry* tcLastHop;
@@ -760,7 +768,7 @@ void FindNeighbors(
 
       OLSR_PRINTF(
         9,
-        "%s: ----> Considering forwarding pkt on \"%s\" to %s\n",
+        "%s: ----> considering forwarding pkt on \"%s\" to %s\n",
         PLUGIN_NAME_SHORT,
         intf->ifName,
         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
@@ -773,7 +781,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is source of pkt\n",
+          "%s: ----> not forwarding to %s: is source of pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -785,7 +793,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node that forwarded the pkt\n",
+          "%s: ----> not forwarding to %s: is the node that forwarded the pkt\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -797,7 +805,7 @@ void FindNeighbors(
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: is the node to which the pkt was forwarded\n",
+          "%s: ----> not forwarding to %s: is the node to which the pkt was forwarded\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -809,11 +817,11 @@ void FindNeighbors(
       /* Calculate the link quality (ETX) of the link to the found neighbor */
       currEtx = walker->linkcost;
  
-      if (currEtx < LINK_COST_BROKEN)
+      if (currEtx >= LINK_COST_BROKEN)
       {
         OLSR_PRINTF(
           9,
-          "%s: ----> Not forwarding to %s: link is timing out\n",
+          "%s: ----> not forwarding to %s: link is timing out\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
 
@@ -823,27 +831,23 @@ void FindNeighbors(
       /* Compare costs to check if the candidate neighbor is best reached via 'intf' */
       OLSR_PRINTF(
         9,
-        "%s: ----> Forwarding pkt to %s will cost ETX %5.2f\n",
+        "%s: ----> forwarding pkt to %s will cost ETX %5.2f\n",
         PLUGIN_NAME_SHORT,
         olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
-        currEtx);
+        (double)currEtx);
 
       /* If the candidate neighbor is best reached via another interface, then skip 
        * the candidate neighbor; the candidate neighbor has been / will be selected via that
-       * other interface.
-       * TODO: get_best_link_to_neighbor() is not thread-safe. */
+       * other interface. */
       bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
 
       if (walker != bestLinkToNeighbor)
       {
         if (bestLinkToNeighbor == NULL)
         {
-#ifndef NODEBUG
-          struct ipaddr_str buf;
-#endif
           OLSR_PRINTF(
             9,
-            "%s: ----> Not forwarding to %s: no link found\n",
+            "%s: ----> not forwarding to %s: no link found\n",
             PLUGIN_NAME_SHORT,
             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr));
         }
@@ -851,16 +855,15 @@ void FindNeighbors(
         {
 #ifndef NODEBUG
           struct interface* bestIntf = if_ifwithaddr(&bestLinkToNeighbor->local_iface_addr);
-          struct ipaddr_str buf;
           struct lqtextbuffer lqbuffer;
-#endif
+#endif /* NODEBUG */
           OLSR_PRINTF(
             9,
-            "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
+            "%s: ----> not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
             PLUGIN_NAME_SHORT,
             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
-            bestIntf->int_name,
-            get_linkcost_text(bestLinkToNeighbor->linkcost, OLSR_FALSE, &lqbuffer));
+            bestIntf ? bestIntf->int_name : "NULL",
+            get_linkcost_text(bestLinkToNeighbor->linkcost, false, &lqbuffer));
         }
 
         continue; /* for */
@@ -871,14 +874,14 @@ void FindNeighbors(
 #ifndef NODEBUG
         struct ipaddr_str forwardedByBuf, niaBuf;
         struct lqtextbuffer lqbuffer;
-#endif
+#endif /* NODEBUG */
         OLSR_PRINTF(
           9,
           "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&forwardedByBuf, forwardedBy),
           olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
-          get_linkcost_text(previousLinkEtx + currEtx, OLSR_TRUE, &lqbuffer));
+          get_linkcost_text(previousLinkEtx + currEtx, true, &lqbuffer));
       }
 
       /* Check the topology table whether the 'forwardedBy' node is itself a direct
@@ -887,13 +890,11 @@ void FindNeighbors(
        * neighbor, because the 'forwardedBy' node will forward the packet. */
       if (forwardedBy != NULL)
       {
-        /* TODO: olsr_lookup_tc_entry() is not thread-safe. */
         tcLastHop = olsr_lookup_tc_entry(MainAddressOf(forwardedBy));
         if (tcLastHop != NULL)
         {
           struct tc_edge_entry* tc_edge;
 
-          /* TODO: olsr_lookup_tc_edge() is not thread-safe. */
           tc_edge = olsr_lookup_tc_edge(tcLastHop, MainAddressOf(&walker->neighbor_iface_addr));
 
           /* We are not interested in dead-end edges. */
@@ -906,15 +907,15 @@ void FindNeighbors(
               struct ipaddr_str neighbor_iface_buf, forw_buf;
               struct lqtextbuffer lqbuffer;
               olsr_ip_to_string(&neighbor_iface_buf, &walker->neighbor_iface_addr);
-#endif
+#endif /* NODEBUG */
               OLSR_PRINTF(
                 9,
-                "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
+                "%s: ----> not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
                 PLUGIN_NAME_SHORT,
                 neighbor_iface_buf.buf,
                 olsr_ip_to_string(&forw_buf, forwardedBy),
                 neighbor_iface_buf.buf,
-                get_linkcost_text(tcEtx, OLSR_FALSE, &lqbuffer));
+                get_linkcost_text(tcEtx, false, &lqbuffer));
 
               continue; /* for */
             } /* if */
@@ -949,15 +950,12 @@ void FindNeighbors(
   {
     OLSR_PRINTF(
       9,
-      "%s: ----> No suitable neighbor found to forward to on \"%s\"\n",
+      "%s: ----> no suitable neighbor found to forward to on \"%s\"\n",
       PLUGIN_NAME_SHORT,
       intf->ifName);
   }
   else
   {
-#ifndef NODEBUG
-    struct ipaddr_str buf;
-#endif
     OLSR_PRINTF(
       9,
       "%s: ----> %d neighbors found on \"%s\"; best neighbor to forward to: %s\n",
@@ -1204,7 +1202,7 @@ static int CreateEncapsulateSocket(const char* ifName)
  * ------------------------------------------------------------------------- */
 static int CreateLocalEtherTunTap(void)
 {
-  static const char deviceName[] = "/dev/net/tun";
+  static const char * deviceName = OS_TUNNEL_PATH;
   struct ifreq ifreq;
   int etfd;
   int ioctlSkfd;
@@ -1273,17 +1271,17 @@ static int CreateLocalEtherTunTap(void)
     EtherTunTapIp = ETHERTUNTAPDEFAULTIP;
   }
 
-  ((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr.s_addr = htonl(EtherTunTapIp);
+  ((struct sockaddr_in*) ARM_NOWARN_ALIGN(&ifreq.ifr_addr))->sin_addr.s_addr = htonl(EtherTunTapIp);
   ioctlres = ioctl(ioctlSkfd, SIOCSIFADDR, &ifreq);
   if (ioctlres >= 0)
   {
     /* Set net mask */
-    ((struct sockaddr_in*)&ifreq.ifr_netmask)->sin_addr.s_addr = htonl(EtherTunTapIpMask);
+    ((struct sockaddr_in*) ARM_NOWARN_ALIGN(&ifreq.ifr_netmask))->sin_addr.s_addr = htonl(EtherTunTapIpMask);
     ioctlres = ioctl(ioctlSkfd, SIOCSIFNETMASK, &ifreq);
     if (ioctlres >= 0)
     {
       /* Set broadcast IP */
-      ((struct sockaddr_in*)&ifreq.ifr_broadaddr)->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
+      ((struct sockaddr_in*) ARM_NOWARN_ALIGN(&ifreq.ifr_broadaddr))->sin_addr.s_addr = htonl(EtherTunTapIpBroadcast);
       ioctlres = ioctl(ioctlSkfd, SIOCSIFBRDADDR, &ifreq);
       if (ioctlres >= 0)
       {
@@ -1330,9 +1328,9 @@ static int CreateLocalEtherTunTap(void)
   /* Use ioctl to make the tuntap persistent. Otherwise it will disappear
    * when this program exits. That is not desirable, since a multicast
    * daemon (e.g. mrouted) may be using the tuntap interface. */
-  if (ioctl(etfd, TUNSETPERSIST, (void *)&ifreq) < 0)
+  if (ioctl(etfd, TUNSETPERSIST, EtherTunTapPersistent ? (void *)&ifreq : NULL) < 0)
   {
-    BmfPError("error making EtherTunTap interface \"%s\" persistent", EtherTunTapIfName);
+    BmfPError("error making EtherTunTap interface \"%s\" %spersistent", EtherTunTapIfName, !EtherTunTapPersistent ? "non-" : "");
 
     /* Continue anyway */
   }
@@ -1407,7 +1405,9 @@ static int CreateInterface(
     capturingSkfd = CreateCaptureSocket(ifName);
     if (capturingSkfd < 0)
     {
-      close(encapsulatingSkfd);
+      if (encapsulatingSkfd >= 0) {
+        close(encapsulatingSkfd);
+      }
       free(newIf);
       return 0;
     }
@@ -1422,8 +1422,9 @@ static int CreateInterface(
     listeningSkfd = CreateListeningSocket(ifName);
     if (listeningSkfd < 0)
     {
-      close(listeningSkfd);
-      close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
+      if (encapsulatingSkfd >= 0) {
+        close(encapsulatingSkfd); /* no problem if 'encapsulatingSkfd' is -1 */
+      }
       free(newIf);
       return 0;
     }
@@ -1442,12 +1443,26 @@ static int CreateInterface(
   if (ioctl(ioctlSkfd, SIOCGIFHWADDR, &ifr) < 0)
   {
     BmfPError("ioctl(SIOCGIFHWADDR) error for interface \"%s\"", ifName);
-    close(capturingSkfd);
-    close(encapsulatingSkfd);
+    if (capturingSkfd >= 0) {
+      close(capturingSkfd);
+    }
+    if (encapsulatingSkfd >= 0) {
+      close(encapsulatingSkfd);
+    }
     free(newIf);
     return 0;
   }
 
+  /* add listeners to sockets */
+  if (capturingSkfd != -1) {
+    add_olsr_socket(capturingSkfd, NULL, BMF_handle_captureFd, newIf, SP_IMM_READ);
+  }
+  if (encapsulatingSkfd != -1) {
+    add_olsr_socket(encapsulatingSkfd, NULL, BMF_handle_encapsulatingFd, newIf, SP_IMM_READ);
+  }
+  if (listeningSkfd != -1) {
+    add_olsr_socket(listeningSkfd, NULL, BMF_handle_listeningFd, newIf, SP_IMM_READ);
+  }
   /* Copy data into TBmfInterface object */
   newIf->capturingSkfd = capturingSkfd;
   newIf->encapsulatingSkfd = encapsulatingSkfd;
@@ -1478,7 +1493,7 @@ static int CreateInterface(
     else
     {
       /* Downcast to correct sockaddr subtype */
-      newIf->intAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
+      newIf->intAddr.v4 = ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&ifr.ifr_addr))->sin_addr;
     }
 
     /* For a non-OLSR interface, retrieve the IP broadcast address ourselves */
@@ -1494,14 +1509,10 @@ static int CreateInterface(
     else
     {
       /* Downcast to correct sockaddr subtype */
-      newIf->broadAddr.v4 = ((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr;
+      newIf->broadAddr.v4 = ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&ifr.ifr_broadaddr))->sin_addr;
     }
   }
 
-  /* Initialize fragment history table */
-  memset(&newIf->fragmentHistory, 0, sizeof(newIf->fragmentHistory));
-  newIf->nextFragmentHistoryEntry = 0;
-
   /* Reset counters */
   newIf->nBmfPacketsRx = 0;
   newIf->nBmfPacketsRxDup = 0;
@@ -1512,6 +1523,7 @@ static int CreateInterface(
   if (BmfInterfaces == NULL)
   {
     /* First TBmfInterface object in list */
+    newIf->next = NULL;
     BmfInterfaces = newIf;
     LastBmfInterface = newIf;
   }
@@ -1610,7 +1622,7 @@ int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
     }
 
     /* ...find the OLSR interface structure, if any */
-    ipAddr.v4 =  ((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr;
+    ipAddr.v4 =  ((struct sockaddr_in*) ARM_NOWARN_ALIGN(&ifr->ifr_addr))->sin_addr;
     olsrIntf = if_ifwithaddr(&ipAddr);
 
     if (skipThisIntf != NULL && olsrIntf == skipThisIntf)
@@ -1635,6 +1647,7 @@ int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
   EtherTunTapFd = CreateLocalEtherTunTap();
   if (EtherTunTapFd >= 0)
   {
+    add_olsr_socket(EtherTunTapFd, NULL, BMF_handle_tuntapFd, NULL, SP_IMM_READ);
     nOpenedSockets++;
   }
 
@@ -1649,33 +1662,13 @@ int CreateBmfNetworkInterfaces(struct interface* skipThisIntf)
   return 0;
 } /* CreateBmfNetworkInterfaces */
 
-/* -------------------------------------------------------------------------
- * Function   : AddInterface
- * Description: Add an OLSR-enabled network interface to the list of BMF-enabled
- *              network interfaces
- * Input      : newIntf - network interface to add
- * Output     : none
- * Return     : none
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-void AddInterface(struct interface* newIntf)
-{
-  int nOpened;
-
-  assert(newIntf != NULL);
-
-  nOpened = CreateInterface(newIntf->int_name, newIntf);
-
-  olsr_printf(1, "%s: opened %d sockets\n", PLUGIN_NAME, nOpened);
-} /* AddInterface */
-
 /* -------------------------------------------------------------------------
  * Function   : CloseBmfNetworkInterfaces
  * Description: Closes every socket on each network interface used by BMF
  * Input      : none
  * Output     : none
  * Return     : none
- * Data Used  : none
+ * Data Used  : BmfInterfaces, LastBmfInterface
  * Notes      : Closes
  *              - the local EtherTunTap interface (e.g. "tun0" or "tap0")
  *              - for each BMF-enabled interface, the socket used for
@@ -1705,11 +1698,19 @@ void CloseBmfNetworkInterfaces(void)
     if (bmfIf->capturingSkfd >= 0)
     {
       close(bmfIf->capturingSkfd);
+      remove_olsr_socket(bmfIf->capturingSkfd, NULL, BMF_handle_captureFd);
       nClosed++;
     }
     if (bmfIf->encapsulatingSkfd >= 0) 
     {
       close(bmfIf->encapsulatingSkfd);
+      remove_olsr_socket(bmfIf->encapsulatingSkfd, NULL, BMF_handle_encapsulatingFd);
+      nClosed++;
+    }
+    if (bmfIf->listeningSkfd >= 0)
+    {
+      close(bmfIf->listeningSkfd);
+      remove_olsr_socket(bmfIf->listeningSkfd, NULL, BMF_handle_listeningFd);
       nClosed++;
     }
 
@@ -1750,25 +1751,31 @@ void CloseBmfNetworkInterfaces(void)
   if (EtherTunTapFd >= 0)
   {
     close(EtherTunTapFd);
+    remove_olsr_socket(EtherTunTapFd, NULL, BMF_handle_tuntapFd);
     nClosed++;
 
     OLSR_PRINTF(7, "%s: closed \"%s\"\n", PLUGIN_NAME_SHORT, EtherTunTapIfName);
   }
 
   BmfInterfaces = NULL;
+  LastBmfInterface = NULL;
+
+  /* Re-initialize the IP address for the BMF network interface. Thanks to
+   * Daniele Lacamera for finding and solving this bug. */
+  EtherTunTapIp = ETHERTUNTAPIPNOTSET;
 
   olsr_printf(1, "%s: closed %d sockets\n", PLUGIN_NAME_SHORT, nClosed);
 
   OLSR_PRINTF(
     7,
-    "%s: Total all OLSR interfaces    : RX pkts %d (%d dups); TX pkts %d\n",
+    "%s: total all OLSR interfaces    : RX pkts %d (%d dups); TX pkts %d\n",
     PLUGIN_NAME_SHORT,
     totalOlsrBmfPacketsRx,
     totalOlsrBmfPacketsRxDup,
     totalOlsrBmfPacketsTx);
   OLSR_PRINTF(
     7,
-    "%s: Total all non-OLSR interfaces: RX pkts %d (%d dups); TX pkts %d\n",
+    "%s: total all non-OLSR interfaces: RX pkts %d (%d dups); TX pkts %d\n",
     PLUGIN_NAME_SHORT,
     totalNonOlsrBmfPacketsRx,
     totalNonOlsrBmfPacketsRxDup,
@@ -1854,7 +1861,7 @@ void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* b
 
   assert(ipPacket != NULL && broadAddr != NULL);
 
-  iph = (struct iphdr*) ipPacket;
+  iph = (struct iphdr*) ARM_NOWARN_ALIGN(ipPacket);
   destIp.v4.s_addr = iph->daddr;
   if (! IsMulticast(&destIp))
   {
@@ -1882,7 +1889,7 @@ void CheckAndUpdateLocalBroadcast(unsigned char* ipPacket, union olsr_ip_addr* b
       /* Re-calculate UDP/IP checksum for new destination */
 
       int ipHeaderLen = GetIpHeaderLength(ipPacket);
-      struct udphdr* udph = (struct udphdr*) (ipPacket + ipHeaderLen);
+      struct udphdr* udph = (struct udphdr*) ARM_NOWARN_ALIGN((ipPacket + ipHeaderLen));
 
       /* RFC 1624, Eq. 3: HC' = ~(~HC - m + m') */
 
@@ -1920,13 +1927,13 @@ void AddMulticastRoute(void)
 
   memset(&kernel_route, 0, sizeof(struct rtentry));
 
-  ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
-  ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
-  ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
+  ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_dst))->sa_family = AF_INET;
+  ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_gateway))->sa_family = AF_INET;
+  ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_genmask))->sa_family = AF_INET;
 
   /* 224.0.0.0/4 */
-  ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
-  ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
+  ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&kernel_route.rt_dst))->sin_addr.s_addr = htonl(0xE0000000);
+  ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&kernel_route.rt_genmask))->sin_addr.s_addr = htonl(0xF0000000);
 
   kernel_route.rt_metric = 0;
   kernel_route.rt_flags = RTF_UP;
@@ -1965,13 +1972,13 @@ void DeleteMulticastRoute(void)
 
     memset(&kernel_route, 0, sizeof(struct rtentry));
 
-    ((struct sockaddr_in*)&kernel_route.rt_dst)->sin_family = AF_INET;
-    ((struct sockaddr_in*)&kernel_route.rt_gateway)->sin_family = AF_INET;
-    ((struct sockaddr_in*)&kernel_route.rt_genmask)->sin_family = AF_INET;
+    ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_dst))->sa_family = AF_INET;
+    ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_gateway))->sa_family = AF_INET;
+    ((struct sockaddr *) ARM_NOWARN_ALIGN(&kernel_route.rt_genmask))->sa_family = AF_INET;
 
     /* 224.0.0.0/4 */
-    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = htonl(0xE0000000);
-    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = htonl(0xF0000000);
+    ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&kernel_route.rt_dst))->sin_addr.s_addr = htonl(0xE0000000);
+    ((struct sockaddr_in *) ARM_NOWARN_ALIGN(&kernel_route.rt_genmask))->sin_addr.s_addr = htonl(0xF0000000);
 
     kernel_route.rt_metric = 0;
     kernel_route.rt_flags = RTF_UP;