summaryrefslogtreecommitdiffstats
path: root/routing-table.h
diff options
context:
space:
mode:
Diffstat (limited to 'routing-table.h')
-rw-r--r--routing-table.h54
1 files changed, 54 insertions, 0 deletions
diff --git a/routing-table.h b/routing-table.h
new file mode 100644
index 0000000..1044474
--- /dev/null
+++ b/routing-table.h
@@ -0,0 +1,54 @@
+/* Copyright 2015 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. */
+
+#ifndef ROUTINGTABLE_H
+#define ROUTINGTABLE_H
+
+#include <linux/list.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+
+struct routing_table {
+ struct hlist_head head;
+};
+
+void routing_table_init(struct routing_table *table);
+void routing_table_free(struct routing_table *table);
+int routing_table_insert_v4(struct routing_table *table, struct in_addr ip, uint8_t cidr, void *value);
+int routing_table_insert_v6(struct routing_table *table, struct in6_addr ip, uint8_t cidr, void *value);
+void *routing_table_lookup_v4(struct routing_table *table, struct in_addr ip);
+void *routing_table_lookup_v6(struct routing_table *table, struct in6_addr ip);
+int routing_table_remove_v4(struct routing_table *table, struct in_addr ip, uint8_t cidr);
+int routing_table_remove_v6(struct routing_table *table, struct in6_addr ip, uint8_t cidr);
+int routing_table_remove_by_value(struct routing_table *table, void *value);
+int routing_table_walk_ips(struct routing_table *table, void *ctx, int (*func)(void *ctx, void *value, union nf_inet_addr ip, uint8_t cidr, uint8_t ip_version));
+int routing_table_walk_ips_by_value(struct routing_table *table, void *ctx, void *value, int (*func)(void *ctx, union nf_inet_addr ip, uint8_t cidr, uint8_t ip_version));
+
+static inline void *routing_table_lookup_dst(struct routing_table *table, struct sk_buff *skb)
+{
+ switch (ip_hdr(skb)->version) {
+ case 4:
+ return routing_table_lookup_v4(table, *(struct in_addr *)&ip_hdr(skb)->daddr);
+ case 6:
+ return routing_table_lookup_v6(table, ipv6_hdr(skb)->daddr);
+ default:
+ return NULL;
+ }
+}
+
+static inline void *routing_table_lookup_src(struct routing_table *table, struct sk_buff *skb)
+{
+ switch (ip_hdr(skb)->version) {
+ case 4:
+ return routing_table_lookup_v4(table, *(struct in_addr *)&ip_hdr(skb)->saddr);
+ case 6:
+ return routing_table_lookup_v6(table, ipv6_hdr(skb)->saddr);
+ default:
+ return NULL;
+ }
+}
+
+#ifdef DEBUG
+void routing_table_selftest(void);
+#endif
+
+#endif