diff -Nur olsrd-0.5.3.orig/lib/httpinfo/src/olsrd_httpinfo.c olsrd-0.5.3/lib/httpinfo/src/olsrd_httpinfo.c
--- olsrd-0.5.3.orig/lib/httpinfo/src/olsrd_httpinfo.c	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/lib/httpinfo/src/olsrd_httpinfo.c	2007-09-04 16:46:11.000000000 +0200
@@ -851,6 +851,8 @@
 
     size += snprintf(&buf[size], bufsize-size, "<td>TOS: 0x%04x</td>\n", olsr_cnf->tos);
 
+    size += sprintf(&buf[size], "<td>RtTable: 0x%04x</td>\n", olsr_cnf->rttable);
+
     size += snprintf(&buf[size], bufsize-size, "<td>Willingness: %d %s</td>\n", olsr_cnf->willingness, olsr_cnf->willingness_auto ? "(auto)" : "");
     
     size += snprintf(&buf[size], bufsize-size, "</tr>\n<tr>\n");
diff -Nur olsrd-0.5.3.orig/src/cfgparser/cfgfile_gen.c olsrd-0.5.3/src/cfgparser/cfgfile_gen.c
--- olsrd-0.5.3.orig/src/cfgparser/cfgfile_gen.c	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/cfgparser/cfgfile_gen.c	2007-09-04 16:46:11.000000000 +0200
@@ -123,6 +123,10 @@
   fprintf(fd, "# TOS(type of service) to use. Default is 16\n\n");
   fprintf(fd, "TosValue\t%d\n\n", cnf->tos);
 
+  /* RtTable */
+  fprintf(fd, "# Policy Routing Table to use. Default is 254\n\n");
+  fprintf(fd, "RtTable\t%d\n\n", cnf->rttable);
+
   /* Willingness */
   fprintf(fd, "# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n");
   if(cnf->willingness_auto)
@@ -442,6 +446,10 @@
   WRITE_TO_BUF("# TOS(type of service) to use. Default is 16\n\n")
   WRITE_TO_BUF("TosValue\t%d\n\n", cnf->tos)
 
+  /* RtTable */
+  WRITE_TO_BUF("# Policy Routing Tableto use. Default is 254\n\n")
+  WRITE_TO_BUF("RtTable\t%d\n\n", cnf->rttable)
+
   /* Willingness */
   WRITE_TO_BUF("# The fixed willingness to use(0-7)\n# If not set willingness will be calculated\n# dynammically based on battery/power status\n\n")
   if(cnf->willingness_auto)
diff -Nur olsrd-0.5.3.orig/src/cfgparser/olsrd_conf.c olsrd-0.5.3/src/cfgparser/olsrd_conf.c
--- olsrd-0.5.3.orig/src/cfgparser/olsrd_conf.c	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/cfgparser/olsrd_conf.c	2007-09-04 16:46:11.000000000 +0200
@@ -453,6 +453,7 @@
     cnf->ip_version  = AF_INET;
     cnf->allow_no_interfaces = DEF_ALLOW_NO_INTS;
     cnf->tos = DEF_TOS;
+    cnf->rttable = 254;
     cnf->willingness_auto = DEF_WILL_AUTO;
     cnf->ipc_connections = DEF_IPC_CONNECTIONS;
     cnf->open_ipc = cnf->ipc_connections ? OLSR_TRUE : OLSR_FALSE;
@@ -482,7 +483,11 @@
     cnf->exit_value = EXIT_SUCCESS;
     cnf->max_tc_vtime = 0.0;
     cnf->ioctl_s = 0;
+#ifdef LINUX_POLICY_ROUTING
+    cnf->rtnl_s = 0;
+#else
     cnf->rts = 0;
+#endif
 }
 
 
@@ -558,6 +563,7 @@
   else
     printf("No interfaces    : NOT ALLOWED\n");
   printf("TOS              : 0x%02x\n", cnf->tos);
+  printf("RtTable          : 0x%02x\n", cnf->rttable);
   if(cnf->willingness_auto)
     printf("Willingness      : AUTO\n");
   else
