From db28a51f7e3b7ada03994e1fb4eb027fc9b37f11 Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Thu, 1 Feb 2018 14:30:34 +0100 Subject: [PATCH] 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 --- ospfd/ospf_ext.c | 17 ++++++++++------- ospfd/ospf_ext.h | 2 +- ospfd/ospf_sr.c | 14 +++++--------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c index 474f173cbd..afa70c0f16 100644 --- a/ospfd/ospf_ext.c +++ b/ospfd/ospf_ext.c @@ -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__); diff --git a/ospfd/ospf_ext.h b/ospfd/ospf_ext.h index 130faf6710..3ebca7f5dd 100644 --- a/ospfd/ospf_ext.h +++ b/ospfd/ospf_ext.h @@ -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); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 43f5d0e0bf..d906a4ce59 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -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; }