Implements an option that allows to change a set of stub networks.

This commit is contained in:
Ondrej Zajicek 2009-06-11 17:25:38 +02:00
parent 3d15dcdb1c
commit 3867520281
5 changed files with 123 additions and 6 deletions

View file

@ -1195,8 +1195,13 @@ protocol ospf <name> {
<prefix>;
<prefix> hidden;
}
interface <interface pattern>
{
stubnet <prefix>;
stubnet <prefix> {
hidden <switch>;
summary <switch>;
cost <num>;
}
interface <interface pattern> {
cost <num>;
stub <switch>;
hello <num>;
@ -1223,8 +1228,7 @@ protocol ospf <name> {
<ip> eligible;
};
};
virtual link <id>
{
virtual link <id> {
hello <num>;
retransmit <num>;
wait <num>;
@ -1265,6 +1269,24 @@ protocol ospf <name> {
Definition of area IP ranges. This is used in summary lsa origination.
Hidden networks are not propagated into other areas.
<tag>stubnet <m/prefix/ { <m/options/ }</tag>
Stub networks are networks that are not transit networks
between OSPF routers. They are also propagated through an
OSPF area as a part of a link state database. By default,
BIRD generates a stub network record for each primary network
address on each OSPF interface that does not have any OSPF
neighbors, and also for each non-primary network address on
each OSPF interface. This option allows to alter a set of
stub networks propagated by this router.
Each instance of this option adds a stub network with given
network prefix to the set of propagated stub network, unless
option <cf/hidden/ is used. It also suppresses default stub
networks for given network prefix. When option
<cf/summary/ is used, also default stub networks that are
subnetworks of given stub network are suppressed. This might
be used, for example, to aggregate generated stub networks.
<tag>interface <M>pattern</M></tag>
Defines that the specified interfaces belong to the area being defined.
See <ref id="dsc-iface" name="interface"> common option for detailed description.

View file

@ -18,6 +18,7 @@ CF_DEFINES
static struct ospf_area_config *this_area;
static struct nbma_node *this_nbma;
static struct area_net_config *this_pref;
static struct ospf_stubnet_config *this_stubnet;
static void
finish_iface_config(struct ospf_iface_patt *ip)
@ -38,7 +39,7 @@ CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT)
CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
%type <t> opttext
@ -75,6 +76,7 @@ ospf_area_start: AREA idval '{' {
init_list(&this_area->patt_list);
init_list(&this_area->vlink_list);
init_list(&this_area->net_list);
init_list(&this_area->stubnet_list);
}
;
@ -90,10 +92,36 @@ ospf_area_item:
STUB COST expr { this_area->stub = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); }
| STUB bool {if($2) { if(!this_area->stub) this_area->stub=DEFAULT_STUB_COST;}else{ this_area->stub=0;}}
| NETWORKS '{' pref_list '}'
| STUBNET ospf_stubnet
| INTERFACE ospf_iface
| ospf_vlink
;
ospf_stubnet:
ospf_stubnet_start '{' ospf_stubnet_opts '}'
| ospf_stubnet_start
;
ospf_stubnet_start:
prefix {
this_stubnet = cfg_allocz(sizeof(struct stubnet_config));
add_tail(&this_area->stubnet_list, NODE this_stubnet);
this_stubnet->px = $1;
this_stubnet->cost = COST_D;
}
;
ospf_stubnet_opts:
/* empty */
| ospf_stubnet_opts ospf_stubnet_item ';'
;
ospf_stubnet_item:
HIDDEN bool { this_stubnet->hidden = $2; }
| SUMMARY bool { this_stubnet->summary = $2; }
| COST expr { this_stubnet->cost = $2; }
;
ospf_vlink:
ospf_vlink_start '{' ospf_vlink_opts '}' { finish_iface_config(OSPF_PATT); }
| ospf_vlink_start

View file

@ -148,6 +148,7 @@ ospf_start(struct proto *p)
oa = mb_allocz(p->pool, sizeof(struct ospf_area));
add_tail(&po->area_list, NODE oa);
po->areano++;
oa->ac = ac;
oa->stub = ac->stub;
oa->areaid = ac->areaid;
oa->rt = NULL;
@ -629,9 +630,31 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
if (!oa)
return 0;
oa->ac = newac;
oa->stub = newac->stub;
if (newac->stub && (oa->areaid == 0)) oa->stub = 0;
/* Check stubnet_list */
struct ospf_stubnet_config *oldsn = HEAD(oldac->stubnet_list);
struct ospf_stubnet_config *newsn = HEAD(newac->stubnet_list);
while (((NODE(oldsn))->next != NULL) && ((NODE(newsn))->next != NULL))
{
if (!ipa_equal(oldsn->px.addr, newsn->px.addr) ||
(oldsn->px.len != newsn->px.len) ||
(oldsn->hidden != newsn->hidden) ||
(oldsn->summary != newsn->summary) ||
(oldsn->cost != newsn->cost))
break;
oldsn = (struct ospf_stubnet_config *)(NODE(oldsn))->next;
newsn = (struct ospf_stubnet_config *)(NODE(newsn))->next;
}
/* If there is no change, both pointers should be NULL */
if (((NODE(oldsn))->next) != ((NODE(newsn))->next))
schedule_rt_lsa(oa);
/* Change net_list */
FIB_WALK(&oa->net_fib, nf) /* First check if some networks are deleted */
{

View file

@ -99,6 +99,14 @@ struct area_net
u32 metric;
};
struct ospf_stubnet_config
{
node n;
struct prefix px;
int hidden, summary;
u32 cost;
};
struct ospf_area_config
{
node n;
@ -107,6 +115,7 @@ struct ospf_area_config
list patt_list;
list vlink_list;
list net_list;
list stubnet_list;
};
struct obits
@ -523,6 +532,7 @@ struct ospf_area
{
node n;
u32 areaid;
struct ospf_area_config *ac; /* Related area config */
int origrt; /* Rt lsa origination scheduled? */
struct top_hash_entry *rt; /* My own router LSA */
list cand; /* List of candidates for RT calc. */

View file

@ -52,6 +52,25 @@ lsab_flush(struct proto_ospf *po)
return r;
}
static int
configured_stubnet(struct ospf_area *oa, struct ifa *a)
{
struct ospf_stubnet_config *sn;
WALK_LIST(sn, oa->ac->stubnet_list)
{
if (sn->summary)
{
if (ipa_in_net(a->prefix, sn->px.addr, sn->px.len) && (a->pxlen >= sn->px.len))
return 1;
}
else
{
if (ipa_equal(a->prefix, sn->px.addr) && (a->pxlen == sn->px.len))
return 1;
}
}
return 0;
}
static void *
originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
@ -163,9 +182,11 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
{
if (((a == ifa->iface->addr) && master) ||
(a->flags & IA_SECONDARY) ||
(a->flags & IA_UNNUMBERED))
(a->flags & IA_UNNUMBERED) ||
configured_stubnet(oa, a))
continue;
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
ln->type = LSART_STUB;
ln->id = ipa_to_u32(a->prefix);
@ -176,6 +197,19 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 * length)
}
}
struct ospf_stubnet_config *sn;
WALK_LIST(sn, oa->ac->stubnet_list)
if (!sn->hidden)
{
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
ln->type = LSART_STUB;
ln->id = ipa_to_u32(sn->px.addr);
ln->data = ipa_to_u32(ipa_mkmask(sn->px.len));
ln->metric = sn->cost;
ln->notos = 0;
i++;
}
rt = po->lsab;
rt->links = i;
rt->veb.bit.v = bitv;