]> git.proxmox.com Git - mirror_frr.git/commitdiff
pimd, pim6d: Send register msg via register socket
authorMobashshera Rasool <mrasool@vmware.com>
Tue, 2 Aug 2022 06:12:53 +0000 (23:12 -0700)
committerMobashshera Rasool <mrasool@vmware.com>
Thu, 4 Aug 2022 07:49:10 +0000 (00:49 -0700)
The problem here is when the same node is FHR as well as RP,
then the node keeps on sending the register packet.
Register-stop is not sent as well.

This problem has occurred because the RP is the same node
and there is no socket created on loopback interface, so the
packet is never send out and never received back on the same
node, so register recv could not be processed on the node and
hence no register-stop is sent.

Since register packets are unicast packets, its better to handle
the send of register packet via a separate register socket.
This fixes the problem mentioned above as well.

Fixes: #11331
Signed-off-by: Mobashshera Rasool <mrasool@vmware.com>
pimd/pim_cmd_common.c
pimd/pim_instance.c
pimd/pim_instance.h
pimd/pim_register.c
pimd/pim_sock.c
pimd/pim_sock.h

index b7bd7375c595218db0c8b0837b51887e60a1d5b3..a04e36dbfca6c1448bcc2ecccc1af3f45f49c74b 100644 (file)
@@ -3352,6 +3352,8 @@ void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, struct vty *vty)
        vty_out(vty, "Mroute socket descriptor:");
 
        vty_out(vty, " %d(%s)\n", pim->mroute_socket, vrf->name);
+       vty_out(vty, "PIM Register socket descriptor:");
+       vty_out(vty, " %d(%s)\n", pim->reg_sock, vrf->name);
 
        pim_time_uptime(uptime, sizeof(uptime),
                        now - pim->mroute_socket_creation);
index 359e3db71867a2c4d68e30a321d2838ef2f7ca2a..4b85d45751a5207fb337a824a5eef5d5a37edc23 100644 (file)
@@ -36,6 +36,7 @@
 #include "pim_vty.h"
 #include "pim_bsm.h"
 #include "pim_mlag.h"
+#include "pim_sock.h"
 
 static void pim_instance_terminate(struct pim_instance *pim)
 {
@@ -70,6 +71,8 @@ static void pim_instance_terminate(struct pim_instance *pim)
 
        pim_msdp_exit(pim);
 
+       close(pim->reg_sock);
+
        pim_mroute_socket_disable(pim);
 
        XFREE(MTYPE_PIM_PLIST_NAME, pim->spt.plist);
@@ -131,6 +134,10 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf)
 
        pim->last_route_change_time = -1;
 
+       pim->reg_sock = pim_reg_sock();
+       if (pim->reg_sock < 0)
+               assert(0);
+
        /* MSDP global timer defaults. */
        pim->msdp.hold_time = PIM_MSDP_PEER_HOLD_TIME;
        pim->msdp.keep_alive = PIM_MSDP_PEER_KA_TIME;
index 684785dd13e174784b6b951fae3f02504bed0c5c..0da881557c0a8db07987cb82e9503e31a2e56c6f 100644 (file)
@@ -136,6 +136,7 @@ struct pim_instance {
 
        struct thread *thread;
        int mroute_socket;
+       int reg_sock; /* Socket to send register msg */
        int64_t mroute_socket_creation;
        int64_t mroute_add_events;
        int64_t mroute_add_last;
index 0eb49a7f91a3962173e921348ef6e17d60b2135f..4e2c44b172df88baa5b5147f698cf1598a1ae6c0 100644 (file)
@@ -331,7 +331,7 @@ void pim_register_send(const uint8_t *buf, int buf_size, pim_addr src,
        if (!pinfo->pim_passive_enable)
                ++pinfo->pim_ifstat_reg_send;
 
-       if (pim_msg_send(pinfo->pim_sock_fd, src, rpg->rpf_addr, buffer,
+       if (pim_msg_send(pinfo->pim->reg_sock, src, rpg->rpf_addr, buffer,
                         buf_size + PIM_MSG_REGISTER_LEN, ifp)) {
                if (PIM_DEBUG_PIM_TRACE) {
                        zlog_debug(
index afc5d471183c3a978ffced4a5b962814e127b14d..73184d5c63f96651f49d2db3d306814f5a93fcf6 100644 (file)
@@ -179,6 +179,46 @@ static inline int pim_setsockopt(int protocol, int fd, struct interface *ifp)
 }
 #endif
 
+int pim_reg_sock(void)
+{
+       int fd;
+       long flags;
+
+       frr_with_privs (&pimd_privs) {
+               fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+       }
+
+       if (fd < 0) {
+               zlog_warn("Could not create raw socket: errno=%d: %s", errno,
+                         safe_strerror(errno));
+               return PIM_SOCK_ERR_SOCKET;
+       }
+
+       if (sockopt_reuseaddr(fd)) {
+               close(fd);
+               return PIM_SOCK_ERR_REUSE;
+       }
+
+       flags = fcntl(fd, F_GETFL, 0);
+       if (flags < 0) {
+               zlog_warn(
+                       "Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+                       fd, errno, safe_strerror(errno));
+               close(fd);
+               return PIM_SOCK_ERR_NONBLOCK_GETFL;
+       }
+
+       if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+               zlog_warn(
+                       "Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+                       fd, errno, safe_strerror(errno));
+               close(fd);
+               return PIM_SOCK_ERR_NONBLOCK_SETFL;
+       }
+
+       return fd;
+}
+
 int pim_socket_mcast(int protocol, pim_addr ifaddr, struct interface *ifp,
                     uint8_t loop)
 {
index ea9f7009bc7f0d747d05c8e34631764f6ac1765f..4dcb9e6466cdf687e5f794ac2b1de4f9df486cb4 100644 (file)
@@ -51,4 +51,6 @@ int pim_socket_recvfromto(int fd, uint8_t *buf, size_t len,
 
 int pim_socket_getsockname(int fd, struct sockaddr *name, socklen_t *namelen);
 
+int pim_reg_sock(void);
+
 #endif /* PIM_SOCK_H */