0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-18 18:08:45 +00:00

Merge commit 'dd4da6f640fb581cbd7d1ca537bf382558492b8e' into integrated

This commit is contained in:
Ondrej Zajicek 2013-01-13 00:17:49 +01:00
commit 07a6d8d1a0
9 changed files with 109 additions and 60 deletions

View File

@ -79,6 +79,7 @@ ospf_proto_finish(void)
if (cf->abr && !backbone)
{
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);
init_list(&ac->patt_list);
init_list(&ac->net_list);

View File

@ -284,7 +284,7 @@ ospf_hello_send(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
{
struct ospf_hello3_packet *ps = (void *) pkt;
ps->iface_id = htonl(ifa->iface->index);
ps->iface_id = htonl(ifa->iface_id);
ps->priority = ifa->priority;
ps->options3 = ifa->oa->options >> 16;
ps->options2 = ifa->oa->options >> 8;

View File

@ -560,6 +560,8 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
log(L_WARN "%s: Cannot use interface %s as %s, forcing %s",
po->proto.name, iface->name, ospf_it[old_type], ospf_it[ifa->type]);
/* Assign iface ID, for vlinks, this is ugly hack */
ifa->iface_id = (ifa->type != OSPF_IT_VLINK) ? iface->index : oa->po->last_vlink_id++;
init_list(&ifa->neigh_list);
init_list(&ifa->nbma_list);

View File

@ -139,13 +139,16 @@ lsa_ntoh_body(void *n, void *h, u16 len)
int
lsa_flooding_allowed(u32 type, u32 domain, struct ospf_iface *ifa)
{
{
/* Handle inactive vlinks */
if (ifa->state == OSPF_IS_DOWN)
return 0;
/* 4.5.2 (Case 2) */
switch (LSA_SCOPE(type))
{
case LSA_SCOPE_LINK:
return ifa->iface->index == domain;
return ifa->iface_id == domain;
case LSA_SCOPE_AREA:
return ifa->oa->areaid == domain;
@ -208,7 +211,7 @@ lsa_xxxxtype(u32 itype, struct ospf_iface *ifa, u32 *otype, u32 *domain)
switch (LSA_SCOPE(itype))
{
case LSA_SCOPE_LINK:
*domain = ifa->iface->index;
*domain = ifa->iface_id;
return;
case LSA_SCOPE_AREA:

View File

@ -93,7 +93,6 @@ static void ospf_lsupd_dump(struct proto_ospf *po, struct ospf_packet *pkt)
}
}
/**
* ospf_lsupd_flood - send received or generated lsa to the neighbors
* @po: OSPF protocol

View File

@ -444,7 +444,7 @@ bdr_election(struct ospf_iface *ifa)
me.dr = ospf_is_v2(po) ? ipa_to_u32(ifa->drip) : ifa->drid;
me.bdr = ospf_is_v2(po) ? ipa_to_u32(ifa->bdrip) : ifa->bdrid;
me.iface_id = ifa->iface->index;
me.iface_id = ifa->iface_id;
add_tail(&ifa->neigh_list, NODE & me);

View File

@ -228,6 +228,7 @@ ospf_start(struct proto *p)
struct ospf_area_config *ac;
po->router_id = proto_get_router_id(p->cf);
po->last_vlink_id = 0x80000000;
po->rfc1583 = c->rfc1583;
po->ebit = 0;
po->ecmp = c->ecmp;
@ -943,8 +944,10 @@ lsa_compare_for_state(const void *p1, const void *p2)
u16 lsa1_type = he1->lsa_type;
u16 lsa2_type = he2->lsa_type;
if (he1->domain != he2->domain)
return he1->domain - he2->domain;
if (he1->domain < he2->domain)
return -1;
if (he1->domain > he2->domain)
return 1;
/* px1 or px2 assumes OSPFv3 */
@ -973,13 +976,20 @@ lsa_compare_for_state(const void *p1, const void *p2)
if (nt1)
{
/* In OSPFv3, networks are named based on ID of DR */
if (lsa_compare_ospf3 && (lsa1->rt != lsa2->rt))
return lsa1->rt - lsa2->rt;
if (lsa_compare_ospf3)
{
if (lsa1->rt < lsa2->rt)
return -1;
if (lsa1->rt > lsa2->rt)
return 1;
}
/* For OSPFv2, this is IP of the network,
for OSPFv3, this is interface ID */
if (lsa1->id != lsa2->id)
return lsa1->id - lsa2->id;
if (lsa1->id < lsa2->id)
return -1;
if (lsa1->id > lsa2->id)
return 1;
if (px1 != px2)
return px1 - px2;
@ -988,14 +998,20 @@ lsa_compare_for_state(const void *p1, const void *p2)
}
else
{
if (lsa1->rt != lsa2->rt)
return lsa1->rt - lsa2->rt;
if (lsa1->rt < lsa2->rt)
return -1;
if (lsa1->rt > lsa2->rt)
return 1;
if (lsa1_type != lsa2_type)
return lsa1_type - lsa2_type;
if (lsa1->id != lsa2->id)
return lsa1->id - lsa2->id;
if (lsa1_type < lsa2_type)
return -1;
if (lsa1_type > lsa2_type)
return 1;
if (lsa1->id < lsa2->id)
return -1;
if (lsa1->id > lsa2->id)
return 1;
if (px1 != px2)
return px1 - px2;
@ -1012,12 +1028,16 @@ ext_compare_for_state(const void *p1, const void *p2)
struct ospf_lsa_header *lsa1 = &(he1->lsa);
struct ospf_lsa_header *lsa2 = &(he2->lsa);
if (lsa1->rt != lsa2->rt)
return lsa1->rt - lsa2->rt;
if (lsa1->rt < lsa2->rt)
return -1;
if (lsa1->rt > lsa2->rt)
return 1;
if (lsa1->id < lsa2->id)
return -1;
if (lsa1->id > lsa2->id)
return 1;
if (lsa1->id != lsa2->id)
return lsa1->id - lsa2->id;
return lsa1->sn - lsa2->sn;
}

View File

@ -185,7 +185,8 @@ struct ospf_iface
u32 rxmtint; /* number of seconds between LSA retransmissions */
u32 pollint; /* Poll interval */
u32 deadint; /* after "deadint" missing hellos is router dead */
u32 vid; /* Id of peer of virtual link */
u32 iface_id; /* Interface ID (iface->index or new value for vlinks) */
u32 vid; /* ID of peer of virtual link */
ip_addr vip; /* IP of peer of virtual link */
struct ospf_iface *vifa; /* OSPF iface which the vlink goes through */
struct ospf_area *voa; /* OSPF area which the vlink goes through */
@ -724,6 +725,7 @@ struct proto_ospf
int lsab_size, lsab_used;
linpool *nhpool; /* Linpool used for next hops computed in SPF */
u32 router_id;
u32 last_vlink_id; /* Interface IDs for vlinks (starts at 0x80000000) */
};
struct ospf_iface_patt

View File

@ -262,7 +262,7 @@ originate_rt2_lsa_body(struct ospf_area *oa, u16 *length)
WALK_LIST(neigh, ifa->neigh_list)
if (neigh->state == NEIGHBOR_FULL)
{
u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface->index : ipa_to_u32(ifa->addr->ip);
u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface_id : ipa_to_u32(ifa->addr->ip);
add_rt2_lsa_link(po, LSART_PTP, neigh->rid, data, ifa->cost);
i++;
}
@ -331,7 +331,7 @@ add_rt3_lsa_link(struct proto_ospf *po, u8 type, struct ospf_iface *ifa, u32 nif
ln->type = type;
ln->padding = 0;
ln->metric = ifa->cost;
ln->lif = ifa->iface->index;
ln->lif = ifa->iface_id;
ln->nif = nif;
ln->id = id;
}
@ -515,7 +515,7 @@ originate_net3_lsa_body(struct proto_ospf *po, struct ospf_iface *ifa, u16 *leng
if (n->state == NEIGHBOR_FULL)
{
/* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */
en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK);
en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK);
if (en)
options |= ((struct ospf_lsa_link *) en->lsa_body)->options;
@ -561,7 +561,7 @@ originate_net_lsa(struct ospf_iface *ifa)
lsa.age = 0;
lsa.type_raw = LSA_T_NET;
lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface->index;
lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id;
lsa.rt = po->router_id;
lsa.sn = get_seqnum(ifa->net_lsa);
lsa_fix_options(po, &lsa, ifa->oa->options);
@ -1185,7 +1185,7 @@ originate_link_lsa(struct ospf_iface *ifa)
{
struct proto_ospf *po = ifa->oa->po;
struct ospf_lsa_header lsa;
u32 dom = ifa->iface->index;
u32 dom = ifa->iface_id;
void *body;
/* FIXME check for vlink and skip that? */
@ -1193,7 +1193,7 @@ originate_link_lsa(struct ospf_iface *ifa)
lsa.age = 0;
lsa.type_raw = LSA_T_LINK;
lsa.id = ifa->iface->index;
lsa.id = ifa->iface_id;
lsa.rt = po->router_id;
lsa.sn = get_seqnum(ifa->link_lsa);
@ -1240,7 +1240,6 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
struct ospf_config *cf = (struct ospf_config *) (po->proto.cf);
struct ospf_iface *ifa;
struct ospf_lsa_prefix *lp;
struct ifa *vlink_addr = NULL;
int host_addr = 0;
int net_lsa;
int i = 0;
@ -1254,7 +1253,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
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;
ifa->px_pos_beg = i;
@ -1273,9 +1272,6 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
(a->scope <= SCOPE_LINK))
continue;
if (!vlink_addr)
vlink_addr = a;
if (((a->pxlen < MAX_PREFIX_LENGTH) && net_lsa) ||
configured_stubnet(oa, a))
continue;
@ -1295,23 +1291,41 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
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;
if (oa->ac)
WALK_LIST(sn, oa->ac->stubnet_list)
if (!sn->hidden)
{
lsa_put_prefix(po, sn->px.addr, sn->px.len, sn->cost);
if (sn->px.len == MAX_PREFIX_LENGTH)
host_addr = 1;
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->pxcount = i;
*length = po->lsab_used + sizeof(struct ospf_lsa_header);
@ -1384,15 +1398,12 @@ add_prefix(struct proto_ospf *po, u32 *px, int offset, int *pxc)
{
u32 *pxl = lsab_offset(po, offset);
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;
return;
}
pxl = prefix_advance(pxl);
/* Options should be logically OR'ed together */
*pxl |= (*px & 0x00FF0000);
return;
}
ASSERT(pxl == lsab_end(po));
@ -1400,6 +1411,7 @@ add_prefix(struct proto_ospf *po, u32 *px, int offset, int *pxc)
int pxspace = prefix_space(px);
pxl = lsab_alloc(po, pxspace);
memcpy(pxl, px, pxspace);
*pxl &= 0xFFFF0000; /* Set metric to zero */
(*pxc)++;
}
@ -1410,11 +1422,21 @@ add_link_lsa(struct proto_ospf *po, struct top_hash_entry *en, int offset, int *
u32 *pxb = ll->rest;
int j;
for (j = 0; j < ll->pxcount; j++)
{
add_prefix(po, pxb, offset, pxc);
pxb = prefix_advance(pxb);
}
for (j = 0; j < ll->pxcount; pxb = prefix_advance(pxb), j++)
{
u8 pxlen = (pxb[0] >> 24);
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);
}
}
@ -1443,7 +1465,7 @@ originate_prefix_net_lsa_body(struct ospf_iface *ifa, u16 *length)
WALK_LIST(n, ifa->neigh_list)
if ((n->state == NEIGHBOR_FULL) &&
(en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK)))
(en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK)))
add_link_lsa(po, en, offset, &pxc);
lp = po->lsab;
@ -1465,7 +1487,7 @@ originate_prefix_net_lsa(struct ospf_iface *ifa)
lsa.age = 0;
lsa.type_raw = LSA_T_PREFIX;
lsa.id = ifa->iface->index;
lsa.id = ifa->iface_id;
lsa.rt = po->router_id;
lsa.sn = get_seqnum(ifa->pxn_lsa);