1df6ad731Slogwang /*
2*2317ada5Sfengbojiang * Copyright (C) 2017-2021 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
33df6ad731Slogwang int
sysctl(int * name,unsigned namelen,void * old,size_t * oldlenp,const void * new,size_t newlen)34df6ad731Slogwang sysctl(int *name, unsigned namelen, void *old,
35df6ad731Slogwang size_t *oldlenp, const void *new, size_t newlen)
36df6ad731Slogwang {
37df6ad731Slogwang struct ff_msg *msg, *retmsg = NULL;
3832ff8fdaSfengbojiang char *extra_buf = NULL;
3932ff8fdaSfengbojiang size_t total_len;
40df6ad731Slogwang
41df6ad731Slogwang if (old != NULL && oldlenp == NULL) {
42df6ad731Slogwang errno = EINVAL;
43df6ad731Slogwang return -1;
44df6ad731Slogwang }
45df6ad731Slogwang
46df6ad731Slogwang msg = ff_ipc_msg_alloc();
47df6ad731Slogwang if (msg == NULL) {
48df6ad731Slogwang errno = ENOMEM;
49df6ad731Slogwang return -1;
50df6ad731Slogwang }
51df6ad731Slogwang
52df6ad731Slogwang size_t oldlen = 0;
53df6ad731Slogwang if (old && oldlenp) {
54df6ad731Slogwang oldlen = *oldlenp;
55df6ad731Slogwang }
56df6ad731Slogwang
578d0052bcSfengbojiang total_len = namelen * sizeof(int) + sizeof(size_t) + oldlen + newlen;
581eaf0ac3Slogwang if (total_len > msg->buf_len) {
591eaf0ac3Slogwang extra_buf = rte_malloc(NULL, total_len, 0);
601eaf0ac3Slogwang if (extra_buf == NULL) {
611eaf0ac3Slogwang errno = ENOMEM;
62df6ad731Slogwang ff_ipc_msg_free(msg);
63df6ad731Slogwang return -1;
64df6ad731Slogwang }
6532ff8fdaSfengbojiang msg->original_buf = msg->buf_addr;
6632ff8fdaSfengbojiang msg->original_buf_len = msg->buf_len;
671eaf0ac3Slogwang msg->buf_addr = extra_buf;
681eaf0ac3Slogwang msg->buf_len = total_len;
691eaf0ac3Slogwang }
70df6ad731Slogwang
71df6ad731Slogwang char *buf_addr = msg->buf_addr;
72df6ad731Slogwang
73df6ad731Slogwang msg->msg_type = FF_SYSCTL;
74df6ad731Slogwang msg->sysctl.name = (int *)buf_addr;
75df6ad731Slogwang msg->sysctl.namelen = namelen;
76df6ad731Slogwang memcpy(msg->sysctl.name, name, namelen * sizeof(int));
77df6ad731Slogwang
78df6ad731Slogwang buf_addr += namelen * sizeof(int);
79df6ad731Slogwang
80df6ad731Slogwang if (new != NULL && newlen != 0) {
81df6ad731Slogwang msg->sysctl.new = buf_addr;
82df6ad731Slogwang msg->sysctl.newlen = newlen;
83df6ad731Slogwang memcpy(msg->sysctl.new, new, newlen);
84df6ad731Slogwang
85df6ad731Slogwang buf_addr += newlen;
86df6ad731Slogwang } else {
87df6ad731Slogwang msg->sysctl.new = NULL;
88df6ad731Slogwang msg->sysctl.newlen = 0;
89df6ad731Slogwang }
90df6ad731Slogwang
91df6ad731Slogwang if (oldlenp != NULL) {
92df6ad731Slogwang msg->sysctl.oldlenp = (size_t *)buf_addr;
93df6ad731Slogwang memcpy(msg->sysctl.oldlenp, oldlenp, sizeof(size_t));
94df6ad731Slogwang buf_addr += sizeof(size_t);
95df6ad731Slogwang
96df6ad731Slogwang if (old != NULL) {
97df6ad731Slogwang msg->sysctl.old = (void *)buf_addr;
98df6ad731Slogwang memcpy(msg->sysctl.old, old, *oldlenp);
99df6ad731Slogwang buf_addr += *oldlenp;
100df6ad731Slogwang } else {
101df6ad731Slogwang msg->sysctl.old = NULL;
102df6ad731Slogwang }
103df6ad731Slogwang } else {
104df6ad731Slogwang msg->sysctl.oldlenp = NULL;
105df6ad731Slogwang msg->sysctl.old = NULL;
106df6ad731Slogwang }
107df6ad731Slogwang
108df6ad731Slogwang int ret = ff_ipc_send(msg);
109df6ad731Slogwang if (ret < 0) {
110df6ad731Slogwang errno = EPIPE;
11173e135b8Sfengbojiang(姜凤波) goto error;
112df6ad731Slogwang }
113df6ad731Slogwang
114df6ad731Slogwang do {
115df6ad731Slogwang if (retmsg != NULL) {
1168d0052bcSfengbojiang ff_ipc_msg_free(retmsg);
117df6ad731Slogwang }
1186194fcd2Sfengbojiang(姜凤波) ret = ff_ipc_recv(&retmsg, msg->msg_type);
119df6ad731Slogwang if (ret < 0) {
120df6ad731Slogwang errno = EPIPE;
12132ff8fdaSfengbojiang return -1;
122df6ad731Slogwang }
123df6ad731Slogwang } while (msg != retmsg);
124df6ad731Slogwang
125df6ad731Slogwang if (retmsg->result == 0) {
126df6ad731Slogwang ret = 0;
127df6ad731Slogwang if (oldlenp && retmsg->sysctl.oldlenp) {
128df6ad731Slogwang *oldlenp = *retmsg->sysctl.oldlenp;
129df6ad731Slogwang }
130df6ad731Slogwang
131df6ad731Slogwang if (old && retmsg->sysctl.old && oldlenp) {
132df6ad731Slogwang memcpy(old, retmsg->sysctl.old, *oldlenp);
133df6ad731Slogwang }
134df6ad731Slogwang } else {
135df6ad731Slogwang ret = -1;
136df6ad731Slogwang errno = retmsg->result;
137df6ad731Slogwang }
138df6ad731Slogwang
13973e135b8Sfengbojiang(姜凤波) error:
1408d0052bcSfengbojiang ff_ipc_msg_free(msg);
141df6ad731Slogwang
142df6ad731Slogwang return ret;
143df6ad731Slogwang }
144