Fixes several bugs related to OSPFv3 vlinks.
This commit is contained in:
parent
0343d066da
commit
e4404cef0b
3 changed files with 53 additions and 26 deletions
|
@ -92,6 +92,7 @@ ospf_proto_finish(void)
|
||||||
if (cf->abr && !backbone)
|
if (cf->abr && !backbone)
|
||||||
{
|
{
|
||||||
struct ospf_area_config *ac = cfg_allocz(sizeof(struct ospf_area_config));
|
struct ospf_area_config *ac = cfg_allocz(sizeof(struct ospf_area_config));
|
||||||
|
ac->type = OPT_E; /* Backbone is non-stub */
|
||||||
add_head(&cf->area_list, NODE ac);
|
add_head(&cf->area_list, NODE ac);
|
||||||
init_list(&ac->patt_list);
|
init_list(&ac->patt_list);
|
||||||
init_list(&ac->net_list);
|
init_list(&ac->net_list);
|
||||||
|
|
|
@ -112,6 +112,10 @@ ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_i
|
||||||
{
|
{
|
||||||
u32 scope = LSA_SCOPE(lsa);
|
u32 scope = LSA_SCOPE(lsa);
|
||||||
|
|
||||||
|
/* Handle inactive vlinks */
|
||||||
|
if (ifa->state == OSPF_IS_DOWN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* 4.5.2 (Case 2) */
|
/* 4.5.2 (Case 2) */
|
||||||
if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT))
|
if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT))
|
||||||
scope = LSA_SCOPE_LINK;
|
scope = LSA_SCOPE_LINK;
|
||||||
|
|
|
@ -1249,7 +1249,6 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
struct ospf_config *cf = (struct ospf_config *) (po->proto.cf);
|
struct ospf_config *cf = (struct ospf_config *) (po->proto.cf);
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct ospf_lsa_prefix *lp;
|
struct ospf_lsa_prefix *lp;
|
||||||
struct ifa *vlink_addr = NULL;
|
|
||||||
int host_addr = 0;
|
int host_addr = 0;
|
||||||
int net_lsa;
|
int net_lsa;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -1263,7 +1262,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
|
|
||||||
WALK_LIST(ifa, po->iface_list)
|
WALK_LIST(ifa, po->iface_list)
|
||||||
{
|
{
|
||||||
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
if ((ifa->oa != oa) || (ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ifa->px_pos_beg = i;
|
ifa->px_pos_beg = i;
|
||||||
|
@ -1282,9 +1281,6 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
(a->scope <= SCOPE_LINK))
|
(a->scope <= SCOPE_LINK))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!vlink_addr)
|
|
||||||
vlink_addr = a;
|
|
||||||
|
|
||||||
if (((a->pxlen < MAX_PREFIX_LENGTH) && net_lsa) ||
|
if (((a->pxlen < MAX_PREFIX_LENGTH) && net_lsa) ||
|
||||||
configured_stubnet(oa, a))
|
configured_stubnet(oa, a))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1304,23 +1300,41 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
ifa->px_pos_end = i;
|
ifa->px_pos_end = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are some configured vlinks, add some global address,
|
|
||||||
which will be used as a vlink endpoint. */
|
|
||||||
if (!EMPTY_LIST(cf->vlink_list) && !host_addr && vlink_addr)
|
|
||||||
{
|
|
||||||
lsa_put_prefix(po, vlink_addr->ip, MAX_PREFIX_LENGTH, 0);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ospf_stubnet_config *sn;
|
struct ospf_stubnet_config *sn;
|
||||||
if (oa->ac)
|
if (oa->ac)
|
||||||
WALK_LIST(sn, oa->ac->stubnet_list)
|
WALK_LIST(sn, oa->ac->stubnet_list)
|
||||||
if (!sn->hidden)
|
if (!sn->hidden)
|
||||||
{
|
{
|
||||||
lsa_put_prefix(po, sn->px.addr, sn->px.len, sn->cost);
|
lsa_put_prefix(po, sn->px.addr, sn->px.len, sn->cost);
|
||||||
|
if (sn->px.len == MAX_PREFIX_LENGTH)
|
||||||
|
host_addr = 1;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there are some configured vlinks, find some global address
|
||||||
|
(even from another area), which will be used as a vlink endpoint. */
|
||||||
|
if (!EMPTY_LIST(cf->vlink_list) && !host_addr)
|
||||||
|
{
|
||||||
|
WALK_LIST(ifa, po->iface_list)
|
||||||
|
{
|
||||||
|
if ((ifa->type == OSPF_IT_VLINK) || (ifa->state == OSPF_IS_DOWN))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct ifa *a;
|
||||||
|
WALK_LIST(a, ifa->iface->addrs)
|
||||||
|
{
|
||||||
|
if ((a->flags & IA_SECONDARY) || (a->scope <= SCOPE_LINK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Found some IP */
|
||||||
|
lsa_put_prefix(po, a->ip, MAX_PREFIX_LENGTH, 0);
|
||||||
|
i++;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
lp = po->lsab;
|
lp = po->lsab;
|
||||||
lp->pxcount = i;
|
lp->pxcount = i;
|
||||||
*length = po->lsab_used + sizeof(struct ospf_lsa_header);
|
*length = po->lsab_used + sizeof(struct ospf_lsa_header);
|
||||||
|
@ -1389,15 +1403,12 @@ add_prefix(struct proto_ospf *po, u32 *px, int offset, int *pxc)
|
||||||
{
|
{
|
||||||
u32 *pxl = lsab_offset(po, offset);
|
u32 *pxl = lsab_offset(po, offset);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < *pxc; i++)
|
for (i = 0; i < *pxc; pxl = prefix_advance(pxl), i++)
|
||||||
|
if (prefix_same(px, pxl))
|
||||||
{
|
{
|
||||||
if (prefix_same(px, pxl))
|
/* Options should be logically OR'ed together */
|
||||||
{
|
*pxl |= (*px & 0x00FF0000);
|
||||||
/* Options should be logically OR'ed together */
|
return;
|
||||||
*pxl |= *px;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pxl = prefix_advance(pxl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(pxl == lsab_end(po));
|
ASSERT(pxl == lsab_end(po));
|
||||||
|
@ -1405,6 +1416,7 @@ add_prefix(struct proto_ospf *po, u32 *px, int offset, int *pxc)
|
||||||
int pxspace = prefix_space(px);
|
int pxspace = prefix_space(px);
|
||||||
pxl = lsab_alloc(po, pxspace);
|
pxl = lsab_alloc(po, pxspace);
|
||||||
memcpy(pxl, px, pxspace);
|
memcpy(pxl, px, pxspace);
|
||||||
|
*pxl &= 0xFFFF0000; /* Set metric to zero */
|
||||||
(*pxc)++;
|
(*pxc)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,11 +1427,21 @@ add_link_lsa(struct proto_ospf *po, struct top_hash_entry *en, int offset, int *
|
||||||
u32 *pxb = ll->rest;
|
u32 *pxb = ll->rest;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = 0; j < ll->pxcount; j++)
|
for (j = 0; j < ll->pxcount; pxb = prefix_advance(pxb), j++)
|
||||||
{
|
{
|
||||||
add_prefix(po, pxb, offset, pxc);
|
u8 pxlen = (pxb[0] >> 24);
|
||||||
pxb = prefix_advance(pxb);
|
u8 pxopts = (pxb[0] >> 16);
|
||||||
}
|
|
||||||
|
/* Skip NU or LA prefixes */
|
||||||
|
if (pxopts & (OPT_PX_NU | OPT_PX_LA))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Skip link-local prefixes */
|
||||||
|
if ((pxlen >= 10) && ((pxb[1] & 0xffc00000) == 0xfe800000))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
add_prefix(po, pxb, offset, pxc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue