OSPFd: Correct Extended Prefix LSA refresh

- When Extended Prefix LSA need to be refresh, paramaters may be
taken from the wrong interface i.e. Extended Link instead of Prefix
resulting in producing an empty LSA body. Then, ospfd crash due to the
assert on LSA length in ospf_lsa_different() function: code check that
the LSA size is larger than LSA header i.e. LSA is not empty.

Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
Olivier Dugeon 2018-02-01 14:30:34 +01:00
parent 62c9979094
commit db28a51f7e
3 changed files with 16 additions and 17 deletions

View File

@ -238,10 +238,12 @@ static struct ext_itf *lookup_ext_by_instance(struct ospf_lsa *lsa)
{
struct listnode *node;
struct ext_itf *exti;
unsigned int key = GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr));
uint32_t key = GET_OPAQUE_ID(ntohl(lsa->data->id.s_addr));
uint8_t type = GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr));
for (ALL_LIST_ELEMENTS_RO(OspfEXT.iflist, node, exti))
if (exti->instance == key)
if ((exti->instance == key) && (exti->type == type))
return exti;
return NULL;
@ -419,8 +421,8 @@ static void set_rmt_itf_addr(struct ext_itf *exti, struct in_addr rmtif)
*
* @return instance number if update is OK, 0 otherwise
*/
int ospf_ext_schedule_prefix_index(struct interface *ifp, uint32_t index,
struct prefix_ipv4 *p, uint8_t flags)
uint32_t ospf_ext_schedule_prefix_index(struct interface *ifp, uint32_t index,
struct prefix_ipv4 *p, uint8_t flags)
{
int rc = 0;
struct ext_itf *exti;
@ -462,7 +464,7 @@ int ospf_ext_schedule_prefix_index(struct interface *ifp, uint32_t index,
}
}
return exti->instance;
return SET_OPAQUE_LSID(exti->type, exti->instance);
}
/*
@ -587,6 +589,7 @@ static void ospf_ext_link_ism_change(struct ospf_interface *oi, int old_status)
exti->stype = ADJ_SID;
exti->instance = get_ext_link_instance_value();
exti->type = OPAQUE_TYPE_EXTENDED_LINK_LSA;
zlog_debug(
"EXT (%s): Set %s SID to interface %s ", __func__,
@ -616,6 +619,7 @@ static void ospf_ext_pref_ism_change(struct ospf_interface *oi, int old_status)
if (oi->type == OSPF_IFTYPE_LOOPBACK) {
exti->stype = PREF_SID;
exti->instance = get_ext_pref_instance_value();
exti->type = OPAQUE_TYPE_EXTENDED_PREFIX_LSA;
zlog_debug(
"EXT (%s): Set Node SID to interface %s ", __func__,
@ -1329,8 +1333,7 @@ static struct ospf_lsa *ospf_ext_pref_lsa_refresh(struct ospf_lsa *lsa)
}
/* Create new Opaque-LSA/Extended Prefix Opaque LSA instance. */
if (exti)
new = ospf_ext_pref_lsa_new(area, exti);
new = ospf_ext_pref_lsa_new(area, exti);
if (new == NULL) {
zlog_warn("EXT (%s): ospf_ext_pref_lsa_new() error", __func__);

View File

@ -192,7 +192,7 @@ struct ext_itf {
extern int ospf_ext_init(void);
extern void ospf_ext_term(void);
extern void ospf_ext_update_sr(bool enable);
extern int ospf_ext_schedule_prefix_index(struct interface *ifp,
extern uint32_t ospf_ext_schedule_prefix_index(struct interface *ifp,
uint32_t index,
struct prefix_ipv4 *p,
uint8_t flags);

View File

@ -1489,7 +1489,6 @@ void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p)
{
struct listnode *node;
struct sr_prefix *srp;
uint32_t rc;
/* Sanity Check */
if ((ifp == NULL) || (p == NULL))
@ -1514,10 +1513,8 @@ void ospf_sr_update_prefix(struct interface *ifp, struct prefix *p)
IPV4_ADDR_COPY(&srp->nhlfe.nexthop, &p->u.prefix4);
/* OK. Let's Schedule Extended Prefix LSA */
rc = ospf_ext_schedule_prefix_index(ifp, srp->sid,
&srp->nhlfe.prefv4, srp->flags);
srp->instance = SET_OPAQUE_LSID(
OPAQUE_TYPE_EXTENDED_PREFIX_LSA, rc);
srp->instance = ospf_ext_schedule_prefix_index(ifp,
srp->sid, &srp->nhlfe.prefv4, srp->flags);
/* Install NHLFE if NO-PHP is requested */
if (CHECK_FLAG(srp->flags,
@ -2021,14 +2018,13 @@ DEFUN (sr_prefix_sid,
}
/* Finally, update Extended Prefix LSA */
rc = ospf_ext_schedule_prefix_index(ifp, srp->sid,
&srp->nhlfe.prefv4, srp->flags);
if (rc == 0) {
srp->instance = ospf_ext_schedule_prefix_index(ifp, srp->sid,
&srp->nhlfe.prefv4, srp->flags);
if (srp->instance) {
vty_out(vty, "Unable to set index %u for prefix %s/%u\n", index,
inet_ntoa(p.u.prefix4), p.prefixlen);
return CMD_WARNING;
}
srp->instance = SET_OPAQUE_LSID(OPAQUE_TYPE_EXTENDED_PREFIX_LSA, rc);
return CMD_SUCCESS;
}