Merge pull request #15796 from LabNConsulting/aceelindem/ospf-ospfapi-options

ospfd: OSPFAPI Server options to limit to local connections and per-instance TCP
This commit is contained in:
Donatas Abraitis 2024-04-26 23:31:38 +03:00 committed by GitHub
commit 24a9f1c9ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 14 deletions

View 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.

View 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;

View 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.
* -----------------------------------------------------------

View 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);