static int filter_route(struct kernel_route *route, void *data) { void **args = (void**)data; int maxroutes = *(int*)args[0]; struct kernel_route *routes = (struct kernel_route *)args[1]; int *found = (int*)args[2]; if(*found >= maxroutes) return -1; if(martian_prefix(route->prefix, route->plen) || martian_prefix(route->src_prefix, route->src_plen)) return 0; routes[*found] = *route; ++ *found; return 0; }
static int kernel_rule_notify(struct kernel_rule *rule, void *closure) { int i; if(martian_prefix(rule->src, rule->src_plen)) return 0; i = rule->priority - src_table_prio; if(i < 0 || SRC_TABLE_NUM <= i) return 0; kernel_rules_changed = 1; return -1; }
/* add an xroute, verifying some conditions; return 0 if there is no changes */ static int xroute_add_new_route(unsigned char prefix[16], unsigned char plen, unsigned short metric, unsigned int ifindex, int proto, int send_updates) { int rc; if(martian_prefix(prefix, plen)) return 0; metric = redistribute_filter(prefix, plen, ifindex, proto); if(metric < INFINITY) { rc = add_xroute(prefix, plen, metric, ifindex, proto); if(rc > 0) { struct babel_route *route; route = find_installed_route(prefix, plen); if(route) uninstall_route(route); if(send_updates) send_update(NULL, 0, prefix, plen); return 1; } } return 0; }
static int filter_kernel_routes(struct nlmsghdr *nh, void *data) { int rc; struct kernel_route *current_route; struct kernel_route route; int maxroutes = 0; struct kernel_route *routes = NULL; int *found = NULL; int len; struct rtmsg *rtm; if(data) { void **args = (void**)data; maxroutes = *(int*)args[0]; routes = (struct kernel_route *)args[1]; found = (int*)args[2]; } len = nh->nlmsg_len; if(data && *found >= maxroutes) return 0; if(nh->nlmsg_type != RTM_NEWROUTE && (data || nh->nlmsg_type != RTM_DELROUTE)) return 0; rtm = (struct rtmsg*)NLMSG_DATA(nh); len -= NLMSG_LENGTH(0); if(rtm->rtm_protocol == RTPROT_BABEL) return 0; if(rtm->rtm_src_len != 0) return 0; if(data) current_route = &routes[*found]; else current_route = &route; rc = parse_kernel_route_rta(rtm, len, current_route); if(rc < 0) return 0; if(martian_prefix(current_route->prefix, current_route->plen)) return 0; /* Ignore default unreachable routes; no idea where they come from. */ if(current_route->plen == 0 && current_route->metric >= KERNEL_INFINITY) return 0; if(debug >= 2) { if(rc >= 0) { print_kernel_route(nh->nlmsg_type, rtm->rtm_protocol, rtm->rtm_type, current_route); } } if (data) *found = (*found)+1; return 1; }