/* Copyright 2015 Jason A. Donenfeld . All Rights Reserved. */ #ifndef ROUTINGTABLE_H #define ROUTINGTABLE_H #include #include #include 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