utils.c revision 535e83162249ed6274ba46bc72d8cc683ba20e17
1535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf/*
2535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf * src/route-utils.c     Route Helpers
3535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *
4535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *	This library is free software; you can redistribute it and/or
5535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *	modify it under the terms of the GNU Lesser General Public
6535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *	License as published by the Free Software Foundation version 2.1
7535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *	of the License.
8535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf *
9535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf * Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
10535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf */
11535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
12535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf#include "route-utils.h"
13535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
14535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_family(struct rtnl_route *route, char *arg)
15535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
16535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int family;
17535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
18535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((family = nl_str2af(arg)) != AF_UNSPEC)
19535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		rtnl_route_set_family(route, family);
20535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
21535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
22535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_dst(struct rtnl_route *route, char *arg)
23535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
24535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	struct nl_addr *addr;
25535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int err;
26535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
27535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	addr = nl_addr_parse(arg, rtnl_route_get_family(route));
28535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (addr == NULL)
29535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(nl_get_errno(), nl_geterror());
30535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
31535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((err = rtnl_route_set_dst(route, addr)) < 0)
32535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(err, nl_geterror());
33535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
34535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	nl_addr_put(addr);
35535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
36535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
37535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_src(struct rtnl_route *route, char *arg)
38535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
39535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	struct nl_addr *addr;
40535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int err;
41535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
42535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	addr = nl_addr_parse(arg, rtnl_route_get_family(route));
43535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (addr == NULL)
44535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(nl_get_errno(), nl_geterror());
45535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
46535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((err = rtnl_route_set_src(route, addr)) < 0)
47535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(err, nl_geterror());
48535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
49535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	nl_addr_put(addr);
50535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
51535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
52535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_pref_src(struct rtnl_route *route, char *arg)
53535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
54535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	struct nl_addr *addr;
55535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int err;
56535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
57535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	addr = nl_addr_parse(arg, rtnl_route_get_family(route));
58535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (addr == NULL)
59535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(nl_get_errno(), nl_geterror());
60535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
61535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((err = rtnl_route_set_pref_src(route, addr)) < 0)
62535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(err, nl_geterror());
63535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
64535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	nl_addr_put(addr);
65535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
66535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
67535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_metric(struct rtnl_route *route, char *subopts)
68535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
69535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	/* strict equal order to RTAX_* */
70535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	static char *const tokens[] = {
71535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"unspec",
72535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"lock",
73535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"mtu",
74535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"window",
75535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"rtt",
76535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"rttvar",
77535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"sstresh",
78535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"cwnd",
79535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"advmss",
80535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"reordering",
81535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"hoplimit",
82535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"initcwnd",
83535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"features",
84535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		NULL,
85535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	};
86535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	unsigned long lval;
87535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	char *arg, *endptr;
88535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
89535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	while (*subopts != '\0') {
90535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		int ret = getsubopt(&subopts, tokens, &arg);
91535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if (ret == -1)
92535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Unknown metric token \"%s\"", arg);
93535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
94535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if (ret == 0)
95535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Invalid metric \"%s\"", tokens[ret]);
96535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
97535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if (arg == NULL)
98535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Metric \"%s\", no value given", tokens[ret]);
99535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
100535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		lval = strtoul(arg, &endptr, 0);
101535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if (endptr == arg)
102535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]);
103535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
104535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0)
105535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(ret, nl_geterror());
106535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	}
107535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
108535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
109535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_nexthop(struct rtnl_route *route, char *subopts,
110535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		   struct nl_cache *link_cache)
111535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
112535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	enum {
113535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		NH_DEV,
114535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		NH_VIA,
115535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		NH_WEIGHT,
116535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	};
117535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	static char *const tokens[] = {
118535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"dev",
119535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"via",
120535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		"weight",
121535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		NULL,
122535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	};
123535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	struct rtnl_nexthop *nh;
124535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	unsigned long lval;
125535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	struct nl_addr *addr;
126535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int ival;
127535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	char *arg, *endptr;
128535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
129535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (!(nh = rtnl_route_nh_alloc()))
130535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(ENOMEM, "Out of memory");
131535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
132535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	while (*subopts != '\0') {
133535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		int ret = getsubopt(&subopts, tokens, &arg);
134535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if (ret == -1)
135535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Unknown nexthop token \"%s\"", arg);
136535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
137535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		switch (ret) {
138535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		case NH_DEV:
139535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			ival = rtnl_link_name2i(link_cache, arg);
140535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			if (ival == RTNL_LINK_NOT_FOUND)
141535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf				fatal(ENOENT, "Link \"%s\" does not exist", arg);
142535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
143535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			rtnl_route_nh_set_ifindex(nh, ival);
144535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			break;
145535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
146535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		case NH_VIA:
147535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			addr = nl_addr_parse(arg, rtnl_route_get_family(route));
148535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			if (addr == NULL)
149535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf				fatal(nl_get_errno(), nl_geterror());
150535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
151535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			rtnl_route_nh_set_gateway(nh, addr);
152535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			nl_addr_put(addr);
153535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			break;
154535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
155535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		case NH_WEIGHT:
156535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			lval = strtoul(arg, &endptr, 0);
157535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			if (endptr == arg)
158535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf				fatal(EINVAL, "Invalid weight \"%s\", not numeric", arg);
159535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			rtnl_route_nh_set_weight(nh, lval);
160535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			break;
161535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		}
162535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	}
163535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
164535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_add_nexthop(route, nh);
165535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
166535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
167535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_table(struct rtnl_route *route, char *arg)
168535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
169535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	unsigned long lval;
170535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	char *endptr;
171535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
172535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	lval = strtoul(arg, &endptr, 0);
173535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (endptr == arg) {
174535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if ((lval = rtnl_route_str2table(arg)) < 0)
175535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Unknown table name \"%s\"", arg);
176535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	}
177535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
178535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_set_table(route, lval);
179535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
180535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
181535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_prio(struct rtnl_route *route, char *arg)
182535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
183535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	unsigned long lval;
184535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	char *endptr;
185535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
186535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	lval = strtoul(arg, &endptr, 0);
187535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (endptr == arg)
188535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(EINVAL, "Invalid priority value, not numeric");
189535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_set_priority(route, lval);
190535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
191535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
192535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_scope(struct rtnl_route *route, char *arg)
193535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
194535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int ival;
195535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
196535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((ival = rtnl_str2scope(arg)) < 0)
197535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(EINVAL, "Unknown routing scope \"%s\"", arg);
198535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
199535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_set_scope(route, ival);
200535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
201535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
202535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_protocol(struct rtnl_route *route, char *arg)
203535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
204535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	unsigned long lval;
205535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	char *endptr;
206535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
207535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	lval = strtoul(arg, &endptr, 0);
208535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (endptr == arg) {
209535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		if ((lval = rtnl_route_str2proto(arg)) < 0)
210535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf			fatal(EINVAL, "Unknown routing protocol name \"%s\"",
211535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf				arg);
212535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	}
213535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
214535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_set_protocol(route, lval);
215535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
216535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
217535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_type(struct rtnl_route *route, char *arg)
218535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
219535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int ival;
220535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
221535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((ival = nl_str2rtntype(arg)) < 0)
222535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(EINVAL, "Unknown routing type \"%s\"", arg);
223535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
224535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if ((ival = rtnl_route_set_type(route, ival)) < 0)
225535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(ival, nl_geterror());
226535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
227535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
228535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Grafvoid parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache)
229535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf{
230535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	int ival;
231535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
232535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	ival = rtnl_link_name2i(link_cache, arg);
233535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	if (ival == RTNL_LINK_NOT_FOUND)
234535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf		fatal(ENOENT, "Link \"%s\" does not exist", arg);
235535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf
236535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf	rtnl_route_set_iif(route, ival);
237535e83162249ed6274ba46bc72d8cc683ba20e17Thomas Graf}
238