]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/agentx.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / agentx.c
index 53e5f2bc53427918d3d690aa21e7523390c588b8..40cac722ae8dba1a4a47db2cecea6661ff73680b 100644 (file)
@@ -31,6 +31,7 @@
 #include "memory.h"
 #include "linklist.h"
 #include "version.h"
+#include "lib_errors.h"
 
 static int agentx_enabled = 0;
 
@@ -40,136 +41,141 @@ static struct list *events = NULL;
 
 static void agentx_events_update(void);
 
-static int
-agentx_timeout(struct thread *t)
+static int agentx_timeout(struct thread *t)
 {
-  timeout_thr = NULL;
+       timeout_thr = NULL;
 
-  snmp_timeout ();
-  run_alarms ();
-  netsnmp_check_outstanding_agent_requests ();
-  agentx_events_update ();
-  return 0;
+       snmp_timeout();
+       run_alarms();
+       netsnmp_check_outstanding_agent_requests();
+       agentx_events_update();
+       return 0;
 }
 
-static int
-agentx_read(struct thread *t)
+static int agentx_read(struct thread *t)
 {
-  fd_set fds;
-  struct listnode *ln = THREAD_ARG (t);
-  list_delete_node (events, ln);
+       fd_set fds;
+       struct listnode *ln = THREAD_ARG(t);
+       list_delete_node(events, ln);
 
-  FD_ZERO (&fds);
-  FD_SET (THREAD_FD (t), &fds);
-  snmp_read (&fds);
+       FD_ZERO(&fds);
+       FD_SET(THREAD_FD(t), &fds);
+       snmp_read(&fds);
 
-  netsnmp_check_outstanding_agent_requests ();
-  agentx_events_update ();
-  return 0;
+       netsnmp_check_outstanding_agent_requests();
+       agentx_events_update();
+       return 0;
 }
 
-static void
-agentx_events_update(void)
+static void agentx_events_update(void)
 {
-  int maxfd = 0;
-  int block = 1;
-  struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 };
-  fd_set fds;
-  struct listnode *ln;
-  struct thread *thr;
-  int fd, thr_fd;
-
-  THREAD_OFF (timeout_thr);
-
-  FD_ZERO (&fds);
-  snmp_select_info (&maxfd, &fds, &timeout, &block);
-
-  if (!block) {
-    timeout_thr = NULL;
-    thread_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout,
-                        &timeout_thr);
-  }
-
-  ln = listhead (events);
-  thr = ln ? listgetdata (ln) : NULL;
-  thr_fd = thr ? THREAD_FD (thr) : -1;
-
-  /* "two-pointer" / two-list simultaneous iteration
-   * ln/thr/thr_fd point to the next existing event listener to hit while
-   * fd counts to catch up */
-  for (fd = 0; fd < maxfd; fd++)
-    {
-      /* caught up */
-      if (thr_fd == fd)
-        {
-          struct listnode *nextln = listnextnode (ln);
-          if (!FD_ISSET (fd, &fds))
-            {
-              thread_cancel (thr);
-              list_delete_node (events, ln);
-            }
-          ln = nextln;
-          thr = ln ? listgetdata (ln) : NULL;
-          thr_fd = thr ? THREAD_FD (thr) : -1;
-        }
-      /* need listener, but haven't hit one where it would be */
-      else if (FD_ISSET (fd, &fds))
-        {
-          struct listnode *newln;
-          thr = NULL;
-          thread_add_read(agentx_tm, agentx_read, NULL, fd, &thr);
-          newln = listnode_add_before (events, ln, thr);
-          thr->arg = newln;
-        }
-    }
-
-  /* leftover event listeners at this point have fd > maxfd, delete them */
-  while (ln)
-    {
-      struct listnode *nextln = listnextnode (ln);
-      thread_cancel (listgetdata (ln));
-      list_delete_node (events, ln);
-      ln = nextln;
-    }
+       int maxfd = 0;
+       int block = 1;
+       struct timeval timeout = {.tv_sec = 0, .tv_usec = 0};
+       fd_set fds;
+       struct listnode *ln;
+       struct thread *thr;
+       int fd, thr_fd;
+
+       THREAD_OFF(timeout_thr);
+
+       FD_ZERO(&fds);
+       snmp_select_info(&maxfd, &fds, &timeout, &block);
+
+       if (!block) {
+               timeout_thr = NULL;
+               thread_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout,
+                                   &timeout_thr);
+       }
+
+       ln = listhead(events);
+       thr = ln ? listgetdata(ln) : NULL;
+       thr_fd = thr ? THREAD_FD(thr) : -1;
+
+       /* "two-pointer" / two-list simultaneous iteration
+        * ln/thr/thr_fd point to the next existing event listener to hit while
+        * fd counts to catch up */
+       for (fd = 0; fd < maxfd; fd++) {
+               /* caught up */
+               if (thr_fd == fd) {
+                       struct listnode *nextln = listnextnode(ln);
+                       if (!FD_ISSET(fd, &fds)) {
+                               thread_cancel(thr);
+                               list_delete_node(events, ln);
+                       }
+                       ln = nextln;
+                       thr = ln ? listgetdata(ln) : NULL;
+                       thr_fd = thr ? THREAD_FD(thr) : -1;
+               }
+               /* need listener, but haven't hit one where it would be */
+               else if (FD_ISSET(fd, &fds)) {
+                       struct listnode *newln;
+                       thr = NULL;
+                       thread_add_read(agentx_tm, agentx_read, NULL, fd, &thr);
+                       newln = listnode_add_before(events, ln, thr);
+                       thr->arg = newln;
+               }
+       }
+
+       /* leftover event listeners at this point have fd > maxfd, delete them
+        */
+       while (ln) {
+               struct listnode *nextln = listnextnode(ln);
+               thread_cancel(listgetdata(ln));
+               list_delete_node(events, ln);
+               ln = nextln;
+       }
 }
 
 /* AgentX node. */