diff -Nur olsrd-0.5.3.orig/src/cfgparser/oparse.y olsrd-0.5.3/src/cfgparser/oparse.y
--- olsrd-0.5.3.orig/src/cfgparser/oparse.y	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/cfgparser/oparse.y	2007-09-04 16:46:11.000000000 +0200
@@ -149,6 +149,7 @@
 %token TOK_INTERFACE
 %token TOK_NOINT
 %token TOK_TOS
+%token TOK_RTTABLE
 %token TOK_WILLINGNESS
 %token TOK_IPCCON
 %token TOK_USEHYST
@@ -206,6 +207,7 @@
           | iipversion
           | bnoint
           | atos
+          | arttable
           | awillingness
           | busehyst
           | fhystscale
@@ -864,6 +866,16 @@
 }
 ;
 
+arttable: TOK_RTTABLE TOK_INTEGER
+{
+  if(PARSER_DEBUG) printf("RtTable: %d\n", $2->integer);
+  cnf->rttable = $2->integer;
+
+  free($2);
+
+}
+;
+
 awillingness: TOK_WILLINGNESS TOK_INTEGER
 {
   cnf->willingness_auto = OLSR_FALSE;
diff -Nur olsrd-0.5.3.orig/src/cfgparser/oscan.lex olsrd-0.5.3/src/cfgparser/oscan.lex
--- olsrd-0.5.3.orig/src/cfgparser/oscan.lex	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/cfgparser/oscan.lex	2007-09-04 16:46:11.000000000 +0200
@@ -299,6 +299,11 @@
     return TOK_TOS;
 }
 
