/* vi: set sw=4 ts=4: */
/*
 * iproute.c		"ip route".
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 *
 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 *
 * Changes:
 *
 * Rani Assaf <rani@magic.metawire.com> 980929:	resolve addresses
 * Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized
 */

#include "ip_common.h"	/* #include "libbb.h" is inside */
#include "rt_names.h"
#include "utils.h"

#ifndef RTAX_RTTVAR
#define RTAX_RTTVAR RTAX_HOPS
#endif


typedef struct filter_t {
	int tb;
	smallint flushed;
	char *flushb;
	int flushp;
	int flushe;
	struct rtnl_handle *rth;
	int protocol, protocolmask;
	int scope, scopemask;
	int type, typemask;
	int tos, tosmask;
	int iif, iifmask;
	int oif, oifmask;
	int realm, realmmask;
	inet_prefix rprefsrc;
	inet_prefix rvia;
	inet_prefix rdst;
	inet_prefix mdst;
	inet_prefix rsrc;
	inet_prefix msrc;
} filter_t;

#define filter (*(filter_t*)&bb_common_bufsiz1)

static int flush_update(void)
{
	if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
		bb_perror_msg("failed to send flush request");
		return -1;
	}
	filter.flushp = 0;
	return 0;
}

static unsigned get_hz(void)
{
	static unsigned hz_internal;
	FILE *fp;

	if (hz_internal)
		return hz_internal;

	fp = fopen_for_read("/proc/net/psched");
	if (fp) {
		unsigned nom, denom;

		if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
			if (nom == 1000000)
				hz_internal = denom;
		fclose(fp);
	}
	if (!hz_internal)
		hz_internal = sysconf(_SC_CLK_TCK);
	return hz_internal;
}

static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
		struct nlmsghdr *n, void *arg UNUSED_PARAM)
{
	struct rtmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * tb[RTA_MAX+1];
	char abuf[256];
	inet_prefix dst;
	inet_prefix src;
	int host_len = -1;
	SPRINT_BUF(b1);

