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>