+"RtTable" {
+  yylval = NULL;
+  return TOK_RTTABLE;
+}
+
 "Willingness" {
     yylval = NULL;
     return TOK_WILLINGNESS;
diff -Nur olsrd-0.5.3.orig/src/linux/kernel_routes.c olsrd-0.5.3/src/linux/kernel_routes.c
--- olsrd-0.5.3.orig/src/linux/kernel_routes.c	2007-05-17 22:30:09.000000000 +0200
+++ olsrd-0.5.3/src/linux/kernel_routes.c	2007-09-04 16:46:11.000000000 +0200
@@ -1,6 +1,7 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(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 
@@ -49,6 +50,8 @@
 #include <sys/ioctl.h>
 #include <unistd.h>
 
+#ifndef LINUX_POLICY_ROUTING
+
 
 
 static struct sockaddr_in6 null_addr6; /* Address used as Originator Address IPv6 */
@@ -404,3 +407,164 @@
   return 0;
        
 }
+
+#else /* LINUX_POLICY_ROUTING */
+
+#include <assert.h>
+#include <linux/types.h>
+#include <linux/rtnetlink.h>
+
+struct olsr_rtreq
+{
+	struct nlmsghdr		n;
+	struct rtmsg		r;
+	char			buf[256];
+};
+
+static void olsr_netlink_addreq(struct olsr_rtreq *req, int type, void *data, int len)
+{
+	struct rtattr *rta = (struct rtattr*)(((char*)req) + NLMSG_ALIGN(req->n.nlmsg_len));
+	req->n.nlmsg_len = NLMSG_ALIGN(req->n.nlmsg_len) + RTA_LENGTH(len);
+	assert(req->n.nlmsg_len < sizeof(struct olsr_rtreq));
+	rta->rta_type = type;
+	rta->rta_len = RTA_LENGTH(len);
+	memcpy(RTA_DATA(rta), data, len);
+}
+
+static int olsr_netlink_route(struct rt_entry *destination, olsr_u8_t family, olsr_u8_t rttable, __u16 cmd)
+{
+	int ret = 0;
+	olsr_32_t rt_metric = destination->rt_metric;
+	struct olsr_rtreq req;
+	struct iovec iov;
+	struct sockaddr_nl nladdr;
+	struct msghdr msg =
+	{
+		(void*)&nladdr,
+		sizeof(nladdr),
+		&iov,
+		1,
+		NULL,
+		0,
+		0
+	};
+
+	memset(&req, 0, sizeof(req));
+	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+	req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
+	req.n.nlmsg_type = cmd;
+	req.r.rtm_family = family;
+	req.r.rtm_table = rttable;
+	req.r.rtm_protocol = RTPROT_BOOT;
+	req.r.rtm_scope = RT_SCOPE_LINK;
+	req.r.rtm_type = RTN_UNICAST;
+
+	if (AF_INET == family)
+	{
+		olsr_u32_t netmask = htonl(destination->rt_mask.v4);
+		req.r.rtm_dst_len = 0;
+		while(0xff000000L == (netmask & 0xff000000L))
+		{
+			req.r.rtm_dst_len += 8;
+			netmask <<= 8;
+		}
+		while(0x80000000L == (netmask & 0x80000000L))
+		{
+			req.r.rtm_dst_len ++;
+			netmask <<= 1;
+		}
+		if (destination->rt_dst.v4 != destination->rt_router.v4)
+		{
+			olsr_netlink_addreq(&req, RTA_GATEWAY, &destination->rt_router.v4, sizeof(destination->rt_router.v4));
+			req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+		}
+		olsr_netlink_addreq(&req, RTA_DST, &destination->rt_dst.v4, sizeof(destination->rt_dst.v4));
+	}
+	else
+	{
+		req.r.rtm_dst_len = destination->rt_mask.v6;
+		if (0 != memcmp(&destination->rt_dst.v6, &destination->rt_router.v6, sizeof(destination->rt_router.v6)))
+		{
+			olsr_netlink_addreq(&req, RTA_GATEWAY, &destination->rt_router.v6, sizeof(destination->rt_router.v6));
+			req.r.rtm_scope = RT_SCOPE_UNIVERSE;
+		}
+		olsr_netlink_addreq(&req, RTA_DST, &destination->rt_dst.v6, sizeof(destination->rt_dst.v6));
+	}
+	olsr_netlink_addreq(&req, RTA_PRIORITY, &rt_metric, sizeof(rt_metric));
+	olsr_netlink_addreq(&req, RTA_OIF, &destination->rt_if->if_index, sizeof(destination->rt_if->if_index));
+	iov.iov_base = (void*)&req.n;
+	iov.iov_len = req.n.nlmsg_len;
+	memset(&nladdr, 0, sizeof(nladdr));
+	nladdr.nl_family = AF_NETLINK;
+	if (0 <= (ret = sendmsg(olsr_cnf->rtnl_s, &msg, 0)))
+	{
+		iov.iov_base = req.buf;
+		iov.iov_len = sizeof(req.buf);
+		if (0 < (ret = recvmsg(olsr_cnf->rtnl_s, &msg, 0)))
+		{
+			struct nlmsghdr* h = (struct nlmsghdr*)req.buf;
+			while (NLMSG_OK(h, (unsigned int)ret)) {
+				if (NLMSG_DONE == h->nlmsg_type) break;
+				if (NLMSG_ERROR == h->nlmsg_type)
+				{
+					if (NLMSG_LENGTH(sizeof(struct nlmsgerr) <= h->nlmsg_len))
+					{
+						struct nlmsgerr *l_err = (struct nlmsgerr*)NLMSG_DATA(h);
+						errno = -l_err->error;
+						if (0 != errno) ret = -1;
+					}
+					break;
+				}
+				h = NLMSG_NEXT(h, ret);
+			}
+		}
+		if (0 <= ret && olsr_cnf->open_ipc)
+		{
+			ipc_route_send_rtentry(
+				&destination->rt_dst,
+				RTM_NEWROUTE == cmd ? &destination->rt_router : NULL,
+			       	destination->rt_metric,
+			       	RTM_NEWROUTE == cmd,
+			       	destination->rt_if->int_name);
+		}
+	}
+	return ret;
+}
+
+int olsr_ioctl_add_route(struct rt_entry *destination)
+{
+	if (0 == destination->rt_mask.v4 && 253 > olsr_cnf->rttable)
+	{
+		/*
+		 * Users start whining about not having internet with policy
+		 * routing activated and no static default route in table 254.
+		 * We maintain a fallback defroute in the default=253 table.
+		 */
+		olsr_netlink_route(destination, AF_INET, 253, RTM_NEWROUTE);
+	}
+	return olsr_netlink_route(destination, AF_INET, olsr_cnf->rttable, RTM_NEWROUTE);
+}
+
+int olsr_ioctl_del_route(struct rt_entry *destination)
+{
+	if (0 == destination->rt_mask.v4 && 253 > olsr_cnf->rttable)
+	{
+		/*
+		 * Also remove the fallback default route
+		 */
+		olsr_netlink_route(destination, AF_INET, 253, RTM_DELROUTE);
+	}
+	return olsr_netlink_route(destination, AF_INET, olsr_cnf->rttable, RTM_DELROUTE);
+}
+
+int olsr_ioctl_add_route6(struct rt_entry *destination)
+{
+	return olsr_netlink_route(destination, AF_INET6, olsr_cnf->rttable, RTM_NEWROUTE);
+}
+
+int olsr_ioctl_del_route6(struct rt_entry *destination)
+{
+	return olsr_netlink_route(destination, AF_INET6, olsr_cnf->rttable, RTM_DELROUTE);
+}
+
+#endif /* LINUX_POLICY_ROUTING */
diff -Nur olsrd-0.5.3.orig/src/main.c olsrd-0.5.3/src/main.c
--- olsrd-0.5.3.orig/src/main.c	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/main.c	2007-09-04 16:46:11.000000000 +0200
@@ -56,6 +56,12 @@
 #include "net_os.h"
 #include "build_msg.h"
 
+#ifdef LINUX_POLICY_ROUTING
+#include <linux/types.h>
+#include <linux/rtnetlink.h>
+#include <fcntl.h>
+#endif
+
 /* Global stuff externed in defs.h */
 FILE *debug_handle;             /* Where to send debug(defaults to stdout) */
 struct olsrd_config *olsr_cnf;  /* The global configuration */
@@ -266,6 +272,15 @@
       olsr_exit(__func__, 0);
     }
 
