[CUWiN-Dev] multiple gateways?

David Young dyoung at pobox.com
Wed Dec 14 03:40:55 CST 2005


On Tue, Dec 13, 2005 at 12:00:22PM -0600, Bill Comisky wrote:
> Upgrading the 2nd gateway did indeed fix the problem of the weird default 
> route.  We're still seeing a lot of hslsd core dumps though (running CUWiN 
> r3715 and the 8-Dec netbsd snapshot).  From the timestamps (and adjusting 
> for the watchdog timeout), they happen anywhere from immediately after 
> hslsd is restarted to 90 minutes later, with the mean at about 22 minutes.

I see a lot of coredumps, too.  It has been a serious operational
problem.

The segfaults only happen in a couple of places.  I haven't been able
to track down the root cause, but Router LSAs are implicated, always.
The Router LSA implementation was overly complicated.  Today, I simplified
a lot.  I have run the simplified code for more than an hour on four
routers without a single coredump.  Let's see what happens overnight.

I have attached a patch containing the simplifications, which shorten
the code by more than 200 lines.  Give them a try?

> I put the latest core files with the output from 'mkstaboot -S -S' here, 
> if they can tell you anything:
> http://flatiron.cntwireless.org/cuwin/12-Dec-2005/

Thanks.

Dave

-- 
David Young             OJC Technologies
dyoung at ojctech.com      Urbana, IL * (217) 278-3933
-------------- next part --------------
Index: hsls/hsls_ls_rtr.c
===================================================================
--- hsls/hsls_ls_rtr.c	(revision 3688)
+++ hsls/hsls_ls_rtr.c	(working copy)
@@ -234,12 +234,7 @@ static const struct hsls_ls_mtab orig_ls
 static u_int
 foreign_rtr_getmasklen(struct hsls_ls_rtr *lr)
 {
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	return ri->ri_masklen;
+	return lr->lr_if.ri_masklen;
 }
 
 static u_int
