summaryrefslogtreecommitdiff
path: root/lib/mgmt_msg.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mgmt_msg.h')
-rw-r--r--lib/mgmt_msg.h162
1 files changed, 148 insertions, 14 deletions
diff --git a/lib/mgmt_msg.h b/lib/mgmt_msg.h
index e2dd2d476a..6bdc9a6cfc 100644
--- a/lib/mgmt_msg.h
+++ b/lib/mgmt_msg.h
@@ -7,10 +7,25 @@
#ifndef _MGMT_MSG_H
#define _MGMT_MSG_H
+#include "memory.h"
#include "stream.h"
#include "frrevent.h"
-#define MGMT_MSG_MARKER (0x4D724B21u) /* ASCII - "MrK!"*/
+DECLARE_MTYPE(MSG_CONN);
+
+/*
+ * Messages on the stream start with a marker that encodes a version octet.
+ */
+#define MGMT_MSG_MARKER_PFX (0x23232300u) /* ASCII - "###\ooo"*/
+#define MGMT_MSG_IS_MARKER(x) (((x)&0xFFFFFF00u) == MGMT_MSG_MARKER_PFX)
+#define MGMT_MSG_MARKER(version) (MGMT_MSG_MARKER_PFX | (version))
+#define MGMT_MSG_MARKER_VERSION(x) (0xFF & (x))
+
+#define MGMT_MSG_VERSION_PROTOBUF 0
+#define MGMT_MSG_VERSION_NATIVE 1
+
+/* The absolute maximum message size (16MB) */
+#define MGMT_MSG_MAX_MSG_ALLOC_LEN (16 * 1024 * 1024)
struct mgmt_msg_state {
struct stream *ins;
@@ -41,33 +56,152 @@ enum mgmt_msg_rsched {
enum mgmt_msg_wsched {
MSW_SCHED_NONE, /* no scheduling required */
MSW_SCHED_STREAM, /* schedule writing */
- MSW_SCHED_WRITES_OFF, /* toggle writes off */
MSW_DISCONNECT, /* disconnect and start reconnecting */
};
-static inline uint8_t *msg_payload(struct mgmt_msg_hdr *mhdr)
-{
- return (uint8_t *)(mhdr + 1);
-}
+struct msg_conn;
-typedef size_t (*mgmt_msg_packf)(void *msg, void *data);
extern int mgmt_msg_connect(const char *path, size_t sendbuf, size_t recvbuf,
const char *dbgtag);
-extern void mgmt_msg_destroy(struct mgmt_msg_state *ms);
-extern void mgmt_msg_init(struct mgmt_msg_state *ms, size_t max_read_buf,
- size_t max_write_buf, size_t max_msg_sz,
- const char *idtag);
extern bool mgmt_msg_procbufs(struct mgmt_msg_state *ms,
- void (*handle_msg)(void *user, uint8_t *msg,
- size_t msglen),
+ void (*handle_msg)(uint8_t version, uint8_t *msg,
+ size_t msglen, void *user),
void *user, bool debug);
extern enum mgmt_msg_rsched mgmt_msg_read(struct mgmt_msg_state *ms, int fd,
bool debug);
extern size_t mgmt_msg_reset_writes(struct mgmt_msg_state *ms);
-extern int mgmt_msg_send_msg(struct mgmt_msg_state *ms, void *msg, size_t len,
+extern int mgmt_msg_send_msg(struct mgmt_msg_state *ms, uint8_t version,
+ void *msg, size_t len,
size_t (*packf)(void *msg, void *buf), bool debug);
extern enum mgmt_msg_wsched mgmt_msg_write(struct mgmt_msg_state *ms, int fd,
bool debug);
+extern void mgmt_msg_destroy(struct mgmt_msg_state *state);
+
+extern void mgmt_msg_init(struct mgmt_msg_state *ms, size_t max_read_buf,
+ size_t max_write_buf, size_t max_msg_sz,
+ const char *idtag);
+
+/*
+ * Connections
+ */
+
+struct msg_conn {
+ int fd;
+ struct mgmt_msg_state mstate;
+ struct event_loop *loop;
+ struct event *read_ev;
+ struct event *write_ev;
+ struct event *proc_msg_ev;
+ struct msg_conn *remote_conn;
+ int (*notify_disconnect)(struct msg_conn *conn);
+ void (*handle_msg)(uint8_t version, uint8_t *data, size_t len,
+ struct msg_conn *conn);
+ void *user;
+ uint short_circuit_depth;
+ bool is_short_circuit; /* true when the message being handled is SC */
+ bool is_client;
+ bool debug;
+};
+
+
+/*
+ * `notify_disconnect` is not called when `msg_conn_cleanup` is called for a
+ * msg_conn which is currently connected. The socket is closed but there is no
+ * notification.
+ */
+extern void msg_conn_cleanup(struct msg_conn *conn);
+extern void msg_conn_disconnect(struct msg_conn *conn, bool reconnect);
+extern int msg_conn_send_msg(struct msg_conn *client, uint8_t version,
+ void *msg, size_t mlen,
+ size_t (*packf)(void *, void *),
+ bool short_circuit_ok);
+
+/*
+ * Client-side Connections
+ */
+
+struct msg_client {
+ struct msg_conn conn;
+ struct event *conn_retry_tmr;
+ char *sopath;
+ int (*notify_connect)(struct msg_client *client);
+ bool short_circuit_ok;
+};
+
+/*
+ * `notify_disconnect` is not called when `msg_client_cleanup` is called for a
+ * msg_client which is currently connected. The socket is closed but there is no
+ * notification.
+ */
+extern void msg_client_cleanup(struct msg_client *client);
+
+/*
+ * If `short_circuit_ok` is true, then the client-server connection will use a
+ * socketpair() rather than a unix-domain socket. This must be passed true if
+ * you wish to send messages short-circuit later.
+ *
+ * `notify_disconnect` is not called when the user `msg_client_cleanup` is
+ * called for a client which is currently connected. The socket is closed
+ * but there is no notification.
+ */
+extern void
+msg_client_init(struct msg_client *client, struct event_loop *tm,
+ const char *sopath,
+ int (*notify_connect)(struct msg_client *client),
+ int (*notify_disconnect)(struct msg_conn *client),
+ void (*handle_msg)(uint8_t version, uint8_t *data, size_t len,
+ struct msg_conn *client),
+ size_t max_read_buf, size_t max_write_buf, size_t max_msg_sz,
+ bool short_circuit_ok, const char *idtag, bool debug);
+
+/*
+ * Server-side Connections
+ */
+#define MGMTD_MAX_CONN 32
+
+PREDECL_LIST(msg_server_list);
+
+struct msg_server {
+ int fd;
+ struct msg_server_list_item link;
+ struct event_loop *loop;
+ struct event *listen_ev;
+ const char *sopath;
+ const char *idtag;
+ struct msg_conn *(*create)(int fd, union sockunion *su);
+ struct debug *debug;
+};
+
+extern int msg_server_init(struct msg_server *server, const char *sopath,
+ struct event_loop *loop,
+ struct msg_conn *(*create)(int fd,
+ union sockunion *su),
+ const char *idtag, struct debug *debug);
+extern void msg_server_cleanup(struct msg_server *server);
+
+/*
+ * `notify_disconnect` is not called when the user `msg_conn_cleanup` is
+ * called for a client which is currently connected. The socket is closed
+ * but there is no notification.
+ */
+struct msg_conn *
+msg_server_conn_create(struct event_loop *tm, int fd,
+ int (*notify_disconnect)(struct msg_conn *conn),
+ void (*handle_msg)(uint8_t version, uint8_t *data,
+ size_t len, struct msg_conn *conn),
+ size_t max_read, size_t max_write, size_t max_size,
+ void *user, const char *idtag);
+
+extern void msg_server_conn_delete(struct msg_conn *conn);
+
+extern void
+msg_conn_accept_init(struct msg_conn *conn, struct event_loop *tm, int fd,
+ int (*notify_disconnect)(struct msg_conn *conn),
+ void (*handle_msg)(uint8_t version, uint8_t *data,
+ size_t len, struct msg_conn *conn),
+ size_t max_read, size_t max_write, size_t max_size,
+ const char *idtag);
+
#endif /* _MGMT_MSG_H */