Changes OSPF to generate stub networks for non-primary addresses.
Also does some reorganization in RT LSA announcement.
This commit is contained in:
parent
b99d378698
commit
3d15dcdb1c
6 changed files with 184 additions and 109 deletions
|
@ -327,6 +327,42 @@ mb_allocz(pool *p, unsigned size)
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mb_realloc - reallocate a memory block
|
||||||
|
* @p: pool
|
||||||
|
* @m: memory block
|
||||||
|
* @size: new size of the block
|
||||||
|
*
|
||||||
|
* mb_realloc() changes the size of the memory block @m to a given size.
|
||||||
|
* The contents will be unchanged to the minimum of the old and new sizes;
|
||||||
|
* newly allocated memory will be uninitialized. If @m is NULL, the call
|
||||||
|
* is equivalent to mb_alloc(@p, @size).
|
||||||
|
*
|
||||||
|
* Like mb_alloc(), mb_realloc() also returns a pointer to the memory
|
||||||
|
* chunk , not to the resource, hence you have to free it using
|
||||||
|
* mb_free(), not rfree().
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
mb_realloc(pool *p, void *m, unsigned size)
|
||||||
|
{
|
||||||
|
struct mblock *ob = NULL;
|
||||||
|
|
||||||
|
if (m)
|
||||||
|
{
|
||||||
|
ob = SKIP_BACK(struct mblock, data, m);
|
||||||
|
if (ob->r.n.next)
|
||||||
|
rem_node(&ob->r.n);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mblock *b = xrealloc(ob, sizeof(struct mblock) + size);
|
||||||
|
|
||||||
|
b->r.class = &mb_class;
|
||||||
|
add_tail(&p->inside, &b->r.n);
|
||||||
|
b->size = size;
|
||||||
|
return b->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mb_free - free a memory block
|
* mb_free - free a memory block
|
||||||
* @m: memory block
|
* @m: memory block
|
||||||
|
@ -339,3 +375,4 @@ mb_free(void *m)
|
||||||
struct mblock *b = SKIP_BACK(struct mblock, data, m);
|
struct mblock *b = SKIP_BACK(struct mblock, data, m);
|
||||||
rfree(b);
|
rfree(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern pool root_pool;
|
||||||
|
|
||||||
void *mb_alloc(pool *, unsigned size);
|
void *mb_alloc(pool *, unsigned size);
|
||||||
void *mb_allocz(pool *, unsigned size);
|
void *mb_allocz(pool *, unsigned size);
|
||||||
|
void *mb_realloc(pool *p, void *m, unsigned size);
|
||||||
void mb_free(void *);
|
void mb_free(void *);
|
||||||
|
|
||||||
/* Memory pools with linear allocation */
|
/* Memory pools with linear allocation */
|
||||||
|
@ -75,12 +76,13 @@ void sl_free(slab *, void *);
|
||||||
#ifdef HAVE_LIBDMALLOC
|
#ifdef HAVE_LIBDMALLOC
|
||||||
/*
|
/*
|
||||||
* The standard dmalloc macros tend to produce lots of namespace
|
* The standard dmalloc macros tend to produce lots of namespace
|
||||||
* conflicts and we use only xmalloc and xfree, so we can define
|
* conflicts and we use only xmalloc, xrealloc and xfree, so we
|
||||||
* the stubs ourselves.
|
* can define the stubs ourselves.
|
||||||
*/
|
*/
|
||||||
#define DMALLOC_DISABLE
|
#define DMALLOC_DISABLE
|
||||||
#include <dmalloc.h>
|
#include <dmalloc.h>
|
||||||
#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
|
#define xmalloc(size) _xmalloc_leap(__FILE__, __LINE__, size)
|
||||||
|
#define xrealloc(size) _xrealloc_leap(__FILE__, __LINE__, size)
|
||||||
#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
|
#define xfree(ptr) _xfree_leap(__FILE__, __LINE__, ptr)
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
|
@ -89,7 +91,9 @@ void sl_free(slab *, void *);
|
||||||
* the renaming.
|
* the renaming.
|
||||||
*/
|
*/
|
||||||
#define xmalloc bird_xmalloc
|
#define xmalloc bird_xmalloc
|
||||||
|
#define xrealloc bird_xrealloc
|
||||||
void *xmalloc(unsigned);
|
void *xmalloc(unsigned);
|
||||||
|
void *xrealloc(void *, unsigned);
|
||||||
#define xfree(x) free(x)
|
#define xfree(x) free(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -32,4 +32,24 @@ xmalloc(unsigned size)
|
||||||
die("Unable to allocate %d bytes of memory", size);
|
die("Unable to allocate %d bytes of memory", size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xrealloc - realloc with checking
|
||||||
|
* @ptr: original memory block
|
||||||
|
* @size: block size
|
||||||
|
*
|
||||||
|
* This function is equivalent to realloc() except that in case of
|
||||||
|
* failure it calls die() to quit the program instead of returning
|
||||||
|
* a %NULL pointer.
|
||||||
|
*
|
||||||
|
* Wherever possible, please use the memory resources instead.
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
xrealloc(void *ptr, unsigned size)
|
||||||
|
{
|
||||||
|
void *p = realloc(ptr, size);
|
||||||
|
if (p)
|
||||||
|
return p;
|
||||||
|
die("Unable to allocate %d bytes of memory", size);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -76,6 +76,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ospf.h"
|
#include "ospf.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED, ea_list * attrs);
|
||||||
|
static void ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a);
|
||||||
static int ospf_rte_better(struct rte *new, struct rte *old);
|
static int ospf_rte_better(struct rte *new, struct rte *old);
|
||||||
static int ospf_rte_same(struct rte *new, struct rte *old);
|
static int ospf_rte_same(struct rte *new, struct rte *old);
|
||||||
static void ospf_disp(timer *timer);
|
static void ospf_disp(timer *timer);
|
||||||
|
@ -124,6 +127,9 @@ ospf_start(struct proto *p)
|
||||||
po->disp_timer->hook = ospf_disp;
|
po->disp_timer->hook = ospf_disp;
|
||||||
po->disp_timer->recurrent = po->tick;
|
po->disp_timer->recurrent = po->tick;
|
||||||
tm_start(po->disp_timer, 1);
|
tm_start(po->disp_timer, 1);
|
||||||
|
po->lsab_size = 256;
|
||||||
|
po->lsab_used = 0;
|
||||||
|
po->lsab = mb_alloc(p->pool, po->lsab_size);
|
||||||
init_list(&(po->iface_list));
|
init_list(&(po->iface_list));
|
||||||
init_list(&(po->area_list));
|
init_list(&(po->area_list));
|
||||||
fib_init(&po->rtf, p->pool, sizeof(ort), 16, ospf_rt_initort);
|
fib_init(&po->rtf, p->pool, sizeof(ort), 16, ospf_rt_initort);
|
||||||
|
@ -227,6 +233,7 @@ ospf_init(struct proto_config *c)
|
||||||
p->accept_ra_types = RA_OPTIMAL;
|
p->accept_ra_types = RA_OPTIMAL;
|
||||||
p->rt_notify = ospf_rt_notify;
|
p->rt_notify = ospf_rt_notify;
|
||||||
p->if_notify = ospf_iface_notify;
|
p->if_notify = ospf_iface_notify;
|
||||||
|
p->ifa_notify = ospf_ifa_notify;
|
||||||
p->rte_better = ospf_rte_better;
|
p->rte_better = ospf_rte_better;
|
||||||
p->rte_same = ospf_rte_same;
|
p->rte_same = ospf_rte_same;
|
||||||
|
|
||||||
|
@ -429,7 +436,7 @@ ospf_shutdown(struct proto *p)
|
||||||
return PS_DOWN;
|
return PS_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
|
ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
|
||||||
ea_list * attrs)
|
ea_list * attrs)
|
||||||
{
|
{
|
||||||
|
@ -473,6 +480,25 @@ ospf_rt_notify(struct proto *p, net * n, rte * new, rte * old UNUSED,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ospf_ifa_notify(struct proto *p, unsigned flags, struct ifa *a)
|
||||||
|
{
|
||||||
|
struct proto_ospf *po = (struct proto_ospf *) p;
|
||||||
|
struct ospf_iface *ifa;
|
||||||
|
|
||||||
|
if ((a->flags & IA_SECONDARY) || (a->flags & IA_UNNUMBERED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
WALK_LIST(ifa, po->iface_list)
|
||||||
|
{
|
||||||
|
if (ifa->iface == a->iface)
|
||||||
|
{
|
||||||
|
schedule_rt_lsa(ifa->oa);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ospf_get_status(struct proto *p, byte * buf)
|
ospf_get_status(struct proto *p, byte * buf)
|
||||||
{
|
{
|
||||||
|
|
|
@ -550,6 +550,8 @@ struct proto_ospf
|
||||||
int rfc1583; /* RFC1583 compatibility */
|
int rfc1583; /* RFC1583 compatibility */
|
||||||
int ebit; /* Did I originate any ext lsa? */
|
int ebit; /* Did I originate any ext lsa? */
|
||||||
struct ospf_area *backbone; /* If exists */
|
struct ospf_area *backbone; /* If exists */
|
||||||
|
void *lsab; /* LSA buffer used when originating router LSAs */
|
||||||
|
int lsab_size, lsab_used;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ospf_iface_patt
|
struct ospf_iface_patt
|
||||||
|
@ -585,8 +587,6 @@ int ospf_import_control(struct proto *p, rte **new, ea_list **attrs,
|
||||||
struct linpool *pool);
|
struct linpool *pool);
|
||||||
struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
|
struct ea_list *ospf_make_tmp_attrs(struct rte *rt, struct linpool *pool);
|
||||||
void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
|
void ospf_store_tmp_attrs(struct rte *rt, struct ea_list *attrs);
|
||||||
void ospf_rt_notify(struct proto *p, net *n, rte *new, rte *old,
|
|
||||||
ea_list * attrs);
|
|
||||||
void schedule_rt_lsa(struct ospf_area *oa);
|
void schedule_rt_lsa(struct ospf_area *oa);
|
||||||
void schedule_rtcalc(struct proto_ospf *po);
|
void schedule_rtcalc(struct proto_ospf *po);
|
||||||
void schedule_net_lsa(struct ospf_iface *ifa);
|
void schedule_net_lsa(struct ospf_iface *ifa);
|
||||||
|
|
|
@ -22,123 +22,99 @@
|
||||||
|
|
||||||
int ptp_unnumbered_stub_lsa = 0;
|
int ptp_unnumbered_stub_lsa = 0;
|
||||||
|
|
||||||
|
static void *
|
||||||
|
lsab_alloc(struct proto_ospf *po, unsigned size)
|
||||||
|
{
|
||||||
|
unsigned offset = po->lsab_used;
|
||||||
|
po->lsab_used += size;
|
||||||
|
if (po->lsab_used > po->lsab_size)
|
||||||
|
{
|
||||||
|
po->lsab_size = MAX(po->lsab_used, 2 * po->lsab_size);
|
||||||
|
po->lsab = mb_realloc(po->proto.pool, po->lsab, po->lsab_size);
|
||||||
|
}
|
||||||
|
return ((byte *) po->lsab) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
lsab_allocz(struct proto_ospf *po, unsigned size)
|
||||||
|
{
|
||||||
|
void *r = lsab_alloc(po, size);
|
||||||
|
bzero(r, size);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
lsab_flush(struct proto_ospf *po)
|
||||||
|
{
|
||||||
|
void *r = mb_alloc(po->proto.pool, po->lsab_size);
|
||||||
|
memcpy(r, po->lsab, po->lsab_used);
|
||||||
|
po->lsab_used = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
|
originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
|
||||||
{
|
{
|
||||||
struct proto_ospf *po = oa->po;
|
struct proto_ospf *po = oa->po;
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
int j = 0, k = 0;
|
int i = 0, j = 0, k = 0, bitv = 0;
|
||||||
u16 i = 0;
|
|
||||||
struct ospf_lsa_rt *rt;
|
struct ospf_lsa_rt *rt;
|
||||||
struct ospf_lsa_rt_link *ln, *ln_after;
|
struct ospf_lsa_rt_link *ln;
|
||||||
struct ospf_neighbor *neigh;
|
struct ospf_neighbor *neigh;
|
||||||
|
|
||||||
DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name,
|
DBG("%s: Originating RT_lsa body for area \"%I\".\n", po->proto.name,
|
||||||
oa->areaid);
|
oa->areaid);
|
||||||
|
|
||||||
WALK_LIST(ifa, po->iface_list)
|
ASSERT(po->lsab_used == 0);
|
||||||
{
|
rt = lsab_allocz(po, sizeof(struct ospf_lsa_rt));
|
||||||
if ((ifa->oa == oa) && (ifa->state != OSPF_IS_DOWN))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
if ((ifa->type == OSPF_IT_PTP) && (ifa->state == OSPF_IS_PTP) &&
|
|
||||||
(ptp_unnumbered_stub_lsa || !(ifa->iface->addr->flags & IA_UNNUMBERED)))
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rt = mb_allocz(po->proto.pool, sizeof(struct ospf_lsa_rt) +
|
|
||||||
i * sizeof(struct ospf_lsa_rt_link));
|
|
||||||
if (po->areano > 1)
|
if (po->areano > 1)
|
||||||
rt->veb.bit.b = 1;
|
rt->veb.bit.b = 1;
|
||||||
if ((po->ebit) && (!oa->stub))
|
if ((po->ebit) && (!oa->stub))
|
||||||
rt->veb.bit.e = 1;
|
rt->veb.bit.e = 1;
|
||||||
ln = (struct ospf_lsa_rt_link *) (rt + 1);
|
rt = NULL; /* buffer might be reallocated later */
|
||||||
ln_after = ln + i;
|
|
||||||
|
|
||||||
WALK_LIST(ifa, po->iface_list)
|
WALK_LIST(ifa, po->iface_list)
|
||||||
{
|
{
|
||||||
if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) && (!EMPTY_LIST(ifa->neigh_list)))
|
int master = 0;
|
||||||
|
|
||||||
|
if ((ifa->type == OSPF_IT_VLINK) && (ifa->voa == oa) &&
|
||||||
|
(!EMPTY_LIST(ifa->neigh_list)))
|
||||||
{
|
{
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||||
if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
if ((neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
||||||
rt->veb.bit.v = 1;
|
bitv = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ln == ln_after)
|
/* BIRD does not support interface loops */
|
||||||
die("LSA space overflow");
|
ASSERT(ifa->state != OSPF_IS_LOOP);
|
||||||
|
|
||||||
if (ifa->state == OSPF_IS_LOOP)
|
|
||||||
{
|
|
||||||
ln->type = 3;
|
|
||||||
ln->id = ipa_to_u32(ifa->iface->addr->ip);
|
|
||||||
ln->data = 0xffffffff;
|
|
||||||
ln->metric = 0;
|
|
||||||
ln->notos = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP: /* rfc2328 - pg126 */
|
case OSPF_IT_PTP: /* RFC2328 - 12.4.1.1 */
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
||||||
{
|
{
|
||||||
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
ln->type = LSART_PTP;
|
ln->type = LSART_PTP;
|
||||||
ln->id = neigh->rid;
|
ln->id = neigh->rid;
|
||||||
|
ln->data = (ifa->iface->addr->flags & IA_UNNUMBERED) ?
|
||||||
|
ifa->iface->index : ipa_to_u32(ifa->iface->addr->ip);
|
||||||
ln->metric = ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos = 0;
|
ln->notos = 0;
|
||||||
if (ifa->iface->addr->flags & IA_UNNUMBERED)
|
i++;
|
||||||
{
|
master = 1;
|
||||||
ln->data = ifa->iface->index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ln->data = ipa_to_u32(ifa->iface->addr->ip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ln--;
|
|
||||||
i--; /* No link added */
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ifa->state == OSPF_IS_PTP) &&
|
|
||||||
(ptp_unnumbered_stub_lsa || !(ifa->iface->addr->flags & IA_UNNUMBERED)))
|
|
||||||
{
|
|
||||||
ln++;
|
|
||||||
if (ln == ln_after)
|
|
||||||
die("LSA space overflow");
|
|
||||||
|
|
||||||
ln->type = LSART_STUB;
|
|
||||||
ln->metric = ifa->cost;
|
|
||||||
ln->notos = 0;
|
|
||||||
if (ifa->iface->addr->flags & IA_UNNUMBERED)
|
|
||||||
{
|
|
||||||
ln->id = ipa_to_u32(ifa->iface->addr->opposite);
|
|
||||||
ln->data = 0xffffffff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
|
||||||
ln->id = ipa_to_u32(ifa->iface->addr->prefix) & ln->data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSPF_IT_BCAST:
|
|
||||||
|
case OSPF_IT_BCAST: /* RFC2328 - 12.4.1.2 */
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
if (ifa->state == OSPF_IS_WAITING)
|
if (ifa->state == OSPF_IS_WAITING)
|
||||||
{
|
break;
|
||||||
ln->type = LSART_STUB;
|
|
||||||
ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
|
||||||
ln->id = ipa_to_u32(ifa->iface->addr->prefix) & ln->data;
|
|
||||||
ln->metric = ifa->cost;
|
|
||||||
ln->notos = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
j = 0, k = 0;
|
j = 0, k = 0;
|
||||||
WALK_LIST(neigh, ifa->neigh_list)
|
WALK_LIST(neigh, ifa->neigh_list)
|
||||||
{
|
{
|
||||||
|
@ -147,52 +123,64 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
|
||||||
if (neigh->state == NEIGHBOR_FULL)
|
if (neigh->state == NEIGHBOR_FULL)
|
||||||
j = 1;
|
j = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((ifa->state == OSPF_IS_DR) && (j == 1)) || (k == 1))
|
if (((ifa->state == OSPF_IS_DR) && (j == 1)) || (k == 1))
|
||||||
{
|
{
|
||||||
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
ln->type = LSART_NET;
|
ln->type = LSART_NET;
|
||||||
ln->id = ipa_to_u32(ifa->drip);
|
ln->id = ipa_to_u32(ifa->drip);
|
||||||
ln->data = ipa_to_u32(ifa->iface->addr->ip);
|
ln->data = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
ln->metric = ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos = 0;
|
ln->notos = 0;
|
||||||
}
|
i++;
|
||||||
else
|
master = 1;
|
||||||
{
|
|
||||||
ln->type = LSART_STUB;
|
|
||||||
ln->data = ipa_to_u32(ipa_mkmask(ifa->iface->addr->pxlen));
|
|
||||||
ln->id = ipa_to_u32(ifa->iface->addr->prefix) & ln->data;
|
|
||||||
ln->metric = ifa->cost;
|
|
||||||
ln->notos = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OSPF_IT_VLINK:
|
|
||||||
|
case OSPF_IT_VLINK: /* RFC2328 - 12.4.1.3 */
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
||||||
{
|
{
|
||||||
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
ln->type = LSART_VLNK;
|
ln->type = LSART_VLNK;
|
||||||
ln->id = neigh->rid;
|
ln->id = neigh->rid;
|
||||||
|
ln->data = ipa_to_u32(ifa->iface->addr->ip);
|
||||||
ln->metric = ifa->cost;
|
ln->metric = ifa->cost;
|
||||||
ln->notos = 0;
|
ln->notos = 0;
|
||||||
}
|
i++;
|
||||||
else
|
master = 1;
|
||||||
{
|
|
||||||
ln--;
|
|
||||||
i--; /* No link added */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ln--;
|
|
||||||
i--; /* No link added */
|
|
||||||
log("Unknown interface type %s", ifa->iface->name);
|
log("Unknown interface type %s", ifa->iface->name);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now we will originate stub areas for interfaces addresses */
|
||||||
|
struct ifa *a;
|
||||||
|
WALK_LIST(a, ifa->iface->addrs)
|
||||||
|
{
|
||||||
|
if (((a == ifa->iface->addr) && master) ||
|
||||||
|
(a->flags & IA_SECONDARY) ||
|
||||||
|
(a->flags & IA_UNNUMBERED))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
|
ln->type = LSART_STUB;
|
||||||
|
ln->id = ipa_to_u32(a->prefix);
|
||||||
|
ln->data = ipa_to_u32(ipa_mkmask(a->pxlen));
|
||||||
|
ln->metric = ifa->cost;
|
||||||
|
ln->notos = 0;
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
ln++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rt = po->lsab;
|
||||||
rt->links = i;
|
rt->links = i;
|
||||||
*length = i * sizeof(struct ospf_lsa_rt_link) + sizeof(struct ospf_lsa_rt) +
|
rt->veb.bit.v = bitv;
|
||||||
sizeof(struct ospf_lsa_header);
|
*length = po->lsab_used + sizeof(struct ospf_lsa_header);
|
||||||
return rt;
|
return lsab_flush(po);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue