summaryrefslogtreecommitdiff
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r--proto/ospf/topology.c113
1 files changed, 63 insertions, 50 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 7558d4a0..86e39d75 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -283,8 +283,8 @@ ospf_originate_lsa(struct ospf_proto *p, struct ospf_new_lsa *lsa)
if (en->nf != lsa->nf)
{
- log(L_ERR "%s: LSA ID collision for %I/%d",
- p->p.name, lsa->nf->fn.prefix, lsa->nf->fn.pxlen);
+ log(L_ERR "%s: LSA ID collision for %N",
+ p->p.name, lsa->nf->fn.addr);
en = NULL;
goto drop;
@@ -513,15 +513,14 @@ ospf_update_lsadb(struct ospf_proto *p)
}
}
-
-static inline u32
+static u32
ort_to_lsaid(struct ospf_proto *p, ort *nf)
{
/*
* In OSPFv2, 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.
+ * prefix has 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
@@ -542,17 +541,21 @@ ort_to_lsaid(struct ospf_proto *p, ort *nf)
* network appeared, we choose a different way.
*
* In OSPFv3, it is simpler. There is not a requirement for membership of the
- * result in the input network, so we just use a hash-based unique ID of a
- * routing table entry for a route that originated given LSA. For ext-LSA, it
- * is an imported route in the nest's routing table (p->table). For summary-LSA,
- * it is a 'source' route in the protocol internal routing table (p->rtf).
+ * result in the input network, so we just allocate a unique ID from ID map
+ * and store it in nf->lsa_id for further reference.
*/
if (ospf_is_v3(p))
- return nf->fn.uid;
+ {
+ if (!nf->lsa_id)
+ nf->lsa_id = idm_alloc(&p->idm);
- u32 id = ipa_to_u32(nf->fn.prefix);
- int pxlen = nf->fn.pxlen;
+ return nf->lsa_id;
+ }
+
+ net_addr_ip4 *net = (void *) nf->fn.addr;
+ u32 id = ip4_to_u32(net->prefix);
+ int pxlen = net->pxlen;
if ((pxlen == 0) || (pxlen == 32))
return id;
@@ -628,12 +631,12 @@ configured_stubnet(struct ospf_area *oa, struct ifa *a)
{
if (sn->summary)
{
- if (ipa_in_net(a->prefix, sn->px.addr, sn->px.len) && (a->pxlen >= sn->px.len))
+ if (net_in_netX(&a->prefix, &sn->prefix))
return 1;
}
else
{
- if (ipa_equal(a->prefix, sn->px.addr) && (a->pxlen == sn->px.len))
+ if (net_equal(&a->prefix, &sn->prefix))
return 1;
}
}
@@ -781,7 +784,8 @@ prepare_rt2_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
(ifa->type == OSPF_IT_PTMP))
add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->ip), 0xffffffff, 0);
else
- add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(ifa->addr->prefix), u32_mkmask(ifa->addr->pxlen), ifa->cost);
+ add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&ifa->addr->prefix)),
+ u32_mkmask(net4_pxlen(&ifa->addr->prefix)), ifa->cost);
i++;
ifa->rt_pos_end = i;
@@ -790,7 +794,8 @@ prepare_rt2_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
struct ospf_stubnet_config *sn;
WALK_LIST(sn, oa->ac->stubnet_list)
if (!sn->hidden)
- add_rt2_lsa_link(p, LSART_STUB, ipa_to_u32(sn->px.addr), u32_mkmask(sn->px.len), sn->cost), i++;
+ add_rt2_lsa_link(p, LSART_STUB, ip4_to_u32(net4_prefix(&sn->prefix)),
+ u32_mkmask(net4_pxlen(&sn->prefix)), sn->cost), i++;
struct ospf_lsa_rt *rt = p->lsab;
/* Store number of links in lower half of options */
@@ -907,7 +912,7 @@ prepare_net2_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
ASSERT(p->lsab_used == 0);
net = lsab_alloc(p, sizeof(struct ospf_lsa_net) + 4 * nodes);
- net->optx = u32_mkmask(ifa->addr->pxlen);
+ net->optx = u32_mkmask(ifa->addr->prefix.pxlen);
net->routers[0] = p->router_id;
WALK_LIST(n, ifa->neigh_list)
@@ -999,9 +1004,10 @@ prepare_sum3_net_lsa_body(struct ospf_proto *p, ort *nf, u32 metric)
{
struct ospf_lsa_sum3_net *sum;
- sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_net) + IPV6_PREFIX_SPACE(nf->fn.pxlen));
+ sum = lsab_allocz(p, sizeof(struct ospf_lsa_sum3_net) +
+ IPV6_PREFIX_SPACE(nf->fn.addr->pxlen));
sum->metric = metric;
- put_ipv6_prefix(sum->prefix, nf->fn.prefix, nf->fn.pxlen, 0, 0);
+ ospf_put_ipv6_prefix(sum->prefix, nf->fn.addr, 0, 0);
}
static inline void
@@ -1028,7 +1034,7 @@ ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf,
};
if (ospf_is_v2(p))
- prepare_sum2_lsa_body(p, nf->fn.pxlen, metric);
+ prepare_sum2_lsa_body(p, nf->fn.addr->pxlen, metric);
else
prepare_sum3_net_lsa_body(p, nf, metric);
@@ -1036,20 +1042,20 @@ ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf,
}
void
-ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric, u32 options)
+ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 drid, int metric, u32 options)
{
struct ospf_new_lsa lsa = {
.type = LSA_T_SUM_RT,
.mode = LSA_M_RTCALC,
.dom = oa->areaid,
- .id = ipa_to_rid(nf->fn.prefix), /* Router ID of ASBR, irrelevant for OSPFv3 */
+ .id = drid, /* Router ID of ASBR, irrelevant for OSPFv3 */
.opts = oa->options
};
if (ospf_is_v2(p))
prepare_sum2_lsa_body(p, 0, metric);
else
- prepare_sum3_rt_lsa_body(p, lsa.id, metric, options & LSA_OPTIONS_MASK);
+ prepare_sum3_rt_lsa_body(p, drid, metric, options & LSA_OPTIONS_MASK);
ospf_originate_lsa(p, &lsa);
}
@@ -1082,7 +1088,7 @@ prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
{
struct ospf_lsa_ext3 *ext;
int bsize = sizeof(struct ospf_lsa_ext3)
- + IPV6_PREFIX_SPACE(nf->fn.pxlen)
+ + IPV6_PREFIX_SPACE(nf->fn.addr->pxlen)
+ (ipa_nonzero(fwaddr) ? 16 : 0)
+ (tag ? 4 : 0);
@@ -1090,7 +1096,7 @@ prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
ext->metric = metric & LSA_METRIC_MASK;
u32 *buf = ext->rest;
- buf = put_ipv6_prefix(buf, nf->fn.prefix, nf->fn.pxlen, pbit ? OPT_PX_P : 0, 0);
+ buf = ospf_put_ipv6_prefix(buf, nf->fn.addr, pbit ? OPT_PX_P : 0, 0);
if (ebit)
ext->metric |= LSA_EXT3_EBIT;
@@ -1098,7 +1104,7 @@ prepare_ext3_lsa_body(struct ospf_proto *p, ort *nf,
if (ipa_nonzero(fwaddr))
{
ext->metric |= LSA_EXT3_FBIT;
- buf = put_ipv6_addr(buf, fwaddr);
+ buf = ospf_put_ipv6_addr(buf, fwaddr);
}
if (tag)
@@ -1140,7 +1146,7 @@ ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 m
};
if (ospf_is_v2(p))
- prepare_ext2_lsa_body(p, nf->fn.pxlen, metric, ebit, fwaddr, tag);
+ prepare_ext2_lsa_body(p, nf->fn.addr->pxlen, metric, ebit, fwaddr, tag);
else
prepare_ext3_lsa_body(p, nf, metric, ebit, fwaddr, tag, oa && pbit);
@@ -1177,7 +1183,7 @@ use_gw_for_fwaddr(struct ospf_proto *p, ip_addr gw, struct iface *iface)
WALK_LIST(ifa, p->iface_list)
if ((ifa->iface == iface) &&
- (!ospf_is_v2(p) || ipa_in_net(gw, ifa->addr->prefix, ifa->addr->pxlen)))
+ (!ospf_is_v2(p) || ipa_in_netX(gw, &ifa->addr->prefix)))
return 1;
return 0;
@@ -1215,7 +1221,8 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
{
WALK_LIST(a, ifa->iface->addrs)
{
- if ((a->flags & IA_SECONDARY) ||
+ if ((a->prefix.type != NET_IP6) ||
+ (a->flags & IA_SECONDARY) ||
(a->flags & IA_PEER) ||
(a->scope <= SCOPE_LINK))
continue;
@@ -1234,7 +1241,7 @@ find_surrogate_fwaddr(struct ospf_proto *p, struct ospf_area *oa)
}
void
-ospf_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *ea)
+ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *ea)
{
struct ospf_proto *p = (struct ospf_proto *) P;
struct ospf_area *oa = NULL; /* non-NULL for NSSA-LSA */
@@ -1253,7 +1260,7 @@ ospf_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old U
if (!new)
{
- nf = (ort *) fib_find(&p->rtf, &n->n.prefix, n->n.pxlen);
+ nf = fib_find(&p->rtf, n->n.addr);
if (!nf || !nf->external_rte)
return;
@@ -1290,13 +1297,13 @@ ospf_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old U
if (ipa_zero(fwd))
{
- log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %I/%d",
- p->p.name, n->n.prefix, n->n.pxlen);
+ log(L_ERR "%s: Cannot find forwarding address for NSSA-LSA %N",
+ p->p.name, n->n.addr);
return;
}
}
- nf = (ort *) fib_get(&p->rtf, &n->n.prefix, n->n.pxlen);
+ nf = fib_get(&p->rtf, n->n.addr);
ospf_originate_ext_lsa(p, oa, nf, LSA_M_EXPORT, metric, ebit, fwd, tag, 1);
nf->external_rte = 1;
}
@@ -1308,11 +1315,11 @@ ospf_rt_notify(struct proto *P, rtable *tbl UNUSED, net *n, rte *new, rte *old U
*/
static inline void
-lsab_put_prefix(struct ospf_proto *p, ip_addr prefix, u32 pxlen, u32 cost)
+lsab_put_prefix(struct ospf_proto *p, net_addr *net, u32 cost)
{
- void *buf = lsab_alloc(p, IPV6_PREFIX_SPACE(pxlen));
- u8 flags = (pxlen < MAX_PREFIX_LENGTH) ? 0 : OPT_PX_LA;
- put_ipv6_prefix(buf, prefix, pxlen, flags, cost);
+ void *buf = lsab_alloc(p, IPV6_PREFIX_SPACE(net6_pxlen(net)));
+ u8 flags = (net6_pxlen(net) < IP6_MAX_PREFIX_LENGTH) ? 0 : OPT_PX_LA;
+ ospf_put_ipv6_prefix(buf, net, flags, cost);
}
static void
@@ -1330,11 +1337,12 @@ prepare_link_lsa_body(struct ospf_proto *p, struct ospf_iface *ifa)
struct ifa *a;
WALK_LIST(a, ifa->iface->addrs)
{
- if ((a->flags & IA_SECONDARY) ||
- (a->scope < SCOPE_SITE))
+ if ((a->prefix.type != NET_IP6) ||
+ (a->flags & IA_SECONDARY) ||
+ (a->scope <= SCOPE_LINK))
continue;
- lsab_put_prefix(p, a->prefix, a->pxlen, 0);
+ lsab_put_prefix(p, &a->prefix, 0);
i++;
}
@@ -1401,12 +1409,13 @@ prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
struct ifa *a;
WALK_LIST(a, ifa->iface->addrs)
{
- if ((a->flags & IA_SECONDARY) ||
+ if ((a->prefix.type != NET_IP6) ||
+ (a->flags & IA_SECONDARY) ||
(a->flags & IA_PEER) ||
(a->scope <= SCOPE_LINK))
continue;
- if (((a->pxlen < MAX_PREFIX_LENGTH) && net_lsa) ||
+ if (((a->prefix.pxlen < IP6_MAX_PREFIX_LENGTH) && net_lsa) ||
configured_stubnet(oa, a))
continue;
@@ -1414,11 +1423,12 @@ prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
(ifa->state == OSPF_IS_LOOP) ||
(ifa->type == OSPF_IT_PTMP))
{
- lsab_put_prefix(p, a->ip, MAX_PREFIX_LENGTH, 0);
+ net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
+ lsab_put_prefix(p, (net_addr *) &net, 0);
host_addr = 1;
}
else
- lsab_put_prefix(p, a->prefix, a->pxlen, ifa->cost);
+ lsab_put_prefix(p, &a->prefix, ifa->cost);
i++;
}
@@ -1429,8 +1439,8 @@ prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
WALK_LIST(sn, oa->ac->stubnet_list)
if (!sn->hidden)
{
- lsab_put_prefix(p, sn->px.addr, sn->px.len, sn->cost);
- if (sn->px.len == MAX_PREFIX_LENGTH)
+ lsab_put_prefix(p, &sn->prefix, sn->cost);
+ if (sn->prefix.pxlen == IP6_MAX_PREFIX_LENGTH)
host_addr = 1;
i++;
}
@@ -1447,11 +1457,14 @@ prepare_prefix_rt_lsa_body(struct ospf_proto *p, struct ospf_area *oa)
struct ifa *a;
WALK_LIST(a, ifa->iface->addrs)
{
- if ((a->flags & IA_SECONDARY) || (a->scope <= SCOPE_LINK))
+ if ((a->prefix.type != NET_IP6) ||
+ (a->flags & IA_SECONDARY) ||
+ (a->scope <= SCOPE_LINK))
continue;
/* Found some IP */
- lsab_put_prefix(p, a->ip, MAX_PREFIX_LENGTH, 0);
+ net_addr_ip6 net = NET_ADDR_IP6(a->ip, IP6_MAX_PREFIX_LENGTH);
+ lsab_put_prefix(p, (net_addr *) &net, 0);
i++;
goto done;
}