	if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
		fprintf(stderr, "Not a route: %08x %08x %08x\n",
			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
		return 0;
	}
	if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0)
		bb_error_msg_and_die("wrong nlmsg len %d", len);

	if (r->rtm_family == AF_INET6)
		host_len = 128;
	else if (r->rtm_family == AF_INET)
		host_len = 32;

	if (r->rtm_family == AF_INET6) {
		if (filter.tb) {
			if (filter.tb < 0) {
				if (!(r->rtm_flags & RTM_F_CLONED)) {
					return 0;
				}
			} else {
				if (r->rtm_flags & RTM_F_CLONED) {
					return 0;
				}
				if (filter.tb == RT_TABLE_LOCAL) {
					if (r->rtm_type != RTN_LOCAL) {
						return 0;
					}
				} else if (filter.tb == RT_TABLE_MAIN) {
					if (r->rtm_type == RTN_LOCAL) {
						return 0;
					}
				} else {
					return 0;
				}
			}
		}
	} else {
		if (filter.tb > 0 && filter.tb != r->rtm_table) {
			return 0;
		}
	}
	if (filter.rdst.family &&
	    (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) {
		return 0;
	}
	if (filter.mdst.family &&
	    (r->rtm_family != filter.mdst.family ||
	     (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) {
		return 0;
	}
	if (filter.rsrc.family &&
	    (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) {
		return 0;
	}
	if (filter.msrc.family &&
	    (r->rtm_family != filter.msrc.family ||
	     (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) {
		return 0;
	}

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);

	if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
		return 0;
	if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
	    inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
		return 0;

	if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
		return 0;
	if (filter.msrc.family && filter.msrc.bitlen >= 0 &&
	    inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
		return 0;

	if (filter.flushb &&
	    r->rtm_family == AF_INET6 &&
	    r->rtm_dst_len == 0 &&
	    r->rtm_type == RTN_UNREACHABLE &&
	    tb[RTA_PRIORITY] &&
	    *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1)
		return 0;

	if (filter.flushb) {
		struct nlmsghdr *fn;
		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
			if (flush_update())
				bb_error_msg_and_die("flush");
		}
		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELROUTE;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++filter.rth->seq;
		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
		filter.flushed = 1;
		return 0;
	}

	if (n->nlmsg_type == RTM_DELROUTE) {
		printf("Deleted ");
	}
	if (r->rtm_type != RTN_UNICAST && !filter.type) {
		printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1));
	}

	if (tb[RTA_DST]) {
		if (r->rtm_dst_len != host_len) {
			printf("%s/%u ", rt_addr_n2a(r->rtm_family,
						RTA_DATA(tb[RTA_DST]),
						abuf, sizeof(abuf)),
					r->rtm_dst_len
					);
		} else {
			printf("%s ", format_host(r->rtm_family,
						RTA_PAYLOAD(tb[RTA_DST]),
						RTA_DATA(tb[RTA_DST]),
						abuf, sizeof(abuf))
					);
		}
	} else if (r->rtm_dst_len) {
		printf("0/%d ", r->rtm_dst_len);
	} else {
		printf("default ");
	}
	if (tb[RTA_SRC]) {
		if (r->rtm_src_len != host_len) {
			printf("from %s/%u ", rt_addr_n2a(r->rtm_family,
						RTA_DATA(tb[RTA_SRC]),
						abuf, sizeof(abuf)),
					r->rtm_src_len
					);
		} else {
			printf("from %s ", format_host(r->rtm_family,
						RTA_PAYLOAD(tb[RTA_SRC]),
						RTA_DATA(tb[RTA_SRC]),
						abuf, sizeof(abuf))
					);
		}
	} else if (r->rtm_src_len) {
		printf("from 0/%u ", r->rtm_src_len);
	}
	if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
		printf("via %s ", format_host(r->rtm_family,
					RTA_PAYLOAD(tb[RTA_GATEWAY]),
					RTA_DATA(tb[RTA_GATEWAY]),
					abuf, sizeof(abuf)));
	}
	if (tb[RTA_OIF] && filter.oifmask != -1) {
		printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
	}

	if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) {
		/* Do not use format_host(). It is our local addr
		   and symbolic name will not be useful.
		 */
		printf(" src %s ", rt_addr_n2a(r->rtm_family,
					RTA_DATA(tb[RTA_PREFSRC]),
					abuf, sizeof(abuf)));
	}
	if (tb[RTA_PRIORITY]) {
		printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
	}
	if (r->rtm_family == AF_INET6) {
		struct rta_cacheinfo *ci = NULL;
		if (tb[RTA_CACHEINFO]) {
			ci = RTA_DATA(tb[RTA_CACHEINFO]);
		}
		if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
			if (r->rtm_flags & RTM_F_CLONED) {
				printf("%c    cache ", _SL_);
			}
			if (ci->rta_expires) {
				printf(" expires %dsec", ci->rta_expires / get_hz());
			}
			if (ci->rta_error != 0) {
				printf(" error %d", ci->rta_error);
			}
		} else if (ci) {
			if (ci->rta_error != 0)
				printf(" error %d", ci->rta_error);
		}
	}
	if (tb[RTA_IIF] && filter.iifmask != -1) {
		printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
	}
	bb_putchar('\n');
	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
