summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/config.Y15
-rw-r--r--proto/ospf/hello.c8
-rw-r--r--proto/ospf/iface.c36
-rw-r--r--proto/ospf/lsalib.c24
-rw-r--r--proto/ospf/lsalib.h2
-rw-r--r--proto/ospf/lsupd.c2
-rw-r--r--proto/ospf/ospf.c59
-rw-r--r--proto/ospf/ospf.h76
-rw-r--r--proto/ospf/packet.c8
-rw-r--r--proto/ospf/rt.c227
-rw-r--r--proto/ospf/rt.h3
-rw-r--r--proto/ospf/topology.c95
-rw-r--r--proto/ospf/topology.h2
-rw-r--r--proto/pipe/pipe.c6
-rw-r--r--proto/radv/config.Y10
-rw-r--r--proto/radv/packets.c25
-rw-r--r--proto/radv/radv.c9
-rw-r--r--proto/radv/radv.h8
-rw-r--r--proto/rip/packets.c60
-rw-r--r--proto/rip/rip.c48
-rw-r--r--proto/rip/rip.h7
-rw-r--r--proto/static/config.Y7
-rw-r--r--proto/static/static.c35
-rw-r--r--proto/static/static.h4
24 files changed, 403 insertions, 373 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index c859960f..e8fb7f2e 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -132,7 +132,6 @@ CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY
CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY, LENGTH)
CF_KEYWORDS(SECONDARY, MERGE, LSA, SUPPRESSION)
-%type <t> opttext
%type <ld> lsadb_args
%type <i> nbma_eligible
@@ -212,10 +211,10 @@ ospf_stubnet:
;
ospf_stubnet_start:
- prefix {
+ net_ip {
this_stubnet = cfg_allocz(sizeof(struct ospf_stubnet_config));
add_tail(&this_area->stubnet_list, NODE this_stubnet);
- this_stubnet->px = $1;
+ this_stubnet->prefix = $1.n;
this_stubnet->cost = COST_D;
}
;
@@ -322,12 +321,11 @@ pref_list:
pref_item: pref_base pref_opt ';' ;
-pref_base: prefix
+pref_base: net_ip
{
this_pref = cfg_allocz(sizeof(struct area_net_config));
add_tail(this_nets, NODE this_pref);
- this_pref->px.addr = $1.addr;
- this_pref->px.len = $1.len;
+ this_pref->prefix = $1.n;
}
;
@@ -401,11 +399,6 @@ ospf_iface:
ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
;
-opttext:
- TEXT
- | /* empty */ { $$ = NULL; }
- ;
-
CF_ADDTO(dynamic_attr, OSPF_METRIC1 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC1); })
CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_METRIC2); })
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c
index 50cf1407..3fbb6167 100644
--- a/proto/ospf/hello.c
+++ b/proto/ospf/hello.c
@@ -74,7 +74,7 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
((ifa->type == OSPF_IT_PTP) && !ifa->ptp_netmask))
ps->netmask = 0;
else
- ps->netmask = htonl(u32_mkmask(ifa->addr->pxlen));
+ ps->netmask = htonl(u32_mkmask(ifa->addr->prefix.pxlen));
ps->helloint = ntohs(ifa->helloint);
ps->options = ifa->oa->options;
@@ -105,7 +105,7 @@ ospf_send_hello(struct ospf_iface *ifa, int kind, struct ospf_neighbor *dirn)
}
i = 0;
- max = (ospf_pkt_maxsize(ifa) - length) / sizeof(u32);
+ max = (ospf_pkt_maxsize(p, ifa) - length) / sizeof(u32);
/* Fill all neighbors */
if (kind != OHS_SHUTDOWN)
@@ -198,7 +198,7 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
/* RFC 2328 10.5 */
/*
- * We may not yet havethe associate neighbor, so we use Router ID from the
+ * We may not yet have the associate neighbor, so we use Router ID from the
* packet instead of one from the neighbor structure for log messages.
*/
u32 rcv_rid = ntohl(pkt->routerid);
@@ -224,7 +224,7 @@ ospf_receive_hello(struct ospf_packet *pkt, struct ospf_iface *ifa,
int pxlen = u32_masklen(ntohl(ps->netmask));
if ((ifa->type != OSPF_IT_VLINK) &&
(ifa->type != OSPF_IT_PTP) &&
- (pxlen != ifa->addr->pxlen))
+ (pxlen != ifa->addr->prefix.pxlen))
DROP("prefix length mismatch", pxlen);
neighbors = ps->neighbors;
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index 77ce839a..5d37b005 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -67,7 +67,9 @@ ifa_flood_queue_size(struct ospf_iface *ifa)
int
ospf_iface_assure_bufsize(struct ospf_iface *ifa, uint plen)
{
- plen += SIZE_OF_IP_HEADER;
+ struct ospf_proto *p = ifa->oa->po;
+
+ plen += ospf_is_v2(p) ? IP4_HEADER_LENGTH : IP6_HEADER_LENGTH;
/* This is relevant just for OSPFv2 */
if (ifa->autype == OSPF_AUTH_CRYPT)
@@ -235,8 +237,8 @@ ospf_iface_down(struct ospf_iface *ifa)
OSPF_TRACE(D_EVENTS, "Removing interface %s (peer %I) from area %R",
ifa->ifname, ifa->addr->opposite, ifa->oa->areaid);
else
- OSPF_TRACE(D_EVENTS, "Removing interface %s (%I/%d) from area %R",
- ifa->ifname, ifa->addr->prefix, ifa->addr->pxlen, ifa->oa->areaid);
+ OSPF_TRACE(D_EVENTS, "Removing interface %s (%N) from area %R",
+ ifa->ifname, &ifa->addr->prefix, ifa->oa->areaid);
/* First of all kill all the related vlinks */
WALK_LIST(iff, p->iface_list)
@@ -548,8 +550,8 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
OSPF_TRACE(D_EVENTS, "Adding interface %s (peer %I) to area %R",
iface->name, addr->opposite, oa->areaid);
else
- OSPF_TRACE(D_EVENTS, "Adding interface %s (%I/%d) to area %R",
- iface->name, addr->prefix, addr->pxlen, oa->areaid);
+ OSPF_TRACE(D_EVENTS, "Adding interface %s (%N) to area %R",
+ iface->name, &addr->prefix, oa->areaid);
pool = rp_new(p->p.pool, "OSPF Interface");
ifa = mb_allocz(pool, sizeof(struct ospf_iface));
@@ -625,7 +627,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
should be used). Because OSPFv3 iface is not subnet-specific,
there is no need for ipa_in_net() check */
- if (ospf_is_v2(p) && !ipa_in_net(nb->ip, addr->prefix, addr->pxlen))
+ if (ospf_is_v2(p) && !ipa_in_netX(nb->ip, &addr->prefix))
continue;
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
@@ -638,7 +640,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
add_tail(&oa->po->iface_list, NODE ifa);
struct object_lock *lock = olock_new(pool);
- lock->addr = ospf_is_v2(p) ? ifa->addr->prefix : IPA_NONE;
+ lock->addr = ospf_is_v2(p) ? ipa_from_ip4(net4_prefix(&ifa->addr->prefix)) : IPA_NONE;
lock->type = OBJLOCK_IP;
lock->port = OSPF_PROTO;
lock->inst = ifa->instance_id;
@@ -884,7 +886,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
WALK_LIST(nb, new->nbma_list)
{
/* See related note in ospf_iface_new() */
- if (ospf_is_v2(p) && !ipa_in_net(nb->ip, ifa->addr->prefix, ifa->addr->pxlen))
+ if (ospf_is_v2(p) && !ipa_in_netX(nb->ip, &ifa->addr->prefix))
continue;
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
@@ -1071,6 +1073,9 @@ ospf_ifa_notify2(struct proto *P, uint flags, struct ifa *a)
{
struct ospf_proto *p = (struct ospf_proto *) P;
+ if (a->prefix.type != NET_IP4)
+ return;
+
if (a->flags & IA_SECONDARY)
return;
@@ -1100,6 +1105,9 @@ ospf_ifa_notify3(struct proto *P, uint flags, struct ifa *a)
{
struct ospf_proto *p = (struct ospf_proto *) P;
+ if (a->prefix.type != NET_IP6)
+ return;
+
if (a->flags & IA_SECONDARY)
return;
@@ -1152,6 +1160,9 @@ ospf_reconfigure_ifaces2(struct ospf_proto *p)
WALK_LIST(a, iface->addrs)
{
+ if (a->prefix.type != NET_IP4)
+ continue;
+
if (a->flags & IA_SECONDARY)
continue;
@@ -1170,8 +1181,8 @@ ospf_reconfigure_ifaces2(struct ospf_proto *p)
continue;
/* Hard restart */
- log(L_INFO "%s: Restarting interface %s (%I/%d) in area %R",
- p->p.name, ifa->ifname, a->prefix, a->pxlen, s.oa->areaid);
+ log(L_INFO "%s: Restarting interface %s (%N) in area %R",
+ p->p.name, ifa->ifname, &a->prefix, s.oa->areaid);
ospf_iface_shutdown(ifa);
ospf_iface_remove(ifa);
}
@@ -1195,6 +1206,9 @@ ospf_reconfigure_ifaces3(struct ospf_proto *p)
WALK_LIST(a, iface->addrs)
{
+ if (a->prefix.type != NET_IP6)
+ continue;
+
if (a->flags & IA_SECONDARY)
continue;
@@ -1326,7 +1340,7 @@ ospf_iface_info(struct ospf_iface *ifa)
else if (ifa->addr->flags & IA_PEER)
cli_msg(-1015, "Interface %s (peer %I)", ifa->ifname, ifa->addr->opposite);
else
- cli_msg(-1015, "Interface %s (%I/%d)", ifa->ifname, ifa->addr->prefix, ifa->addr->pxlen);
+ cli_msg(-1015, "Interface %s (%N)", ifa->ifname, ifa->addr->prefix);
cli_msg(-1015, "\tType: %s%s", ospf_it[ifa->type], more);
cli_msg(-1015, "\tArea: %R (%u)", ifa->oa->areaid, ifa->oa->areaid);
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index 66a3a23d..9a6b0457 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -280,21 +280,19 @@ lsa_walk_rt(struct ospf_lsa_rt_walk *rt)
void
-lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, ip_addr *ip, int *pxlen, u8 *pxopts, u32 *metric)
+lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, net_addr *net, u8 *pxopts, u32 *metric)
{
if (ospf2)
{
struct ospf_lsa_sum2 *ls = en->lsa_body;
- *ip = ipa_from_u32(en->lsa.id & ls->netmask);
- *pxlen = u32_masklen(ls->netmask);
+ net_fill_ip4(net, ip4_from_u32(en->lsa.id & ls->netmask), u32_masklen(ls->netmask));
*pxopts = 0;
*metric = ls->metric & LSA_METRIC_MASK;
}
else
{
struct ospf_lsa_sum3_net *ls = en->lsa_body;
- u16 rest;
- lsa_get_ipv6_prefix(ls->prefix, ip, pxlen, pxopts, &rest);
+ ospf_get_ipv6_prefix(ls->prefix, net, pxopts, NULL);
*metric = ls->metric & LSA_METRIC_MASK;
}
}
@@ -324,8 +322,9 @@ lsa_parse_ext(struct top_hash_entry *en, int ospf2, struct ospf_lsa_ext_local *r
if (ospf2)
{
struct ospf_lsa_ext2 *ext = en->lsa_body;
- rt->ip = ipa_from_u32(en->lsa.id & ext->netmask);
- rt->pxlen = u32_masklen(ext->netmask);
+ net_fill_ip4(&rt->net,
+ ip4_from_u32(en->lsa.id & ext->netmask),
+ u32_masklen(ext->netmask));
rt->pxopts = 0;
rt->metric = ext->metric & LSA_METRIC_MASK;
rt->ebit = ext->metric & LSA_EXT2_EBIT;
@@ -339,14 +338,13 @@ lsa_parse_ext(struct top_hash_entry *en, int ospf2, struct ospf_lsa_ext_local *r
else
{
struct ospf_lsa_ext3 *ext = en->lsa_body;
- u16 rest;
- u32 *buf = lsa_get_ipv6_prefix(ext->rest, &rt->ip, &rt->pxlen, &rt->pxopts, &rest);
+ u32 *buf = ospf_get_ipv6_prefix(ext->rest, &rt->net, &rt->pxopts, NULL);
rt->metric = ext->metric & LSA_METRIC_MASK;
rt->ebit = ext->metric & LSA_EXT3_EBIT;
rt->fbit = ext->metric & LSA_EXT3_FBIT;
if (rt->fbit)
- buf = lsa_get_ipv6_addr(buf, &rt->fwaddr);
+ buf = ospf_get_ipv6_addr(buf, &rt->fwaddr);
else
rt->fwaddr = IPA_NONE;
@@ -452,7 +450,7 @@ lsa_validate_sum3_net(struct ospf_lsa_header *lsa, struct ospf_lsa_sum3_net *bod
return 0;
u8 pxl = pxlen(body->prefix);
- if (pxl > MAX_PREFIX_LENGTH)
+ if (pxl > IP6_MAX_PREFIX_LENGTH)
return 0;
if (lsa->length != (HDRLEN + sizeof(struct ospf_lsa_sum3_net) +
@@ -491,7 +489,7 @@ lsa_validate_ext3(struct ospf_lsa_header *lsa, struct ospf_lsa_ext3 *body)
return 0;
u8 pxl = pxlen(body->rest);
- if (pxl > MAX_PREFIX_LENGTH)
+ if (pxl > IP6_MAX_PREFIX_LENGTH)
return 0;
int len = IPV6_PREFIX_SPACE(pxl);
@@ -520,7 +518,7 @@ lsa_validate_pxlist(struct ospf_lsa_header *lsa, u32 pxcount, uint offset, u8 *p
return 0;
u8 pxl = pxlen((u32 *) (pbuf + offset));
- if (pxl > MAX_PREFIX_LENGTH)
+ if (pxl > IP6_MAX_PREFIX_LENGTH)
return 0;
offset += IPV6_PREFIX_SPACE(pxl);
diff --git a/proto/ospf/lsalib.h b/proto/ospf/lsalib.h
index ae6af044..c93f0295 100644
--- a/proto/ospf/lsalib.h
+++ b/proto/ospf/lsalib.h
@@ -55,7 +55,7 @@ u16 lsa_verify_checksum(const void *lsa_n, int lsa_len);
int lsa_comp(struct ospf_lsa_header *l1, struct ospf_lsa_header *l2);
void lsa_walk_rt_init(struct ospf_proto *po, struct top_hash_entry *act, struct ospf_lsa_rt_walk *rt);
int lsa_walk_rt(struct ospf_lsa_rt_walk *rt);
-void lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, ip_addr *ip, int *pxlen, u8 *pxopts, u32 *metric);
+void lsa_parse_sum_net(struct top_hash_entry *en, int ospf2, net_addr *net, u8 *pxopts, u32 *metric);
void lsa_parse_sum_rt(struct top_hash_entry *en, int ospf2, u32 *drid, u32 *metric, u32 *options);
void lsa_parse_ext(struct top_hash_entry *en, int ospf2, struct ospf_lsa_ext_local *rt);
int lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body);
diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c
index c6a734ca..65ad8e3d 100644
--- a/proto/ospf/lsupd.c
+++ b/proto/ospf/lsupd.c
@@ -330,7 +330,7 @@ ospf_prepare_lsupd(struct ospf_proto *p, struct ospf_iface *ifa,
pkt = ospf_tx_buffer(ifa);
hlen = ospf_lsupd_hdrlen(p);
- maxsize = ospf_pkt_maxsize(ifa);
+ maxsize = ospf_pkt_maxsize(p, ifa);
ospf_pkt_fill_hdr(ifa, pkt, LSUPD_P);
pos = hlen;
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index d5d5d354..cdc62d0a 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -107,13 +107,6 @@ static int ospf_rte_better(struct rte *new, struct rte *old);
static int ospf_rte_same(struct rte *new, struct rte *old);
static void ospf_disp(timer *timer);
-static void
-ospf_area_initfib(struct fib_node *fn)
-{
- struct area_net *an = (struct area_net *) fn;
- an->hidden = 0;
- an->active = 0;
-}
static void
add_area_nets(struct ospf_area *oa, struct ospf_area_config *ac)
@@ -122,18 +115,20 @@ add_area_nets(struct ospf_area *oa, struct ospf_area_config *ac)
struct area_net_config *anc;
struct area_net *an;
- fib_init(&oa->net_fib, p->p.pool, sizeof(struct area_net), 0, ospf_area_initfib);
- fib_init(&oa->enet_fib, p->p.pool, sizeof(struct area_net), 0, ospf_area_initfib);
+ fib_init(&oa->net_fib, p->p.pool, ospf_is_v2(p) ? NET_IP4 : NET_IP6,
+ sizeof(struct area_net), OFFSETOF(struct area_net, fn), 0, NULL);
+ fib_init(&oa->enet_fib, p->p.pool, ospf_is_v2(p) ? NET_IP4 : NET_IP6,
+ sizeof(struct area_net), OFFSETOF(struct area_net, fn), 0, NULL);
WALK_LIST(anc, ac->net_list)
{
- an = (struct area_net *) fib_get(&oa->net_fib, &anc->px.addr, anc->px.len);
+ an = fib_get(&oa->net_fib, &anc->prefix);
an->hidden = anc->hidden;
}
WALK_LIST(anc, ac->enet_list)
{
- an = (struct area_net *) fib_get(&oa->enet_fib, &anc->px.addr, anc->px.len);
+ an = fib_get(&oa->enet_fib, &anc->prefix);
an->hidden = anc->hidden;
an->tag = anc->tag;
}
@@ -154,7 +149,7 @@ ospf_area_add(struct ospf_proto *p, struct ospf_area_config *ac)
oa->areaid = ac->areaid;
oa->rt = NULL;
oa->po = p;
- fib_init(&oa->rtr, p->p.pool, sizeof(ort), 0, ospf_rt_initort);
+ fib_init(&oa->rtr, p->p.pool, NET_IP4, sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
add_area_nets(oa, ac);
if (oa->areaid == 0)
@@ -243,7 +238,8 @@ ospf_start(struct proto *P)
p->nhpool = lp_new(P->pool, 12*sizeof(struct mpnh));
init_list(&(p->iface_list));
init_list(&(p->area_list));
- fib_init(&p->rtf, P->pool, sizeof(ort), 0, ospf_rt_initort);
+ fib_init(&p->rtf, P->pool, p->ospf2 ? NET_IP4 : NET_IP6,
+ sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
p->areano = 0;
p->gr = ospf_top_new(p, P->pool);
s_init_list(&(p->lsal));
@@ -803,7 +799,7 @@ ospf_sh(struct proto *P)
cli_msg(-1014, "\t\tArea networks:");
firstfib = 0;
}
- cli_msg(-1014, "\t\t\t%1I/%u\t%s\t%s", anet->fn.prefix, anet->fn.pxlen,
+ cli_msg(-1014, "\t\t\t%1N\t%s\t%s", anet->fn.addr,
anet->hidden ? "Hidden" : "Advertise", anet->active ? "Active" : "");
}
FIB_WALK_END;
@@ -817,7 +813,7 @@ ospf_sh(struct proto *P)
cli_msg(-1014, "\t\tArea external networks:");
firstfib = 0;
}
- cli_msg(-1014, "\t\t\t%1I/%u\t%s\t%s", anet->fn.prefix, anet->fn.pxlen,
+ cli_msg(-1014, "\t\t\t%1N\t%s\t%s", anet->fn.addr,
anet->hidden ? "Hidden" : "Advertise", anet->active ? "Active" : "");
}
FIB_WALK_END;
@@ -1074,13 +1070,12 @@ show_lsa_network(struct top_hash_entry *he, int ospf2)
static inline void
show_lsa_sum_net(struct top_hash_entry *he, int ospf2)
{
- ip_addr ip;
- int pxlen;
+ net_addr net;
u8 pxopts;
u32 metric;
- lsa_parse_sum_net(he, ospf2, &ip, &pxlen, &pxopts, &metric);
- cli_msg(-1016, "\t\txnetwork %I/%d metric %u", ip, pxlen, metric);
+ lsa_parse_sum_net(he, ospf2, &net, &pxopts, &metric);
+ cli_msg(-1016, "\t\txnetwork %N metric %u", &net, metric);
}
static inline void
@@ -1113,19 +1108,15 @@ show_lsa_external(struct top_hash_entry *he, int ospf2)
if (rt.tag)
bsprintf(str_tag, " tag %08x", rt.tag);
- cli_msg(-1016, "\t\t%s %I/%d metric%s %u%s%s",
+ cli_msg(-1016, "\t\t%s %N metric%s %u%s%s",
(he->lsa_type == LSA_T_NSSA) ? "nssa-ext" : "external",
- rt.ip, rt.pxlen, rt.ebit ? "2" : "", rt.metric, str_via, str_tag);
+ &rt.net, rt.ebit ? "2" : "", rt.metric, str_via, str_tag);
}
static inline void
show_lsa_prefix(struct top_hash_entry *he, struct top_hash_entry *cnode)
{
struct ospf_lsa_prefix *px = he->lsa_body;
- ip_addr pxa;
- int pxlen;
- u8 pxopts;
- u16 metric;
u32 *buf;
int i;
@@ -1141,14 +1132,18 @@ show_lsa_prefix(struct top_hash_entry *he, struct top_hash_entry *cnode)
buf = px->rest;
for (i = 0; i < px->pxcount; i++)
- {
- buf = lsa_get_ipv6_prefix(buf, &pxa, &pxlen, &pxopts, &metric);
+ {
+ net_addr net;
+ u8 pxopts;
+ u16 metric;
- if (px->ref_type == LSA_T_RT)
- cli_msg(-1016, "\t\tstubnet %I/%d metric %u", pxa, pxlen, metric);
- else
- cli_msg(-1016, "\t\taddress %I/%d", pxa, pxlen);
- }
+ buf = ospf_get_ipv6_prefix(buf, &net, &pxopts, &metric);
+
+ if (px->ref_type == LSA_T_RT)
+ cli_msg(-1016, "\t\tstubnet %N metric %u", &net, metric);
+ else
+ cli_msg(-1016, "\t\taddress %N", &net);
+ }
}
void
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index a4e525ec..6291ae1a 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -125,24 +125,24 @@ struct ospf_area_config
struct area_net_config
{
node n;
- struct prefix px;
+ net_addr prefix;
u32 tag;
u8 hidden;
};
struct area_net
{
- struct fib_node fn;
u32 metric; /* With possible LSA_EXT3_EBIT for NSSA area nets */
u32 tag;
u8 hidden;
u8 active;
+ struct fib_node fn;
};
struct ospf_stubnet_config
{
node n;
- struct prefix px;
+ net_addr prefix;
u32 cost;
u8 hidden;
u8 summary;
@@ -681,8 +681,8 @@ struct ospf_lsa_ext3
struct ospf_lsa_ext_local
{
- ip_addr ip, fwaddr;
- int pxlen;
+ net_addr net;
+ ip_addr fwaddr;
u32 metric, ebit, fbit, tag, propagate;
u8 pxopts;
};
@@ -720,8 +720,8 @@ lsa_net_count(struct ospf_lsa_header *lsa)
/* In ospf_area->rtr we store paths to routers, but we use RID (and not IP address)
as index, so we need to encapsulate RID to IP address */
-#define ipa_from_rid(x) ipa_from_u32(x)
-#define ipa_to_rid(x) ipa_to_u32(x)
+#define net_from_rid(x) NET_ADDR_IP4(ip4_from_u32(x), IP4_MAX_PREFIX_LENGTH)
+#define rid_from_net(x) ip4_to_u32(((net_addr_ip4 *) x)->prefix)
#define IPV6_PREFIX_SPACE(x) ((((x) + 63) / 32) * 4)
#define IPV6_PREFIX_WORDS(x) (((x) + 63) / 32)
@@ -730,63 +730,63 @@ lsa_net_count(struct ospf_lsa_header *lsa)
also should be named as ospf3_* instead of *_ipv6_* */
static inline u32 *
-lsa_get_ipv6_prefix(u32 *buf, ip_addr *addr, int *pxlen, u8 *pxopts, u16 *rest)
+ospf_get_ipv6_prefix(u32 *buf, net_addr *N, u8 *pxopts, u16 *rest)
{
- u8 pxl = (*buf >> 24);
- *pxopts = (*buf >> 16);
- *rest = *buf;
- *pxlen = pxl;
+ net_addr_ip6 *net = (void *) N;
+ u8 pxlen = (*buf >> 24);
+ *pxopts = (*buf >> 16) & 0xff;
+ if (rest) *rest = *buf & 0xffff;
buf++;
- *addr = IPA_NONE;
+ *net = NET_ADDR_IP6(IP6_NONE, pxlen);
-#ifdef IPV6
- if (pxl > 0)
- _I0(*addr) = *buf++;
- if (pxl > 32)
- _I1(*addr) = *buf++;
- if (pxl > 64)
- _I2(*addr) = *buf++;
- if (pxl > 96)
- _I3(*addr) = *buf++;
+ if (pxlen > 0)
+ _I0(net->prefix) = *buf++;
+ if (pxlen > 32)
+ _I1(net->prefix) = *buf++;
+ if (pxlen > 64)
+ _I2(net->prefix) = *buf++;
+ if (pxlen > 96)
+ _I3(net->prefix) = *buf++;
/* Clean up remaining bits */
- if (pxl < 128)
- addr->addr[pxl / 32] &= u32_mkmask(pxl % 32);
-#endif
+ if (pxlen < 128)
+ net->prefix.addr[pxlen / 32] &= u32_mkmask(pxlen % 32);
return buf;
}
static inline u32 *
-lsa_get_ipv6_addr(u32 *buf, ip_addr *addr)
+ospf_get_ipv6_addr(u32 *buf, ip_addr *addr)
{
- *addr = *(ip_addr *) buf;
+ *addr = ipa_from_ip6(*(ip6_addr *) buf);
return buf + 4;
}
static inline u32 *
-put_ipv6_prefix(u32 *buf, ip_addr addr, u8 pxlen, u8 pxopts, u16 lh)
+ospf_put_ipv6_prefix(u32 *buf, net_addr *N, u8 pxopts, u16 rest)
{
-#ifdef IPV6
- *buf++ = ((pxlen << 24) | (pxopts << 16) | lh);
+ net_addr_ip6 *net = (void *) N;
+ u32 pxlen = net->pxlen;
+
+ *buf++ = ((pxlen << 24) | (pxopts << 16) | rest);
if (pxlen > 0)
- *buf++ = _I0(addr);
+ *buf++ = _I0(net->prefix);
if (pxlen > 32)
- *buf++ = _I1(addr);
+ *buf++ = _I1(net->prefix);
if (pxlen > 64)
- *buf++ = _I2(addr);
+ *buf++ = _I2(net->prefix);
if (pxlen > 96)
- *buf++ = _I3(addr);
-#endif
+ *buf++ = _I3(net->prefix);
+
return buf;
}
static inline u32 *
-put_ipv6_addr(u32 *buf, ip_addr addr)
+ospf_put_ipv6_addr(u32 *buf, ip_addr addr)
{
- *(ip_addr *) buf = addr;
+ *(ip6_addr *) buf = ipa_to_ip6(addr);
return buf + 4;
}
@@ -896,7 +896,7 @@ void ospf_sh_neigh_info(struct ospf_neighbor *n);
/* packet.c */
void ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type);
-uint ospf_pkt_maxsize(struct ospf_iface *ifa);
+uint ospf_pkt_maxsize(struct ospf_proto *p, struct ospf_iface *ifa);
int ospf_rx_hook(sock * sk, int size);
// void ospf_tx_hook(sock * sk);
void ospf_err_hook(sock * sk, int err);
diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c
index faa33664..9690c28a 100644
--- a/proto/ospf/packet.c
+++ b/proto/ospf/packet.c
@@ -23,7 +23,7 @@ ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type)
pkt->version = ospf_get_version(p);
pkt->type = h_type;
- pkt->length = htons(ospf_pkt_maxsize(ifa));
+ pkt->length = htons(ospf_pkt_maxsize(p, ifa));
pkt->routerid = htonl(p->router_id);
pkt->areaid = htonl(ifa->oa->areaid);
pkt->checksum = 0;
@@ -32,9 +32,9 @@ ospf_pkt_fill_hdr(struct ospf_iface *ifa, void *buf, u8 h_type)
}
uint
-ospf_pkt_maxsize(struct ospf_iface *ifa)
+ospf_pkt_maxsize(struct ospf_proto *p, struct ospf_iface *ifa)
{
- uint headers = SIZE_OF_IP_HEADER;
+ uint headers = ospf_is_v2(p) ? IP4_HEADER_LENGTH : IP6_HEADER_LENGTH;
/* Relevant just for OSPFv2 */
if (ifa->autype == OSPF_AUTH_CRYPT)
@@ -235,7 +235,7 @@ ospf_rx_hook(sock *sk, int len)
return 1;
int src_local, dst_local, dst_mcast;
- src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen);
+ src_local = ipa_in_netX(sk->faddr, &ifa->addr->prefix);
dst_local = ipa_equal(sk->laddr, ifa->addr->ip);
dst_mcast = ipa_equal(sk->laddr, ifa->all_routers) || ipa_equal(sk->laddr, ifa->des_routers);
diff --git a/proto/ospf/rt.c b/proto/ospf/rt.c
index cdf8012a..aee0368a 100644
--- a/proto/ospf/rt.c
+++ b/proto/ospf/rt.c
@@ -21,15 +21,6 @@ static inline void reset_ri(ort *ort)
bzero(&ort->n, sizeof(orta));
}
-void
-ospf_rt_initort(struct fib_node *fn)
-{
- ort *ri = (ort *) fn;
- reset_ri(ri);
- ri->old_rta = NULL;
- ri->fn.flags = 0;
-}
-
static inline int
nh_is_vlink(struct mpnh *nhs)
{
@@ -334,9 +325,9 @@ ort_merge_ext(struct ospf_proto *p, ort *o, const orta *new)
static inline void
-ri_install_net(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
+ri_install_net(struct ospf_proto *p, net_addr *net, const orta *new)
{
- ort *old = (ort *) fib_get(&p->rtf, &prefix, pxlen);
+ ort *old = fib_get(&p->rtf, net);
int cmp = orta_compare(p, new, &old->n);
if (cmp > 0)
@@ -348,8 +339,8 @@ ri_install_net(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
static inline void
ri_install_rt(struct ospf_area *oa, u32 rid, const orta *new)
{
- ip_addr addr = ipa_from_rid(rid);
- ort *old = (ort *) fib_get(&oa->rtr, &addr, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(rid);
+ ort *old = fib_get(&oa->rtr, (net_addr *) &nrid);
int cmp = orta_compare(oa->po, new, &old->n);
if (cmp > 0)
@@ -359,17 +350,19 @@ ri_install_rt(struct ospf_area *oa, u32 rid, const orta *new)
}
static inline void
-ri_install_asbr(struct ospf_proto *p, ip_addr *addr, const orta *new)
+ri_install_asbr(struct ospf_proto *p, u32 rid, const orta *new)
{
- ort *old = (ort *) fib_get(&p->backbone->rtr, addr, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(rid);
+ ort *old = fib_get(&p->backbone->rtr, (net_addr *) &nrid);
+
if (orta_compare_asbr(p, new, &old->n) > 0)
ort_replace(old, new);
}
static inline void
-ri_install_ext(struct ospf_proto *p, ip_addr prefix, int pxlen, const orta *new)
+ri_install_ext(struct ospf_proto *p, net_addr *net, const orta *new)
{
- ort *old = (ort *) fib_get(&p->rtf, &prefix, pxlen);
+ ort *old = fib_get(&p->rtf, net);
int cmp = orta_compare_ext(p, new, &old->n);
if (cmp > 0)
@@ -404,7 +397,7 @@ px_pos_to_ifa(struct ospf_area *oa, int pos)
static void
-add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_hash_entry *en, int pos)
+add_network(struct ospf_area *oa, net_addr *net, int metric, struct top_hash_entry *en, int pos)
{
struct ospf_proto *p = oa->po;
@@ -419,7 +412,7 @@ add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_
.nhs = en->nhs
};
- if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
+ if (net->pxlen > MAX_PREFIX_LENGTH)
{
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
@@ -441,7 +434,7 @@ add_network(struct ospf_area *oa, ip_addr px, int pxlen, int metric, struct top_
nf.nhs = ifa ? new_nexthop(p, IPA_NONE, ifa->iface, ifa->ecmp_weight) : NULL;
}
- ri_install_net(p, px, pxlen, &nf);
+ ri_install_net(p, net, &nf);
}
@@ -452,8 +445,7 @@ spfa_process_rt(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_entr
struct ospf_lsa_rt *rt = act->lsa_body;
struct ospf_lsa_rt_walk rtl;
struct top_hash_entry *tmp;
- ip_addr prefix;
- int pxlen, i;
+ int i;
if (rt->options & OPT_RT_V)
oa->trcap = 1;
@@ -503,9 +495,10 @@ spfa_process_rt(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_entr
* the same result by handing them here because add_network()
* will keep the best (not the first) found route.
*/
- prefix = ipa_from_u32(rtl.id & rtl.data);
- pxlen = u32_masklen(rtl.data);
- add_network(oa, prefix, pxlen, act->dist + rtl.metric, act, i);
+ net_addr_ip4 net =
+ NET_ADDR_IP4(ip4_from_u32(rtl.id & rtl.data), u32_masklen(rtl.data));
+
+ add_network(oa, (net_addr *) &net, act->dist + rtl.metric, act, i);
break;
case LSART_NET:
@@ -527,14 +520,14 @@ spfa_process_net(struct ospf_proto *p, struct ospf_area *oa, struct top_hash_ent
{
struct ospf_lsa_net *ln = act->lsa_body;
struct top_hash_entry *tmp;
- ip_addr prefix;
- int pxlen, i, cnt;
+ int i, cnt;
if (ospf_is_v2(p))
{
- prefix = ipa_from_u32(act->lsa.id & ln->optx);
- pxlen = u32_masklen(ln->optx);
- add_network(oa, prefix, pxlen, act->dist, act, -1);
+ net_addr_ip4 net =
+ NET_ADDR_IP4(ip4_from_u32(act->lsa.id & ln->optx), u32_masklen(ln->optx));
+
+ add_network(oa, (net_addr *) &net, act->dist, act, -1);
}
cnt = lsa_net_count(&act->lsa);
@@ -550,10 +543,6 @@ spfa_process_prefixes(struct ospf_proto *p, struct ospf_area *oa)
{
struct top_hash_entry *en, *src;
struct ospf_lsa_prefix *px;
- ip_addr pxa;
- int pxlen;
- u8 pxopts;
- u16 metric;
u32 *buf;
int i;
@@ -588,18 +577,22 @@ spfa_process_prefixes(struct ospf_proto *p, struct ospf_area *oa)
buf = px->rest;
for (i = 0; i < px->pxcount; i++)
- {
- buf = lsa_get_ipv6_prefix(buf, &pxa, &pxlen, &pxopts, &metric);
+ {
+ net_addr_ip6 net;
+ u8 pxopts;
+ u16 metric;
- if (pxopts & OPT_PX_NU)
- continue;
+ buf = ospf_get_ipv6_prefix(buf, (net_addr *) &net, &pxopts, &metric);
- /* Store the first global address to use it later as a vlink endpoint */
- if ((pxopts & OPT_PX_LA) && ipa_zero(src->lb))
- src->lb = pxa;
+ if (pxopts & OPT_PX_NU)
+ continue;
- add_network(oa, pxa, pxlen, src->dist + metric, src, i);
- }
+ /* 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);
+
+ add_network(oa, (net_addr *) &net, src->dist + metric, src, i);
+ }
}
}
@@ -742,13 +735,12 @@ ospf_rt_sum(struct ospf_area *oa)
{
struct ospf_proto *p = oa->po;
struct top_hash_entry *en;
- ip_addr ip, abrip;
+ net_addr net;
u32 dst_rid, metric, options;
ort *abr;
- int pxlen = -1, type = -1;
+ int type;
u8 pxopts;
-
OSPF_TRACE(D_EVENTS, "Starting routing table calculation for inter-area (area %R)", oa->areaid);
WALK_SLIST(en, p->lsal)
@@ -771,12 +763,12 @@ ospf_rt_sum(struct ospf_area *oa)
if (en->lsa_type == LSA_T_SUM_NET)
{
- lsa_parse_sum_net(en, ospf_is_v2(p), &ip, &pxlen, &pxopts, &metric);
+ lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
if (pxopts & OPT_PX_NU)
continue;
- if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
+ if (net.pxlen > MAX_PREFIX_LENGTH)
{
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
@@ -803,8 +795,8 @@ ospf_rt_sum(struct ospf_area *oa)
continue;
/* 16.2. (4) */
- abrip = ipa_from_rid(en->lsa.rt);
- abr = (ort *) fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(en->lsa.rt);
+ abr = fib_find(&oa->rtr, (net_addr *) &nrid);
if (!abr || !abr->n.type)
continue;
@@ -828,7 +820,7 @@ ospf_rt_sum(struct ospf_area *oa)
};
if (type == ORT_NET)
- ri_install_net(p, ip, pxlen, &nf);
+ ri_install_net(p, &net, &nf);
else
ri_install_rt(oa, dst_rid, &nf);
}
@@ -842,11 +834,7 @@ ospf_rt_sum_tr(struct ospf_area *oa)
struct ospf_area *bb = p->backbone;
struct top_hash_entry *en;
ort *re, *abr;
- ip_addr ip, abrip;
- u32 dst_rid, metric, options;
- int pxlen;
- u8 pxopts;
-
+ u32 metric;
if (!bb)
return;
@@ -869,26 +857,31 @@ ospf_rt_sum_tr(struct ospf_area *oa)
if (en->lsa_type == LSA_T_SUM_NET)
{
- lsa_parse_sum_net(en, ospf_is_v2(p), &ip, &pxlen, &pxopts, &metric);
+ net_addr net;
+ u8 pxopts;
+
+ lsa_parse_sum_net(en, ospf_is_v2(p), &net, &pxopts, &metric);
if (pxopts & OPT_PX_NU)
continue;
- if (pxlen < 0 || pxlen > MAX_PREFIX_LENGTH)
+ if (net.pxlen > MAX_PREFIX_LENGTH)
{
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
continue;
}
- re = fib_find(&p->rtf, &ip, pxlen);
+ re = fib_find(&p->rtf, &net);
}
else // en->lsa_type == LSA_T_SUM_RT
{
+ u32 dst_rid, options;
+
lsa_parse_sum_rt(en, ospf_is_v2(p), &dst_rid, &metric, &options);
- ip = ipa_from_rid(dst_rid);
- re = fib_find(&bb->rtr, &ip, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(dst_rid);
+ re = fib_find(&bb->rtr, (net_addr *) &nrid);
}
/* 16.3 (1b) */
@@ -906,8 +899,8 @@ ospf_rt_sum_tr(struct ospf_area *oa)
continue;
/* 16.3. (4) */
- abrip = ipa_from_rid(en->lsa.rt);
- abr = fib_find(&oa->rtr, &abrip, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(en->lsa.rt);
+ abr = fib_find(&oa->rtr, (net_addr *) &nrid);
if (!abr || !abr->n.type)
continue;
@@ -998,7 +991,7 @@ decide_sum_lsa(struct ospf_area *oa, ort *nf, int dest)
return 1;
struct area_net *anet = (struct area_net *)
- fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
+ fib_route(&nf->n.oa->net_fib, nf->fn.addr);
/* Condensed area network found */
if (anet)
@@ -1017,13 +1010,13 @@ check_sum_net_lsa(struct ospf_proto *p, ort *nf)
if (nf->area_net)
{
/* It is a default route for stub areas, handled entirely in ospf_rt_abr() */
- if (nf->fn.pxlen == 0)
+ if (nf->fn.addr->pxlen == 0)
return;
/* Find that area network */
WALK_LIST(anet_oa, p->area_list)
{
- anet = (struct area_net *) fib_find(&anet_oa->net_fib, &nf->fn.prefix, nf->fn.pxlen);
+ anet = fib_find(&anet_oa->net_fib, nf->fn.addr);
if (anet)
break;
}
@@ -1042,10 +1035,12 @@ check_sum_net_lsa(struct ospf_proto *p, ort *nf)
static inline void
check_sum_rt_lsa(struct ospf_proto *p, ort *nf)
{
+ u32 rid = rid_from_net(nf->fn.addr);
+
struct ospf_area *oa;
WALK_LIST(oa, p->area_list)
if (decide_sum_lsa(oa, nf, ORT_ROUTER))
- ospf_originate_sum_rt_lsa(p, oa, nf, nf->n.metric1, nf->n.options);
+ ospf_originate_sum_rt_lsa(p, oa, rid, nf->n.metric1, nf->n.options);
}
static inline int
@@ -1058,7 +1053,7 @@ decide_nssa_lsa(struct ospf_proto *p, ort *nf, struct ospf_lsa_ext_local *rt)
return 0;
/* Condensed area network found */
- if (fib_route(&oa->enet_fib, nf->fn.prefix, nf->fn.pxlen))
+ if (fib_route(&oa->enet_fib, nf->fn.addr))
return 0;
if (!en || (en->lsa_type != LSA_T_NSSA))
@@ -1093,7 +1088,7 @@ check_nssa_lsa(struct ospf_proto *p, ort *nf)
/* Find that area network */
WALK_LIST(oa, p->area_list)
{
- anet = (struct area_net *) fib_find(&oa->enet_fib, &nf->fn.prefix, nf->fn.pxlen);
+ anet = fib_find(&oa->enet_fib, nf->fn.addr);
if (anet)
break;
}
@@ -1164,6 +1159,7 @@ ospf_rt_abr1(struct ospf_proto *p)
{
struct area_net *anet;
ort *nf, *default_nf;
+ net_addr default_net;
/* RFC 2328 G.3 - incomplete resolution of virtual next hops - routers */
FIB_WALK(&p->backbone->rtr, nftmp)
@@ -1189,7 +1185,7 @@ ospf_rt_abr1(struct ospf_proto *p)
/* Compute condensed area networks */
if (nf->n.type == RTS_OSPF)
{
- anet = (struct area_net *) fib_route(&nf->n.oa->net_fib, nf->fn.prefix, nf->fn.pxlen);
+ anet = (struct area_net *) fib_route(&nf->n.oa->net_fib, nf->fn.addr);
if (anet)
{
if (!anet->active)
@@ -1197,7 +1193,7 @@ ospf_rt_abr1(struct ospf_proto *p)
anet->active = 1;
/* 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);
+ ort *nfi = fib_get(&p->rtf, anet->fn.addr);
nfi->area_net = 1;
/* 16.2. (3) */
@@ -1212,8 +1208,13 @@ ospf_rt_abr1(struct ospf_proto *p)
}
FIB_WALK_END;
- ip_addr addr = IPA_NONE;
- default_nf = (ort *) fib_get(&p->rtf, &addr, 0);
+
+ if (ospf_is_v2(p))
+ net_fill_ip4(&default_net, IP4_NONE, 0);
+ else
+ net_fill_ip6(&default_net, IP6_NONE, 0);
+
+ default_nf = fib_get(&p->rtf, &default_net);
default_nf->area_net = 1;
struct ospf_area *oa;
@@ -1244,7 +1245,7 @@ ospf_rt_abr1(struct ospf_proto *p)
{
nf = (ort *) nftmp;
if (nf->n.options & ORTA_ASBR)
- ri_install_asbr(p, &nf->fn.prefix, &nf->n);
+ ri_install_asbr(p, rid_from_net(nf->fn.addr), &nf->n);
}
FIB_WALK_END;
}
@@ -1300,7 +1301,7 @@ ospf_rt_abr2(struct ospf_proto *p)
if (!nf->n.type || !(nf->n.options & ORTA_ABR))
continue;
- nf2 = fib_find(&bb->rtr, &nf->fn.prefix, MAX_PREFIX_LENGTH);
+ nf2 = fib_find(&bb->rtr, nf->fn.addr);
if (!nf2 || !nf2->n.type || !(nf2->n.options & ORTA_ABR))
continue;
@@ -1346,7 +1347,7 @@ ospf_rt_abr2(struct ospf_proto *p)
if (rt_is_nssa(nf) && (nf->n.options & ORTA_PROP))
{
struct area_net *anet = (struct area_net *)
- fib_route(&nf->n.oa->enet_fib, nf->fn.prefix, nf->fn.pxlen);
+ fib_route(&nf->n.oa->enet_fib, nf->fn.addr);
if (anet)
{
@@ -1355,7 +1356,7 @@ ospf_rt_abr2(struct ospf_proto *p)
anet->active = 1;
/* 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 = fib_get(&p->rtf, anet->fn.addr);
nf2->area_net = 1;
}
@@ -1383,22 +1384,57 @@ ospf_rt_abr2(struct ospf_proto *p)
/* Like fib_route(), but ignores dummy rt entries */
static void *
-ospf_fib_route(struct fib *f, ip_addr a, int len)
+ospf_fib_route_ip4(struct fib *f, ip4_addr a, int len)
+{
+ net_addr_ip4 net = NET_ADDR_IP4(a, len);
+ ort *nf;
+
+loop:
+ nf = fib_find(f, (net_addr *) &net);
+ if (nf && nf->n.type)
+ return nf;
+
+ if (net.pxlen > 0)
+ {
+ net.pxlen--;
+ ip4_clrbit(&net.prefix, net.pxlen);
+ goto loop;
+ }
+
+ return NULL;
+}
+
+static void *
+ospf_fib_route_ip6(struct fib *f, ip6_addr a, int len)
{
- ip_addr a0;
+ net_addr_ip6 net = NET_ADDR_IP6(a, len);
ort *nf;
- while (len >= 0)
+loop:
+ nf = fib_find(f, (net_addr *) &net);
+ if (nf && nf->n.type)
+ return nf;
+
+ if (net.pxlen > 0)
{
- a0 = ipa_and(a, ipa_mkmask(len));
- nf = fib_find(f, &a0, len);
- if (nf && nf->n.type)
- return nf;
- len--;
+ net.pxlen--;
+ ip6_clrbit(&net.prefix, net.pxlen);
+ goto loop;
}
+
return NULL;
}
+static void *
+ospf_fib_route(struct fib *f, ip_addr a)
+{
+ if (ospf_is_v2(p))
+ return ospf_fib_route_ip4(f, ipa_to_ip4(a), IP4_MAX_PREFIX_LENGTH);
+ else
+ return ospf_fib_route_ip6(f, ipa_to_ip6(a), IP6_MAX_PREFIX_LENGTH);
+}
+
+
/* RFC 2328 16.4. calculating external routes */
static void
ospf_ext_spf(struct ospf_proto *p)
@@ -1407,7 +1443,6 @@ ospf_ext_spf(struct ospf_proto *p)
struct ospf_lsa_ext_local rt;
ort *nf1, *nf2;
orta nfa = {};
- ip_addr rtid;
u32 br_metric;
struct ospf_area *atmp;
@@ -1437,7 +1472,7 @@ ospf_ext_spf(struct ospf_proto *p)
if (rt.pxopts & OPT_PX_NU)
continue;
- if (rt.pxlen < 0 || rt.pxlen > MAX_PREFIX_LENGTH)
+ if (rt.net.pxlen > MAX_PREFIX_LENGTH)
{
log(L_WARN "%s: Invalid prefix in LSA (Type: %04x, Id: %R, Rt: %R)",
p->p.name, en->lsa_type, en->lsa.id, en->lsa.rt);
@@ -1457,8 +1492,8 @@ ospf_ext_spf(struct ospf_proto *p)
if (!atmp)
continue; /* Should not happen */
- rtid = ipa_from_rid(en->lsa.rt);
- nf1 = fib_find(&atmp->rtr, &rtid, MAX_PREFIX_LENGTH);
+ net_addr_ip4 nrid = net_from_rid(en->lsa.rt);
+ nf1 = fib_find(&atmp->rtr, (net_addr *) &nrid);
if (!nf1 || !nf1->n.type)
continue; /* No AS boundary router found */
@@ -1468,7 +1503,7 @@ ospf_ext_spf(struct ospf_proto *p)
/* 16.4. (3) NSSA - special rule for default routes */
/* ABR should use default only if P-bit is set and summaries are active */
- if ((en->lsa_type == LSA_T_NSSA) && ipa_zero(rt.ip) && (rt.pxlen == 0) &&
+ if ((en->lsa_type == LSA_T_NSSA) && (rt.net.pxlen == 0) &&
(p->areano > 1) && !(rt.propagate && atmp->ac->summary))
continue;
@@ -1480,7 +1515,7 @@ ospf_ext_spf(struct ospf_proto *p)
}
else
{
- nf2 = ospf_fib_route(&p->rtf, rt.fwaddr, MAX_PREFIX_LENGTH);
+ nf2 = ospf_fib_route(&p->rtf, rt.fwaddr);
if (!nf2)
continue;
@@ -1542,7 +1577,7 @@ ospf_ext_spf(struct ospf_proto *p)
nfa.oa = atmp; /* undefined in RFC 2328 */
nfa.en = en; /* store LSA for later (NSSA processing) */
- ri_install_ext(p, rt.ip, rt.pxlen, &nfa);
+ ri_install_ext(p, &rt.net, &nfa);
}
}
@@ -1961,7 +1996,7 @@ again1:
if (reload || ort_changed(nf, &a0))
{
- net *ne = net_get(p->p.table, nf->fn.prefix, nf->fn.pxlen);
+ net *ne = net_get(p->p.table, nf->fn.addr);
rta *a = rta_lookup(&a0);
rte *e = rte_get_temp(a);
@@ -1975,8 +2010,8 @@ again1:
e->net = ne;
e->pref = p->p.preference;
- DBG("Mod rte type %d - %I/%d via %I on iface %s, met %d\n",
- a0.source, nf->fn.prefix, nf->fn.pxlen, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
+ DBG("Mod rte type %d - %N via %I on iface %s, met %d\n",
+ a0.source, nf->fn.addr, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
rte_update(&p->p, ne, e);
}
}
@@ -1986,7 +2021,7 @@ again1:
rta_free(nf->old_rta);
nf->old_rta = NULL;
- net *ne = net_get(p->p.table, nf->fn.prefix, nf->fn.pxlen);
+ net *ne = net_get(p->p.table, nf->fn.addr);
rte_update(&p->p, ne, NULL);
}
diff --git a/proto/ospf/rt.h b/proto/ospf/rt.h
index 30332f3b..80243c9a 100644
--- a/proto/ospf/rt.h
+++ b/proto/ospf/rt.h
@@ -78,12 +78,13 @@ typedef struct ort
* route was not in the last update, in that case other old_* values are not
* valid.
*/
- struct fib_node fn;
orta n;
u32 old_metric1, old_metric2, old_tag, old_rid;
rta *old_rta;
u8 external_rte;
u8 area_net;
+
+ struct fib_node fn;
}
ort;
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 8119cfa6..59e76019 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;
@@ -520,8 +520,8 @@ 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
@@ -551,8 +551,9 @@ ort_to_lsaid(struct ospf_proto *p, ort *nf)
if (ospf_is_v3(p))
return nf->fn.uid;
- u32 id = ipa_to_u32(nf->fn.prefix);
- int pxlen = nf->fn.pxlen;
+ 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 +629,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 +782,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 +792,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 +910,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 +1002,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 +1032,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 +1040,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 +1086,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 +1094,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 +1102,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 +1144,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 +1181,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 +1219,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;
@@ -1253,7 +1258,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 +1295,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 +1313,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 +1335,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 +1407,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 +1421,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 +1437,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 +1455,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;
}
diff --git a/proto/ospf/topology.h b/proto/ospf/topology.h
index 5652ced0..1dbee070 100644
--- a/proto/ospf/topology.h
+++ b/proto/ospf/topology.h
@@ -185,7 +185,7 @@ static inline void ospf_flush2_lsa(struct ospf_proto *p, struct top_hash_entry *
{ if (*en) { ospf_flush_lsa(p, *en); *en = NULL; } }
void ospf_originate_sum_net_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric);
-void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, int metric, u32 options);
+void ospf_originate_sum_rt_lsa(struct ospf_proto *p, struct ospf_area *oa, u32 drid, int metric, u32 options);
void ospf_originate_ext_lsa(struct ospf_proto *p, struct ospf_area *oa, ort *nf, u8 mode, u32 metric, u32 ebit, ip_addr fwaddr, u32 tag, int pbit);
void ospf_rt_notify(struct proto *P, rtable *tbl, net *n, rte *new, rte *old, ea_list *attrs);
diff --git a/proto/pipe/pipe.c b/proto/pipe/pipe.c
index 6ef80322..42285880 100644
--- a/proto/pipe/pipe.c
+++ b/proto/pipe/pipe.c
@@ -60,12 +60,12 @@ pipe_rt_notify(struct proto *P, rtable *src_table, net *n, rte *new, rte *old, e
if (dst_table->pipe_busy)
{
- log(L_ERR "Pipe loop detected when sending %I/%d to table %s",
- n->n.prefix, n->n.pxlen, dst_table->name);
+ log(L_ERR "Pipe loop detected when sending %N to table %s",
+ n->n.addr, dst_table->name);
return;
}
- nn = net_get(dst_table, n->n.prefix, n->n.pxlen);
+ nn = net_get(dst_table, n->n.addr);
if (new)
{
memcpy(&a, new->attrs, sizeof(rta));
diff --git a/proto/radv/config.Y b/proto/radv/config.Y
index da300667..efb474a6 100644
--- a/proto/radv/config.Y
+++ b/proto/radv/config.Y
@@ -53,9 +53,8 @@ radv_proto_item:
| PREFIX radv_prefix { add_tail(&RADV_CFG->pref_list, NODE this_radv_prefix); }
| RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_CFG->rdnss_list, &radv_dns_list); }
| DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_CFG->dnssl_list, &radv_dns_list); }
- | TRIGGER prefix {
- RADV_CFG->trigger_prefix = $2.addr;
- RADV_CFG->trigger_pxlen = $2.len;
+ | TRIGGER net_any {
+ RADV_CFG->trigger = $2;
RADV_CFG->trigger_valid = 1;
}
;
@@ -148,11 +147,10 @@ radv_iface:
radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish;
-radv_prefix_start: prefix
+radv_prefix_start: net_ip6
{
this_radv_prefix = cfg_allocz(sizeof(struct radv_prefix_config));
- RADV_PREFIX->prefix = $1.addr;
- RADV_PREFIX->pxlen = $1.len;
+ RADV_PREFIX->prefix = $1.ip6;
RADV_PREFIX->onlink = 1;
RADV_PREFIX->autonomous = 1;
diff --git a/proto/radv/packets.c b/proto/radv/packets.c
index 3862af8d..a38b58b2 100644
--- a/proto/radv/packets.c
+++ b/proto/radv/packets.c
@@ -38,7 +38,7 @@ struct radv_opt_prefix
u32 valid_lifetime;
u32 preferred_lifetime;
u32 reserved;
- ip_addr prefix;
+ ip6_addr prefix;
};
#define OPT_PX_ONLINK 0x80
@@ -58,7 +58,7 @@ struct radv_opt_rdnss
u8 length;
u16 reserved;
u32 lifetime;
- ip_addr servers[];
+ ip6_addr servers[];
};
struct radv_opt_dnssl
@@ -90,11 +90,11 @@ radv_prefix_match(struct radv_iface *ifa, struct ifa *a)
return NULL;
WALK_LIST(pc, ifa->cf->pref_list)
- if ((a->pxlen >= pc->pxlen) && ipa_in_net(a->prefix, pc->prefix, pc->pxlen))
+ if (net_in_netX(&a->prefix, (net_addr *) &pc->prefix))
return pc;
WALK_LIST(pc, cf->pref_list)
- if ((a->pxlen >= pc->pxlen) && ipa_in_net(a->prefix, pc->prefix, pc->pxlen))
+ if (net_in_netX(&a->prefix, (net_addr *) &pc->prefix))
return pc;
return &default_prefix;
@@ -109,7 +109,7 @@ radv_prepare_rdnss(struct radv_iface *ifa, list *rdnss_list, char **buf, char *b
{
struct radv_rdnss_config *rcf_base = rcf;
struct radv_opt_rdnss *op = (void *) *buf;
- int max_i = (bufend - *buf - sizeof(struct radv_opt_rdnss)) / sizeof(ip_addr);
+ int max_i = (bufend - *buf - sizeof(struct radv_opt_rdnss)) / sizeof(ip6_addr);
int i = 0;
if (max_i < 1)
@@ -123,20 +123,19 @@ radv_prepare_rdnss(struct radv_iface *ifa, list *rdnss_list, char **buf, char *b
else
op->lifetime = htonl(rcf->lifetime);
- while(NODE_VALID(rcf) &&
+ while(NODE_VALID(rcf) &&
(rcf->lifetime == rcf_base->lifetime) &&
(rcf->lifetime_mult == rcf_base->lifetime_mult))
{
if (i >= max_i)
goto too_much;
- op->servers[i] = rcf->server;
- ipa_hton(op->servers[i]);
+ op->servers[i] = ip6_hton(rcf->server);
i++;
rcf = NODE_NEXT(rcf);
}
-
+
op->length = 1+2*i;
*buf += 8 * op->length;
}
@@ -273,6 +272,9 @@ radv_prepare_ra(struct radv_iface *ifa)
struct ifa *addr;
WALK_LIST(addr, ifa->iface->addrs)
{
+ if (addr->prefix.type != NET_IP6)
+ continue;
+
struct radv_prefix_config *pc;
pc = radv_prefix_match(ifa, addr);
@@ -288,7 +290,7 @@ radv_prepare_ra(struct radv_iface *ifa)
struct radv_opt_prefix *op = (void *) buf;
op->type = OPT_PREFIX;
op->length = 4;
- op->pxlen = addr->pxlen;
+ op->pxlen = net6_pxlen(&addr->prefix);
op->flags = (pc->onlink ? OPT_PX_ONLINK : 0) |
(pc->autonomous ? OPT_PX_AUTONOMOUS : 0);
op->valid_lifetime = (ra->active || !pc->valid_lifetime_sensitive) ?
@@ -296,8 +298,7 @@ radv_prepare_ra(struct radv_iface *ifa)
op->preferred_lifetime = (ra->active || !pc->preferred_lifetime_sensitive) ?
htonl(pc->preferred_lifetime) : 0;
op->reserved = 0;
- op->prefix = addr->prefix;
- ipa_hton(op->prefix);
+ op->prefix = ip6_hton(net6_prefix(&addr->prefix));
buf += sizeof(*op);
}
diff --git a/proto/radv/radv.c b/proto/radv/radv.c
index 6370e006..97713b95 100644
--- a/proto/radv/radv.c
+++ b/proto/radv/radv.c
@@ -143,7 +143,7 @@ find_lladdr(struct iface *iface)
{
struct ifa *a;
WALK_LIST(a, iface->addrs)
- if (a->scope == SCOPE_LINK)
+ if ((a->prefix.type == NET_IP6) && (a->scope == SCOPE_LINK))
return a;
return NULL;
@@ -258,9 +258,7 @@ radv_ifa_notify(struct proto *p, unsigned flags, struct ifa *a)
static inline int radv_net_match_trigger(struct radv_config *cf, net *n)
{
- return cf->trigger_valid &&
- (n->n.pxlen == cf->trigger_pxlen) &&
- ipa_equal(n->n.prefix, cf->trigger_prefix);
+ return cf->trigger_valid && net_equal(n->n.addr, cf->trigger);
}
int
@@ -306,8 +304,7 @@ radv_check_active(struct proto_radv *ra)
if (! cf->trigger_valid)
return 1;
- return rt_examine(ra->p.table, cf->trigger_prefix, cf->trigger_pxlen,
- &(ra->p), ra->p.cf->out_filter);
+ return rt_examine(ra->p.table, cf->trigger, &ra->p, ra->p.cf->out_filter);
}
static struct proto *
diff --git a/proto/radv/radv.h b/proto/radv/radv.h
index 48ba9c1a..755009d4 100644
--- a/proto/radv/radv.h
+++ b/proto/radv/radv.h
@@ -50,8 +50,7 @@ struct radv_config
list rdnss_list; /* Global list of RDNSS configs (struct radv_rdnss_config) */
list dnssl_list; /* Global list of DNSSL configs (struct radv_dnssl_config) */
- ip_addr trigger_prefix; /* Prefix of a trigger route, if defined */
- u8 trigger_pxlen; /* Pxlen of a trigger route, if defined */
+ net_addr *trigger; /* Prefix of a trigger route, if defined */
u8 trigger_valid; /* Whether a trigger route is defined */
};
@@ -83,8 +82,7 @@ struct radv_iface_config
struct radv_prefix_config
{
node n;
- ip_addr prefix;
- int pxlen;
+ net_addr_ip6 prefix;
u8 skip; /* Do not include this prefix to RA */
u8 onlink; /* Standard options from RFC 4261 */
@@ -100,7 +98,7 @@ struct radv_rdnss_config
node n;
u32 lifetime; /* Valid if lifetime_mult is 0 */
u16 lifetime_mult; /* Lifetime specified as multiple of max_ra_int */
- ip_addr server; /* IP address of recursive DNS server */
+ ip6_addr server; /* IP address of recursive DNS server */
};
struct radv_dnssl_config
diff --git a/proto/rip/packets.c b/proto/rip/packets.c
index 9f10fd67..4fc832d5 100644
--- a/proto/rip/packets.c
+++ b/proto/rip/packets.c
@@ -78,8 +78,7 @@ struct rip_auth_tail
/* Internal representation of RTE block data */
struct rip_block
{
- ip_addr prefix;
- int pxlen;
+ net_addr net;
u32 metric;
u16 tag;
u16 no_af;
@@ -115,17 +114,17 @@ rip_put_block(struct rip_proto *p, byte *pos, struct rip_block *rte)
struct rip_block_v2 *block = (void *) pos;
block->family = rte->no_af ? 0 : htons(RIP_AF_IPV4);
block->tag = htons(rte->tag);
- block->network = ip4_hton(ipa_to_ip4(rte->prefix));
- block->netmask = ip4_hton(ip4_mkmask(rte->pxlen));
+ block->network = ip4_hton(net4_prefix(&rte->net));
+ block->netmask = ip4_hton(ip4_mkmask(net4_pxlen(&rte->net)));
block->next_hop = ip4_hton(ipa_to_ip4(rte->next_hop));
block->metric = htonl(rte->metric);
}
else /* RIPng */
{
struct rip_block_ng *block = (void *) pos;
- block->prefix = ip6_hton(ipa_to_ip6(rte->prefix));
+ block->prefix = ip6_hton(net6_prefix(&rte->net));
block->tag = htons(rte->tag);
- block->pxlen = rte->pxlen;
+ block->pxlen = net6_pxlen(&rte->net);
block->metric = rte->metric;
}
}
@@ -151,8 +150,8 @@ rip_get_block(struct rip_proto *p, byte *pos, struct rip_block *rte)
if (block->family != (rte->no_af ? 0 : htons(RIP_AF_IPV4)))
return 0;
- rte->prefix = ipa_from_ip4(ip4_ntoh(block->network));
- rte->pxlen = ip4_masklen(ip4_ntoh(block->netmask));
+ uint pxlen = ip4_masklen(ip4_ntoh(block->netmask));
+ net_fill_ip4(&rte->net, ip4_ntoh(block->network), pxlen);
rte->metric = ntohl(block->metric);
rte->tag = ntohs(block->tag);
rte->next_hop = ipa_from_ip4(ip4_ntoh(block->next_hop));
@@ -171,8 +170,8 @@ rip_get_block(struct rip_proto *p, byte *pos, struct rip_block *rte)
return 0;
}
- rte->prefix = ipa_from_ip6(ip6_ntoh(block->prefix));
- rte->pxlen = block->pxlen;
+ uint pxlen = (block->pxlen < IP6_MAX_PREFIX_LENGTH) ? block->pxlen : 255;
+ net_fill_ip6(&rte->net, ip6_ntoh(block->prefix), pxlen);
rte->metric = block->metric;
rte->tag = ntohs(block->tag);
/* rte->next_hop is deliberately kept unmodified */;
@@ -383,8 +382,9 @@ rip_receive_request(struct rip_proto *p, struct rip_iface *ifa, struct rip_packe
if (!rip_get_block(p, pos, &b))
return;
- /* Special case - zero prefix, infinity metric */
- if (ipa_nonzero(b.prefix) || b.pxlen || (b.metric != p->infinity))
+ /* Special case - infinity metric, for RIPng also zero prefix */
+ if ((b.metric != p->infinity) ||
+ (rip_is_ng(p) && !net_zero_ip6((net_addr_ip6 *) &b.net)))
return;
/* We do nothing if TX is already active */
@@ -442,23 +442,23 @@ rip_send_response(struct rip_proto *p, struct rip_iface *ifa)
}
struct rip_block rte = {
- .prefix = en->n.prefix,
- .pxlen = en->n.pxlen,
.metric = en->metric,
.tag = en->tag
};
+ net_copy(&rte.net, en->n.addr);
+
if (en->iface == ifa->iface)
rte.next_hop = en->next_hop;
if (rip_is_v2(p) && (ifa->cf->version == RIP_V1))
{
/* Skipping subnets (i.e. not hosts, classful networks or default route) */
- if (ip4_masklen(ip4_class_mask(ipa_to_ip4(en->n.prefix))) != en->n.pxlen)
+ if (ip4_masklen(ip4_class_mask(net4_prefix(&rte.net))) != rte.net.pxlen)
goto next_entry;
rte.tag = 0;
- rte.pxlen = 0;
+ rte.net.pxlen = 0;
rte.next_hop = IPA_NONE;
}
@@ -474,7 +474,7 @@ rip_send_response(struct rip_proto *p, struct rip_iface *ifa)
goto next_entry;
}
- // TRACE(D_PACKETS, " %I/%d -> %I metric %d", rte.prefix, rte.pxlen, rte.next_hop, rte.metric);
+ // TRACE(D_PACKETS, " %N -> %I metric %d", &rte.net, rte.next_hop, rte.metric);
/* RIPng next hop entry */
if (rip_is_ng(p) && !ipa_equal(rte.next_hop, last_next_hop))
@@ -575,23 +575,25 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
if (!rip_get_block(p, pos, &rte))
continue;
- int c = ipa_classify_net(rte.prefix);
- if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
- SKIP("invalid prefix");
-
if (rip_is_v2(p) && (pkt->version == RIP_V1))
{
- if (ifa->cf->check_zero && (rte.tag || rte.pxlen || ipa_nonzero(rte.next_hop)))
+ if (ifa->cf->check_zero && (rte.tag || rte.net.pxlen || ipa_nonzero(rte.next_hop)))
SKIP("RIPv1 reserved field is nonzero");
rte.tag = 0;
- rte.pxlen = ip4_masklen(ip4_class_mask(ipa_to_ip4(rte.prefix)));
+ rte.net.pxlen = ip4_masklen(ip4_class_mask(net4_prefix(&rte.net)));
rte.next_hop = IPA_NONE;
}
- if ((rte.pxlen < 0) || (rte.pxlen > MAX_PREFIX_LENGTH))
+ if (rte.net.pxlen == 255)
SKIP("invalid prefix length");
+ net_normalize(&rte.net);
+
+ int c = net_classify(&rte.net);
+ if ((c < 0) || !(c & IADDR_HOST) || ((c & IADDR_SCOPE_MASK) <= SCOPE_LINK))
+ SKIP("invalid prefix");
+
if (rte.metric > p->infinity)
SKIP("invalid metric");
@@ -602,7 +604,7 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
rte.next_hop = IPA_NONE;
}
- // TRACE(D_PACKETS, " %I/%d -> %I metric %d", rte.prefix, rte.pxlen, rte.next_hop, rte.metric);
+ // TRACE(D_PACKETS, " %N -> %I metric %d", &rte.net.n, rte.next_hop, rte.metric);
rte.metric += ifa->cf->metric;
@@ -616,16 +618,16 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
.expires = now + ifa->cf->timeout_time
};
- rip_update_rte(p, &rte.prefix, rte.pxlen, &new);
+ rip_update_rte(p, &rte.net, &new);
}
else
- rip_withdraw_rte(p, &rte.prefix, rte.pxlen, from);
+ rip_withdraw_rte(p, &rte.net, from);
continue;
skip:
- LOG_RTE("Ignoring route %I/%d received from %I - %s",
- rte.prefix, rte.pxlen, from->nbr->addr, err_dsc);
+ LOG_RTE("Ignoring route %N received from %I - %s",
+ &rte.net, from->nbr->addr, err_dsc);
}
}
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index c85fd69b..d8c3b6a8 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -92,15 +92,6 @@ static void rip_trigger_update(struct rip_proto *p);
* RIP routes
*/
-static void
-rip_init_entry(struct fib_node *fn)
-{
- // struct rip_entry *en = (void) *fn;
-
- const uint offset = OFFSETOF(struct rip_entry, routes);
- memset((byte *)fn + offset, 0, sizeof(struct rip_entry) - offset);
-}
-
static struct rip_rte *
rip_add_rte(struct rip_proto *p, struct rip_rte **rp, struct rip_rte *src)
{
@@ -152,7 +143,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
if (rt)
{
/* Update */
- net *n = net_get(p->p.table, en->n.prefix, en->n.pxlen);
+ net *n = net_get(p->p.table, en->n.addr);
rta a0 = {
.src = p->p.main_source,
@@ -221,7 +212,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
else
{
/* Withdraw */
- net *n = net_find(p->p.table, en->n.prefix, en->n.pxlen);
+ net *n = net_find(p->p.table, en->n.addr);
rte_update(&p->p, n, NULL);
}
}
@@ -229,8 +220,7 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
/**
* rip_update_rte - enter a route update to RIP routing table
* @p: RIP instance
- * @prefix: network prefix
- * @pxlen: network prefix length
+ * @addr: network address
* @new: a &rip_rte representing the new route
*
* The function is called by the RIP packet processing code whenever it receives
@@ -240,9 +230,9 @@ rip_announce_rte(struct rip_proto *p, struct rip_entry *en)
* rip_withdraw_rte() should be called instead of rip_update_rte().
*/
void
-rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte *new)
+rip_update_rte(struct rip_proto *p, net_addr *n, struct rip_rte *new)
{
- struct rip_entry *en = fib_get(&p->rtable, prefix, pxlen);
+ struct rip_entry *en = fib_get(&p->rtable, n);
struct rip_rte *rt, **rp;
int changed = 0;
@@ -282,8 +272,7 @@ rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte *
/**
* rip_withdraw_rte - enter a route withdraw to RIP routing table
* @p: RIP instance
- * @prefix: network prefix
- * @pxlen: network prefix length
+ * @addr: network address
* @from: a &rip_neighbor propagating the withdraw
*
* The function is called by the RIP packet processing code whenever it receives
@@ -291,9 +280,9 @@ rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte *
* removed. Eventually, the change is also propagated by rip_announce_rte().
*/
void
-rip_withdraw_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_neighbor *from)
+rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from)
{
- struct rip_entry *en = fib_find(&p->rtable, prefix, pxlen);
+ struct rip_entry *en = fib_find(&p->rtable, n);
struct rip_rte *rt, **rp;
if (!en)
@@ -335,15 +324,15 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net,
if (rt_metric > p->infinity)
{
- log(L_WARN "%s: Invalid rip_metric value %u for route %I/%d",
- p->p.name, rt_metric, net->n.prefix, net->n.pxlen);
+ log(L_WARN "%s: Invalid rip_metric value %u for route %N",
+ p->p.name, rt_metric, net->n.addr);
rt_metric = p->infinity;
}
if (rt_tag > 0xffff)
{
- log(L_WARN "%s: Invalid rip_tag value %u for route %I/%d",
- p->p.name, rt_tag, net->n.prefix, net->n.pxlen);
+ log(L_WARN "%s: Invalid rip_tag value %u for route %N",
+ p->p.name, rt_tag, net->n.addr);
rt_metric = p->infinity;
rt_tag = 0;
}
@@ -355,7 +344,7 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net,
* collection.
*/
- en = fib_get(&p->rtable, &net->n.prefix, net->n.pxlen);
+ en = fib_get(&p->rtable, net->n.addr);
old_metric = en->valid ? en->metric : -1;
@@ -369,7 +358,7 @@ rip_rt_notify(struct proto *P, struct rtable *table UNUSED, struct network *net,
else
{
/* Withdraw */
- en = fib_find(&p->rtable, &net->n.prefix, net->n.pxlen);
+ en = fib_find(&p->rtable, net->n.addr);
if (!en || en->valid != RIP_ENTRY_VALID)
return;
@@ -875,7 +864,7 @@ rip_timer(timer *t)
if (expires <= now)
{
- // TRACE(D_EVENTS, "entry is too old: %I/%d", en->n.prefix, en->n.pxlen);
+ // TRACE(D_EVENTS, "entry is too old: %N", en->n.addr);
en->valid = 0;
}
else
@@ -1108,7 +1097,8 @@ rip_start(struct proto *P)
struct rip_config *cf = (void *) (P->cf);
init_list(&p->iface_list);
- fib_init(&p->rtable, P->pool, sizeof(struct rip_entry), 0, rip_init_entry);
+ fib_init(&p->rtable, P->pool, rip_is_v2(p) ? NET_IP4 : NET_IP6,
+ sizeof(struct rip_entry), OFFSETOF(struct rip_entry, n), 0, NULL);
p->rte_slab = sl_new(P->pool, sizeof(struct rip_rte));
p->timer = tm_new_set(P->pool, rip_timer, p, 0, 0);
@@ -1257,8 +1247,8 @@ rip_dump(struct proto *P)
FIB_WALK(&p->rtable, e)
{
struct rip_entry *en = (struct rip_entry *) e;
- debug("RIP: entry #%d: %I/%d via %I dev %s valid %d metric %d age %d s\n",
- i++, en->n.prefix, en->n.pxlen, en->next_hop, en->iface->name,
+ debug("RIP: entry #%d: %N via %I dev %s valid %d metric %d age %d s\n",
+ i++, en->n.addr, en->next_hop, en->iface->name,
en->valid, en->metric, now - en->changed);
}
FIB_WALK_END;
diff --git a/proto/rip/rip.h b/proto/rip/rip.h
index f245e612..97c5ab3f 100644
--- a/proto/rip/rip.h
+++ b/proto/rip/rip.h
@@ -149,7 +149,6 @@ struct rip_neighbor
struct rip_entry
{
- struct fib_node n;
struct rip_rte *routes; /* List of incoming routes */
u8 valid; /* Entry validity state (RIP_ENTRY_*) */
@@ -160,6 +159,8 @@ struct rip_entry
ip_addr next_hop; /* Outgoing route next hop */
bird_clock_t changed; /* Last time when the outgoing route metric changed */
+
+ struct fib_node n;
};
struct rip_rte
@@ -211,8 +212,8 @@ rip_reset_tx_session(struct rip_proto *p, struct rip_iface *ifa)
}
/* rip.c */
-void rip_update_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_rte *new);
-void rip_withdraw_rte(struct rip_proto *p, ip_addr *prefix, int pxlen, struct rip_neighbor *from);
+void rip_update_rte(struct rip_proto *p, net_addr *n, struct rip_rte *new);
+void rip_withdraw_rte(struct rip_proto *p, net_addr *n, struct rip_neighbor *from);
struct rip_neighbor * rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct rip_iface *ifa);
void rip_update_bfd(struct rip_proto *p, struct rip_neighbor *n);
void rip_show_interfaces(struct proto *P, char *iff);
diff --git a/proto/static/config.Y b/proto/static/config.Y
index 182721b3..9e634803 100644
--- a/proto/static/config.Y
+++ b/proto/static/config.Y
@@ -52,11 +52,10 @@ static_proto:
| static_proto stat_route stat_route_opt_list ';' { static_route_finish(); }
;
-stat_route0: ROUTE prefix {
+stat_route0: ROUTE net_any {
this_srt = cfg_allocz(sizeof(struct static_route));
add_tail(&STATIC_CFG->other_routes, &this_srt->n);
- this_srt->net = $2.addr;
- this_srt->masklen = $2.len;
+ this_srt->net = $2;
this_srt_last_cmd = &(this_srt->cmds);
}
;
@@ -72,7 +71,7 @@ stat_multipath1:
this_srt_nh->use_bfd = -1; /* undefined */
}
| stat_multipath1 WEIGHT expr {
- this_srt_nh->masklen = $3 - 1; /* really */
+ this_srt_nh->weight = $3 - 1;
if (($3<1) || ($3>256)) cf_error("Weight must be in range 1-256");
}
| stat_multipath1 BFD bool {
diff --git a/proto/static/static.c b/proto/static/static.c
index be808593..bc5f104f 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -26,7 +26,7 @@
* nodes (of dest RTD_NONE), which stores info about nexthops and are
* connected to neighbor entries and neighbor notifications. Dummy
* nodes are chained using mp_next, they aren't in other_routes list,
- * and abuse some fields (masklen, if_name) for other purposes.
+ * and abuse if_name field for other purposes.
*
* The only other thing worth mentioning is that when asked for reconfiguration,
* Static not only compares the two configurations, but it also calculates
@@ -67,7 +67,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
if (r->installed > 0)
return;
- DBG("Installing static route %I/%d, rtd=%d\n", r->net, r->masklen, r->dest);
+ DBG("Installing static route %N, rtd=%d\n", r->net, r->dest);
bzero(&a, sizeof(a));
a.src = p->main_source;
a.source = (r->dest == RTD_DEVICE) ? RTS_STATIC_DEVICE : RTS_STATIC;
@@ -89,7 +89,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
struct mpnh *nh = alloca(sizeof(struct mpnh));
nh->gw = r2->via;
nh->iface = r2->neigh->iface;
- nh->weight = r2->masklen; /* really */
+ nh->weight = r2->weight;
nh->next = NULL;
*nhp = nh;
nhp = &(nh->next);
@@ -112,7 +112,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
/* We skip rta_lookup() here */
- n = net_get(p->table, r->net, r->masklen);
+ n = net_get(p->table, r->net);
e = rte_get_temp(&a);
e->net = n;
e->pflags = 0;
@@ -135,8 +135,8 @@ static_remove(struct proto *p, struct static_route *r)
if (!r->installed)
return;
- DBG("Removing static route %I/%d via %I\n", r->net, r->masklen, r->via);
- n = net_find(p->table, r->net, r->masklen);
+ DBG("Removing static route %N via %I\n", r->net, r->via);
+ n = net_find(p->table, r->net);
rte_update(p, n, NULL);
r->installed = 0;
}
@@ -186,7 +186,7 @@ static_decide(struct static_config *cf, struct static_route *r)
static void
static_add(struct proto *p, struct static_config *cf, struct static_route *r)
{
- DBG("static_add(%I/%d,%d)\n", r->net, r->masklen, r->dest);
+ DBG("static_add(%N,%d)\n", r->net, r->dest);
switch (r->dest)
{
case RTD_ROUTER:
@@ -388,7 +388,7 @@ static_bfd_notify(struct bfd_request *req)
static void
static_dump_rt(struct static_route *r)
{
- debug("%-1I/%2d: ", r->net, r->masklen);
+ debug("%-1N: ", r->net);
switch (r->dest)
{
case RTD_ROUTER:
@@ -463,12 +463,6 @@ static_init(struct proto_config *c)
}
static inline int
-static_same_net(struct static_route *x, struct static_route *y)
-{
- return ipa_equal(x->net, y->net) && (x->masklen == y->masklen);
-}
-
-static inline int
static_same_dest(struct static_route *x, struct static_route *y)
{
if (x->dest != y->dest)
@@ -486,7 +480,10 @@ static_same_dest(struct static_route *x, struct static_route *y)
for (x = x->mp_next, y = y->mp_next;
x && y;
x = x->mp_next, y = y->mp_next)
- if (!ipa_equal(x->via, y->via) || (x->via_if != y->via_if) || (x->use_bfd != y->use_bfd))
+ if (!ipa_equal(x->via, y->via) ||
+ (x->via_if != y->via_if) ||
+ (x->use_bfd != y->use_bfd) ||
+ (x->weight != y->weight))
return 0;
return !x && !y;
@@ -521,11 +518,11 @@ static_match(struct proto *p, struct static_route *r, struct static_config *n)
r->neigh->data = NULL;
WALK_LIST(t, n->iface_routes)
- if (static_same_net(r, t))
+ if (net_equal(r->net, t->net))
goto found;
WALK_LIST(t, n->other_routes)
- if (static_same_net(r, t))
+ if (net_equal(r->net, t->net))
goto found;
static_remove(p, r);
@@ -659,13 +656,13 @@ static_show_rt(struct static_route *r)
case RTDX_RECURSIVE: bsprintf(via, "recursive %I", r->via); break;
default: bsprintf(via, "???");
}
- cli_msg(-1009, "%I/%d %s%s%s", r->net, r->masklen, via,
+ cli_msg(-1009, "%N %s%s%s", r->net, via,
r->bfd_req ? " (bfd)" : "", r->installed ? "" : " (dormant)");
struct static_route *r2;
if (r->dest == RTD_MULTIPATH)
for (r2 = r->mp_next; r2; r2 = r2->mp_next)
- cli_msg(-1009, "\tvia %I%J weight %d%s%s", r2->via, r2->via_if, r2->masklen + 1, /* really */
+ cli_msg(-1009, "\tvia %I%J weight %d%s%s", r2->via, r2->via_if, r2->weight + 1,
r2->bfd_req ? " (bfd)" : "", r2->installed ? "" : " (dormant)");
}
diff --git a/proto/static/static.h b/proto/static/static.h
index 6b047234..51486e83 100644
--- a/proto/static/static.h
+++ b/proto/static/static.h
@@ -26,8 +26,7 @@ void static_init_config(struct static_config *);
struct static_route {
node n;
struct static_route *chain; /* Next for the same neighbor */
- ip_addr net; /* Network we route */
- int masklen; /* Mask length */
+ net_addr *net; /* Network we route */
int dest; /* Destination type (RTD_*) */
ip_addr via; /* Destination router */
struct iface *via_if; /* Destination iface, for link-local vias */
@@ -37,6 +36,7 @@ struct static_route {
struct f_inst *cmds; /* List of commands for setting attributes */
int installed; /* Installed in rt table, -1 for reinstall */
int use_bfd; /* Configured to use BFD */
+ int weight; /* Multipath next hop weight */
struct bfd_request *bfd_req; /* BFD request, if BFD is used */
};