diff options
-rw-r--r-- | proto/ospf/config.Y | 35 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 65 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 9 |
3 files changed, 94 insertions, 15 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 140cbb44..9431f24c 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -17,14 +17,15 @@ static struct ospf_area_config *this_area; static struct iface_patt *this_ipatt; #define OSPF_PATT ((struct ospf_iface_patt *) this_ipatt) static struct nbma_node *this_nbma; +static struct area_net *this_pref; CF_DECLS CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG) CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, RETRANSMIT) CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, NONBROADCAST, POINTOPOINT, TYPE) -CF_KEYWORDS(NEIGHBORS, NONE, SIMPLE, AUTHENTICATION, PASSWORD, STRICT) -CF_KEYWORDS(ELIGIBLE, POLL) +CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, PASSWORD, STRICT) +CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN) %type <t> opttext @@ -58,6 +59,7 @@ ospf_area_start: AREA idval '{' { this_area->tick = DISPTICK; this_area->stub = 0; init_list(&this_area->patt_list); + init_list(&this_area->net_list); } ; @@ -72,6 +74,7 @@ ospf_area_opts: ospf_area_item: STUB COST expr { this_area->stub = $3 ; if($3<=0) cf_error("Stub cost must be greater than zero"); } | TICK expr { this_area->tick = $2 ; if($2<=0) cf_error("Tick must be greater than zero"); } + | NETWORKS '{' pref_list '}' | INTERFACE ospf_iface_list ; @@ -96,6 +99,34 @@ ospf_iface_item: | ; +pref_list: + /* empty */ + | pref_list pref_item + ; + +pref_item: + pref_el; + | pref_hid; + +pref_el: prefix ';' + { + this_pref = cfg_allocz(sizeof(struct area_net)); + add_tail(&this_area->net_list, NODE this_pref); + this_pref->net = $1.addr; + this_pref->mlen = $1.len; + } +; + +pref_hid: prefix HIDDEN ';' + { + this_pref = cfg_allocz(sizeof(struct area_net)); + add_tail(&this_area->net_list, NODE this_pref); + this_pref->net = $1.addr; + this_pref->mlen = $1.len; + this_pref->hidden = 1; + } +; + ipa_list: /* empty */ | ipa_list ipa_item diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index 8447e698..23e668d8 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -77,6 +77,7 @@ ospf_start(struct proto *p) struct ospf_config *c=(struct ospf_config *)(p->cf); struct ospf_area_config *ac; struct ospf_area *oa; + struct area_net *anet,*antmp; fib_init(&po->efib,p->pool,sizeof(struct extfib),16,init_efib); init_list(&(po->iface_list)); @@ -91,7 +92,7 @@ ospf_start(struct proto *p) WALK_LIST(ac,c->area_list) { oa=mb_allocz(po->proto.pool, sizeof(struct ospf_area)); - add_tail(&po->area_list,NODE oa); + add_tail(&po->area_list, NODE oa); po->areano++; oa->stub=ac->stub; oa->tick=ac->tick; @@ -108,6 +109,15 @@ ospf_start(struct proto *p) tm_start(oa->disp_timer,oa->tick); oa->calcrt=0; oa->origrt=0; + init_list(&oa->net_list); + WALK_LIST(anet,ac->net_list) + { + antmp=mb_allocz(po->proto.pool, sizeof(struct area_net)); + antmp->net=anet->net; + antmp->mlen=anet->mlen; + antmp->hidden=anet->hidden; + add_tail(&oa->net_list, NODE antmp); + } fib_init(&oa->infib,po->proto.pool,sizeof(struct infib),16,init_infib); } return PS_UP; @@ -485,7 +495,8 @@ ospf_reconfigure(struct proto *p, struct proto_config *c) struct ospf_iface_patt *ip1,*ip2; struct ospf_iface *ifa; struct nbma_node *nb1,*nb2,*nbnx; - struct ospf_area *oa; + struct ospf_area *oa=NULL; + struct area_net *anet,*antmp; int found; po->rfc1583=new->rfc1583; @@ -502,23 +513,41 @@ ospf_reconfigure(struct proto *p, struct proto_config *c) while(((NODE (ac1))->next!=NULL) && ((NODE (ac2))->next!=NULL)) { if(ac1->areaid!=ac2->areaid) return 0; - if(ac1->stub!=ac2->stub) return 0; + if(ac1->stub!=ac2->stub) return 0; /* FIXME: non zero values can change */ + + WALK_LIST(oa,po->area_list) + if(oa->areaid==ac2->areaid) break; + + if(!oa) return 0; + if(ac1->tick!=ac2->tick) { - WALK_LIST(oa,po->area_list) + if(oa->areaid==ac2->areaid) { - if(oa->areaid==ac2->areaid) - { - oa->tick=ac2->tick; - tm_start(oa->disp_timer,oa->tick); - OSPF_TRACE(D_EVENTS, - "Changing tick interval on area %I from %d to %d", - oa->areaid, ac1->tick, ac2->tick); - break; - } + oa->tick=ac2->tick; + tm_start(oa->disp_timer,oa->tick); + OSPF_TRACE(D_EVENTS, + "Changing tick interval on area %I from %d to %d", + oa->areaid, ac1->tick, ac2->tick); + break; } } + /* Change net_list */ + WALK_LIST_DELSAFE(anet, antmp, oa->net_list) + { + rem_node(NODE anet); + mb_free(anet); + } + WALK_LIST(anet, ac2->net_list) + { + antmp=mb_alloc(p->pool, sizeof(struct area_net)); + antmp->net=anet->net; + antmp->mlen=anet->mlen; + antmp->hidden=anet->hidden; + add_tail(&oa->net_list, NODE antmp); + } + if(!iface_patts_equal(&ac1->patt_list, &ac2->patt_list, (void *) ospf_patt_compare)) return 0; @@ -801,6 +830,16 @@ ospf_sh(struct proto *p) cli_msg(-1014,"\t\tNumber of LSAs in DB:\t%u", oa->gr->hash_entries); cli_msg(-1014,"\t\tNumber of neighbors:\t%u", nno); cli_msg(-1014,"\t\tNumber of adjacent neighbors:\t%u", adjno); + if(!EMPTY_LIST(oa->net_list)) + { + struct area_net *anet; + cli_msg(-1014,"\t\tArea networks:"); + WALK_LIST(anet, oa->net_list) + { + cli_msg(-1014,"\t\t\t%18I/%u\t%s", anet->net, anet->mlen, + anet->hidden ? "Hidden" : "Advertise"); + } + } } cli_msg(0,""); } diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 11283a7e..d04638b1 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -65,12 +65,20 @@ struct nbma_node { int eligible; }; +struct area_net { + node n; + ip_addr net; + int mlen; + int hidden; +}; + struct ospf_area_config { node n; u32 areaid; int stub; unsigned tick; list patt_list; + list net_list; }; struct ospf_iface { @@ -379,6 +387,7 @@ struct ospf_area { slist lsal; /* List of all LSA's */ struct top_hash_entry *rt; /* My own router LSA */ list cand; /* List of candidates for RT calc. */ + list net_list; /* Networks to advertise or not */ int stub; int trcap; /* Transit capability? */ struct proto_ospf *po; |