@@ -395,7 +390,6 @@ static int
 foreign_hsls_ls_rtr_verify(struct hsls_ls *hl)
 {
 	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
 	struct hpkt_rtrlsa_if *ri;
 	struct hpkt_rtrlsa_neighbor *rn;
 
@@ -403,28 +397,12 @@ foreign_hsls_ls_rtr_verify(struct hsls_l
 		return -1;
 
 	lr = (struct hsls_ls_rtr *)hl;
-	rh = &lr->lr_lsa;
-
-	if (lr->lr_which_if >= rh->rh_nif)
-		return -1;
-	if (rh->rh_ifs == NULL)
-		return -1;
-
-	ri = &rh->rh_ifs[lr->lr_which_if];
-
-	if (ri->ri_ifaddr == NULL)
-		return -1;
-	if (lr->lr_which_nbr >= ri->ri_nneighbor)
-		return -1;
-	if (ri->ri_neighbors == NULL)
-		return -1;
 
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
-	if (rn->rn_nbraddr == NULL)
-		return -1;
-
-	if (ri->ri_ifaddr->sa_family != rn->rn_nbraddr->sa_family)
+	if (ri->ri_ifaddr == NULL || rn->rn_nbraddr == NULL ||
+	    ri->ri_ifaddr->sa_family != rn->rn_nbraddr->sa_family)
 		return -1;
 
 	return 0;
@@ -459,21 +437,12 @@ static uint32_t
 foreign_hsls_ls_rtr_seqno(struct hsls_ls *hl)
 {
 	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-	struct hpkt_rtrlsa_neighbor *rn;
 
 	assert(foreign_hsls_ls_rtr_verify(hl) != -1);
 
 	lr = (struct hsls_ls_rtr *)hl;
 
-	rh = &lr->lr_lsa;
-
-	ri = &rh->rh_ifs[lr->lr_which_if];
-
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
-
-	return rn->rn_seqno;
+	return lr->lr_neighbor.rn_seqno;
 }
 
 static uint32_t
@@ -507,14 +476,10 @@ static sa_family_t
 foreign_hsls_ls_rtr_getfamily(struct hsls_ls *hl)
 {
 	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
 
 	lr = (struct hsls_ls_rtr *)hl;
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
 
-	return ri->ri_ifaddr->sa_family;
+	return lr->lr_if.ri_ifaddr->sa_family;
 }
 
 static enum hsls_join_rc
@@ -540,7 +505,6 @@ foreign_hsls_ls_rtr_update(struct hsls_l
 {
 	enum hsls_join_rc rc;
 	struct hsls_ls_rtr *nlr, *olr;
-	struct hpkt_rtrlsa_hdr *nrh, *orh;
 	struct hpkt_rtrlsa_if *nri, *ori;
 	struct hpkt_rtrlsa_neighbor *nrn, *orn;
 
@@ -549,14 +513,11 @@ foreign_hsls_ls_rtr_update(struct hsls_l
 	nlr = (struct hsls_ls_rtr *)nhl;
 	olr = (struct hsls_ls_rtr *)ohl;
 
-	nrh = &nlr->lr_lsa;
-	orh = &olr->lr_lsa;
-
-	ori = &orh->rh_ifs[olr->lr_which_if];
-	orn = &ori->ri_neighbors[olr->lr_which_nbr];
+	ori = &olr->lr_if;
+	orn = &olr->lr_neighbor;
 
-	nri = &nrh->rh_ifs[nlr->lr_which_if];
-	nrn = &nri->ri_neighbors[nlr->lr_which_nbr];
+	nri = &nlr->lr_if;
+	nrn = &nlr->lr_neighbor;
 
 	if ((rc = hpkt_rtrlsa_if_update(ori, nri)) == HSLS_JOIN_ERROR) {
 		LOGLIB_LOG(&log_ls, "%s: hpkt_rtrlsa_if_update failed",
@@ -607,14 +568,12 @@ foreign_hsls_ls_rtr_metric_get(struct hs
 {
 	int i;
 	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
 	struct hpkt_rtrlsa_if *ri;
 	struct hpkt_rtrlsa_neighbor *rn;
 
 	lr = (struct hsls_ls_rtr *)hl;
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
 	if (mtype == HSLS_METRIC_RADIUS) {
 		*valp = 1;
@@ -728,69 +687,22 @@ hsls_ls_rtr_alloc(enum hsls_net_type net
 	return lr;
 }
 
-static struct hsls_ls_rtr *
-foreign_hsls_ls_rtr_create(enum hsls_net_type nettype)
-{
-	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-	struct hpkt_rtrlsa_neighbor *rn;
-	static struct nmalloc_pool *ri_pool = NULL, *rn_pool = NULL;
-
-	if (ri_pool == NULL &&
-	    (ri_pool = nmalloc_pool_create("router lsa interface")) == NULL)
-		return NULL;
-
-	if (rn_pool == NULL &&
-	    (rn_pool = nmalloc_pool_create("router lsa neighbor")) == NULL)
-		return NULL;
-
-	if ((lr = hsls_ls_rtr_alloc(nettype, 0)) == NULL)
-		goto err;
-
-	if ((ri = nzmalloc(ri_pool, sizeof(*ri))) == NULL)
-		goto post_lr_err;
-
-	if ((rn = nzmalloc(rn_pool, sizeof(*rn))) == NULL)
-		goto post_ri_err;
-
-	lr->lr_which_if = lr->lr_which_nbr = 0;
-
-	rh = &lr->lr_lsa;
-	rh->rh_nif = 1;
-	rh->rh_ifs = ri;
-
-	ri->ri_nneighbor = 1;
-	ri->ri_neighbors = rn;
-
-	return lr;
-post_ri_err:
-	nfree(ri);
-post_lr_err:
-	hsls_ls_decref(&lr->lr_ls);
-err:
-	return NULL;
-}
-
 static struct hsls_ls *
 foreign_hsls_ls_rtr_dup(struct hsls_ls *hl)
 {
 	struct hsls_ls_rtr *lr, *olr;
-	struct hpkt_rtrlsa_hdr *rh, *orh;
 	struct hpkt_rtrlsa_if *ri, *ori;
 	struct hpkt_rtrlsa_neighbor *rn, *orn;
 
 	olr = (struct hsls_ls_rtr *)hl;
-	orh = &olr->lr_lsa;
-	ori = &orh->rh_ifs[olr->lr_which_if];
-	orn = &ori->ri_neighbors[olr->lr_which_nbr];
+	ori = &olr->lr_if;
+	orn = &olr->lr_neighbor;
 
-	if ((lr = foreign_hsls_ls_rtr_create(ori->ri_type)) == NULL)
+	if ((lr = hsls_ls_rtr_alloc(ori->ri_type, 0)) == NULL)
 		goto err;
 
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
 	if (hpkt_rtrlsa_if_copy(ri, ori) == -1)
 		goto post_lr_err;
@@ -810,19 +722,13 @@ foreign_hsls_ls_rtr_snprintf(struct hsls
 {
 	int accum_rc, rc;
 	struct hsls_ls_rtr *lr = (struct hsls_ls_rtr *)hl;
-	struct hpkt_rtrlsa_hdr *rh;
 	struct hpkt_rtrlsa_if *ri;
 	struct hpkt_rtrlsa_neighbor *rn;
 
 	assert((hl->hl_flags & HSLS_LS_F_ORIGINATED) == 0);
 
-	rh = &lr->lr_lsa;
-
-	assert(lr->lr_which_if < rh->rh_nif);
-	ri = &rh->rh_ifs[lr->lr_which_if];
-
-	assert(lr->lr_which_nbr < ri->ri_nneighbor);
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
 	accum_rc = snprintf(buf, buflen, "%d-ref foreign router lsa ",
 	    hl->hl_refcnt);
@@ -852,32 +758,43 @@ foreign_hsls_ls_rtr_snprintf(struct hsls
 
 static int
 hsls_ls_rtr_unpack_neighbor(void *buf, size_t buflen, sa_family_t family,
-    u_int nmetric, struct hpkt_rtrlsa_neighbor *rn, void **next)
+    struct hpkt_rtrlsa_if *ri, struct hsls_ls_workq *wq, void **next)
 {
+	int rc;
+	struct hsls_ls_rtr *lr;
+	struct hpkt_rtrlsa_neighbor *rn;
 	static struct nmalloc_pool *pool = NULL;
 
+	*next = buf;
+
 	if (pool == NULL &&
 	    (pool = nmalloc_pool_create("neighbor metrics")) == NULL)
 		return -1;
 
-	rn->rn_nmetric = nmetric;
+	/* XXX HSLS_NET_T_PTMP is just a default; it will be overwritten. */
+	if ((lr = hsls_ls_rtr_alloc(HSLS_NET_T_PTMP, 0)) == NULL)
+		return -1;
+
+	if (hpkt_rtrlsa_if_copy(&lr->lr_if, ri) == -1)
+		goto post_lr_err;
+
+	rn = &lr->lr_neighbor;
+	rn->rn_nmetric = ri->ri_nmetric;	/* XXX get rid of rn_nmetric? */
 	if (rn->rn_nmetric == 0)
 		rn->rn_metrics = NULL;
-	else {
-		rn->rn_metrics = nzmalloc(pool, sizeof(*rn->rn_metrics) *
-		    rn->rn_nmetric);
-		if (rn->rn_metrics == NULL) {
-			loglib_warnx("%s: failed metrics allocation", __func__);
-			goto err;
-		}
+	else if ((rn->rn_metrics = nzmalloc(pool,
+	             sizeof(*rn->rn_metrics) * rn->rn_nmetric)) == NULL) {
+		rn->rn_nmetric = 0;
+		loglib_warn("%s: nzmalloc", __func__);
+		goto post_lr_err;
 	}
 
-	*next = hpkt_rtrlsa_neighbor_unpack(buf, buflen, family, rn);
+	rc = hpkt_rtrlsa_neighbor_unpack(buf, buflen, family, rn, next);
 
-	if (*next == NULL) {
+	if (rc == -1) {
 		LOGLIB_LOG(&log_pack_err,
-		    "PACKERR hpkt_rtrlsa_neighbor_unpack failed");
-		goto post_mtrs_err;
+		    "%s: hpkt_rtrlsa_neighbor_unpack", __func__);
+		goto post_lr_err;
 	}
 
 	LOGLIB_LOG(&log_pkt,
@@ -886,17 +803,15 @@ hsls_ls_rtr_unpack_neighbor(void *buf, s
 	    rn->rn_nmetric, sockaddrtoa("%a", rn->rn_nbraddr),
 	    raw_metricstoa(rn->rn_metrics, rn->rn_nmetric));
 
+	WQ_INSERT_TAIL(wq, &lr->lr_ls, hl_workq_next);
 	return 0;
-post_mtrs_err:
-	if (rn->rn_metrics != NULL)
-		nfree(rn->rn_metrics);
-	rn->rn_metrics = NULL;
-	rn->rn_nmetric = 0;
-err:
+post_lr_err:
+	hsls_ls_decref(&lr->lr_ls);
 	*next = buf;
 	return -1;
 }
 
+#if 0
 static void
 hsls_ls_rtr_check_if(struct hpkt_rtrlsa_if *ri, const char *func)
 {
@@ -928,65 +843,46 @@ hsls_ls_rtr_check_if(struct hpkt_rtrlsa_
 	    __func__, ri->ri_nmetric, max_nmetric, func);
 #endif /* DIAGNOSTIC */
 }
+#endif
 
 static int
-hsls_ls_rtr_unpack_if(void *buf, size_t buflen, sa_family_t family,
-    struct hpkt_rtrlsa_if *ri, void **next)
+hsls_ls_rtr_unpack_if(void *buf, size_t buflen, struct hpkt_rtrlsa_hdr *rh,
+    sa_family_t family, struct hsls_ls_workq *wq, void **next)
 {
+	struct hpkt_rtrlsa_if ri;
+	struct sockaddr_storage ss;
 	int i, rc;
-	static struct nmalloc_pool *pool = NULL;
-
-	if (pool == NULL &&
-	    (pool = nmalloc_pool_create("neighbor array")) == NULL)
-		return -1;
 
-	rc = hpkt_rtrlsa_if_unpack(buf, buflen, family,
-	    &ri->ri_flags, &ri->ri_type, &ri->ri_nmetric, &ri->ri_nneighbor,
-	    &ri->ri_masklen, &ri->ri_ifindex, &ri->ri_ifaddr, next);
+	(void)memset(&ri, 0, sizeof(ri));
+	ri.ri_ifaddr = lintfree_cast(struct sockaddr *)&ss;
+	rc = hpkt_rtrlsa_if_unpack(buf, buflen, family, &ri, next);
 
 	if (rc == -1) {
-		LOGLIB_LOG(&log_pack_err,
-		    "PACKERR hpkt_rtrlsa_if_unpack failed");
+		LOGLIB_LOG(&log_pack_err, "%s: hpkt_rtrlsa_if_unpack failed",
+		    __func__);
 		goto err;
 	}
 
 	LOGLIB_LOG(&log_pkt, "interface type %s, %d metrics, "
 	    "%u neighbors, masklen %u, index %u, address %s",
-	    hsls_nettype_string(ri->ri_type), ri->ri_nmetric, ri->ri_nneighbor,
-	    ri->ri_masklen, ri->ri_ifindex, sockaddrtoa("%a", ri->ri_ifaddr));
-
-	if (ri->ri_nneighbor == 0) {
-		ri->ri_neighbors = NULL;
-		return 0;
-	}
-
-	ri->ri_neighbors = nzmalloc(pool, sizeof(*ri->ri_neighbors) *
-	    ri->ri_nneighbor);
-
-	if (ri->ri_neighbors == NULL) {
-		LOGLIB_LOG(&log_warn, "%s: allocate neighbors, failed",
-		    __func__);
-		goto err;
-	}
+	    hsls_nettype_string(ri.ri_type), ri.ri_nmetric, ri.ri_nneighbor,
+	    ri.ri_masklen, ri.ri_ifindex, sockaddrtoa("%a", ri.ri_ifaddr));
 
-	for (i = 0; i < ri->ri_nneighbor; i++) {
+	for (i = 0; i < ri.ri_nneighbor; i++) {
 		rc = hsls_ls_rtr_unpack_neighbor(*next,
-		    buflen - byte_difference(*next, buf), family,
-		    ri->ri_nmetric, &ri->ri_neighbors[i], next);
+		    buflen - byte_difference(*next, buf), family, &ri, wq,
+		    next);
 		if (rc == -1)
-			goto post_nbrs_err;
+			goto err;
 	}
-
+#if 0
 	hsls_ls_rtr_check_if(ri, __func__);
+#endif
 
 	return 0;
-post_nbrs_err:
-	nfree(ri->ri_neighbors);
-	ri->ri_nneighbor = 0;
-	ri->ri_neighbors = NULL;
 err:
-	sockaddr_free(ri->ri_ifaddr);
-	ri->ri_ifaddr = NULL;
+	sockaddr_free(ri.ri_ifaddr);
+	ri.ri_ifaddr = NULL;
 	*next = buf;
 	return -1;
 }
@@ -1012,84 +908,45 @@ hsls_ls_rtr_hash(struct hsls_ls *hl, int
 }
 
 static void
-foreign_hsls_ls_rtr_destroy_neighbor(struct hpkt_rtrlsa_neighbor *rn)
+hpkt_rtrlsa_neighbor_cleanup(struct hpkt_rtrlsa_neighbor *rn)
 {
-	struct sockaddr *sa;
+	LOGLIB_LOG(&log_ls, "%s: %p", __func__, (void *)rn);
 	if (rn->rn_metrics != NULL) {
 		nfree(rn->rn_metrics);
 		rn->rn_metrics = NULL;
 		rn->rn_nmetric = 0;
 	}
-	sa = rn->rn_nbraddr;
-	rn->rn_nbraddr = NULL;
-	if (sa != NULL)
-		sockaddr_free(sa);
-	LOGLIB_LOG(&log_ls, "%s: destroyed %p", __func__, (void *)rn);
+	if (rn->rn_nbraddr != NULL) {
+		sockaddr_free(rn->rn_nbraddr);
+		rn->rn_nbraddr = NULL;
+	}
 }
 
 static void
-foreign_hsls_ls_rtr_destroy_if(struct hpkt_rtrlsa_if *ri)
+hpkt_rtrlsa_if_cleanup(struct hpkt_rtrlsa_if *ri)
 {
-	int i;
-	struct sockaddr *sa;
-	LOGLIB_LOG(&log_ls, "%s: enter %p", __func__, (void *)ri);
-	for (i = 0; i < ri->ri_nneighbor; i++) {
-		foreign_hsls_ls_rtr_destroy_neighbor(&ri->ri_neighbors[i]);
+	LOGLIB_LOG(&log_ls, "%s: %p", __func__, (void *)ri);
+	if (ri->ri_ifaddr != NULL) {
+		sockaddr_free(ri->ri_ifaddr);
+		ri->ri_ifaddr = NULL;
 	}
-	if (ri->ri_neighbors != NULL) {
-		nfree(ri->ri_neighbors);
-		ri->ri_neighbors = NULL;
-	}
-	sa = ri->ri_ifaddr;
-	ri->ri_ifaddr = NULL;
-	if (sa != NULL)
-		sockaddr_free(sa);
-	LOGLIB_LOG(&log_ls, "%s: exit %p", __func__, (void *)ri);
 }
 
 static void
 foreign_hsls_ls_rtr_destroy(struct hsls_ls *hl)
 {
-	int i;
-	u_int which_if, which_nbr;
 	struct hsls_ls_rtr *lr;
-	struct hsls_ls *parent;
-	struct hpkt_rtrlsa_hdr *rh;
 
-	assert(hl->hl_refcnt == 0);
-	lr = (struct hsls_ls_rtr *)hl;
-	rh = &lr->lr_lsa;
+	LOGLIB_LOG(&log_ls, "%s: %p", __func__, (void *)hl);
 
-	if (lr->lr_parent != NULL) {
-		parent = &lr->lr_parent->lr_ls;
-		which_if = lr->lr_which_if;
-		which_nbr = lr->lr_which_nbr;
-		nfree(lr);
-		LOGLIB_LOG(&log_ls, "%s: destroyed %p (if %u, nbr %u)",
-		    __func__, (void *)hl, which_if, which_nbr);
-		hsls_ls_decref(parent);
-		return;
-	}
-
-	rh = &lr->lr_lsa;
-	hl = &lr->lr_ls;
-
-	which_if = lr->lr_which_if;
-	which_nbr = lr->lr_which_nbr;
+	assert(hl->hl_refcnt == 0);
 
-	for (i = 0; i < rh->rh_nif; i++)
-		foreign_hsls_ls_rtr_destroy_if(&rh->rh_ifs[i]);
+	lr = (struct hsls_ls_rtr *)hl;
 
-	if (rh->rh_ifs != NULL) {
-		nfree(rh->rh_ifs);
-		rh->rh_ifs = NULL;
-	}
-	rh->rh_nif = 0;
+	hpkt_rtrlsa_if_cleanup(&lr->lr_if);
+	hpkt_rtrlsa_neighbor_cleanup(&lr->lr_neighbor);
 
 	nfree(lr);
-	LOGLIB_LOG(&log_ls, "%s: destroyed %p (if %u, nbr %u)", __func__,
-	    (void *)hl, which_if, which_nbr);
-	return;
 }
 
 static void
@@ -1108,11 +965,7 @@ orig_hsls_ls_rtr_destroy(struct hsls_ls 
 static const struct sockaddr *
 foreign_hsls_ls_rtr_getnbraddr(struct hsls_ls_rtr *lr)
 {
-	struct hpkt_rtrlsa_if *ri;
-
-	ri = &lr->lr_lsa.rh_ifs[lr->lr_which_if];
-
-	return ri->ri_neighbors[lr->lr_which_nbr].rn_nbraddr;
+	return lr->lr_neighbor.rn_nbraddr;
 }
 
 static const struct sockaddr *
@@ -1126,7 +979,7 @@ orig_hsls_ls_rtr_getnbraddr(struct hsls_
 static const struct sockaddr *
 foreign_hsls_ls_rtr_getifaddr(struct hsls_ls_rtr *lr)
 {
-	return lr->lr_lsa.rh_ifs[lr->lr_which_if].ri_ifaddr;
+	return lr->lr_if.ri_ifaddr;
 }
 
 static const struct sockaddr *
@@ -1172,12 +1025,7 @@ orig_ls_rtr_nettype(struct hsls_ls_rtr *
 static enum hsls_net_type
 foreign_ls_rtr_nettype(struct hsls_ls_rtr *lr)
 {
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	return ri->ri_type;
+	return lr->lr_if.ri_type;
 }
 
 static int
@@ -1220,13 +1068,7 @@ hsls_ls_rtr_vizdump(struct hsls_ls *hl, 
 static u_int
 foreign_hsls_ls_rtr_metrics_count(struct hsls_ls_rtr *lr)
 {
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-	struct hpkt_rtrlsa_neighbor *rn;
-
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	const struct hpkt_rtrlsa_neighbor *rn = &lr->lr_neighbor;
 	return raw_metrics_hopcounts_suppress(rn->rn_metrics, rn->rn_nmetric);
 }
 
@@ -1282,13 +1124,11 @@ static int
 foreign_hsls_ls_rtr_pack_if(struct hsls_ls_rtr *lr, uint16_t **ncountp,
     void *buf, size_t buflen, void **next)
 {
-	struct hpkt_rtrlsa_hdr *rh;
-	struct hpkt_rtrlsa_if *ri;
-
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
+	const struct hpkt_rtrlsa_if *ri = &lr->lr_if;
 
+#if 0
 	hsls_ls_rtr_check_if(ri, __func__);
+#endif
 
 	return hpkt_rtrlsa_if_pack(buf, buflen, 0, ri->ri_type, ri->ri_nmetric,
 	    ncountp, ri->ri_masklen, ri->ri_ifindex, ri->ri_ifaddr, next);
@@ -1298,16 +1138,13 @@ static int
 foreign_hsls_ls_rtr_pack_neighbor(struct hsls_ls_rtr *lr, u_int nmetric,
     void *buf, size_t buflen, void **next)
 {
-	struct hpkt_rtrlsa_hdr *rh;
 	struct hpkt_rtrlsa_if *ri;
 	struct hpkt_rtrlsa_neighbor *rn;
 
 	assert((lr->lr_ls.hl_flags & HSLS_LS_F_ORIGINATED) == 0);
 
-	rh = &lr->lr_lsa;
-
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
 	LOGLIB_LOG(&log_pack_metric_rtr, "%s: packing %u metrics", __func__,
 	    ri->ri_nmetric);
@@ -1467,114 +1304,45 @@ err:
 		return 1;		/* some interfaces & peers */
 }
 
-static int
-foreign_hsls_ls_rtr_split_nbrs(struct hsls_ls_rtr *parent,
-    struct hpkt_rtrlsa_if *ri, u_int which_if, struct hsls_ls_workq *wq)
-{
-	int refcnt;
-	u_int which_nbr;
-	struct hsls_ls_rtr *lr;
-
-	for (which_nbr = 0; which_nbr < ri->ri_nneighbor; which_nbr++) {
-		if ((lr = hsls_ls_rtr_alloc(ri->ri_type, 0)) == NULL)
-			return -1;
-		lr->lr_lsa = parent->lr_lsa;
-		lr->lr_parent = parent;
-		refcnt = hsls_ls_incref(&parent->lr_ls);
-		LOGLIB_LOG(&log_ls, "LS %p child of %p (refcnt %d)", (void *)lr,
-		    (void *)parent, refcnt);
-
-		lr->lr_which_if = which_if;
-		lr->lr_which_nbr = which_nbr;
-		hsls_ls_rtr_check_if(ri, __func__);
-		WQ_INSERT_TAIL(wq, &lr->lr_ls, hl_workq_next);
-	}
-	return 0;
-}
-
-static int
-foreign_hsls_ls_rtr_split_ifs(struct hsls_ls_rtr *lr, struct hsls_ls_workq *wq)
-{
-	int rc, which_if;
-	struct hpkt_rtrlsa_hdr *rh;
-
-	rh = &lr->lr_lsa;
-
-	for (which_if = 0; which_if < rh->rh_nif; which_if++) {
-		struct hpkt_rtrlsa_if *ri = &rh->rh_ifs[which_if];
-
-		rc = foreign_hsls_ls_rtr_split_nbrs(lr, ri,
-		    which_if, wq);
-		if (rc == -1)
-			return -1;
-		hsls_ls_rtr_check_if(ri, __func__);
-	}
-	return 0;
-}
-
 int
 hsls_ls_rtr_unpack(void *buf, size_t buflen, sa_family_t family,
     struct hsls_ls_workq *wq, void **next)
 {
 	int i, rc;
-	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
+	struct hpkt_rtrlsa_hdr rh;
 	static struct nmalloc_pool *pool = NULL;
 
 	if (pool == NULL &&
 	    (pool = nmalloc_pool_create("interface array")) == NULL)
 		return -1;
 
-	/* XXX HSLS_NET_T_PTMP is just a default; it will be overwritten. */
-	if ((lr = hsls_ls_rtr_alloc(HSLS_NET_T_PTMP, 0)) == NULL)
-		goto err;
-
-	rh = &lr->lr_lsa;
-
-	if ((rc = hpkt_rtr_hdr_unpack(buf, buflen, &rh->rh_nif, next)) == -1) {
+	if ((rc = hpkt_rtr_hdr_unpack(buf, buflen, &rh.rh_nif, next)) == -1) {
 		LOGLIB_LOG(&log_pack_err,
 		    "PACKERR hsls_ls_rtr_unpack failed");
-		goto post_ls_err;
+		goto err;
 	}
 
-	if (rh->rh_nif == 0) {
+	if (rh.rh_nif == 0) {
 		LOGLIB_LOG(&log_malformed, "%s: no interfaces, failed",
 		    __func__);
-		goto post_ls_err;
+		goto err;
 	}
 
 	LOGLIB_LOG(&log_pkt, "%s: Router LSA; %u interfaces", __func__,
-	    rh->rh_nif);
+	    rh.rh_nif);
 
-	rh->rh_ifs = nzmalloc(pool, rh->rh_nif * sizeof(*rh->rh_ifs));
-
-	if (rh->rh_ifs == NULL) {
-		LOGLIB_LOG(&log_warn,
-		    "%s: could not allocate Router LSA ifs", __func__);
-		goto post_ls_err;
-	}
-
-	for (i = 0; i < rh->rh_nif; i++) {
+	for (i = 0; i < rh.rh_nif; i++) {
 		rc = hsls_ls_rtr_unpack_if(*next,
-		    buflen - byte_difference(*next, buf), family,
-		    &rh->rh_ifs[i], next);
+		    buflen - byte_difference(*next, buf), &rh, family, wq,
+		    next);
 		if (rc == -1) {
 			LOGLIB_LOG(&log_pack_err,
 			    "PACKERR hsls_ls_rtr_unpack_if failed");
-			goto post_ifs_err;
+			goto err;
 		}
 	}
 
-	rc = foreign_hsls_ls_rtr_split_ifs(lr, wq);
-	hsls_ls_decref(&lr->lr_ls);
 	return rc;
-post_ifs_err:
-	nfree(rh->rh_ifs);
-	rh->rh_nif = 0;
-	rh->rh_ifs = NULL;
-post_ls_err:
-	hsls_ls_decref(&lr->lr_ls);
-	lr = NULL;
 err:
 	*next = buf;
 	return -1;
@@ -1606,7 +1374,6 @@ foreign_hsls_ls_rtr_reverse(struct hsls_
 {
 	struct hsls_ls *hl;
 	struct hsls_ls_rtr *lr;
-	struct hpkt_rtrlsa_hdr *rh;
 	struct hpkt_rtrlsa_if *ri;
 	struct hpkt_rtrlsa_neighbor *rn;
 	struct sockaddr *tmp;
@@ -1616,9 +1383,8 @@ foreign_hsls_ls_rtr_reverse(struct hsls_
 
 	lr = (struct hsls_ls_rtr *)hl;
 
-	rh = &lr->lr_lsa;
-	ri = &rh->rh_ifs[lr->lr_which_if];
-	rn = &ri->ri_neighbors[lr->lr_which_nbr];
+	ri = &lr->lr_if;
+	rn = &lr->lr_neighbor;
 
 	tmp = rn->rn_nbraddr;
 	rn->rn_nbraddr = ri->ri_ifaddr;
Index: hsls/hsls_ls_rtr.h
===================================================================
--- hsls/hsls_ls_rtr.h	(revision 3658)
+++ hsls/hsls_ls_rtr.h	(working copy)
@@ -82,18 +82,16 @@ struct hsls_ls_rtr {
 	union {
 		struct hsls_peer	*u_peer;
 		struct {
-			struct hpkt_rtrlsa_hdr	f_lsa;
-			u_int			f_which_if;
-			u_int			f_which_nbr;
-			struct hsls_ls_rtr	*f_parent;
+			struct hpkt_rtrlsa_hdr		f_hdr;
+			struct hpkt_rtrlsa_if		f_if;
+			struct hpkt_rtrlsa_neighbor	f_neighbor;
 		} u_foreign;
 	} lr_u;
 #define	lr_peer lr_u.u_peer
 #define	lr_stub lr_u.u_stub
-#define	lr_lsa lr_u.u_foreign.f_lsa
-#define	lr_which_if lr_u.u_foreign.f_which_if
-#define	lr_which_nbr lr_u.u_foreign.f_which_nbr
-#define	lr_parent lr_u.u_foreign.f_parent
+#define	lr_hdr lr_u.u_foreign.f_hdr
+#define	lr_if lr_u.u_foreign.f_if
+#define	lr_neighbor lr_u.u_foreign.f_neighbor
 };
 
 struct hsls_ls_rtr_mtab {
Index: hsls/hsls_pkt.c
===================================================================
--- hsls/hsls_pkt.c	(revision 3658)
+++ hsls/hsls_pkt.c	(working copy)
@@ -656,9 +656,7 @@ hpkt_rtrlsa_hdr_pack(void *buf, size_t b
 
 int
 hpkt_rtrlsa_if_unpack(void *buf, size_t buflen, sa_family_t family,
-    uint32_t *flagsp, enum hsls_net_type *iftypep, uint8_t *nmetricp,
-    uint16_t *ncountp, uint16_t *masklenp, uint16_t *ifindexp,
-    struct sockaddr **ifaddr, void **next)
+    struct hpkt_rtrlsa_if *ri, void **next)
 {
 	socklen_t addrlen;
 	uint8_t iftype;
@@ -667,33 +665,32 @@ hpkt_rtrlsa_if_unpack(void *buf, size_t 
 	union anyaddr zero;
 
 	(void)memset(&zero, 0, sizeof(zero));
-	if ((*ifaddr = sockaddr_create(family, &zero, 0)) == NULL) {
-		LOGLIB_LOG(&log_err,
-		    "%s: failed to create socket", __func__);
+	if (sockaddr_init(ri->ri_ifaddr, family, &zero, 0) == NULL) {
+		LOGLIB_LOG(&log_err, "%s: failed to create socket", __func__);
 		goto err;
 	}
 
-	if ((addr = sockaddr_addr(*ifaddr, &addrlen)) == NULL) {
+	if ((addr = sockaddr_addr(ri->ri_ifaddr, &addrlen)) == NULL) {
 		LOGLIB_LOG(&log_err, "%s: sockaddr_addr failed", __func__);
 		goto post_ifalloc_err;
 	}
 
 	rc = unpack(buf, buflen,
 	    MUST_DWORD_ALIGN HPKT_RTRLSA_INTERFACE_FMT MUST_DWORD_ALIGN,
-	    &start, flagsp, &iftype, nmetricp, ncountp, masklenp, ifindexp,
-	    addrlen, addr, next);
+	    &start, &ri->ri_flags, &iftype, &ri->ri_nmetric, &ri->ri_nneighbor,
+	    &ri->ri_masklen, &ri->ri_ifindex, addrlen, addr, next);
 
 	if (rc != 9) {
 		LOGLIB_LOG(&log_pack_any, "%s: unpack failed", __func__);
 		goto post_ifalloc_err;
 	}
 
-	*iftypep = iftype;
+	ri->ri_type = iftype;
 
 	return 0;
 post_ifalloc_err:
-	sockaddr_free(*ifaddr);
-	*ifaddr = NULL;
+	sockaddr_free(ri->ri_ifaddr);
+	ri->ri_ifaddr = NULL;
 err:
 	*next = buf;
 	return -1;
@@ -733,18 +730,20 @@ err:
 	return -1;
 }
 
-void *
+int
 hpkt_rtrlsa_neighbor_unpack(void *buf, size_t buflen, sa_family_t family,
-    struct hpkt_rtrlsa_neighbor *rn)
+    struct hpkt_rtrlsa_neighbor *rn, void **next)
 {
 	socklen_t addrlen;
 	int rc;
-	void *addr, *end, *start;
+	void *addr, *start;
 	union anyaddr zero;
 
+	*next = buf;
+
 	(void)memset(&zero, 0, sizeof(zero));
 	if ((rn->rn_nbraddr = sockaddr_create(family, &zero, 0)) == NULL)
-		return NULL;
+		return -1;
 
 	if ((addr = sockaddr_addr(rn->rn_nbraddr, &addrlen)) == NULL)
 		goto err;
@@ -752,7 +751,7 @@ hpkt_rtrlsa_neighbor_unpack(void *buf, s
 	rc = unpack(buf, buflen,
 	    MUST_DWORD_ALIGN HPKT_RTRLSA_NEIGHBOR_FMT MUST_DWORD_ALIGN,
 	    &start, &rn->rn_seqno, &rn->rn_flags, rn->rn_nmetric,
-	    rn->rn_metrics, addrlen, addr, &end);
+	    rn->rn_metrics, addrlen, addr, next);
 
 	if (rc != 6) {
 		LOGLIB_LOG(&log_pack_any, "%s: unpack yields %d, nmetric %u",
@@ -762,11 +761,12 @@ hpkt_rtrlsa_neighbor_unpack(void *buf, s
 
 	LOGLIB_LOG(&log_pack_metric, "%s: %d metrics", __func__,
 	    rn->rn_nmetric);
-	return end;
+	return 0;
 err:
 	sockaddr_free(rn->rn_nbraddr);
 	rn->rn_nbraddr = NULL;
-	return NULL;
+	*next = buf;
+	return -1;
 }
 
 int
@@ -991,35 +991,33 @@ int
 hpkt_rtrlsa_neighbor_copy(struct hpkt_rtrlsa_neighbor *nrn,
     struct hpkt_rtrlsa_neighbor *orn)
 {
-	struct sockaddr *sa;
 	uint32_t *metrics;
 	static struct nmalloc_pool *pool = NULL;
 
 	if (pool == NULL && (pool = nmalloc_pool_create(__func__)) == NULL)
 		return -1;
 
-	if ((sa = sockaddr_dup(orn->rn_nbraddr)) == NULL)
+	if ((nrn->rn_nbraddr = sockaddr_dup(orn->rn_nbraddr)) == NULL)
 		return -1;
 
 	if (orn->rn_metrics == NULL)
 		metrics = NULL;
 	else if ((metrics = nmalloc(pool,
 	    orn->rn_nmetric * sizeof(*metrics))) == NULL)
-		goto post_sa_err;
+		goto post_nbraddr_err;
 	else {
 		(void)memcpy(metrics, orn->rn_metrics,
 		    orn->rn_nmetric * sizeof(*metrics));
 	}
 
-	nrn->rn_nbraddr	=	sa;
 	nrn->rn_flags	=	orn->rn_flags;
 	nrn->rn_seqno	=	orn->rn_seqno;
 	nrn->rn_metrics	=	metrics;
 	nrn->rn_nmetric	=	orn->rn_nmetric;
 
 	return 0;
-post_sa_err:
-	sockaddr_free(sa);
+post_nbraddr_err:
+	sockaddr_free(nrn->rn_nbraddr);
 	return -1;
 }
 
@@ -1040,11 +1038,9 @@ hpkt_bpllsa_if_copy(struct hpkt_bpllsa_i
 int
 hpkt_rtrlsa_if_copy(struct hpkt_rtrlsa_if *nri, struct hpkt_rtrlsa_if *ori)
 {
-	struct sockaddr *sa;
-	if ((sa = sockaddr_dup(ori->ri_ifaddr)) == NULL)
+	if ((nri->ri_ifaddr = sockaddr_dup(ori->ri_ifaddr)) == NULL)
 		return -1;
 
-	nri->ri_ifaddr	=	sa;
 	nri->ri_flags	=	ori->ri_flags;
 	nri->ri_ifindex	=	ori->ri_ifindex;
 	nri->ri_masklen	=	ori->ri_masklen;
Index: hsls/hsls_pkt.h
===================================================================
--- hsls/hsls_pkt.h	(revision 3658)
+++ hsls/hsls_pkt.h	(working copy)
@@ -328,14 +328,13 @@ struct hpkt_rtrlsa_if {
 							 * required for BCAST
 							 * networks (neighbors
 							 * are listed in the
-							 * Router LSA).  1 or
+							 * Network LSA).  1 or
 							 * greater required for
 							 * PtMP, PtP.
 							 */
 	uint16_t			ri_masklen;
 	uint16_t			ri_ifindex;
 	struct sockaddr 		*ri_ifaddr;
-	struct hpkt_rtrlsa_neighbor	*ri_neighbors;
 };
 
 struct hpkt_rtrlsa_hdr {
@@ -384,16 +383,15 @@ int hpkt_bpllsa_if_copy(struct hpkt_bpll
 enum hsls_join_rc hpkt_bpllsa_if_update(struct hpkt_bpllsa_if *,
     struct hpkt_bpllsa_if *);
 
-int hpkt_rtrlsa_if_unpack(void *, size_t, sa_family_t,
-    uint32_t *, enum hsls_net_type *, uint8_t *, uint16_t *, uint16_t *,
-    uint16_t *, struct sockaddr **, void **);
+int hpkt_rtrlsa_if_unpack(void *, size_t, sa_family_t, struct hpkt_rtrlsa_if *,
+    void **);
 
 int hpkt_rtrlsa_if_pack(void *, size_t, uint32_t,
     enum hsls_net_type, uint8_t, uint16_t **, uint16_t, uint16_t,
     const struct sockaddr *, void **);
 
-void *hpkt_rtrlsa_neighbor_unpack(void *, size_t, sa_family_t,
-    struct hpkt_rtrlsa_neighbor *);
+int hpkt_rtrlsa_neighbor_unpack(void *, size_t, sa_family_t,
+    struct hpkt_rtrlsa_neighbor *, void **);
 
 int hpkt_rtrlsa_neighbor_pack(void *, size_t, uint32_t, uint32_t,
     uint32_t *, u_int, const struct sockaddr *, void **);


More information about the CU-Wireless-Dev mailing list