static int iproute_modify(int cmd, unsigned flags, char **argv)
{
	static const char keywords[] ALIGN1 =
		"src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0")
		"dev\0""oif\0""to\0""metric\0";
	enum {
		ARG_src,
		ARG_via,
		ARG_mtu, PARM_lock,
		ARG_protocol,
IF_FEATURE_IP_RULE(ARG_table,)
		ARG_dev,
		ARG_oif,
		ARG_to,
		ARG_metric,
	};
	enum {
		gw_ok = 1 << 0,
		dst_ok = 1 << 1,
		proto_ok = 1 << 2,
		type_ok = 1 << 3
	};
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr		n;
		struct rtmsg		r;
		char			buf[1024];
	} req;
	char mxbuf[256];
	struct rtattr * mxrta = (void*)mxbuf;
	unsigned mxlock = 0;
	char *d = NULL;
	smalluint ok = 0;
	int arg;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
	req.n.nlmsg_type = cmd;
	req.r.rtm_family = preferred_family;
	if (RT_TABLE_MAIN) /* if it is zero, memset already did it */
		req.r.rtm_table = RT_TABLE_MAIN;
	if (RT_SCOPE_NOWHERE)
		req.r.rtm_scope = RT_SCOPE_NOWHERE;

	if (cmd != RTM_DELROUTE) {
		req.r.rtm_protocol = RTPROT_BOOT;
		req.r.rtm_scope = RT_SCOPE_UNIVERSE;
		req.r.rtm_type = RTN_UNICAST;
	}

	mxrta->rta_type = RTA_METRICS;
	mxrta->rta_len = RTA_LENGTH(0);

	while (*argv) {
		arg = index_in_substrings(keywords, *argv);
		if (arg == ARG_src) {
			inet_prefix addr;
			NEXT_ARG();
			get_addr(&addr, *argv, req.r.rtm_family);
			if (req.r.rtm_family == AF_UNSPEC)
				req.r.rtm_family = addr.family;
			addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
		} else if (arg == ARG_via) {
			inet_prefix addr;
			ok |= gw_ok;
			NEXT_ARG();
			get_addr(&addr, *argv, req.r.rtm_family);
			if (req.r.rtm_family == AF_UNSPEC) {
				req.r.rtm_family = addr.family;
			}
			addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen);
		} else if (arg == ARG_mtu) {
			unsigned mtu;
			NEXT_ARG();
			if (index_in_strings(keywords, *argv) == PARM_lock) {
				mxlock |= (1 << RTAX_MTU);
				NEXT_ARG();
			}
			mtu = get_unsigned(*argv, "mtu");
			rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu);
		} else if (arg == ARG_protocol) {
			uint32_t prot;
			NEXT_ARG();
			if (rtnl_rtprot_a2n(&prot, *argv))
				invarg(*argv, "protocol");
			req.r.rtm_protocol = prot;
			ok |= proto_ok;
#if ENABLE_FEATURE_IP_RULE
		} else if (arg == ARG_table) {
			uint32_t tid;
			NEXT_ARG();
			if (rtnl_rttable_a2n(&tid, *argv))
				invarg(*argv, "table");
			req.r.rtm_table = tid;
#endif
		} else if (arg == ARG_dev || arg == ARG_oif) {
			NEXT_ARG();
			d = *argv;
		} else if (arg == ARG_metric) {
			uint32_t metric;
			NEXT_ARG();
			metric = get_u32(*argv, "metric");
			addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric);
		} else {
			int type;
			inet_prefix dst;

			if (arg == ARG_to) {
				NEXT_ARG();
			}
			if ((**argv < '0' || **argv > '9')
			 && rtnl_rtntype_a2n(&type, *argv) == 0) {
				NEXT_ARG();
				req.r.rtm_type = type;
				ok |= type_ok;
			}

			if (ok & dst_ok) {
				duparg2("to", *argv);
			}
			get_prefix(&dst, *argv, req.r.rtm_family);
			if (req.r.rtm_family == AF_UNSPEC) {
				req.r.rtm_family = dst.family;
			}
			req.r.rtm_dst_len = dst.bitlen;
			ok |= dst_ok;
			if (dst.bytelen) {
				addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
			}
		}
		argv++;
	}

	xrtnl_open(&rth);

	if (d)  {
		int idx;

		ll_init_map(&rth);

		if (d) {
			idx = xll_name_to_index(d);
			addattr32(&req.n, sizeof(req), RTA_OIF, idx);
		}
	}

	if (mxrta->rta_len > RTA_LENGTH(0)) {
		if (mxlock) {
			rta_addattr32(mxrta, sizeof(mxbuf), RTAX_LOCK, mxlock);
		}
		addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta));
	}

	if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT)
		req.r.rtm_scope = RT_SCOPE_HOST;
	else if (req.r.rtm_type == RTN_BROADCAST ||
			req.r.rtm_type == RTN_MULTICAST ||
			req.r.rtm_type == RTN_ANYCAST)
		req.r.rtm_scope = RT_SCOPE_LINK;
	else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) {
		if (cmd == RTM_DELROUTE)
			req.r.rtm_scope = RT_SCOPE_NOWHERE;
		else if (!(ok & gw_ok))
			req.r.rtm_scope = RT_SCOPE_LINK;
	}

	if (req.r.rtm_family == AF_UNSPEC) {
		req.r.rtm_family = AF_INET;
	}

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
		return 2;
	}

	return 0;
}

