Infrastructure for storing gateway information
authorHenning Rogge <hrogge@googlemail.com>
Tue, 5 Jan 2010 19:00:08 +0000 (20:00 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Tue, 5 Jan 2010 19:00:08 +0000 (20:00 +0100)
src/gateway.c [new file with mode: 0644]
src/gateway.h [new file with mode: 0644]
src/olsr_cfg.h

diff --git a/src/gateway.c b/src/gateway.c
new file mode 100644 (file)
index 0000000..292aed5
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * gateway.c
+ *
+ *  Created on: 05.01.2010
+ *      Author: henning
+ */
+
+#include "common/avl.h"
+#include "defs.h"
+#include "olsr.h"
+#include "olsr_cfg.h"
+#include "olsr_cookie.h"
+#include "gateway.h"
+
+struct avl_tree gateway_tree;
+
+struct olsr_cookie_info *gw_mem_cookie = NULL;
+
+static uint32_t deserialize_gw_speed(uint8_t value) {
+  uint32_t speed, exp;
+
+  speed = value >> 3;
+  exp = value & 7;
+  while (exp-- > 0) {
+    speed *= 10;
+  }
+  return speed;
+}
+
+static uint8_t serialize_gw_speed(uint32_t speed) {
+  uint8_t exp = 0;
+
+  if (speed == 0 || speed > 310000000) {
+    return 0;
+  }
+
+  while (speed > 32 || (speed % 10) == 0) {
+    speed /= 10;
+    exp ++;
+  }
+  return (speed << 3) | exp;
+}
+
+void
+olsr_init_gateways(void) {
+  uint8_t *ip;
+  gw_mem_cookie = olsr_alloc_cookie("Gateway cookie", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(gw_mem_cookie, sizeof(struct gateway_entry));
+
+  avl_init(&gateway_tree, avl_comp_default);
+
+  memset(&olsr_cnf->smart_gateway_netmask, 0, sizeof(olsr_cnf->smart_gateway_netmask));
+
+  if (olsr_cnf->smart_gateway_active) {
+    union olsr_ip_addr gw_net;
+    int prefix;
+
+    memset(&gw_net, 0, sizeof(gw_net));
+
+    /*
+     * hack for Vienna network to remove 0.0.0.0/128.0.0.0 and 128.0.0.0/128.0.0.0 routes
+     * just set MAXIMUM_GATEWAY_PREFIX_LENGTH to 1
+     */
+    for (prefix = 1; prefix <= MAXIMUM_GATEWAY_PREFIX_LENGTH; prefix++) {
+      while (ip_prefix_list_remove(&olsr_cnf->hna_entries, &gw_net, prefix));
+    }
+
+    ip = (uint8_t *) &olsr_cnf->smart_gateway_netmask;
+    ip[olsr_cnf->ipsize - 2] = serialize_gw_speed(olsr_cnf->smart_gateway_uplink);
+    ip[olsr_cnf->ipsize - 1] = serialize_gw_speed(olsr_cnf->smart_gateway_downlink);
+  }
+}
+
+struct gateway_entry *
+olsr_find_gateway(union olsr_ip_addr *originator) {
+  struct avl_node *node = avl_find(&gateway_tree, originator);
+
+  return node == NULL ? NULL : node2gateway(node);
+}
+
+void
+olsr_set_gateway(union olsr_ip_addr *originator, union olsr_ip_addr *subnetmask) {
+  struct gateway_entry *gw;
+  uint8_t *ip;
+
+  gw = olsr_find_gateway(originator);
+  if (!gw) {
+    gw = olsr_cookie_malloc(gw_mem_cookie);
+
+    gw->originator = *originator;
+    gw->node.key = &gw->originator;
+
+    avl_insert(&gateway_tree, &gw->node, AVL_DUP_NO);
+  }
+
+  ip = (uint8_t *)subnetmask;
+  gw->uplink = deserialize_gw_speed(ip[olsr_cnf->ipsize - 2]);
+  gw->downlink = deserialize_gw_speed(ip[olsr_cnf->ipsize - 1]);
+}
+
+void
+olsr_delete_gateway(union olsr_ip_addr *originator) {
+  struct gateway_entry *gw;
+
+  gw = olsr_find_gateway(originator);
+  if (gw) {
+    avl_delete(&gateway_tree, &gw->node);
+
+    olsr_cookie_free(gw_mem_cookie, gw);
+  }
+}
+
+bool olsr_is_smart_gateway(union olsr_ip_addr *netmask) {
+  uint8_t i;
+  uint8_t *ip;
+
+  ip = (uint8_t *)netmask;
+
+  for (i=0; i<olsr_cnf->ipsize-2; i++) {
+    if (*ip++ != 0) {
+      return false;
+    }
+  }
+
+  return ip[0] > 0 && ip[1] > 0;
+}
diff --git a/src/gateway.h b/src/gateway.h
new file mode 100644 (file)
index 0000000..94a5dda
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * gateway.h
+ *
+ *  Created on: 05.01.2010
+ *      Author: henning
+ */
+
+#ifndef GATEWAY_H_
+#define GATEWAY_H_
+
+#include "common/avl.h"
+#include "defs.h"
+#include "olsr.h"
+
+#define MAXIMUM_GATEWAY_PREFIX_LENGTH 0
+
+struct gateway_entry {
+  struct avl_node node;
+  union olsr_ip_addr originator;
+  uint32_t uplink;
+  uint32_t downlink;
+};
+
+AVLNODE2STRUCT(node2gateway, struct gateway_entry, node);
+
+#define OLSR_FOR_ALL_GATEWAY_ENTRIES(gw) \
+{ \
+  struct avl_node *gw_node, *next_gw_node; \
+  for (gw_node = avl_walk_first(&gateway_tree); \
+    gw_node; gw_node = next_gw_node) { \
+    next_gw_node = avl_walk_next(gw_node); \
+    gw = node2gateway(gw_node);
+#define OLSR_FOR_ALL_GATEWAY_ENTRIES_END(gw) }}
+
+extern struct avl_tree gateway_tree;
+
+void olsr_init_gateways(void);
+struct gateway_entry *olsr_find_gateway(union olsr_ip_addr *originator);
+void olsr_set_gateway(union olsr_ip_addr *originator, union olsr_ip_addr *subnetmask);
+void olsr_delete_gateway(union olsr_ip_addr *originator);
+bool olsr_is_smart_gateway(union olsr_ip_addr *netmask);
+
+#endif /* GATEWAY_H_ */
index baaae78..437ce71 100644 (file)
@@ -253,6 +253,11 @@ struct olsrd_config {
   char *niit_if;
   int niit_if_index;
 
+  bool smart_gateway_active;
+  uint32_t smart_gateway_uplink;
+  uint32_t smart_gateway_downlink;
+  union olsr_ip_addr smart_gateway_netmask;
+
   int ioctl_s;                         /* Socket used for ioctl calls */
 #if LINUX_POLICY_ROUTING
   int rtnl_s;                          /* Socket used for rtnetlink messages */