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

Temporary OSPFv3 development commit

parent 3aab39f5
......@@ -43,15 +43,13 @@ AC_SUBST(srcdir_rel_mf)
if test "$enable_ipv6" = yes ; then
ip=ipv6
SUFFIX6=6
if test "$with_protocols" = all ; then
with_protocols=bgp,pipe,rip,static
fi
else
ip=ipv4
SUFFIX6=""
if test "$with_protocols" = all ; then
with_protocols=bgp,ospf,pipe,rip,static
fi
fi
if test "$with_protocols" = all ; then
with_protocols=bgp,ospf,pipe,rip,static
fi
AC_SEARCH_LIBS(clock_gettime,[c rt posix4])
......
......@@ -71,6 +71,7 @@ ea__find(ea_list *e, unsigned id)
while (e)
{
/*
if (e->flags & EALF_BISECT)
{
l = 0;
......@@ -88,6 +89,7 @@ ea__find(ea_list *e, unsigned id)
}
}
else
*/
for(m=0; m<e->count; m++)
if (e->attrs[m].id == id)
return &e->attrs[m];
......
......@@ -20,6 +20,7 @@ static struct nbma_node *this_nbma;
static struct area_net_config *this_pref;
static struct ospf_stubnet_config *this_stubnet;
#ifdef OSPFv2
static void
finish_iface_config(struct ospf_iface_patt *ip)
{
......@@ -31,6 +32,16 @@ finish_iface_config(struct ospf_iface_patt *ip)
if ((ip->autype == OSPF_AUTH_NONE) && (ip->passwords != NULL))
log(L_WARN "Password option without authentication option does not make sense");
}
#endif
#ifdef OSPFv3
static void
finish_iface_config(struct ospf_iface_patt *ip)
{
if ((ip->autype != OSPF_AUTH_NONE) || (get_passwords() != NULL))
log(L_WARN "Authentication not supported in OSPFv3");
}
#endif
CF_DECLS
......
......@@ -8,6 +8,37 @@
#include "ospf.h"
#ifdef OSPFv2
struct ospf_dbdes_packet
{
struct ospf_packet ospf_packet;
u16 iface_mtu;
u8 options;
union imms imms; /* I, M, MS bits */
u32 ddseq;
};
#define hton_opt(X) X
#define ntoh_opt(X) X
#endif
#ifdef OSPFv3
struct ospf_dbdes_packet
{
struct ospf_packet ospf_packet;
u32 options;
u16 iface_mtu;
u8 padding;
union imms imms; /* I, M, MS bits */
u32 ddseq;
};
#define hton_opt(X) htonl(X)
#define ntoh_opt(X) ntohl(X)
#endif
static void ospf_dump_dbdes(struct proto *p, struct ospf_dbdes_packet *pkt)
{
......@@ -37,7 +68,7 @@ static void ospf_dump_dbdes(struct proto *p, struct ospf_dbdes_packet *pkt)
* @n: neighbor
* @next: whether to send a next packet in a sequence (1) or to retransmit the old one (0)
*
* Sending of a database description packet is described in 10.6 of RFC 2328.
* Sending of a database description packet is described in 10.8 of RFC 2328.
* Reception of each packet is acknowledged in the sequence number of another.
* When I send a packet to a neighbor I keep a copy in a buffer. If the neighbor
* does not reply, I don't create a new packet but just send the content
......@@ -65,7 +96,7 @@ ospf_dbdes_send(struct ospf_neighbor *n, int next)
op = (struct ospf_packet *) pkt;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
pkt->iface_mtu = htons(ifa->iface->mtu);
pkt->options = oa->opt.byte;
pkt->options = hton_opt(oa->options);
pkt->imms = n->myimms;
pkt->ddseq = htonl(n->dds);
length = sizeof(struct ospf_dbdes_packet);
......@@ -88,8 +119,8 @@ ospf_dbdes_send(struct ospf_neighbor *n, int next)
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
pkt->iface_mtu = htons(ifa->iface->mtu);
pkt->options = oa->opt.byte;
pkt->ddseq = htonl(n->dds);
pkt->options = hton_opt(oa->options);
j = i = (ospf_pkt_maxsize(ifa) - sizeof(struct ospf_dbdes_packet)) / sizeof(struct ospf_lsa_header); /* Number of possible lsaheaders to send */
lsa = (n->ldbdes + sizeof(struct ospf_dbdes_packet));
......@@ -102,16 +133,8 @@ ospf_dbdes_send(struct ospf_neighbor *n, int next)
for (; i > 0; i--)
{
struct top_hash_entry *en= (struct top_hash_entry *) sn;
int send = 1;
/* Don't send ext LSA into stub areas */
if (oa->stub && (en->lsa.type == LSA_T_EXT)) send = 0;
/* Don't send ext LSAs through VLINK */
if ((ifa->type == OSPF_IT_VLINK) && (en->lsa.type == LSA_T_EXT)) send = 0;;
/* Don't send LSA of other areas */
if ((en->lsa.type != LSA_T_EXT) && (en->oa != oa)) send = 0;
if (send)
if (ospf_lsa_flooding_allowed(&en->lsa, en->domain, ifa))
{
htonlsah(&(en->lsa), lsa);
DBG("Working on: %d\n", i);
......@@ -204,13 +227,13 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n)
for (i = 0; i < j; i++)
{
ntohlsah(plsa + i, &lsa);
if (((he = ospf_hash_find(gr, oa->areaid, lsa.id, lsa.rt, lsa.type)) == NULL) ||
if (((he = ospfxx_hash_find_smart(gr, n->ifa, &lsa)) == NULL) ||
(lsa_comp(&lsa, &(he->lsa)) == 1))
{
/* Is this condition necessary? */
if (ospf_hash_find(n->lsrqh, oa->areaid, lsa.id, lsa.rt, lsa.type) == NULL)
if (ospfxx_hash_find_smart(n->lsrqh, n->ifa, &lsa) == NULL)
{
sn = ospf_hash_get(n->lsrqh, oa, lsa.id, lsa.rt, lsa.type);
sn = ospfxx_hash_get_smart(n->lsrqh, n->ifa, &lsa);
ntohlsah(plsa + i, &(sn->lsa));
s_add_tail(&(n->lsrql), SNODE sn);
}
......@@ -219,13 +242,17 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n)
}
void
ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n)
ospf_dbdes_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n)
{
struct ospf_dbdes_packet *ps = (void *) ps_i;
struct proto *p = &ifa->oa->po->proto;
u32 myrid = p->cf->global->router_id;
unsigned int size = ntohs(ps->ospf_packet.length);
u32 ps_ddseq = ntohl(ps->ddseq);
u32 ps_options = ntoh_opt(ps->options);
OSPF_PACKET(ospf_dump_dbdes, ps, "DBDES packet received from %I via %s", n->ip, ifa->iface->name);
ospf_neigh_sm(n, INM_HELLOREC);
......@@ -246,9 +273,9 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
&& (n->rid > myrid) && (size == sizeof(struct ospf_dbdes_packet)))
{
/* I'm slave! */
n->dds = ntohl(ps->ddseq);
n->ddr = ntohl(ps->ddseq);
n->options = ps->options;
n->dds = ps_ddseq;
n->ddr = ps_ddseq;
n->options = ps_options;
n->myimms.bit.ms = 0;
n->imms.byte = ps->imms.byte;
OSPF_TRACE(D_PACKETS, "I'm slave to %I.", n->ip);
......@@ -258,11 +285,11 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
}
if (((ps->imms.bit.i == 0) && (ps->imms.bit.ms == 0)) &&
(n->rid < myrid) && (n->dds == ntohl(ps->ddseq)))
(n->rid < myrid) && (n->dds == ps_ddseq))
{
/* I'm master! */
n->options = ps->options;
n->ddr = ntohl(ps->ddseq) - 1; /* It will be set corectly a few lines down */
n->options = ps_options;
n->ddr = ps_ddseq - 1; /* It will be set corectly a few lines down */
n->imms.byte = ps->imms.byte;
OSPF_TRACE(D_PACKETS, "I'm master to %I.", n->ip);
ospf_neigh_sm(n, INM_NEGDONE);
......@@ -274,8 +301,8 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
break;
}
case NEIGHBOR_EXCHANGE:
if ((ps->imms.byte == n->imms.byte) && (ps->options == n->options) &&
(ntohl(ps->ddseq) == n->ddr))
if ((ps->imms.byte == n->imms.byte) && (ps_options == n->options) &&
(ps_ddseq == n->ddr))
{
/* Duplicate packet */
OSPF_TRACE(D_PACKETS, "Received duplicate dbdes from %I.", n->ip);
......@@ -287,7 +314,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
return;
}
n->ddr = ntohl(ps->ddseq);
n->ddr = ps_ddseq;
if (ps->imms.bit.ms != n->imms.bit.ms) /* M/S bit differs */
{
......@@ -307,7 +334,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
n->imms.byte = ps->imms.byte;
if (ps->options != n->options) /* Options differs */
if (ps_options != n->options) /* Options differs */
{
OSPF_TRACE(D_PACKETS, "dbdes - sequence mismatch neighbor %I (options)",
n->ip);
......@@ -317,7 +344,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
if (n->myimms.bit.ms)
{
if (ntohl(ps->ddseq) != n->dds) /* MASTER */
if (ps_ddseq != n->dds) /* MASTER */
{
OSPF_TRACE(D_PACKETS,
"dbdes - sequence mismatch neighbor %I (master)", n->ip);
......@@ -339,15 +366,15 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
}
else
{
if (ntohl(ps->ddseq) != (n->dds + 1)) /* SLAVE */
if (ps_ddseq != (n->dds + 1)) /* SLAVE */
{
OSPF_TRACE(D_PACKETS, "dbdes - sequence mismatch neighbor %I (slave)",
n->ip);
ospf_neigh_sm(n, INM_SEQMIS);
break;
}
n->ddr = ntohl(ps->ddseq);
n->dds = ntohl(ps->ddseq);
n->ddr = ps_ddseq;
n->dds = ps_ddseq;
ospf_dbdes_reqladd(ps, n);
ospf_dbdes_send(n, 1);
}
......@@ -355,8 +382,8 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
break;
case NEIGHBOR_LOADING:
case NEIGHBOR_FULL:
if ((ps->imms.byte == n->imms.byte) && (ps->options == n->options)
&& (ntohl(ps->ddseq) == n->ddr))
if ((ps->imms.byte == n->imms.byte) && (ps_options == n->options)
&& (ps_ddseq == n->ddr))
/* Only duplicate are accepted */
{
OSPF_TRACE(D_PACKETS, "Received duplicate dbdes from %I.", n->ip);
......@@ -371,7 +398,7 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
{
OSPF_TRACE(D_PACKETS, "dbdes - sequence mismatch neighbor %I (full)",
n->ip);
DBG("PS=%u, DDR=%u, DDS=%u\n", ntohl(ps->ddseq), n->ddr, n->dds);
DBG("PS=%u, DDR=%u, DDS=%u\n", ps_ddseq, n->ddr, n->dds);
ospf_neigh_sm(n, INM_SEQMIS);
}
break;
......
......@@ -11,7 +11,7 @@
#define _BIRD_OSPF_DBDES_H_
void ospf_dbdes_send(struct ospf_neighbor *n, int next);
void ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n);
void ospf_dbdes_receive(struct ospf_packet *ps, struct ospf_iface *ifa,
struct ospf_neighbor *n);
#endif /* _BIRD_OSPF_DBDES_H_ */
......@@ -8,12 +8,46 @@
#include "ospf.h"
#ifdef OSPFv2
struct ospf_hello_packet
{
struct ospf_packet ospf_packet;
ip_addr netmask;
u16 helloint;
u8 options;
u8 priority;
u32 deadint;
u32 dr;
u32 bdr;
};
#endif
#ifdef OSPFv3
struct ospf_hello_packet
{
struct ospf_packet ospf_packet;
u32 iface_id;
u8 priority;
u8 options3;
u8 options2;
u8 options;
u16 helloint;
u16 deadint;
u32 dr;
u32 bdr;
};
#endif
void
ospf_hello_receive(struct ospf_hello_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n, ip_addr faddr)
ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n, ip_addr faddr)
{
struct ospf_hello_packet *ps = (void *) ps_i;
u32 *pnrid;
ip_addr olddr, oldbdr;
u32 olddr, oldbdr, oldiface_id, tmp;
ip_addr mask;
char *beg = "Bad OSPF hello packet from ", *rec = " received: ";
struct proto *p = (struct proto *) ifa->oa->po;
......@@ -21,9 +55,10 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
OSPF_TRACE(D_PACKETS, "HELLO packet received from %I via %s%s", faddr,
(ifa->type == OSPF_IT_VLINK ? "vlink-" : ""), ifa->iface->name);
#ifdef OSPFv2
mask = ps->netmask;
ipa_ntoh(mask);
if (ifa->type != OSPF_IT_VLINK)
{
char *msg = L_WARN "Received HELLO packet %s (%I) is inconsistent "
......@@ -50,24 +85,30 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
return;
}
}
#endif
if (ntohs(ps->helloint) != ifa->helloint)
tmp = ntohs(ps->helloint);
if (tmp != ifa->helloint)
{
log(L_ERR "%s%I%shello interval mismatch (%d).", beg, faddr, rec,
ntohs(ps->helloint));
log(L_ERR "%s%I%shello interval mismatch (%d).", beg, faddr, rec, tmp);
return;
}
if (ntohl(ps->deadint) != ifa->dead)
#ifdef OSPFv2
tmp = ntohl(ps->deadint);
#else /* OSPFv3 */
tmp = ntohs(ps->deadint);
#endif
if (tmp != ifa->dead)
{
log(L_ERR "%s%I%sdead interval mismatch (%d).", beg, faddr, rec,
ntohl(ps->deadint));
log(L_ERR "%s%I%sdead interval mismatch (%d).", beg, faddr, rec, tmp);
return;
}
if (ps->options != ifa->oa->opt.byte)
tmp = !(ps->options & OPT_E);
if (tmp != ifa->oa->stub)
{
log(L_ERR "%s%I%soptions mismatch (0x%x).", beg, faddr, rec, ps->options);
log(L_ERR "%s%I%sstub area flag mismatch (%d).", beg, faddr, rec, tmp);
return;
}
......@@ -111,12 +152,12 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
n->rid = ntohl(((struct ospf_packet *) ps)->routerid);
n->ip = faddr;
n->dr = ps->dr;
ipa_ntoh(n->dr);
n->bdr = ps->bdr;
ipa_ntoh(n->bdr);
n->dr = ntohl(ps->dr);
n->bdr = ntohl(ps->bdr);
n->priority = ps->priority;
n->options = ps->options;
#ifdef OSPFv3
n->iface_id = ntohl(ps->iface_id);
#endif
}
ospf_neigh_sm(n, INM_HELLOREC);
......@@ -140,35 +181,54 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
ospf_neigh_sm(n, INM_1WAYREC);
olddr = n->dr;
n->dr = ipa_ntoh(ps->dr);
oldbdr = n->bdr;
n->bdr = ipa_ntoh(ps->bdr);
oldpriority = n->priority;
#ifdef OSPFv3
oldiface_id = n->iface_id;
#endif
n->dr = ntohl(ps->dr);
n->bdr = ntohl(ps->bdr);
n->priority = ps->priority;
#ifdef OSPFv3
n->iface_id = ntohl(ps->iface_id);
#endif
/* Check priority change */
if (n->state >= NEIGHBOR_2WAY)
{
#ifdef OSPFv2
u32 rid = n->ip;
#else /* OSPFv3 */
u32 rid = p->cf->global->router_id;
#endif
if (n->priority != oldpriority)
ospf_iface_sm(ifa, ISM_NEICH);
#ifdef OSPFv3
if (n->iface_id != oldiface_id)
ospf_iface_sm(ifa, ISM_NEICH);
#endif
/* Router is declaring itself ad DR and there is no BDR */
if (ipa_equal(n->ip, n->dr) && (ipa_to_u32(n->bdr) == 0)
if ((rid == n->dr) && (n->bdr == 0)
&& (n->state != NEIGHBOR_FULL))
ospf_iface_sm(ifa, ISM_BACKS);
/* Neighbor is declaring itself as BDR */
if (ipa_equal(n->ip, n->bdr) && (n->state != NEIGHBOR_FULL))
if ((rid == n->bdr) && (n->state != NEIGHBOR_FULL))
ospf_iface_sm(ifa, ISM_BACKS);
/* Neighbor is newly declaring itself as DR or BDR */
if ((ipa_equal(n->ip, n->dr) && (!ipa_equal(n->dr, olddr)))
|| (ipa_equal(n->ip, n->bdr) && (!ipa_equal(n->bdr, oldbdr))))
if (((rid == n->dr) && (n->dr != olddr))
|| ((rid == n->bdr) && (n->bdr != oldbdr)))
ospf_iface_sm(ifa, ISM_NEICH);
/* Neighbor is no more declaring itself as DR or BDR */
if ((ipa_equal(n->ip, olddr) && (!ipa_equal(n->dr, olddr)))
|| (ipa_equal(n->ip, oldbdr) && (!ipa_equal(n->bdr, oldbdr))))
if (((rid == olddr) && (n->dr != olddr))
|| ((rid == oldbdr) && (n->bdr != oldbdr)))
ospf_iface_sm(ifa, ISM_NEICH);
}
......@@ -181,7 +241,7 @@ ospf_hello_receive(struct ospf_hello_packet *ps,
}
void
ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
{
struct ospf_iface *ifa;
struct ospf_hello_packet *pkt;
......@@ -223,18 +283,33 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
ospf_pkt_fill_hdr(ifa, pkt, HELLO_P);
#ifdef OSPFv2
pkt->netmask = ipa_mkmask(ifa->iface->addr->pxlen);
ipa_hton(pkt->netmask);
if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP))
pkt->netmask = IPA_NONE;
#endif
pkt->helloint = ntohs(ifa->helloint);
pkt->options = ifa->oa->opt.byte;
pkt->priority = ifa->priority;
#ifdef OSPFv3
pkt->iface_id = htonl(ifa->iface->index);
pkt->options3 = ifa->oa->options >> 16;
pkt->options2 = ifa->oa->options >> 8;
#endif
pkt->options = ifa->oa->options;
#ifdef OSPFv2
pkt->deadint = htonl(ifa->dead);
pkt->dr = ifa->drip;
ipa_hton(pkt->dr);
pkt->bdr = ifa->bdrip;
ipa_hton(pkt->bdr);
pkt->dr = htonl(ipa_to_u32(ifa->drip));
pkt->bdr = htonl(ipa_to_u32(ifa->bdrip));
#else /* OSPFv3 */
pkt->deadint = htons(ifa->dead);
pkt->dr = htonl(ifa->drid);
pkt->bdr = htonl(ifa->bdrid);
#endif
/* Fill all neighbors */
i = 0;
......
......@@ -10,8 +10,8 @@
#ifndef _BIRD_OSPF_HELLO_H_
#define _BIRD_OSPF_HELLO_H_
void ospf_hello_receive(struct ospf_hello_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n, ip_addr faddr);
void ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n, ip_addr faddr);
void ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn);
#endif /* _BIRD_OSPF_HELLO_H_ */
......@@ -157,16 +157,16 @@ ospf_iface_chstate(struct ospf_iface *ifa, u8 state)
rfree(ifa->dr_sk);
ifa->dr_sk = NULL;
}
if ((oldstate == OSPF_IS_DR) && (ifa->nlsa != NULL))
if ((oldstate == OSPF_IS_DR) && (ifa->net_lsa != NULL))
{
ifa->nlsa->lsa.age = LSA_MAXAGE;
ifa->net_lsa->lsa.age = LSA_MAXAGE;
if (state >= OSPF_IS_WAITING)
{
ospf_lsupd_flush_nlsa(ifa->nlsa, ifa->oa);
ospf_lsupd_flush_nlsa(po, ifa->net_lsa);
}
if (can_flush_lsa(po))
flush_lsa(ifa->nlsa, po);
ifa->nlsa = NULL;
flush_lsa(ifa->net_lsa, po);
ifa->net_lsa = NULL;
}
}
}
......@@ -412,8 +412,16 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface,
ifa->waitint = ip->waitint;
ifa->dead = (ip->dead == 0) ? ip->deadc * ifa->helloint : ip->dead;
ifa->stub = ip->stub;
#ifdef OSPFv2
ifa->autype = ip->autype;
ifa->passwords = ip->passwords;
#endif
#ifdef OSPFv3
ifa->instance_id = ip->instance_id;
#endif
ifa->rxbuf = ip->rxbuf;
if (ip->type == OSPF_IT_UNDEF)
......
......@@ -8,6 +8,14 @@
#include "ospf.h"
struct ospf_lsack_packet
{
struct ospf_packet ospf_packet;
struct ospf_lsa_header lsh[];
};
char *s_queue[] = { "direct", "delayed" };
......@@ -18,14 +26,12 @@ static void ospf_dump_lsack(struct proto *p, struct ospf_lsack_packet *pkt)
ASSERT(op->type == LSACK_P);
ospf_dump_common(p, op);
struct ospf_lsa_header *plsa = (void *) (pkt + 1);
int i, j;
j = (ntohs(op->length) - sizeof(struct ospf_lsack_packet)) /
sizeof(struct ospf_lsa_header);
for (i = 0; i < j; i++)
ospf_dump_lsahdr(p, plsa + i);
ospf_dump_lsahdr(p, pkt->lsh + i);
}
......@@ -70,7 +76,7 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
op = (struct ospf_packet *) sk->tbuf;
ospf_pkt_fill_hdr(n->ifa, pk, LSACK_P);
h = (struct ospf_lsa_header *) (pk + 1);
h = pk->lsh;
while (!EMPTY_LIST(n->ackl[queue]))
{
......@@ -141,10 +147,11 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
}
void
ospf_lsack_receive(struct ospf_lsack_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n)
ospf_lsack_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n)
{
struct ospf_lsa_header lsa, *plsa;
struct ospf_lsack_packet *ps = (void *) ps_i;
struct ospf_lsa_header lsa;
u16 nolsa;
struct top_hash_entry *en;
struct proto *p = &ifa->oa->po->proto;
......@@ -167,12 +174,10 @@ ospf_lsack_receive(struct ospf_lsack_packet *ps,
return;
}
plsa = (struct ospf_lsa_header *) (ps + 1);
for (i = 0; i < nolsa; i++)
{
ntohlsah(plsa + i, &lsa);
if ((en = ospf_hash_find_header(n->lsrth, n->ifa->oa->areaid, &lsa)) == NULL)
ntohlsah(ps->lsh + i, &lsa);
if ((en = ospfxx_hash_find_smart(n->lsrth, n->ifa, &lsa)) == NULL)
continue; /* pg 155 */
if (lsa_comp(&lsa, &en->lsa) != CMP_SAME) /* pg 156 */
......
......@@ -16,8 +16,8 @@ struct lsah_n
struct ospf_lsa_header lsa;
};
void ospf_lsack_receive(struct ospf_lsack_packet *ps,
struct ospf_iface *ifa, struct ospf_neighbor *n);
void ospf_lsack_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n);
void ospf_lsack_send(struct ospf_neighbor *n, int queue);
void ospf_lsack_enqueue(struct ospf_neighbor *n, struct ospf_lsa_header *h,
int queue);
......
......@@ -65,8 +65,8 @@ ospf_age(struct proto_ospf *po)
flush_lsa(en, po);
continue;
}
if ((en->lsa.rt == p->cf->global->router_id) &&(en->lsa.age >=
LSREFRESHTIME))
if ((en->lsa.rt == p->cf->global->router_id) &&
(en->lsa.age >= LSREFRESHTIME))
{
OSPF_TRACE(D_EVENTS, "Refreshing my LSA: Type: %u, Id: %R, Rt: %R",
en->lsa.type, en->lsa.id, en->lsa.rt);
......@@ -75,7 +75,7 @@ ospf_age(struct proto_ospf *po)
en->inst_t = now;
en->ini_age = 0;
lsasum_calculate(&en->lsa, en->lsa_body);
ospf_lsupd_flood(NULL, NULL, &en->lsa, NULL, en->oa, 1);
ospf_lsupd_flood(po, NULL, NULL, &en->lsa, en->domain, 1);
continue;
}
if ((en->lsa.age = (en->ini_age + (now - en->inst_t))) >= LSA_MAXAGE)
......@@ -96,7 +96,9 @@ void
htonlsah(struct ospf_lsa_header *h, struct ospf_lsa_header *n)
{
n->age = htons(h->age);
#ifdef OSPFv2
n->options = h->options;
#endif
n->type = h->type;
n->id = htonl(h->id);
n->rt = htonl(h->rt);
......@@ -109,7 +111,9 @@ void
ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
{
h->age = ntohs(n->age);
#ifdef OSPFv2
h->options = n->options;
#endif
h->type = n->type;
h->id = ntohl(n->id);
h->rt = ntohl(n->rt);
......@@ -119,7 +123,7 @@ ntohlsah(struct ospf_lsa_header *n, struct ospf_lsa_header *h)
};
void
htonlsab(void *h, void *n, u8 type, u16 len)
htonlsab(void *h, void *n, u16 type, u16 len)
{
unsigned int i;
switch (type)
......@@ -132,24 +136,43 @@ htonlsab(void *h, void *n, u8 type, u16 len)
nrt = n;
hrt = h;
links = hrt->links;
#ifdef OSPFv2
nrt->veb.byte = hrt->veb.byte;
nrt->padding = 0;
nrt->links = htons(hrt->links);
links = hrt->links;
#else /* OSPFv3 */
hrt->options = htonl(nrt->options);
links = (len - sizeof(struct ospf_lsa_rt)) /
sizeof(struct ospf_lsa_rt_link);
#endif
nrtl = (struct ospf_lsa_rt_link *) (nrt + 1);
hrtl = (struct ospf_lsa_rt_link *) (hrt + 1);
for (i = 0; i < links; i++)
{
(nrtl + i)->id = htonl((hrtl + i)->id);
(nrtl + i)->data = htonl((hrtl + i)->data);