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>;
<prefix> hidden; <prefix> hidden;
} }
interface <interface pattern> stubnet <prefix>;
{ stubnet <prefix> {
hidden <switch>;
summary <switch>;
cost <num>;
}
interface <interface pattern> {
cost <num>; cost <num>;
stub <switch>; stub <switch>;
hello <num>; hello <num>;
@ -1223,8 +1228,7 @@ protocol ospf <name> {
<ip> eligible; <ip> eligible;
}; };
}; };
virtual link <id> virtual link <id> {
{
hello <num>; hello <num>;
retransmit <num>; retransmit <num>;
wait <num>; wait <num>;
@ -1265,6 +1269,24 @@ protocol ospf <name> {
Definition of area IP ranges. This is used in summary lsa origination. Definition of area IP ranges. This is used in summary lsa origination.
Hidden networks are not propagated into other areas. 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> <tag>interface <M>pattern</M></tag>
Defines that the specified interfaces belong to the area being defined. Defines that the specified interfaces belong to the area being defined.
See <ref id="dsc-iface" name="interface"> common option for detailed description. 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 ospf_area_config *this_area;
static struct nbma_node *this_nbma; static struct nbma_node *this_nbma;
static struct area_net_config *this_pref; static struct area_net_config *this_pref;
static struct ospf_stubnet_config *this_stubnet;
static void static void
finish_iface_config(struct ospf_iface_patt *ip) 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(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE)
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC) CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK) 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 %type <t> opttext
@ -75,6 +76,7 @@ ospf_area_start: AREA idval '{' {
init_list(&this_area->patt_list); init_list(&this_area->patt_list);
init_list(&this_area->vlink_list); init_list(&this_area->vlink_list);
init_list(&this_area->net_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 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;}} | STUB bool {if($2) { if(!this_area->stub) this_area->stub=DEFAULT_STUB_COST;}else{ this_area->stub=0;}}
| NETWORKS '{' pref_list '}' | NETWORKS '{' pref_list '}'
| STUBNET ospf_stubnet
| INTERFACE ospf_iface | INTERFACE ospf_iface
| ospf_vlink | 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:
ospf_vlink_start '{' ospf_vlink_opts '}' { finish_iface_config(OSPF_PATT); } ospf_vlink_start '{' ospf_vlink_opts '}' { finish_iface_config(OSPF_PATT); }
| ospf_vlink_start | ospf_vlink_start

View file

@ -148,6 +148,7 @@ ospf_start(struct proto *p)
oa = mb_allocz(p->pool, sizeof(struct ospf_area)); oa = mb_allocz(p->pool, sizeof(struct ospf_area));
add_tail(&po->area_list, NODE oa); add_tail(&po->area_list, NODE oa);
po->areano++; po->areano++;
oa->ac = ac;
oa->stub = ac->stub; oa->stub = ac->stub;
oa->areaid = ac->areaid; oa->areaid = ac->areaid;
oa->rt = NULL; oa->rt = NULL;
@ -629,9 +630,31 @@ ospf_reconfigure(struct proto *p, struct proto_config *c)
if (!oa) if (!oa)
return 0; return 0;
oa->ac = newac;
oa->stub = newac->stub; oa->stub = newac->stub;
if (newac->stub && (oa->areaid == 0)) oa->stub = 0; 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 */ /* Change net_list */
FIB_WALK(&oa->net_fib, nf) /* First check if some networks are deleted */ FIB_WALK(&oa->net_fib, nf) /* First check if some networks are deleted */
{ {

View file

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

View file

@ -52,6 +52,25 @@ lsab_flush(struct proto_ospf *po)
return r; 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 * static void *
originate_rt_lsa_body(struct ospf_area *oa, u16 * length) 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) || if (((a == ifa->iface->addr) && master) ||
(a->flags & IA_SECONDARY) || (a->flags & IA_SECONDARY) ||
(a->flags & IA_UNNUMBERED)) (a->flags & IA_UNNUMBERED) ||
configured_stubnet(oa, a))
continue; continue;
ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
ln->type = LSART_STUB; ln->type = LSART_STUB;
ln->id = ipa_to_u32(a->prefix); 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 = po->lsab;
rt->links = i; rt->links = i;
rt->veb.bit.v = bitv; rt->veb.bit.v = bitv;