/**
 *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;
}
Ejemplo n.º 4
0
/*
 * 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;
}