Commit a7a7372a authored by Ondřej Zajíček's avatar Ondřej Zajíček

Temporary integrated OSPF commit.

parent 70945cb6
......@@ -22,10 +22,11 @@
* or some other non-shareable resource, it asks the core to lock it and it doesn't
* use the resource until it's notified that it has acquired the lock.
*
* Object locks are represented by &object_lock structures which are in turn a kind of
* resource. Lockable resources are uniquely determined by resource type
* Object locks are represented by &object_lock structures which are in turn a
* kind of resource. Lockable resources are uniquely determined by resource type
* (%OBJLOCK_UDP for a UDP port etc.), IP address (usually a broadcast or
* multicast address the port is bound to), port number and interface.
* multicast address the port is bound to), port number, interface and optional
* instance ID.
*/
#undef LOCAL_DEBUG
......@@ -45,6 +46,7 @@ olock_same(struct object_lock *x, struct object_lock *y)
x->type == y->type &&
x->iface == y->iface &&
x->port == y->port &&
x->inst == y->inst &&
ipa_equal(x->addr, y->addr);
}
......@@ -88,7 +90,7 @@ olock_dump(resource *r)
struct object_lock *l = (struct object_lock *) r;
static char *olock_states[] = { "free", "locked", "waiting", "event" };
debug("(%d:%s:%I:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->port, olock_states[l->state]);
debug("(%d:%s:%I:%d:%d) [%s]\n", l->type, (l->iface ? l->iface->name : "?"), l->addr, l->port, l->inst, olock_states[l->state]);
if (!EMPTY_LIST(l->waiters))
debug(" [wanted]\n");
}
......
......@@ -26,9 +26,10 @@
struct object_lock {
resource r;
ip_addr addr; /* Identification of a object: IP address */
unsigned int type; /* ... object type (OBJLOCK_xxx) */
uint type; /* ... object type (OBJLOCK_xxx) */
uint port; /* ... port number */
uint inst; /* ... instance ID */
struct iface *iface; /* ... interface */
unsigned int port; /* ... port number */
void (*hook)(struct object_lock *); /* Called when the lock succeeds */
void *data; /* User data */
/* ... internal to lock manager, don't touch ... */
......
......@@ -200,15 +200,11 @@ ospf_do_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n)
* of the buffer.
*/
void
ospf_send_dbdes(struct ospf_neighbor *n, int next)
ospf_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n, int next)
{
struct ospf_iface *ifa = n->ifa;
struct ospf_area *oa = ifa->oa;
struct ospf_proto *p = oa->po;
/* RFC 2328 10.8 */
if (oa->rt == NULL)
if (n->ifa->oa->rt == NULL)
return;
switch (n->state)
......@@ -312,6 +308,7 @@ ospf_process_dbdes(struct ospf_proto *p, struct ospf_packet *pkt, struct ospf_ne
s_add_tail(&n->lsrql, SNODE req);
req->lsa = lsa;
req->lsa_body = LSA_BODY_DUMMY;
}
}
......@@ -394,7 +391,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
n->imms = rcv_imms;
OSPF_TRACE(D_PACKETS, "I'm slave to %I", n->ip);
ospf_neigh_sm(n, INM_NEGDONE);
ospf_send_dbdes(n, 1);
ospf_send_dbdes(p, n, 1);
break;
}
......@@ -426,7 +423,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (!(n->myimms & DBDES_MS))
{
/* Slave should retransmit dbdes packet */
ospf_send_dbdes(n, 0);
ospf_send_dbdes(p, n, 0);
}
return;
}
......@@ -472,7 +469,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (!(n->myimms & DBDES_M) && !(n->imms & DBDES_M))
ospf_neigh_sm(n, INM_EXDONE);
else
ospf_send_dbdes(n, 1);
ospf_send_dbdes(p, n, 1);
}
else
{
......@@ -489,7 +486,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (ospf_process_dbdes(p, pkt, n) < 0)
return;
ospf_send_dbdes(n, 1);
ospf_send_dbdes(p, n, 1);
}
break;
......@@ -504,7 +501,7 @@ ospf_receive_dbdes(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (!(n->myimms & DBDES_MS))
{
/* Slave should retransmit dbdes packet */
ospf_send_dbdes(n, 0);
ospf_send_dbdes(p, n, 0);
}
return;
}
......
......@@ -275,7 +275,7 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
/* Check consistency of existing neighbor entry */
if (n)
{
unsigned t = ifa->type;
uint t = ifa->type;
if (ospf_is_v2(p) && ((t == OSPF_IT_BCAST) || (t == OSPF_IT_NBMA) || (t == OSPF_IT_PTMP)))
{
/* Neighbor identified by IP address; Router ID may change */
......
......@@ -620,18 +620,11 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
add_tail(&oa->po->iface_list, NODE ifa);
/*
* In some cases we allow more ospf_ifaces on one physical iface.
* In OSPFv2, if they use different IP address prefix.
* In OSPFv3, if they use different instance_id.
* Therefore, we store such info to lock->addr field.
*/
// XXXX review
struct object_lock *lock = olock_new(pool);
lock->addr = ospf_is_v2(p) ? ifa->addr->prefix : _MI6(0,0,0,ifa->instance_id);
lock->addr = ospf_is_v2(p) ? ifa->addr->prefix : IPA_NONE;
lock->type = OBJLOCK_IP;
lock->port = OSPF_PROTO;
lock->inst = ifa->instance_id;
lock->iface = iface;
lock->data = ifa;
lock->hook = ospf_iface_add;
......@@ -997,7 +990,7 @@ ospf_walk_matching_iface_patts(struct ospf_proto *p, struct ospf_mip_walk *s)
BIT32_SET(s->ignore, id);
/* If we already found it in previous areas, ignore it and add warning */
if (!BIT32_TEST(s->active, id))
if (BIT32_TEST(s->active, id))
{ s->warn = 1; continue; }
BIT32_SET(s->active, id);
......@@ -1046,7 +1039,7 @@ ospf_ifa_notify2(struct proto *P, uint flags, struct ifa *a)
{
struct ospf_mip_walk s = { .iface = a->iface, .a = a };
while (ospf_walk_matching_iface_patts(p, &s))
ospf_iface_new(s.oa, s.a, s.ip);
ospf_iface_new(s.oa, a, s.ip);
}
if (flags & IF_CHANGE_DOWN)
......@@ -1078,7 +1071,7 @@ ospf_ifa_notify3(struct proto *P, uint flags, struct ifa *a)
{
struct ospf_mip_walk s = { .iface = a->iface };
while (ospf_walk_matching_iface_patts(p, &s))
ospf_iface_new(s.oa, s.a, s.ip);
ospf_iface_new(s.oa, a, s.ip);
}
if (flags & IF_CHANGE_DOWN)
......
......@@ -79,10 +79,9 @@ ospf_reset_lsack_queue(struct ospf_neighbor *n)
}
static inline void
ospf_send_lsack(struct ospf_neighbor *n, int queue)
ospf_send_lsack_(struct ospf_proto *p, struct ospf_neighbor *n, int queue)
{
struct ospf_iface *ifa = n->ifa;
struct ospf_proto *p = ifa->oa->po;
struct ospf_lsa_header *lsas;
struct ospf_packet *pkt;
struct lsa_node *no;
......@@ -121,10 +120,10 @@ ospf_send_lsack(struct ospf_neighbor *n, int queue)
}
void
ospf_lsack_send(struct ospf_neighbor *n, int queue)
ospf_send_lsack(struct ospf_proto *p, struct ospf_neighbor *n, int queue)
{
while (!EMPTY_LIST(n->ackl[queue]))
ospf_send_lsack(n, queue);
ospf_send_lsack_(p, n, queue);
}
void
......@@ -160,9 +159,6 @@ ospf_receive_lsack(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (lsa_comp(&lsa, &ret->lsa) != CMP_SAME)
{
if ((lsa.sn == LSA_MAXSEQNO) && (lsa.age == LSA_MAXAGE))
continue;
OSPF_TRACE(D_PACKETS, "Strange LSACK from %I", n->ip);
OSPF_TRACE(D_PACKETS, "Type: %04x, Id: %R, Rt: %R",
lsa_type, lsa.id, lsa.rt);
......
......@@ -71,7 +71,8 @@ ospf_send_lsreq(struct ospf_proto *p, struct ospf_neighbor *n)
ospf_pkt_fill_hdr(ifa, pkt, LSREQ_P);
ospf_lsreq_body(p, pkt, &lsrs, &lsr_max);
// for (i = 0; i < lsr_max; i++)
/* We send smaller LSREQ to prevent multiple LSACKs as answer */
lsr_max = lsr_max / 4;
i = 0;
WALK_SLIST(en, n->lsrql)
......
......@@ -115,7 +115,8 @@ ospf_lsa_lsrt_up(struct top_hash_entry *en, struct ospf_neighbor *n)
s_add_tail(&n->lsrtl, SNODE ret);
}
memcpy(&ret->lsa, &en->lsa, sizeof(struct ospf_lsa_header));
ret->lsa = en->lsa;
ret->lsa_body = LSA_BODY_DUMMY;
}
static inline int
......@@ -134,25 +135,37 @@ ospf_lsa_lsrt_down(struct top_hash_entry *en, struct ospf_neighbor *n)
return 0;
}
void
ospf_add_flushed_to_lsrt(struct ospf_proto *p, struct ospf_neighbor *n)
{
struct top_hash_entry *en;
WALK_SLIST(en, p->lsal)
if ((en->lsa.age == LSA_MAXAGE) && (en->lsa_body != NULL) &&
lsa_flooding_allowed(en->lsa_type, en->domain, n->ifa))
ospf_lsa_lsrt_up(en, n);
}
static void ospf_lsupd_flood_ifa(struct ospf_proto *p, struct ospf_iface *ifa, struct top_hash_entry *en);
static void ospf_send_lsupd_to_ifa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa);
/**
* ospf_lsupd_flood - send received or generated LSA to the neighbors
* @p: OSPF protocol
* ospf_flood_lsa - send LSA to the neighbors
* @p: OSPF protocol instance
* @en: LSA entry
* @from: neighbor than sent this LSA (or NULL if LSA is local)
*
* return value - was the LSA flooded back?
*/
int
ospf_lsupd_flood(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
ospf_flood_lsa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_neighbor *from)
{
struct ospf_iface *ifa;
struct ospf_neighbor *n;
/* RFC 2328 13.3 */
int back = 0;
WALK_LIST(ifa, p->iface_list)
{
......@@ -185,6 +198,8 @@ ospf_lsupd_flood(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_ne
{
s_rem_node(SNODE req);
ospf_hash_delete(n->lsrqh, req);
n->want_lsreq = 1;
if ((EMPTY_SLIST(n->lsrql)) && (n->state == NEIGHBOR_LOADING))
ospf_neigh_sm(n, INM_LOADDONE);
}
......@@ -227,7 +242,7 @@ ospf_lsupd_flood(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_ne
}
/* 13.3 (5) - finally flood the packet */
ospf_lsupd_flood_ifa(p, ifa, en);
ospf_send_lsupd_to_ifa(p, en, ifa);
}
return back;
......@@ -288,7 +303,7 @@ ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa,
static void
ospf_lsupd_flood_ifa(struct ospf_proto *p, struct ospf_iface *ifa, struct top_hash_entry *en)
ospf_send_lsupd_to_ifa(struct ospf_proto *p, struct top_hash_entry *en, struct ospf_iface *ifa)
{
uint c = ospf_prepare_lsupd(p, ifa, &en, 1);
......@@ -384,7 +399,8 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
/* RFC 2328 13. */
int sendreq = 1; /* XXXX: review sendreq */
int skip_lsreq = 0;
n->want_lsreq = 0;
uint plen = ntohs(pkt->length);
if (plen < (ospf_lsupd_hdrlen(p) + sizeof(struct ospf_lsa_header)))
......@@ -436,7 +452,7 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
u16 chsum = lsa_n->checksum;
if (chsum != lsasum_check(lsa_n, NULL))
{
log(L_WARN "%s: Received LSA from %I with bad checskum: %x %x",
log(L_WARN "%s: Received LSA from %I with bad checksum: %x %x",
p->p.name, n->ip, chsum, lsa_n->checksum);
continue;
}
......@@ -501,7 +517,7 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
if (en && ((now - en->inst_time) < MINLSARRIVAL))
{
OSPF_TRACE(D_EVENTS, "Skipping LSA received in less that MinLSArrival");
sendreq = 0;
skip_lsreq = 1;
continue;
}
......@@ -514,7 +530,6 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
{
log(L_WARN "%s: Received invalid LSA from %I", p->p.name, n->ip);
mb_free(body);
sendreq = 0;
continue;
}
......@@ -528,22 +543,27 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
}
/* 13. (5c) - remove old LSA from all retransmission lists */
/* Must be done before (5b), otherwise it also removes the new entries from (5b) */
/*
* We only need to remove it from the retransmission list of the neighbor
* that send us the new LSA. The old LSA is automatically replaced in
* retransmission lists by the new LSA.
*/
if (en)
ospf_lsa_lsrt_down(en, n);
#if 0
/*
{
struct ospf_iface *ifi;
struct ospf_neighbor *ni;
WALK_LIST(ifi, p->iface_list)
WALK_LIST(ni, ifi->neigh_list)
if (ni->state > NEIGHBOR_EXSTART)
ospf_lsa_lsrt_down(en, ni);
}
*/
* Old code for removing LSA from all retransmission lists. Must be done
* before (5b), otherwise it also removes the new entries from (5b).
*/
struct ospf_iface *ifi;
struct ospf_neighbor *ni;
WALK_LIST(ifi, p->iface_list)
WALK_LIST(ni, ifi->neigh_list)
if (ni->state > NEIGHBOR_EXSTART)
ospf_lsa_lsrt_down(en, ni);
#endif
/* 13. (5d) - install new LSA into database */
en = ospf_install_lsa(p, &lsa, lsa_type, lsa_domain, body);
......@@ -553,7 +573,7 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
ospf_notify_net_lsa(ifa);
/* 13. (5b) - flood new LSA */
int flood_back = ospf_lsupd_flood(p, en, n);
int flood_back = ospf_flood_lsa(p, en, n);
/* 13.5. - schedule ACKs (tbl 19, cases 1+2) */
if (! flood_back)
......@@ -582,7 +602,7 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
else
ospf_enqueue_lsack(n, lsa_n, ACKL_DIRECT);
sendreq = 0;
skip_lsreq = 1;
continue;
}
......@@ -598,11 +618,17 @@ ospf_receive_lsupd(struct ospf_packet *pkt, struct ospf_iface *ifa,
}
}
/* Send direct LSAs */
ospf_lsack_send(n, ACKL_DIRECT);
/* If loading, ask for another part of neighbor's database */
if (sendreq && (n->state == NEIGHBOR_LOADING))
/* Send direct LSACKs */
ospf_send_lsack(p, n, ACKL_DIRECT);
/*
* In loading state, we should ask for another batch of LSAs. This is only
* vaguely mentioned in RFC 2328. We send a new LSREQ only if the current
* LSUPD actually removed some entries from LSA request list (want_lsreq) and
* did not contain duplicate or early LSAs (skip_lsreq). The first condition
* prevents endless floods, the second condition helps with flow control.
*/
if ((n->state == NEIGHBOR_LOADING) && n->want_lsreq && !skip_lsreq)
ospf_send_lsreq(p, n);
}
......@@ -33,13 +33,26 @@ static void rxmt_timer_hook(timer * timer);
static void ackd_timer_hook(timer * t);
static void
init_lists(struct ospf_neighbor *n)
init_lists(struct ospf_proto *p, struct ospf_neighbor *n)
{
s_init_list(&(n->lsrql));
n->lsrqh = ospf_top_new(n->pool);
n->lsrqh = ospf_top_new(p, n->pool);
s_init_list(&(n->lsrtl));
n->lsrth = ospf_top_new(n->pool);
n->lsrth = ospf_top_new(p, n->pool);
}
static void
release_lsrtl(struct ospf_proto *p, struct ospf_neighbor *n)
{
struct top_hash_entry *ret, *en;
WALK_SLIST(ret, n->lsrtl)
{
en = ospf_hash_find_entry(p->gr, ret);
if (en)
en->ret_count--;
}
}
/* Resets LSA request and retransmit lists.
......@@ -47,11 +60,12 @@ init_lists(struct ospf_neighbor *n)
* it is reset during entering EXCHANGE state.
*/
static void
reset_lists(struct ospf_neighbor *n)
reset_lists(struct ospf_proto *p, struct ospf_neighbor *n)
{
release_lsrtl(p,n);
ospf_top_free(n->lsrqh);
ospf_top_free(n->lsrth);
init_lists(n);
init_lists(p, n);
}
struct ospf_neighbor *
......@@ -68,7 +82,7 @@ ospf_neighbor_new(struct ospf_iface *ifa)
n->csn = 0;
n->state = NEIGHBOR_DOWN;
init_lists(n);
init_lists(p, n);
s_init(&(n->dbsi), &(p->lsal));
n->inactim = tm_new(pool);
......@@ -360,6 +374,10 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
s_get(&(n->dbsi));
s_init(&(n->dbsi), &p->lsal);
/* Add MaxAge LSA entries to retransmission list */
ospf_add_flushed_to_lsrt(p, n);
/* FIXME: Why is this here ? */
ospf_reset_lsack_queue(n);
}
else
......@@ -388,7 +406,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
if (n->state >= NEIGHBOR_EXSTART)
if (!can_do_adj(n))
{
reset_lists(n);
reset_lists(p,n);
neigh_chstate(n, NEIGHBOR_2WAY);
}
break;
......@@ -399,7 +417,7 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
case INM_BADLSREQ:
if (n->state >= NEIGHBOR_EXCHANGE)
{
reset_lists(n);
reset_lists(p, n);
neigh_chstate(n, NEIGHBOR_EXSTART);
}
break;
......@@ -407,12 +425,12 @@ ospf_neigh_sm(struct ospf_neighbor *n, int event)
case INM_KILLNBR:
case INM_LLDOWN:
case INM_INACTTIM:
reset_lists(n);
reset_lists(p, n);
neigh_chstate(n, NEIGHBOR_DOWN);
break;
case INM_1WAYREC:
reset_lists(n);
reset_lists(p, n);
neigh_chstate(n, NEIGHBOR_INIT);
break;
......@@ -552,8 +570,10 @@ ospf_neigh_remove(struct ospf_neighbor *n)
nn->found = 0;
}
s_get(&(n->dbsi));
neigh_chstate(n, NEIGHBOR_DOWN);
s_get(&(n->dbsi));
release_lsrtl(p, n);
rem_node(NODE n);
rfree(n->pool);
OSPF_TRACE(D_EVENTS, "Deleting neigbor %R", n->rid);
......@@ -620,9 +640,9 @@ ospf_sh_neigh_info(struct ospf_neighbor *n)
}
static void
rxmt_timer_hook(timer * timer)
rxmt_timer_hook(timer *t)
{
struct ospf_neighbor *n = (struct ospf_neighbor *) timer->data;
struct ospf_neighbor *n = t->data;
struct ospf_proto *p = n->ifa->oa->po;
DBG("%s: RXMT timer fired on interface %s for neigh %I\n",
......@@ -631,12 +651,12 @@ rxmt_timer_hook(timer * timer)
switch (n->state)
{
case NEIGHBOR_EXSTART:
ospf_send_dbdes(n, 1);
ospf_send_dbdes(p, n, 1);
return;
case NEIGHBOR_EXCHANGE:
if (n->myimms & DBDES_MS)
ospf_send_dbdes(n, 0);
ospf_send_dbdes(p, n, 0);
case NEIGHBOR_LOADING:
ospf_send_lsreq(p, n);
return;
......@@ -653,8 +673,13 @@ rxmt_timer_hook(timer * timer)
}
static void
ackd_timer_hook(timer * t)
ackd_timer_hook(timer *t)
{
struct ospf_neighbor *n = t->data;
ospf_lsack_send(n, ACKL_DELAY);
struct ospf_proto *p = n->ifa->oa->po;
DBG("%s: ACKD timer fired on interface %s for neigh %I\n",
p->p.name, n->ifa->ifname, n->ip);
ospf_send_lsack(p, n, ACKL_DELAY);
}
This diff is collapsed.
This diff is collapsed.
......@@ -557,7 +557,7 @@ spfa_process_rt(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_entr
/* Errata 2078 to RFC 5340 4.8.1 - skip links from non-routing nodes */
if (ospf_is_v3(p) && (act != oa->rt) && !(rt->options & OPT_R))
break;
return;
/* Now process Rt links */
for (lsa_walk_rt_init(p, act, &rtl), i = 0; lsa_walk_rt(&rtl); i++)
......@@ -688,6 +688,8 @@ ospf_rt_spfa(struct ospf_area *oa)
if (oa->rt == NULL)
return;
if (oa->rt->lsa.age == LSA_MAXAGE)
return;
OSPF_TRACE(D_EVENTS, "Starting routing table calculation for area %R", oa->areaid);
......@@ -1087,8 +1089,7 @@ check_sum_net_lsa(struct ospf_proto *p, ort *nf)
struct area_net *anet = NULL;
struct ospf_area *anet_oa = NULL;
/* RT entry marked as area network */
if (nf->fn.flags & OSPF_RT_PERSISTENT)
if (nf->area_net)
{
/* It is a default route for stub areas, handled entirely in ospf_rt_abr() */
if (nf->fn.pxlen == 0)
......@@ -1162,8 +1163,7 @@ check_nssa_lsa(struct ospf_proto *p, ort *nf)
if (nf->external_rte)
return;
/* RT entry marked as area network */
if (nf->fn.flags & OSPF_RT_PERSISTENT)
if (nf->area_net)
{
/* Find that area network */
WALK_LIST(oa, p->area_list)
......@@ -1176,12 +1176,12 @@ check_nssa_lsa(struct ospf_proto *p, ort *nf)
/* RFC 3103 3.2 (3) - originate the aggregated address range */
if (anet && anet->active && !anet->hidden && oa->translate)
ospf_originate_ext_lsa(p, NULL, nf, LSA_RTCALC, anet->metric,
ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, anet->metric,
(anet->metric & LSA_EXT3_EBIT), IPA_NONE, anet->tag, 0);
/* RFC 3103 3.2 (2) - originate the same network */
else if (decide_nssa_lsa(p, nf, &rt))
ospf_originate_ext_lsa(p, NULL, nf, LSA_RTCALC, rt.metric, rt.ebit, rt.fwaddr, rt.tag, 0);
ospf_originate_ext_lsa(p, NULL, nf, LSA_M_RTCALC, rt.metric, rt.ebit, rt.fwaddr, rt.tag, 0);
}
/* RFC 2328 16.7. p2 - find new/lost vlink endpoints */
......@@ -1273,7 +1273,7 @@ ospf_rt_abr1(struct ospf_proto *p)
/* Get a RT entry and mark it to know that it is an area network */
ort *nfi = (ort *) fib_get(&p->rtf, &anet->fn.prefix, anet->fn.pxlen);
nfi->fn.flags |= OSPF_RT_PERSISTENT; /* mark persistent, to have stable UID */
nfi->area_net = 1;
/* 16.2. (3) */
if (nfi->n.type == RTS_OSPF_IA)
......@@ -1289,7 +1289,7 @@ ospf_rt_abr1(struct ospf_proto *p)
ip_addr addr = IPA_NONE;
default_nf = (ort *) fib_get(&p->rtf, &addr, 0);
default_nf->fn.flags |= OSPF_RT_PERSISTENT; /* keep persistent */
default_nf->area_net = 1;
struct ospf_area *oa;
WALK_LIST(oa, p->area_list)
......@@ -1309,7 +1309,7 @@ ospf_rt_abr1(struct ospf_proto *p)
*/
if (oa_is_nssa(oa) && oa->ac->default_nssa)
ospf_originate_ext_lsa(p, oa, default_nf, LSA_RTCALC, oa->ac->default_cost,
ospf_originate_ext_lsa(p, oa, default_nf, LSA_M_RTCALC, oa->ac->default_cost,
(oa->ac->default_cost & LSA_EXT3_EBIT), IPA_NONE, 0, 0);
/* RFC 2328 16.4. (3) - precompute preferred ASBR entries */
......@@ -1348,7 +1348,7 @@ translator_timer_hook(timer *timer)
return;
oa->translate = TRANS_OFF;
schedule_rtcalc(oa->po);
ospf_schedule_rtcalc(oa->po);
}
static void
......@@ -1431,7 +1431,7 @@ ospf_rt_abr2(struct ospf_proto *p)
/* Get a RT entry and mark it to know that it is an area network */
nf2 = (ort *) fib_get(&p->rtf, &anet->fn.prefix, anet->fn.pxlen);
nf2->fn.flags |= OSPF_RT_PERSISTENT; /* keep persistent */
nf2->area_net = 1;
}
u32 metric = (nf->n.type == RTS_OSPF_EXT1) ?
......@@ -1634,7 +1634,7 @@ ospf_rt_reset(struct ospf_proto *p)
FIB_WALK(&p->rtf, nftmp)
{
ri = (ort *) nftmp;
ri->fn.flags &= ~OSPF_RT_PERSISTENT;
ri->area_net = 0;
reset_ri(ri);
}
FIB_WALK_END;
......@@ -1647,8 +1647,8 @@ ospf_rt_reset(struct ospf_proto *p)
en->nhs = NULL;
en->lb = IPA_NONE;
if (en->rtcalc == LSA_RTCALC)
en->rtcalc = LSA_STALE;
if (en->mode == LSA_M_RTCALC)
en->mode = LSA_M_STALE;
}
WALK_LIST(oa, p->area_list)
......@@ -1683,14 +1683,9 @@ ospf_rt_reset(struct ospf_proto *p)
}
}
static void
ospf_flush_stale(struct ospf_proto *p)
{
}
/**
* ospf_rt_spf - calculate internal routes
* @p: OSPF protocol
* @p: OSPF protocol instance
*
* Calculation of internal paths in an area is described in 16.1 of RFC 2328.
* It's based on Dijkstra's shortest path tree algorithms.
......@@ -2064,8 +2059,8 @@ again1:
rte_update(&p->p, ne, NULL);
}
/* Remove unused rt entry. Entries with any flags are persistent. */
if (!nf->n.type && !nf->external_rte) // XXXX
/* Remove unused rt entry, some special entries are persistent */
if (!nf->n.type && !nf->external_rte && !nf->area_net)
{
FIB_ITERATE_PUT(&fit, nftmp);
fib_delete(fib, nftmp);
......@@ -2096,6 +2091,6 @@ again2:
/* Cleanup stale LSAs */
WALK_SLIST(en, p->lsal)
if (en->rtcalc == LSA_STALE)
if (en->mode == LSA_M_STALE)
ospf_flush_lsa(p, en);
}
......@@ -2,9 +2,10 @@
* BIRD -- OSPF
*
* (c) 2000--2004 Ondrej Filip <feela@network.cz>
* (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
* (c) 2009--2014 CZ.NIC z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*
*/
#ifndef _BIRD_OSPF_RT_H_
......@@ -28,12 +29,17 @@ typedef struct orta
#define ORTA_ASBR OPT_RT_E
#define ORTA_ABR OPT_RT_B
/*
* For ORT_NET routes, the field is almost unused with one
* exception: ORTA_PREF for external routes means that the route is
* preferred in AS external route selection according to 16.4.1. -
* it is intra-area path using non-backbone area. In other words,
* the forwarding address (or ASBR if forwarding address is zero) is
* intra-area (type == RTS_OSPF) and its area is not a backbone.
* For ORT_NET routes, there are just several flags for external routes:
*
* ORTA_PREF for external routes means that the route is preferred in AS
* external route selection according to 16.4.1. - it is intra-area path using
* non-backbone area. In other words, the forwarding address (or ASBR if
* forwarding address is zero) is intra-area (type == RTS_OSPF) and its area
* is not a backbone.
*
* ORTA_NSSA means that the entry represents an NSSA route, and ORTA_PROP
* means that the NSSA route has propagate-bit set. These flags are used in
* NSSA translation.
*/
#define ORTA_PREF 0x80000000
#define ORTA_NSSA 0x40000000
......@@ -51,41 +57,38 @@ typedef struct orta
}
orta;
/* Values for fn.flags in struct ort */
#define OSPF_RT_PERSISTENT 0x01