• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2022 Huawei Device Co., Ltd.
4  *
5  * Description: Demo example of configuring NewIP route.
6  *
7  * Author: Yang Yanjun <yangyanjun@huawei.com>
8  *
9  * Data: 2022-09-06
10  */
11 #include <sys/socket.h>
12 #include <sys/ioctl.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <unistd.h>
17 #include <linux/route.h>
18 
19 #include "nip_uapi.h"
20 #include "nip_lib.h"
21 #include "newip_route.h"
22 
23 /* get ifindex based on the device name
24  * struct ifreq ifr;
25  * struct nip_ifreq ifrn;
26  * ioctl(fd, SIOGIFINDEX, &ifr);
27  * ifr.ifr_ifindex; ===> ifindex
28  */
nip_route_add(int ifindex,const struct nip_addr * dst_addr,const struct nip_addr * gateway_addr,__u8 gateway_flag,int opt)29 int nip_route_add(int ifindex, const struct nip_addr *dst_addr,
30 		  const struct nip_addr *gateway_addr, __u8 gateway_flag, int opt)
31 {
32 	int fd, ret;
33 	struct nip_rtmsg rt;
34 
35 	fd = socket(AF_NINET, SOCK_DGRAM, 0);
36 	if (fd < 0)
37 		return -1;
38 
39 	memset(&rt, 0, sizeof(rt));
40 	rt.rtmsg_ifindex = ifindex;
41 	rt.rtmsg_flags = RTF_UP;
42 	rt.rtmsg_dst = *dst_addr;
43 
44 	if (gateway_flag) {
45 		rt.rtmsg_gateway = *gateway_addr;
46 		rt.rtmsg_flags |= RTF_GATEWAY;
47 	}
48 
49 	ret = ioctl(fd, opt, &rt);
50 	if (ret < 0 && errno != EEXIST) { // ignore File Exists error
51 		close(fd);
52 		return -1;
53 	}
54 
55 	close(fd);
56 	return 0;
57 }
58 
cmd_help(void)59 void cmd_help(void)
60 {
61 	/* nip_route add 02   wlan0
62 	 * (配置目的地址02设备路由,出口是wlan0)
63 	 * nip_route add 02   wlan0 03
64 	 * (配置目的地址02设备路由,出口是wlan0,网关地址是03)
65 	 * nip_route add ff09 wlan0 03
66 	 * (配置广播默认路由,      出口是wlan0,网关地址是03)
67 	 */
68 	printf("\n[cmd example]\n");
69 	printf("nip_route { add | del } <dst-addr> <netcard-name>\n");
70 	printf("nip_route { add | del } <dst-addr> <netcard-name> <gateway-addr>\n");
71 }
72 
parse_name(char ** argv,int * ifindex,char * dev)73 int parse_name(char **argv, int *ifindex, char *dev)
74 {
75 	int len = strlen(*argv);
76 
77 	memset(dev, 0, ARRAY_LEN);
78 	if (len >= (ARRAY_LEN - 1) || !len)
79 		return -1;
80 	memcpy(dev, *argv, len);
81 	dev[len + 1] = '\0';
82 
83 	if (strncmp(dev, NIC_NAME_CHECK, strlen(NIC_NAME_CHECK))) {
84 		printf("unsupport addr cfg cmd-3, cmd=%s\n", dev);
85 		cmd_help();
86 		return -1;
87 	}
88 	return nip_get_ifindex(dev, ifindex);
89 }
90 
parse_cmd(char ** argv,int * opt)91 int parse_cmd(char **argv, int *opt)
92 {
93 	int len = strlen(*argv);
94 	char cmd[ARRAY_LEN];
95 
96 	memset(cmd, 0, ARRAY_LEN);
97 	if (!len || len >= (ARRAY_LEN - 1))
98 		return -1;
99 	memcpy(cmd, *argv, len);
100 	cmd[len + 1] = '\0';
101 
102 	if (!strncmp(cmd, CMD_ADD, strlen(CMD_ADD))) {
103 		*opt = SIOCADDRT;
104 	} else if (!strncmp(cmd, CMD_DEL, strlen(CMD_DEL))) {
105 		*opt = SIOCDELRT;
106 	} else {
107 		printf("unsupport route cfg cmd-1, cmd=%s\n", cmd);
108 		cmd_help();
109 		return -1;
110 	}
111 	return 0;
112 }
113 
parse_args(char ** argv,int * opt,__u8 * gateway_flag,int * ifindex,struct nip_addr * dst_addr,struct nip_addr * gateway_addr,char * dev,int argc)114 int parse_args(char **argv, int *opt, __u8 *gateway_flag, int *ifindex,
115 	       struct nip_addr *dst_addr, struct nip_addr *gateway_addr, char *dev, int argc)
116 {
117 	/* 配置参数1解析: { add | del } */
118 	int ret;
119 
120 	argv++;
121 	ret = parse_cmd(argv, opt);
122 	if (ret != 0)
123 		return -1;
124 
125 	/* 配置参数2解析: <dst-addr> */
126 	argv++;
127 	if (nip_get_addr(argv, dst_addr)) {
128 		printf("unsupport route cfg cmd-2\n");
129 		cmd_help();
130 		return -1;
131 	}
132 
133 	/* 配置参数3解析: <netcard-name> */
134 	argv++;
135 	ret = parse_name(argv, ifindex, dev);
136 	if (ret != 0)
137 		return -1;
138 
139 	/* 配置参数4解析: <gateway-addr> */
140 	if (argc == DEMO_INPUT_4) {
141 		argv++;
142 		if (nip_get_addr(argv, gateway_addr)) {
143 			printf("unsupport route cfg cmd-4\n");
144 			cmd_help();
145 			return -1;
146 		}
147 		*gateway_flag = 1;
148 	}
149 	return ret;
150 }
151 
main(int argc,char ** argv_input)152 int main(int argc, char **argv_input)
153 {
154 	int ret;
155 	int opt;
156 	int ifindex = 0;
157 	__u8 gateway_flag = 0;
158 	char **argv = argv_input;
159 	char dev[ARRAY_LEN];
160 	struct nip_addr dst_addr = {0};
161 	struct nip_addr gateway_addr = {0};
162 
163 	if (argc != DEMO_INPUT_3 && argc != DEMO_INPUT_4) {
164 		printf("unsupport route cfg input, argc=%d\n", argc);
165 		cmd_help();
166 		return -1;
167 	}
168 
169 	ret = parse_args(argv, &opt, &gateway_flag, &ifindex,
170 			 &dst_addr, &gateway_addr, dev, argc);
171 	if (ret != 0)
172 		return -1;
173 
174 	ret = nip_get_ifindex(dev, &ifindex);
175 	if (ret != 0) {
176 		printf("get %s ifindex fail, ret=%d\n", dev, ret);
177 		return -1;
178 	}
179 
180 	ret = nip_route_add(ifindex, &dst_addr, &gateway_addr, gateway_flag, opt);
181 	if (ret != 0) {
182 		printf("get %s ifindex fail, ret=%d\n", dev, ret);
183 		return -1;
184 	}
185 
186 	printf("%s (ifindex=%d) cfg route success\n", dev, ifindex);
187 	return 0;
188 }
189 
190