static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
{
	struct {
		struct nlmsghdr nlh;
		struct rtmsg rtm;
	} req;
	struct sockaddr_nl nladdr;

	memset(&nladdr, 0, sizeof(nladdr));
	memset(&req, 0, sizeof(req));
	nladdr.nl_family = AF_NETLINK;

	req.nlh.nlmsg_len = sizeof(req);
	if (RTM_GETROUTE)
		req.nlh.nlmsg_type = RTM_GETROUTE;
	if (NLM_F_ROOT | NLM_F_REQUEST)
		req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
	/*req.nlh.nlmsg_pid = 0; - memset did it already */
	req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
	req.rtm.rtm_family = family;
	if (RTM_F_CLONED)
		req.rtm.rtm_flags = RTM_F_CLONED;

	return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
}

static void iproute_flush_cache(void)
{
	static const char fn[] ALIGN1 = "/proc/sys/net/ipv4/route/flush";
	int flush_fd = open_or_warn(fn, O_WRONLY);

	if (flush_fd < 0) {
		return;
	}

	if (write(flush_fd, "-1", 2) < 2) {
		bb_perror_msg("can't flush routing cache");
		return;
	}
	close(flush_fd);
}

static void iproute_reset_filter(void)
{
	memset(&filter, 0, sizeof(filter));
	filter.mdst.bitlen = -1;
	filter.msrc.bitlen = -1;
}

/* Return value becomes exitcode. It's okay to not return at all */
static int iproute_list_or_flush(char **argv, int flush)
{
	int do_ipv6 = preferred_family;
	struct rtnl_handle rth;
	char *id = NULL;
	char *od = NULL;
	static const char keywords[] ALIGN1 =
		/* "ip route list/flush" parameters: */
		"protocol\0" "dev\0"   "oif\0"   "iif\0"
		"via\0"      "table\0" "cache\0"
		"from\0"     "to\0"
		/* and possible further keywords */
		"all\0"
		"root\0"
		"match\0"
		"exact\0"
		"main\0"
		;
	enum {
		KW_proto, KW_dev,   KW_oif,  KW_iif,
		KW_via,   KW_table, KW_cache,
		KW_from,  KW_to,
		/* */
		KW_all,
		KW_root,
		KW_match,
		KW_exact,
		KW_main,
	};
	int arg, parm;

	iproute_reset_filter();
	filter.tb = RT_TABLE_MAIN;

	if (flush && !*argv)
		bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");

	while (*argv) {
		arg = index_in_substrings(keywords, *argv);
		if (arg == KW_proto) {
			uint32_t prot = 0;
			NEXT_ARG();
			filter.protocolmask = -1;
			if (rtnl_rtprot_a2n(&prot, *argv)) {
				if (index_in_strings(keywords, *argv) != KW_all)
					invarg(*argv, "protocol");
				prot = 0;
				filter.protocolmask = 0;
			}
			filter.protocol = prot;
		} else if (arg == KW_dev || arg == KW_oif) {
			NEXT_ARG();
			od = *argv;
		} else if (arg == KW_iif) {
			NEXT_ARG();
			id = *argv;
		} else if (arg == KW_via) {
			NEXT_ARG();
			get_prefix(&filter.rvia, *argv, do_ipv6);
		} else if (arg == KW_table) { /* table all/cache/main */
			NEXT_ARG();
			parm = index_in_substrings(keywords, *argv);
			if (parm == KW_cache)
				filter.tb = -1;
			else if (parm == KW_all)
				filter.tb = 0;
			else if (parm != KW_main) {
#if ENABLE_FEATURE_IP_RULE
				uint32_t tid;
				if (rtnl_rttable_a2n(&tid, *argv))
					invarg(*argv, "table");
				filter.tb = tid;
#else
				invarg(*argv, "table");
#endif
			}
		} else if (arg == KW_cache) {
			/* The command 'ip route flush cache' is used by OpenSWAN.
			 * Assuming it's a synonym for 'ip route flush table cache' */
			filter.tb = -1;
		} else if (arg == KW_from) {
			NEXT_ARG();
			parm = index_in_substrings(keywords, *argv);
			if (parm == KW_root) {
				NEXT_ARG();
				get_prefix(&filter.rsrc, *argv, do_ipv6);
			} else if (parm == KW_match) {
				NEXT_ARG();
				get_prefix(&filter.msrc, *argv, do_ipv6);
			} else {
				if (parm == KW_exact)
					NEXT_ARG();
				get_prefix(&filter.msrc, *argv, do_ipv6);
				filter.rsrc = filter.msrc;
			}
		} else { /* "to" is the default parameter */
			if (arg == KW_to) {
				NEXT_ARG();
				arg = index_in_substrings(keywords, *argv);
			}
			/* parm = arg; - would be more plausible, but we reuse 'arg' here */
			if (arg == KW_root) {
				NEXT_ARG();
				get_prefix(&filter.rdst, *argv, do_ipv6);
			} else if (arg == KW_match) {
				NEXT_ARG();
				get_prefix(&filter.mdst, *argv, do_ipv6);
			} else { /* "to exact" is the default */
				if (arg == KW_exact)
					NEXT_ARG();
				get_prefix(&filter.mdst, *argv, do_ipv6);
				filter.rdst = filter.mdst;
			}
		}
		argv++;
	}

	if (do_ipv6 == AF_UNSPEC && filter.tb) {
		do_ipv6 = AF_INET;
	}

	xrtnl_open(&rth);
	ll_init_map(&rth);

	if (id || od)  {
		int idx;

		if (id) {
			idx = xll_name_to_index(id);
			filter.iif = idx;
			filter.iifmask = -1;
		}
		if (od) {
			idx = xll_name_to_index(od);
			filter.oif = idx;
			filter.oifmask = -1;
		}
	}

	if (flush) {
		char flushb[4096-512];

		if (filter.tb == -1) { /* "flush table cache" */
			if (do_ipv6 != AF_INET6)
				iproute_flush_cache();
			if (do_ipv6 == AF_INET)
				return 0;
		}

		filter.flushb = flushb;
		filter.flushp = 0;
		filter.flushe = sizeof(flushb);
		filter.rth = &rth;

		for (;;) {
			xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
			filter.flushed = 0;
			xrtnl_dump_filter(&rth, print_route, NULL);
			if (filter.flushed == 0)
				return 0;
			if (flush_update())
				return 1;
		}
	}

	if (filter.tb != -1) {
		xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
	} else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
		bb_perror_msg_and_die("can't send dump request");
	}
	xrtnl_dump_filter(&rth, print_route, NULL);

	return 0;
}


