summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@users.noreply.github.com>2019-05-07 22:41:20 +0200
committerGitHub <noreply@github.com>2019-05-07 22:41:20 +0200
commit6c90b756696900eb8cf649982b941659671558e1 (patch)
treec3c0deb5818681f74b5ca6f9d3a1b2b054cfb9a1
parentMerge pull request #4273 from donaldsharp/doc_zebra_command (diff)
parentospfd: Correct Link-ID and Remote IP for TE LSA (diff)
downloadfrr-6c90b756696900eb8cf649982b941659671558e1.tar.xz
frr-6c90b756696900eb8cf649982b941659671558e1.zip
Merge pull request #4215 from Orange-OpenSource/TE
ospfd: Correct Link-ID and Remote IP for TE LSA
-rw-r--r--ospfd/ospf_te.c195
1 files changed, 98 insertions, 97 deletions
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index bd8cbee11..1488aa88c 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -397,53 +397,13 @@ static void set_linkparams_link_type(struct ospf_interface *oi,
return;
}
-static void set_linkparams_link_id(struct ospf_interface *oi,
- struct mpls_te_link *lp)
+static void set_linkparams_link_id(struct mpls_te_link *lp,
+ struct in_addr link_id)
{
- struct ospf_neighbor *nbr;
- int done = 0;
lp->link_id.header.type = htons(TE_LINK_SUBTLV_LINK_ID);
lp->link_id.header.length = htons(TE_LINK_SUBTLV_DEF_SIZE);
-
- /*
- * The Link ID is identical to the contents of the Link ID field
- * in the Router LSA for these link types.
- */
- switch (oi->type) {
- case OSPF_IFTYPE_POINTOPOINT:
- /* Take the router ID of the neighbor. */
- if ((nbr = ospf_nbr_lookup_ptop(oi))
- && nbr->state == NSM_Full) {
- lp->link_id.value = nbr->router_id;
- done = 1;
- }
- break;
- case OSPF_IFTYPE_BROADCAST:
- case OSPF_IFTYPE_NBMA:
- /* Take the interface address of the designated router. */
- if ((nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi))) == NULL)
- break;
-
- if (nbr->state == NSM_Full
- || (IPV4_ADDR_SAME(&oi->address->u.prefix4, &DR(oi))
- && ospf_nbr_count(oi, NSM_Full) > 0)) {
- lp->link_id.value = DR(oi);
- done = 1;
- }
- break;
- default:
- /* Not supported yet. */ /* XXX */
- lp->link_id.header.type = htons(0);
- break;
- }
-
- if (!done) {
- struct in_addr mask;
- masklen2ip(oi->address->prefixlen, &mask);
- lp->link_id.value.s_addr =
- oi->address->u.prefix4.s_addr & mask.s_addr;
- }
+ lp->link_id.value = link_id;
return;
}
@@ -958,40 +918,33 @@ void ospf_mpls_te_update_if(struct interface *ifp)
return;
}
+/*
+ * Just add interface and set available information. Other information
+ * and flooding of LSA will be done later when adjacency will be up
+ * See ospf_mpls_te_nsm_change() after
+ */
static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state)
{
- struct te_link_subtlv_link_type old_type;
- struct te_link_subtlv_link_id old_id;
+
struct mpls_te_link *lp;
- if ((lp = lookup_linkparams_by_ifp(oi->ifp)) == NULL) {
+ lp = lookup_linkparams_by_ifp(oi->ifp);
+ if (lp == NULL) {
flog_warn(
EC_OSPF_TE_UNEXPECTED,
- "ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?",
- IF_NAME(oi));
+ "MPLS-TE (%s): Cannot get linkparams from OI(%s)?",
+ __func__, IF_NAME(oi));
return;
}
if (oi->area == NULL || oi->area->ospf == NULL) {
flog_warn(
EC_OSPF_TE_UNEXPECTED,
- "ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
- IF_NAME(oi));
+ "MPLS-TE (%s): Cannot refer to OSPF from OI(%s)?",
+ __func__, IF_NAME(oi));
return;
}
-#ifdef notyet
- if ((lp->area != NULL
- && !IPV4_ADDR_SAME(&lp->area->area_id, &oi->area->area_id))
- || (lp->area != NULL && oi->area == NULL)) {
- /* How should we consider this case? */
- flog_warn(
- EC_OSPF_TE_UNEXPECTED,
- "MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs",
- IF_NAME(oi),
- oi->area ? inet_ntoa(oi->area->area_id) : "N/A");
- ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
- }
-#endif
+
/* Keep Area information in combination with linkparams. */
lp->area = oi->area;
@@ -1003,55 +956,103 @@ static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_state)
case ISM_DROther:
case ISM_Backup:
case ISM_DR:
- old_type = lp->link_type;
- old_id = lp->link_id;
-
- /* Set Link type, Link ID, Local and Remote IP addr */
+ /* Set Link type and Local IP addr */
set_linkparams_link_type(oi, lp);
- set_linkparams_link_id(oi, lp);
set_linkparams_lclif_ipaddr(lp, oi->address->u.prefix4);
- if (oi->type == LINK_TYPE_SUBTLV_VALUE_PTP) {
- struct prefix *pref = CONNECTED_PREFIX(oi->connected);
- if (pref != NULL)
- set_linkparams_rmtif_ipaddr(lp,
- pref->u.prefix4);
- }
-
- /* Update TE parameters */
- update_linkparams(lp);
-
- /* Try to Schedule LSA */
- if ((ntohs(old_type.header.type)
- != ntohs(lp->link_type.header.type)
- || old_type.link_type.value
- != lp->link_type.link_type.value)
- || (ntohs(old_id.header.type)
- != ntohs(lp->link_id.header.type)
- || ntohl(old_id.value.s_addr)
- != ntohl(lp->link_id.value.s_addr))) {
- if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
- ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
- else
- ospf_mpls_te_lsa_schedule(lp,
- REORIGINATE_THIS_LSA);
- }
break;
default:
- lp->link_type.header.type = htons(0);
- lp->link_id.header.type = htons(0);
-
+ /* State is undefined: Flush LSA if engaged */
if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
break;
}
+ if (IS_DEBUG_OSPF_TE)
+ zlog_debug(
+ "MPLS-TE(%s): Update Link parameters for interface %s",
+ __func__, IF_NAME(oi));
+
return;
}
+/*
+ * Complete TE info and schedule LSA flooding
+ * Link-ID and Remote IP address must be set with neighbor info
+ * which are only valid once NSM state is FULL
+ */
static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state)
{
- /* Nothing to do here */
+ struct ospf_interface *oi = nbr->oi;
+ struct mpls_te_link *lp;
+
+ /* Process Neighbor only when its state is NSM Full */
+ if (nbr->state != NSM_Full)
+ return;
+
+ /* Get interface information for Traffic Engineering */
+ lp = lookup_linkparams_by_ifp(oi->ifp);
+ if (lp == NULL) {
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
+ "MPLS-TE (%s): Cannot get linkparams from OI(%s)?",
+ __func__, IF_NAME(oi));
+ return;
+ }
+
+ if (oi->area == NULL || oi->area->ospf == NULL) {
+ flog_warn(
+ EC_OSPF_TE_UNEXPECTED,
+ "MPLS-TE (%s): Cannot refer to OSPF from OI(%s)?",
+ __func__, IF_NAME(oi));
+ return;
+ }
+
+ /* Keep Area information in combination with SR info. */
+ lp->area = oi->area;
+
+ /* Keep interface MPLS-TE status */
+ lp->flags = HAS_LINK_PARAMS(oi->ifp);
+
+ /*
+ * The Link ID is identical to the contents of the Link ID field
+ * in the Router LSA for these link types.
+ */
+ switch (oi->state) {
+ case ISM_PointToPoint:
+ /* Set Link ID with neighbor Router ID */
+ set_linkparams_link_id(lp, nbr->router_id);
+ /* Set Remote IP address */
+ set_linkparams_rmtif_ipaddr(lp, nbr->address.u.prefix4);
+ break;
+
+ case ISM_DR:
+ case ISM_DROther:
+ case ISM_Backup:
+ /* Set Link ID with the Designated Router ID */
+ set_linkparams_link_id(lp, DR(oi));
+ break;
+
+ default:
+ /* State is undefined: Flush LSA if engaged */
+ if (OspfMplsTE.enabled &&
+ CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
+ ospf_mpls_te_lsa_schedule(lp, FLUSH_THIS_LSA);
+ return;
+ }
+
+ if (IS_DEBUG_OSPF_TE)
+ zlog_debug(
+ "MPLS-TE (%s): Add Link-ID %s for interface %s ",
+ __func__, inet_ntoa(lp->link_id.value), oi->ifp->name);
+
+ /* Try to Schedule LSA */
+ if (OspfMplsTE.enabled) {
+ if (CHECK_FLAG(lp->flags, LPFLG_LSA_ENGAGED))
+ ospf_mpls_te_lsa_schedule(lp, REFRESH_THIS_LSA);
+ else
+ ospf_mpls_te_lsa_schedule(lp, REORIGINATE_THIS_LSA);
+ }
return;
}