blob: c2cffba9e97c0f087e7a08cde700e5e9c0374f0f [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5#include <unistd.h>
6#include <errno.h>
7#include <netdb.h>
8#include <fcntl.h>
9#include <dirent.h>
10#include <time.h>
11#include <linux/capability.h>
12#include <sys/capability.h>
13#include <cutils/properties.h>
14#include "setkey_fileio.h"
15#include "setkey_xfrm_parse.h"
16#include "utils_xfrm.h"
17#define LOG_TAG "setkey"
18#include <log/log.h>
19#include <cutils/log.h>
20
21int volte_pid = -1;
22extern program_invocation_name;
23/*only record volte_stack's pid for flush_SA_SP_exist's use*/
24void set_property_volte()
25{
26 char pid[8] ={0};
27 if(program_invocation_name!=NULL)
28 {
29 ALOGE("program_invocation_name:%s\n",program_invocation_name);
30 }
31 if(strstr(program_invocation_name,"volte")!= NULL)
32 if(volte_pid ==-1)
33 {
34 sprintf(pid,"%d",getpid());
35 int ret = property_set("net.ims.volte.pid",pid);
36 if(ret != 0)
37 {
38 ALOGE("set property failed,errno:%d\n",errno);
39 return;
40 }
41 volte_pid =getpid();
42 }
43}
44
45static int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
46 int alen)
47{
48 int len = RTA_LENGTH(alen);
49 struct rtattr *rta = NULL;
50
51 if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
52 ALOGD( "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
53 return -1;
54 }
55
56 rta = NLMSG_TAIL(n);
57 rta->rta_type = type;
58 rta->rta_len = len;
59 memcpy(RTA_DATA(rta), data, alen);
60 n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
61 return 0;
62}
63
64int setkey_deleteSP_xfrm(char * src,char * dst,enum PROTOCOL_TYPE protocol,char * src_port,char * dst_port,char * direction)
65{
66
67 char src_arr[128] = {0};
68 char dst_arr[128] = {0};
69 unsigned groups = ~((unsigned)0); /* XXX */
70 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
71
72
73 memcpy(src_arr,src,strlen(src));
74 memcpy(dst_arr,dst,strlen(dst));
75
76
77/*fragment delete policy netlink msg*/
78 struct {
79 struct nlmsghdr n;
80 struct xfrm_userpolicy_id xpid;
81 char buf[RTA_BUF_SIZE];
82 } req;
83
84 memset(&req, 0, sizeof(req));
85
86 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
87 req.n.nlmsg_flags = NLM_F_REQUEST;
88 req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
89
90 req.xpid.dir = xfrm_dir_parse(direction);
91 if(req.xpid.dir == XFRM_POLICY_ERROR)
92 {
93 ALOGD("setkey_deleteSP_xfrm dir:%s is wrong\n",direction);
94 return -1;
95 }
96 xfrm_selector_parse(&req.xpid.sel, src_arr,dst_arr,protocol,src_port,dst_port);
97
98 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
99 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
100 return -1;
101
102 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
103 {
104 ALOGD("set2layeripsecrules_xfrm send failed,errno:%d\n",errno);
105 rtnl_close_xfrm(&rth);
106 return -1;
107 }
108 if(req.xpid.dir ==XFRM_POLICY_IN)
109 {
110 req.xpid.dir = XFRM_POLICY_FWD;
111 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
112 {
113 ALOGD("setkey_deleteSP_xfrm send POLICY_FWD failed,errno:%d",errno);
114 rtnl_close_xfrm(&rth);
115 return -1;
116 }
117 }
118#ifdef INIT_ENG_BUILD
119 ALOGD("setkey_deleteSP_xfrm successed fd:%d --spddelete %s[%s] %s[%s] %d -P %s;\n",rth.fd,src,src_port,dst,dst_port,protocol,direction);
120#endif
121 rtnl_close_xfrm(&rth);
122 return 0;
123}
124
125int setkey_deleteSA_xfrm(char * src,char * dst,char * ipsec_type,char * spi_src)
126{
127
128 char src_arr[128] = {0};
129 char dst_arr[128] = {0};
130 unsigned groups = ~((unsigned)0); /* XXX */
131 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
132
133 memcpy(src_arr,src,strlen(src));
134 memcpy(dst_arr,dst,strlen(dst));
135
136 /*fragment delete state netlink msg*/
137 struct {
138 struct nlmsghdr n;
139 struct xfrm_usersa_id xsid;
140 char buf[RTA_BUF_SIZE];
141 } req;
142
143 memset(&req, 0, sizeof(req));
144
145 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid));
146 req.n.nlmsg_flags = NLM_F_REQUEST;
147 req.n.nlmsg_type = XFRM_MSG_DELSA;
148 req.xsid.family = AF_UNSPEC;
149
150 /* ID */
151 struct xfrm_id id ;
152 xfrm_address_t saddr_xfrm;
153 memset(&id, 0, sizeof(id));
154 memset(&saddr_xfrm, 0, sizeof(saddr_xfrm));
155 xfrm_id_parse(&saddr_xfrm, &id, &req.xsid.family,src_arr,dst_arr,ipsec_type);
156 __u32 spi;
157 if (get_u32(&spi, spi_src, 0))
158 {
159 ALOGD("xfrm_id_parse spi:%s is wrong\n",spi_src);
160 return -1;
161 }
162
163 spi = htonl(spi);
164 id.spi = spi;
165 memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
166 req.xsid.spi = id.spi;
167 req.xsid.proto = id.proto;
168
169 addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
170 (void *)&saddr_xfrm, sizeof(saddr_xfrm));
171
172 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
173
174 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
175 return -1;
176 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
177 {
178 ALOGD("set2layeripsecrules_xfrm send failed,errno:%d\n",errno);
179 rtnl_close_xfrm(&rth);
180 return -1;
181 }
182#ifdef INIT_ENG_BUILD
183 ALOGD("setkey_deleteSA_xfrm successed fd:%d --delete %s %s %s %s;\n",rth.fd,src,dst,ipsec_type,spi_src);
184#endif
185 rtnl_close_xfrm(&rth);
186 return 0;
187}
188
189int setkey_setSA_xfrm(int cmd,char * ip_src,char * ip_dst,char * ipsec_type,char * spi_src,char * mode,
190 char * encrp_algo_src,char * encrp_key_src,char * intergrity_algo_src,char * intergrity_key_src,int u_id)
191{
192
193 char encrp_algo_arr[128] = {0};
194 char intergrity_algo_arr[128] = {0};
195 char srcport_arr[64] = {0};
196 char dstport_arr[64] = {0};
197 char * port_head = NULL;
198 char * port_tail = NULL;
199 char src_arr[128] = {0};
200 char dst_arr[128] = {0};
201 unsigned groups = ~((unsigned)0); /* XXX */
202 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
203
204 set_property_volte();
205
206 /*sepearte src addr and src port\dst addr and dst port, state's format often is add xx[xx] xx[xx] esp xx ....*/
207 port_head = strchr(ip_src,'[');
208 if(port_head == NULL)
209 {
210 memcpy(src_arr,ip_src,strlen(ip_src));
211 memcpy(srcport_arr,"0",1);
212 }
213 else
214 {
215 port_tail = strchr(ip_src,']');
216 if (port_tail == NULL)
217 {
218#ifdef INIT_ENG_BUILD
219 ALOGD("setkey_SA_xfrm wrong src ip:%s \n",ip_src);
220#endif
221 return -1;
222 }
223 else
224 {
225 memcpy(srcport_arr,port_head+1,port_tail-port_head-1);
226 memcpy(src_arr,ip_src,port_head-ip_src);
227 }
228 }
229 port_head = strchr(ip_dst,'[');
230 if(port_head==NULL)
231 {
232 memcpy(dst_arr,ip_dst,strlen(ip_dst));
233 memcpy(dstport_arr,"0",1);
234 }
235 else
236 {
237 port_tail = strchr(ip_dst,']');
238 if (port_tail == NULL)
239 {
240#ifdef INIT_ENG_BUILD
241 ALOGD("setkey_SA_xfrm wrong dst ip:%s \n",ip_dst);
242#endif
243 return -1;
244 }
245 else
246 {
247 memcpy(dstport_arr,port_head+1,port_tail-port_head-1);
248 memcpy(dst_arr,ip_dst,port_head-ip_dst);
249 }
250 }
251
252 /*fragment add/modify state netlink msg*/
253 struct {
254 struct nlmsghdr n;
255 struct xfrm_usersa_info xsinfo;
256 char buf[RTA_BUF_SIZE];
257 } req;
258
259 memset(&req, 0, sizeof(req));
260
261 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsinfo));
262 req.n.nlmsg_flags = NLM_F_REQUEST;
263 req.n.nlmsg_type = cmd;
264
265
266 req.xsinfo.family = AF_UNSPEC;
267 req.xsinfo.lft.soft_byte_limit = XFRM_INF;
268 req.xsinfo.lft.hard_byte_limit = XFRM_INF;
269 req.xsinfo.lft.soft_packet_limit = XFRM_INF;
270 req.xsinfo.lft.hard_packet_limit = XFRM_INF;
271 req.xsinfo.reqid = u_id;
272 /* ID */
273 if(xfrm_mode_parse(&req.xsinfo.mode, mode) ==-1)
274 {
275 ALOGD("setkey_SA_xfrm mode:%s is wrong\n",mode);
276 return -1;
277 }
278 __u32 spi;
279 if (get_u32(&spi, spi_src, 0))
280 {
281 ALOGD("xfrm_id_parse spi:%s is wrong\n",spi_src);
282 return -1;
283 }
284
285 spi = htonl(spi);
286 req.xsinfo.id.spi = spi;
287 if(xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,&req.xsinfo.family,
288 src_arr,dst_arr,ipsec_type)<0)
289 {
290#ifdef INIT_ENG_BUILD
291 ALOGD("setkey_SA_xfrm->xfrm_id_parse failed ip_src:%s,ip_dst:%s,ipsec_type:%s",ip_src,ip_dst,ipsec_type);
292#endif
293 return -1;
294 }
295 xfrm_selector_parse(&req.xsinfo.sel, src_arr,dst_arr,0,srcport_arr,dstport_arr);
296 /* ALGO */
297 struct {
298 union {
299 struct xfrm_algo alg;
300 struct xfrm_algo_aead aead;
301 struct xfrm_algo_auth auth;
302 } u;
303 char buf[XFRM_ALGO_KEY_BUF_SIZE];
304 } alg;
305 int len;
306 char *buf = NULL;
307 memset(&alg, 0, sizeof(alg));
308 buf = alg.u.alg.alg_key;
309 len = sizeof(alg.u.alg);
310
311 xfrm_encry_algo_parse(encrp_algo_src, encrp_algo_arr);
312 if(strcmp(encrp_algo_arr,"not-supported") == 0)
313 return -1;
314
315 if((encrp_algo_src == NULL)||(strcmp(encrp_algo_src,"null")==0))
316 {
317 alg.u.alg.alg_key_len = 0;
318 memcpy(alg.u.alg.alg_name, "ecb(cipher_null)", strlen("ecb(cipher_null)"));
319 }
320 else
321 if(xfrm_algo_parse((void *)&alg, encrp_algo_arr, encrp_key_src,
322 buf, sizeof(alg.buf))==-1)
323 {
324#ifdef INIT_ENG_BUILD
325 ALOGD("setkey_SA_xfrm->xfrm_algo_parse failed encrp_algo:%s,encrp_key:%s,",encrp_algo_src, encrp_key_src);
326#endif
327 return -1;
328 }
329 len += alg.u.alg.alg_key_len;
330 addattr_l(&req.n, sizeof(req.buf), XFRMA_ALG_CRYPT,(void *)&alg, len);
331
332 memset((void *)&alg, 0,sizeof(alg));
333 buf = alg.u.alg.alg_key;
334 len = sizeof(alg.u.alg);
335 xfrm_interg_algo_parse(intergrity_algo_src, intergrity_algo_arr);
336 if(strcmp(intergrity_algo_arr ,"not-supported") == 0)
337 return -1;
338 if((intergrity_algo_src == NULL)||(strcmp(intergrity_algo_src,"null")==0))
339 {
340 alg.u.alg.alg_key_len = 0;
341 memcpy(alg.u.alg.alg_name, "digest_null", strlen("digest_null"));
342 }
343 else
344 if(xfrm_algo_parse((void *)&alg, intergrity_algo_arr, intergrity_key_src,
345 buf, sizeof(alg.buf))<-1)
346 {
347#ifdef INIT_ENG_BUILD
348 ALOGD("setkey_SA_xfrm->xfrm_algo_parse failed intergrity crp_algo:%s,intergrity _key:%s,",intergrity_algo_src, intergrity_key_src);
349#endif
350 return -1;
351 }
352 len += alg.u.alg.alg_key_len;
353 addattr_l(&req.n, sizeof(req.buf), XFRMA_ALG_AUTH,(void *)&alg, len);
354
355 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
356
357 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
358 return -1;
359
360 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
361 {
362 ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
363 rtnl_close_xfrm(&rth);
364 return -1;
365 }
366#ifdef INIT_ENG_BUILD
367 ALOGD("setkey_SA_xfrm successed fd:%d ---add %s %s %s %s -m %s -E %s %s -A %s %s -u %d; spi:%d\n",rth.fd,ip_src,ip_dst,ipsec_type,spi_src,mode,
368 encrp_algo_src,encrp_key_src,intergrity_algo_src,intergrity_key_src,u_id,req.xsinfo.id.spi);
369#endif
370 rtnl_close_xfrm(&rth);
371 return 0;
372}
373
374
375int setkey_SP_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type,char * mode, char * direction,int u_id)
376{
377 char src_arr[128] = {0};
378 char dst_arr[128] = {0};
379 char src_tunnel_arr[128] = {0};
380 char dst_tunnel_arr[128] = {0};
381 unsigned groups = ~((unsigned)0); /* XXX */
382 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
383
384 memcpy(src_arr,src_range,strlen(src_range));
385 memcpy(dst_arr,dst_range,strlen(dst_range));
386 if(src_tunnel)
387 memcpy(src_tunnel_arr,src_tunnel,strlen(src_tunnel));
388 if(dst_tunnel)
389 memcpy(dst_tunnel_arr,dst_tunnel,strlen(dst_tunnel));
390
391 set_property_volte();
392
393
394
395 struct req_handle_xfrm req;
396 char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
397 struct xfrm_user_tmpl *tmpl = NULL;
398 int tmpls_len = 0;
399
400
401 memset(&req, 0, sizeof(req));
402 memset(&tmpls_buf, 0, sizeof(tmpls_buf));
403
404 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
405 req.n.nlmsg_flags = NLM_F_REQUEST;
406 req.n.nlmsg_type = cmd;
407
408 req.xpinfo.lft.soft_byte_limit = XFRM_INF;
409 req.xpinfo.lft.hard_byte_limit = XFRM_INF;
410 req.xpinfo.lft.soft_packet_limit = XFRM_INF;
411 req.xpinfo.lft.hard_packet_limit = XFRM_INF;
412 req.xpinfo.dir = xfrm_dir_parse(direction);
413 req.xpinfo.priority = 1000;
414 xfrm_selector_parse(&req.xpinfo.sel, src_arr,dst_arr,protocol,port_src,port_dst);
415
416 if(req.xpinfo.dir == XFRM_POLICY_ERROR)
417 {
418 ALOGD("setkey_SP_xfrm dir:%s is wrong",direction);
419 return -1;
420 }
421 tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
422
423 if(xfrm_mode_parse(&tmpl->mode, mode) ==-1)
424 {
425 ALOGD("setkey_SP_xfrm mode:%s is wrong",mode);
426 return -1;
427 }
428 tmpl->family = req.xpinfo.sel.family;
429 if(tmpl->mode == XFRM_MODE_TUNNEL)
430 {
431 xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
432 src_tunnel_arr,dst_tunnel_arr,ipsec_type);
433 }
434
435 tmpl->aalgos = (~(__u32)0);
436 tmpl->ealgos = (~(__u32)0);
437 tmpl->calgos = (~(__u32)0);
438 tmpl->reqid = u_id;
439 tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type);
440 if(tmpl->id.proto <0)
441 {
442 ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type);
443 return -1;
444 }
445 tmpls_len += sizeof(*tmpl);
446 if (tmpls_len > 0) {
447 addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
448 (void *)tmpls_buf, tmpls_len);
449 }
450
451 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
452
453 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
454 return -1;
455
456 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
457 {
458 ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
459 rtnl_close_xfrm(&rth);
460 return -1;
461 }
462 if(req.xpinfo.dir ==XFRM_POLICY_IN)
463 {
464 req.xpinfo.dir = XFRM_POLICY_FWD;
465 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
466 {
467 ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
468 rtnl_close_xfrm(&rth);
469 return -1;
470 }
471 }
472#ifdef INIT_ENG_BUILD
473 ALOGD("setkey_SP_xfrm successed fd:%d --spdadd %s[%s] %s[%s] %d -P %s ipsec %s/%s//unique:%d;\n",rth.fd,src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type,mode,u_id);
474#endif
475 rtnl_close_xfrm(&rth);
476 return 0;
477}
478
479int setkey_SP_2layer_xfrm(int cmd,char * src_range,char * dst_range,enum PROTOCOL_TYPE protocol,char * port_src,char * port_dst,char * src_tunnel,char * dst_tunnel,char * ipsec_type1,char * mode1, char * ipsec_type2,char * mode2,char * direction,int u_id1,int u_id2)
480{
481 char src_arr[128] = {0};
482 char dst_arr[128] = {0};
483 char src_tunnel_arr[128] = {0};
484 char dst_tunnel_arr[128] = {0};
485 unsigned groups = ~((unsigned)0); /* XXX */
486 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
487
488 memcpy(src_arr,src_range,strlen(src_range));
489 memcpy(dst_arr,dst_range,strlen(dst_range));
490 if(src_tunnel)
491 memcpy(src_tunnel_arr,src_tunnel,strlen(src_tunnel));
492 if(dst_tunnel)
493 memcpy(dst_tunnel_arr,dst_tunnel,strlen(dst_tunnel));
494
495
496 struct req_handle_xfrm req;
497 char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
498 struct xfrm_user_tmpl *tmpl = NULL;
499 int tmpls_len = 0;
500
501 set_property_volte();
502
503 memset(&req, 0, sizeof(req));
504 memset(&tmpls_buf, 0, sizeof(tmpls_buf));
505
506 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpinfo));
507 req.n.nlmsg_flags = NLM_F_REQUEST;
508 req.n.nlmsg_type = cmd;
509
510 req.xpinfo.lft.soft_byte_limit = XFRM_INF;
511 req.xpinfo.lft.hard_byte_limit = XFRM_INF;
512 req.xpinfo.lft.soft_packet_limit = XFRM_INF;
513 req.xpinfo.lft.hard_packet_limit = XFRM_INF;
514 req.xpinfo.dir = xfrm_dir_parse(direction);
515 req.xpinfo.priority = 1000;
516 xfrm_selector_parse(&req.xpinfo.sel, src_arr,dst_arr,protocol,port_src,port_dst);
517
518 if(req.xpinfo.dir == XFRM_POLICY_ERROR)
519 {
520 ALOGD("setkey_SP_xfrm dir:%s is wrong",direction);
521 return -1;
522 }
523 tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
524
525 if(xfrm_mode_parse(&tmpl->mode, mode1) ==-1)
526 {
527 ALOGD("setkey_SP_xfrm mode:%s is wrong",mode1);
528 return -1;
529 }
530 tmpl->family = req.xpinfo.sel.family;
531 if(tmpl->mode == XFRM_MODE_TUNNEL)
532 {
533 xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
534 src_tunnel_arr,dst_tunnel_arr,ipsec_type1);
535 }
536
537 tmpl->aalgos = (~(__u32)0);
538 tmpl->ealgos = (~(__u32)0);
539 tmpl->calgos = (~(__u32)0);
540 tmpl->reqid = u_id1;
541 tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type1);
542 if(tmpl->id.proto <0)
543 {
544 ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type1);
545 return -1;
546 }
547 tmpls_len += sizeof(*tmpl);
548 tmpl = (struct xfrm_user_tmpl *)((char *)tmpls_buf + tmpls_len);
549
550 if(xfrm_mode_parse(&tmpl->mode, mode2) ==-1)
551 {
552 ALOGD("setkey_SP_xfrm mode:%s is wrong",mode1);
553 return -1;
554 }
555 tmpl->family = req.xpinfo.sel.family;
556 if(tmpl->mode == XFRM_MODE_TUNNEL)
557 {
558 xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
559 src_tunnel_arr,dst_tunnel_arr,ipsec_type2);
560 }
561 tmpl->aalgos = (~(__u32)0);
562 tmpl->ealgos = (~(__u32)0);
563 tmpl->calgos = (~(__u32)0);
564 tmpl->reqid = u_id2;
565 tmpl->id.proto = xfrm_xfrmproto_getbyname(ipsec_type2);
566 if(tmpl->id.proto <0)
567 {
568 ALOGD("setkey_SP_xfrm ipsec_type:%s is wrong",ipsec_type2);
569 return -1;
570 }
571 tmpls_len += sizeof(*tmpl);
572 if (tmpls_len > 0) {
573 addattr_l(&req.n, sizeof(req), XFRMA_TMPL,
574 (void *)tmpls_buf, tmpls_len);
575 }
576
577 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
578
579 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
580 return -1;
581
582 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
583 {
584 ALOGD("set2layeripsecrules_xfrm send failed,errno:%d",errno);
585 rtnl_close_xfrm(&rth);
586 return -1;
587 }
588 if(req.xpinfo.dir ==XFRM_POLICY_IN)
589 {
590 req.xpinfo.dir = XFRM_POLICY_FWD;
591 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
592 {
593 ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
594 rtnl_close_xfrm(&rth);
595 return -1;
596 }
597 }
598#ifdef INIT_ENG_BUILD
599 ALOGD("setkey_SP_2layer_xfrm successed fd:%d --spdupdate %s[%s] %s[%s] %d -P %s prio 1000 ipsec %s/%s//unique:%d %s/%s/%s-%s/unique:%d;\n",rth.fd,src_range,port_src,dst_range,port_dst,protocol,direction,ipsec_type1,mode1,u_id1,ipsec_type2,mode2,src_tunnel,dst_tunnel,u_id2);
600#endif
601 rtnl_close_xfrm(&rth);
602 return 0;
603}
604int setkey_flushSAD_xfrm(char * ipsec_type)
605{
606 unsigned groups = ~((unsigned)0); /* XXX */
607 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
608
609 struct {
610 struct nlmsghdr n;
611 struct xfrm_usersa_flush xsf;
612 } req;
613
614
615 memset(&req, 0, sizeof(req));
616
617 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsf));
618 req.n.nlmsg_flags = NLM_F_REQUEST;
619 req.n.nlmsg_type = XFRM_MSG_FLUSHSA;
620 req.xsf.proto = 0;
621
622 req.xsf.proto = (__u8)xfrm_xfrmproto_getbyname(ipsec_type);
623 if (req.xsf.proto < 0)
624 {
625 ALOGD("setkey_flushSAD_xfrm :%s is wrong",ipsec_type);
626 return -1;
627 }
628
629 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
630
631 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
632 return -1;
633
634 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
635 {
636 ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
637 rtnl_close_xfrm(&rth);
638 return -1;
639 }
640 ALOGD("setkey_flushSAD_xfrm successed fd:%d --flush ;\n",rth.fd);
641 rtnl_close_xfrm(&rth);
642
643 return 0;
644}
645int setkey_flushSPD_xfrm(void)
646{
647 unsigned groups = ~((unsigned)0); /* XXX */
648 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
649
650
651 struct {
652 struct nlmsghdr n;
653 char buf[RTA_BUF_SIZE];
654 } req;
655
656 memset(&req, 0, sizeof(req));
657
658
659 req.n.nlmsg_len = NLMSG_LENGTH(0); /* nlmsg data is nothing */
660 req.n.nlmsg_flags = NLM_F_REQUEST;
661 req.n.nlmsg_type = XFRM_MSG_FLUSHPOLICY;
662
663 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
664
665 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
666 return -1;
667 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
668 {
669 ALOGD("set2layeripsecrules_xfrm send POLICY_FWD failed,errno:%d",errno);
670 rtnl_close_xfrm(&rth);
671 return -1;
672 }
673 ALOGD("setkey_flushSPD_xfrm successed fd:%d --flush ;\n",rth.fd);
674
675 rtnl_close_xfrm(&rth);
676
677 return 0;
678}
679int flush_SA_SP_exist_xfrm()
680{
681 unsigned groups = ~((unsigned)0); /* XXX */
682 struct rtnl_handle_xfrm rth = { -1,{0},{0},0,0 };
683
684 struct {
685 struct nlmsghdr nlh;
686 struct rtgenmsg g;
687 __u16 align_rta; /* attribute has to be 32bit aligned */
688 struct rtattr ext_req;
689 __u32 ext_filter_mask;
690 } req;
691
692 memset(&req, 0, sizeof(req));
693 req.nlh.nlmsg_len = sizeof(req);
694 req.nlh.nlmsg_type = XFRM_MSG_GETPOLICY;
695 req.nlh.nlmsg_flags = NLM_F_DUMP|NLM_F_REQUEST;
696 req.nlh.nlmsg_seq = rth.dump = ++rth.seq;
697 req.g.rtgen_family = AF_UNSPEC;
698
699 req.ext_req.rta_type = IFLA_EXT_MASK;
700 req.ext_req.rta_len = RTA_LENGTH(sizeof(__u32));
701 req.ext_filter_mask = RTEXT_FILTER_VF;
702
703 groups |= (nl_mgrp_xfrm(XFRMNLGRP_ACQUIRE)|nl_mgrp_xfrm(XFRMNLGRP_EXPIRE)|nl_mgrp_xfrm(XFRMNLGRP_SA)|nl_mgrp_xfrm(XFRMNLGRP_POLICY));
704
705 if (rtnl_open_byproto_xfrm(&rth, groups, NETLINK_XFRM) < 0)
706 return -1;
707 if(send(rth.fd, (void*)&req, sizeof(req), 0)<0)
708 {
709 ALOGD("flush_SA_SP_exist_xfrm send msg failed,errno:%d",errno);
710 rtnl_close_xfrm(&rth);
711 return -1;
712 }
713 if (rtnl_listen_xfrm(&rth, rtnl_accept_msg_xfrm) < 0)
714 {
715 rtnl_close_xfrm(&rth);
716 ALOGD("flush_SA_SP_exist_xfrm <0 done");
717 return -2;
718 }
719 ALOGD("flush_SA_SP_exist_xfrm done");
720 rtnl_close_xfrm(&rth);
721
722 return 0;
723}
724
725int xfrm_policy_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n,pid_t volte_pid)
726{
727
728 struct xfrm_userpolicy_info *xpinfo = NULL;
729 int len = n->nlmsg_len;
730
731
732 xpinfo = NLMSG_DATA(n);
733 len -= NLMSG_SPACE(sizeof(*xpinfo));
734 if (len < 0) {
735 ALOGE( "BUG: wrong nlmsg len %d\n", len);
736 return -1;
737 }
738 if(xpinfo->sel.user != volte_pid)
739 {
740 ALOGE( "we donot need to process:%d's policy\n", xpinfo->sel.user);
741 return 0;
742 }
743
744/*fragment delete policy*/
745 struct {
746 struct nlmsghdr n;
747 struct xfrm_userpolicy_id xpid;
748 char buf[RTA_BUF_SIZE];
749 } req;
750
751 memset(&req, 0, sizeof(req));
752
753 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid));
754 req.n.nlmsg_flags = NLM_F_REQUEST;
755 req.n.nlmsg_type = XFRM_MSG_DELPOLICY;
756
757 req.xpid.dir = xpinfo->dir;
758
759 memcpy(&req.xpid.sel,&xpinfo->sel,sizeof(req.xpid.sel));
760
761
762 if(send(rth->fd, (void*)&req, sizeof(req), 0)<0)
763 {
764 ALOGD("xfrm_policy_process_delete_exist send failed,errno:%d",errno);
765 return -1;
766 }
767#ifdef INIT_ENG_BUILD
768 if(req.xpid.sel.family == AF_INET)
769 ALOGD("xfrm_policy_process_delete_exist successed fd:%d --spddelete 0x%x[%d] 0x%x[%d] %d -P %d;\n",rth->fd,req.xpid.sel.saddr.a4,req.xpid.sel.sport,req.xpid.sel.daddr.a4,req.xpid.sel.dport,req.xpid.sel.proto,req.xpid.dir);
770 else
771 ALOGD("xfrm_policy_process_delete_exist successed fd:%d --spddelete 0x%x %x %x %x[%d] 0x%x %x %x %x[%d] %d -P %d;\n",rth->fd,
772 req.xpid.sel.saddr.a6[0],req.xpid.sel.saddr.a6[1],req.xpid.sel.saddr.a6[2],req.xpid.sel.saddr.a6[3],req.xpid.sel.sport,
773 req.xpid.sel.daddr.a6[0],req.xpid.sel.daddr.a6[1],req.xpid.sel.daddr.a6[2],req.xpid.sel.daddr.a6[3],req.xpid.sel.dport,
774 req.xpid.sel.proto,req.xpid.dir);
775#endif
776 return 0;
777}
778
779int xfrm_state_process_delete_exist( struct rtnl_handle_xfrm * rth,struct nlmsghdr *n,pid_t volte_pid)
780{
781
782 struct xfrm_usersa_info * xsinfo = NULL;
783 int len = n->nlmsg_len;
784 xfrm_address_t saddr;
785
786 xsinfo = NLMSG_DATA(n);
787 len -= NLMSG_SPACE(sizeof(*xsinfo));
788 if (len < 0) {
789 ALOGE( "BUG: wrong nlmsg len %d\n", len);
790 return -1;
791 }
792
793 if(xsinfo->sel.user != volte_pid)
794 {
795 ALOGE( "we donot need to process:%d's policy\n", xsinfo->sel.user);
796 return 0;
797 }
798
799/*fragment delete state*/
800 struct {
801 struct nlmsghdr n;
802 struct xfrm_usersa_id xsid;
803 char buf[RTA_BUF_SIZE];
804 } req;
805
806 memset(&req, 0, sizeof(req));
807
808 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid));
809 req.n.nlmsg_flags = NLM_F_REQUEST;
810 req.n.nlmsg_type = XFRM_MSG_DELSA;
811
812 req.xsid.family = xsinfo->family;
813 memcpy(&req.xsid.daddr,&xsinfo->sel.daddr,sizeof(xsinfo->sel.daddr));
814 memcpy(&saddr,&xsinfo->saddr,sizeof(xsinfo->saddr));
815 addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
816 (void *)&saddr, sizeof(saddr));
817 if(send(rth->fd, (void*)&req, sizeof(req), 0)<0)
818 {
819 ALOGD("xfrm_state_process_delete_exist send failed,errno:%d",errno);
820 return -1;
821 }
822#ifdef INIT_ENG_BUILD
823 if(xsinfo->sel.family == AF_INET)
824 ALOGD("xfrm_state_process_delete_exist successed fd:%d --delete 0x%x 0x%x %d;\n",rth->fd,xsinfo->sel.saddr.a4,xsinfo->sel.daddr.a4,xsinfo->id.spi);
825 else
826 ALOGD("xfrm_state_process_delete_exist successed fd:%d --delete 0x%x %x %x %x 0x%x %x %x %x %d ;\n",rth->fd,
827 xsinfo->sel.saddr.a6[0],xsinfo->sel.saddr.a6[1],xsinfo->sel.saddr.a6[2],xsinfo->sel.saddr.a6[3],
828 xsinfo->sel.daddr.a6[0],xsinfo->sel.daddr.a6[1],xsinfo->sel.daddr.a6[2],xsinfo->sel.daddr.a6[3],
829 xsinfo->id.spi);
830#endif
831 return 0;
832}
833