]> git.proxmox.com Git - mirror_frr.git/blob - mgmtd/mgmt_be_server.c
Merge pull request #13455 from sri-mohan1/srib-ldpd
[mirror_frr.git] / mgmtd / mgmt_be_server.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * MGMTD Backend Server
4 *
5 * Copyright (C) 2021 Vmware, Inc.
6 * Pushpasis Sarkar <spushpasis@vmware.com>
7 */
8
9 #include <zebra.h>
10 #include "network.h"
11 #include "libfrr.h"
12 #include "mgmtd/mgmt.h"
13 #include "mgmtd/mgmt_be_server.h"
14 #include "mgmtd/mgmt_be_adapter.h"
15
16 #define MGMTD_BE_SRVR_DBG(fmt, ...) \
17 DEBUGD(&mgmt_debug_be, "%s:" fmt, __func__, ##__VA_ARGS__)
18 #define MGMTD_BE_SRVR_ERR(fmt, ...) \
19 zlog_err("%s: ERROR: " fmt, __func__, ##__VA_ARGS__)
20
21 static int mgmt_be_listen_fd = -1;
22 static struct event_loop *mgmt_be_listen_tm;
23 static struct event *mgmt_be_listen_ev;
24 static void mgmt_be_server_register_event(enum mgmt_be_event event);
25
26 static void mgmt_be_conn_accept(struct event *thread)
27 {
28 int client_conn_fd;
29 union sockunion su;
30
31 if (mgmt_be_listen_fd < 0)
32 return;
33
34 /* We continue hearing server listen socket. */
35 mgmt_be_server_register_event(MGMTD_BE_SERVER);
36
37 memset(&su, 0, sizeof(union sockunion));
38
39 /* We can handle IPv4 or IPv6 socket. */
40 client_conn_fd = sockunion_accept(mgmt_be_listen_fd, &su);
41 if (client_conn_fd < 0) {
42 MGMTD_BE_SRVR_ERR(
43 "Failed to accept MGMTD Backend client connection : %s",
44 safe_strerror(errno));
45 return;
46 }
47 set_nonblocking(client_conn_fd);
48 set_cloexec(client_conn_fd);
49
50 MGMTD_BE_SRVR_DBG("Got a new MGMTD Backend connection");
51
52 mgmt_be_create_adapter(client_conn_fd, &su);
53 }
54
55 static void mgmt_be_server_register_event(enum mgmt_be_event event)
56 {
57 if (event == MGMTD_BE_SERVER) {
58 event_add_read(mgmt_be_listen_tm, mgmt_be_conn_accept,
59 NULL, mgmt_be_listen_fd,
60 &mgmt_be_listen_ev);
61 assert(mgmt_be_listen_ev);
62 } else {
63 assert(!"mgmt_be_server_post_event() called incorrectly");
64 }
65 }
66
67 static void mgmt_be_server_start(const char *hostname)
68 {
69 int ret;
70 int sock;
71 struct sockaddr_un addr;
72 mode_t old_mask;
73
74 /* Set umask */
75 old_mask = umask(0077);
76
77 sock = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC);
78 if (sock < 0) {
79 MGMTD_BE_SRVR_ERR("Failed to create server socket: %s",
80 safe_strerror(errno));
81 goto mgmt_be_server_start_failed;
82 }
83
84 addr.sun_family = AF_UNIX,
85 strlcpy(addr.sun_path, MGMTD_BE_SERVER_PATH, sizeof(addr.sun_path));
86 unlink(addr.sun_path);
87 ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
88 if (ret < 0) {
89 MGMTD_BE_SRVR_ERR(
90 "Failed to bind server socket to '%s'. Err: %s",
91 addr.sun_path, safe_strerror(errno));
92 goto mgmt_be_server_start_failed;
93 }
94
95 ret = listen(sock, MGMTD_BE_MAX_CONN);
96 if (ret < 0) {
97 MGMTD_BE_SRVR_ERR("Failed to listen on server socket: %s",
98 safe_strerror(errno));
99 goto mgmt_be_server_start_failed;
100 }
101
102 /* Restore umask */
103 umask(old_mask);
104
105 mgmt_be_listen_fd = sock;
106 mgmt_be_server_register_event(MGMTD_BE_SERVER);
107
108 MGMTD_BE_SRVR_DBG("Started MGMTD Backend Server!");
109 return;
110
111 mgmt_be_server_start_failed:
112 if (sock > 0)
113 close(sock);
114
115 mgmt_be_listen_fd = -1;
116 exit(-1);
117 }
118
119 int mgmt_be_server_init(struct event_loop *master)
120 {
121 if (mgmt_be_listen_tm) {
122 MGMTD_BE_SRVR_DBG("MGMTD Backend Server already running!");
123 return 0;
124 }
125
126 mgmt_be_listen_tm = master;
127
128 mgmt_be_server_start("localhost");
129
130 return 0;
131 }
132
133 void mgmt_be_server_destroy(void)
134 {
135 if (mgmt_be_listen_tm) {
136 MGMTD_BE_SRVR_DBG("Closing MGMTD Backend Server!");
137
138 if (mgmt_be_listen_ev) {
139 EVENT_OFF(mgmt_be_listen_ev);
140 mgmt_be_listen_ev = NULL;
141 }
142
143 if (mgmt_be_listen_fd >= 0) {
144 close(mgmt_be_listen_fd);
145 mgmt_be_listen_fd = -1;
146 }
147
148 mgmt_be_listen_tm = NULL;
149 }
150 }