Cleanup for linux netlink code, removing RT_NETLINK_MONITOR preprocessor flag
authorHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Mon, 8 Feb 2010 15:28:35 +0000 (16:28 +0100)
committerHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Mon, 8 Feb 2010 15:28:35 +0000 (16:28 +0100)
Move LINUX_POLICY_ROUTING flag to linux makefile
Fix bug in linux non-policy-routing code

make/Makefile.linux
src/kernel_routes.h
src/linux/kernel_routes.c
src/linux/kernel_routes_npr.c [new file with mode: 0644]
src/main.c
src/olsr_cfg.h
src/olsr_niit.c
src/olsr_niit.h
src/process_routes.c

index 4c7f1de..9e42cfb 100644 (file)
@@ -9,7 +9,7 @@ LIBDIR =        $(DESTDIR)$(shell if [ "$(ARCH)" = "x86_64" -a -d "/usr/lib64" ]; then
 SRCS +=        $(wildcard src/linux/*.c src/unix/*.c)
 HDRS +=                $(wildcard src/linux/*.h src/unix/*.h)
 
-CPPFLAGS +=    -Dlinux
+CPPFLAGS +=    -Dlinux -D LINUX_POLICY_ROUTING
 LIBS +=                
 
 PLUGIN_FULLNAME ?= $(PLUGIN_NAME).so.$(PLUGIN_VER)
index b2dba0c..59f974e 100644 (file)
@@ -56,6 +56,8 @@ int olsr_ioctl_del_route6(const struct rt_entry *);
 #if LINUX_POLICY_ROUTING
 static const char TUNL_BASE[IFNAMSIZ] = "tunl0";
 
+int rtnetlink_register_socket(int);
+
 void olsr_os_niit_4to6_route(const struct olsr_ip_prefix *dst_v4, bool set);
 void olsr_os_niit_6to4_route(const struct olsr_ip_prefix *dst_v6, bool set);
 
@@ -64,9 +66,6 @@ int olsr_os_create_localhostif(union olsr_ip_addr *ip, bool create);
 
 int olsr_del_tunl(void);
 
-#if LINUX_RTNETLINK_LISTEN
-int rtnetlink_register_socket(int);
-#endif /*LINUX_RTNETLINK_LISTEN*/
 
 #endif
 
index 7a597fa..abf25ff 100644 (file)
 #include "ipc_frontend.h"
 #include "log.h"
 #include "net_os.h"
-
-/* values for control flag to handle recursive route corrections 
- *  currently only requires in linux specific kernel_routes.c */
-
-#define RT_ORIG_REQUEST 0
-#define RT_RETRY_AFTER_ADD_GATEWAY 1
-#define RT_RETRY_AFTER_DELETE_SIMILAR 2
-#define RT_DELETE_SIMILAR_ROUTE 3
-#define RT_AUTO_ADD_GATEWAY_ROUTE 4
-#define RT_DELETE_SIMILAR_AUTO_ROUTE 5
-#define RT_NIIT 6
-#define RT_SMARTGW 7
-
-#if !LINUX_POLICY_ROUTING
-
-static int delete_all_inet_gws(void);
-
-#else /* !LINUX_POLICY_ROUTING */
+#include "ifnet.h"
 
 #include <assert.h>
 #include <linux/types.h>
@@ -79,7 +62,14 @@ static int delete_all_inet_gws(void);
 #include <sys/types.h>
 #include <net/if.h>
 
-// static struct rtnl_handle rth;
+#ifdef LINUX_POLICY_ROUTING
+/*
+ * The ARM compile complains about alignment. Copied
+ * from /usr/include/linux/netlink.h and adapted for ARM
+ */
+#define MY_NLMSG_NEXT(nlh,len)   ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
+          (struct nlmsghdr*)(ARM_NOWARN_ALIGN)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+
 
 static void rtnetlink_read(int sock, void *, unsigned int);
 
@@ -95,9 +85,6 @@ struct olsr_ipadd_req {
   char buf[256];
 };
 
-#if LINUX_RTNETLINK_LISTEN
-#include "ifnet.h"
-
 int rtnetlink_register_socket(int rtnl_mgrp)
 {
   int sock = socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE);
@@ -210,14 +197,7 @@ static void rtnetlink_read(int sock, void *data __attribute__ ((unused)), unsign
   iov.iov_base = (void *) buffer;
   iov.iov_len = sizeof(buffer);
 
-  while (true) { //read until ret<0;
-    ret = recvmsg(sock, &msg, MSG_DONTWAIT);
-    if (ret < 0) {
-      if (errno != EAGAIN) {
-        OLSR_PRINTF(1,"netlink listen error %u - %s\n",errno,strerror(errno));
-      }
-      return;
-    }
+  while ((ret = recvmsg(sock, &msg, MSG_DONTWAIT)) >= 0) {
     /*check message*/
     len = nlh->nlmsg_len;
     plen = len - sizeof(nlh);
@@ -232,11 +212,11 @@ static void rtnetlink_read(int sock, void *data __attribute__ ((unused)), unsign
       netlink_process_link(nlh);
     }
   }
-}
-
-//!!?? listen on our own tunlx interfaces aswell
 
-#endif /*linux_rtnetlink_listen*/
+  if (errno != EAGAIN) {
+    OLSR_PRINTF(1,"netlink listen error %u - %s\n",errno,strerror(errno));
+  }
+}
 
 /*create or change a ipip tunnel ipv4 only*/
 static int set_tunl(int cmd, unsigned long int ipv4)
@@ -288,13 +268,6 @@ olsr_netlink_addreq(struct nlmsghdr *n, size_t reqSize __attribute__ ((unused)),
   memcpy(RTA_DATA(rta), data, len);
 }
 
-/*
- * The ARM compile complains about alignment. Copied
- * from /usr/include/linux/netlink.h and adapted for ARM
- */
-#define MY_NLMSG_NEXT(nlh,len)   ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
-          (struct nlmsghdr*)(ARM_NOWARN_ALIGN)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
-
 /*rt_entry and nexthop and family and table must only be specified with an flag != RT_NONE  && != RT_LO_IP*/
 static int
 olsr_netlink_send(struct nlmsghdr *nl_hdr)
@@ -675,7 +648,77 @@ static int olsr_os_process_rt_entry(int af_family, const struct rt_entry *rt, bo
   return err;
 }
 
+/**
+ * Insert a route in the kernel routing table
+ *
+ * @param destination the route to add
+ *
+ * @return negative on error
+ */
+int
+olsr_ioctl_add_route(const struct rt_entry *rt)
+{
+  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+  return olsr_os_process_rt_entry(AF_INET, rt, true);
+}
+
+/**
+ *Insert a route in the kernel routing table
+ *
+ *@param destination the route to add
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_add_route6(const struct rt_entry *rt)
+{
+  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+  return olsr_os_process_rt_entry(AF_INET6, rt, true);
+}
+
+/**
+ *Remove a route from the kernel
+ *
+ *@param destination the route to remove
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_del_route(const struct rt_entry *rt)
+{
+  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+  return olsr_os_process_rt_entry(AF_INET, rt, false);
+}
+
+/**
+ *Remove a route from the kernel
+ *
+ *@param destination the route to remove
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_del_route6(const struct rt_entry *rt)
+{
+  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+  return olsr_os_process_rt_entry(AF_INET6, rt, false);
+}
+
+#endif
+
 #if 0
+/* values for control flag to handle recursive route corrections
+ *  currently only requires in linux specific kernel_routes.c */
+
+// #define RT_ORIG_REQUEST 0
+// #define RT_RETRY_AFTER_ADD_GATEWAY 1
+// #define RT_RETRY_AFTER_DELETE_SIMILAR 2
+// #define RT_DELETE_SIMILAR_ROUTE 3
+// #define RT_AUTO_ADD_GATEWAY_ROUTE 4
+// #define RT_DELETE_SIMILAR_AUTO_ROUTE 5
+// #define RT_NIIT 6
+// #define RT_SMARTGW 7
+
 /* returns
  * -1 on unrecoverable error (calling function will have to handle it)
  *  0 on unexpected but recoverable rtnetlink behaviour
@@ -925,7 +968,7 @@ olsr_netlink_route_int(const struct rt_entry *rt, uint8_t family, uint8_t rttabl
               rt_ret = 1;
             }
 
-            /* resolve "File exist" (17) propblems (on orig and autogen routes)*/      
+            /* resolve "File exist" (17) propblems (on orig and autogen routes)*/
             if ((errno == 17) && (cmd == RTM_NEWROUTE) && ((flag == RT_ORIG_REQUEST) || (flag == RT_AUTO_ADD_GATEWAY_ROUTE))) {
               /* a similar route going over another gateway may be present, which has to be deleted! */
               olsr_syslog(OLSR_LOG_ERR, ". auto-deleting similar routes to resolve 'File exists' (17) while adding route!");
@@ -976,8 +1019,8 @@ olsr_netlink_route_int(const struct rt_entry *rt, uint8_t family, uint8_t rttabl
  * The ARM compile complains about alignment. Copied
  * from /usr/include/linux/netlink.h and adapted for ARM
  */
-#define MY_NLMSG_NEXT(nlh,len)  ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
-                                 (struct nlmsghdr*)(ARM_NOWARN_ALIGN)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+#define MY_NLMSG_NEXT(nlh,len)   ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len), \
+          (struct nlmsghdr*)(ARM_NOWARN_ALIGN)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
         h = MY_NLMSG_NEXT(h, ret);
       }
     }
@@ -1105,285 +1148,6 @@ printf("index of new olsrtunl is %i\n",olsr_cnf->ipip_if_index);
   return olsr_netlink_route_int(rt, family, rttable, cmd, RT_ORIG_REQUEST);
 }
 #endif
-
-#endif /* LINUX_POLICY_ROUTING */
-
-/**
- * Insert a route in the kernel routing table
- *
- * @param destination the route to add
- *
- * @return negative on error
- */
-int
-olsr_ioctl_add_route(const struct rt_entry *rt)
-{
-#if !LINUX_POLICY_ROUTING
-  struct rtentry kernel_route;
-  union olsr_ip_addr mask;
-  int rslt;
-#endif /* LINUX_POLICY_ROUTING */
-
-  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
-
-#if !LINUX_POLICY_ROUTING
-  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_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4;
-
-  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
-    return -1;
-  }
-  ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4;
-
-  if (rt->rt_dst.prefix.v4.s_addr != rt->rt_best->rtp_nexthop.gateway.v4.s_addr) {
-    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_best->rtp_nexthop.gateway.v4;
-  }
-
-  kernel_route.rt_flags = olsr_rt_flags(rt);
-  kernel_route.rt_metric = olsr_fib_metric(&rt->rt_best->rtp_metric.hops);
-
-  /*
-   * Set interface
-   */
-  kernel_route.rt_dev = if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index);
-
-  /* delete existing default route before ? */
-  if ((olsr_cnf->del_gws) && (rt->rt_dst.prefix.v4.s_addr == INADDR_ANY) && (rt->rt_dst.prefix_len == INADDR_ANY)) {
-    delete_all_inet_gws();
-    olsr_cnf->del_gws = false;
-  }
-
-  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) {
-
-    /*
-     * Send IPC route update message
-     */
-    ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1,
-                           if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
-  }
-
-  return rslt;
-#else /* !LINUX_POLICY_ROUTING */
-  return olsr_os_process_rt_entry(AF_INET, rt, true);
-#endif /* LINUX_POLICY_ROUTING */
-}
-
-/**
- *Insert a route in the kernel routing table
- *
- *@param destination the route to add
- *
- *@return negative on error
- */
-int
-olsr_ioctl_add_route6(const struct rt_entry *rt)
-{
-#if !LINUX_POLICY_ROUTING
-  struct in6_rtmsg kernel_route;
-  int rslt;
-
-  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
-
-  memset(&kernel_route, 0, sizeof(struct in6_rtmsg));
-
-  kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6;
-  kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len;
-
-  kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6;
-
-  kernel_route.rtmsg_flags = olsr_rt_flags(rt);
-  kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric.hops);
-
-  /*
-   * set interface
-   */
-  kernel_route.rtmsg_ifindex = rt->rt_best->rtp_nexthop.iif_index;
-
-  /* XXX delete 0/0 route before ? */
-
-  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) {
-
-    /*
-     * Send IPC route update message
-     */
-    ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1,
-                           if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
-  }
-  return rslt;
-#else /* !LINUX_POLICY_ROUTING */
-
-  return olsr_os_process_rt_entry(AF_INET6, rt, true);
-#endif /* LINUX_POLICY_ROUTING */
-}
-
-/**
- *Remove a route from the kernel
- *
- *@param destination the route to remove
- *
- *@return negative on error
- */
-int
-olsr_ioctl_del_route(const struct rt_entry *rt)
-{
-#if !LINUX_POLICY_ROUTING
-  struct rtentry kernel_route;
-  union olsr_ip_addr mask;
-  int rslt;
-#endif /* LINUX_POLICY_ROUTING */
-
-  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
-
-#if !LINUX_POLICY_ROUTING
-  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_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4;
-
-  if (rt->rt_dst.prefix.v4.s_addr != rt->rt_nexthop.gateway.v4.s_addr) {
-    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_nexthop.gateway.v4;
-  }
-
-  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
-    return -1;
-  } else {
-    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4;
-  }
-
-  kernel_route.rt_flags = olsr_rt_flags(rt);
-  kernel_route.rt_metric = olsr_fib_metric(&rt->rt_metric.hops);
-
-  /*
-   * Set interface
-   */
-  kernel_route.rt_dev = NULL;
-
-  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route)) >= 0) {
-
-    /*
-     * Send IPC route update message
-     */
-    ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL);
-  }
-
-  return rslt;
-#else /* !LINUX_POLICY_ROUTING */
-  return olsr_os_process_rt_entry(AF_INET, rt, false);
-#endif /* LINUX_POLICY_ROUTING */
-}
-
-/**
- *Remove a route from the kernel
- *
- *@param destination the route to remove
- *
- *@return negative on error
- */
-int
-olsr_ioctl_del_route6(const struct rt_entry *rt)
-{
-#if !LINUX_POLICY_ROUTING
-  struct in6_rtmsg kernel_route;
-  int rslt;
-#endif /* LINUX_POLICY_ROUTING */
-
-  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
-
-#if !LINUX_POLICY_ROUTING
-  memset(&kernel_route, 0, sizeof(struct in6_rtmsg));
-
-  kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6;
-  kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len;
-
-  kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6;
-
-  kernel_route.rtmsg_flags = olsr_rt_flags(rt);
-  kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric.hops);
-
-  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route) >= 0)) {
-
-    /*
-     * Send IPC route update message
-     */
-    ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL);
-  }
-
-  return rslt;
-#else /* !LINUX_POLICY_ROUTING */
-  return olsr_os_process_rt_entry(AF_INET6, rt, false);
-#endif /* LINUX_POLICY_ROUTING */
-}
-
-#if !LINUX_POLICY_ROUTING
-static int
-delete_all_inet_gws(void)
-{
-  int s;
-  char buf[BUFSIZ], *cp, *cplim;
-  struct ifconf ifc;
-  struct ifreq *ifr;
-
-  OLSR_PRINTF(1, "Internet gateway detected...\nTrying to delete default gateways\n");
-
-  /* Get a socket */
-  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-    olsr_syslog(OLSR_LOG_ERR, "socket: %m");
-    return -1;
-  }
-
-  ifc.ifc_len = sizeof(buf);
-  ifc.ifc_buf = buf;
-  if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
-    olsr_syslog(OLSR_LOG_ERR, "ioctl (get interface configuration)");
-    close(s);
-    return -1;
-  }
-
-  ifr = ifc.ifc_req;
-  cplim = buf + ifc.ifc_len;    /*skip over if's with big ifr_addr's */
-  for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
-    struct rtentry kernel_route;
-    ifr = (struct ifreq *)cp;
-
-    if (strcmp(ifr->ifr_ifrn.ifrn_name, "lo") == 0) {
-      OLSR_PRINTF(1, "Skipping loopback...\n");
-      continue;
-    }
-
-    OLSR_PRINTF(1, "Trying 0.0.0.0/0 %s...", ifr->ifr_ifrn.ifrn_name);
-
-    memset(&kernel_route, 0, sizeof(struct rtentry));
-
-    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = 0;
-    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_family = AF_INET;
-    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = 0;
-    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_family = AF_INET;
-
-    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr.s_addr = INADDR_ANY;
-    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_family = AF_INET;
-
-    kernel_route.rt_flags = RTF_UP | RTF_GATEWAY;
-
-    kernel_route.rt_dev = ifr->ifr_ifrn.ifrn_name;
-
-    if ((ioctl(s, SIOCDELRT, &kernel_route)) < 0)
-      OLSR_PRINTF(1, "NO\n");
-    else
-      OLSR_PRINTF(1, "YES\n");
-  }
-  close(s);
-  return 0;
-}
-#endif /* LINUX_POLICY_ROUTING */
-
 /*
  * Local Variables:
  * c-basic-offset: 2
diff --git a/src/linux/kernel_routes_npr.c b/src/linux/kernel_routes_npr.c
new file mode 100644 (file)
index 0000000..416d05c
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
+ * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
+ * Copyright (c) 2007, Sven-Ola for the policy routing stuff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+#include "defs.h"
+#include "kernel_routes.h"
+#include "ipc_frontend.h"
+#include "log.h"
+#include "net_os.h"
+#include "process_routes.h"
+
+#include <assert.h>
+#include <linux/types.h>
+#include <linux/rtnetlink.h>
+
+#if LINUX_POLICY_ROUTING==0
+
+static int
+delete_all_inet_gws(void)
+{
+  int s;
+  char buf[BUFSIZ], *cp, *cplim;
+  struct ifconf ifc;
+  struct ifreq *ifr;
+
+  OLSR_PRINTF(1, "Internet gateway detected...\nTrying to delete default gateways\n");
+
+  /* Get a socket */
+  if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+    olsr_syslog(OLSR_LOG_ERR, "socket: %m");
+    return -1;
+  }
+
+  ifc.ifc_len = sizeof(buf);
+  ifc.ifc_buf = buf;
+  if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+    olsr_syslog(OLSR_LOG_ERR, "ioctl (get interface configuration)");
+    close(s);
+    return -1;
+  }
+
+  ifr = ifc.ifc_req;
+  cplim = buf + ifc.ifc_len;    /*skip over if's with big ifr_addr's */
+  for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
+    struct rtentry kernel_route;
+    ifr = (struct ifreq *)cp;
+
+    if (strcmp(ifr->ifr_ifrn.ifrn_name, "lo") == 0) {
+      OLSR_PRINTF(1, "Skipping loopback...\n");
+      continue;
+    }
+
+    OLSR_PRINTF(1, "Trying 0.0.0.0/0 %s...", ifr->ifr_ifrn.ifrn_name);
+
+    memset(&kernel_route, 0, sizeof(struct rtentry));
+
+    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr.s_addr = 0;
+    ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_family = AF_INET;
+    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr.s_addr = 0;
+    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_family = AF_INET;
+
+    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr.s_addr = INADDR_ANY;
+    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_family = AF_INET;
+
+    kernel_route.rt_flags = RTF_UP | RTF_GATEWAY;
+
+    kernel_route.rt_dev = ifr->ifr_ifrn.ifrn_name;
+
+    if ((ioctl(s, SIOCDELRT, &kernel_route)) < 0)
+      OLSR_PRINTF(1, "NO\n");
+    else
+      OLSR_PRINTF(1, "YES\n");
+  }
+  close(s);
+  return 0;
+}
+
+/**
+ * Insert a route in the kernel routing table
+ *
+ * @param destination the route to add
+ *
+ * @return negative on error
+ */
+int
+olsr_ioctl_add_route(const struct rt_entry *rt)
+{
+  char if_name[IFNAMSIZ];
+  struct rtentry kernel_route;
+  union olsr_ip_addr mask;
+  int rslt;
+
+  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+
+  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_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4;
+
+  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
+    return -1;
+  }
+  ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4;
+
+  if (rt->rt_dst.prefix.v4.s_addr != rt->rt_best->rtp_nexthop.gateway.v4.s_addr) {
+    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_best->rtp_nexthop.gateway.v4;
+  }
+
+  kernel_route.rt_flags = olsr_rt_flags(rt);
+  kernel_route.rt_metric = olsr_fib_metric(&rt->rt_best->rtp_metric);
+
+  /*
+   * Set interface
+   */
+  strcpy(if_name, if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
+  kernel_route.rt_dev = if_name;
+
+  /* delete existing default route before ? */
+  if ((olsr_cnf->del_gws) && (rt->rt_dst.prefix.v4.s_addr == INADDR_ANY) && (rt->rt_dst.prefix_len == INADDR_ANY)) {
+    delete_all_inet_gws();
+    olsr_cnf->del_gws = false;
+  }
+
+  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) {
+
+    /*
+     * Send IPC route update message
+     */
+    ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1,
+                           if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
+  }
+
+  return rslt;
+}
+
+/**
+ *Insert a route in the kernel routing table
+ *
+ *@param destination the route to add
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_add_route6(const struct rt_entry *rt)
+{
+  struct in6_rtmsg kernel_route;
+  int rslt;
+
+  OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+
+  memset(&kernel_route, 0, sizeof(struct in6_rtmsg));
+
+  kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6;
+  kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len;
+
+  kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6;
+
+  kernel_route.rtmsg_flags = olsr_rt_flags(rt);
+  kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric);
+
+  /*
+   * set interface
+   */
+  kernel_route.rtmsg_ifindex = rt->rt_best->rtp_nexthop.iif_index;
+
+  /* XXX delete 0/0 route before ? */
+
+  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) {
+
+    /*
+     * Send IPC route update message
+     */
+    ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1,
+                           if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
+  }
+  return rslt;
+}
+
+/**
+ *Remove a route from the kernel
+ *
+ *@param destination the route to remove
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_del_route(const struct rt_entry *rt)
+{
+  struct rtentry kernel_route;
+  union olsr_ip_addr mask;
+  int rslt;
+
+  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+
+  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_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4;
+
+  if (rt->rt_dst.prefix.v4.s_addr != rt->rt_nexthop.gateway.v4.s_addr) {
+    ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_nexthop.gateway.v4;
+  }
+
+  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
+    return -1;
+  } else {
+    ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4;
+  }
+
+  kernel_route.rt_flags = olsr_rt_flags(rt);
+  kernel_route.rt_metric = olsr_fib_metric(&rt->rt_metric);
+
+  /*
+   * Set interface
+   */
+  kernel_route.rt_dev = NULL;
+
+  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route)) >= 0) {
+
+    /*
+     * Send IPC route update message
+     */
+    ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL);
+  }
+
+  return rslt;
+}
+
+/**
+ *Remove a route from the kernel
+ *
+ *@param destination the route to remove
+ *
+ *@return negative on error
+ */
+int
+olsr_ioctl_del_route6(const struct rt_entry *rt)
+{
+  struct in6_rtmsg kernel_route;
+  int rslt;
+
+  OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+
+  memset(&kernel_route, 0, sizeof(struct in6_rtmsg));
+
+  kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6;
+  kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len;
+
+  kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6;
+
+  kernel_route.rtmsg_flags = olsr_rt_flags(rt);
+  kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric);
+
+  if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route) >= 0)) {
+
+    /*
+     * Send IPC route update message
+     */
+    ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL);
+  }
+
+  return rslt;
+}
+
+#endif /* LINUX_POLICY_ROUTING */
index 60d599a..db16d79 100644 (file)
@@ -91,7 +91,7 @@ void olsr_reconfigure(int) __attribute__ ((noreturn));
 
 static void print_usage(bool error);
 