+#ifdef LINUX_POLICY_ROUTING
+  if ((olsr_cnf->rtnl_s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0) 
+    {
+      olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
+      olsr_exit(__func__, 0);
+    }
+  fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
+#endif
+
 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
   if ((olsr_cnf->rts = socket(PF_ROUTE, SOCK_RAW, 0)) < 0)
     {
@@ -488,6 +503,10 @@
   /* ioctl socket */
   close(olsr_cnf->ioctl_s);
 
+#ifdef LINUX_POLICY_ROUTING
+  close(olsr_cnf->rtnl_s);
+#endif
+
 #if defined __FreeBSD__ || defined __MacOSX__ || defined __NetBSD__ || defined __OpenBSD__
   /* routing socket */
   close(olsr_cnf->rts);
diff -Nur olsrd-0.5.3.orig/src/olsr_cfg.h olsrd-0.5.3/src/olsr_cfg.h
--- olsrd-0.5.3.orig/src/olsr_cfg.h	2007-09-04 16:46:11.000000000 +0200
+++ olsrd-0.5.3/src/olsr_cfg.h	2007-09-04 16:46:11.000000000 +0200
@@ -45,6 +45,10 @@
 
 #include "olsr_types.h"
 
+#if defined linux
+#  define LINUX_POLICY_ROUTING
+#endif
+
 /* Default valuse not declared in olsr_protocol.h */
 #define DEF_POLLRATE        0.05
 #define DEF_NICCHGPOLLRT    2.5
@@ -203,6 +207,7 @@
   int                      ip_version;
   olsr_bool                allow_no_interfaces;
   olsr_u16_t               tos;
+  olsr_u8_t                rttable;
   olsr_bool                willingness_auto;
   olsr_u8_t                willingness;
   int                      ipc_connections;
@@ -239,7 +244,11 @@
   float                    max_tc_vtime;
 
   int                      ioctl_s;              /* Socket used for ioctl calls */
+#ifdef LINUX_POLICY_ROUTING
+  int                      rtnl_s;               /* Socket used for rtnetlink messages */
+#else
   int                      rts;                  /* Socket used for route changes on BSDs */
+#endif
 };
 
 #if defined __cplusplus
