mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-23 09:21:53 +00:00
Merge commit 'dd4da6f640fb581cbd7d1ca537bf382558492b8e' into integrated
This commit is contained in:
commit
07a6d8d1a0
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user