diff options
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_flood.c | 29 | ||||
-rw-r--r-- | ospfd/ospf_interface.c | 1 | ||||
-rw-r--r-- | ospfd/ospf_interface.h | 6 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 53 | ||||
-rw-r--r-- | ospfd/ospfd.c | 1 |
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); |