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