Commit 98ac6176 authored by Ondřej Filip's avatar Ondřej Filip

A lot of changes:

	- metric is 3 byte long now
	- summary lsa originating
	- more OSPF areas possible
	- virtual links
	- better E1/E2 routes handling
	- some bug fixes..

I have to do:
	- md5 auth (last mandatory item from rfc2328)
	- !!!!DEBUG!!!!! (mainly virtual link system has probably a lot of bugs)
	- 2328 appendig E
parent 5ed68e46
......@@ -51,7 +51,5 @@ OSPF
- automatic generation of external route tags (RFC1403)
- RFC1587 NSSA areas
- RFC2370 opaque LSA's
- respect interface MTU and try not to create larger packets unless unavoidable
- AS external LSAs are in topology database of every OSPF Area
- Limit export rate of external LSAs (like Gated does)
- Maximal distance is just 0xffff, but 2328 requires 0xffffff
......@@ -1034,6 +1034,16 @@ protocol ospf <name> {
<ip> eligible;
};
};
virtual link <id>
{
hello <num>;
poll <num>;
retransmit <num>;
wait <num>;
dead count <num>;
authentication [none|simple];
password "<text>";
};
};
}
</code>
......@@ -1068,6 +1078,10 @@ protocol ospf &lt;name&gt; {
<tag>interface <M>pattern</M></tag>
Defines that the specified interfaces belong to the area being defined.
<tag>virtual link <M>id</M></tag>
Virtual link to router with the router id. This item cannot be in the
backbone area (ID 0).
<tag>cost <M>num</M></tag>
Specifies output cost (metric) of an interface. Default value is 10.
......@@ -1163,7 +1177,7 @@ protocol ospf MyOSPF {
ospf_metric1 = 100;
accept;
}
reject;
reject;
};
area 0.0.0.0 {
tick 8;
......@@ -1185,6 +1199,10 @@ protocol ospf MyOSPF {
};
area 120 {
stub yes;
networks {
172.16.1.0/24;
172.16.2.0/24 hidden;
}
interface "-arc0" , "arc*" {
type nonbroadcast;
authentication none;
......
......@@ -25,7 +25,7 @@ CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFA
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREIMPORT)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_EXT, OSPF_IA, BGP, PIPE)
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
CF_ENUM(T_ENUM_SCOPE, SCOPE_, HOST, LINK, SITE, ORGANIZATION, UNIVERSE)
CF_ENUM(T_ENUM_RTC, RTC_, UNICAST, BROADCAST, MULTICAST, ANYCAST)
CF_ENUM(T_ENUM_RTD, RTD_, ROUTER, DEVICE, BLACKHOLE, UNREACHABLE, PROHIBIT)
......
......@@ -253,9 +253,10 @@ typedef struct rta {
#define RTS_RIP 6 /* RIP route */
#define RTS_OSPF 7 /* OSPF route */
#define RTS_OSPF_IA 8 /* OSPF inter-area route */
#define RTS_OSPF_EXT 9 /* OSPF external route */
#define RTS_BGP 10 /* BGP route */
#define RTS_PIPE 11 /* Inter-table wormhole */
#define RTS_OSPF_EXT1 9 /* OSPF external route type 1 */
#define RTS_OSPF_EXT2 10 /* OSPF external route type 2 */
#define RTS_BGP 11 /* BGP route */
#define RTS_PIPE 12 /* Inter-table wormhole */
#define RTC_UNICAST 0
#define RTC_BROADCAST 1
......
......@@ -705,7 +705,8 @@ rta_dump(rta *a)
{
static char *rts[] = { "RTS_DUMMY", "RTS_STATIC", "RTS_INHERIT", "RTS_DEVICE",
"RTS_STAT_DEV", "RTS_REDIR", "RTS_RIP",
"RTS_OSPF", "RTS_OSPF_EXT", "RTS_OSPF_IA", "RTS_BGP" };
"RTS_OSPF", "RTS_OSPF_IA", "RTS_OSPF_EXT1",
"RTS_OSPF_EXT2", "RTS_BGP" };
static char *rtc[] = { "", " BC", " MC", " AC" };
static char *rtd[] = { "", " DEV", " HOLE", " UNREACH", " PROHIBIT" };
......
......@@ -560,7 +560,7 @@ bgp_create_attrs(struct bgp_proto *p, rte *e, ea_list **attrs, struct linpool *p
ea->count = 4;
bgp_set_attr(ea->attrs, pool, BA_ORIGIN,
(rta->source == RTS_OSPF_EXT) ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
((rta->source == RTS_OSPF_EXT1) || (rta->source == RTS_OSPF_EXT2)) ? ORIGIN_INCOMPLETE : ORIGIN_IGP);
if (p->is_internal)
bgp_set_attr(ea->attrs+1, pool, BA_AS_PATH, 0);
......
......@@ -17,7 +17,7 @@ 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;
static struct area_net_config *this_pref;
CF_DECLS
......@@ -25,7 +25,7 @@ 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(NONE, SIMPLE, AUTHENTICATION, PASSWORD, STRICT)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, LINK)
%type <t> opttext
......@@ -78,8 +78,46 @@ ospf_area_item:
| TICK expr { this_area->tick = $2 ; if($2<=0) cf_error("Tick must be greater than zero"); }
| NETWORKS '{' pref_list '}'
| INTERFACE ospf_iface_list
| ospf_vlink '}'
;
ospf_vlink: ospf_vlink_start ospf_vlink_opts
;
ospf_vlink_opts:
/* empty */
| ospf_vlink_opts ospf_vlink_item ';'
;
ospf_vlink_item:
HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
| POLL expr { OSPF_PATT->pollint = $2 ; if ($2<=0) cf_error("Poll int must be greater than zero"); }
| RETRANSMIT expr { OSPF_PATT->rxmtint = $2 ; if ($2<=0) cf_error("Retransmit int must be greater than zero"); }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| WAIT expr { OSPF_PATT->waitint = $2 ; }
| DEAD COUNT expr { OSPF_PATT->deadc = $3 ; if ($3<=1) cf_error("Dead count must be greater than one"); }
| AUTHENTICATION NONE { OSPF_PATT->autype = AU_NONE ; }
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = AU_SIMPLE ; }
| PASSWORD TEXT { memcpy(OSPF_PATT->password, $2, 8); }
;
ospf_vlink_start: VIRTUAL LINK '{'
{
if (this_area->areaid == 0) cf_error("Virtual link cannot be in backbone");
this_ipatt = cfg_allocz(sizeof(struct ospf_iface_patt));
add_tail(&this_area->patt_list, NODE this_ipatt);
OSPF_PATT->cost = COST_D;
OSPF_PATT->helloint = HELLOINT_D;
OSPF_PATT->pollint = POLLINT_D;
OSPF_PATT->rxmtint = RXMTINT_D;
OSPF_PATT->inftransdelay = INFTRANSDELAY_D;
OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
OSPF_PATT->deadc = DEADC_D;
OSPF_PATT->type = OSPF_IT_VLINK;
OSPF_PATT->autype = AU_NONE;
}
;
ospf_iface_item:
COST expr { OSPF_PATT->cost = $2 ; if (($2<=0) || ($2>65535)) cf_error("Cost must be in range 1-65535"); }
| HELLO expr { OSPF_PATT->helloint = $2 ; if (($2<=0) || ($2>65535)) cf_error("Hello interval must be in range 1-65535"); }
......@@ -95,8 +133,8 @@ ospf_iface_item:
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
| STUB bool { OSPF_PATT->stub = $2 ; }
| NEIGHBORS '{' ipa_list '}'
| AUTHENTICATION NONE { OSPF_PATT->autype=AU_NONE ; }
| AUTHENTICATION SIMPLE { OSPF_PATT->autype=AU_SIMPLE ; }
| AUTHENTICATION NONE { OSPF_PATT->autype = AU_NONE ; }
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = AU_SIMPLE ; }
| PASSWORD TEXT { memcpy(OSPF_PATT->password, $2, 8); }
;
......@@ -111,7 +149,7 @@ pref_item:
pref_el: prefix ';'
{
this_pref = cfg_allocz(sizeof(struct area_net));
this_pref = cfg_allocz(sizeof(struct area_net_config));
add_tail(&this_area->net_list, NODE this_pref);
this_pref->px.addr = $1.addr;
this_pref->px.len = $1.len;
......@@ -120,7 +158,7 @@ pref_el: prefix ';'
pref_hid: prefix HIDDEN ';'
{
this_pref = cfg_allocz(sizeof(struct area_net));
this_pref = cfg_allocz(sizeof(struct area_net_config));
add_tail(&this_area->net_list, NODE this_pref);
this_pref->px.addr = $1.addr;
this_pref->px.len = $1.len;
......@@ -172,7 +210,7 @@ ospf_iface_start:
OSPF_PATT->strictnbma = 0;
OSPF_PATT->stub = 0;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype=AU_NONE;
OSPF_PATT->autype = AU_NONE;
}
;
......
......@@ -39,14 +39,14 @@ ospf_dbdes_send(struct ospf_neighbor *n)
pkt = (struct ospf_dbdes_packet *) (ifa->ip_sk->tbuf);
op = (struct ospf_packet *) pkt;
fill_ospf_pkt_hdr(ifa, pkt, DBDES_P);
pkt->iface_mtu = htons(ifa->iface->mtu); /* FIXME NOT for VLINK! */
pkt->iface_mtu = htons(ifa->iface->mtu);
pkt->options = ifa->options;
pkt->imms = n->myimms;
pkt->ddseq = htonl(n->dds);
length = sizeof(struct ospf_dbdes_packet);
op->length = htons(length);
ospf_pkt_finalize(ifa, op);
sk_send_to(ifa->ip_sk, length, n->ip, OSPF_PROTO);
ospf_send_to(ifa->ip_sk, length, n->ip);
OSPF_TRACE(D_PACKETS, "DB_DES (I) sent to %I via %s.", n->ip,
ifa->iface->name);
break;
......@@ -79,20 +79,26 @@ ospf_dbdes_send(struct ospf_neighbor *n)
for (; i > 0; i--)
{
struct top_hash_entry *en;
en = (struct top_hash_entry *) sn;
htonlsah(&(en->lsa), lsa);
DBG("Working on: %d\n", i);
DBG("\tX%01x %-1I %-1I %p\n", en->lsa.type, en->lsa.id,
en->lsa.rt, en->lsa_body);
if ((n->ifa->type != OSPF_IT_VLINK) && (en->lsa.type != LSA_T_EXT))
{
htonlsah(&(en->lsa), lsa);
DBG("Working on: %d\n", i);
DBG("\tX%01x %-1I %-1I %p\n", en->lsa.type, en->lsa.id,
en->lsa.rt, en->lsa_body);
lsa++;
}
else i++; /* No lsa added */
if (sn == STAIL(n->ifa->oa->lsal))
{
i--;
break; /* Should set some flag? */
}
{
i--;
break;
}
sn = sn->next;
lsa++;
}
if (sn == STAIL(n->ifa->oa->lsal))
......@@ -130,7 +136,7 @@ ospf_dbdes_send(struct ospf_neighbor *n)
memcpy(ifa->ip_sk->tbuf, n->ldbdes, length);
/* Copy last sent packet again */
sk_send_to(ifa->ip_sk, length, n->ip, OSPF_PROTO);
ospf_send_to(ifa->ip_sk, length, n->ip);
if(n->myimms.bit.ms) tm_start(n->rxmt_timer, n->ifa->rxmtint); /* Restart timer */
......@@ -245,8 +251,6 @@ ospf_dbdes_receive(struct ospf_dbdes_packet *ps,
ps->imms.byte);
break;
}
if(ps->imms.bit.i) log("FUCK");
case NEIGHBOR_EXCHANGE:
if ((ps->imms.byte == n->imms.byte) && (ps->options == n->options) &&
(ntohl(ps->ddseq) == n->ddr))
......
......@@ -166,16 +166,20 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
struct ospf_hello_packet *pkt;
struct ospf_packet *op;
struct proto *p;
struct ospf_neighbor *neigh;
struct ospf_neighbor *neigh, *n1;
u16 length;
u32 *pp;
int i;
int i, send;
struct nbma_node *nb;
if (timer == NULL)
ifa = dirn->ifa;
else
ifa = (struct ospf_iface *) timer->data;
if (ifa->state == OSPF_IS_DOWN)
return;
if (ifa->stub)
return; /* Don't send any packet on stub iface */
......@@ -184,13 +188,13 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
p->name, ifa->iface->name);
/* Now we should send a hello packet */
/* First a common packet header */
if (ifa->type != OSPF_IT_NBMA)
if ((ifa->type == OSPF_IT_NBMA) || (ifa->type == OSPF_IT_VLINK))
{
pkt = (struct ospf_hello_packet *) (ifa->hello_sk->tbuf);
pkt = (struct ospf_hello_packet *) (ifa->ip_sk->tbuf);
}
else
{
pkt = (struct ospf_hello_packet *) (ifa->ip_sk->tbuf);
pkt = (struct ospf_hello_packet *) (ifa->hello_sk->tbuf);
}
/* Now fill ospf_hello header */
......@@ -224,56 +228,55 @@ ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn)
ospf_pkt_finalize(ifa, op);
/* And finally send it :-) */
if (ifa->type != OSPF_IT_NBMA)
{
sk_send(ifa->hello_sk, length);
}
else /* NBMA */
switch(ifa->type)
{
struct ospf_neighbor *n1;
struct nbma_node *nb;
int send;
if (timer == NULL) /* Response to received hello */
{
sk_send_to(ifa->ip_sk, length, dirn->ip, OSPF_PROTO);
}
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)
case OSPF_IT_NBMA:
if (timer == NULL) /* Response to received hello */
{
send = 1;
WALK_LIST(n1, ifa->neigh_list)
{
if (ipa_compare(nb->ip, n1->ip) == 0)
{
send = 0;
break;
}
}
if ((poll == 1) && (send))
{
if (toall || (meeli && nb->eligible))
sk_send_to(ifa->ip_sk, length, nb->ip, OSPF_PROTO);
}
ospf_send_to(ifa->ip_sk, length, dirn->ip);
}
if (poll == 0)
else
{
WALK_LIST(n1, ifa->neigh_list)
{
if (toall || (n1->rid == ifa->drid) || (n1->rid == ifa->bdrid) ||
(meeli && (n1->priority > 0)))
sk_send_to(ifa->ip_sk, length, n1->ip, OSPF_PROTO);
}
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_compare(nb->ip, n1->ip) == 0)
{
send = 0;
break;
}
}
if ((poll == 1) && (send))
{
if (toall || (meeli && nb->eligible))
ospf_send_to(ifa->ip_sk, length, 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->ip_sk, length, n1->ip);
}
}
}
}
break;
case OSPF_IT_VLINK:
ospf_send_to(ifa->ip_sk, length, ifa->vip);
break;
default:
sk_send(ifa->hello_sk, length);
}
OSPF_TRACE(D_PACKETS, "Hello sent via %s", ifa->iface->name);
}
......@@ -117,24 +117,34 @@ ospf_iface_down(struct ospf_iface *ifa)
{
struct ospf_neighbor *n, *nx;
struct proto *p = &ifa->proto->proto;
struct proto_ospf *po = ifa->proto;
struct ospf_iface *iff;
WALK_LIST_DELSAFE(n, nx, ifa->neigh_list)
{
OSPF_TRACE(D_EVENTS, "Removing neighbor %I", n->ip);
ospf_neigh_remove(n);
}
rem_node(NODE ifa);
rfree(ifa->hello_sk);
rfree(ifa->dr_sk);
rfree(ifa->ip_sk);
rfree(ifa->wait_timer);
rfree(ifa->hello_timer);
rfree(ifa->poll_timer);
rfree(ifa->lock);
mb_free(ifa);
if(ifa->type == OSPF_IT_VLINK)
{
ifa->ip_sk = NULL;
ifa->iface = NULL;
return;
}
else
{
rfree(ifa->wait_timer);
rfree(ifa->hello_timer);
rfree(ifa->poll_timer);
rfree(ifa->lock);
rem_node(NODE ifa);
mb_free(ifa);
}
/* FIXME: Should I down related VLINK also? */
}
/**
......@@ -142,7 +152,7 @@ ospf_iface_down(struct ospf_iface *ifa)
* @ifa: OSPF interface
* @event: event comming to state machine
*
* This fully respect 9.3 of RFC 2328 except we don't use %LOOP state of
* This fully respects 9.3 of RFC 2328 except we don't use %LOOP state of
* interface.
*/
void
......@@ -260,6 +270,7 @@ ospf_open_ip_socket(struct ospf_iface *ifa)
ipsk->saddr = ifa->iface->addr->ip;
ipsk->tos = IP_PREC_INTERNET_CONTROL;
ipsk->ttl = 1;
if (ifa->type == OSPF_IT_VLINK) ipsk->ttl = 255;
ipsk->rx_hook = ospf_rx_hook;
ipsk->tx_hook = ospf_tx_hook;
ipsk->err_hook = ospf_err_hook;
......@@ -307,6 +318,8 @@ ospf_iface_add(struct object_lock *lock)
struct iface *iface = lock->iface;
struct proto *p = &po->proto;
ifa->lock = lock;
ifa->ioprob = OSPF_I_OK;
if (ifa->type != OSPF_IT_NBMA)
......@@ -330,12 +343,113 @@ ospf_iface_add(struct object_lock *lock)
ifa->stub = 1;
ifa->ioprob += OSPF_I_IP;
}
ifa->lock = lock;
ifa->state = OSPF_IS_DOWN;
ospf_iface_sm(ifa, ISM_UP);
}
void
ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ospf_area_config *ac, struct ospf_iface_patt *ip)
{
struct proto *p = &po->proto;
struct ospf_iface *ifa;
struct nbma_node *nbma, *nb;
struct object_lock *lock;
struct ospf_area *oa;
ifa = mb_allocz(p->pool, sizeof(struct ospf_iface));
ifa->proto = po;
ifa->iface = iface;
ifa->an = ac->areaid;
ifa->cost = ip->cost;
ifa->rxmtint = ip->rxmtint;
ifa->inftransdelay = ip->inftransdelay;
ifa->priority = ip->priority;
ifa->helloint = ip->helloint;
ifa->pollint = ip->pollint;
ifa->strictnbma = ip->strictnbma;
ifa->waitint = ip->waitint;
ifa->deadc = ip->deadc;
ifa->stub = ip->stub;
ifa->autype = ip->autype;
memcpy(ifa->aukey, ip->password, 8);
ifa->options = 2; /* FIXME what options? */
if (ip->type == OSPF_IT_UNDEF)
ifa->type = ospf_iface_clasify(ifa->iface);
else
ifa->type = ip->type;
init_list(&ifa->neigh_list);
init_list(&ifa->nbma_list);
WALK_LIST(nb, ip->nbma_list)
{
nbma = mb_alloc(p->pool, sizeof(struct nbma_node));
nbma->ip = nb->ip;
nbma->eligible = nb->eligible;
add_tail(&ifa->nbma_list, NODE nbma);
}
/* Add hello timer */
ifa->hello_timer = tm_new(p->pool);
ifa->hello_timer->data = ifa;
ifa->hello_timer->randomize = 0;
ifa->hello_timer->hook = hello_timer_hook;
ifa->hello_timer->recurrent = ifa->helloint;
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
if (ifa->type == OSPF_IT_NBMA)
{
ifa->poll_timer = tm_new(p->pool);
ifa->poll_timer->data = ifa;
ifa->poll_timer->randomize = 0;
ifa->poll_timer->hook = poll_timer_hook;
ifa->poll_timer->recurrent = ifa->pollint;
DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint);
}
else
ifa->poll_timer = NULL;
ifa->wait_timer = tm_new(p->pool);
ifa->wait_timer->data = ifa;
ifa->wait_timer->randomize = 0;
ifa->wait_timer->hook = wait_timer_hook;
ifa->wait_timer->recurrent = 0;
DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint);
add_tail(&((struct proto_ospf *) p)->iface_list, NODE ifa);
ifa->state = OSPF_IS_DOWN;
WALK_LIST(oa, po->area_list)
{
if (oa->areaid == ifa->an)
break;
}
if (EMPTY_LIST(po->area_list) || (oa->areaid != ifa->an)) /* New area */
bug("Cannot add any area to accepted Interface");
else
ifa->oa = oa;
if (ifa->type == OSPF_IT_VLINK)
{
ifa->oa = po->backbone;
ifa->voa = oa;
ifa->vid = ip->vid;
return; /* Don't lock, don't add sockets */
}
lock = olock_new(p->pool);
lock->addr = AllSPFRouters;
lock->type = OBJLOCK_IP;
lock->port = OSPF_PROTO;
lock->iface = iface;
lock->data = ifa;
lock->hook = ospf_iface_add;
olock_acquire(lock);
}
void
ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
{
......@@ -344,8 +458,6 @@ ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
struct ospf_area_config *ac;
struct ospf_iface_patt *ip = NULL;
struct ospf_iface *ifa;
struct object_lock *lock;
struct nbma_node *nbma, *nb;
struct ospf_area *oa;
DBG("%s: If notify called\n", p->name);
......@@ -364,90 +476,7 @@ ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface)
if (ip)
{
OSPF_TRACE(D_EVENTS, "Using interface %s.", iface->name);
ifa = mb_allocz(p->pool, sizeof(struct ospf_iface));
ifa->proto = po;
ifa->iface = iface;
ifa->an = ac->areaid;
ifa->cost = ip->cost;
ifa->rxmtint = ip->rxmtint;
ifa->inftransdelay = ip->inftransdelay;
ifa->priority = ip->priority;
ifa->helloint = ip->helloint;
ifa->pollint = ip->pollint;
ifa->strictnbma = ip->strictnbma;
ifa->waitint = ip->waitint;
ifa->deadc = ip->deadc;
ifa->stub = ip->stub;
ifa->autype = ip->autype;
memcpy(ifa->aukey, ip->password, 8);
ifa->options = 2; /* FIXME what options? */
if (ip->type == OSPF_IT_UNDEF)
ifa->type = ospf_iface_clasify(ifa->iface);
else
ifa->type = ip->type;
init_list(&ifa->neigh_list);
init_list(&ifa->nbma_list);
WALK_LIST(nb, ip->nbma_list)
{
nbma = mb_alloc(p->pool, sizeof(struct nbma_node));
nbma->ip = nb->ip;
nbma->eligible = nb->eligible;
add_tail(&ifa->nbma_list, NODE nbma);
}
/* Add hello timer */
ifa->hello_timer = tm_new(p->pool);
ifa->hello_timer->data = ifa;
ifa->hello_timer->randomize = 0;
ifa->hello_timer->hook = hello_timer_hook;
ifa->hello_timer->recurrent = ifa->helloint;
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
if (ifa->type == OSPF_IT_NBMA)
{
ifa->poll_timer = tm_new(p->pool);
ifa->poll_timer->data = ifa;
ifa->poll_timer->randomize = 0;
ifa->poll_timer->hook = poll_timer_hook;
ifa->poll_timer->recurrent = ifa->pollint;
DBG("%s: Installing poll timer. (%u)\n", p->name, ifa->pollint);
}
else
ifa->poll_timer = NULL;
ifa->wait_timer = tm_new(p->pool);
ifa->wait_timer->data = ifa;
ifa->wait_timer->randomize = 0;
ifa->wait_timer->hook = wait_timer_hook;
ifa->wait_timer->recurrent = 0;
DBG("%s: Installing wait timer. (%u)\n", p->name, ifa->waitint);
add_tail(&((struct proto_ospf *) p)->iface_list, NODE ifa);
ifa->state = OSPF_IS_DOWN;
lock = olock_new(p->pool);
lock->addr = AllSPFRouters;
lock->type = OBJLOCK_IP;
lock->port = OSPF_PROTO;
lock->iface = iface;
lock->data = ifa;
lock->hook = ospf_iface_add;
WALK_LIST(NODE oa, po->area_list)
{
if (oa->areaid == ifa->an)
break;
}
if (EMPTY_LIST(po->area_list) || (oa->areaid != ifa->an)) /* New area */
bug("Cannot add any area to accepted Interface");
else
ifa->oa = oa;
olock_acquire(lock);
ospf_iface_new(po, iface, ac, ip);
}
}
......
......@@ -16,5 +16,6 @@ struct ospf_iface *ospf_iface_find(struct proto_ospf *p, struct iface *what);
void ospf_iface_notify(struct proto *p, unsigned flags, struct iface *iface);
void ospf_iface_info(struct ospf_iface *ifa);
void ospf_iface_shutdown(struct ospf_iface *ifa);
void ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ospf_area_config *ac, struct ospf_iface_patt *ip);
#endif /* _BIRD_OSPF_IFACE_H_ */
......@@ -78,16 +78,16 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
if (ifa->type == OSPF_IT_BCAST)
{
if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
sk_send_to(sk, len, AllSPFRouters, OSPF_PROTO);
ospf_send_to(sk, len, AllSPFRouters);
else
sk_send_to(sk, len, AllDRouters, OSPF_PROTO);
ospf_send_to(sk, len, AllDRouters);
}
else
{
if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
ospf_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
else
sk_send_to_bdr(sk, len, ifa);
ospf_send_to_bdr(sk, len, ifa);
}
fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
......@@ -104,16 +104,16 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue)
{
if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
{
sk_send_to(sk, len, AllSPFRouters, OSPF_PROTO);
ospf_send_to(sk, len, AllSPFRouters);
}
else
{
sk_send_to(sk, len, AllDRouters, OSPF_PROTO);
ospf_send_to(sk, len, AllDRouters);
}