summaryrefslogtreecommitdiff
path: root/proto/ospf/rt.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2017-10-09 01:16:29 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2017-10-10 16:10:02 +0200
commitd3f4f92b0ece0ce4031087a25735e6cbf0d741e2 (patch)
treee19713ebf6be06e4933c6a56eb4e3260e01dcb0a /proto/ospf/rt.c
parent15a4421f9cb2c077cc484e3cda94e8710a1d68f5 (diff)
OSPF: Support of address families in OSPFv3
OSPFv3-AF can handle multiple topologies of diferent address families (IPv4, IPv6, both unicast and multicast) using separate instances distinguished by instance ID ranges.
Diffstat (limited to 'proto/ospf/rt.c')
-rw-r--r--proto/ospf/rt.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index df9eb75b..f57925c3 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -576,20 +576,20 @@ spfa_process_prefixes(struct ospf_proto *p, struct ospf_area *oa)
buf = px->rest;
for (i = 0; i < px->pxcount; i++)
{
- net_addr_ip6 net;
+ net_addr net;
u8 pxopts;
u16 metric;
- buf = ospf_get_ipv6_prefix(buf, (net_addr *) &net, &pxopts, &metric);
+ buf = ospf3_get_prefix(buf, ospf_get_af(p), &net, &pxopts, &metric);
if (pxopts & OPT_PX_NU)
continue;
/* Store the first global address to use it later as a vlink endpoint */
- if ((pxopts & OPT_PX_LA) && ipa_zero(src->lb))
- src->lb = ipa_from_ip6(net.prefix);
+ if ((pxopts & OPT_PX_LA) && (net.type == NET_IP6) && ipa_zero(src->lb))
+ src->lb = ipa_from_ip6(net6_prefix(&net));
- add_network(oa, (net_addr *) &net, src->dist + metric, src, i);
+ add_network(oa, &net, src->dist + metric, src, i);
}
}
}
@@ -761,7 +761,7 @@ ospf_rt_sum(struct ospf_area *oa)
if (en->lsa_type == LSA_T_SUM_NET)
{
- lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
+ lsa_parse_sum_net(en, ospf_is_v2(p), ospf_get_af(p), &net, &pxopts, &metric);
if (!ospf_valid_prefix(&net))
{
@@ -858,7 +858,7 @@ ospf_rt_sum_tr(struct ospf_area *oa)
net_addr net;
u8 pxopts;
- lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
+ lsa_parse_sum_net(en, ospf_is_v2(p), ospf_get_af(p), &net, &pxopts, &metric);
if (!ospf_valid_prefix(&net))
{
@@ -1058,7 +1058,7 @@ decide_nssa_lsa(struct ospf_proto *p, ort *nf, struct ospf_lsa_ext_local *rt)
return 0;
/* We do not store needed data in struct orta, we have to parse the LSA */
- lsa_parse_ext(en, ospf_is_v2(p), rt);
+ lsa_parse_ext(en, ospf_is_v2(p), ospf_get_af(p), rt);
if (rt->pxopts & OPT_PX_NU)
return 0;
@@ -1450,7 +1450,7 @@ ospf_ext_spf(struct ospf_proto *p)
DBG("%s: Working on LSA. ID: %R, RT: %R, Type: %u\n",
p->p.name, en->lsa.id, en->lsa.rt, en->lsa_type);
- lsa_parse_ext(en, ospf_is_v2(p), &rt);
+ lsa_parse_ext(en, ospf_is_v2(p), ospf_get_af(p), &rt);
if (!ospf_valid_prefix(&rt.net))
{
@@ -1765,7 +1765,11 @@ calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
if (ip6_zero(llsa->lladdr))
return NULL;
- return new_nexthop(p, ipa_from_ip6(llsa->lladdr), pn->iface, pn->weight);
+ ip_addr nh = ospf_is_ip4(p) ?
+ ipa_from_ip4(ospf3_6to4(llsa->lladdr)) :
+ ipa_from_ip6(llsa->lladdr);
+
+ return new_nexthop(p, nh, pn->iface, pn->weight);
}
}
@@ -1792,9 +1796,9 @@ add_cand(list * l, struct top_hash_entry *en, struct top_hash_entry *par,
if (en->lsa.age == LSA_MAXAGE)
return;
- if (ospf_is_v3(p) && (en->lsa_type == LSA_T_RT))
+ if (ospf_is_v3(p) && (oa->options & OPT_V6) && (en->lsa_type == LSA_T_RT))
{
- /* In OSPFv3, check V6 flag */
+ /* In OSPFv3 IPv6 unicast, check V6 flag */
struct ospf_lsa_rt *rt = en->lsa_body;
if (!(rt->options & OPT_V6))
return;