]> git.proxmox.com Git - mirror_frr.git/blob - lib/mgmt_msg.h
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / mgmt_msg.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * March 6 2023, Christian Hopps <chopps@labn.net>
4 *
5 * Copyright (c) 2023, LabN Consulting, L.L.C.
6 */
7 #ifndef _MGMT_MSG_H
8 #define _MGMT_MSG_H
9
10 #include "memory.h"
11 #include "stream.h"
12 #include "frrevent.h"
13
14 DECLARE_MTYPE(MSG_CONN);
15
16 /*
17 * Messages on the stream start with a marker that encodes a version octet.
18 */
19 #define MGMT_MSG_MARKER_PFX (0x23232300u) /* ASCII - "###\ooo"*/
20 #define MGMT_MSG_IS_MARKER(x) (((x)&0xFFFFFF00u) == MGMT_MSG_MARKER_PFX)
21 #define MGMT_MSG_MARKER(version) (MGMT_MSG_MARKER_PFX | (version))
22 #define MGMT_MSG_MARKER_VERSION(x) (0xFF & (x))
23
24 #define MGMT_MSG_VERSION_PROTOBUF 0
25 #define MGMT_MSG_VERSION_NATIVE 1
26
27
28 struct mgmt_msg_state {
29 struct stream *ins;
30 struct stream *outs;
31 struct stream_fifo inq;
32 struct stream_fifo outq;
33 uint64_t nrxm; /* number of received messages */
34 uint64_t nrxb; /* number of received bytes */
35 uint64_t ntxm; /* number of sent messages */
36 uint64_t ntxb; /* number of sent bytes */
37 size_t max_read_buf; /* should replace with max time value */
38 size_t max_write_buf; /* should replace with max time value */
39 size_t max_msg_sz;
40 char *idtag; /* identifying tag for messages */
41 };
42
43 struct mgmt_msg_hdr {
44 uint32_t marker;
45 uint32_t len;
46 };
47
48 enum mgmt_msg_rsched {
49 MSR_SCHED_BOTH, /* schedule both queue and read */
50 MSR_SCHED_STREAM, /* schedule read */
51 MSR_DISCONNECT, /* disconnect and start reconnecting */
52 };
53
54 enum mgmt_msg_wsched {
55 MSW_SCHED_NONE, /* no scheduling required */
56 MSW_SCHED_STREAM, /* schedule writing */
57 MSW_DISCONNECT, /* disconnect and start reconnecting */
58 };
59
60 struct msg_conn;
61
62
63 extern int mgmt_msg_connect(const char *path, size_t sendbuf, size_t recvbuf,
64 const char *dbgtag);
65 extern bool mgmt_msg_procbufs(struct mgmt_msg_state *ms,
66 void (*handle_msg)(uint8_t version, uint8_t *msg,
67 size_t msglen, void *user),
68 void *user, bool debug);
69 extern enum mgmt_msg_rsched mgmt_msg_read(struct mgmt_msg_state *ms, int fd,
70 bool debug);
71 extern size_t mgmt_msg_reset_writes(struct mgmt_msg_state *ms);
72 extern int mgmt_msg_send_msg(struct mgmt_msg_state *ms, uint8_t version,
73 void *msg, size_t len,
74 size_t (*packf)(void *msg, void *buf), bool debug);
75 extern enum mgmt_msg_wsched mgmt_msg_write(struct mgmt_msg_state *ms, int fd,
76 bool debug);
77
78 extern void mgmt_msg_destroy(struct mgmt_msg_state *state);
79
80 extern void mgmt_msg_init(struct mgmt_msg_state *ms, size_t max_read_buf,
81 size_t max_write_buf, size_t max_msg_sz,
82 const char *idtag);
83
84 /*
85 * Connections
86 */
87
88 struct msg_conn {
89 int fd;
90 struct mgmt_msg_state mstate;
91 struct event_loop *loop;
92 struct event *read_ev;
93 struct event *write_ev;
94 struct event *proc_msg_ev;
95 struct msg_conn *remote_conn;
96 int (*notify_disconnect)(struct msg_conn *conn);
97 void (*handle_msg)(uint8_t version, uint8_t *data, size_t len,
98 struct msg_conn *conn);
99 void *user;
100 uint short_circuit_depth;
101 bool is_client;
102 bool is_short_circuit;
103 bool debug;
104 };
105
106
107 /*
108 * `notify_disconnect` is not called when `msg_conn_cleanup` is called for a
109 * msg_conn which is currently connected. The socket is closed but there is no
110 * notification.
111 */
112 extern void msg_conn_cleanup(struct msg_conn *conn);
113 extern void msg_conn_disconnect(struct msg_conn *conn, bool reconnect);
114 extern int msg_conn_send_msg(struct msg_conn *client, uint8_t version,
115 void *msg, size_t mlen,
116 size_t (*packf)(void *, void *),
117 bool short_circuit_ok);
118
119 /*
120 * Client-side Connections
121 */
122
123 struct msg_client {
124 struct msg_conn conn;
125 struct event *conn_retry_tmr;
126 char *sopath;
127 int (*notify_connect)(struct msg_client *client);
128 bool short_circuit_ok;
129 };
130
131 /*
132 * `notify_disconnect` is not called when `msg_client_cleanup` is called for a
133 * msg_client which is currently connected. The socket is closed but there is no
134 * notification.
135 */
136 extern void msg_client_cleanup(struct msg_client *client);
137
138 /*
139 * `notify_disconnect` is not called when the user `msg_client_cleanup` is
140 * called for a client which is currently connected. The socket is closed
141 * but there is no notification.
142 */
143 extern void
144 msg_client_init(struct msg_client *client, struct event_loop *tm,
145 const char *sopath,
146 int (*notify_connect)(struct msg_client *client),
147 int (*notify_disconnect)(struct msg_conn *client),
148 void (*handle_msg)(uint8_t version, uint8_t *data, size_t len,
149 struct msg_conn *client),
150 size_t max_read_buf, size_t max_write_buf, size_t max_msg_sz,
151 bool short_circuit_ok, const char *idtag, bool debug);
152
153 /*
154 * Server-side Connections
155 */
156 #define MGMTD_MAX_CONN 32
157
158 PREDECL_LIST(msg_server_list);
159
160 struct msg_server {
161 int fd;
162 struct msg_server_list_item link;
163 struct event_loop *loop;
164 struct event *listen_ev;
165 const char *sopath;
166 const char *idtag;
167 struct msg_conn *(*create)(int fd, union sockunion *su);
168 struct debug *debug;
169 };
170
171 extern int msg_server_init(struct msg_server *server, const char *sopath,
172 struct event_loop *loop,
173 struct msg_conn *(*create)(int fd,
174 union sockunion *su),
175 const char *idtag, struct debug *debug);
176 extern void msg_server_cleanup(struct msg_server *server);
177
178 /*
179 * `notify_disconnect` is not called when the user `msg_conn_cleanup` is
180 * called for a client which is currently connected. The socket is closed
181 * but there is no notification.
182 */
183 struct msg_conn *
184 msg_server_conn_create(struct event_loop *tm, int fd,
185 int (*notify_disconnect)(struct msg_conn *conn),
186 void (*handle_msg)(uint8_t version, uint8_t *data,
187 size_t len, struct msg_conn *conn),
188 size_t max_read, size_t max_write, size_t max_size,
189 void *user, const char *idtag);
190
191 extern void msg_server_conn_delete(struct msg_conn *conn);
192
193 extern void
194 msg_conn_accept_init(struct msg_conn *conn, struct event_loop *tm, int fd,
195 int (*notify_disconnect)(struct msg_conn *conn),
196 void (*handle_msg)(uint8_t version, uint8_t *data,
197 size_t len, struct msg_conn *conn),
198 size_t max_read, size_t max_write, size_t max_size,
199 const char *idtag);
200
201 #endif /* _MGMT_MSG_H */