xref: /f-stack/tools/README.md (revision 2d99e60c)
1# Introduction
2
3Directory `ipc` implements an ipc library using dpdk `rte_ring`, can be used to communicate with F-Stack processes.
4
5All other directories are useful tools ported from FreeBSD.
6
7# ipc
8
9This is a simple implemention using dpdk `rte_ring`.
10```
11ff_ipc_msg_alloc: get msg structure from rte_mempool.
12ff_ipc_msg_free: put msg to rte_mempool.
13ff_ipc_send: enqueue msg to rte_ring.
14ff_ipc_recv: dequeue msg from rte_ring.
15```
16
17Since F-Stack is multi-process architecture and every process has an independent stack, so we must communicate with every F-Stack process.
18
19# sysctl
20Usage:
21```
22sysctl -p <f-stack proc_id> [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...
23sysctl -p <f-stack proc_id> [-bdehNnoqTtWx] [ -B <bufsize> ] -a
24```
25
26```
27-p   Which F-Stack process to communicate with, default 0.
28```
29
30Except this option, it is same with the original FreeBSD sysctl, see [Manual page](https://www.freebsd.org/cgi/man.cgi?sysctl).
31
32# how to implement a custom tool for communicating with F-Stack process
33
34Add a new FF_MSG_TYPE in ff_msg.h:
35```
36enum FF_MSG_TYPE {
37    FF_UNKNOWN = 0,
38    FF_SYSCTL,
39    FF_HELLOWORLD,
40};
41```
42
43Define a structure used to communicate:
44```
45struct ff_helloworld_args {
46    void *request;
47    size_t req_len;
48    void *reply;
49    size_t rep_len;
50};
51```
52Note that, when using struct ff_helloworld_args, pointers in this structure must point to the addresses range from ff_msg.buf_addr and ff_msg.buf_addr+ff_msg.buf_len, ff_msg.buf_len is (10240 - sizeof(struct ff_msg)).
53
54And add it to ff_msg:
55```
56struct ff_msg {
57    ...
58    union {
59        struct ff_sysctl_args sysctl;
60        struct ff_helloworld_args helloworld;
61    };
62};
63```
64
65Modify ff_dpdk_if.c, add a handle function:
66```
67static inline void
68handle_helloworld_msg(struct ff_msg *msg, uint16_t proc_id)
69{
70    printf("helloworld msg recved.\n");
71    msg->result = 0;
72    rte_ring_enqueue(msg_ring[proc_id].ring[1], msg);
73}
74
75static inline void
76handle_msg(struct ff_msg *msg, uint16_t proc_id)
77{
78    switch (msg->msg_type) {
79        case FF_SYSCTL:
80            handle_sysctl_msg(msg, proc_id);
81            break;
82        case FF_HELLOWORLD:
83            handle_helloworld_msg(msg, proc_id);
84        default:
85            handle_default_msg(msg, proc_id);
86            break;
87    }
88}
89```
90
91Create helloworld.c:
92
93```
94int main()
95{
96    struct ff_msg *msg = ff_ipc_msg_alloc();
97
98    char *buf = msg->buf_addr;
99
100    msg->helloworld.request = buf;
101    memcpy(msg->helloworld.request, "hello", 5);
102    msg->helloworld.req_len = 5;
103    buf += 5;
104
105    msg->helloworld.reply = buf;
106    msg->helloworld.rep_len = 10;
107
108    ff_ipc_send(msg, 0);
109
110    struct ff_msg *retmsg;
111    ff_ipc_recv(retmsg, 0);
112    assert(remsg==msg);
113
114    ff_ipc_msg_free(msg);
115}
116
117```
118
119The Makefile may like this:
120```
121TOPDIR?=${CURDIR}/../..
122
123PROG=helloworld
124
125include ${TOPDIR}/tools/prog.mk
126```
127