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>