Annotation of embedaddon/dnsmasq/src/ubus.c, revision 1.1.1.1
1.1 misho 1: /* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
2:
3: This program is free software; you can redistribute it and/or modify
4: it under the terms of the GNU General Public License as published by
5: the Free Software Foundation; version 2 dated June, 1991, or
6: (at your option) version 3 dated 29 June, 2007.
7:
8: This program is distributed in the hope that it will be useful,
9: but WITHOUT ANY WARRANTY; without even the implied warranty of
10: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11: GNU General Public License for more details.
12:
13: You should have received a copy of the GNU General Public License
14: along with this program. If not, see <http://www.gnu.org/licenses/>.
15: */
16:
17: #include "dnsmasq.h"
18:
19: #ifdef HAVE_UBUS
20:
21: #include <libubus.h>
22:
23: static struct blob_buf b;
24: static int notify;
25: static int error_logged = 0;
26:
27: static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
28: struct ubus_request_data *req, const char *method,
29: struct blob_attr *msg);
30:
31: static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj);
32:
33: static const struct ubus_method ubus_object_methods[] = {
34: UBUS_METHOD_NOARG("metrics", ubus_handle_metrics),
35: };
36:
37: static struct ubus_object_type ubus_object_type =
38: UBUS_OBJECT_TYPE("dnsmasq", ubus_object_methods);
39:
40: static struct ubus_object ubus_object = {
41: .name = NULL,
42: .type = &ubus_object_type,
43: .methods = ubus_object_methods,
44: .n_methods = ARRAY_SIZE(ubus_object_methods),
45: .subscribe_cb = ubus_subscribe_cb,
46: };
47:
48: static void ubus_subscribe_cb(struct ubus_context *ctx, struct ubus_object *obj)
49: {
50: (void)ctx;
51:
52: my_syslog(LOG_DEBUG, _("UBus subscription callback: %s subscriber(s)"), obj->has_subscribers ? "1" : "0");
53: notify = obj->has_subscribers;
54: }
55:
56: static void ubus_destroy(struct ubus_context *ubus)
57: {
58: // Forces re-initialization when we're reusing the same definitions later on.
59: ubus_object.id = 0;
60: ubus_object_type.id = 0;
61:
62: ubus_free(ubus);
63: daemon->ubus = NULL;
64: }
65:
66: static void ubus_disconnect_cb(struct ubus_context *ubus)
67: {
68: int ret;
69:
70: ret = ubus_reconnect(ubus, NULL);
71: if (ret)
72: {
73: my_syslog(LOG_ERR, _("Cannot reconnect to UBus: %s"), ubus_strerror(ret));
74:
75: ubus_destroy(ubus);
76: }
77: }
78:
79: void ubus_init()
80: {
81: struct ubus_context *ubus = NULL;
82: int ret = 0;
83:
84: ubus = ubus_connect(NULL);
85: if (!ubus)
86: {
87: if (!error_logged)
88: {
89: my_syslog(LOG_ERR, _("Cannot initialize UBus: connection failed"));
90: error_logged = 1;
91: }
92:
93: ubus_destroy(ubus);
94: return;
95: }
96:
97: ubus_object.name = daemon->ubus_name;
98: ret = ubus_add_object(ubus, &ubus_object);
99: if (ret)
100: {
101: if (!error_logged)
102: {
103: my_syslog(LOG_ERR, _("Cannot add object to UBus: %s"), ubus_strerror(ret));
104: error_logged = 1;
105: }
106: ubus_destroy(ubus);
107: return;
108: }
109:
110: ubus->connection_lost = ubus_disconnect_cb;
111: daemon->ubus = ubus;
112: error_logged = 0;
113:
114: my_syslog(LOG_INFO, _("Connected to system UBus"));
115: }
116:
117: void set_ubus_listeners()
118: {
119: struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
120: if (!ubus)
121: {
122: if (!error_logged)
123: {
124: my_syslog(LOG_ERR, _("Cannot set UBus listeners: no connection"));
125: error_logged = 1;
126: }
127: return;
128: }
129:
130: error_logged = 0;
131:
132: poll_listen(ubus->sock.fd, POLLIN);
133: poll_listen(ubus->sock.fd, POLLERR);
134: poll_listen(ubus->sock.fd, POLLHUP);
135: }
136:
137: void check_ubus_listeners()
138: {
139: struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
140: if (!ubus)
141: {
142: if (!error_logged)
143: {
144: my_syslog(LOG_ERR, _("Cannot poll UBus listeners: no connection"));
145: error_logged = 1;
146: }
147: return;
148: }
149:
150: error_logged = 0;
151:
152: if (poll_check(ubus->sock.fd, POLLIN))
153: ubus_handle_event(ubus);
154:
155: if (poll_check(ubus->sock.fd, POLLHUP | POLLERR))
156: {
157: my_syslog(LOG_INFO, _("Disconnecting from UBus"));
158:
159: ubus_destroy(ubus);
160: }
161: }
162:
163: static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj,
164: struct ubus_request_data *req, const char *method,
165: struct blob_attr *msg)
166: {
167: int i;
168:
169: (void)obj;
170: (void)method;
171: (void)msg;
172:
173: blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
174:
175: for (i=0; i < __METRIC_MAX; i++)
176: blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
177:
178: return ubus_send_reply(ctx, req, b.head);
179: }
180:
181: void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name, const char *interface)
182: {
183: struct ubus_context *ubus = (struct ubus_context *)daemon->ubus;
184: int ret;
185:
186: if (!ubus || !notify)
187: return;
188:
189: blob_buf_init(&b, BLOBMSG_TYPE_TABLE);
190: if (mac)
191: blobmsg_add_string(&b, "mac", mac);
192: if (ip)
193: blobmsg_add_string(&b, "ip", ip);
194: if (name)
195: blobmsg_add_string(&b, "name", name);
196: if (interface)
197: blobmsg_add_string(&b, "interface", interface);
198:
199: ret = ubus_notify(ubus, &ubus_object, type, b.head, -1);
200: if (!ret)
201: my_syslog(LOG_ERR, _("Failed to send UBus event: %s"), ubus_strerror(ret));
202: }
203:
204:
205: #endif /* HAVE_UBUS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>