Annotation of embedaddon/dnsmasq/src/ubus.c, revision 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>