-static struct cmd_node agentx_node =
-{
-  SMUX_NODE,
-  "",                           /* AgentX has no interface. */
-  1
-};
+static struct cmd_node agentx_node = {SMUX_NODE,
+                                     "", /* AgentX has no interface. */
+                                     1};
 
 /* Logging NetSNMP messages */
-static int
-agentx_log_callback(int major, int minor,
-                   void *serverarg, void *clientarg)
+static int agentx_log_callback(int major, int minor, void *serverarg,
+                              void *clientarg)
 {
-  struct snmp_log_message *slm = (struct snmp_log_message *)serverarg;
-  char *msg = XSTRDUP(MTYPE_TMP, slm->msg);
-  if (msg) msg[strlen(msg)-1] = '\0';
-  switch (slm->priority)
-    {
-    case LOG_EMERG:   zlog_err   ("snmp[emerg]: %s",   msg?msg:slm->msg); break;
-    case LOG_ALERT:   zlog_err   ("snmp[alert]: %s",   msg?msg:slm->msg); break;
-    case LOG_CRIT:    zlog_err   ("snmp[crit]: %s",    msg?msg:slm->msg); break;
-    case LOG_ERR:     zlog_err   ("snmp[err]: %s",     msg?msg:slm->msg); break;
-    case LOG_WARNING: zlog_warn  ("snmp[warning]: %s", msg?msg:slm->msg); break;
-    case LOG_NOTICE:  zlog_notice("snmp[notice]: %s",  msg?msg:slm->msg); break;
-    case LOG_INFO:    zlog_info  ("snmp[info]: %s",    msg?msg:slm->msg); break;
-    case LOG_DEBUG:   zlog_debug ("snmp[debug]: %s",   msg?msg:slm->msg); break;
-    }
-  XFREE(MTYPE_TMP, msg);
-  return SNMP_ERR_NOERROR;
+       struct snmp_log_message *slm = (struct snmp_log_message *)serverarg;
+       char *msg = XSTRDUP(MTYPE_TMP, slm->msg);
+       if (msg)
+               msg[strlen(msg) - 1] = '\0';
+       switch (slm->priority) {
+       case LOG_EMERG:
+               flog_err(EC_LIB_SNMP, "snmp[emerg]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_ALERT:
+               flog_err(EC_LIB_SNMP, "snmp[alert]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_CRIT:
+               flog_err(EC_LIB_SNMP, "snmp[crit]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_ERR:
+               flog_err(EC_LIB_SNMP, "snmp[err]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_WARNING:
+               flog_warn(EC_LIB_SNMP, "snmp[warning]: %s",
+                         msg ? msg : slm->msg);
+               break;
+       case LOG_NOTICE:
+               zlog_notice("snmp[notice]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_INFO:
+               zlog_info("snmp[info]: %s", msg ? msg : slm->msg);
+               break;
+       case LOG_DEBUG:
+               zlog_debug("snmp[debug]: %s", msg ? msg : slm->msg);
+               break;
+       }
+       XFREE(MTYPE_TMP, msg);
+       return SNMP_ERR_NOERROR;
 }
 
-static int
-config_write_agentx (struct vty *vty)
+static int config_write_agentx(struct vty *vty)
 {
-  if (agentx_enabled)
-      vty_outln (vty, "agentx");
-  return 1;
+       if (agentx_enabled)
+               vty_out(vty, "agentx\n");
+       return 1;
 }
 
 DEFUN (agentx_enable,
@@ -177,16 +183,14 @@ DEFUN (agentx_enable,
        "agentx",
        "SNMP AgentX protocol settings\n")
 {
-  if (!agentx_enabled)
-    {
-      init_snmp(FRR_SMUX_NAME);
-      events = list_new();
-      agentx_events_update ();
-      agentx_enabled = 1;
-      return CMD_SUCCESS;
-    }
-  vty_outln (vty, "SNMP AgentX already enabled");
-  return CMD_SUCCESS;
+       if (!agentx_enabled) {
+               init_snmp(FRR_SMUX_NAME);
+               events = list_new();
+               agentx_events_update();
+               agentx_enabled = 1;
+       }
+
+       return CMD_SUCCESS;
 }
 
 DEFUN (no_agentx,
@@ -195,126 +199,119 @@ DEFUN (no_agentx,
        NO_STR
        "SNMP AgentX protocol settings\n")
 {
-  if (!agentx_enabled) return CMD_SUCCESS;
-  vty_outln (vty, "SNMP AgentX support cannot be disabled once enabled");
-  return CMD_WARNING_CONFIG_FAILED;
+       if (!agentx_enabled)
+               return CMD_SUCCESS;
+       vty_out(vty, "SNMP AgentX support cannot be disabled once enabled\n");
+       return CMD_WARNING_CONFIG_FAILED;
 }
 
-void
-smux_init (struct thread_master *tm)
+void smux_init(struct thread_master *tm)
 {
-  agentx_tm = tm;
-
-  netsnmp_enable_subagent ();
-  snmp_disable_log ();
-  snmp_enable_calllog ();
-  snmp_register_callback (SNMP_CALLBACK_LIBRARY,
-                         SNMP_CALLBACK_LOGGING,
-                         agentx_log_callback,
-                         NULL);
-  init_agent (FRR_SMUX_NAME);
-
-  install_node (&agentx_node, config_write_agentx);
-  install_element (CONFIG_NODE, &agentx_enable_cmd);
-  install_element (CONFIG_NODE, &no_agentx_cmd);
+       agentx_tm = tm;
+
+       netsnmp_enable_subagent();
+       snmp_disable_log();
+       snmp_enable_calllog();
+       snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING,
+                              agentx_log_callback, NULL);
+       init_agent(FRR_SMUX_NAME);
+
+       install_node(&agentx_node, config_write_agentx);
+       install_element(CONFIG_NODE, &agentx_enable_cmd);
+       install_element(CONFIG_NODE, &no_agentx_cmd);
 }
 
-void
-smux_register_mib (const char *descr, struct variable *var, 
-                  size_t width, int num,
-                  oid name[], size_t namelen)
+void smux_register_mib(const char *descr, struct variable *var, size_t width,
+                      int num, oid name[], size_t namelen)
 {
-  register_mib (descr, var, width, num, name, namelen);
+       register_mib(descr, var, width, num, name, namelen);
 }
 
-int
-smux_trap (struct variable *vp, size_t vp_len,
-          const oid *ename, size_t enamelen,
-          const oid *name, size_t namelen,
-          const oid *iname, size_t inamelen,
-          const struct trap_object *trapobj, size_t trapobjlen,
-          u_char sptrap)
+int smux_trap(struct variable *vp, size_t vp_len, const oid *ename,
+             size_t enamelen, const oid *name, size_t namelen,
+             const oid *iname, size_t inamelen,
+             const struct trap_object *trapobj, size_t trapobjlen,
+             uint8_t sptrap)
 {
-  oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
-  size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof (oid);
-  oid notification_oid[MAX_OID_LEN];
-  size_t notification_oid_len;
-  unsigned int i;
-
-  netsnmp_variable_list *notification_vars = NULL;
-  if (!agentx_enabled) return 0;
-
-  /* snmpTrapOID */
-  oid_copy (notification_oid, ename, enamelen);
-  notification_oid[enamelen] = sptrap;
-  notification_oid_len = enamelen + 1;
-  snmp_varlist_add_variable (&notification_vars,
-                            objid_snmptrap, objid_snmptrap_len,
-                            ASN_OBJECT_ID,
-                            (u_char *) notification_oid,
-                            notification_oid_len * sizeof(oid));
-
-  /* Provided bindings */
-  for (i = 0; i < trapobjlen; i++)
-    {
-      unsigned int j;
-      oid oid[MAX_OID_LEN];
-      size_t oid_len, onamelen;
-      u_char *val;
-      size_t val_len;
-      WriteMethod *wm = NULL;
-      struct variable cvp;
-
-      /* Make OID. */
-      if (trapobj[i].namelen > 0)
-        {
-         /* Columnar object */
-         onamelen = trapobj[i].namelen;
-         oid_copy (oid, name, namelen);
-         oid_copy (oid + namelen, trapobj[i].name, onamelen);
-         oid_copy (oid + namelen + onamelen, iname, inamelen);
-         oid_len = namelen + onamelen + inamelen;
-        }
-      else
-        {
-         /* Scalar object */
-         onamelen = trapobj[i].namelen * (-1);
-         oid_copy (oid, name, namelen);
-         oid_copy (oid + namelen, trapobj[i].name, onamelen);
-         oid[onamelen + namelen] = 0;
-         oid_len = namelen + onamelen + 1;
-        }
-
-      /* Locate the appropriate function and type in the MIB registry. */
-      for (j = 0; j < vp_len; j++)
-       {
-         if (oid_compare (trapobj[i].name, onamelen, vp[j].name, vp[j].namelen) != 0)
-           continue;
-         /* We found the appropriate variable in the MIB registry. */
-         oid_copy(cvp.name, name, namelen);
-         oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen);
-         cvp.namelen = namelen + vp[j].namelen;
-         cvp.type = vp[j].type;
-         cvp.magic = vp[j].magic;
-         cvp.acl = vp[j].acl;
-         cvp.findVar = vp[j].findVar;
-         /* Grab the result. */
-         val = cvp.findVar (&cvp, oid, &oid_len, 1, &val_len, &wm);
-         if (!val) break;
-         snmp_varlist_add_variable (&notification_vars,
-                                    oid, oid_len,
-                                    vp[j].type,
-                                    val,
-                                    val_len);
-         break;
+       oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
+       size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof(oid);
+       oid notification_oid[MAX_OID_LEN];
+       size_t notification_oid_len;
+       unsigned int i;
+
+       netsnmp_variable_list *notification_vars = NULL;
+       if (!agentx_enabled)
+               return 0;
+
+       /* snmpTrapOID */
+       oid_copy(notification_oid, ename, enamelen);
+       notification_oid[enamelen] = sptrap;
+       notification_oid_len = enamelen + 1;
+       snmp_varlist_add_variable(&notification_vars, objid_snmptrap,
+                                 objid_snmptrap_len, ASN_OBJECT_ID,
+                                 (uint8_t *)notification_oid,
+                                 notification_oid_len * sizeof(oid));
+
+       /* Provided bindings */
+       for (i = 0; i < trapobjlen; i++) {
+               unsigned int j;
+               oid oid[MAX_OID_LEN];
+               size_t oid_len, onamelen;
+               uint8_t *val;
+               size_t val_len;
+               WriteMethod *wm = NULL;
+               struct variable cvp;
+
+               /* Make OID. */
+               if (trapobj[i].namelen > 0) {
+                       /* Columnar object */
+                       onamelen = trapobj[i].namelen;
+                       oid_copy(oid, name, namelen);
+                       oid_copy(oid + namelen, trapobj[i].name, onamelen);
+                       oid_copy(oid + namelen + onamelen, iname, inamelen);
+                       oid_len = namelen + onamelen + inamelen;
+               } else {
+                       /* Scalar object */
+                       onamelen = trapobj[i].namelen * (-1);
+                       oid_copy(oid, name, namelen);
+                       oid_copy(oid + namelen, trapobj[i].name, onamelen);
+                       oid[onamelen + namelen] = 0;
+                       oid_len = namelen + onamelen + 1;
+               }
+
+               /* Locate the appropriate function and type in the MIB registry.
+                */
+               for (j = 0; j < vp_len; j++) {
+                       if (oid_compare(trapobj[i].name, onamelen, vp[j].name,
+                                       vp[j].namelen)
+                           != 0)
+                               continue;
+                       /* We found the appropriate variable in the MIB
+                        * registry. */
+                       oid_copy(cvp.name, name, namelen);
+                       oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen);
+                       cvp.namelen = namelen + vp[j].namelen;
+                       cvp.type = vp[j].type;
+                       cvp.magic = vp[j].magic;
+                       cvp.acl = vp[j].acl;
+                       cvp.findVar = vp[j].findVar;
+                       /* Grab the result. */
+                       val = cvp.findVar(&cvp, oid, &oid_len, 1, &val_len,
+                                         &wm);
+                       if (!val)
+                               break;
+                       snmp_varlist_add_variable(&notification_vars, oid,
+                                                 oid_len, vp[j].type, val,
+                                                 val_len);
+                       break;
+               }
        }
-    }
 
 
-  send_v2trap (notification_vars);
-  snmp_free_varbind (notification_vars);
-  agentx_events_update ();
-  return 1;
+       send_v2trap(notification_vars);
+       snmp_free_varbind(notification_vars);
+       agentx_events_update();
+       return 1;
 }
 
 #endif /* SNMP_AGENTX */