summaryrefslogtreecommitdiff
path: root/pimd
diff options
context:
space:
mode:
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim_autorp.c63
-rw-r--r--pimd/pim_autorp.h1
-rw-r--r--pimd/pim_iface.c7
-rw-r--r--pimd/pim_instance.c7
-rw-r--r--pimd/pim_mroute.c10
-rw-r--r--pimd/pim_register.c19
6 files changed, 61 insertions, 46 deletions
diff --git a/pimd/pim_autorp.c b/pimd/pim_autorp.c
index dc077dbbd6..d3f3517efd 100644
--- a/pimd/pim_autorp.c
+++ b/pimd/pim_autorp.c
@@ -967,6 +967,7 @@ err:
static bool pim_autorp_socket_enable(struct pim_autorp *autorp)
{
int fd;
+ struct interface *ifp;
/* Return early if socket is already enabled */
if (autorp->sock != -1)
@@ -980,6 +981,13 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp)
return false;
}
+ if (vrf_bind(autorp->pim->vrf->vrf_id, fd, NULL)) {
+ zlog_warn("Could not bind autorp socket to vrf fd=%d: vrf_id=%d: errno=%d: %s",
+ fd, autorp->pim->vrf->vrf_id, errno, safe_strerror(errno));
+ close(fd);
+ return false;
+ }
+
if (!pim_autorp_setup(fd)) {
zlog_warn("Could not setup autorp socket fd=%d: errno=%d: %s", fd, errno,
safe_strerror(errno));
@@ -990,6 +998,11 @@ static bool pim_autorp_socket_enable(struct pim_autorp *autorp)
autorp->sock = fd;
+ /* Join autorp groups on all pim enabled interfaces in the VRF */
+ FOR_ALL_INTERFACES (autorp->pim->vrf, ifp) {
+ pim_autorp_add_ifp(ifp);
+ }
+
if (PIM_DEBUG_AUTORP)
zlog_debug("%s: AutoRP socket enabled (fd=%u)", __func__, fd);
@@ -1002,6 +1015,7 @@ static bool pim_autorp_socket_disable(struct pim_autorp *autorp)
if (autorp->sock == -1)
return true;
+ /* No need to leave the autorp groups explicitly, they are left when the socket is closed */
if (close(autorp->sock)) {
zlog_warn("Failure closing autorp socket: fd=%d errno=%d: %s", autorp->sock, errno,
safe_strerror(errno));
@@ -1428,10 +1442,10 @@ void pim_autorp_add_ifp(struct interface *ifp)
{
/* Add a new interface for autorp
* When autorp is enabled, we must join the autorp groups on all
- * pim/multicast interfaces. When autorp first starts, if finds all
- * current multicast interfaces and joins on them. If a new interface
- * comes up or is configured for multicast after autorp is running, then
- * this method will add it for autorp->
+ * pim/multicast interfaces. When autorp becomes enabled, it finds all
+ * current pim enabled interfaces and joins the autorp groups on them.
+ * Any new interfaces added after autorp is enabled will use this function
+ * to join the autorp groups
* This is called even when adding a new pim interface that is not yet
* active, so make sure the check, it'll call in again once the interface is up.
*/
@@ -1441,7 +1455,8 @@ void pim_autorp_add_ifp(struct interface *ifp)
pim_ifp = ifp->info;
if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && pim_ifp && pim_ifp->pim_enable) {
pim = pim_ifp->pim;
- if (pim && pim->autorp && pim->autorp->do_discovery) {
+ if (pim && pim->autorp &&
+ (pim->autorp->do_discovery || pim->autorp->send_rp_discovery)) {
if (PIM_DEBUG_AUTORP)
zlog_debug("%s: Adding interface %s to AutoRP, joining AutoRP groups",
__func__, ifp->name);
@@ -1477,44 +1492,37 @@ void pim_autorp_rm_ifp(struct interface *ifp)
void pim_autorp_start_discovery(struct pim_instance *pim)
{
- struct interface *ifp;
struct pim_autorp *autorp = pim->autorp;
+ if (autorp->do_discovery)
+ return;
+
+ autorp->do_discovery = true;
+
/* 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);
-
- FOR_ALL_INTERFACES (autorp->pim->vrf, ifp) {
- pim_autorp_add_ifp(ifp);
- }
+ autorp_read_on(autorp);
- if (PIM_DEBUG_AUTORP)
- zlog_debug("%s: AutoRP Discovery started", __func__);
- }
+ if (PIM_DEBUG_AUTORP)
+ zlog_debug("%s: AutoRP Discovery started", __func__);
}
void pim_autorp_stop_discovery(struct pim_instance *pim)
{
- struct interface *ifp;
struct pim_autorp *autorp = pim->autorp;
- if (autorp->do_discovery) {
- FOR_ALL_INTERFACES (autorp->pim->vrf, ifp) {
- pim_autorp_rm_ifp(ifp);
- }
+ if (!autorp->do_discovery)
+ return;
- autorp->do_discovery = false;
- autorp_read_off(autorp);
+ autorp->do_discovery = false;
+ autorp_read_off(autorp);
- if (PIM_DEBUG_AUTORP)
- zlog_debug("%s: AutoRP Discovery stopped", __func__);
- }
+ 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))
@@ -1549,7 +1557,10 @@ void pim_autorp_init(struct pim_instance *pim)
if (PIM_DEBUG_AUTORP)
zlog_debug("%s: AutoRP Initialized", __func__);
+}
+void pim_autorp_enable(struct pim_instance *pim)
+{
/* Start AutoRP discovery by default on startup */
pim_autorp_start_discovery(pim);
}
diff --git a/pimd/pim_autorp.h b/pimd/pim_autorp.h
index e4c6530109..88aebe5b7d 100644
--- a/pimd/pim_autorp.h
+++ b/pimd/pim_autorp.h
@@ -173,6 +173,7 @@ void pim_autorp_rm_ifp(struct interface *ifp);
void pim_autorp_start_discovery(struct pim_instance *pim);
void pim_autorp_stop_discovery(struct pim_instance *pim);
void pim_autorp_init(struct pim_instance *pim);
+void pim_autorp_enable(struct pim_instance *pim);
void pim_autorp_finish(struct pim_instance *pim);
int pim_autorp_config_write(struct pim_instance *pim, struct vty *vty);
void pim_autorp_show_autorp(struct vty *vty, struct pim_instance *pim, const char *component,
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 9316cebc0a..6d0f2798f9 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1898,9 +1898,7 @@ static int pim_ifp_up(struct interface *ifp)
}
#if PIM_IPV == 4
- if (pim->autorp && pim->autorp->do_discovery && pim_ifp &&
- pim_ifp->pim_enable)
- pim_autorp_add_ifp(ifp);
+ pim_autorp_add_ifp(ifp);
#endif
pim_cand_addrs_changed();
@@ -2017,8 +2015,7 @@ void pim_pim_interface_delete(struct interface *ifp)
return;
#if PIM_IPV == 4
- if (pim_ifp->pim_enable)
- pim_autorp_rm_ifp(ifp);
+ pim_autorp_rm_ifp(ifp);
#endif
pim_ifp->pim_enable = false;
diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c
index 3945c5923d..f64b02e44d 100644
--- a/pimd/pim_instance.c
+++ b/pimd/pim_instance.c
@@ -181,8 +181,15 @@ static int pim_vrf_enable(struct vrf *vrf)
zlog_debug("%s: for %s %u", __func__, vrf->name, vrf->vrf_id);
+ if (vrf_bind(vrf->vrf_id, pim->reg_sock, NULL) < 0)
+ zlog_warn("Failed to bind register socket to VRF %s", vrf->name);
+
pim_mroute_socket_enable(pim);
+#if PIM_IPV == 4
+ pim_autorp_enable(pim);
+#endif
+
FOR_ALL_INTERFACES (vrf, ifp) {
if (!ifp->info)
continue;
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 6c13e1324f..30daa3a929 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -876,17 +876,11 @@ int pim_mroute_socket_enable(struct pim_instance *pim)
pim->vrf->name);
#endif
-#ifdef SO_BINDTODEVICE
- if (pim->vrf->vrf_id != VRF_DEFAULT
- && setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
- pim->vrf->name, strlen(pim->vrf->name))) {
- zlog_warn("Could not setsockopt SO_BINDTODEVICE: %s",
- safe_strerror(errno));
+ if (vrf_bind(pim->vrf->vrf_id, fd, NULL)) {
+ zlog_warn("Could not bind to vrf: %s", safe_strerror(errno));
close(fd);
return -3;
}
-#endif
-
}
pim->mroute_socket = fd;
diff --git a/pimd/pim_register.c b/pimd/pim_register.c
index f776a59b7f..29e658ef16 100644
--- a/pimd/pim_register.c
+++ b/pimd/pim_register.c
@@ -186,8 +186,9 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
*/
for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
if (PIM_DEBUG_PIM_REG)
- zlog_debug("Executing Reg stop for %s",
- child->sg_str);
+ zlog_debug(
+ "Executing Reg stop for upstream child %s",
+ child->sg_str);
pim_reg_stop_upstream(pim, child);
}
@@ -208,8 +209,9 @@ int pim_register_stop_recv(struct interface *ifp, uint8_t *buf, int buf_size)
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
if (pim_addr_cmp(up->sg.grp, sg.grp) == 0) {
if (PIM_DEBUG_PIM_REG)
- zlog_debug("Executing Reg stop for %s",
- up->sg_str);
+ zlog_debug(
+ "Executing Reg stop for upstream %s",
+ up->sg_str);
pim_reg_stop_upstream(pim, up);
}
}
@@ -682,9 +684,12 @@ int pim_register_recv(struct interface *ifp, pim_addr dest_addr,
}
}
- if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE)
- || ((SwitchToSptDesiredOnRp(pim, &sg))
- && pim_upstream_inherited_olist(pim, upstream) == 0)) {
+ if ((upstream->sptbit == PIM_UPSTREAM_SPTBIT_TRUE) ||
+ (PIM_UPSTREAM_FLAG_TEST_FHR(upstream->flags) && i_am_rp) ||
+ ((SwitchToSptDesiredOnRp(pim, &sg)) &&
+ pim_upstream_inherited_olist(pim, upstream) == 0)) {
+ zlog_debug("sending pim register stop message : %s ",
+ upstream->sg_str);
pim_register_stop_send(ifp, &sg, dest_addr, src_addr);
sentRegisterStop = 1;
} else {