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