summaryrefslogtreecommitdiffstats
path: root/ospfd
diff options
context:
space:
mode:
authorAcee <aceelindem@gmail.com>2023-05-18 16:43:52 +0200
committerAcee <aceelindem@gmail.com>2023-05-22 21:51:41 +0200
commit0d8ef0477ca02ead3ce9b6dd63f6943fd2b02dec (patch)
tree6695da96b114a226a7d63990f0e1d623b874fcce /ospfd
parentMerge pull request #13560 from donaldsharp/fpm_netlink_aroni (diff)
downloadfrr-0d8ef0477ca02ead3ce9b6dd63f6943fd2b02dec.tar.xz
frr-0d8ef0477ca02ead3ce9b6dd63f6943fd2b02dec.zip
ospfd: OSPF P2MP Delayed Reflooding configuration
Currently, delayed reflooding on P2MP interfaces for LSAs received from neighbors on the interface is unconditionally (see commit c706f0e32ba8aa8780a0618b6fbba364c383ae05). In some cases, this change wasn't desirable and this feature makes delayed reflooding configurable for P2MP interfaces via the CLI command: "ip ospf network point-to-multipoint delay-reflood" in interface submode. Signed-off-by: Acee <aceelindem@gmail.com>
Diffstat (limited to 'ospfd')
-rw-r--r--ospfd/ospf_flood.c29
-rw-r--r--ospfd/ospf_interface.c1
-rw-r--r--ospfd/ospf_interface.h6
-rw-r--r--ospfd/ospf_vty.c53
-rw-r--r--ospfd/ospfd.c1
5 files changed, 73 insertions, 17 deletions
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index f3fe504a0..a4d0f77fa 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -770,15 +770,26 @@ int ospf_flood_through_interface(struct ospf_interface *oi,
OSPF_SEND_PACKET_DIRECT);
}
} else
- /* Optimization: for P2MP interfaces,
- don't send back out the incoming interface immediately,
- allow time to rx multicast ack to the rx'ed (multicast)
- update */
- if (retx_flag != 1 ||
- oi->type != OSPF_IFTYPE_POINTOMULTIPOINT || inbr == NULL ||
- oi != inbr->oi)
- ospf_ls_upd_send_lsa(oi->nbr_self, lsa,
- OSPF_SEND_PACKET_INDIRECT);
+ /* If P2MP delayed reflooding is configured and the LSA was
+ received from a neighbor on the P2MP interface, do not flood
+ if back out on the interface. The LSA will be retransmitted
+ upon expiration of each neighbor's retransmission timer. This
+ will allow time to receive a multicast multicast link state
+ acknoweldgement and remove the LSA from each neighbor's link
+ state retransmission list. */
+ if (oi->p2mp_delay_reflood &&
+ (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) &&
+ (inbr != NULL) && (oi == inbr->oi)) {
+ if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+ zlog_debug(
+ "Delay reflooding for LSA[%s] from NBR %pI4 on interface %s",
+ dump_lsa_key(lsa),
+ inbr ? &(inbr->router_id)
+ : &(oi->ospf->router_id),
+ IF_NAME(oi));
+ } else
+ ospf_ls_upd_send_lsa(oi->nbr_self, lsa,
+ OSPF_SEND_PACKET_INDIRECT);
return 0;
}
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 8da982aed..2c66cb3cf 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -545,6 +545,7 @@ static struct ospf_if_params *ospf_new_if_params(void)
oip->is_v_wait_set = false;
oip->ptp_dmvpn = 0;
+ oip->p2mp_delay_reflood = OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
return oip;
}
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h
index 24768b9ab..ec1afa1b8 100644
--- a/ospfd/ospf_interface.h
+++ b/ospfd/ospf_interface.h
@@ -109,6 +109,9 @@ struct ospf_if_params {
/* point-to-point DMVPN configuration */
uint8_t ptp_dmvpn;
+
+ /* point-to-multipoint delayed reflooding configuration */
+ bool p2mp_delay_reflood;
};
enum { MEMBER_ALLROUTERS = 0,
@@ -177,6 +180,9 @@ struct ospf_interface {
/* point-to-point DMVPN configuration */
uint8_t ptp_dmvpn;
+ /* point-to-multipoint delayed reflooding */
+ bool p2mp_delay_reflood;
+
/* State of Interface State Machine. */
uint8_t state;
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index f92be3fca..0ee42e0e7 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3958,6 +3958,16 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
/* OSPF Authentication information */
ospf_interface_auth_show(vty, oi, json_interface_sub, use_json);
+ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
+ if (use_json)
+ json_object_boolean_add(json_interface_sub,
+ "p2mpDelayReflood",
+ oi->p2mp_delay_reflood);
+ else
+ vty_out(vty,
+ " %sDelay reflooding LSAs received on P2MP interface\n",
+ oi->p2mp_delay_reflood ? "" : "Don't ");
+ }
}
}
@@ -8308,13 +8318,17 @@ DEFUN_HIDDEN (no_ospf_hello_interval,
}
DEFUN(ip_ospf_network, ip_ospf_network_cmd,
- "ip ospf network <broadcast|non-broadcast|point-to-multipoint|point-to-point [dmvpn]>",
+ "ip ospf network <broadcast|"
+ "non-broadcast|"
+ "point-to-multipoint [delay-reflood]|"
+ "point-to-point [dmvpn]>",
"IP Information\n"
"OSPF interface commands\n"
"Network type\n"
"Specify OSPF broadcast multi-access network\n"
"Specify OSPF NBMA network\n"
"Specify OSPF point-to-multipoint network\n"
+ "Specify OSPF delayed reflooding of LSAs received on P2MP interface\n"
"Specify OSPF point-to-point network\n"
"Specify OSPF point-to-point DMVPN network\n")
{
@@ -8322,6 +8336,7 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
int idx = 0;
int old_type = IF_DEF_PARAMS(ifp)->type;
uint8_t old_ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ uint8_t old_p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
struct route_node *rn;
if (old_type == OSPF_IFTYPE_LOOPBACK) {
@@ -8331,21 +8346,26 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
}
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
+ OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
if (argv_find(argv, argc, "broadcast", &idx))
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_BROADCAST;
else if (argv_find(argv, argc, "non-broadcast", &idx))
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_NBMA;
- else if (argv_find(argv, argc, "point-to-multipoint", &idx))
+ else if (argv_find(argv, argc, "point-to-multipoint", &idx)) {
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOMULTIPOINT;
- else if (argv_find(argv, argc, "point-to-point", &idx)) {
+ if (argv_find(argv, argc, "delay-reflood", &idx))
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood = true;
+ } else if (argv_find(argv, argc, "point-to-point", &idx)) {
IF_DEF_PARAMS(ifp)->type = OSPF_IFTYPE_POINTOPOINT;
if (argv_find(argv, argc, "dmvpn", &idx))
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 1;
}
- if (IF_DEF_PARAMS(ifp)->type == old_type
- && IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn)
+ if (IF_DEF_PARAMS(ifp)->type == old_type &&
+ IF_DEF_PARAMS(ifp)->ptp_dmvpn == old_ptp_dmvpn &&
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood == old_p2mp_delay_reflood)
return CMD_SUCCESS;
SET_IF_PARAM(IF_DEF_PARAMS(ifp), type);
@@ -8357,10 +8377,19 @@ DEFUN(ip_ospf_network, ip_ospf_network_cmd,
continue;
oi->type = IF_DEF_PARAMS(ifp)->type;
+ oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
- if (oi->state > ISM_Down) {
- OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
- OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
+ /*
+ * The OSPF interface only needs to be flapped if the network
+ * type or DMVPN parameter changes.
+ */
+ if (IF_DEF_PARAMS(ifp)->type != old_type ||
+ IF_DEF_PARAMS(ifp)->ptp_dmvpn != old_ptp_dmvpn) {
+ if (oi->state > ISM_Down) {
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
+ OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceUp);
+ }
}
}
@@ -8398,6 +8427,8 @@ DEFUN (no_ip_ospf_network,
IF_DEF_PARAMS(ifp)->type = ospf_default_iftype(ifp);
IF_DEF_PARAMS(ifp)->ptp_dmvpn = 0;
+ IF_DEF_PARAMS(ifp)->p2mp_delay_reflood =
+ OSPF_P2MP_DELAY_REFLOOD_DEFAULT;
if (IF_DEF_PARAMS(ifp)->type == old_type)
return CMD_SUCCESS;
@@ -8409,6 +8440,8 @@ DEFUN (no_ip_ospf_network,
continue;
oi->type = IF_DEF_PARAMS(ifp)->type;
+ oi->ptp_dmvpn = IF_DEF_PARAMS(ifp)->ptp_dmvpn;
+ oi->p2mp_delay_reflood = IF_DEF_PARAMS(ifp)->p2mp_delay_reflood;
if (oi->state > ISM_Down) {
OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
@@ -11817,6 +11850,10 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
== OSPF_IFTYPE_POINTOPOINT
&& params->ptp_dmvpn)
vty_out(vty, " dmvpn");
+ if (params->type ==
+ OSPF_IFTYPE_POINTOMULTIPOINT &&
+ params->p2mp_delay_reflood)
+ vty_out(vty, " delay-reflood");
if (params != IF_DEF_PARAMS(ifp) && rn)
vty_out(vty, " %pI4",
&rn->p.u.prefix4);
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index eae1f301a..51e937f42 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -1113,6 +1113,7 @@ struct ospf_interface *add_ospf_interface(struct connected *co,
skip network type setting. */
oi->type = IF_DEF_PARAMS(co->ifp)->type;
oi->ptp_dmvpn = IF_DEF_PARAMS(co->ifp)->ptp_dmvpn;
+ oi->p2mp_delay_reflood = IF_DEF_PARAMS(co->ifp)->p2mp_delay_reflood;
/* Add pseudo neighbor. */
ospf_nbr_self_reset(oi, oi->ospf->router_id);