Commit 8e48831a authored by Ondřej Zajíček's avatar Ondřej Zajíček
Browse files

Vastly improved OSPF reconfiguration.

Now it can handle a change in iface pattern structure.
It can add, remove and reconfigure interfaces, vlinks and areas.
parent 93e868c7
......@@ -22,8 +22,13 @@ static struct ospf_stubnet_config *this_stubnet;
#ifdef OSPFv2
static void
finish_iface_config(struct ospf_iface_patt *ip)
ospf_iface_finish(void)
{
struct ospf_iface_patt *ip = OSPF_PATT;
if (ip->deadint == 0)
ip->deadint = ip->deadc * ip->helloint;
ip->passwords = get_passwords();
if ((ip->autype == OSPF_AUTH_CRYPT) && (ip->helloint < 5))
......@@ -36,13 +41,57 @@ finish_iface_config(struct ospf_iface_patt *ip)
#ifdef OSPFv3
static void
finish_iface_config(struct ospf_iface_patt *ip)
ospf_iface_finish(void)
{
struct ospf_iface_patt *ip = OSPF_PATT;
if (ip->deadint == 0)
ip->deadint = ip->deadc * ip->helloint;
if ((ip->autype != OSPF_AUTH_NONE) || (get_passwords() != NULL))
cf_error("Authentication not supported in OSPFv3");
}
#endif
static void
ospf_area_finish(void)
{
if ((this_area->areaid == 0) && (this_area->stub != 0))
cf_error( "Backbone area cannot be stub");
}
static void
ospf_proto_finish(void)
{
struct ospf_config *cf = OSPF_CFG;
if (EMPTY_LIST(cf->area_list))
cf_error( "No configured areas in OSPF");
int areano = 0;
int backbone = 0;
struct ospf_area_config *ac;
WALK_LIST(ac, cf->area_list)
{
areano++;
if (ac->areaid == 0)
backbone = 1;
}
cf->abr = areano > 1;
if (cf->abr && !backbone)
{
struct ospf_area_config *ac = cfg_allocz(sizeof(struct ospf_area_config));
add_head(&cf->area_list, NODE ac);
init_list(&ac->patt_list);
init_list(&ac->net_list);
init_list(&ac->stubnet_list);
}
if (!cf->abr && !EMPTY_LIST(cf->vlink_list))
cf_error( "No configured areas in OSPF");
}
CF_DECLS
CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID)
......@@ -58,12 +107,13 @@ CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT)
CF_GRAMMAR
CF_ADDTO(proto, ospf_proto '}')
CF_ADDTO(proto, ospf_proto '}' { ospf_proto_finish(); } )
ospf_proto_start: proto_start OSPF {
this_proto = proto_config_new(&proto_ospf, sizeof(struct ospf_config));
this_proto->preference = DEF_PREF_OSPF;
init_list(&OSPF_CFG->area_list);
init_list(&OSPF_CFG->vlink_list);
OSPF_CFG->rfc1583 = DEFAULT_RFC1583;
OSPF_CFG->tick = DEFAULT_OSPFTICK;
}
......@@ -80,22 +130,21 @@ ospf_proto_item:
| ECMP bool { OSPF_CFG->ecmp = $2 ? DEFAULT_ECMP_LIMIT : 0; }
| ECMP bool LIMIT expr { OSPF_CFG->ecmp = $2 ? $4 : 0; if ($4 < 0) cf_error("ECMP limit cannot be negative"); }
| TICK expr { OSPF_CFG->tick = $2; if($2<=0) cf_error("Tick must be greater than zero"); }
| ospf_area '}'
| ospf_area
;
ospf_area_start: AREA idval '{' {
ospf_area_start: AREA idval {
this_area = cfg_allocz(sizeof(struct ospf_area_config));
add_tail(&OSPF_CFG->area_list, NODE this_area);
this_area->areaid = $2;
this_area->stub = 0;
init_list(&this_area->patt_list);
init_list(&this_area->vlink_list);
init_list(&this_area->net_list);
init_list(&this_area->stubnet_list);
}
;
ospf_area: ospf_area_start ospf_area_opts
ospf_area: ospf_area_start '{' ospf_area_opts '}' { ospf_area_finish(); }
;
ospf_area_opts:
......@@ -138,7 +187,7 @@ ospf_stubnet_item:
;
ospf_vlink:
ospf_vlink_start '{' ospf_vlink_opts '}' { finish_iface_config(OSPF_PATT); }
ospf_vlink_start '{' ospf_vlink_opts '}' { ospf_iface_finish(); }
| ospf_vlink_start
;
......@@ -152,7 +201,7 @@ ospf_vlink_item:
| 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 expr { OSPF_PATT->dead = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
| DEAD expr { OSPF_PATT->deadint = $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"); }
| AUTHENTICATION NONE { OSPF_PATT->autype = OSPF_AUTH_NONE ; }
| AUTHENTICATION SIMPLE { OSPF_PATT->autype = OSPF_AUTH_SIMPLE ; }
......@@ -164,15 +213,16 @@ ospf_vlink_start: VIRTUAL LINK idval
{
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->vlink_list, NODE this_ipatt);
add_tail(&OSPF_CFG->vlink_list, NODE this_ipatt);
init_list(&this_ipatt->ipn_list);
OSPF_PATT->voa = this_area->areaid;
OSPF_PATT->vid = $3;
OSPF_PATT->helloint = HELLOINT_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->dead = 0;
OSPF_PATT->deadint = 0;
OSPF_PATT->type = OSPF_IT_VLINK;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype = OSPF_AUTH_NONE;
......@@ -185,10 +235,8 @@ ospf_iface_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"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); }
| WAIT expr { OSPF_PATT->waitint = $2 ; }
| DEAD expr { OSPF_PATT->dead = $2 ; if ($2<=1) cf_error("Dead interval must be greater than one"); }
| DEAD expr { OSPF_PATT->deadint = $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 ; }
......@@ -198,6 +246,8 @@ ospf_iface_item:
| TYPE PTP { OSPF_PATT->type = OSPF_IT_PTP ; }
| TYPE POINTOMULTIPOINT { OSPF_PATT->type = OSPF_IT_PTMP ; }
| TYPE PTMP { OSPF_PATT->type = OSPF_IT_PTMP ; }
| TRANSMIT DELAY expr { OSPF_PATT->inftransdelay = $3 ; if (($3<=0) || ($3>65535)) cf_error("Transmit delay must be in range 1-65535"); }
| PRIORITY expr { OSPF_PATT->priority = $2 ; if (($2<0) || ($2>255)) cf_error("Priority must be in range 0-255"); }
| STRICT NONBROADCAST bool { OSPF_PATT->strictnbma = $3 ; }
| STUB bool { OSPF_PATT->stub = $2 ; }
| CHECK LINK bool { OSPF_PATT->check_link = $3; }
......@@ -281,7 +331,7 @@ ospf_iface_start:
OSPF_PATT->priority = PRIORITY_D;
OSPF_PATT->waitint = WAIT_DMH*HELLOINT_D;
OSPF_PATT->deadc = DEADC_D;
OSPF_PATT->dead = 0;
OSPF_PATT->deadint = 0;
OSPF_PATT->type = OSPF_IT_UNDEF;
init_list(&OSPF_PATT->nbma_list);
OSPF_PATT->autype = OSPF_AUTH_NONE;
......@@ -300,7 +350,7 @@ ospf_iface_opt_list:
;
ospf_iface:
ospf_iface_start iface_patt_list ospf_iface_opt_list { finish_iface_config(OSPF_PATT); }
ospf_iface_start iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); }
;
opttext:
......
......@@ -88,7 +88,7 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
#else /* OSPFv3 */
tmp = ntohs(ps->deadint);
#endif
if (tmp != ifa->dead)
if (tmp != ifa->deadint)
{
log(L_ERR "%s%I - dead interval mismatch (%d)", beg, faddr, tmp);
return;
......@@ -217,13 +217,13 @@ ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
if (ifa->type == OSPF_IT_NBMA)
{
if ((ifa->priority == 0) && (n->priority > 0))
ospf_hello_send(NULL, 0, n);
ospf_hello_send(NULL, OHS_HELLO, n);
}
ospf_neigh_sm(n, INM_HELLOREC);
}
void
ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
ospf_hello_send(timer *timer, int kind, struct ospf_neighbor *dirn)
{
struct ospf_iface *ifa;
struct ospf_hello_packet *pkt;
......@@ -231,7 +231,6 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
struct proto *p;
struct ospf_neighbor *neigh, *n1;
u16 length;
u32 *pp;
int i;
struct nbma_node *nb;
......@@ -276,27 +275,31 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
pkt->options = ifa->oa->options;
#ifdef OSPFv2
pkt->deadint = htonl(ifa->dead);
pkt->deadint = htonl(ifa->deadint);
pkt->dr = htonl(ipa_to_u32(ifa->drip));
pkt->bdr = htonl(ipa_to_u32(ifa->bdrip));
#else /* OSPFv3 */
pkt->deadint = htons(ifa->dead);
pkt->deadint = htons(ifa->deadint);
pkt->dr = htonl(ifa->drid);
pkt->bdr = htonl(ifa->bdrid);
#endif
/* Fill all neighbors */
i = 0;
pp = (u32 *) (((u8 *) pkt) + sizeof(struct ospf_hello_packet));
WALK_LIST(neigh, ifa->neigh_list)
if (kind != OHS_SHUTDOWN)
{
if ((i+1) * sizeof(u32) + sizeof(struct ospf_hello_packet) > ospf_pkt_bufsize(ifa))
u32 *pp = (u32 *) (((u8 *) pkt) + sizeof(struct ospf_hello_packet));
WALK_LIST(neigh, ifa->neigh_list)
{
OSPF_TRACE(D_PACKETS, "Too many neighbors on the interface!");
break;
if ((i+1) * sizeof(u32) + sizeof(struct ospf_hello_packet) > ospf_pkt_bufsize(ifa))
{
log(L_WARN "%s: Too many neighbors on interface %s", p->name, ifa->iface->name);
break;
}
*(pp + i) = htonl(neigh->rid);
i++;
}
*(pp + i) = htonl(neigh->rid);
i++;
}
length = sizeof(struct ospf_hello_packet) + i * sizeof(u32);
......@@ -319,7 +322,7 @@ ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn)
int to_all = ifa->state > OSPF_IS_DROTHER;
int me_elig = ifa->priority > 0;
if (poll) /* Poll timer */
if (kind == OHS_POLL) /* Poll timer */
{
WALK_LIST(nb, ifa->nbma_list)
if (!nb->found && (to_all || (me_elig && nb->eligible)))
......
......@@ -12,6 +12,10 @@
void ospf_hello_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_neighbor *n, ip_addr faddr);
void ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn);
void ospf_hello_send(timer *timer, int kind, struct ospf_neighbor *dirn);
#define OHS_HELLO 0
#define OHS_POLL 1
#define OHS_SHUTDOWN 2
#endif /* _BIRD_OSPF_HELLO_H_ */
......@@ -21,13 +21,13 @@ char *ospf_it[] = { "broadcast", "nbma", "ptp", "ptmp", "virtual link" };
static void
poll_timer_hook(timer * timer)
{
ospf_hello_send(timer, 1, NULL);
ospf_hello_send(timer, OHS_POLL, NULL);
}
static void
hello_timer_hook(timer * timer)
{
ospf_hello_send(timer, 0, NULL);
ospf_hello_send(timer, OHS_HELLO, NULL);
}
static void
......@@ -40,6 +40,8 @@ wait_timer_hook(timer * timer)
ospf_iface_sm(ifa, ISM_WAITF);
}
static void ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa);
u32
rxbufsize(struct ospf_iface *ifa)
{
......@@ -163,7 +165,13 @@ ospf_iface_down(struct ospf_iface *ifa)
if (ifa->type != OSPF_IT_VLINK)
{
OSPF_TRACE(D_EVENTS, "Removing interface %s", ifa->iface->name);
#ifdef OSPFv2
OSPF_TRACE(D_EVENTS, "Removing interface %s (%I/%d) from area %R",
ifa->iface->name, ifa->addr->prefix, ifa->addr->pxlen, ifa->oa->areaid);
#else
OSPF_TRACE(D_EVENTS, "Removing interface %s (IID %d) from area %R",
ifa->iface->name, ifa->instance_id, ifa->oa->areaid);
#endif
/* First of all kill all the related vlinks */
WALK_LIST(iff, po->iface_list)
......@@ -207,14 +215,25 @@ ospf_iface_down(struct ospf_iface *ifa)
}
static void
void
ospf_iface_remove(struct ospf_iface *ifa)
{
struct proto *p = &ifa->oa->po->proto;
if (ifa->type == OSPF_IT_VLINK)
OSPF_TRACE(D_EVENTS, "Removing vlink to %R via area %R", ifa->vid, ifa->voa->areaid);
ospf_iface_sm(ifa, ISM_DOWN);
rem_node(NODE ifa);
rfree(ifa->pool);
}
void
ospf_iface_shutdown(struct ospf_iface *ifa)
{
if (ifa->state > OSPF_IS_DOWN)
ospf_hello_send(ifa->hello_timer, OHS_SHUTDOWN, NULL);
}
/**
* ospf_iface_chstate - handle changes of interface state
* @ifa: OSPF interface
......@@ -357,7 +376,7 @@ ospf_iface_sm(struct ospf_iface *ifa, int event)
}
static u8
ospf_iface_classify(struct iface *ifa, struct ifa *addr)
ospf_iface_classify_int(struct iface *ifa, struct ifa *addr)
{
if (ipa_nonzero(addr->opposite))
return (ifa->flags & IF_MULTICAST) ? OSPF_IT_PTP : OSPF_IT_PTMP;
......@@ -372,6 +391,13 @@ ospf_iface_classify(struct iface *ifa, struct ifa *addr)
return OSPF_IT_PTP;
}
static inline u8
ospf_iface_classify(u8 type, struct ifa *addr)
{
return (type != OSPF_IT_UNDEF) ? type : ospf_iface_classify_int(addr->iface, addr);
}
struct ospf_iface *
ospf_iface_find(struct proto_ospf *p, struct iface *what)
{
......@@ -401,23 +427,69 @@ ospf_iface_add(struct object_lock *lock)
ospf_iface_sm(ifa, (ifa->check_link && !(ifa->iface->flags & IF_LINK_UP)) ? ISM_LOOP : ISM_UP);
}
static inline void
add_nbma_node(struct ospf_iface *ifa, struct nbma_node *src, int found)
{
struct nbma_node *n = mb_alloc(ifa->pool, sizeof(struct nbma_node));
add_tail(&ifa->nbma_list, NODE n);
n->ip = src->ip;
n->eligible = src->eligible;
n->found = found;
}
static int
ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr)
{
if (! addr)
return 0;
/*
* We cannot properly support multiple OSPF ifaces on real iface
* with multiple prefixes, therefore we force OSPF ifaces with
* non-primary IP prefixes to be stub.
*/
#if defined(OSPFv2) && !defined(CONFIG_MC_PROPER_SRC)
if (! (addr->flags & IA_PRIMARY))
return 1;
#endif
/* a loopback/dummy address */
if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite))
return 1;
return ip->stub;
}
void
ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
struct ospf_area_config *ac, struct ospf_iface_patt *ip)
ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *ip)
{
struct proto *p = &po->proto;
struct pool *pool = rp_new(p->pool, "OSPF Interface");
struct proto *p = &oa->po->proto;
struct iface *iface = addr ? addr->iface : NULL;
struct pool *pool;
struct ospf_iface *ifa;
struct nbma_node *nbma, *nb;
struct nbma_node *nb;
struct object_lock *lock;
struct ospf_area *oa;
if (ip->type != OSPF_IT_VLINK)
OSPF_TRACE(D_EVENTS, "Adding interface %s", iface->name);
if (ip->type == OSPF_IT_VLINK)
OSPF_TRACE(D_EVENTS, "Adding vlink to %R via area %R", ip->vid, ip->voa);
else
{
#ifdef OSPFv2
OSPF_TRACE(D_EVENTS, "Adding interface %s (%I/%d) to area %R",
iface->name, addr->prefix, addr->pxlen, oa->areaid);
#else
OSPF_TRACE(D_EVENTS, "Adding interface %s (IID %d) to area %R",
iface->name, ip->instance_id, oa->areaid);
#endif
}
pool = rp_new(p->pool, "OSPF Interface");
ifa = mb_allocz(pool, sizeof(struct ospf_iface));
ifa->iface = iface;
ifa->addr = addr;
ifa->oa = oa;
ifa->cf = ip;
ifa->pool = pool;
ifa->cost = ip->cost;
......@@ -428,7 +500,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
ifa->pollint = ip->pollint;
ifa->strictnbma = ip->strictnbma;
ifa->waitint = ip->waitint;
ifa->dead = (ip->dead == 0) ? ip->deadc * ifa->helloint : ip->dead;
ifa->deadint = ip->deadint;
ifa->stub = ospf_iface_stubby(ip, addr);
ifa->ioprob = OSPF_I_OK;
ifa->rxbuf = ip->rxbuf;
......@@ -444,14 +516,7 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
ifa->instance_id = ip->instance_id;
#endif
if (ip->type == OSPF_IT_UNDEF)
ifa->type = ospf_iface_classify(iface, addr);
else
ifa->type = ip->type;
/* a loopback/dummy address */
if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite))
ifa->stub = 1;
ifa->type = ospf_iface_classify(ip->type, addr);
/* Check validity of interface type */
int old_type = ifa->type;
......@@ -479,16 +544,8 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
init_list(&ifa->nbma_list);
WALK_LIST(nb, ip->nbma_list)
{
if (!ipa_in_net(nb->ip, addr->prefix, addr->pxlen))
continue;
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);
}
if (ipa_in_net(nb->ip, addr->prefix, addr->pxlen))
add_nbma_node(ifa, nb, 0);
DBG("%s: Installing hello timer. (%u)\n", p->name, ifa->helloint);
ifa->hello_timer = tm_new(pool);
......@@ -518,26 +575,11 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
}
ifa->state = OSPF_IS_DOWN;
add_tail(&po->iface_list, NODE ifa);
ifa->oa = NULL;
WALK_LIST(oa, po->area_list)
{
if (oa->areaid == ac->areaid)
{
ifa->oa = oa;
break;
}
}
if (!ifa->oa)
bug("Cannot add any area to accepted Interface");
else
add_tail(&oa->po->iface_list, NODE ifa);
if (ifa->type == OSPF_IT_VLINK)
{
ifa->oa = po->backbone;
ifa->voa = oa;
ifa->voa = ospf_find_area(oa->po, ip->voa);
ifa->vid = ip->vid;
return; /* Don't lock, don't add sockets */
}
......@@ -564,14 +606,209 @@ ospf_iface_new(struct proto_ospf *po, struct iface *iface, struct ifa *addr,
olock_acquire(lock);
}
int
ospf_iface_reconfigure(struct ospf_iface *ifa, struct ospf_iface_patt *new)
{
struct proto *p = &ifa->oa->po->proto;
struct nbma_node *nb, *nbx;
char *ifname = (ifa->type != OSPF_IT_VLINK) ? ifa->iface->name : "vlink";
/* Type could be changed in ospf_iface_new(),
but if config values are same then also results are same */
int old_type = ospf_iface_classify(ifa->cf->type, ifa->addr);
int new_type = ospf_iface_classify(new->type, ifa->addr);
if (old_type != new_type)
return 0;
int new_stub = ospf_iface_stubby(new, ifa->addr);
if (ifa->stub != new_stub)
return 0;
ifa->cf = new;
ifa->marked = 0;
/* HELLO TIMER */
if (ifa->helloint != new->helloint)
{
OSPF_TRACE(D_EVENTS, "Changing hello interval on interface %s from %d to %d",
ifname, ifa->helloint, new->helloint);
ifa->helloint = new->helloint;
ifa->hello_timer->recurrent = ifa->helloint;
tm_start(ifa->hello_timer, ifa->helloint);
}
/* RXMT TIMER */
if (ifa->rxmtint != new->rxmtint)
{
OSPF_TRACE(D_EVENTS, "Changing retransmit interval on interface %s from %d to %d",
ifname, ifa->rxmtint, new->rxmtint);
ifa->rxmtint = new->rxmtint;
}
/* POLL TIMER */
if (ifa->pollint != new->pollint)
{
OSPF_TRACE(D_EVENTS, "Changing poll interval on interface %s from %d to %d",
ifname, ifa->pollint, new->pollint);
ifa->pollint = new->helloint;
ifa->poll_timer->recurrent = ifa->pollint;
tm_start(ifa->poll_timer, ifa->pollint);
}
/* WAIT TIMER */
if (ifa->waitint != new->waitint)
{
OSPF_TRACE(D_EVENTS, "Changing wait interval on interface %s from %d to %d",
ifname, ifa->waitint, new->waitint);
ifa->waitint = new->waitint;
if (ifa->wait_timer->expires != 0)
tm_start(ifa->wait_timer, ifa->waitint);
}
/* DEAD TIMER */
if (ifa->deadint != new->deadint)
{
OSPF_TRACE(D_EVENTS, "Changing dead interval on interface %s from %d to %d",
ifname, ifa->deadint, new->deadint);
ifa->deadint = new->deadint;
}
/* INFTRANS */
if (ifa->inftransdelay != new->inftransdelay)
{
OSPF_TRACE(D_EVENTS, "Changing transmit delay on interface %s from %d to %d",
ifname, ifa->inftransdelay, new->inftransdelay);
ifa->inftransdelay = new->inftransdelay;
}
#ifdef OSPFv2
/* AUTHENTICATION */
if (ifa->autype != new->autype)
{
OSPF_TRACE(D_EVENTS, "Changing authentication type on interface %s", ifname);
ifa->autype = new->autype;
}
/* Update passwords */
ifa->passwords = new->passwords;
#endif
/* Remaining options are just for proper interfaces */
if (ifa->type == OSPF_IT_VLINK)
return 1;
/* COST */
if (ifa->cost != new->cost)
{
OSPF_TRACE(D_EVENTS, "Changing cost on interface %s from %d to %d",
ifname, ifa->cost, new->cost);
ifa->cost = new->cost;
}
/* PRIORITY */
if (ifa->priority != new->priority)
{
OSPF_TRACE(D_EVENTS, "Changing priority on interface %s from %d to %d",
ifname, ifa->priority, new->priority);
ifa->priority = new->priority;