/** *Remove a route from the kernel * *@param destination the route to remove * *@return negative on error */ int olsr_ioctl_del_route6(const struct rt_entry *rt) { struct in6_rtmsg kernel_route; int rslt; OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt)); memset(&kernel_route, 0, sizeof(struct in6_rtmsg)); kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6; kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len; kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6; kernel_route.rtmsg_flags = olsr_rt_flags(rt); kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric); if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route) >= 0)) { /* * Send IPC route update message */ ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL); } return rslt; }
/** *Insert a route in the kernel routing table * *@param destination the route to add * *@return negative on error */ int olsr_ioctl_add_route6(const struct rt_entry *rt) { struct in6_rtmsg kernel_route; int rslt; OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best)); memset(&kernel_route, 0, sizeof(struct in6_rtmsg)); kernel_route.rtmsg_dst = rt->rt_dst.prefix.v6; kernel_route.rtmsg_dst_len = rt->rt_dst.prefix_len; kernel_route.rtmsg_gateway = rt->rt_best->rtp_nexthop.gateway.v6; kernel_route.rtmsg_flags = olsr_rt_flags(rt); kernel_route.rtmsg_metric = olsr_fib_metric(&rt->rt_best->rtp_metric); /* * set interface */ kernel_route.rtmsg_ifindex = rt->rt_best->rtp_nexthop.iif_index; /* XXX delete 0/0 route before ? */ if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) { /* * Send IPC route update message */ ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1, if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index)); } return rslt; }
/** * Insert a route in the kernel routing table * * @param destination the route to add * * @return negative on error */ int olsr_ioctl_add_route(const struct rt_entry *rt) { char if_name[IFNAMSIZ]; struct rtentry kernel_route; union olsr_ip_addr mask; int rslt; OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best)); memset(&kernel_route, 0, sizeof(struct rtentry)); ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4; if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) { return -1; } ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4; if (rt->rt_dst.prefix.v4.s_addr != rt->rt_best->rtp_nexthop.gateway.v4.s_addr) { ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_best->rtp_nexthop.gateway.v4; } kernel_route.rt_flags = olsr_rt_flags(rt); kernel_route.rt_metric = olsr_fib_metric(&rt->rt_best->rtp_metric); /* * Set interface */ strcpy(if_name, if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index)); kernel_route.rt_dev = if_name; /* delete existing default route before ? */ if ((olsr_cnf->del_gws) && (rt->rt_dst.prefix.v4.s_addr == INADDR_ANY) && (rt->rt_dst.prefix_len == INADDR_ANY)) { delete_all_inet_gws(); olsr_cnf->del_gws = false; } if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCADDRT, &kernel_route)) >= 0) { /* * Send IPC route update message */ ipc_route_send_rtentry(&rt->rt_dst.prefix, &rt->rt_best->rtp_nexthop.gateway, rt->rt_best->rtp_metric.hops, 1, if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index)); } return rslt; }
/* * Remove a route from the kernel * @param destination the route to remove * @return negative on error */ int os_route_del_rtentry(const struct rt_entry *rt, int ip_version) { MIB_IPFORWARDROW Row; union olsr_ip_addr mask; unsigned long Res; struct interface *iface = rt->rt_nexthop.interface; if (AF_INET != ip_version) { /* * Not implemented */ return -1; } OLSR_DEBUG(LOG_NETWORKING, "KERN: Deleting %s\n", olsr_rt_to_string(rt)); memset(&Row, 0, sizeof(Row)); Row.dwForwardDest = rt->rt_dst.prefix.v4.s_addr; if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) { return -1; } Row.dwForwardMask = mask.v4.s_addr; Row.dwForwardPolicy = 0; Row.dwForwardNextHop = rt->rt_nexthop.gateway.v4.s_addr; Row.dwForwardIfIndex = iface->if_index; // MIB_IPROUTE_TYPE_DIRECT and MIB_IPROUTE_TYPE_INDIRECT Row.dwForwardType = (rt->rt_dst.prefix.v4.s_addr == rt->rt_nexthop.gateway.v4.s_addr) ? 3 : 4; Row.dwForwardProto = 3; // MIB_IPPROTO_NETMGMT Row.dwForwardAge = INFINITE; Row.dwForwardNextHopAS = 0; Row.dwForwardMetric1 = olsr_fib_metric(&rt->rt_metric); Row.dwForwardMetric2 = -1; Row.dwForwardMetric3 = -1; Row.dwForwardMetric4 = -1; Row.dwForwardMetric5 = -1; Res = DeleteIpForwardEntry(&Row); if (Res != NO_ERROR) { OLSR_WARN(LOG_NETWORKING, "DeleteIpForwardEntry() = %08lx, %s", Res, win32_strerror(Res)); // XXX - report error in a different way errno = Res; return -1; } return 0; }
/** *Remove a route from the kernel * *@param destination the route to remove * *@return negative on error */ int olsr_ioctl_del_route(const struct rt_entry *rt) { struct rtentry kernel_route; union olsr_ip_addr mask; int rslt; OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt)); memset(&kernel_route, 0, sizeof(struct rtentry)); ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_family = AF_INET; ((struct sockaddr_in *)&kernel_route.rt_dst)->sin_addr = rt->rt_dst.prefix.v4; if (rt->rt_dst.prefix.v4.s_addr != rt->rt_nexthop.gateway.v4.s_addr) { ((struct sockaddr_in *)&kernel_route.rt_gateway)->sin_addr = rt->rt_nexthop.gateway.v4; } if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) { return -1; } else { ((struct sockaddr_in *)&kernel_route.rt_genmask)->sin_addr = mask.v4; } kernel_route.rt_flags = olsr_rt_flags(rt); kernel_route.rt_metric = olsr_fib_metric(&rt->rt_metric); /* * Set interface */ kernel_route.rt_dev = NULL; if ((rslt = ioctl(olsr_cnf->ioctl_s, SIOCDELRT, &kernel_route)) >= 0) { /* * Send IPC route update message */ ipc_route_send_rtentry(&rt->rt_dst.prefix, NULL, 0, 0, NULL); } return rslt; }