]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Close AutoRP socket when not needed
authorNathan Bahr <nbahr@atcorp.com>
Mon, 27 Jan 2025 15:57:04 +0000 (15:57 +0000)
committerNathan Bahr <nbahr@atcorp.com>
Mon, 27 Jan 2025 17:04:14 +0000 (17:04 +0000)
Don't leave the socket open if we are not enabled for discovery
or announcements.

Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
pimd/pim_autorp.c
pimd/pim_cmd_common.c

index caed914a87fbed4a151430bca579a50f3051d36b..dc077dbbd623aa8639b1af401a92b0a11769e2f2 100644 (file)
@@ -113,6 +113,12 @@ static void pim_autorp_free(struct pim_autorp *autorp)
                XFREE(MTYPE_PIM_AUTORP_ANNOUNCE, autorp->announce_pkt);
 }
 
+static bool pim_autorp_should_close(struct pim_autorp *autorp)
+{
+       /* If discovery or mapping agent is active, then we need the socket open */
+       return !autorp->do_discovery && !autorp->send_rp_discovery;
+}
+
 static bool pim_autorp_join_groups(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
@@ -670,10 +676,19 @@ static void autorp_send_discovery(struct event *evt)
                        &(autorp->send_discovery_timer));
 }
 
+static bool pim_autorp_socket_enable(struct pim_autorp *autorp);
+static bool pim_autorp_socket_disable(struct pim_autorp *autorp);
+
 static void autorp_send_discovery_on(struct pim_autorp *autorp)
 {
        int interval = 5;
 
+       /* Make sure the socket is open and ready */
+       if (!pim_autorp_socket_enable(autorp)) {
+               zlog_err("%s: AutoRP failed to open socket", __func__);
+               return;
+       }
+
        /* Send the first discovery shortly after being enabled.
         * If the configured interval is less than 5 seconds, then just use that.
         */
@@ -695,6 +710,10 @@ static void autorp_send_discovery_off(struct pim_autorp *autorp)
                if (PIM_DEBUG_AUTORP)
                        zlog_debug("%s: AutoRP discovery sending disabled", __func__);
        event_cancel(&(autorp->send_discovery_timer));
+
+       /* Close the socket if we need to */
+       if (pim_autorp_should_close(autorp) && !pim_autorp_socket_disable(autorp))
+               zlog_warn("%s: AutoRP failed to close socket", __func__);
 }
 
 static bool autorp_recv_discovery(struct pim_autorp *autorp, uint8_t rpcnt, uint16_t holdtime,
@@ -949,6 +968,10 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp)
 {
        int fd;
 
+       /* Return early if socket is already enabled */
+       if (autorp->sock != -1)
+               return true;
+
        frr_with_privs (&pimd_privs) {
                fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
                if (fd < 0) {
@@ -975,6 +998,10 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp)
 
 static bool pim_autorp_socket_disable(struct pim_autorp *autorp)
 {
+       /* Return early if socket is already disabled */
+       if (autorp->sock == -1)
+               return true;
+
        if (close(autorp->sock)) {
                zlog_warn("Failure closing autorp socket: fd=%d errno=%d: %s", autorp->sock, errno,
                          safe_strerror(errno));
@@ -1453,6 +1480,12 @@ void pim_autorp_start_discovery(struct pim_instance *pim)
        struct interface *ifp;
        struct pim_autorp *autorp = pim->autorp;
 
+       /* Make sure the socket is open and ready */
+       if (!pim_autorp_socket_enable(autorp)) {
+               zlog_err("%s: AutoRP failed to open socket", __func__);
+               return;
+       }
+
        if (!autorp->do_discovery) {
                autorp->do_discovery = true;
                autorp_read_on(autorp);
@@ -1482,6 +1515,10 @@ void pim_autorp_stop_discovery(struct pim_instance *pim)
                if (PIM_DEBUG_AUTORP)
                        zlog_debug("%s: AutoRP Discovery stopped", __func__);
        }
+
+       /* Close the socket if we need to */
+       if (pim_autorp_should_close(autorp) && !pim_autorp_socket_disable(autorp))
+               zlog_warn("%s: AutoRP failed to close socket", __func__);
 }
 
 void pim_autorp_init(struct pim_instance *pim)
@@ -1510,12 +1547,6 @@ void pim_autorp_init(struct pim_instance *pim)
 
        pim->autorp = autorp;
 
-       if (!pim_autorp_socket_enable(autorp)) {
-               zlog_warn("%s: AutoRP failed to initialize, feature will not work correctly",
-                         __func__);
-               return;
-       }
-
        if (PIM_DEBUG_AUTORP)
                zlog_debug("%s: AutoRP Initialized", __func__);
 
index 8aebce7d27a927dd2e54f47d98d52314010e17b8..9f09852a948756247e9b67ef9d86d4fd09e13c2b 100644 (file)
@@ -608,26 +608,14 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
 
 int pim_process_autorp_cmd(struct vty *vty)
 {
-       char xpath[XPATH_MAXLEN];
-
-       snprintf(xpath, sizeof(xpath), "%s/%s", FRR_PIM_AUTORP_XPATH,
-                "discovery-enabled");
-
-       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true");
-
-       return nb_cli_apply_changes(vty, NULL);
+       nb_cli_enqueue_change(vty, "./discovery-enabled", NB_OP_MODIFY, "true");
+       return nb_cli_apply_changes(vty, "%s", FRR_PIM_AUTORP_XPATH);
 }
 
 int pim_process_no_autorp_cmd(struct vty *vty)
 {
-       char xpath[XPATH_MAXLEN];
-
-       snprintf(xpath, sizeof(xpath), "%s/%s", FRR_PIM_AUTORP_XPATH,
-                "discovery-enabled");
-
-       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
-
-       return nb_cli_apply_changes(vty, NULL);
+       nb_cli_enqueue_change(vty, "./discovery-enabled", NB_OP_MODIFY, "false");
+       return nb_cli_apply_changes(vty, "%s", FRR_PIM_AUTORP_XPATH);
 }
 
 int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str,