/* Return value becomes exitcode. It's okay to not return at all */
static int iproute_get(char **argv)
{
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr n;
		struct rtmsg    r;
		char            buf[1024];
	} req;
	char *idev = NULL;
	char *odev = NULL;
	bool connected = 0;
	bool from_ok = 0;
	static const char options[] ALIGN1 =
		"from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0";

	memset(&req, 0, sizeof(req));

	iproute_reset_filter();

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	if (NLM_F_REQUEST)
		req.n.nlmsg_flags = NLM_F_REQUEST;
	if (RTM_GETROUTE)
		req.n.nlmsg_type = RTM_GETROUTE;
	req.r.rtm_family = preferred_family;
	/*req.r.rtm_table = 0; - memset did this already */
	/*req.r.rtm_protocol = 0;*/
	/*req.r.rtm_scope = 0;*/
	/*req.r.rtm_type = 0;*/
	/*req.r.rtm_src_len = 0;*/
	/*req.r.rtm_dst_len = 0;*/
	/*req.r.rtm_tos = 0;*/

	while (*argv) {
		switch (index_in_strings(options, *argv)) {
			case 0: /* from */
			{
				inet_prefix addr;
				NEXT_ARG();
				from_ok = 1;
				get_prefix(&addr, *argv, req.r.rtm_family);
				if (req.r.rtm_family == AF_UNSPEC) {
					req.r.rtm_family = addr.family;
				}
				if (addr.bytelen) {
					addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen);
				}
				req.r.rtm_src_len = addr.bitlen;
				break;
			}
			case 1: /* iif */
				NEXT_ARG();
				idev = *argv;
				break;
			case 2: /* oif */
			case 3: /* dev */
				NEXT_ARG();
				odev = *argv;
				break;
			case 4: /* notify */
				req.r.rtm_flags |= RTM_F_NOTIFY;
				break;
			case 5: /* connected */
				connected = 1;
				break;
			case 6: /* to */
				NEXT_ARG();
			default:
			{
				inet_prefix addr;
				get_prefix(&addr, *argv, req.r.rtm_family);
				if (req.r.rtm_family == AF_UNSPEC) {
					req.r.rtm_family = addr.family;
				}
				if (addr.bytelen) {
					addattr_l(&req.n, sizeof(req), RTA_DST, &addr.data, addr.bytelen);
				}
				req.r.rtm_dst_len = addr.bitlen;
			}
			argv++;
		}
	}

	if (req.r.rtm_dst_len == 0) {
		bb_error_msg_and_die("need at least destination address");
	}

	xrtnl_open(&rth);

	ll_init_map(&rth);

	if (idev || odev)  {
		int idx;

		if (idev) {
			idx = xll_name_to_index(idev);
			addattr32(&req.n, sizeof(req), RTA_IIF, idx);
		}
		if (odev) {
			idx = xll_name_to_index(odev);
			addattr32(&req.n, sizeof(req), RTA_OIF, idx);
		}
	}

	if (req.r.rtm_family == AF_UNSPEC) {
		req.r.rtm_family = AF_INET;
	}

	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
		return 2;
	}

	if (connected && !from_ok) {
		struct rtmsg *r = NLMSG_DATA(&req.n);
		int len = req.n.nlmsg_len;
		struct rtattr * tb[RTA_MAX+1];

		print_route(NULL, &req.n, NULL);

		if (req.n.nlmsg_type != RTM_NEWROUTE) {
			bb_error_msg_and_die("not a route?");
		}
		len -= NLMSG_LENGTH(sizeof(*r));
		if (len < 0) {
			bb_error_msg_and_die("wrong len %d", len);
		}

		memset(tb, 0, sizeof(tb));
		parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);

		if (tb[RTA_PREFSRC]) {
			tb[RTA_PREFSRC]->rta_type = RTA_SRC;
			r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
		} else if (!tb[RTA_SRC]) {
			bb_error_msg_and_die("failed to connect the route");
		}
		if (!odev && tb[RTA_OIF]) {
			tb[RTA_OIF]->rta_type = 0;
		}
		if (tb[RTA_GATEWAY]) {
			tb[RTA_GATEWAY]->rta_type = 0;
		}
		if (!idev && tb[RTA_IIF]) {
			tb[RTA_IIF]->rta_type = 0;
		}
		req.n.nlmsg_flags = NLM_F_REQUEST;
		req.n.nlmsg_type = RTM_GETROUTE;

		if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
			return 2;
		}
	}
	print_route(NULL, &req.n, NULL);
	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
