Implements Point-to-MultiPoint interface type for OSPF.
This commit is contained in:
parent
39847cda73
commit
919f5411c4
13 changed files with 253 additions and 204 deletions
|
@ -407,8 +407,8 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
|
||||||
<cf>interface "*" { type broadcast; };</cf> - start the protocol on all interfaces with
|
<cf>interface "*" { type broadcast; };</cf> - start the protocol on all interfaces with
|
||||||
<cf>type broadcast</cf> option.
|
<cf>type broadcast</cf> option.
|
||||||
|
|
||||||
<cf>interface "eth1", "eth4", "eth5" { type pointopoint; };</cf> - start the protocol
|
<cf>interface "eth1", "eth4", "eth5" { type ptp; };</cf> - start the protocol
|
||||||
on enumerated interfaces with <cf>type pointopoint</cf> option.
|
on enumerated interfaces with <cf>type ptp</cf> option.
|
||||||
|
|
||||||
<cf>interface -192.168.1.0/24, 192.168.0.0/16;</cf> - start the protocol on all
|
<cf>interface -192.168.1.0/24, 192.168.0.0/16;</cf> - start the protocol on all
|
||||||
interfaces that have address from 192.168.0.0/16, but not
|
interfaces that have address from 192.168.0.0/16, but not
|
||||||
|
@ -1549,7 +1549,8 @@ protocol ospf <name> {
|
||||||
dead count <num>;
|
dead count <num>;
|
||||||
dead <num>;
|
dead <num>;
|
||||||
rx buffer [normal|large|<num>];
|
rx buffer [normal|large|<num>];
|
||||||
type [broadcast|nonbroadcast|pointopoint];
|
type [broadcast|bcast|pointopoint|ptp|
|
||||||
|
nonbroadcast|nbma|pointomultipoint|ptmp];
|
||||||
strict nonbroadcast <switch>;
|
strict nonbroadcast <switch>;
|
||||||
check link <switch>;
|
check link <switch>;
|
||||||
ecmp weight <num>;
|
ecmp weight <num>;
|
||||||
|
@ -1688,23 +1689,43 @@ protocol ospf <name> {
|
||||||
be bigger than maximal size of any packets. Value NORMAL (default)
|
be bigger than maximal size of any packets. Value NORMAL (default)
|
||||||
means 2*MTU, value LARGE means maximal allowed packet - 65535.
|
means 2*MTU, value LARGE means maximal allowed packet - 65535.
|
||||||
|
|
||||||
<tag>type broadcast</tag>
|
<tag>type broadcast|bcast</tag>
|
||||||
BIRD detects a type of a connected network automatically, but sometimes it's
|
BIRD detects a type of a connected network automatically, but
|
||||||
convenient to force use of a different type manually.
|
sometimes it's convenient to force use of a different type
|
||||||
On broadcast networks, flooding and Hello messages are sent using multicasts
|
manually. On broadcast networks (like ethernet), flooding
|
||||||
(a single packet for all the neighbors).
|
and Hello messages are sent using multicasts (a single packet
|
||||||
|
for all the neighbors). A designated router is elected and it
|
||||||
|
is responsible for synchronizing the link-state databases and
|
||||||
|
originating network LSAs. This network type cannot be used on
|
||||||
|
physically NBMA networks and on unnumbered networks (networks
|
||||||
|
without proper IP prefix).
|
||||||
|
|
||||||
<tag>type pointopoint</tag>
|
<tag>type pointopoint|ptp</tag>
|
||||||
Point-to-point networks connect just 2 routers together. No election
|
Point-to-point networks connect just 2 routers together. No
|
||||||
is performed there which reduces the number of messages sent.
|
election is performed and no network LSA is originated, which
|
||||||
|
makes it simpler and faster to establish. This network type
|
||||||
|
is useful not only for physically PtP ifaces (like PPP or
|
||||||
|
tunnels), but also for broadcast networks used as PtP links.
|
||||||
|
This network type cannot be used on physically NBMA networks.
|
||||||
|
|
||||||
<tag>type nonbroadcast</tag>
|
<tag>type nonbroadcast|nbma</tag>
|
||||||
On nonbroadcast networks, the packets are sent to each neighbor
|
On NBMA networks, the packets are sent to each neighbor
|
||||||
separately because of lack of multicast capabilities.
|
separately because of lack of multicast capabilities.
|
||||||
|
Like on broadcast networks, a designated router is elected,
|
||||||
|
which plays a central role in propagation of LSAs.
|
||||||
|
This network type cannot be used on unnumbered networks.
|
||||||
|
|
||||||
|
<tag>type pointomultipoint|ptmp</tag>
|
||||||
|
This is another network type designed to handle NBMA
|
||||||
|
networks. In this case the NBMA network is treated as a
|
||||||
|
collection of PtP links. This is useful if not every pair of
|
||||||
|
routers on the NBMA network has direct communication, or if
|
||||||
|
the NBMA network is used as an (possibly unnumbered) PtP
|
||||||
|
link.
|
||||||
|
|
||||||
<tag>strict nonbroadcast <M>switch</M></tag>
|
<tag>strict nonbroadcast <M>switch</M></tag>
|
||||||
If set, don't send hello to any undefined neighbor. This switch
|
If set, don't send hello to any undefined neighbor. This switch
|
||||||
is ignored on any non-NBMA network. Default value is no.
|
is ignored on other than NBMA or PtMP networks. Default value is no.
|
||||||
|
|
||||||
<tag>check link <M>switch</M></tag>
|
<tag>check link <M>switch</M></tag>
|
||||||
If set, a hardware link state (reported by OS) is taken into
|
If set, a hardware link state (reported by OS) is taken into
|
||||||
|
@ -1738,8 +1759,9 @@ protocol ospf <name> {
|
||||||
See <ref id="dsc-pass" name="password"> common option for detailed description.
|
See <ref id="dsc-pass" name="password"> common option for detailed description.
|
||||||
|
|
||||||
<tag>neighbors { <m/set/ } </tag>
|
<tag>neighbors { <m/set/ } </tag>
|
||||||
A set of neighbors to which Hello messages on nonbroadcast networks
|
A set of neighbors to which Hello messages on NBMA or PtMP
|
||||||
are to be sent. Some of them could be marked as eligible.
|
networks are to be sent. For NBMA networks, some of them
|
||||||
|
could be marked as eligible.
|
||||||
|
|
||||||
</descrip>
|
</descrip>
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,9 @@ finish_iface_config(struct ospf_iface_patt *ip)
|
||||||
CF_DECLS
|
CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
|
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
|
||||||
CF_KEYWORDS(BROADCAST, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
||||||
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
|
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST)
|
||||||
|
CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
|
||||||
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
||||||
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
|
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
|
||||||
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
|
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
|
||||||
|
@ -190,8 +191,13 @@ ospf_iface_item:
|
||||||
| DEAD expr { OSPF_PATT->dead = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
|
| DEAD expr { OSPF_PATT->dead = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
|
||||||
| DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
|
| DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
|
||||||
| TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
|
| TYPE BROADCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
|
||||||
|
| TYPE BCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
|
||||||
| TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
|
| TYPE NONBROADCAST { OSPF_PATT->type = OSPF_IT_NBMA ; }
|
||||||
|
| TYPE NBMA { OSPF_PATT->type = OSPF_IT_NBMA ; }
|
||||||
| TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
|
| TYPE POINTOPOINT { OSPF_PATT->type = OSPF_IT_PTP ; }
|
||||||
|
| TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
|
||||||
|
| TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
|
||||||
|
| TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
|
||||||
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
|
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
|
||||||
| STUB bool { OSPF_PATT->stub = $2 ; }
|
| STUB bool { OSPF_PATT->stub = $2 ; }
|
||||||
| CHECK LINK bool { OSPF_PATT->check_link = $3; }
|
| CHECK LINK bool { OSPF_PATT->check_link = $3; }
|
||||||
|
|
|
@ -48,7 +48,7 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
|
||||||
struct proto_ospf *po = ifa->oa->po;
|
struct proto_ospf *po = ifa->oa->po;
|
||||||
struct proto *p = &po->proto;
|
struct proto *p = &po->proto;
|
||||||
char *beg = "OSPF: Bad HELLO packet from ";
|
char *beg = "OSPF: Bad HELLO packet from ";
|
||||||
unsigned int size, i, twoway, eligible, peers;
|
unsigned int size, i, twoway, peers;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
u32 *pnrid;
|
u32 *pnrid;
|
||||||
|
|
||||||
|
@ -103,37 +103,30 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
{
|
{
|
||||||
if ((ifa->type == OSPF_IT_NBMA))
|
if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
|
||||||
{
|
{
|
||||||
struct nbma_node *nn;
|
struct nbma_node *nn = find_nbma_node(ifa, faddr);
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
WALK_LIST(nn, ifa->nbma_list)
|
if (!nn && ifa->strictnbma)
|
||||||
{
|
|
||||||
if (ipa_equal(faddr, nn->ip))
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((found == 0) && (ifa->strictnbma))
|
|
||||||
{
|
{
|
||||||
log(L_WARN "Ignoring new neighbor: %I on %s", faddr,
|
log(L_WARN "Ignoring new neighbor: %I on %s", faddr,
|
||||||
ifa->iface->name);
|
ifa->iface->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (found)
|
|
||||||
{
|
if (nn && (ifa->type == OSPF_IT_NBMA) &&
|
||||||
eligible = nn->eligible;
|
(((ps->priority == 0) && nn->eligible) ||
|
||||||
if (((ps->priority == 0) && eligible)
|
((ps->priority > 0) && !nn->eligible)))
|
||||||
|| ((ps->priority > 0) && (eligible == 0)))
|
|
||||||
{
|
{
|
||||||
log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
|
log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
|
||||||
faddr, ifa->iface->name);
|
faddr, ifa->iface->name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nn)
|
||||||
|
nn->found = 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr,
|
OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr,
|
||||||
ifa->iface->name);
|
ifa->iface->name);
|
||||||
|
|
||||||
|
@ -239,7 +232,7 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
|
||||||
struct ospf_neighbor *neigh, *n1;
|
struct ospf_neighbor *neigh, *n1;
|
||||||
u16 length;
|
u16 length;
|
||||||
u32 *pp;
|
u32 *pp;
|
||||||
int i, send;
|
int i;
|
||||||
struct nbma_node *nb;
|
struct nbma_node *nb;
|
||||||
|
|
||||||
if (timer == NULL)
|
if (timer == NULL)
|
||||||
|
@ -311,53 +304,56 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
|
||||||
|
|
||||||
switch(ifa->type)
|
switch(ifa->type)
|
||||||
{
|
{
|
||||||
|
case OSPF_IT_BCAST:
|
||||||
|
case OSPF_IT_PTP:
|
||||||
|
ospf_send_to(ifa, AllSPFRouters);
|
||||||
|
break;
|
||||||
|
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
if (timer == NULL) /* Response to received hello */
|
if (timer == NULL) /* Response to received hello */
|
||||||
{
|
{
|
||||||
ospf_send_to(ifa, dirn->ip);
|
ospf_send_to(ifa, dirn->ip);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int toall = 0;
|
|
||||||
int meeli = 0;
|
|
||||||
if (ifa->state > OSPF_IS_DROTHER)
|
|
||||||
toall = 1;
|
|
||||||
if (ifa->priority > 0)
|
|
||||||
meeli = 1;
|
|
||||||
|
|
||||||
WALK_LIST(nb, ifa->nbma_list)
|
|
||||||
{
|
|
||||||
send = 1;
|
|
||||||
WALK_LIST(n1, ifa->neigh_list)
|
|
||||||
{
|
|
||||||
if (ipa_equal(nb->ip, n1->ip))
|
|
||||||
{
|
|
||||||
send = 0;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ((poll == 1) && (send))
|
int to_all = ifa->state > OSPF_IS_DROTHER;
|
||||||
|
int me_elig = ifa->priority > 0;
|
||||||
|
|
||||||
|
if (poll) /* Poll timer */
|
||||||
{
|
{
|
||||||
if (toall || (meeli && nb->eligible))
|
WALK_LIST(nb, ifa->nbma_list)
|
||||||
|
if (!nb->found && (to_all || (me_elig && nb->eligible)))
|
||||||
ospf_send_to(ifa, nb->ip);
|
ospf_send_to(ifa, nb->ip);
|
||||||
}
|
}
|
||||||
}
|
else /* Hello timer */
|
||||||
if (poll == 0)
|
|
||||||
{
|
{
|
||||||
WALK_LIST(n1, ifa->neigh_list)
|
WALK_LIST(n1, ifa->neigh_list)
|
||||||
{
|
if (to_all || (me_elig && (n1->priority > 0)) ||
|
||||||
if (toall || (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid) ||
|
(n1->rid == ifa->drid) || (n1->rid == ifa->bdrid))
|
||||||
(meeli && (n1->priority > 0)))
|
|
||||||
ospf_send_to(ifa, n1->ip);
|
ospf_send_to(ifa, n1->ip);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OSPF_IT_PTMP:
|
||||||
|
WALK_LIST(n1, ifa->neigh_list)
|
||||||
|
ospf_send_to(ifa, n1->ip);
|
||||||
|
|
||||||
|
WALK_LIST(nb, ifa->nbma_list)
|
||||||
|
if (!nb->found)
|
||||||
|
ospf_send_to(ifa, nb->ip);
|
||||||
|
|
||||||
|
/* If there is no other target, we also send HELLO packet to the other end */
|
||||||
|
if (ipa_nonzero(ifa->addr->opposite) && !ifa->strictnbma &&
|
||||||
|
EMPTY_LIST(ifa->neigh_list) && EMPTY_LIST(ifa->nbma_list))
|
||||||
|
ospf_send_to(ifa, ifa->addr->opposite);
|
||||||
|
break;
|
||||||
|
|
||||||
case OSPF_IT_VLINK:
|
case OSPF_IT_VLINK:
|
||||||
ospf_send_to(ifa, ifa->vip);
|
ospf_send_to(ifa, ifa->vip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ospf_send_to(ifa, AllSPFRouters);
|
bug("Bug in ospf_hello_send()");
|
||||||
}
|
}
|
||||||
|
|
||||||
OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s",
|
OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#include "ospf.h"
|
#include "ospf.h"
|
||||||
|
|
||||||
char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother",
|
char *ospf_is[] = { "down", "loop", "waiting", "ptp", "drother",
|
||||||
"backup", "dr"
|
"backup", "dr"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen",
|
||||||
"neighbor change", "loop indicated", "unloop indicated", "interface down"
|
"neighbor change", "loop indicated", "unloop indicated", "interface down"
|
||||||
};
|
};
|
||||||
|
|
||||||
char *ospf_it[] = { "broadcast", "nbma", "point-to-point", "virtual link" };
|
char *ospf_it[] = { "broadcast", "nbma", "ptp", "ptmp", "virtual link" };
|
||||||
|
|
||||||
static void
|
static void
|
||||||
poll_timer_hook(timer * timer)
|
poll_timer_hook(timer * timer)
|
||||||
|
@ -57,8 +57,18 @@ rxbufsize(struct ospf_iface *ifa)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct nbma_node *
|
||||||
|
find_nbma_node_in(list *nnl, ip_addr ip)
|
||||||
|
{
|
||||||
|
struct nbma_node *nn;
|
||||||
|
WALK_LIST(nn, *nnl)
|
||||||
|
if (ipa_equal(nn->ip, ip))
|
||||||
|
return nn;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ospf_sk_open(struct ospf_iface *ifa)
|
ospf_sk_open(struct ospf_iface *ifa, int multicast)
|
||||||
{
|
{
|
||||||
sock *sk = sk_new(ifa->pool);
|
sock *sk = sk_new(ifa->pool);
|
||||||
sk->type = SK_IP;
|
sk->type = SK_IP;
|
||||||
|
@ -106,11 +116,16 @@ ospf_sk_open(struct ospf_iface *ifa)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sk->saddr = ifa->addr->ip;
|
sk->saddr = ifa->addr->ip;
|
||||||
|
if (multicast)
|
||||||
|
{
|
||||||
if (sk_setup_multicast(sk) < 0)
|
if (sk_setup_multicast(sk) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
if (sk_join_group(sk, AllSPFRouters) < 0)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
ifa->sk = sk;
|
ifa->sk = sk;
|
||||||
ifa->sk_spf = 0;
|
|
||||||
ifa->sk_dr = 0;
|
ifa->sk_dr = 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -119,16 +134,6 @@ ospf_sk_open(struct ospf_iface *ifa)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
ospf_sk_join_spf(struct ospf_iface *ifa)
|
|
||||||
{
|
|
||||||
if (ifa->sk_spf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sk_join_group(ifa->sk, AllSPFRouters);
|
|
||||||
ifa->sk_spf = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ospf_sk_join_dr(struct ospf_iface *ifa)
|
ospf_sk_join_dr(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
|
@ -138,17 +143,6 @@ ospf_sk_join_dr(struct ospf_iface *ifa)
|
||||||
sk_join_group(ifa->sk, AllDRouters);
|
sk_join_group(ifa->sk, AllDRouters);
|
||||||
ifa->sk_dr = 1;
|
ifa->sk_dr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
ospf_sk_leave_spf(struct ospf_iface *ifa)
|
|
||||||
{
|
|
||||||
if (!ifa->sk_spf)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sk_leave_group(ifa->sk, AllSPFRouters);
|
|
||||||
ifa->sk_spf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
ospf_sk_leave_dr(struct ospf_iface *ifa)
|
ospf_sk_leave_dr(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
|
@ -291,7 +285,7 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
|
||||||
if (ifa->state <= OSPF_IS_LOOP)
|
if (ifa->state <= OSPF_IS_LOOP)
|
||||||
{
|
{
|
||||||
/* Now, nothing should be adjacent */
|
/* Now, nothing should be adjacent */
|
||||||
if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_VLINK))
|
if ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP) || (ifa->type == OSPF_IT_VLINK))
|
||||||
{
|
{
|
||||||
ospf_iface_chstate(ifa, OSPF_IS_PTP);
|
ospf_iface_chstate(ifa, OSPF_IS_PTP);
|
||||||
}
|
}
|
||||||
|
@ -355,11 +349,11 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8
|
static u8
|
||||||
ospf_iface_clasify(struct iface *ifa, struct ifa *addr)
|
ospf_iface_classify(struct iface *ifa, struct ifa *addr)
|
||||||
{
|
{
|
||||||
if (ipa_nonzero(addr->opposite))
|
if (ipa_nonzero(addr->opposite))
|
||||||
return OSPF_IT_PTP;
|
return (ifa->flags & IF_MULTICAST) ? OSPF_IT_PTP : OSPF_IT_PTMP;
|
||||||
|
|
||||||
if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
|
if ((ifa->flags & (IF_MULTIACCESS | IF_MULTICAST)) ==
|
||||||
(IF_MULTIACCESS | IF_MULTICAST))
|
(IF_MULTIACCESS | IF_MULTICAST))
|
||||||
|
@ -388,12 +382,8 @@ ospf_iface_add(struct object_lock *lock)
|
||||||
struct proto_ospf *po = ifa->oa->po;
|
struct proto_ospf *po = ifa->oa->po;
|
||||||
struct proto *p = &po->proto;
|
struct proto *p = &po->proto;
|
||||||
|
|
||||||
if (ospf_sk_open(ifa))
|
int mc = (ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP);
|
||||||
{
|
if (! ospf_sk_open(ifa, mc))
|
||||||
if (ifa->type != OSPF_IT_NBMA)
|
|
||||||
ospf_sk_join_spf(ifa);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
log(L_ERR "%s: Socket open failed on interface %s, declaring as stub", p->name, ifa->iface->name);
|
log(L_ERR "%s: Socket open failed on interface %s, declaring as stub", p->name, ifa->iface->name);
|
||||||
ifa->ioprob = OSPF_I_SK;
|
ifa->ioprob = OSPF_I_SK;
|
||||||
|
@ -448,7 +438,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ip->type == OSPF_IT_UNDEF)
|
if (ip->type == OSPF_IT_UNDEF)
|
||||||
ifa->type = ospf_iface_clasify(iface, addr);
|
ifa->type = ospf_iface_classify(iface, addr);
|
||||||
else
|
else
|
||||||
ifa->type = ip->type;
|
ifa->type = ip->type;
|
||||||
|
|
||||||
|
@ -456,16 +446,28 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
|
||||||
if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite))
|
if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite))
|
||||||
ifa->stub = 1;
|
ifa->stub = 1;
|
||||||
|
|
||||||
|
/* Check validity of interface type */
|
||||||
|
int old_type = ifa->type;
|
||||||
|
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
if ((ifa->type != OSPF_IT_PTP) && (ifa->type != OSPF_IT_VLINK) &&
|
if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_UNNUMBERED))
|
||||||
(addr->flags & IA_UNNUMBERED))
|
|
||||||
{
|
|
||||||
log(L_WARN "%s: Missing proper IP prefix on interface %s, forcing point-to-point mode",
|
|
||||||
p->name, iface->name);
|
|
||||||
ifa->type = OSPF_IT_PTP;
|
ifa->type = OSPF_IT_PTP;
|
||||||
}
|
|
||||||
|
if ((ifa->type == OSPF_IT_NBMA) && (addr->flags & IA_UNNUMBERED))
|
||||||
|
ifa->type = OSPF_IT_PTMP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((ifa->type == OSPF_IT_BCAST) && !(iface->flags & IF_MULTICAST))
|
||||||
|
ifa->type = OSPF_IT_NBMA;
|
||||||
|
|
||||||
|
if ((ifa->type == OSPF_IT_PTP) && !(iface->flags & IF_MULTICAST))
|
||||||
|
ifa->type = OSPF_IT_PTMP;
|
||||||
|
|
||||||
|
if (ifa->type != old_type)
|
||||||
|
log(L_WARN "%s: Cannot use interface %s as %s, forcing %s",
|
||||||
|
p->name, iface->name, ospf_it[old_type], ospf_it[ifa->type]);
|
||||||
|
|
||||||
|
|
||||||
init_list(&ifa->neigh_list);
|
init_list(&ifa->neigh_list);
|
||||||
init_list(&ifa->nbma_list);
|
init_list(&ifa->nbma_list);
|
||||||
|
|
||||||
|
@ -477,6 +479,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
|
||||||
nbma = mb_alloc(pool, sizeof(struct nbma_node));
|
nbma = mb_alloc(pool, sizeof(struct nbma_node));
|
||||||
nbma->ip = nb->ip;
|
nbma->ip = nb->ip;
|
||||||
nbma->eligible = nb->eligible;
|
nbma->eligible = nb->eligible;
|
||||||
|
nbma->found = 0;
|
||||||
add_tail(&ifa->nbma_list, NODE nbma);
|
add_tail(&ifa->nbma_list, NODE nbma);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,10 +769,12 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||||
void
|
void
|
||||||
ospf_iface_info(struct ospf_iface *ifa)
|
ospf_iface_info(struct ospf_iface *ifa)
|
||||||
{
|
{
|
||||||
char *strict = "(strict)";
|
char *strict = "";
|
||||||
|
|
||||||
|
if (ifa->strictnbma &&
|
||||||
|
((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP)))
|
||||||
|
strict = "(strict)";
|
||||||
|
|
||||||
if ((ifa->type != OSPF_IT_NBMA) || (ifa->strictnbma == 0))
|
|
||||||
strict = "";
|
|
||||||
if (ifa->type == OSPF_IT_VLINK)
|
if (ifa->type == OSPF_IT_VLINK)
|
||||||
{
|
{
|
||||||
cli_msg(-1015, "Virtual link to %R:", ifa->vid);
|
cli_msg(-1015, "Virtual link to %R:", ifa->vid);
|
||||||
|
|
|
@ -21,6 +21,11 @@ void ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr
|
||||||
void ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa);
|
void ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa);
|
||||||
void ospf_set_rxbuf_size(struct ospf_iface *ifa, u32 rxbuf);
|
void ospf_set_rxbuf_size(struct ospf_iface *ifa, u32 rxbuf);
|
||||||
|
|
||||||
|
struct nbma_node *find_nbma_node_in(list *nnl, ip_addr ip);
|
||||||
|
|
||||||
|
static inline struct nbma_node *
|
||||||
|
find_nbma_node(struct ospf_iface *ifa, ip_addr ip)
|
||||||
|
{ return find_nbma_node_in(&ifa->nbma_list, ip); }
|
||||||
|
|
||||||
|
|
||||||
#endif /* _BIRD_OSPF_IFACE_H_ */
|
#endif /* _BIRD_OSPF_IFACE_H_ */
|
||||||
|
|
|
@ -304,6 +304,13 @@ ospf_lsupd_flood(struct proto_ospf *po,
|
||||||
|
|
||||||
switch (ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
|
case OSPF_IT_BCAST:
|
||||||
|
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
|
||||||
|
ospf_send_to(ifa, AllSPFRouters);
|
||||||
|
else
|
||||||
|
ospf_send_to(ifa, AllDRouters);
|
||||||
|
break;
|
||||||
|
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
|
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
|
||||||
ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
|
ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
|
||||||
|
@ -311,16 +318,20 @@ ospf_lsupd_flood(struct proto_ospf *po,
|
||||||
ospf_send_to_bdr(ifa);
|
ospf_send_to_bdr(ifa);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OSPF_IT_PTP:
|
||||||
|
ospf_send_to(ifa, AllSPFRouters);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OSPF_IT_PTMP:
|
||||||
|
ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
|
||||||
|
break;
|
||||||
|
|
||||||
case OSPF_IT_VLINK:
|
case OSPF_IT_VLINK:
|
||||||
ospf_send_to(ifa, ifa->vip);
|
ospf_send_to(ifa, ifa->vip);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR) ||
|
bug("Bug in ospf_lsupd_flood()");
|
||||||
(ifa->type == OSPF_IT_PTP))
|
|
||||||
ospf_send_to(ifa, AllSPFRouters);
|
|
||||||
else
|
|
||||||
ospf_send_to(ifa, AllDRouters);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,6 +276,7 @@ can_do_adj(struct ospf_neighbor *n)
|
||||||
switch (ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP:
|
case OSPF_IT_PTP:
|
||||||
|
case OSPF_IT_PTMP:
|
||||||
case OSPF_IT_VLINK:
|
case OSPF_IT_VLINK:
|
||||||
i = 1;
|
i = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -531,8 +532,18 @@ struct ospf_neighbor *
|
||||||
find_neigh(struct ospf_iface *ifa, u32 rid)
|
find_neigh(struct ospf_iface *ifa, u32 rid)
|
||||||
{
|
{
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
|
if (n->rid == rid)
|
||||||
|
return n;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
WALK_LIST(n, ifa->neigh_list) if (n->rid == rid)
|
struct ospf_neighbor *
|
||||||
|
find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip)
|
||||||
|
{
|
||||||
|
struct ospf_neighbor *n;
|
||||||
|
WALK_LIST(n, ifa->neigh_list)
|
||||||
|
if (ipa_equal(n->ip, ip))
|
||||||
return n;
|
return n;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -567,6 +578,13 @@ ospf_neigh_remove(struct ospf_neighbor *n)
|
||||||
struct ospf_iface *ifa = n->ifa;
|
struct ospf_iface *ifa = n->ifa;
|
||||||
struct proto *p = &ifa->oa->po->proto;
|
struct proto *p = &ifa->oa->po->proto;
|
||||||
|
|
||||||
|
if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
|
||||||
|
{
|
||||||
|
struct nbma_node *nn = find_nbma_node(ifa, n->ip);
|
||||||
|
if (nn)
|
||||||
|
nn->found = 0;
|
||||||
|
}
|
||||||
|
|
||||||
s_get(&(n->dbsi));
|
s_get(&(n->dbsi));
|
||||||
neigh_chstate(n, NEIGHBOR_DOWN);
|
neigh_chstate(n, NEIGHBOR_DOWN);
|
||||||
rem_node(NODE n);
|
rem_node(NODE n);
|
||||||
|
@ -596,9 +614,10 @@ ospf_sh_neigh_info(struct ospf_neighbor *n)
|
||||||
|
|
||||||
if (n->rid == ifa->drid)
|
if (n->rid == ifa->drid)
|
||||||
pos = "dr ";
|
pos = "dr ";
|
||||||
if (n->rid == ifa->bdrid)
|
else if (n->rid == ifa->bdrid)
|
||||||
pos = "bdr ";
|
pos = "bdr ";
|
||||||
if ((n->ifa->type == OSPF_IT_PTP) || (n->ifa->type == OSPF_IT_VLINK))
|
else if ((n->ifa->type == OSPF_IT_PTP) || (n->ifa->type == OSPF_IT_PTMP) ||
|
||||||
|
(n->ifa->type == OSPF_IT_VLINK))
|
||||||
pos = "ptp ";
|
pos = "ptp ";
|
||||||
|
|
||||||
cli_msg(-1013, "%-1R\t%3u\t%s/%s\t%-5s\t%-10s %-1I", n->rid, n->priority,
|
cli_msg(-1013, "%-1R\t%3u\t%s/%s\t%-5s\t%-10s %-1I", n->rid, n->priority,
|
||||||
|
|
|
@ -14,9 +14,9 @@ struct ospf_neighbor *ospf_neighbor_new(struct ospf_iface *ifa);
|
||||||
void ospf_neigh_sm(struct ospf_neighbor *n, int event);
|
void ospf_neigh_sm(struct ospf_neighbor *n, int event);
|
||||||
void bdr_election(struct ospf_iface *ifa);
|
void bdr_election(struct ospf_iface *ifa);
|
||||||
struct ospf_neighbor *find_neigh(struct ospf_iface *ifa, u32 rid);
|
struct ospf_neighbor *find_neigh(struct ospf_iface *ifa, u32 rid);
|
||||||
|
struct ospf_neighbor *find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip);
|
||||||
struct ospf_area *ospf_find_area(struct proto_ospf *po, u32 aid);
|
struct ospf_area *ospf_find_area(struct proto_ospf *po, u32 aid);
|
||||||
void ospf_neigh_remove(struct ospf_neighbor *n);
|
void ospf_neigh_remove(struct ospf_neighbor *n);
|
||||||
void ospf_sh_neigh_info(struct ospf_neighbor *n);
|
void ospf_sh_neigh_info(struct ospf_neighbor *n);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _BIRD_OSPF_NEIGHBOR_H_ */
|
#endif /* _BIRD_OSPF_NEIGHBOR_H_ */
|
||||||
|
|
|
@ -649,7 +649,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
struct ospf_iface *ifa;
|
struct ospf_iface *ifa;
|
||||||
struct nbma_node *nb1, *nb2, *nbnx;
|
struct nbma_node *nb1, *nb2, *nbnx;
|
||||||
struct ospf_area *oa = NULL;
|
struct ospf_area *oa = NULL;
|
||||||
int found, olddead, newdead;
|
int olddead, newdead;
|
||||||
|
|
||||||
if (po->rfc1583 != new->rfc1583)
|
if (po->rfc1583 != new->rfc1583)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -881,19 +881,17 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
/* First remove old */
|
/* First remove old */
|
||||||
WALK_LIST_DELSAFE(nb1, nbnx, ifa->nbma_list)
|
WALK_LIST_DELSAFE(nb1, nbnx, ifa->nbma_list)
|
||||||
{
|
{
|
||||||
found = 0;
|
nb2 = find_nbma_node_in(&newip->nbma_list, nb1->ip);
|
||||||
WALK_LIST(nb2, newip->nbma_list)
|
if (nb2)
|
||||||
if (ipa_equal(nb1->ip, nb2->ip))
|
|
||||||
{
|
{
|
||||||
found = 1;
|
|
||||||
if (nb1->eligible != nb2->eligible)
|
if (nb1->eligible != nb2->eligible)
|
||||||
OSPF_TRACE(D_EVENTS,
|
{
|
||||||
"Changing neighbor eligibility %I on interface %s",
|
nb1->eligible = nb2->eligible;
|
||||||
|
OSPF_TRACE(D_EVENTS, "Changing neighbor eligibility %I on interface %s",
|
||||||
nb1->ip, ifa->iface->name);
|
nb1->ip, ifa->iface->name);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!found)
|
else
|
||||||
{
|
{
|
||||||
OSPF_TRACE(D_EVENTS,
|
OSPF_TRACE(D_EVENTS,
|
||||||
"Removing NBMA neighbor %I on interface %s",
|
"Removing NBMA neighbor %I on interface %s",
|
||||||
|
@ -908,18 +906,12 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||||
if (!ipa_in_net(nb2->ip, ifa->addr->prefix, ifa->addr->pxlen))
|
if (!ipa_in_net(nb2->ip, ifa->addr->prefix, ifa->addr->pxlen))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
found = 0;
|
if (find_nbma_node(ifa, nb2->ip) == NULL)
|
||||||
WALK_LIST(nb1, ifa->nbma_list)
|
|
||||||
if (ipa_equal(nb1->ip, nb2->ip))
|
|
||||||
{
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
{
|
||||||
nb1 = mb_alloc(ifa->pool, sizeof(struct nbma_node));
|
nb1 = mb_alloc(ifa->pool, sizeof(struct nbma_node));
|
||||||
nb1->ip = nb2->ip;
|
nb1->ip = nb2->ip;
|
||||||
nb1->eligible = nb2->eligible;
|
nb1->eligible = nb2->eligible;
|
||||||
|
nb1->found = !!find_neigh_by_ip(ifa, nb1->ip);
|
||||||
add_tail(&ifa->nbma_list, NODE nb1);
|
add_tail(&ifa->nbma_list, NODE nb1);
|
||||||
OSPF_TRACE(D_EVENTS,
|
OSPF_TRACE(D_EVENTS,
|
||||||
"Adding NBMA neighbor %I on interface %s",
|
"Adding NBMA neighbor %I on interface %s",
|
||||||
|
|
|
@ -90,7 +90,8 @@ struct nbma_node
|
||||||
{
|
{
|
||||||
node n;
|
node n;
|
||||||
ip_addr ip;
|
ip_addr ip;
|
||||||
int eligible;
|
byte eligible;
|
||||||
|
byte found;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct area_net_config
|
struct area_net_config
|
||||||
|
@ -205,8 +206,9 @@ struct ospf_iface
|
||||||
#define OSPF_IT_BCAST 0
|
#define OSPF_IT_BCAST 0
|
||||||
#define OSPF_IT_NBMA 1
|
#define OSPF_IT_NBMA 1
|
||||||
#define OSPF_IT_PTP 2
|
#define OSPF_IT_PTP 2
|
||||||
#define OSPF_IT_VLINK 3
|
#define OSPF_IT_PTMP 3
|
||||||
#define OSPF_IT_UNDEF 4
|
#define OSPF_IT_VLINK 4
|
||||||
|
#define OSPF_IT_UNDEF 5
|
||||||
u8 strictnbma; /* Can I talk with unknown neighbors? */
|
u8 strictnbma; /* Can I talk with unknown neighbors? */
|
||||||
u8 stub; /* Inactive interface */
|
u8 stub; /* Inactive interface */
|
||||||
u8 state; /* Interface state machine */
|
u8 state; /* Interface state machine */
|
||||||
|
@ -245,7 +247,7 @@ struct ospf_iface
|
||||||
#define OSPF_I_OK 0 /* Everything OK */
|
#define OSPF_I_OK 0 /* Everything OK */
|
||||||
#define OSPF_I_SK 1 /* Socket open failed */
|
#define OSPF_I_SK 1 /* Socket open failed */
|
||||||
#define OSPF_I_LL 2 /* Missing link-local address (OSPFv3) */
|
#define OSPF_I_LL 2 /* Missing link-local address (OSPFv3) */
|
||||||
u8 sk_spf; /* Socket is a member of SPFRouters group */
|
// u8 sk_spf; /* Socket is a member of SPFRouters group */
|
||||||
u8 sk_dr; /* Socket is a member of DRouters group */
|
u8 sk_dr; /* Socket is a member of DRouters group */
|
||||||
u16 rxbuf; /* Buffer size */
|
u16 rxbuf; /* Buffer size */
|
||||||
u8 check_link; /* Whether iface link change is used */
|
u8 check_link; /* Whether iface link change is used */
|
||||||
|
|
|
@ -240,19 +240,6 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OSPFv2
|
|
||||||
static inline struct ospf_neighbor *
|
|
||||||
find_neigh_by_ip(struct ospf_iface *ifa, ip_addr ip)
|
|
||||||
{
|
|
||||||
struct ospf_neighbor *n;
|
|
||||||
WALK_LIST(n, ifa->neigh_list)
|
|
||||||
if (ipa_equal(n->ip, ip))
|
|
||||||
return n;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ospf_rx_hook
|
* ospf_rx_hook
|
||||||
|
@ -433,7 +420,7 @@ ospf_rx_hook(sock *sk, int size)
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
/* In OSPFv2, neighbors are identified by either IP or Router ID, base on network type */
|
/* In OSPFv2, neighbors are identified by either IP or Router ID, base on network type */
|
||||||
struct ospf_neighbor *n;
|
struct ospf_neighbor *n;
|
||||||
if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA))
|
if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
|
||||||
n = find_neigh_by_ip(ifa, sk->faddr);
|
n = find_neigh_by_ip(ifa, sk->faddr);
|
||||||
else
|
else
|
||||||
n = find_neigh(ifa, rid);
|
n = find_neigh(ifa, rid);
|
||||||
|
|
|
@ -1341,12 +1341,13 @@ static inline int
|
||||||
match_rtlink(struct ospf_iface *ifa, struct ospf_lsa_rt_link *rtl)
|
match_rtlink(struct ospf_iface *ifa, struct ospf_lsa_rt_link *rtl)
|
||||||
{
|
{
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
return (ifa->type == OSPF_IT_PTP) && (ifa->cost == rtl->metric) &&
|
return ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP)) &&
|
||||||
|
(ifa->cost == rtl->metric) &&
|
||||||
(((ifa->addr->flags & IA_UNNUMBERED) ? ifa->iface->index :
|
(((ifa->addr->flags & IA_UNNUMBERED) ? ifa->iface->index :
|
||||||
ipa_to_u32(ifa->addr->ip)) == rtl->data);
|
ipa_to_u32(ifa->addr->ip)) == rtl->data);
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
return (ifa->type == OSPF_IT_PTP) && (ifa->cost == rtl->metric) &&
|
return ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP)) &&
|
||||||
(ifa->iface->index == rtl->lif);
|
(ifa->cost == rtl->metric) && (ifa->iface->index == rtl->lif);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,11 +241,13 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* RFC2328 - 12.4.1.1-4 */
|
||||||
switch (ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP: /* RFC2328 - 12.4.1.1 */
|
case OSPF_IT_PTP:
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
case OSPF_IT_PTMP:
|
||||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
WALK_LIST(neigh, ifa->neigh_list)
|
||||||
|
if (neigh->state == NEIGHBOR_FULL)
|
||||||
{
|
{
|
||||||
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
ln->type = LSART_PTP;
|
ln->type = LSART_PTP;
|
||||||
|
@ -258,7 +260,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OSPF_IT_BCAST: /* RFC2328 - 12.4.1.2 */
|
case OSPF_IT_BCAST:
|
||||||
case OSPF_IT_NBMA:
|
case OSPF_IT_NBMA:
|
||||||
if (bcast_net_active(ifa))
|
if (bcast_net_active(ifa))
|
||||||
{
|
{
|
||||||
|
@ -273,7 +275,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OSPF_IT_VLINK: /* RFC2328 - 12.4.1.3 */
|
case OSPF_IT_VLINK:
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL) && (ifa->cost <= 0xffff))
|
||||||
{
|
{
|
||||||
|
@ -300,7 +302,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||||
if (ifa->state == OSPF_IS_LOOP)
|
if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP))
|
||||||
{
|
{
|
||||||
/* Host stub entry */
|
/* Host stub entry */
|
||||||
ln->type = LSART_STUB;
|
ln->type = LSART_STUB;
|
||||||
|
@ -398,8 +400,9 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
switch (ifa->type)
|
switch (ifa->type)
|
||||||
{
|
{
|
||||||
case OSPF_IT_PTP:
|
case OSPF_IT_PTP:
|
||||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
case OSPF_IT_PTMP:
|
||||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
WALK_LIST(neigh, ifa->neigh_list)
|
||||||
|
if (neigh->state == NEIGHBOR_FULL)
|
||||||
add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
|
add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1202,7 +1205,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
configured_stubnet(oa, a))
|
configured_stubnet(oa, a))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ifa->state == OSPF_IS_LOOP)
|
if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP))
|
||||||
lsa_put_prefix(po, a->ip, MAX_PREFIX_LENGTH, 0);
|
lsa_put_prefix(po, a->ip, MAX_PREFIX_LENGTH, 0);
|
||||||
else
|
else
|
||||||
lsa_put_prefix(po, a->prefix, a->pxlen, ifa->cost);
|
lsa_put_prefix(po, a->prefix, a->pxlen, ifa->cost);
|
||||||
|
|
Loading…
Reference in a new issue