/*
 * Copyright 2012 Daniel Drown <dan-android@drown.org>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * setroute.c - network route configuration
 */
#include <errno.h>
#include <netinet/in.h>
#include <net/if.h>

#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <netlink/handlers.h>
#include <netlink/msg.h>

#include "netlink_msg.h"
#include "setroute.h"
#include "logging.h"
#include "getroute.h"

/* function: if_route
 * create/replace/delete a route
 * ifname      - name of the outbound interface
 * family      - AF_INET or AF_INET6
 * destination - pointer to a struct in_addr or in6_addr for the destination network
 * prefixlen   - bitlength of the network address (example: 24 for AF_INET's 255.255.255.0)
 * gateway     - pointer to a struct in_addr or in6_addr for the gateway to use or NULL for an interface route
 * metric      - route metric (lower is better)
 * mtu         - route-specific mtu or 0 for the interface mtu
 * change_type - ROUTE_DELETE, ROUTE_REPLACE, or ROUTE_CREATE
 */
int if_route(const char *ifname, int family, const void *destination, int prefixlen, const void *gateway, int metric, int mtu, int change_type) {
  int retval;
  struct nl_msg *msg = NULL;
  struct rtmsg rt;
  uint16_t type, flags = 0;
  size_t addr_size;
  uint32_t ifindex;

  addr_size = inet_family_size(family);
  if(addr_size == 0) {
    retval = -EAFNOSUPPORT;
    goto cleanup;
  }

  if (!(ifindex = if_nametoindex(ifname))) {
    retval = -ENODEV;
    goto cleanup;
  }

  memset(&rt, 0, sizeof(rt));
  rt.rtm_family = family;
  rt.rtm_table = RT_TABLE_LOCAL;
  rt.rtm_dst_len = prefixlen;
  switch(change_type) {
    case ROUTE_DELETE:
      rt.rtm_scope = RT_SCOPE_NOWHERE;
      type = RTM_DELROUTE;
      break;

    case ROUTE_REPLACE:
      flags = NLM_F_REPLACE;
    case ROUTE_CREATE:
      type = RTM_NEWROUTE;
      flags |= NLM_F_CREATE;
      if(gateway == NULL) {
        rt.rtm_scope = RT_SCOPE_LINK;
      } else {
        rt.rtm_scope = RT_SCOPE_UNIVERSE;
      }
      rt.rtm_type = RTN_UNICAST;
      //RTPROT_STATIC = from administrator's configuration
      //RTPROT_BOOT = from an automatic process
      rt.rtm_protocol = RTPROT_BOOT;
      break;

    default:
      retval = -EINVAL;
      goto cleanup;
  }

  flags |= NLM_F_REQUEST | NLM_F_ACK;

  msg = nlmsg_alloc_rtmsg(type, flags, &rt);
  if(!msg) {
    retval = -ENOMEM;
    goto cleanup;
  }

  if(nla_put(msg, RTA_DST, addr_size, destination) < 0) {
    retval = -ENOMEM;
    goto cleanup;
  }
  if(gateway != NULL)
    if(nla_put(msg, RTA_GATEWAY, addr_size, gateway) < 0) {
      retval = -ENOMEM;
      goto cleanup;
    }
  if(nla_put(msg, RTA_OIF, 4, &ifindex) < 0) {
    retval = -ENOMEM;
    goto cleanup;
  }
  if(nla_put(msg, RTA_PRIORITY, 4, &metric) < 0) {
    retval = -ENOMEM;
    goto cleanup;
  }
  if(mtu > 0 && change_type != ROUTE_DELETE) {
    // MTU is inside an RTA_METRICS nested message
    struct nlattr *metrics = nla_nest_start(msg, RTA_METRICS);
    if(metrics == NULL) {
      retval = -ENOMEM;
      goto cleanup;
    }

    if(nla_put(msg, RTAX_MTU, 4, &mtu) < 0) {
      retval = -ENOMEM;
      goto cleanup;
    }

    nla_nest_end(msg, metrics);
  }

  retval = netlink_sendrecv(msg);

cleanup:
  if(msg)
    nlmsg_free(msg);

  return retval;
}
