xref: /aosp_15_r20/external/libnl/src/lib/route.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2008-2009 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup cli
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup cli_route Routing
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * @{
11*4dc78e53SAndroid Build Coastguard Worker  */
12*4dc78e53SAndroid Build Coastguard Worker 
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cli/utils.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/cli/route.h>
17*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_alloc(void)18*4dc78e53SAndroid Build Coastguard Worker struct rtnl_route *nl_cli_route_alloc(void)
19*4dc78e53SAndroid Build Coastguard Worker {
20*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_route *route;
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker 	route = rtnl_route_alloc();
23*4dc78e53SAndroid Build Coastguard Worker 	if (!route)
24*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(ENOMEM, "Unable to allocate route object");
25*4dc78e53SAndroid Build Coastguard Worker 
26*4dc78e53SAndroid Build Coastguard Worker 	return route;
27*4dc78e53SAndroid Build Coastguard Worker }
28*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_alloc_cache(struct nl_sock * sk,int flags)29*4dc78e53SAndroid Build Coastguard Worker struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *sk, int flags)
30*4dc78e53SAndroid Build Coastguard Worker {
31*4dc78e53SAndroid Build Coastguard Worker 	struct nl_cache *cache;
32*4dc78e53SAndroid Build Coastguard Worker 	int err;
33*4dc78e53SAndroid Build Coastguard Worker 
34*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0)
35*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(err, "Unable to allocate route cache: %s\n",
36*4dc78e53SAndroid Build Coastguard Worker 			     nl_geterror(err));
37*4dc78e53SAndroid Build Coastguard Worker 
38*4dc78e53SAndroid Build Coastguard Worker 	nl_cache_mngt_provide(cache);
39*4dc78e53SAndroid Build Coastguard Worker 
40*4dc78e53SAndroid Build Coastguard Worker 	return cache;
41*4dc78e53SAndroid Build Coastguard Worker }
42*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_family(struct rtnl_route * route,char * arg)43*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_family(struct rtnl_route *route, char *arg)
44*4dc78e53SAndroid Build Coastguard Worker {
45*4dc78e53SAndroid Build Coastguard Worker 	int family;
46*4dc78e53SAndroid Build Coastguard Worker 
47*4dc78e53SAndroid Build Coastguard Worker 	if ((family = nl_str2af(arg)) != AF_UNSPEC)
48*4dc78e53SAndroid Build Coastguard Worker 		rtnl_route_set_family(route, family);
49*4dc78e53SAndroid Build Coastguard Worker }
50*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_dst(struct rtnl_route * route,char * arg)51*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_dst(struct rtnl_route *route, char *arg)
52*4dc78e53SAndroid Build Coastguard Worker {
53*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *addr;
54*4dc78e53SAndroid Build Coastguard Worker 	int err;
55*4dc78e53SAndroid Build Coastguard Worker 
56*4dc78e53SAndroid Build Coastguard Worker 	addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
57*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_route_set_dst(route, addr)) < 0)
58*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(err, "Unable to set destination address: %s",
59*4dc78e53SAndroid Build Coastguard Worker 		      nl_geterror(err));
60*4dc78e53SAndroid Build Coastguard Worker 
61*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_put(addr);
62*4dc78e53SAndroid Build Coastguard Worker }
63*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_src(struct rtnl_route * route,char * arg)64*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_src(struct rtnl_route *route, char *arg)
65*4dc78e53SAndroid Build Coastguard Worker {
66*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *addr;
67*4dc78e53SAndroid Build Coastguard Worker 	int err;
68*4dc78e53SAndroid Build Coastguard Worker 
69*4dc78e53SAndroid Build Coastguard Worker 	addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
70*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_route_set_src(route, addr)) < 0)
71*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(err, "Unable to set source address: %s",
72*4dc78e53SAndroid Build Coastguard Worker 		      nl_geterror(err));
73*4dc78e53SAndroid Build Coastguard Worker 
74*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_put(addr);
75*4dc78e53SAndroid Build Coastguard Worker }
76*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_pref_src(struct rtnl_route * route,char * arg)77*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_pref_src(struct rtnl_route *route, char *arg)
78*4dc78e53SAndroid Build Coastguard Worker {
79*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *addr;
80*4dc78e53SAndroid Build Coastguard Worker 	int err;
81*4dc78e53SAndroid Build Coastguard Worker 
82*4dc78e53SAndroid Build Coastguard Worker 	addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
83*4dc78e53SAndroid Build Coastguard Worker 	if ((err = rtnl_route_set_pref_src(route, addr)) < 0)
84*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(err, "Unable to set preferred source address: %s",
85*4dc78e53SAndroid Build Coastguard Worker 		      nl_geterror(err));
86*4dc78e53SAndroid Build Coastguard Worker 
87*4dc78e53SAndroid Build Coastguard Worker 	nl_addr_put(addr);
88*4dc78e53SAndroid Build Coastguard Worker }
89*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_metric(struct rtnl_route * route,char * subopts)90*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_metric(struct rtnl_route *route, char *subopts)
91*4dc78e53SAndroid Build Coastguard Worker {
92*4dc78e53SAndroid Build Coastguard Worker 	/* strict equal order to RTAX_* */
93*4dc78e53SAndroid Build Coastguard Worker 	static char *const tokens[] = {
94*4dc78e53SAndroid Build Coastguard Worker 		"unspec",
95*4dc78e53SAndroid Build Coastguard Worker 		"lock",
96*4dc78e53SAndroid Build Coastguard Worker 		"mtu",
97*4dc78e53SAndroid Build Coastguard Worker 		"window",
98*4dc78e53SAndroid Build Coastguard Worker 		"rtt",
99*4dc78e53SAndroid Build Coastguard Worker 		"rttvar",
100*4dc78e53SAndroid Build Coastguard Worker 		"sstresh",
101*4dc78e53SAndroid Build Coastguard Worker 		"cwnd",
102*4dc78e53SAndroid Build Coastguard Worker 		"advmss",
103*4dc78e53SAndroid Build Coastguard Worker 		"reordering",
104*4dc78e53SAndroid Build Coastguard Worker 		"hoplimit",
105*4dc78e53SAndroid Build Coastguard Worker 		"initcwnd",
106*4dc78e53SAndroid Build Coastguard Worker 		"features",
107*4dc78e53SAndroid Build Coastguard Worker 		NULL,
108*4dc78e53SAndroid Build Coastguard Worker 	};
109*4dc78e53SAndroid Build Coastguard Worker 	unsigned long lval;
110*4dc78e53SAndroid Build Coastguard Worker 	char *arg, *endptr;
111*4dc78e53SAndroid Build Coastguard Worker 
112*4dc78e53SAndroid Build Coastguard Worker 	while (*subopts != '\0') {
113*4dc78e53SAndroid Build Coastguard Worker 		int ret = getsubopt(&subopts, tokens, &arg);
114*4dc78e53SAndroid Build Coastguard Worker 		if (ret == -1)
115*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Unknown metric token \"%s\"", arg);
116*4dc78e53SAndroid Build Coastguard Worker 
117*4dc78e53SAndroid Build Coastguard Worker 		if (ret == 0)
118*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Invalid metric \"%s\"", tokens[ret]);
119*4dc78e53SAndroid Build Coastguard Worker 
120*4dc78e53SAndroid Build Coastguard Worker 		if (arg == NULL)
121*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Metric \"%s\", no value given", tokens[ret]);
122*4dc78e53SAndroid Build Coastguard Worker 
123*4dc78e53SAndroid Build Coastguard Worker 		lval = strtoul(arg, &endptr, 0);
124*4dc78e53SAndroid Build Coastguard Worker 		if (endptr == arg)
125*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]);
126*4dc78e53SAndroid Build Coastguard Worker 
127*4dc78e53SAndroid Build Coastguard Worker 		if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0)
128*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(ret, "Unable to set metric: %s",
129*4dc78e53SAndroid Build Coastguard Worker 			      nl_geterror(ret));
130*4dc78e53SAndroid Build Coastguard Worker 	}
131*4dc78e53SAndroid Build Coastguard Worker }
132*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_nexthop(struct rtnl_route * route,char * subopts,struct nl_cache * link_cache)133*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_nexthop(struct rtnl_route *route, char *subopts,
134*4dc78e53SAndroid Build Coastguard Worker 		   struct nl_cache *link_cache)
135*4dc78e53SAndroid Build Coastguard Worker {
136*4dc78e53SAndroid Build Coastguard Worker 	enum {
137*4dc78e53SAndroid Build Coastguard Worker 		NH_DEV,
138*4dc78e53SAndroid Build Coastguard Worker 		NH_VIA,
139*4dc78e53SAndroid Build Coastguard Worker 		NH_WEIGHT,
140*4dc78e53SAndroid Build Coastguard Worker 		NH_AS,
141*4dc78e53SAndroid Build Coastguard Worker 	};
142*4dc78e53SAndroid Build Coastguard Worker 	static char *const tokens[] = {
143*4dc78e53SAndroid Build Coastguard Worker 		"dev",
144*4dc78e53SAndroid Build Coastguard Worker 		"via",
145*4dc78e53SAndroid Build Coastguard Worker 		"weight",
146*4dc78e53SAndroid Build Coastguard Worker 		"as",
147*4dc78e53SAndroid Build Coastguard Worker 		NULL,
148*4dc78e53SAndroid Build Coastguard Worker 	};
149*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_nexthop *nh;
150*4dc78e53SAndroid Build Coastguard Worker 	unsigned long lval;
151*4dc78e53SAndroid Build Coastguard Worker 	struct nl_addr *addr;
152*4dc78e53SAndroid Build Coastguard Worker 	int ival;
153*4dc78e53SAndroid Build Coastguard Worker 	char *arg, *endptr;
154*4dc78e53SAndroid Build Coastguard Worker 
155*4dc78e53SAndroid Build Coastguard Worker 	if (!(nh = rtnl_route_nh_alloc()))
156*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(ENOMEM, "Out of memory");
157*4dc78e53SAndroid Build Coastguard Worker 
158*4dc78e53SAndroid Build Coastguard Worker 	while (*subopts != '\0') {
159*4dc78e53SAndroid Build Coastguard Worker 		int ret = getsubopt(&subopts, tokens, &arg);
160*4dc78e53SAndroid Build Coastguard Worker 		if (ret == -1)
161*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Unknown nexthop token \"%s\"", arg);
162*4dc78e53SAndroid Build Coastguard Worker 
163*4dc78e53SAndroid Build Coastguard Worker 		if (arg == NULL)
164*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Missing argument to option \"%s\"\n",
165*4dc78e53SAndroid Build Coastguard Worker 				tokens[ret]);
166*4dc78e53SAndroid Build Coastguard Worker 
167*4dc78e53SAndroid Build Coastguard Worker 		switch (ret) {
168*4dc78e53SAndroid Build Coastguard Worker 		case NH_DEV:
169*4dc78e53SAndroid Build Coastguard Worker 			if (!(ival = rtnl_link_name2i(link_cache, arg)))
170*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(ENOENT,"Link \"%s\" does not exist", arg);
171*4dc78e53SAndroid Build Coastguard Worker 
172*4dc78e53SAndroid Build Coastguard Worker 			rtnl_route_nh_set_ifindex(nh, ival);
173*4dc78e53SAndroid Build Coastguard Worker 			break;
174*4dc78e53SAndroid Build Coastguard Worker 
175*4dc78e53SAndroid Build Coastguard Worker 		case NH_VIA:
176*4dc78e53SAndroid Build Coastguard Worker 			if (rtnl_route_get_family(route) == AF_MPLS) {
177*4dc78e53SAndroid Build Coastguard Worker 				addr = nl_cli_addr_parse(arg, 0);
178*4dc78e53SAndroid Build Coastguard Worker 				rtnl_route_nh_set_via(nh, addr);
179*4dc78e53SAndroid Build Coastguard Worker 			} else {
180*4dc78e53SAndroid Build Coastguard Worker 				addr = nl_cli_addr_parse(arg,rtnl_route_get_family(route));
181*4dc78e53SAndroid Build Coastguard Worker 				rtnl_route_nh_set_gateway(nh, addr);
182*4dc78e53SAndroid Build Coastguard Worker 			}
183*4dc78e53SAndroid Build Coastguard Worker 			nl_addr_put(addr);
184*4dc78e53SAndroid Build Coastguard Worker 			break;
185*4dc78e53SAndroid Build Coastguard Worker 
186*4dc78e53SAndroid Build Coastguard Worker 		case NH_AS:
187*4dc78e53SAndroid Build Coastguard Worker 			addr = nl_cli_addr_parse(arg,
188*4dc78e53SAndroid Build Coastguard Worker 						 rtnl_route_get_family(route));
189*4dc78e53SAndroid Build Coastguard Worker 			rtnl_route_nh_set_newdst(nh, addr);
190*4dc78e53SAndroid Build Coastguard Worker 			nl_addr_put(addr);
191*4dc78e53SAndroid Build Coastguard Worker 			break;
192*4dc78e53SAndroid Build Coastguard Worker 
193*4dc78e53SAndroid Build Coastguard Worker 		case NH_WEIGHT:
194*4dc78e53SAndroid Build Coastguard Worker 			lval = strtoul(arg, &endptr, 0);
195*4dc78e53SAndroid Build Coastguard Worker 			if (endptr == arg)
196*4dc78e53SAndroid Build Coastguard Worker 				nl_cli_fatal(EINVAL,
197*4dc78e53SAndroid Build Coastguard Worker 					     "Invalid weight \"%s\", not numeric",
198*4dc78e53SAndroid Build Coastguard Worker 					     arg);
199*4dc78e53SAndroid Build Coastguard Worker 			rtnl_route_nh_set_weight(nh, lval);
200*4dc78e53SAndroid Build Coastguard Worker 			break;
201*4dc78e53SAndroid Build Coastguard Worker 		}
202*4dc78e53SAndroid Build Coastguard Worker 	}
203*4dc78e53SAndroid Build Coastguard Worker 
204*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_add_nexthop(route, nh);
205*4dc78e53SAndroid Build Coastguard Worker }
206*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_table(struct rtnl_route * route,char * arg)207*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_table(struct rtnl_route *route, char *arg)
208*4dc78e53SAndroid Build Coastguard Worker {
209*4dc78e53SAndroid Build Coastguard Worker 	unsigned long lval;
210*4dc78e53SAndroid Build Coastguard Worker 	char *endptr;
211*4dc78e53SAndroid Build Coastguard Worker 	int table;
212*4dc78e53SAndroid Build Coastguard Worker 
213*4dc78e53SAndroid Build Coastguard Worker 	lval = strtoul(arg, &endptr, 0);
214*4dc78e53SAndroid Build Coastguard Worker 	if (endptr == arg) {
215*4dc78e53SAndroid Build Coastguard Worker 		if ((table = rtnl_route_str2table(arg)) < 0)
216*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL, "Unknown table name \"%s\"", arg);
217*4dc78e53SAndroid Build Coastguard Worker 	}
218*4dc78e53SAndroid Build Coastguard Worker 	else {
219*4dc78e53SAndroid Build Coastguard Worker 		table = lval;
220*4dc78e53SAndroid Build Coastguard Worker 	}
221*4dc78e53SAndroid Build Coastguard Worker 
222*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_set_table(route, table);
223*4dc78e53SAndroid Build Coastguard Worker }
224*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_prio(struct rtnl_route * route,char * arg)225*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_prio(struct rtnl_route *route, char *arg)
226*4dc78e53SAndroid Build Coastguard Worker {
227*4dc78e53SAndroid Build Coastguard Worker 	unsigned long lval;
228*4dc78e53SAndroid Build Coastguard Worker 	char *endptr;
229*4dc78e53SAndroid Build Coastguard Worker 
230*4dc78e53SAndroid Build Coastguard Worker 	lval = strtoul(arg, &endptr, 0);
231*4dc78e53SAndroid Build Coastguard Worker 	if (endptr == arg)
232*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(EINVAL, "Invalid priority value, not numeric");
233*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_set_priority(route, lval);
234*4dc78e53SAndroid Build Coastguard Worker }
235*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_scope(struct rtnl_route * route,char * arg)236*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_scope(struct rtnl_route *route, char *arg)
237*4dc78e53SAndroid Build Coastguard Worker {
238*4dc78e53SAndroid Build Coastguard Worker 	int ival;
239*4dc78e53SAndroid Build Coastguard Worker 
240*4dc78e53SAndroid Build Coastguard Worker 	if ((ival = rtnl_str2scope(arg)) < 0)
241*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(EINVAL, "Unknown routing scope \"%s\"", arg);
242*4dc78e53SAndroid Build Coastguard Worker 
243*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_set_scope(route, ival);
244*4dc78e53SAndroid Build Coastguard Worker }
245*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_protocol(struct rtnl_route * route,char * arg)246*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_protocol(struct rtnl_route *route, char *arg)
247*4dc78e53SAndroid Build Coastguard Worker {
248*4dc78e53SAndroid Build Coastguard Worker 	unsigned long lval;
249*4dc78e53SAndroid Build Coastguard Worker 	char *endptr;
250*4dc78e53SAndroid Build Coastguard Worker 	int proto;
251*4dc78e53SAndroid Build Coastguard Worker 
252*4dc78e53SAndroid Build Coastguard Worker 	lval = strtoul(arg, &endptr, 0);
253*4dc78e53SAndroid Build Coastguard Worker 	if (endptr == arg) {
254*4dc78e53SAndroid Build Coastguard Worker 		if ((proto = rtnl_route_str2proto(arg)) < 0)
255*4dc78e53SAndroid Build Coastguard Worker 			nl_cli_fatal(EINVAL,
256*4dc78e53SAndroid Build Coastguard Worker 				     "Unknown routing protocol name \"%s\"",
257*4dc78e53SAndroid Build Coastguard Worker 				     arg);
258*4dc78e53SAndroid Build Coastguard Worker 	}
259*4dc78e53SAndroid Build Coastguard Worker 	else {
260*4dc78e53SAndroid Build Coastguard Worker 		proto = lval;
261*4dc78e53SAndroid Build Coastguard Worker 	}
262*4dc78e53SAndroid Build Coastguard Worker 
263*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_set_protocol(route, proto);
264*4dc78e53SAndroid Build Coastguard Worker }
265*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_type(struct rtnl_route * route,char * arg)266*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_type(struct rtnl_route *route, char *arg)
267*4dc78e53SAndroid Build Coastguard Worker {
268*4dc78e53SAndroid Build Coastguard Worker 	int ival;
269*4dc78e53SAndroid Build Coastguard Worker 
270*4dc78e53SAndroid Build Coastguard Worker 	if ((ival = nl_str2rtntype(arg)) < 0)
271*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(EINVAL, "Unknown routing type \"%s\"", arg);
272*4dc78e53SAndroid Build Coastguard Worker 
273*4dc78e53SAndroid Build Coastguard Worker 	if ((ival = rtnl_route_set_type(route, ival)) < 0)
274*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(ival, "Unable to set routing type: %s",
275*4dc78e53SAndroid Build Coastguard Worker 		      nl_geterror(ival));
276*4dc78e53SAndroid Build Coastguard Worker }
277*4dc78e53SAndroid Build Coastguard Worker 
nl_cli_route_parse_iif(struct rtnl_route * route,char * arg,struct nl_cache * link_cache)278*4dc78e53SAndroid Build Coastguard Worker void nl_cli_route_parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache)
279*4dc78e53SAndroid Build Coastguard Worker {
280*4dc78e53SAndroid Build Coastguard Worker 	int ival;
281*4dc78e53SAndroid Build Coastguard Worker 
282*4dc78e53SAndroid Build Coastguard Worker 	if (!(ival = rtnl_link_name2i(link_cache, arg)))
283*4dc78e53SAndroid Build Coastguard Worker 		nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg);
284*4dc78e53SAndroid Build Coastguard Worker 
285*4dc78e53SAndroid Build Coastguard Worker 	rtnl_route_set_iif(route, ival);
286*4dc78e53SAndroid Build Coastguard Worker }
287*4dc78e53SAndroid Build Coastguard Worker 
288*4dc78e53SAndroid Build Coastguard Worker /** @} */
289