mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Implements Point-to-MultiPoint interface type for OSPF.
This commit is contained in:
parent
39847cda73
commit
919f5411c4
@ -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>type broadcast</cf> option.
|
||||
|
||||
<cf>interface "eth1", "eth4", "eth5" { type pointopoint; };</cf> - start the protocol
|
||||
on enumerated interfaces with <cf>type pointopoint</cf> option.
|
||||
<cf>interface "eth1", "eth4", "eth5" { type ptp; };</cf> - start the protocol
|
||||
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
|
||||
interfaces that have address from 192.168.0.0/16, but not
|
||||
@ -1549,7 +1549,8 @@ protocol ospf <name> {
|
||||
dead count <num>;
|
||||
dead <num>;
|
||||
rx buffer [normal|large|<num>];
|
||||
type [broadcast|nonbroadcast|pointopoint];
|
||||
type [broadcast|bcast|pointopoint|ptp|
|
||||
nonbroadcast|nbma|pointomultipoint|ptmp];
|
||||
strict nonbroadcast <switch>;
|
||||
check link <switch>;
|
||||
ecmp weight <num>;
|
||||
@ -1688,23 +1689,43 @@ protocol ospf <name> {
|
||||
be bigger than maximal size of any packets. Value NORMAL (default)
|
||||
means 2*MTU, value LARGE means maximal allowed packet - 65535.
|
||||
|
||||
<tag>type broadcast</tag>
|
||||
BIRD detects a type of a connected network automatically, but sometimes it's
|
||||
convenient to force use of a different type manually.
|
||||
On broadcast networks, flooding and Hello messages are sent using multicasts
|
||||
(a single packet for all the neighbors).
|
||||
<tag>type broadcast|bcast</tag>
|
||||
BIRD detects a type of a connected network automatically, but
|
||||
sometimes it's convenient to force use of a different type
|
||||
manually. On broadcast networks (like ethernet), flooding
|
||||
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>
|
||||
Point-to-point networks connect just 2 routers together. No election
|
||||
is performed there which reduces the number of messages sent.
|
||||
<tag>type pointopoint|ptp</tag>
|
||||
Point-to-point networks connect just 2 routers together. No
|
||||
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>
|
||||
On nonbroadcast networks, the packets are sent to each neighbor
|
||||
<tag>type nonbroadcast|nbma</tag>
|
||||
On NBMA networks, the packets are sent to each neighbor
|
||||
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>
|
||||
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>
|
||||
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.
|
||||
|
||||
<tag>neighbors { <m/set/ } </tag>
|
||||
A set of neighbors to which Hello messages on nonbroadcast networks
|
||||
are to be sent. Some of them could be marked as eligible.
|
||||
A set of neighbors to which Hello messages on NBMA or PtMP
|
||||
networks are to be sent. For NBMA networks, some of them
|
||||
could be marked as eligible.
|
||||
|
||||
</descrip>
|
||||
|
||||
|
@ -46,8 +46,9 @@ finish_iface_config(struct ospf_iface_patt *ip)
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
|
||||
CF_KEYWORDS(BROADCAST, NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
||||
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
|
||||
CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
|
||||
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(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
|
||||
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 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 BCAST { OSPF_PATT->type = OSPF_IT_BCAST ; }
|
||||
| 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 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 ; }
|
||||
| STUB bool { OSPF_PATT->stub = $2 ; }
|
||||
| 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 *p = &po->proto;
|
||||
char *beg = "OSPF: Bad HELLO packet from ";
|
||||
unsigned int size, i, twoway, eligible, peers;
|
||||
unsigned int size, i, twoway, peers;
|
||||
u32 tmp;
|
||||
u32 *pnrid;
|
||||
|
||||
@ -103,37 +103,30 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
|
||||
|
||||
if (!n)
|
||||
{
|
||||
if ((ifa->type == OSPF_IT_NBMA))
|
||||
if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_PTMP))
|
||||
{
|
||||
struct nbma_node *nn;
|
||||
int found = 0;
|
||||
struct nbma_node *nn = find_nbma_node(ifa, faddr);
|
||||
|
||||
WALK_LIST(nn, ifa->nbma_list)
|
||||
{
|
||||
if (ipa_equal(faddr, nn->ip))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((found == 0) && (ifa->strictnbma))
|
||||
if (!nn && ifa->strictnbma)
|
||||
{
|
||||
log(L_WARN "Ignoring new neighbor: %I on %s", faddr,
|
||||
ifa->iface->name);
|
||||
return;
|
||||
}
|
||||
if (found)
|
||||
|
||||
if (nn && (ifa->type == OSPF_IT_NBMA) &&
|
||||
(((ps->priority == 0) && nn->eligible) ||
|
||||
((ps->priority > 0) && !nn->eligible)))
|
||||
{
|
||||
eligible = nn->eligible;
|
||||
if (((ps->priority == 0) && eligible)
|
||||
|| ((ps->priority > 0) && (eligible == 0)))
|
||||
{
|
||||
log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
|
||||
faddr, ifa->iface->name);
|
||||
return;
|
||||
}
|
||||
log(L_ERR "Eligibility mismatch for neighbor: %I on %s",
|
||||
faddr, ifa->iface->name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nn)
|
||||
nn->found = 1;
|
||||
}
|
||||
|
||||
OSPF_TRACE(D_EVENTS, "New neighbor found: %I on %s", faddr,
|
||||
ifa->iface->name);
|
||||
|
||||
@ -239,7 +232,7 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
|
||||
struct ospf_neighbor *neigh, *n1;
|
||||
u16 length;
|
||||
u32 *pp;
|
||||
int i, send;
|
||||
int i;
|
||||
struct nbma_node *nb;
|
||||
|
||||
if (timer == NULL)
|
||||
@ -311,53 +304,56 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
|
||||
|
||||
switch(ifa->type)
|
||||
{
|
||||
case OSPF_IT_NBMA:
|
||||
if (timer == NULL) /* Response to received hello */
|
||||
{
|
||||
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;
|
||||
case OSPF_IT_BCAST:
|
||||
case OSPF_IT_PTP:
|
||||
ospf_send_to(ifa, AllSPFRouters);
|
||||
break;
|
||||
|
||||
WALK_LIST(nb, ifa->nbma_list)
|
||||
{
|
||||
send = 1;
|
||||
WALK_LIST(n1, ifa->neigh_list)
|
||||
{
|
||||
if (ipa_equal(nb->ip, n1->ip))
|
||||
{
|
||||
send = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((poll == 1) && (send))
|
||||
{
|
||||
if (toall || (meeli && nb->eligible))
|
||||
ospf_send_to(ifa, nb->ip);
|
||||
}
|
||||
}
|
||||
if (poll == 0)
|
||||
{
|
||||
WALK_LIST(n1, ifa->neigh_list)
|
||||
{
|
||||
if (toall || (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid) ||
|
||||
(meeli && (n1->priority > 0)))
|
||||
ospf_send_to(ifa, n1->ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
case OSPF_IT_NBMA:
|
||||
if (timer == NULL) /* Response to received hello */
|
||||
{
|
||||
ospf_send_to(ifa, dirn->ip);
|
||||
break;
|
||||
case OSPF_IT_VLINK:
|
||||
ospf_send_to(ifa, ifa->vip);
|
||||
break;
|
||||
default:
|
||||
ospf_send_to(ifa, AllSPFRouters);
|
||||
}
|
||||
|
||||
int to_all = ifa->state > OSPF_IS_DROTHER;
|
||||
int me_elig = ifa->priority > 0;
|
||||
|
||||
if (poll) /* Poll timer */
|
||||
{
|
||||
WALK_LIST(nb, ifa->nbma_list)
|
||||
if (!nb->found && (to_all || (me_elig && nb->eligible)))
|
||||
ospf_send_to(ifa, nb->ip);
|
||||
}
|
||||
else /* Hello timer */
|
||||
{
|
||||
WALK_LIST(n1, ifa->neigh_list)
|
||||
if (to_all || (me_elig && (n1->priority > 0)) ||
|
||||
(n1->rid == ifa->drid) || (n1->rid == ifa->bdrid))
|
||||
ospf_send_to(ifa, n1->ip);
|
||||
}
|
||||
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:
|
||||
ospf_send_to(ifa, ifa->vip);
|
||||
break;
|
||||
|
||||
default:
|
||||
bug("Bug in ospf_hello_send()");
|
||||
}
|
||||
|
||||
OSPF_TRACE(D_PACKETS, "HELLO packet sent via %s%s",
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "ospf.h"
|
||||
|
||||
char *ospf_is[] = { "down", "loop", "waiting", "point-to-point", "drother",
|
||||
char *ospf_is[] = { "down", "loop", "waiting", "ptp", "drother",
|
||||
"backup", "dr"
|
||||
};
|
||||
|
||||
@ -16,7 +16,7 @@ char *ospf_ism[] = { "interface up", "wait timer fired", "backup seen",
|
||||
"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
|
||||
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
|
||||
ospf_sk_open(struct ospf_iface *ifa)
|
||||
ospf_sk_open(struct ospf_iface *ifa, int multicast)
|
||||
{
|
||||
sock *sk = sk_new(ifa->pool);
|
||||
sk->type = SK_IP;
|
||||
@ -106,11 +116,16 @@ ospf_sk_open(struct ospf_iface *ifa)
|
||||
*/
|
||||
|
||||
sk->saddr = ifa->addr->ip;
|
||||
if (sk_setup_multicast(sk) < 0)
|
||||
goto err;
|
||||
if (multicast)
|
||||
{
|
||||
if (sk_setup_multicast(sk) < 0)
|
||||
goto err;
|
||||
|
||||
if (sk_join_group(sk, AllSPFRouters) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ifa->sk = sk;
|
||||
ifa->sk_spf = 0;
|
||||
ifa->sk_dr = 0;
|
||||
return 1;
|
||||
|
||||
@ -119,16 +134,6 @@ ospf_sk_open(struct ospf_iface *ifa)
|
||||
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
|
||||
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);
|
||||
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
|
||||
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)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
@ -355,11 +349,11 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
|
||||
|
||||
}
|
||||
|
||||
u8
|
||||
ospf_iface_clasify(struct iface *ifa, struct ifa *addr)
|
||||
static u8
|
||||
ospf_iface_classify(struct iface *ifa, struct ifa *addr)
|
||||
{
|
||||
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_MULTIACCESS | IF_MULTICAST))
|
||||
@ -388,12 +382,8 @@ ospf_iface_add(struct object_lock *lock)
|
||||
struct proto_ospf *po = ifa->oa->po;
|
||||
struct proto *p = &po->proto;
|
||||
|
||||
if (ospf_sk_open(ifa))
|
||||
{
|
||||
if (ifa->type != OSPF_IT_NBMA)
|
||||
ospf_sk_join_spf(ifa);
|
||||
}
|
||||
else
|
||||
int mc = (ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP);
|
||||
if (! ospf_sk_open(ifa, mc))
|
||||
{
|
||||
log(L_ERR "%s: Socket open failed on interface %s, declaring as stub", p->name, ifa->iface->name);
|
||||
ifa->ioprob = OSPF_I_SK;
|
||||
@ -448,7 +438,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
|
||||
#endif
|
||||
|
||||
if (ip->type == OSPF_IT_UNDEF)
|
||||
ifa->type = ospf_iface_clasify(iface, addr);
|
||||
ifa->type = ospf_iface_classify(iface, addr);
|
||||
else
|
||||
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))
|
||||
ifa->stub = 1;
|
||||
|
||||
/* Check validity of interface type */
|
||||
int old_type = ifa->type;
|
||||
|
||||
#ifdef OSPFv2
|
||||
if ((ifa->type != OSPF_IT_PTP) && (ifa->type != OSPF_IT_VLINK) &&
|
||||
(addr->flags & IA_UNNUMBERED))
|
||||
{
|
||||
log(L_WARN "%s: Missing proper IP prefix on interface %s, forcing point-to-point mode",
|
||||
p->name, iface->name);
|
||||
if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_UNNUMBERED))
|
||||
ifa->type = OSPF_IT_PTP;
|
||||
}
|
||||
|
||||
if ((ifa->type == OSPF_IT_NBMA) && (addr->flags & IA_UNNUMBERED))
|
||||
ifa->type = OSPF_IT_PTMP;
|
||||
#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->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->ip = nb->ip;
|
||||
nbma->eligible = nb->eligible;
|
||||
nbma->found = 0;
|
||||
add_tail(&ifa->nbma_list, NODE nbma);
|
||||
}
|
||||
|
||||
@ -766,10 +769,12 @@ ospf_if_notify(struct proto *p, unsigned flags, struct iface *iface)
|
||||
void
|
||||
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)
|
||||
{
|
||||
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_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_ */
|
||||
|
@ -304,6 +304,13 @@ ospf_lsupd_flood(struct proto_ospf *po,
|
||||
|
||||
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:
|
||||
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR))
|
||||
ospf_send_to_agt(ifa, NEIGHBOR_EXCHANGE);
|
||||
@ -311,16 +318,20 @@ ospf_lsupd_flood(struct proto_ospf *po,
|
||||
ospf_send_to_bdr(ifa);
|
||||
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:
|
||||
ospf_send_to(ifa, ifa->vip);
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((ifa->state == OSPF_IS_BACKUP) || (ifa->state == OSPF_IS_DR) ||
|
||||
(ifa->type == OSPF_IT_PTP))
|
||||
ospf_send_to(ifa, AllSPFRouters);
|
||||
else
|
||||
ospf_send_to(ifa, AllDRouters);
|
||||
bug("Bug in ospf_lsupd_flood()");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,6 +276,7 @@ can_do_adj(struct ospf_neighbor *n)
|
||||
switch (ifa->type)
|
||||
{
|
||||
case OSPF_IT_PTP:
|
||||
case OSPF_IT_PTMP:
|
||||
case OSPF_IT_VLINK:
|
||||
i = 1;
|
||||
break;
|
||||
@ -531,9 +532,19 @@ struct ospf_neighbor *
|
||||
find_neigh(struct ospf_iface *ifa, u32 rid)
|
||||
{
|
||||
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)
|
||||
return n;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -543,7 +554,7 @@ ospf_find_area(struct proto_ospf *po, u32 aid)
|
||||
struct ospf_area *oa;
|
||||
WALK_LIST(oa, po->area_list)
|
||||
if (((struct ospf_area *) oa)->areaid == aid)
|
||||
return oa;
|
||||
return oa;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -567,6 +578,13 @@ ospf_neigh_remove(struct ospf_neighbor *n)
|
||||
struct ospf_iface *ifa = n->ifa;
|
||||
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));
|
||||
neigh_chstate(n, NEIGHBOR_DOWN);
|
||||
rem_node(NODE n);
|
||||
@ -596,9 +614,10 @@ ospf_sh_neigh_info(struct ospf_neighbor *n)
|
||||
|
||||
if (n->rid == ifa->drid)
|
||||
pos = "dr ";
|
||||
if (n->rid == ifa->bdrid)
|
||||
else if (n->rid == ifa->bdrid)
|
||||
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 ";
|
||||
|
||||
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 bdr_election(struct ospf_iface *ifa);
|
||||
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);
|
||||
void ospf_neigh_remove(struct ospf_neighbor *n);
|
||||
void ospf_sh_neigh_info(struct ospf_neighbor *n);
|
||||
|
||||
|
||||
#endif /* _BIRD_OSPF_NEIGHBOR_H_ */
|
||||
|
@ -649,7 +649,7 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||
struct ospf_iface *ifa;
|
||||
struct nbma_node *nb1, *nb2, *nbnx;
|
||||
struct ospf_area *oa = NULL;
|
||||
int found, olddead, newdead;
|
||||
int olddead, newdead;
|
||||
|
||||
if (po->rfc1583 != new->rfc1583)
|
||||
return 0;
|
||||
@ -881,19 +881,17 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
|
||||
/* First remove old */
|
||||
WALK_LIST_DELSAFE(nb1, nbnx, ifa->nbma_list)
|
||||
{
|
||||
found = 0;
|
||||
WALK_LIST(nb2, newip->nbma_list)
|
||||
if (ipa_equal(nb1->ip, nb2->ip))
|
||||
nb2 = find_nbma_node_in(&newip->nbma_list, nb1->ip);
|
||||
if (nb2)
|
||||
{
|
||||
found = 1;
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
else
|
||||
{
|
||||
OSPF_TRACE(D_EVENTS,
|
||||
"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))
|
||||
continue;
|
||||
|
||||
found = 0;
|
||||
WALK_LIST(nb1, ifa->nbma_list)
|
||||
if (ipa_equal(nb1->ip, nb2->ip))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
if (find_nbma_node(ifa, nb2->ip) == NULL)
|
||||
{
|
||||
nb1 = mb_alloc(ifa->pool, sizeof(struct nbma_node));
|
||||
nb1->ip = nb2->ip;
|
||||
nb1->eligible = nb2->eligible;
|
||||
nb1->found = !!find_neigh_by_ip(ifa, nb1->ip);
|
||||
add_tail(&ifa->nbma_list, NODE nb1);
|
||||
OSPF_TRACE(D_EVENTS,
|
||||
"Adding NBMA neighbor %I on interface %s",
|
||||
|
@ -90,7 +90,8 @@ struct nbma_node
|
||||
{
|
||||
node n;
|
||||
ip_addr ip;
|
||||
int eligible;
|
||||
byte eligible;
|
||||
byte found;
|
||||
};
|
||||
|
||||
struct area_net_config
|
||||
@ -205,8 +206,9 @@ struct ospf_iface
|
||||
#define OSPF_IT_BCAST 0
|
||||
#define OSPF_IT_NBMA 1
|
||||
#define OSPF_IT_PTP 2
|
||||
#define OSPF_IT_VLINK 3
|
||||
#define OSPF_IT_UNDEF 4
|
||||
#define OSPF_IT_PTMP 3
|
||||
#define OSPF_IT_VLINK 4
|
||||
#define OSPF_IT_UNDEF 5
|
||||
u8 strictnbma; /* Can I talk with unknown neighbors? */
|
||||
u8 stub; /* Inactive interface */
|
||||
u8 state; /* Interface state machine */
|
||||
@ -245,7 +247,7 @@ struct ospf_iface
|
||||
#define OSPF_I_OK 0 /* Everything OK */
|
||||
#define OSPF_I_SK 1 /* Socket open failed */
|
||||
#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 */
|
||||
u16 rxbuf; /* Buffer size */
|
||||
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
|
||||
|
||||
#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
|
||||
@ -433,7 +420,7 @@ ospf_rx_hook(sock *sk, int size)
|
||||
#ifdef OSPFv2
|
||||
/* In OSPFv2, neighbors are identified by either IP or Router ID, base on network type */
|
||||
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);
|
||||
else
|
||||
n = find_neigh(ifa, rid);
|
||||
|
@ -1341,12 +1341,13 @@ static inline int
|
||||
match_rtlink(struct ospf_iface *ifa, struct ospf_lsa_rt_link *rtl)
|
||||
{
|
||||
#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 :
|
||||
ipa_to_u32(ifa->addr->ip)) == rtl->data);
|
||||
#else /* OSPFv3 */
|
||||
return (ifa->type == OSPF_IT_PTP) && (ifa->cost == rtl->metric) &&
|
||||
(ifa->iface->index == rtl->lif);
|
||||
return ((ifa->type == OSPF_IT_PTP) || (ifa->type == OSPF_IT_PTMP)) &&
|
||||
(ifa->cost == rtl->metric) && (ifa->iface->index == rtl->lif);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -241,24 +241,26 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||
if ((ifa->oa != oa) || (ifa->state == OSPF_IS_DOWN))
|
||||
continue;
|
||||
|
||||
/* RFC2328 - 12.4.1.1-4 */
|
||||
switch (ifa->type)
|
||||
{
|
||||
case OSPF_IT_PTP: /* RFC2328 - 12.4.1.1 */
|
||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
||||
{
|
||||
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||
ln->type = LSART_PTP;
|
||||
ln->id = neigh->rid;
|
||||
ln->data = (ifa->addr->flags & IA_UNNUMBERED) ?
|
||||
ifa->iface->index : ipa_to_u32(ifa->addr->ip);
|
||||
ln->metric = ifa->cost;
|
||||
ln->padding = 0;
|
||||
i++;
|
||||
}
|
||||
case OSPF_IT_PTP:
|
||||
case OSPF_IT_PTMP:
|
||||
WALK_LIST(neigh, ifa->neigh_list)
|
||||
if (neigh->state == NEIGHBOR_FULL)
|
||||
{
|
||||
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
|
||||
ln->type = LSART_PTP;
|
||||
ln->id = neigh->rid;
|
||||
ln->data = (ifa->addr->flags & IA_UNNUMBERED) ?
|
||||
ifa->iface->index : ipa_to_u32(ifa->addr->ip);
|
||||
ln->metric = ifa->cost;
|
||||
ln->padding = 0;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF_IT_BCAST: /* RFC2328 - 12.4.1.2 */
|
||||
case OSPF_IT_BCAST:
|
||||
case OSPF_IT_NBMA:
|
||||
if (bcast_net_active(ifa))
|
||||
{
|
||||
@ -273,7 +275,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||
}
|
||||
break;
|
||||
|
||||
case OSPF_IT_VLINK: /* RFC2328 - 12.4.1.3 */
|
||||
case OSPF_IT_VLINK:
|
||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||
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;
|
||||
|
||||
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 */
|
||||
ln->type = LSART_STUB;
|
||||
@ -398,9 +400,10 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||
switch (ifa->type)
|
||||
{
|
||||
case OSPF_IT_PTP:
|
||||
neigh = (struct ospf_neighbor *) HEAD(ifa->neigh_list);
|
||||
if ((!EMPTY_LIST(ifa->neigh_list)) && (neigh->state == NEIGHBOR_FULL))
|
||||
add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
|
||||
case OSPF_IT_PTMP:
|
||||
WALK_LIST(neigh, ifa->neigh_list)
|
||||
if (neigh->state == NEIGHBOR_FULL)
|
||||
add_lsa_rt_link(po, ifa, LSART_PTP, neigh->iface_id, neigh->rid);
|
||||
break;
|
||||
|
||||
case OSPF_IT_BCAST:
|
||||
@ -1202,7 +1205,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||
configured_stubnet(oa, a))
|
||||
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);
|
||||
else
|
||||
lsa_put_prefix(po, a->prefix, a->pxlen, ifa->cost);
|
||||
|
Loading…
Reference in New Issue
Block a user