ims_ipsec_pcscf: TCP 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, str src_addr_param, str 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     char* src_addr = NULL;
124     char* dest_addr = NULL;
125
126     memset(l_msg_buf, 0, sizeof(l_msg_buf));
127     memset(l_auth_algo_buf, 0, sizeof(l_auth_algo_buf));
128     memset(l_enc_algo_buf, 0, sizeof(l_enc_algo_buf));
129
130     unsigned sel_proto = 0;
131     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
132         LM_ERR("Invalid port was passed to the function: %d\n", proto);
133         return -1;
134     }
135
136     // convert input IP addresses and keys to char*
137     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
138         LM_ERR("Error allocating memory for src addr during SA creation\n");
139         return -2;
140     }
141
142     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
143         pkg_free(src_addr);
144         LM_ERR("Error allocating memory for dest addr during SA creation\n");
145         return -3;
146     }
147
148     memset(src_addr, 0, src_addr_param.len+1);
149     memset(dest_addr, 0, dest_addr_param.len+1);
150
151     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
152     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
153
154     // nlmsghdr initialization
155     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
156     l_nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
157     l_nlh->nlmsg_type = XFRM_MSG_NEWSA;
158     l_nlh->nlmsg_seq = time(NULL);
159     l_nlh->nlmsg_pid = id;
160
161     // add Security association
162     l_xsainfo = (struct xfrm_usersa_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_usersa_info));
163     l_xsainfo->sel.family       = AF_INET;
164     l_xsainfo->sel.daddr.a4     = inet_addr(dest_addr);
165     l_xsainfo->sel.saddr.a4     = inet_addr(src_addr);
166     l_xsainfo->sel.dport        = htons(d_port);
167     l_xsainfo->sel.dport_mask   = 0xFFFF;
168     l_xsainfo->sel.prefixlen_d  = 32;
169     l_xsainfo->sel.sport        = htons(s_port);
170     l_xsainfo->sel.sport_mask   = 0xFFFF;
171     l_xsainfo->sel.prefixlen_s  = 32;
172     l_xsainfo->sel.proto        = sel_proto;
173     l_xsainfo->sel.user         = htonl(xfrm_user_selector);
174
175     l_xsainfo->saddr.a4         = inet_addr(src_addr);
176     l_xsainfo->id.daddr.a4      = inet_addr(dest_addr);
177     l_xsainfo->id.spi           = htonl(id);
178     l_xsainfo->id.proto         = IPPROTO_ESP;
179
180     l_xsainfo->lft.soft_byte_limit      = XFRM_INF;
181     l_xsainfo->lft.hard_byte_limit      = XFRM_INF;
182     l_xsainfo->lft.soft_packet_limit    = XFRM_INF;
183     l_xsainfo->lft.hard_packet_limit    = XFRM_INF;
184     l_xsainfo->reqid                    = id;
185     l_xsainfo->family                   = AF_INET;
186     l_xsainfo->mode                     = XFRM_MODE_TRANSPORT;
187     l_xsainfo->replay_window            = 32;
188     l_xsainfo->flags                    = XFRM_STATE_NOECN;
189
190     // char* ip addresses are no longer needed - free them
191     pkg_free(src_addr);
192     pkg_free(dest_addr);
193
194     // Add authentication algorithm for this SA
195
196     // The cast below is performed because alg_key from struct xfrm_algo is char[0]
197     // The point is to provide a continuous chunk of memory with the key in it
198     l_auth_algo = (struct xfrm_algo *)l_auth_algo_buf;
199
200     strcpy(l_auth_algo->alg_name,"md5");
201     l_auth_algo->alg_key_len = ik.len * 4;
202     string_to_key(l_auth_algo->alg_key, ik);
203
204     mnl_attr_put(l_nlh, XFRMA_ALG_AUTH, sizeof(struct xfrm_algo) + l_auth_algo->alg_key_len, l_auth_algo);
205
206     // add encription algorithm for this SA
207     l_enc_algo = (struct xfrm_algo *)l_enc_algo_buf;
208     strcpy(l_enc_algo->alg_name,"cipher_null");
209
210     mnl_attr_put(l_nlh, XFRMA_ALG_CRYPT, sizeof(struct xfrm_algo) + l_enc_algo->alg_key_len, l_enc_algo);
211
212     // send it to Netlink socket
213     if(mnl_socket_sendto(nl_sock, l_nlh, l_nlh->nlmsg_len) < 0)
214     {
215         LM_ERR("Failed to send Netlink message for SA creation, error: %s\n", strerror(errno));
216         return -3;
217     }
218
219     return 0;
220 }
221
222
223 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)
224 {
225     char* src_addr = NULL;
226     char* dest_addr = NULL;
227
228     // convert input IP addresses to char*
229     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
230         LM_ERR("Error allocating memory for src addr during SA removal\n");
231         return -1;
232     }
233
234     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
235         pkg_free(src_addr);
236         LM_ERR("Error allocating memory for dest addr during SA removal\n");
237         return -2;
238     }
239
240     memset(src_addr, 0, src_addr_param.len+1);
241     memset(dest_addr, 0, dest_addr_param.len+1);
242
243     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
244     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
245
246
247     struct {
248         struct nlmsghdr n;
249         struct xfrm_usersa_id   xsid;
250         char buf[XFRM_TMPLS_BUF_SIZE];
251
252     } req = {
253         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xsid)),
254         .n.nlmsg_flags = NLM_F_REQUEST,
255         .n.nlmsg_type = XFRM_MSG_DELSA,
256         .xsid.spi = htonl(id),
257         .xsid.family = AF_INET,
258         .xsid.proto = IPPROTO_ESP,
259         .xsid.daddr.a4 = inet_addr(dest_addr)
260     };
261
262     // SADDR
263     xfrm_address_t saddr;
264     memset(&saddr, 0, sizeof(saddr));
265     saddr.a4 = inet_addr(src_addr);
266
267     mnl_attr_put(&req.n, XFRMA_SRCADDR, sizeof(saddr), (void *)&saddr);
268
269     if(mnl_socket_sendto(nl_sock, &req.n, req.n.nlmsg_len) < 0)
270     {
271         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
272         pkg_free(src_addr);
273         pkg_free(dest_addr);
274         return -1;
275     }
276
277     pkg_free(src_addr);
278     pkg_free(dest_addr);
279
280     return 0;
281 }
282
283
284 int add_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)
285 {
286     char                            l_msg_buf[MNL_SOCKET_BUFFER_SIZE];
287     char                            l_tmpls_buf[XFRM_TMPLS_BUF_SIZE];
288     struct nlmsghdr*                l_nlh;
289     struct xfrm_userpolicy_info*    l_xpinfo;
290
291     unsigned sel_proto = 0;
292     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
293         LM_ERR("Invalid port was passed to the function: %d\n", proto);
294         return -1;
295     }
296
297     char* src_addr = NULL;
298     char* dest_addr = NULL;
299
300     memset(l_msg_buf, 0, sizeof(l_msg_buf));
301     memset(l_tmpls_buf, 0, sizeof(l_tmpls_buf));
302
303     // convert input IP addresses to char*
304     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
305         LM_ERR("Error allocating memory for src addr during Policy creation\n");
306         return -1;
307     }
308
309     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
310         pkg_free(src_addr);
311         LM_ERR("Error allocating memory for dest addr during Policy creation\n");
312         return -2;
313     }
314
315     memset(src_addr, 0, src_addr_param.len+1);
316     memset(dest_addr, 0, dest_addr_param.len+1);
317
318     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
319     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
320
321     // nlmsghdr initialization
322     l_nlh = mnl_nlmsg_put_header(l_msg_buf);
323     l_nlh->nlmsg_flags  = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
324     l_nlh->nlmsg_type   = XFRM_MSG_NEWPOLICY;
325     l_nlh->nlmsg_seq    = time(NULL);
326     l_nlh->nlmsg_pid    = p_id;
327
328     // add OUT policy
329     l_xpinfo = (struct xfrm_userpolicy_info*)mnl_nlmsg_put_extra_header(l_nlh, sizeof(struct xfrm_userpolicy_info));
330     l_xpinfo->sel.family        = AF_INET;
331     l_xpinfo->sel.daddr.a4      = inet_addr(dest_addr);
332     l_xpinfo->sel.saddr.a4      = inet_addr(src_addr);
333     l_xpinfo->sel.dport         = htons(dst_port);
334     l_xpinfo->sel.dport_mask    = 0xFFFF;
335     l_xpinfo->sel.prefixlen_d   = 32;
336     l_xpinfo->sel.sport         = htons(src_port);
337     l_xpinfo->sel.sport_mask    = 0xFFFF;
338     l_xpinfo->sel.prefixlen_s   = 32;
339     l_xpinfo->sel.proto         = sel_proto;
340     l_xpinfo->sel.user          = htonl(xfrm_user_selector);
341
342     l_xpinfo->lft.soft_byte_limit   = XFRM_INF;
343     l_xpinfo->lft.hard_byte_limit   = XFRM_INF;
344     l_xpinfo->lft.soft_packet_limit = XFRM_INF;
345     l_xpinfo->lft.hard_packet_limit = XFRM_INF;
346     l_xpinfo->priority              = 2080;
347     l_xpinfo->action                = XFRM_POLICY_ALLOW;
348     l_xpinfo->share                 = XFRM_SHARE_ANY;
349
350     if (dir == IPSEC_POLICY_DIRECTION_IN) {
351         l_xpinfo->dir               = XFRM_POLICY_IN;
352     }
353     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
354         l_xpinfo->dir               = XFRM_POLICY_OUT;
355     }
356     else {
357         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
358         pkg_free(src_addr);
359         pkg_free(dest_addr);
360
361         return -3;
362     }
363
364
365     // xfrm_user_tmpl initialization
366     struct xfrm_user_tmpl* l_tmpl = (struct xfrm_user_tmpl*)l_tmpls_buf;
367     l_tmpl->id.proto    = IPPROTO_ESP;
368     l_tmpl->family      = AF_INET;
369     l_tmpl->reqid       = p_id;
370     l_tmpl->mode        = XFRM_MODE_TRANSPORT;
371     l_tmpl->aalgos      = (~(__u32)0);
372     l_tmpl->ealgos      = (~(__u32)0);
373     l_tmpl->calgos      = (~(__u32)0);
374
375
376     mnl_attr_put(l_nlh, XFRMA_TMPL, sizeof(struct xfrm_user_tmpl), l_tmpl);
377
378     if(mnl_socket_sendto(mnl_socket, l_nlh, l_nlh->nlmsg_len) < 0)
379     {
380         pkg_free(src_addr);
381         pkg_free(dest_addr);
382         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
383         return -4;
384     }
385
386     // char* ip addresses are no longer needed - free them
387     pkg_free(src_addr);
388     pkg_free(dest_addr);
389
390     return 0;
391 }
392
393 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)
394 {
395     unsigned sel_proto = 0;
396     if((sel_proto = kamailio_to_linux_proto(proto)) == IPPROTO_MAX) {
397         LM_ERR("Invalid port was passed to the function: %d\n", proto);
398         return -1;
399     }
400
401     unsigned char policy_dir = 0;
402
403     if(dir == IPSEC_POLICY_DIRECTION_IN) {
404          policy_dir = XFRM_POLICY_IN;
405     }
406     else if(dir == IPSEC_POLICY_DIRECTION_OUT) {
407          policy_dir = XFRM_POLICY_OUT;
408     }
409     else {
410         LM_ERR("Invalid direction parameter passed to add_policy: %d\n", dir);
411         return -1;
412     }
413
414     char* src_addr = NULL;
415     char* dest_addr = NULL;
416
417     // convert input IP addresses to char*
418     if((src_addr = pkg_malloc(src_addr_param.len+1)) == NULL) {
419         LM_ERR("Error allocating memory for src addr during SA removal\n");
420         return -1;
421     }
422
423     if((dest_addr = pkg_malloc(dest_addr_param.len+1)) == NULL) {
424         pkg_free(src_addr);
425         LM_ERR("Error allocating memory for dest addr during SA removal\n");
426         return -2;
427     }
428
429     memset(src_addr, 0, src_addr_param.len+1);
430     memset(dest_addr, 0, dest_addr_param.len+1);
431
432     memcpy(src_addr, src_addr_param.s, src_addr_param.len);
433     memcpy(dest_addr, dest_addr_param.s, dest_addr_param.len);
434
435     struct {
436         struct nlmsghdr n;
437         struct xfrm_userpolicy_id xpid;
438         char buf[XFRM_TMPLS_BUF_SIZE];
439     } req = {
440         .n.nlmsg_len = NLMSG_LENGTH(sizeof(req.xpid)),
441         .n.nlmsg_flags = NLM_F_REQUEST,
442         .n.nlmsg_type = XFRM_MSG_DELPOLICY,
443         .xpid.dir               = policy_dir,
444         .xpid.sel.family        = AF_INET,
445         .xpid.sel.daddr.a4      = inet_addr(dest_addr),
446         .xpid.sel.saddr.a4      = inet_addr(src_addr),
447         .xpid.sel.dport         = htons(dst_port),
448         .xpid.sel.dport_mask    = 0xFFFF,
449         .xpid.sel.prefixlen_d   = 32,
450         .xpid.sel.sport         = htons(src_port),
451         .xpid.sel.sport_mask    = 0xFFFF,
452         .xpid.sel.prefixlen_s   = 32,
453         .xpid.sel.proto         = sel_proto
454     };
455
456     if(mnl_socket_sendto(mnl_socket, &req.n, req.n.nlmsg_len) < 0)
457     {
458         LM_ERR("Failed to send Netlink message, error: %s\n", strerror(errno));
459         pkg_free(src_addr);
460         pkg_free(dest_addr);
461         return -1;
462     }
463
464     pkg_free(src_addr);
465     pkg_free(dest_addr);
466
467     return 0;
468 }
469
470 static int delsa_data_cb(const struct nlmsghdr *nlh, void *data)
471 {
472     struct xfrm_usersa_info *xsinfo = NLMSG_DATA(nlh);
473     int xfrm_userid = ntohl(xsinfo->sel.user);
474
475     //Check if user id is different from Kamailio's
476     if(xfrm_userid != xfrm_user_selector)
477         return MNL_CB_OK;
478
479     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
480     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_id));
481
482     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
483         LM_ERR("Not enough memory allocated for delete SAs netlink command\n");
484         return MNL_CB_ERROR;
485     }
486
487     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
488     new_delmsg->nlmsg_len = new_delmsg_len;
489     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
490     new_delmsg->nlmsg_type = XFRM_MSG_DELSA;
491     new_delmsg->nlmsg_seq = time(NULL);
492
493     struct xfrm_usersa_id *xsid = NLMSG_DATA(new_delmsg);
494     xsid->family = xsinfo->family;
495     memcpy(&xsid->daddr, &xsinfo->id.daddr, sizeof(xsid->daddr));
496     xsid->spi = xsinfo->id.spi;
497     xsid->proto = xsinfo->id.proto;
498
499     mnl_attr_put(new_delmsg, XFRMA_SRCADDR, sizeof(xsid->daddr), &xsinfo->saddr);
500
501     delmsg_buf->offset += new_delmsg->nlmsg_len;
502
503     return MNL_CB_OK;
504 }
505
506 static int delpolicy_data_cb(const struct nlmsghdr *nlh, void *data)
507 {
508     struct xfrm_userpolicy_info *xpinfo = NLMSG_DATA(nlh);
509     int xfrm_userid = ntohl(xpinfo->sel.user);
510
511     //Check if user id is different from Kamailio's
512     if(xfrm_userid != xfrm_user_selector)
513         return MNL_CB_OK;
514
515     struct xfrm_buffer* delmsg_buf = (struct xfrm_buffer*)data;
516     uint32_t new_delmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id));
517
518     if(delmsg_buf->offset + new_delmsg_len > sizeof(delmsg_buf->buf)/sizeof(delmsg_buf->buf[0])) {
519         LM_ERR("Not enough memory allocated for delete policies netlink command\n");
520         return MNL_CB_ERROR;
521     }
522
523     struct nlmsghdr *new_delmsg = (struct nlmsghdr *)&delmsg_buf->buf[delmsg_buf->offset];
524     new_delmsg->nlmsg_len = new_delmsg_len;
525     new_delmsg->nlmsg_flags = NLM_F_REQUEST;
526     new_delmsg->nlmsg_type = XFRM_MSG_DELPOLICY;
527     new_delmsg->nlmsg_seq = time(NULL);
528
529     struct xfrm_userpolicy_id *xpid = NLMSG_DATA(new_delmsg);
530     memcpy(&xpid->sel, &xpinfo->sel, sizeof(xpid->sel));
531     xpid->dir = xpinfo->dir;
532     xpid->index = xpinfo->index;
533
534     delmsg_buf->offset += new_delmsg->nlmsg_len;
535
536     return MNL_CB_OK;
537 }
538
539 int clean_sa(struct mnl_socket*  mnl_socket)
540 {
541     struct {
542         struct nlmsghdr n;
543         //char buf[NLMSG_BUF_SIZE];
544     } req = {
545         .n.nlmsg_len = NLMSG_HDRLEN,
546         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
547         .n.nlmsg_type = XFRM_MSG_GETSA,
548         .n.nlmsg_seq = time(NULL),
549     };
550
551     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
552         LM_ERR("Error sending get all SAs command via netlink socket: %s\n", strerror(errno));
553         return 1;
554     }
555
556     char buf[NLMSG_BUF_SIZE];
557     memset(&buf, 0, sizeof(buf));
558
559     struct xfrm_buffer delmsg_buf;
560     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
561
562     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
563     while (ret > 0) {
564         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delsa_data_cb, &delmsg_buf);
565         if (ret <= MNL_CB_STOP) {
566
567             break;
568         }
569         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
570     }
571
572     // DELETE SAs
573     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
574         LM_ERR("Error sending delete SAs command via netlink socket: %s\n", strerror(errno));
575         return 1;
576     }
577
578     return 0;
579 }
580
581 int clean_policy(struct mnl_socket*  mnl_socket)
582 {
583     struct {
584         struct nlmsghdr n;
585         //char buf[NLMSG_BUF_SIZE];
586     } req = {
587         .n.nlmsg_len = NLMSG_HDRLEN,
588         .n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
589         .n.nlmsg_type = XFRM_MSG_GETPOLICY,
590         .n.nlmsg_seq = time(NULL),
591     };
592
593     if(mnl_socket_sendto(mnl_socket, &req, req.n.nlmsg_len) == -1) {
594         LM_ERR("Error sending get all policies command via netlink socket: %s\n", strerror(errno));
595         return 1;
596     }
597
598     char buf[NLMSG_BUF_SIZE];
599     memset(&buf, 0, sizeof(buf));
600
601     struct xfrm_buffer delmsg_buf;
602     memset(&delmsg_buf, 0, sizeof(struct xfrm_buffer));
603
604     int ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
605     while (ret > 0) {
606         ret = mnl_cb_run(buf, ret, req.n.nlmsg_seq, mnl_socket_get_portid(mnl_socket), delpolicy_data_cb, &delmsg_buf);
607         if (ret <= MNL_CB_STOP) {
608
609             break;
610         }
611         ret = mnl_socket_recvfrom(mnl_socket, buf, sizeof(buf));
612     }
613
614     // DELETE POLICIES
615     if(mnl_socket_sendto(mnl_socket, &delmsg_buf.buf, delmsg_buf.offset) == -1) {
616         LM_ERR("Error sending delete policies command via netlink socket: %s\n", strerror(errno));
617         return 1;
618     }
619
620     return 0;
621 }