]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospfd: fix per-interface sockets
authorMark Stapp <mjs@labn.net>
Thu, 29 Jun 2023 17:51:18 +0000 (13:51 -0400)
committerMark Stapp <mjs@labn.net>
Mon, 3 Jul 2023 13:37:25 +0000 (09:37 -0400)
Some fixes for the per-interface write sockets: better align
opening and closing them with ospf config actions; set
read buffer to zero since these sockets are used only for
writing packets.

Signed-off-by: Mark Stapp <mjs@labn.net>
ospfd/ospf_interface.c
ospfd/ospf_network.c

index 9e6acdbf0de2c77fe91f6b24253da7529eaaa996..840756c05c5737d5786f5a4300280ccb96d3adc3 100644 (file)
@@ -271,6 +271,10 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
 
        QOBJ_REG(oi, ospf_interface);
 
+       /* If first oi, check per-intf write socket */
+       if (ospf->oi_running && ospf->intf_socket_enabled)
+               ospf_ifp_sock_init(ifp);
+
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug("%s: ospf interface %s vrf %s id %u created",
                           __func__, ifp->name, ospf_get_name(ospf),
@@ -327,6 +331,8 @@ void ospf_if_cleanup(struct ospf_interface *oi)
 
 void ospf_if_free(struct ospf_interface *oi)
 {
+       struct interface *ifp = oi->ifp;
+
        ospf_if_down(oi);
 
        ospf_fifo_free(oi->obuf);
@@ -361,6 +367,10 @@ void ospf_if_free(struct ospf_interface *oi)
 
        event_cancel_event(master, oi);
 
+       /* If last oi, close per-interface socket */
+       if (ospf_oi_count(ifp) == 0)
+               ospf_ifp_sock_close(ifp);
+
        memset(oi, 0, sizeof(*oi));
        XFREE(MTYPE_OSPF_IF, oi);
 }
@@ -1404,7 +1414,8 @@ static int ospf_ifp_up(struct interface *ifp)
 
        /* Open per-intf write socket if configured */
        ospf = ifp->vrf->info;
-       if (ospf && ospf->intf_socket_enabled)
+
+       if (ospf && ospf->oi_running && ospf->intf_socket_enabled)
                ospf_ifp_sock_init(ifp);
 
        ospf_if_recalculate_output_cost(ifp);
index aff8ed05c723542ed1118ce70c20799695ace683..801f75ad1853e65e45970eb222b2d5742622ae25 100644 (file)
@@ -159,7 +159,8 @@ int ospf_if_ipmulticast(int fd, struct prefix *p, ifindex_t ifindex)
  * Helper to open and set up a socket; returns the new fd on success,
  * -1 on error.
  */
-static int sock_init_common(vrf_id_t vrf_id, const char *name, int *pfd)
+static int sock_init_common(vrf_id_t vrf_id, const char *name, int proto,
+                           int *pfd)
 {
        int ospf_sock;
        int ret, hincl = 1;
@@ -170,8 +171,7 @@ static int sock_init_common(vrf_id_t vrf_id, const char *name, int *pfd)
        }
 
        frr_with_privs(&ospfd_privs) {
-               ospf_sock = vrf_socket(AF_INET, SOCK_RAW, IPPROTO_OSPFIGP,
-                                      vrf_id, name);
+               ospf_sock = vrf_socket(AF_INET, SOCK_RAW, proto, vrf_id, name);
                if (ospf_sock < 0) {
                        flog_err(EC_LIB_SOCKET, "%s: socket: %s", __func__,
                                 safe_strerror(errno));
@@ -244,7 +244,8 @@ int ospf_sock_init(struct ospf *ospf)
        if (ospf->fd > 0)
                return -1;
 
-       ret = sock_init_common(ospf->vrf_id, ospf->name, &(ospf->fd));
+       ret = sock_init_common(ospf->vrf_id, ospf->name, IPPROTO_OSPFIGP,
+                              &(ospf->fd));
 
        if (ret >= 0) /* Update socket buffer sizes */
                ospf_sock_bufsize_update(ospf, ospf->fd, OSPF_SOCK_BOTH);
@@ -258,8 +259,8 @@ int ospf_sock_init(struct ospf *ospf)
 int ospf_ifp_sock_init(struct interface *ifp)
 {
        struct ospf_if_info *oii;
-       struct ospf_interface *oi;
-       struct ospf *ospf;
+       struct ospf_interface *oi = NULL;
+       struct ospf *ospf = NULL;
        struct route_node *rn;
        int ret;
 
@@ -270,17 +271,26 @@ int ospf_ifp_sock_init(struct interface *ifp)
        if (oii->oii_fd > 0)
                return 0;
 
-       rn = route_top(IF_OIFS(ifp));
-       if (rn && rn->info) {
-               oi = rn->info;
-               ospf = oi->ospf;
-       } else
+       for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
+               if (rn && rn->info) {
+                       oi = rn->info;
+                       ospf = oi->ospf;
+                       break;
+               }
+       }
+
+       if (ospf == NULL)
                return -1;
 
-       ret = sock_init_common(ifp->vrf->vrf_id, ifp->name, &oii->oii_fd);
+       ret = sock_init_common(ifp->vrf->vrf_id, ifp->name, IPPROTO_OSPFIGP,
+                              &oii->oii_fd);
 
-       if (ret >= 0) /* Update socket buffer sizes */
-               ospf_sock_bufsize_update(ospf, oii->oii_fd, OSPF_SOCK_BOTH);
+       if (ret >= 0) { /* Update socket buffer sizes */
+               /* Write-only, so no recv buf */
+               setsockopt_so_recvbuf(oii->oii_fd, 0);
+
+               ospf_sock_bufsize_update(ospf, oii->oii_fd, OSPF_SOCK_SEND);
+       }
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug("%s: ifp %s, oii %p, fd %d", __func__, ifp->name,