filter.c (1872B)
1 #include <string.h> 2 #include <sys/socket.h> 3 4 #include <linux/rtnetlink.h> 5 6 #include "filter.h" 7 8 #define FILTER_MAX_TRACKED 64 9 #define FILTER_MAX_EXCLUDED 16 10 11 static uint32_t tracked[FILTER_MAX_TRACKED]; 12 static int tracked_count = 0; 13 static uint32_t excluded[FILTER_MAX_EXCLUDED]; 14 static int excluded_count = 0; 15 16 static int find_u32(const uint32_t *arr, int n, uint32_t v) { 17 int i; 18 for (i = 0; i < n; i++) { 19 if (arr[i] == v) return i; 20 } 21 return -1; 22 } 23 24 void nl_filter_reset(void) { 25 tracked_count = 0; 26 excluded_count = 0; 27 tracked[tracked_count++] = RT_TABLE_MAIN; 28 } 29 30 void nl_filter_track(uint32_t table) { 31 if (table == RT_TABLE_LOCAL) return; 32 if (find_u32(tracked, tracked_count, table) >= 0) return; 33 if (tracked_count >= FILTER_MAX_TRACKED) return; 34 tracked[tracked_count++] = table; 35 } 36 37 void nl_filter_untrack(uint32_t table) { 38 int idx; 39 if (table == RT_TABLE_MAIN) return; 40 idx = find_u32(tracked, tracked_count, table); 41 if (idx < 0) return; 42 tracked[idx] = tracked[--tracked_count]; 43 } 44 45 void nl_filter_exclude(uint32_t table) { 46 if (find_u32(excluded, excluded_count, table) >= 0) return; 47 if (excluded_count >= FILTER_MAX_EXCLUDED) return; 48 excluded[excluded_count++] = table; 49 } 50 51 bool nl_filter_mgmt_name(const char *ifname) { 52 if (!ifname) return false; 53 if (!strcmp(ifname, "mgmt")) return true; 54 if (!strcmp(ifname, "mgmt0")) return true; 55 return false; 56 } 57 58 bool nl_table_allowed(uint32_t table) { 59 if (table == RT_TABLE_LOCAL) return false; 60 if (find_u32(excluded, excluded_count, table) >= 0) return false; 61 return find_u32(tracked, tracked_count, table) >= 0; 62 } 63 64 bool nl_route_allowed(int family, uint8_t type, uint8_t scope, uint32_t table) { 65 if (family != AF_INET && family != AF_INET6) return false; 66 if (type != RTN_UNICAST) return false; 67 if (scope == RT_SCOPE_HOST) return false; 68 return nl_table_allowed(table); 69 }