ims_ipsec_pcscf: IPv6 support
[sip-router] / src / modules / ims_ipsec_pcscf / ipsec.c
1 /*
2  * IMS IPSEC PCSCF module
3  *
4  * Copyright (C) 2018 Alexander Yosifov
5  * Copyright (C) 2018 Tsvetomir Dimitrov
6  *
7  * This file is part of Kamailio, a free SIP server.
8  *
9  * Kamailio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * Kamailio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #include "ipsec.h"
26
27 #include "../../core/dprint.h"
28 #include "../../core/mem/pkg.h"
29 #include "../../core/ip_addr.h"
30
31 #include <errno.h>
32 #include <arpa/inet.h>
33 #include <libmnl/libmnl.h>
34 #include <linux/xfrm.h>
35 #include <time.h>
36 //#include <stdio.h>
37 //#include <string.h>
38
39
40 #define XFRM_TMPLS_BUF_SIZE 1024
41 #define NLMSG_BUF_SIZE 4096
42 #define NLMSG_DELETEALL_BUF_SIZE 8192
43
44
45 extern int xfrm_user_selector;
46 extern int spi_id_start;
47 extern int spi_id_range;
48
49 struct xfrm_buffer {
50     char buf[NLMSG_DELETEALL_BUF_SIZE];
51     int offset;
52 };
53
54
55 //
56 // This file contains all Linux specific IPSec code.
57 //
58
59 struct mnl_socket* init_mnl_socket()
60 {
61     struct mnl_socket*  mnl_socket = mnl_socket_open(NETLINK_XFRM);
62     if(NULL == mnl_socket) {
63         LM_ERR("Error opening a MNL socket\n");
64         return NULL;
65     }
66
67     if(mnl_socket_bind(mnl_socket, 0, MNL_SOCKET_AUTOPID) < 0) {
68         LM_ERR("Error binding a MNL socket\n");
69         return NULL;
70     }
71
72     return mnl_socket;
73 }
74
75 void close_mnl_socket(struct mnl_socket* sock)
76 {
77     if(mnl_socket_close(sock) != 0) {
78         LM_WARN("Error closing netlink socket\n");
79     }
80 }
81
82 static void string_to_key(char* dst, const str key_string)
83 {
84     int i = 0;
85     char *pos = key_string.s;
86
87     for (i = 0; i < key_string.len/2; i++) {
88         sscanf(pos, "%2hhx", &dst[i]);
89         pos += 2;
90     }
91 }
92
93 // Converts the protocol enum used in Kamailio to the constants used in Linux
94 unsigned short kamailio_to_linux_proto(const unsigned short kamailio_proto)
95 {
96     switch(kamailio_proto) {
97         case PROTO_UDP:
98             return IPPROTO_UDP;
99         case PROTO_TCP:
100             return IPPROTO_TCP;
101         case PROTO_NONE:
102         case PROTO_TLS:
103         case PROTO_SCTP:
104             case PROTO_WS:
105         case PROTO_WSS:
106         case PROTO_OTHER:
107         default:
108             return IPPROTO_MAX;
109     };
110 }
111
112 int add_sa(struct mnl_socket* nl_sock, unsigned short proto, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int s_port, int d_port, int long id, str ck, str ik)
113 {
114     char l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
115     char l_auth_algo_buf[XFRM_TMPLS_BUF_SIZE];
116     char l_enc_algo_buf[XFRM_TMPLS_BUF_SIZE];
117     struct nlmsghdr* l_nlh = NULL;
118     struct xfrm_usersa_info* l_xsainfo = NULL;
119
120     struct xfrm_algo* l_auth_algo = NULL;
121     struct xfrm_algo* l_enc_algo  = NULL;
122
123
124     memset(l_msg_buf, 0, sizeof(l_msg_buf));
125     memset(l_auth_algo_buf, 0, sizeof(l_auth_algo_buf));
126     memset(l_enc_algo_buf, 0, sizeof(l_enc_algo_buf));
127
128     unsigned sel_proto = 0;
129     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
130         LM_ERR("Invalid port was passed to the function: %d\n", proto);
131         return -1;
132     }
133
134     // nlmsghdr initialization
135     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
136     l_nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
137     l_nlh->nlmsg_type = XFRM_MSG_NEWSA;
138     l_nlh->nlmsg_seq = time(NULL);
139     l_nlh->nlmsg_pid = id;
140
141     // add Security association
142     l_xsainfo = (struct xfrm_usersa_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_usersa_info));
143     l_xsainfo->sel.family       = dest_addr_param->af;
144     if(dest_addr_param->af == AF_INET6) {
145         memcpy(l_xsainfo->sel.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xsainfo->sel.daddr.a6));
146         memcpy(l_xsainfo->sel.saddr.a6, src_addr_param->u.addr32, sizeof(l_xsainfo->sel.saddr.a6));
147         l_xsainfo->sel.prefixlen_d  = 128;
148         l_xsainfo->sel.prefixlen_s  = 128;
149     }
150     else {
151         l_xsainfo->sel.daddr.a4     = dest_addr_param->u.addr32[0];
152         l_xsainfo->sel.saddr.a4     = src_addr_param->u.addr32[0];
153         l_xsainfo->sel.prefixlen_d  = 32;
154         l_xsainfo->sel.prefixlen_s  = 32;
155     }
156     l_xsainfo->sel.dport        = htons(d_port);
157     l_xsainfo->sel.dport_mask   = 0xFFFF;
158     l_xsainfo->sel.sport        = htons(s_port);
159     l_xsainfo->sel.sport_mask   = 0xFFFF;
160     //l_xsainfo->sel.proto        = sel_proto;
161     l_xsainfo->sel.user         = htonl(xfrm_user_selector);
162
163     if(dest_addr_param->af == AF_INET6) {
164         memcpy(l_xsainfo->id.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xsainfo->id.daddr.a6));
165         memcpy(l_xsainfo->saddr.a6, src_addr_param->u.addr32, sizeof(l_xsainfo->saddr.a6));
166     }
167     else {
168         l_xsainfo->id.daddr.a4      = dest_addr_param->u.addr32[0];
169         l_xsainfo->saddr.a4         = src_addr_param->u.addr32[0];
170     }
171     l_xsainfo->id.spi           = htonl(id);
172     l_xsainfo->id.proto         = IPPROTO_ESP;
173
174     l_xsainfo->lft.soft_byte_limit      = XFRM_INF;
175     l_xsainfo->lft.hard_byte_limit      = XFRM_INF;
176     l_xsainfo->lft.soft_packet_limit    = XFRM_INF;
177     l_xsainfo->lft.hard_packet_limit    = XFRM_INF;
178     l_xsainfo->reqid                    = id;
179     l_xsainfo->family                   = dest_addr_param->af;
180     l_xsainfo->mode                     = XFRM_MODE_TRANSPORT;
181     l_xsainfo->replay_window            = 32;
182     //l_xsainfo->flags                    = XFRM_STATE_NOECN;
183
184     // Add authentication algorithm for this SA
185
186     // The cast below is performed because alg_key from struct xfrm_algo is char[0]
187     // The point is to provide a continuous chunk of memory with the key in it
188     l_auth_algo = (struct xfrm_algo *)l_auth_algo_buf;
189
190     strcpy(l_auth_algo->alg_name,"md5");
191     l_auth_algo->alg_key_len = ik.len * 4;
192     string_to_key(l_auth_algo->alg_key, ik);
193
194     mnl_attr_put(l_nlh, XFRMA_ALG_AUTH, sizeof(struct xfrm_algo) + l_auth_algo->alg_key_len, l_auth_algo);
195
196     // add encription algorithm for this SA
197     l_enc_algo = (struct xfrm_algo *)l_enc_algo_buf;
198     strcpy(l_enc_algo->alg_name,"cipher_null");
199
200     mnl_attr_put(l_nlh, XFRMA_ALG_CRYPT, sizeof(struct xfrm_algo) + l_enc_algo->alg_key_len, l_enc_algo);
201
202     // send it to Netlink socket
203     if(mnl_socket_sendto(nl_sock, l_nlh, l_nlh->nlmsg_len) < 0)
204     {
205         LM_ERR("Failed to send Netlink message for SA creation, error: %s\n", strerror(errno));
206         return -3;
207     }
208
209     return 0;
210 }
211
212
213 int remove_sa(struct mnl_socket* nl_sock, str src_addr_param, str dest_addr_param, int s_port, int d_port, int long id)
214 {
215     char* src_addr = NULL;
216     char* dest_addr = NULL;
217
218     // convert input IP addresses to char*
219     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
220         LM_ERR("Error allocating memory for src addr during SA removal\n");
221         return -1;
222     }
223
224     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
225         pkg_free(src_addr);
226         LM_ERR("Error allocating memory for dest addr during SA removal\n");
227         return -2;
228     }
229
230     memset(src_addr, 0, src_addr_param.len+1);
231     memset(dest_addr, 0, dest_addr_param.len+1);
232
233     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
234     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
235
236
237     struct {
238         struct nlmsghdr n;
239         struct xfrm_usersa_id   xsid;
240         char buf[XFRM_TMPLS_BUF_SIZE];
241
242     } req = {
243         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)),
244         .n.nlmsg_flags = NLM_F_REQUEST,
245         .n.nlmsg_type = XFRM_MSG_DELSA,
246         .xsid.spi = htonl(id),
247         .xsid.family = AF_INET,
248         .xsid.proto = IPPROTO_ESP,
249         .xsid.daddr.a4 = inet_addr(dest_addr)
250     };
251
252     // SADDR
253     xfrm_address_t saddr;
254     memset(&saddr, 0, sizeof(saddr));
255     saddr.a4 = inet_addr(src_addr);
256
257     mnl_attr_put(&req.n, XFRMA_SRCADDR, sizeof(saddr), (void *)&saddr);
258
259     if(mnl_socket_sendto(nl_sock, &req.n, req.n.nlmsg_len) < 0)
260     {
261         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
262         pkg_free(src_addr);
263         pkg_free(dest_addr);
264         return -1;
265     }
266
267     pkg_free(src_addr);
268     pkg_free(dest_addr);
269
270     return 0;
271 }
272
273
274 int add_policy(struct mnl_socket* mnl_socket, unsigned short proto, const struct ip_addr *src_addr_param, const struct ip_addr *dest_addr_param, int src_port, int dst_port, int long p_id, enum ipsec_policy_direction dir)
275 {
276     char                            l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
277     char                            l_tmpls_buf[XFRM_TMPLS_BUF_SIZE];
278     struct nlmsghdr*                l_nlh;
279     struct xfrm_userpolicy_info*    l_xpinfo;
280
281     unsigned sel_proto = 0;
282     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
283         LM_ERR("Invalid port was passed to the function: %d\n", proto);
284         return -1;
285     }
286
287     memset(l_msg_buf, 0, sizeof(l_msg_buf));
288     memset(l_tmpls_buf, 0, sizeof(l_tmpls_buf));
289
290     // nlmsghdr initialization
291     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
292     l_nlh->nlmsg_flags  = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
293     l_nlh->nlmsg_type   = XFRM_MSG_NEWPOLICY;
294     l_nlh->nlmsg_seq    = time(NULL);
295     l_nlh->nlmsg_pid    = p_id;
296
297     // add OUT policy
298     l_xpinfo = (struct xfrm_userpolicy_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_userpolicy_info));
299     l_xpinfo->sel.family        = dest_addr_param->af;
300     if(dest_addr_param->af == AF_INET6) {
301         memcpy(l_xpinfo->sel.daddr.a6, dest_addr_param->u.addr32, sizeof(l_xpinfo->sel.daddr.a6));
302         memcpy(l_xpinfo->sel.saddr.a6, src_addr_param->u.addr32, sizeof(l_xpinfo->sel.saddr.a6));
303         l_xpinfo->sel.prefixlen_d  = 128;
304         l_xpinfo->sel.prefixlen_s  = 128;
305     }
306     else {
307         l_xpinfo->sel.daddr.a4     = dest_addr_param->u.addr32[0];
308         l_xpinfo->sel.saddr.a4     = src_addr_param->u.addr32[0];
309         l_xpinfo->sel.prefixlen_d  = 32;
310         l_xpinfo->sel.prefixlen_s  = 32;
311     }
312     l_xpinfo->sel.dport         = htons(dst_port);
313     l_xpinfo->sel.dport_mask    = 0xFFFF;
314     l_xpinfo->sel.sport         = htons(src_port);
315     l_xpinfo->sel.sport_mask    = 0xFFFF;
316     //l_xpinfo->sel.proto         = sel_proto;
317     l_xpinfo->sel.user          = htonl(xfrm_user_selector);
318
319     l_xpinfo->lft.soft_byte_limit   = XFRM_INF;
320     l_xpinfo->lft.hard_byte_limit   = XFRM_INF;
321     l_xpinfo->lft.soft_packet_limit = XFRM_INF;
322     l_xpinfo->lft.hard_packet_limit = XFRM_INF;
323     l_xpinfo->priority              = 2080;
324     l_xpinfo->action                = XFRM_POLICY_ALLOW;
325     l_xpinfo->share                 = XFRM_SHARE_ANY;
326
327     if (dir == IPSEC_POLICY_DIRECTION_IN) {
328         l_xpinfo->dir               = XFRM_POLICY_IN;
329     }
330     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
331         l_xpinfo->dir               = XFRM_POLICY_OUT;
332     }
333     else {
334         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
335
336         return -3;
337     }
338
339     // xfrm_user_tmpl initialization
340     struct xfrm_user_tmpl* l_tmpl = (struct xfrm_user_tmpl*)l_tmpls_buf;
341     l_tmpl->id.proto    = IPPROTO_ESP;
342     l_tmpl->family      = dest_addr_param->af;
343     if(dest_addr_param->af == AF_INET6) {
344         memcpy(l_tmpl->id.daddr.a6, dest_addr_param->u.addr32, sizeof(l_tmpl->id.daddr.a6));
345         memcpy(l_tmpl->saddr.a6, src_addr_param->u.addr32, sizeof(l_tmpl->saddr.a6));
346     }
347     else {
348         l_tmpl->id.daddr.a4        = dest_addr_param->u.addr32[0];
349         l_tmpl->saddr.a4           = src_addr_param->u.addr32[0];
350     }
351     l_tmpl->reqid       = p_id;
352     l_tmpl->mode        = XFRM_MODE_TRANSPORT;
353     l_tmpl->aalgos      = (~(__u32)0);
354     l_tmpl->ealgos      = (~(__u32)0);
355     l_tmpl->calgos      = (~(__u32)0);
356
357     mnl_attr_put(l_nlh, XFRMA_TMPL, sizeof(struct xfrm_user_tmpl), l_tmpl);
358
359     if(mnl_socket_sendto(mnl_socket, l_nlh, l_nlh->nlmsg_len) < 0)
360     {
361         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
362         return -4;
363     }
364
365     return 0;
366 }
367
368 int remove_policy(struct mnl_socket* mnl_socket, unsigned short proto, str src_addr_param, str dest_addr_param, int src_port, int dst_port, int long p_id, enum ipsec_policy_direction dir)
369 {
370     unsigned sel_proto = 0;
371     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
372         LM_ERR("Invalid port was passed to the function: %d\n", proto);
373         return -1;
374     }
375
376     unsigned char policy_dir = 0;
377
378     if(dir == IPSEC_POLICY_DIRECTION_IN) {
379          policy_dir = XFRM_POLICY_IN;
380     }
381     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
382          policy_dir = XFRM_POLICY_OUT;
383     }
384     else {
385         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
386         return -1;
387     }
388
389     char* src_addr = NULL;
390     char* dest_addr = NULL;
391
392     // convert input IP addresses to char*
393     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
394         LM_ERR("Error allocating memory for src addr during SA removal\n");
395         return -1;
396     }
397
398     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
399         pkg_free(src_addr);
400         LM_ERR("Error allocating memory for dest addr during SA removal\n");
401         return -2;
402     }
403
404     memset(src_addr, 0, src_addr_param.len+1);
405     memset(dest_addr, 0, dest_addr_param.len+1);
406
407     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
408     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
409
410     struct {
411         struct nlmsghdr n;
412         struct xfrm_userpolicy_id xpid;
413         char buf[XFRM_TMPLS_BUF_SIZE];
414     } req = {
415         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid)),
416         .n.nlmsg_flags = NLM_F_REQUEST,
417         .n.nlmsg_type = XFRM_MSG_DELPOLICY,
418         .xpid.dir               = policy_dir,
419         .xpid.sel.family        = AF_INET,
420         .xpid.sel.daddr.a4      = inet_addr(dest_addr),
421         .xpid.sel.saddr.a4      = inet_addr(src_addr),
422         .xpid.sel.dport         = htons(dst_port),
423         .xpid.sel.dport_mask    = 0xFFFF,
424         .xpid.sel.prefixlen_d   = 32,
425         .xpid.sel.sport         = htons(src_port),
426         .xpid.sel.sport_mask    = 0xFFFF,
427         .xpid.sel.prefixlen_s   = 32//,
428         //.xpid.sel.proto         = sel_proto
429     };
430
431     if(mnl_socket_sendto(mnl_socket, &req.n, req.n.nlmsg_len) < 0)
432     {
433         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
434         pkg_free(src_addr);
435         pkg_free(dest_addr);
436         return -1;
437     }
438
439     pkg_free(src_addr);
440     pkg_free(dest_addr);
441
442     return 0;
443 }
444
445 static int delsa_data_cb(const struct nlmsghdr *nlh, void *data)
446 {
447     struct xfrm_usersa_info *xsinfo = NLMSG_DATA(nlh);
448     int xfrm_userid = ntohl(xsinfo->sel.user);
449
450     //Check if user id is different from Kamailio's
451     if(xfrm_userid != xfrm_user_selector)
452         return MNL_CB_OK;
453
454     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
455     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
456
457     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
458         LM_ERR("Not enough memory allocated for delete SAs netlink command\n");
459         return MNL_CB_ERROR;
460     }
461
462     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
463     new_delmsg->nlmsg_len = new_delmsg_len;
464     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
465     new_delmsg->nlmsg_type = XFRM_MSG_DELSA;
466     new_delmsg->nlmsg_seq = time(NULL);
467
468     struct xfrm_usersa_id *xsid = NLMSG_DATA(new_delmsg);
469     xsid->family = xsinfo->family;
470     memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr));
471     xsid->spi = xsinfo->id.spi;
472     xsid->proto = xsinfo->id.proto;
473
474     mnl_attr_put(new_delmsg, XFRMA_SRCADDR, sizeof(xsid->daddr), &xsinfo->saddr);
475
476     delmsg_buf->offset += new_delmsg->nlmsg_len;
477
478     return MNL_CB_OK;
479 }
480
481 static int delpolicy_data_cb(const struct nlmsghdr *nlh, void *data)
482 {
483     struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(nlh);
484     int xfrm_userid = ntohl(xpinfo->sel.user);
485
486     //Check if user id is different from Kamailio's
487     if(xfrm_userid != xfrm_user_selector)
488         return MNL_CB_OK;
489
490     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
491     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
492
493     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
494         LM_ERR("Not enough memory allocated for delete policies netlink command\n");
495         return MNL_CB_ERROR;
496     }
497
498     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
499     new_delmsg->nlmsg_len = new_delmsg_len;
500     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
501     new_delmsg->nlmsg_type = XFRM_MSG_DELPOLICY;
502     new_delmsg->nlmsg_seq = time(NULL);
503
504     struct xfrm_userpolicy_id *xpid = NLMSG_DATA(new_delmsg);
505     memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
506     xpid->dir = xpinfo->dir;
507     xpid->index = xpinfo->index;
508
509     delmsg_buf->offset += new_delmsg->nlmsg_len;
510
511     return MNL_CB_OK;
512 }
513
514 int clean_sa(struct mnl_socket*  mnl_socket)
515 {
516     struct {
517         struct nlmsghdr n;
518         //char buf[NLMSG_BUF_SIZE];
519     } req = {
520         .n.nlmsg_len = NLMSG_HDRLEN,
521         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
522         .n.nlmsg_type = XFRM_MSG_GETSA,
523         .n.nlmsg_seq = time(NULL),
524     };
525
526     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
527         LM_ERR("Error sending get all SAs command via netlink socket: %s\n", strerror(errno));
528         return 1;
529     }
530
531     char buf[NLMSG_BUF_SIZE];
532     memset(&buf, 0, sizeof(buf));
533
534     struct xfrm_buffer delmsg_buf;
535     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
536
537     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
538     while (ret > 0) {
539         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delsa_data_cb, &delmsg_buf);
540         if (ret <= MNL_CB_STOP) {
541
542             break;
543         }
544         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
545     }
546
547     // DELETE SAs
548     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
549         LM_ERR("Error sending delete SAs command via netlink socket: %s\n", strerror(errno));
550         return 1;
551     }
552
553     return 0;
554 }
555
556 int clean_policy(struct mnl_socket*  mnl_socket)
557 {
558     struct {
559         struct nlmsghdr n;
560         //char buf[NLMSG_BUF_SIZE];
561     } req = {
562         .n.nlmsg_len = NLMSG_HDRLEN,
563         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
564         .n.nlmsg_type = XFRM_MSG_GETPOLICY,
565         .n.nlmsg_seq = time(NULL),
566     };
567
568     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
569         LM_ERR("Error sending get all policies command via netlink socket: %s\n", strerror(errno));
570         return 1;
571     }
572
573     char buf[NLMSG_BUF_SIZE];
574     memset(&buf, 0, sizeof(buf));
575
576     struct xfrm_buffer delmsg_buf;
577     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
578
579     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
580     while (ret > 0) {
581         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delpolicy_data_cb, &delmsg_buf);
582         if (ret <= MNL_CB_STOP) {
583
584             break;
585         }
586         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
587     }
588
589     // DELETE POLICIES
590     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
591         LM_ERR("Error sending delete policies command via netlink socket: %s\n", strerror(errno));
592         return 1;
593     }
594
595     return 0;
596 }