]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospfd: OSPFAPI Server options to limit to local connections and per-instance TCP 15796/head
authorAcee Lindem <acee@lindem.com>
Fri, 19 Apr 2024 15:33:20 +0000 (15:33 +0000)
committerAcee Lindem <acee@lindem.com>
Thu, 25 Apr 2024 16:20:50 +0000 (16:20 +0000)
This commit include OSPFAPI Server options to:

 1. Allow specification of the OSPFAPI server local address.
 2. Allow different OSPFAPI server TCP ports to be specified for different
    OSPF instances in /etc/services.

Signed-off-by: Acee Lindem <acee@lindem.com>
doc/user/ospfd.rst
ospfd/ospf_apiserver.c
ospfd/ospf_apiserver.h
ospfd/ospf_main.c

index 47f8fad17b620ea52ae67cdf9cb2606c23f3f0e7..1d3b1ccb7fed2d41afb475812dae5aa98bf0ef1c 100644 (file)
@@ -28,6 +28,12 @@ Configuring OSPF
 
    Enable the OSPF API server. This is required to use ``ospfclient``.
 
+.. option:: -l, --apiserver_addr <address>
+
+   Specify the local IPv4 address to which to bind the OSPF API server socket.
+   If unspecified, connections are accepted to any address. Specification of
+   127.0.0.1 can be used to limit socket access to local applications.
+
 *ospfd* must acquire interface information from *zebra* in order to function.
 Therefore *zebra* must be running before invoking *ospfd*. Also, if *zebra* is
 restarted then *ospfd* must be too.
index 419113e6d781354b2ca190bf482952756d16b8c5..fcc28c6f9f82a21ad4d7276e35c217b2e97d7c0d 100644 (file)
@@ -62,6 +62,11 @@ DEFINE_MTYPE_STATIC(OSPFD, APISERVER_MSGFILTER, "API Server Message Filter");
 /* List of all active connections. */
 struct list *apiserver_list;
 
+/* Indicates that API the server socket local addresss has been
+ * specified.
+ */
+struct in_addr ospf_apiserver_addr;
+
 /* -----------------------------------------------------------
  * Functions to lookup interfaces
  * -----------------------------------------------------------
@@ -109,7 +114,21 @@ struct ospf_interface *ospf_apiserver_if_lookup_by_ifp(struct interface *ifp)
 
 unsigned short ospf_apiserver_getport(void)
 {
-       struct servent *sp = getservbyname("ospfapi", "tcp");
+       struct servent *sp = NULL;
+       char sbuf[16];
+
+       /*
+        * Allow the OSPF API server port to be specified per-instance by
+        * including the instance ID in the /etc/services name. Use the
+        * prior name if no per-instance service is specified.
+        */
+       if (ospf_instance) {
+               snprintfrr(sbuf, sizeof(sbuf), "ospfapi-%d", ospf_instance);
+               sp = getservbyname(sbuf, "tcp");
+       }
+
+       if (!sp)
+               sp = getservbyname("ospfapi", "tcp");
 
        return sp ? ntohs(sp->s_port) : OSPF_API_SYNC_PORT;
 }
@@ -557,8 +576,10 @@ int ospf_apiserver_serv_sock_family(unsigned short port, int family)
        sockopt_reuseaddr(accept_sock);
        sockopt_reuseport(accept_sock);
 
-       /* Bind socket to address and given port. */
-       rc = sockunion_bind(accept_sock, &su, port, NULL);
+       /* Bind socket to optional lcoal address and port. */
+       if (ospf_apiserver_addr.s_addr)
+               sockunion2ip(&su) = ospf_apiserver_addr.s_addr;
+       rc = sockunion_bind(accept_sock, &su, port, &su);
        if (rc < 0) {
                close(accept_sock); /* Close socket */
                return rc;
index 0aaf67c1f3cd12dba1f068acf9a9f2ebe9235e4c..4341a9d3802387a29d1d6e123820b6cb8bb49924 100644 (file)
@@ -66,6 +66,14 @@ enum ospf_apiserver_event {
        OSPF_APISERVER_ASYNC_WRITE
 };
 
+/* -----------------------------------------------------------
+ * External definitions for OSPF API ospfd parameters.
+ * -----------------------------------------------------------
+ */
+
+extern int ospf_apiserver_enable;
+extern struct in_addr ospf_apiserver_addr;
+
 /* -----------------------------------------------------------
  * Following are functions to manage client connections.
  * -----------------------------------------------------------
index abad6c5b902fbe59ba9cbb1a8a8c31b951c055cd..9e97abba1ca10ea22cb932b416c1200c81f4600b 100644 (file)
@@ -44,6 +44,7 @@
 #include "ospfd/ospf_errors.h"
 #include "ospfd/ospf_ldp_sync.h"
 #include "ospfd/ospf_routemap_nb.h"
+#include "ospfd/ospf_apiserver.h"
 
 #define OSPFD_STATE_NAME        "%s/ospfd.json", frr_libstatedir
 #define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i
@@ -75,6 +76,7 @@ struct zebra_privs_t ospfd_privs = {
 const struct option longopts[] = {
        {"instance", required_argument, NULL, 'n'},
        {"apiserver", no_argument, NULL, 'a'},
+       {"apiserver_addr", required_argument, NULL, 'l'},
        {0}
 };
 
@@ -83,10 +85,6 @@ const struct option longopts[] = {
 /* Master of threads. */
 struct event_loop *master;
 
-#ifdef SUPPORT_OSPF_API
-extern int ospf_apiserver_enable;
-#endif /* SUPPORT_OSPF_API */
-
 /* SIGHUP handler. */
 static void sighup(void)
 {
@@ -193,15 +191,11 @@ static void ospf_config_end(void)
 /* OSPFd main routine. */
 int main(int argc, char **argv)
 {
-#ifdef SUPPORT_OSPF_API
-       /* OSPF apiserver is disabled by default. */
-       ospf_apiserver_enable = 0;
-#endif /* SUPPORT_OSPF_API */
-
        frr_preinit(&ospfd_di, argc, argv);
-       frr_opt_add("n:a", longopts,
+       frr_opt_add("n:al:", longopts,
                    "  -n, --instance     Set the instance id\n"
-                   "  -a, --apiserver    Enable OSPF apiserver\n");
+                   "  -a, --apiserver    Enable OSPF apiserver\n"
+                   "  -l, --apiserver_addr     Set OSPF apiserver bind address\n");
 
        while (1) {
                int opt;
@@ -223,6 +217,14 @@ int main(int argc, char **argv)
                case 'a':
                        ospf_apiserver_enable = 1;
                        break;
+               case 'l':
+                       if (inet_pton(AF_INET, optarg, &ospf_apiserver_addr) <=
+                           0) {
+                               zlog_err("OSPF: Invalid API Server IPv4 address %s specified",
+                                        optarg);
+                               exit(0);
+                       }
+                       break;
 #endif /* SUPPORT_OSPF_API */
                default:
                        frr_help_exit(1);