int do_iproute(char **argv)
{
	static const char ip_route_commands[] ALIGN1 =
	/*0-3*/	"add\0""append\0""change\0""chg\0"
	/*4-7*/	"delete\0""get\0""list\0""show\0"
	/*8..*/	"prepend\0""replace\0""test\0""flush\0";
	int command_num;
	unsigned flags = 0;
	int cmd = RTM_NEWROUTE;

	if (!*argv)
		return iproute_list_or_flush(argv, 0);

	/* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
	/* It probably means that it is using "first match" rule */
	command_num = index_in_substrings(ip_route_commands, *argv);

	switch (command_num) {
		case 0: /* add */
			flags = NLM_F_CREATE|NLM_F_EXCL;
			break;
		case 1: /* append */
			flags = NLM_F_CREATE|NLM_F_APPEND;
			break;
		case 2: /* change */
		case 3: /* chg */
			flags = NLM_F_REPLACE;
			break;
		case 4: /* delete */
			cmd = RTM_DELROUTE;
			break;
		case 5: /* get */
			return iproute_get(argv+1);
		case 6: /* list */
		case 7: /* show */
			return iproute_list_or_flush(argv+1, 0);
		case 8: /* prepend */
			flags = NLM_F_CREATE;
			break;
		case 9: /* replace */
			flags = NLM_F_CREATE|NLM_F_REPLACE;
			break;
		case 10: /* test */
			flags = NLM_F_EXCL;
			break;
		case 11: /* flush */
			return iproute_list_or_flush(argv+1, 1);
		default:
			bb_error_msg_and_die("unknown command %s", *argv);
	}

	return iproute_modify(cmd, flags, argv+1);
}
