xref: /f-stack/tools/compat/sysctl.c (revision 32ff8fda)
1df6ad731Slogwang /*
2df6ad731Slogwang  * Copyright (C) 2017 THL A29 Limited, a Tencent company.
3df6ad731Slogwang  * All rights reserved.
4df6ad731Slogwang  *
5df6ad731Slogwang  * Redistribution and use in source and binary forms, with or without
6df6ad731Slogwang  * modification, are permitted provided that the following conditions are met:
7df6ad731Slogwang  *
8df6ad731Slogwang  * 1. Redistributions of source code must retain the above copyright notice, this
9df6ad731Slogwang  *   list of conditions and the following disclaimer.
10df6ad731Slogwang  * 2. Redistributions in binary form must reproduce the above copyright notice,
11df6ad731Slogwang  *   this list of conditions and the following disclaimer in the documentation
12df6ad731Slogwang  *   and/or other materials provided with the distribution.
13df6ad731Slogwang  *
14df6ad731Slogwang  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15df6ad731Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16df6ad731Slogwang  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17df6ad731Slogwang  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18df6ad731Slogwang  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19df6ad731Slogwang  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20df6ad731Slogwang  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21df6ad731Slogwang  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22df6ad731Slogwang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23df6ad731Slogwang  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24df6ad731Slogwang  *
25df6ad731Slogwang  */
26df6ad731Slogwang 
27df6ad731Slogwang #include <string.h>
28127dd473Swhl739 #include <sys/socket.h>
291eaf0ac3Slogwang #include <rte_malloc.h>
30df6ad731Slogwang 
31df6ad731Slogwang #include "ff_ipc.h"
32df6ad731Slogwang 
33*32ff8fdaSfengbojiang #define FREE_FF_MSG(m) do { \
34*32ff8fdaSfengbojiang         if (m->original_buf) { \
35*32ff8fdaSfengbojiang             rte_free(m->buf_addr); \
36*32ff8fdaSfengbojiang             m->buf_addr = m->original_buf; \
37*32ff8fdaSfengbojiang             m->buf_len = m->original_buf_len; \
38*32ff8fdaSfengbojiang             m->original_buf = NULL; \
39*32ff8fdaSfengbojiang         } \
40*32ff8fdaSfengbojiang         ff_ipc_msg_free(m); \
41*32ff8fdaSfengbojiang     } while (0);
42*32ff8fdaSfengbojiang 
43df6ad731Slogwang int
44df6ad731Slogwang sysctl(int *name, unsigned namelen, void *old,
45df6ad731Slogwang     size_t *oldlenp, const void *new, size_t newlen)
46df6ad731Slogwang {
47df6ad731Slogwang     struct ff_msg *msg, *retmsg = NULL;
48*32ff8fdaSfengbojiang     char *extra_buf = NULL;
49*32ff8fdaSfengbojiang     size_t total_len;
50df6ad731Slogwang 
51df6ad731Slogwang     if (old != NULL && oldlenp == NULL) {
52df6ad731Slogwang         errno = EINVAL;
53df6ad731Slogwang         return -1;
54df6ad731Slogwang     }
55df6ad731Slogwang 
56df6ad731Slogwang     msg = ff_ipc_msg_alloc();
57df6ad731Slogwang     if (msg == NULL) {
58df6ad731Slogwang         errno = ENOMEM;
59df6ad731Slogwang         return -1;
60df6ad731Slogwang     }
61df6ad731Slogwang 
62df6ad731Slogwang     size_t oldlen = 0;
63df6ad731Slogwang     if (old && oldlenp) {
64df6ad731Slogwang         oldlen = *oldlenp;
65df6ad731Slogwang     }
66df6ad731Slogwang 
671eaf0ac3Slogwang     total_len = namelen + oldlen + newlen;
681eaf0ac3Slogwang     if (total_len > msg->buf_len) {
691eaf0ac3Slogwang         extra_buf = rte_malloc(NULL, total_len, 0);
701eaf0ac3Slogwang         if (extra_buf == NULL) {
711eaf0ac3Slogwang             errno = ENOMEM;
72df6ad731Slogwang             ff_ipc_msg_free(msg);
73df6ad731Slogwang             return -1;
74df6ad731Slogwang         }
75*32ff8fdaSfengbojiang         msg->original_buf = msg->buf_addr;
76*32ff8fdaSfengbojiang         msg->original_buf_len = msg->buf_len;
771eaf0ac3Slogwang         msg->buf_addr = extra_buf;
781eaf0ac3Slogwang         msg->buf_len = total_len;
791eaf0ac3Slogwang     }
80df6ad731Slogwang 
81df6ad731Slogwang     char *buf_addr = msg->buf_addr;
82df6ad731Slogwang 
83df6ad731Slogwang     msg->msg_type = FF_SYSCTL;
84df6ad731Slogwang     msg->sysctl.name = (int *)buf_addr;
85df6ad731Slogwang     msg->sysctl.namelen = namelen;
86df6ad731Slogwang     memcpy(msg->sysctl.name, name, namelen * sizeof(int));
87df6ad731Slogwang 
88df6ad731Slogwang     buf_addr += namelen * sizeof(int);
89df6ad731Slogwang 
90df6ad731Slogwang     if (new != NULL && newlen != 0) {
91df6ad731Slogwang         msg->sysctl.new = buf_addr;
92df6ad731Slogwang         msg->sysctl.newlen = newlen;
93df6ad731Slogwang         memcpy(msg->sysctl.new, new, newlen);
94df6ad731Slogwang 
95df6ad731Slogwang         buf_addr += newlen;
96df6ad731Slogwang     } else {
97df6ad731Slogwang         msg->sysctl.new = NULL;
98df6ad731Slogwang         msg->sysctl.newlen = 0;
99df6ad731Slogwang     }
100df6ad731Slogwang 
101df6ad731Slogwang     if (oldlenp != NULL) {
102df6ad731Slogwang         msg->sysctl.oldlenp = (size_t *)buf_addr;
103df6ad731Slogwang         memcpy(msg->sysctl.oldlenp, oldlenp, sizeof(size_t));
104df6ad731Slogwang         buf_addr += sizeof(size_t);
105df6ad731Slogwang 
106df6ad731Slogwang         if (old != NULL) {
107df6ad731Slogwang             msg->sysctl.old = (void *)buf_addr;
108df6ad731Slogwang             memcpy(msg->sysctl.old, old, *oldlenp);
109df6ad731Slogwang             buf_addr += *oldlenp;
110df6ad731Slogwang         } else {
111df6ad731Slogwang             msg->sysctl.old = NULL;
112df6ad731Slogwang         }
113df6ad731Slogwang     } else {
114df6ad731Slogwang         msg->sysctl.oldlenp = NULL;
115df6ad731Slogwang         msg->sysctl.old = NULL;
116df6ad731Slogwang     }
117df6ad731Slogwang 
118df6ad731Slogwang     int ret = ff_ipc_send(msg);
119df6ad731Slogwang     if (ret < 0) {
120df6ad731Slogwang         errno = EPIPE;
12173e135b8Sfengbojiang(姜凤波)         goto error;
122df6ad731Slogwang     }
123df6ad731Slogwang 
124df6ad731Slogwang     do {
125df6ad731Slogwang         if (retmsg != NULL) {
126*32ff8fdaSfengbojiang             FREE_FF_MSG(retmsg)
127df6ad731Slogwang         }
1286194fcd2Sfengbojiang(姜凤波)         ret = ff_ipc_recv(&retmsg, msg->msg_type);
129df6ad731Slogwang         if (ret < 0) {
130df6ad731Slogwang             errno = EPIPE;
131*32ff8fdaSfengbojiang             return -1;
132df6ad731Slogwang         }
133df6ad731Slogwang     } while (msg != retmsg);
134df6ad731Slogwang 
135df6ad731Slogwang     if (retmsg->result == 0) {
136df6ad731Slogwang         ret = 0;
137df6ad731Slogwang         if (oldlenp && retmsg->sysctl.oldlenp) {
138df6ad731Slogwang             *oldlenp = *retmsg->sysctl.oldlenp;
139df6ad731Slogwang         }
140df6ad731Slogwang 
141df6ad731Slogwang         if (old && retmsg->sysctl.old && oldlenp) {
142df6ad731Slogwang             memcpy(old, retmsg->sysctl.old, *oldlenp);
143df6ad731Slogwang         }
144df6ad731Slogwang     } else {
145df6ad731Slogwang         ret = -1;
146df6ad731Slogwang         errno = retmsg->result;
147df6ad731Slogwang     }
148df6ad731Slogwang 
14973e135b8Sfengbojiang(姜凤波) error:
150*32ff8fdaSfengbojiang     FREE_FF_MSG(msg)
151df6ad731Slogwang 
152df6ad731Slogwang     return ret;
153df6ad731Slogwang }
154