[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