-#ifdef linux
+#if LINUX_POLICY_ROUTING
 static const char* ipip_default_name = "olsr_tunnel";
 #endif
 
@@ -392,13 +392,10 @@ int main(int argc, char *argv[]) {
   }
   fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
 
-#if LINUX_RTNETLINK_LISTEN
   if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
     olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m");
     olsr_exit(__func__, 0);
   }
-#endif /*LINUX_RTNETLINK_LISTEN*/
-
 #endif
 
   /*
@@ -412,7 +409,7 @@ int main(int argc, char *argv[]) {
   }
 #endif
 
-#if defined linux
+#if LINUX_POLICY_ROUTING
   /* initialize niit if index */
   if (olsr_cnf->use_niit) {
     olsr_init_niit();
@@ -605,7 +602,7 @@ printf("\nMain Table is %i prio %i", olsr_cnf->rttable, olsr_cnf->rttable_rule);
 
 #endif
 
-#if defined linux
+#if LINUX_POLICY_ROUTING
   /* trigger gateway selection */
   if (olsr_cnf->smart_gw_active) {
     olsr_trigger_inetgw_startup();
@@ -755,7 +752,7 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
   /* delete all routes */
   olsr_delete_all_kernel_routes();
 
-#if defined linux
+#if LINUX_POLICY_ROUTING
   /* trigger gateway selection */
   if (olsr_cnf->smart_gw_active) {
     // TODO: cleanup smart gateway routes
@@ -835,10 +832,7 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
   }
 
   close(olsr_cnf->rtnl_s);
-
-#if LINUX_RTNETLINK_LISTEN
   close (olsr_cnf->rt_monitor_socket);
-#endif /*LINUX_RTNETLINK_LISTEN*/
 
   /*rp_filter*/
   if (olsr_cnf->ipip_base_if.if_index) printf("\nresetting of tunl0 rp_filter not implemented");//!!?? no function extists to reset a single interface
index eafc24c..fddf181 100644 (file)
 /*set to 1 to collect all startup sleep into one sleep (just as long as the longest sleep) useful if many errors on many interfaces*/
 #define OLSR_COLLECT_STARTUP_SLEEP 1
 
-/* set to 1 to enable a second rtnetlink socket 
- * used for listening and reating on interface change events
- * (requires LINUX_POLICY_ROUTING to be enabled aswell) */
-#define LINUX_RTNETLINK_LISTEN 1
-
 #define TESTLIB_PATH 0
 #define SYSLOG_NUMBERING 0
 
-#ifndef LINUX_POLICY_ROUTING
-#if defined linux
-#  define LINUX_POLICY_ROUTING 1
-#else
-#  define LINUX_POLICY_ROUTING 0
-#endif
-#endif
-
 /* Default values not declared in olsr_protocol.h */
 #define DEF_POLLRATE         0.1
 #define DEF_NICCHGPOLLRT     2.5
index 738b995..8003346 100644 (file)
 
 #include <net/if.h>
 
+#if LINUX_POLICY_ROUTING
 static void handle_niit_ifchange (int if_index, struct interface *iface, enum olsr_ifchg_flag);
 
 static bool niit4to6_active, niit6to4_active;
 
-#ifdef linux
 void olsr_init_niit(void) {
   if (olsr_cnf->ip_version == AF_INET) {
     olsr_cnf->use_niit = false;
index 4e087a0..475ba13 100644 (file)
@@ -8,10 +8,13 @@
 #ifndef OLSR_NIIT_H_
 #define OLSR_NIIT_H_
 
+#include "defs.h"
+#include "routing_table.h"
+
 #define DEF_NIIT4TO6_IFNAME         "niit4to6"
 #define DEF_NIIT6TO4_IFNAME         "niit6to4"
 
-#ifdef linux
+#if LINUX_POLICY_ROUTING
 void olsr_init_niit(void);
 void olsr_setup_niit_routes(void);
 void olsr_cleanup_niit_routes(void);
index 452639c..9964d71 100644 (file)
@@ -170,7 +170,7 @@ olsr_delete_kernel_route(struct rt_entry *rt)
 
       olsr_syslog(OLSR_LOG_ERR, "Delete route %s: %s", routestr, err_msg);
     }
-#ifdef linux
+#if LINUX_POLICY_ROUTING
     /* call NIIT handler (always)*/
     if (olsr_cnf->use_niit) {
       olsr_niit_handle_route(rt, false);
@@ -204,7 +204,7 @@ olsr_add_kernel_route(struct rt_entry *rt)
       rt->rt_nexthop = rt->rt_best->rtp_nexthop;
       rt->rt_metric = rt->rt_best->rtp_metric;
 
-#ifdef linux
+#if LINUX_POLICY_ROUTING
       /* call NIIT handler */
       if (olsr_cnf->use_niit) {
         olsr_niit_handle_route(rt, true);