mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Implement proper LSA ID generation.
This commit is contained in:
@@ -30,11 +30,64 @@ void flush_prefix_net_lsa(struct ospf_iface *ifa);
|
||||
#define ipa_to_rid(x) _I3(x)
|
||||
#endif
|
||||
|
||||
/* FIXME very ugly hack */
|
||||
|
||||
#ifdef OSPFv2
|
||||
#define ipa_to_lsaid(x) _I(x)
|
||||
static inline u32
|
||||
fibnode_to_lsaid(struct proto_ospf *po, struct fib_node *fn)
|
||||
{
|
||||
/* We have to map IP prefixes to u32 in such manner that resulting
|
||||
u32 interpreted as IP address is a member of given
|
||||
prefix. Therefore, /32 prefix have to be mapped on itself.
|
||||
All received prefixes have to be mapped on different u32s.
|
||||
|
||||
We have an assumption that if there is nontrivial (non-/32)
|
||||
network prefix, then there is not /32 prefix for the first
|
||||
and the last IP address of the network (these are usually
|
||||
reserved, therefore it is not an important restriction).
|
||||
The network prefix is mapped to the first or the last
|
||||
IP address in the manner that disallow collisions - we
|
||||
use IP address that cannot be used by parent prefix.
|
||||
|
||||
For example:
|
||||
192.168.0.0/24 maps to 192.168.0.255
|
||||
192.168.1.0/24 maps to 192.168.1.0
|
||||
because 192.168.0.0 and 192.168.1.255 might be used by
|
||||
192.168.0.0/23 .
|
||||
|
||||
This is not compatible with older RFC 1583, so we have an option
|
||||
to the RFC 1583 compatible assignment (that always uses the first
|
||||
address) which disallows subnetting.
|
||||
|
||||
Appendig E of RFC 2328 suggests different algorithm, that tries
|
||||
to maximize both compatibility and subnetting. But as it is not
|
||||
possible to have both reliably and the suggested algorithm was
|
||||
unnecessary complicated and it does crazy things like changing
|
||||
LSA ID for a network because different network appeared, we
|
||||
choose a different way. */
|
||||
|
||||
u32 id = _I(fn->prefix);
|
||||
|
||||
if ((po->rfc1583) || (fn->pxlen == 0) || (fn->pxlen == 32))
|
||||
return id;
|
||||
|
||||
if (id & (1 << (32 - fn->pxlen)))
|
||||
return id;
|
||||
else
|
||||
return id | ~u32_mkmask(fn->pxlen);
|
||||
}
|
||||
|
||||
#else /* OSPFv3 */
|
||||
#define ipa_to_lsaid(x) _I0(x) ^ _I1(x) ^ _I2(x) ^ _I3(x)
|
||||
|
||||
static inline u32
|
||||
fibnode_to_lsaid(struct proto_ospf *po, struct fib_node *fn)
|
||||
{
|
||||
/* In OSPFv3, it is simpler. There is not a requirement
|
||||
for membership of the result in input network, so we
|
||||
just use hash-based unique ID. */
|
||||
|
||||
return fn->uid;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -660,8 +713,7 @@ originate_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type, int metri
|
||||
|
||||
if (type == ORT_NET)
|
||||
{
|
||||
/* FIXME proper handling of LSA IDs and check for the same network */
|
||||
lsa.id = ipa_to_lsaid(fn->prefix);
|
||||
lsa.id = fibnode_to_lsaid(po, fn);
|
||||
lsa.type = LSA_T_SUM_NET;
|
||||
}
|
||||
else
|
||||
@@ -710,8 +762,7 @@ flush_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type)
|
||||
lsa.rt = rid;
|
||||
if (type == ORT_NET)
|
||||
{
|
||||
/* FIXME proper handling of LSA IDs and check for the same network */
|
||||
lsa.id = ipa_to_lsaid(fn->prefix);
|
||||
lsa.id = fibnode_to_lsaid(po, fn);
|
||||
lsa.type = LSA_T_SUM_NET;
|
||||
}
|
||||
else
|
||||
@@ -721,6 +772,8 @@ flush_sum_lsa(struct ospf_area *oa, struct fib_node *fn, int type)
|
||||
lsa.type = LSA_T_SUM_RT;
|
||||
}
|
||||
|
||||
/* FIXME check for the same network */
|
||||
|
||||
if ((en = ospf_hash_find_header(po->gr, oa->areaid, &lsa)) != NULL)
|
||||
{
|
||||
struct ospf_lsa_sum *sum = en->lsa_body;
|
||||
@@ -892,7 +945,7 @@ originate_ext_lsa(net * n, rte * e, struct proto_ospf *po,
|
||||
#endif
|
||||
|
||||
/* FIXME proper handling of LSA IDs and check for the same network */
|
||||
lsa.id = ipa_to_lsaid(n->n.prefix);
|
||||
lsa.id = fibnode_to_lsaid(po, &n->n);
|
||||
|
||||
if ((en = ospf_hash_find_header(po->gr, 0, &lsa)) != NULL)
|
||||
{
|
||||
@@ -927,7 +980,7 @@ flush_ext_lsa(net *n, struct proto_ospf *po)
|
||||
n->n.prefix, n->n.pxlen);
|
||||
|
||||
/* FIXME proper handling of LSA IDs and check for the same network */
|
||||
u32 lsaid = ipa_to_lsaid(n->n.prefix);
|
||||
u32 lsaid = fibnode_to_lsaid(po, &n->n);
|
||||
|
||||
if (en = ospf_hash_find(po->gr, 0, lsaid, rid, LSA_T_EXT))
|
||||
{
|
||||
|
Reference in New Issue
Block a user