SrcIP support
authorHenning Rogge <hrogge@googlemail.com>
Sat, 6 Feb 2010 11:32:41 +0000 (12:32 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Sat, 6 Feb 2010 11:32:41 +0000 (12:32 +0100)
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/kernel_routes.h
src/linux/kernel_routes.c
src/main.c
src/olsr_cfg.h

index 9acbc77..2831fd9 100644 (file)
@@ -217,6 +217,7 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_SMART_GW_UPLINK_NAT
 %token TOK_SMART_GW_SPEED
 %token TOK_SMART_GW_PREFIX
+%token TOK_SRC_IP_ROUTES
 
 %token TOK_HOSTLABEL
 %token TOK_NETLABEL
@@ -288,6 +289,7 @@ stmt:       idebug
           | bsmart_gw_uplink_nat
           | ismart_gw_speed
           | ismart_gw_prefix
+          | bsrc_ip_routes
 ;
 
 block:      TOK_HNA4 hna4body
@@ -1214,7 +1216,6 @@ bsmart_gw_uplink_nat: TOK_SMART_GW_UPLINK_NAT TOK_BOOLEAN
 }
 ;
 
-
 ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
 {
   PARSER_DEBUG_PRINTF("Smart gateway prefix: %s %u\n", $2->string, $3->integer);
@@ -1241,6 +1242,15 @@ ismart_gw_prefix: TOK_SMART_GW_PREFIX TOK_IPV6_ADDR TOK_INTEGER
 }
 ;
 
+bsrc_ip_routes: TOK_SRC_IP_ROUTES TOK_BOOLEAN
+{
+       PARSER_DEBUG_PRINTF("Use originator for routes src-ip: %s\n", $2->boolean ? "yes" : "no");
+       olsr_cnf->use_src_ip_routes = $2->boolean;
+       free($2);
+}
+;
+
+
 plblock: TOK_PLUGIN TOK_STRING
 {
   struct plugin_entry *pe, *last;
index 3fe8a1a..ec90f4e 100644 (file)
@@ -463,6 +463,11 @@ IPV6ADDR {IPV6PAT1}|{IPV6PAT2}|{IPV6PAT3}|{IPV6PAT4}|{IPV6PAT5}|{IPV6PAT6}|{IPV6
     return TOK_SMART_GW_PREFIX;
 }
 
+"SrcIpRoutes" {
+    yylval = NULL;
+    return TOK_SRC_IP_ROUTES;
+}
+
 "Weight" {
     yylval = NULL;
     return TOK_IFWEIGHT;
index a803f1e..59bd4a3 100644 (file)
@@ -60,6 +60,7 @@ 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);
 
 int olsr_os_policy_rule(int family, int rttable, uint32_t priority, const char *if_name, bool set);
+int olsr_os_create_localhostif(union olsr_ip_addr *ip, bool create);
 
 int olsr_del_tunl(void);
 
index 373aff7..25dfa77 100644 (file)
@@ -79,7 +79,7 @@ static int delete_all_inet_gws(void);
 #include <sys/types.h>
 #include <net/if.h>
 
-extern struct rtnl_handle rth;
+// static struct rtnl_handle rth;
 
 struct olsr_rtreq {
   struct nlmsghdr n;
@@ -87,6 +87,12 @@ struct olsr_rtreq {
   char buf[512];
 };
 
+struct olsr_ipadd_req {
+  struct nlmsghdr n;
+  struct ifaddrmsg ifa;
+  char buf[256];
+};
+
 #if LINUX_RTNETLINK_LISTEN
 #include "ifnet.h"
 #include "socket_parser.h"
@@ -385,11 +391,35 @@ int olsr_os_policy_rule(int family, int rttable, uint32_t priority, const char *
   return err;
 }
 
-int olsr_new_netlink_route(int family, int rttable, int if_index, int metric, int protocol,
-    const union olsr_ip_addr *src, const union olsr_ip_addr *gw, const struct olsr_ip_prefix *dst,
-    bool set, bool del_similar);
+int
+olsr_os_create_localhostif(union olsr_ip_addr *ip, bool create)
+{
+  struct olsr_ipadd_req req;
+  static char l[] = "lo:olsr";
+
+  memset(&req, 0, sizeof(req));
 
-int olsr_new_netlink_route(int family, int rttable, int if_index, int metric, int protocol,
+  req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+  if (create) {
+   req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK;
+   req.n.nlmsg_type = RTM_NEWADDR;
+  } else {
+   req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+   req.n.nlmsg_type = RTM_DELADDR;
+  }
+  req.ifa.ifa_family = olsr_cnf->ip_version;
+
+  olsr_netlink_addreq(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
+  olsr_netlink_addreq(&req.n, sizeof(req), IFA_LOCAL, ip, olsr_cnf->ipsize);
+
+  req.ifa.ifa_prefixlen = olsr_cnf->ipsize * 8;
+
+  req.ifa.ifa_index = if_nametoindex("lo");
+
+  return olsr_netlink_send(&req.n);
+}
+
+static int olsr_new_netlink_route(int family, int rttable, int if_index, int metric, int protocol,
     const union olsr_ip_addr *src, const union olsr_ip_addr *gw, const struct olsr_ip_prefix *dst,
     bool set, bool del_similar) {
 
@@ -568,7 +598,12 @@ static int olsr_os_process_rt_entry(int af_family, const struct rt_entry *rt, bo
   }
 
   /* get src ip */
-  src = NULL;
+  if (olsr_cnf->use_src_ip_routes) {
+    src = &olsr_cnf->main_addr;
+  }
+  else {
+    src = NULL;
+  }
 
   /* create route */
   err = olsr_new_netlink_route(af_family, table, nexthop->iif_index, metric, protocol,
index 08334ea..89e348b 100644 (file)
@@ -613,6 +613,11 @@ printf("\nMain Table is %i prio %i", olsr_cnf->rttable, olsr_cnf->rttable_rule);
   if (olsr_cnf->use_niit) {
     olsr_setup_niit_routes();
   }
+
+  /* create lo:olsr interface */
+  if (olsr_cnf->use_src_ip_routes) {
+    olsr_os_create_localhostif(&olsr_cnf->main_addr, true);
+  }
 #endif
 
   /* Start syslog entry */
@@ -758,6 +763,11 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
   if (olsr_cnf->use_niit) {
     olsr_cleanup_niit_routes();
   }
+
+  /* cleanup lo:olsr interface */
+  if (olsr_cnf->use_src_ip_routes) {
+    olsr_os_create_localhostif(&olsr_cnf->main_addr, false);
+  }
 #endif
 
   /* send second shutdown message burst */
index 682b251..0a9a01d 100644 (file)
@@ -54,7 +54,6 @@
 
 #define TESTLIB_PATH 0
 #define SYSLOG_NUMBERING 0
-#define SOURCE_IP_ROUTES 0
 
 #ifndef LINUX_POLICY_ROUTING
 #if defined linux
@@ -261,6 +260,8 @@ struct olsrd_config {
   uint32_t smart_gw_uplink, smart_gw_downlink;
   struct olsr_ip_prefix smart_gw_prefix;
 
+  bool use_src_ip_routes;
+
   /* Stuff set by olsrd */
   uint8_t maxplen;                     /* maximum prefix len */
   size_t ipsize;                       /* Size of address */