OSPF: Allow ifaces with host address as unnumbered PtP or PtMP ifaces
Ifaces with host address (/32) were forced to be stubby, but now they can be used as PtP or PtMP. For these ifaces we need to: - Do not force stub mode - Accept packets from any IP as local - Accept any configured neighbor as local - Detect ifaces properly as unnumbered - Use ONLINK flag for nexthops
This commit is contained in:
parent
bc591061f6
commit
2a0af925b8
4 changed files with 30 additions and 16 deletions
|
@ -529,14 +529,14 @@ add_nbma_node(struct ospf_iface *ifa, struct nbma_node *src, int found)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr)
|
ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr, int type)
|
||||||
{
|
{
|
||||||
/* vlink cannot be stub */
|
/* vlink cannot be stub */
|
||||||
if (ip->type == OSPF_IT_VLINK)
|
if (type == OSPF_IT_VLINK)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* a host address */
|
/* Host address on Broadcast/NBMA */
|
||||||
if (addr->flags & IA_HOST)
|
if (((type == OSPF_IT_BCAST) || (type == OSPF_IT_NBMA)) && (addr->flags & IA_HOST))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* a loopback iface */
|
/* a loopback iface */
|
||||||
|
@ -584,7 +584,6 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
|
||||||
ifa->strictnbma = ip->strictnbma;
|
ifa->strictnbma = ip->strictnbma;
|
||||||
ifa->waitint = ip->waitint;
|
ifa->waitint = ip->waitint;
|
||||||
ifa->deadint = ip->deadint;
|
ifa->deadint = ip->deadint;
|
||||||
ifa->stub = ospf_iface_stubby(ip, addr);
|
|
||||||
ifa->ioprob = OSPF_I_OK;
|
ifa->ioprob = OSPF_I_OK;
|
||||||
ifa->check_link = ip->check_link;
|
ifa->check_link = ip->check_link;
|
||||||
ifa->ecmp_weight = ip->ecmp_weight;
|
ifa->ecmp_weight = ip->ecmp_weight;
|
||||||
|
@ -598,18 +597,19 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
|
||||||
ifa->tx_length = ifa_tx_length(ifa);
|
ifa->tx_length = ifa_tx_length(ifa);
|
||||||
ifa->tx_hdrlen = ifa_tx_hdrlen(ifa);
|
ifa->tx_hdrlen = ifa_tx_hdrlen(ifa);
|
||||||
|
|
||||||
ifa->ptp_netmask = !(addr->flags & IA_PEER);
|
ifa->ptp_netmask = !(addr->flags & (IA_HOST | IA_PEER));
|
||||||
if (ip->ptp_netmask < 2)
|
if (ip->ptp_netmask < 2)
|
||||||
ifa->ptp_netmask = ip->ptp_netmask;
|
ifa->ptp_netmask = ip->ptp_netmask;
|
||||||
|
|
||||||
/* For compatibility, we may use ptp_address even for unnumbered links */
|
/* For compatibility, we may use ptp_address even for unnumbered links */
|
||||||
ifa->ptp_address = !(addr->flags & IA_PEER) || (p->gr_mode != OSPF_GR_ABLE);
|
ifa->ptp_address = !(addr->flags & (IA_HOST | IA_PEER)) || (p->gr_mode != OSPF_GR_ABLE);
|
||||||
if (ip->ptp_address < 2)
|
if (ip->ptp_address < 2)
|
||||||
ifa->ptp_address = ip->ptp_address;
|
ifa->ptp_address = ip->ptp_address;
|
||||||
|
|
||||||
ifa->drip = ifa->bdrip = ospf_is_v2(p) ? IPA_NONE4 : IPA_NONE6;
|
ifa->drip = ifa->bdrip = ospf_is_v2(p) ? IPA_NONE4 : IPA_NONE6;
|
||||||
|
|
||||||
ifa->type = ospf_iface_classify(ip->type, addr);
|
ifa->type = ospf_iface_classify(ip->type, addr);
|
||||||
|
ifa->stub = ospf_iface_stubby(ip, addr, ifa->type);
|
||||||
|
|
||||||
/* Check validity of interface type */
|
/* Check validity of interface type */
|
||||||
int old_type = ifa->type;
|
int old_type = ifa->type;
|
||||||
|
@ -647,7 +647,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,
|
should be used). Because OSPFv3 iface is not subnet-specific,
|
||||||
there is no need for ipa_in_net() check */
|
there is no need for ipa_in_net() check */
|
||||||
|
|
||||||
if (ospf_is_v2(p) && !ipa_in_netX(nb->ip, &addr->prefix))
|
if (ospf_is_v2(p) && !ospf_ipa_local(nb->ip, addr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
|
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
|
||||||
|
@ -767,7 +767,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
|
||||||
if (old_type != new_type)
|
if (old_type != new_type)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int new_stub = ospf_iface_stubby(new, ifa->addr);
|
int new_stub = ospf_iface_stubby(new, ifa->addr, new_type);
|
||||||
if (ifa->stub != new_stub)
|
if (ifa->stub != new_stub)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -929,7 +929,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
|
||||||
WALK_LIST(nb, new->nbma_list)
|
WALK_LIST(nb, new->nbma_list)
|
||||||
{
|
{
|
||||||
/* See related note in ospf_iface_new() */
|
/* See related note in ospf_iface_new() */
|
||||||
if (ospf_is_v2(p) && !ipa_in_netX(nb->ip, &ifa->addr->prefix))
|
if (ospf_is_v2(p) && !ospf_ipa_local(nb->ip, ifa->addr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
|
if (ospf_is_v3(p) && !ipa_is_link_local(nb->ip))
|
||||||
|
@ -1011,7 +1011,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
|
||||||
|
|
||||||
/* PtP netmask */
|
/* PtP netmask */
|
||||||
int new_ptp_netmask = (new->ptp_netmask < 2) ? new->ptp_netmask :
|
int new_ptp_netmask = (new->ptp_netmask < 2) ? new->ptp_netmask :
|
||||||
!(ifa->addr->flags & IA_PEER);
|
!(ifa->addr->flags & (IA_HOST | IA_PEER));
|
||||||
if (ifa->ptp_netmask != new_ptp_netmask)
|
if (ifa->ptp_netmask != new_ptp_netmask)
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS, "Changing PtP netmask option of %s from %d to %d",
|
OSPF_TRACE(D_EVENTS, "Changing PtP netmask option of %s from %d to %d",
|
||||||
|
@ -1021,7 +1021,7 @@ ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
|
||||||
|
|
||||||
/* PtP address */
|
/* PtP address */
|
||||||
int new_ptp_address = (new->ptp_address < 2) ? new->ptp_address :
|
int new_ptp_address = (new->ptp_address < 2) ? new->ptp_address :
|
||||||
(!(ifa->addr->flags & IA_PEER) || (p->gr_mode != OSPF_GR_ABLE));
|
(!(ifa->addr->flags & (IA_HOST | IA_PEER)) || (p->gr_mode != OSPF_GR_ABLE));
|
||||||
if (ifa->ptp_address != new_ptp_address)
|
if (ifa->ptp_address != new_ptp_address)
|
||||||
{
|
{
|
||||||
/* Keep it silent for implicit changes */
|
/* Keep it silent for implicit changes */
|
||||||
|
|
|
@ -946,6 +946,14 @@ struct lsadb_show_data {
|
||||||
#define EA_OSPF_ROUTER_ID EA_CODE(PROTOCOL_OSPF, 3)
|
#define EA_OSPF_ROUTER_ID EA_CODE(PROTOCOL_OSPF, 3)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For regular networks, neighbor address must match network prefix.
|
||||||
|
* For unnumbered networks, we consider every address local.
|
||||||
|
*/
|
||||||
|
static inline int ospf_ipa_local(ip_addr a, const struct ifa *addr)
|
||||||
|
{ return ipa_in_netX(a, &addr->prefix) || (addr->flags & IA_HOST); }
|
||||||
|
|
||||||
|
|
||||||
/* ospf.c */
|
/* ospf.c */
|
||||||
void ospf_schedule_rtcalc(struct ospf_proto *p);
|
void ospf_schedule_rtcalc(struct ospf_proto *p);
|
||||||
|
|
||||||
|
|
|
@ -403,7 +403,7 @@ ospf_rx_hook(sock *sk, uint len)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
int src_local, dst_local, dst_mcast;
|
int src_local, dst_local, dst_mcast;
|
||||||
src_local = ipa_in_netX(sk->faddr, &ifa->addr->prefix);
|
src_local = ospf_ipa_local(sk->faddr, ifa->addr);
|
||||||
dst_local = ipa_equal(sk->laddr, ifa->addr->ip);
|
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);
|
dst_mcast = ipa_equal(sk->laddr, ifa->all_routers) || ipa_equal(sk->laddr, ifa->des_routers);
|
||||||
|
|
||||||
|
|
|
@ -1827,7 +1827,12 @@ calc_next_hop(struct ospf_area *oa, struct top_hash_entry *en,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_nexthop(p, nh, ifa->iface, ifa->ecmp_weight);
|
struct nexthop *nhs = new_nexthop(p, nh, ifa->iface, ifa->ecmp_weight);
|
||||||
|
|
||||||
|
if (ifa->addr->flags & IA_HOST)
|
||||||
|
nhs->flags = RNF_ONLINK;
|
||||||
|
|
||||||
|
return nhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The third case - bcast or nbma neighbor */
|
/* The third case - bcast or nbma neighbor */
|
||||||
|
@ -2031,8 +2036,9 @@ again1:
|
||||||
for (nh = nf->n.nhs; nh; nh = nh->next)
|
for (nh = nf->n.nhs; nh; nh = nh->next)
|
||||||
if (ipa_nonzero(nh->gw))
|
if (ipa_nonzero(nh->gw))
|
||||||
{
|
{
|
||||||
neighbor *ng = neigh_find(&p->p, nh->gw, nh->iface, 0);
|
neighbor *nbr = neigh_find(&p->p, nh->gw, nh->iface,
|
||||||
if (!ng || (ng->scope == SCOPE_HOST))
|
(nh->flags & RNF_ONLINK) ? NEF_ONLINK : 0);
|
||||||
|
if (!nbr || (nbr->scope == SCOPE_HOST))
|
||||||
{ reset_ri(nf); break; }
|
{ reset_ri(nf); break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue