summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_ism.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_ism.c')
-rw-r--r--ospf6d/ospf6_ism.c519
1 files changed, 0 insertions, 519 deletions
diff --git a/ospf6d/ospf6_ism.c b/ospf6d/ospf6_ism.c
deleted file mode 100644
index bb14604e..00000000
--- a/ospf6d/ospf6_ism.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 1999 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* Interface State Machine */
-
-#include "ospf6d.h"
-
-int
-ifs_change (state_t ifs_next, char *reason, struct ospf6_interface *o6i)
-{
- state_t ifs_prev;
-
- ifs_prev = o6i->state;
-
- if (ifs_prev == ifs_next)
- return 0;
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: %s -> %s (%s)",
- o6i->interface->name,
- ospf6_interface_state_string[ifs_prev],
- ospf6_interface_state_string[ifs_next], reason);
-
- if ((ifs_prev == IFS_DR || ifs_prev == IFS_BDR) &&
- (ifs_next != IFS_DR && ifs_next != IFS_BDR))
- ospf6_leave_alldrouters (o6i->interface->ifindex);
- else if ((ifs_prev != IFS_DR && ifs_prev != IFS_BDR) &&
- (ifs_next == IFS_DR || ifs_next == IFS_BDR))
- ospf6_join_alldrouters (o6i->interface->ifindex);
-
- o6i->state = ifs_next;
-
- if (o6i->prevdr != o6i->dr || o6i->prevbdr != o6i->bdr)
- {
- if (IS_OSPF6_DUMP_INTERFACE)
- {
- char dr[16], bdr[16], prevdr[16], prevbdr[16];
- inet_ntop (AF_INET, &o6i->prevdr, prevdr, sizeof (prevdr));
- inet_ntop (AF_INET, &o6i->prevbdr, prevbdr, sizeof (prevbdr));
- inet_ntop (AF_INET, &o6i->dr, dr, sizeof (dr));
- inet_ntop (AF_INET, &o6i->bdr, bdr, sizeof (bdr));
- zlog_info ("I/F: %s: DR: %s -> %s", o6i->interface->name,
- prevdr, dr);
- zlog_info ("I/F: %s: BDR: %s -> %s", o6i->interface->name,
- prevbdr, bdr);
- }
- }
-
- CALL_CHANGE_HOOK (&interface_hook, o6i);
- return 0;
-}
-
-
-/* Interface State Machine */
-int
-interface_up (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
-
- assert (ospf6_interface);
- assert (ospf6_interface->interface);
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: InterfaceUp",
- ospf6_interface->interface->name);
-
- /* check physical interface is up */
- if (!if_is_up (ospf6_interface->interface))
- {
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_warn (" interface %s down, can't execute InterfaceUp",
- ospf6_interface->interface->name);
- return -1;
- }
-
- /* if already enabled, do nothing */
- if (ospf6_interface->state > IFS_DOWN)
- {
- zlog_warn ("Interface %s already up",
- ospf6_interface->interface->name);
- return 0;
- }
-
- /* ifid of this interface */
- ospf6_interface->if_id = ospf6_interface->interface->ifindex;
-
- /* Join AllSPFRouters */
- ospf6_join_allspfrouters (ospf6_interface->interface->ifindex);
-
- /* set socket options */
- ospf6_set_reuseaddr ();
- ospf6_reset_mcastloop ();
- ospf6_set_pktinfo ();
- ospf6_set_checksum ();
-
- /* Schedule Hello */
- if (! CHECK_FLAG (ospf6_interface->flag, OSPF6_INTERFACE_FLAG_PASSIVE))
- thread_add_event (master, ospf6_send_hello, ospf6_interface, 0);
-
- /* decide next interface state */
- if (if_is_pointopoint (ospf6_interface->interface))
- ifs_change (IFS_PTOP, "IF Type PointToPoint", ospf6_interface);
- else if (ospf6_interface->priority == 0)
- ifs_change (IFS_DROTHER, "Router Priority = 0", ospf6_interface);
- else
- {
- ifs_change (IFS_WAITING, "Priority > 0", ospf6_interface);
- thread_add_timer (master, wait_timer, ospf6_interface,
- ospf6_interface->dead_interval);
- }
-
- CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, ospf6_interface);
-
- return 0;
-}
-
-int
-wait_timer (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
- assert (ospf6_interface);
-
- if (ospf6_interface->state != IFS_WAITING)
- return 0;
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: WaitTimer", ospf6_interface->interface->name);
-
- ifs_change (dr_election (ospf6_interface),
- "WaitTimer:DR Election", ospf6_interface);
- return 0;
-}
-
-int backup_seen (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
- assert (ospf6_interface);
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: BackupSeen", ospf6_interface->interface->name);
-
- if (ospf6_interface->state == IFS_WAITING)
- ifs_change (dr_election (ospf6_interface),
- "BackupSeen:DR Election", ospf6_interface);
-
- return 0;
-}
-
-int neighbor_change (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
- assert (ospf6_interface);
-
- if (ospf6_interface->state != IFS_DROTHER &&
- ospf6_interface->state != IFS_BDR &&
- ospf6_interface->state != IFS_DR)
- return 0;
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: NeighborChange", ospf6_interface->interface->name);
-
- ifs_change (dr_election (ospf6_interface),
- "NeighborChange:DR Election", ospf6_interface);
-
- return 0;
-}
-
-int
-loopind (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
- assert (ospf6_interface);
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: LoopInd", ospf6_interface->interface->name);
-
- /* XXX not yet */
-
- return 0;
-}
-
-int
-interface_down (struct thread *thread)
-{
- struct ospf6_interface *ospf6_interface;
-
- ospf6_interface = (struct ospf6_interface *) THREAD_ARG (thread);
- assert (ospf6_interface);
-
- if (IS_OSPF6_DUMP_INTERFACE)
- zlog_info ("I/F: %s: InterfaceDown", ospf6_interface->interface->name);
-
- if (ospf6_interface->state == IFS_NONE)
- return 1;
-
- /* Leave AllSPFRouters */
- if (ospf6_interface_is_enabled (ospf6_interface->interface->ifindex))
- ospf6_leave_allspfrouters (ospf6_interface->interface->ifindex);
-
- ifs_change (IFS_DOWN, "Configured", ospf6_interface);
-
- return 0;
-}
-
-
-/* 9.4 of RFC2328 */
-int
-dr_election (struct ospf6_interface *ospf6_interface)
-{
- list candidate_list = list_new ();
- listnode i, j, n;
- ifid_t prevdr, prevbdr, dr = 0, bdr;
- struct ospf6_neighbor *nbpi, *nbpj, myself, *nbr;
- int declare = 0;
- int gofive = 0;
-
- /* statistics */
- ospf6_interface->ospf6_stat_dr_election++;
-
- /* pseudo neighbor "myself" */
- memset (&myself, 0, sizeof (myself));
- myself.state = NBS_TWOWAY;
- myself.dr = ospf6_interface->dr;
- myself.bdr = ospf6_interface->bdr;
- myself.priority = ospf6_interface->priority;
- myself.ifid = ospf6_interface->if_id;
- myself.router_id = ospf6_interface->area->ospf6->router_id;
-
-/* step_one: */
-
- ospf6_interface->prevdr = prevdr = ospf6_interface->dr;
- ospf6_interface->prevbdr = prevbdr = ospf6_interface->bdr;
-
-step_two:
-
- /* Calculate Backup Designated Router. */
- /* Make Candidate list */
- if (!list_isempty (candidate_list))
- list_delete_all_node (candidate_list);
- declare = 0;
- for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
- {
- nbpi = (struct ospf6_neighbor *)getdata (i);
- if (nbpi->priority == 0)
- continue;
- if (nbpi->state < NBS_TWOWAY)
- continue;
- if (nbpi->dr == nbpi->router_id)
- continue;
- if (nbpi->bdr == nbpi->router_id)
- declare++;
- listnode_add (candidate_list, nbpi);
- }
-
- if (myself.priority)
- {
- if (myself.dr != myself.router_id)
- {
- if (myself.bdr == myself.router_id)
- declare++;
- listnode_add (candidate_list, &myself);
- }
- }
-
- /* Elect BDR */
- for (i = listhead (candidate_list);
- candidate_list->count > 1;
- i = listhead (candidate_list))
- {
- j = i;
- nextnode(j);
- assert (j);
- nbpi = (struct ospf6_neighbor *)getdata (i);
- nbpj = (struct ospf6_neighbor *)getdata (j);
- if (declare)
- {
- int deleted = 0;
- if (nbpi->bdr != nbpi->router_id)
- {
- listnode_delete (candidate_list, nbpi);
- deleted++;
- }
- if (nbpj->bdr != nbpj->router_id)
- {
- listnode_delete (candidate_list, nbpj);
- deleted++;
- }
- if (deleted)
- continue;
- }
- if (nbpi->priority > nbpj->priority)
- {
- listnode_delete (candidate_list, nbpj);
- continue;
- }
- else if (nbpi->priority < nbpj->priority)
- {
- listnode_delete (candidate_list, nbpi);
- continue;
- }
- else /* equal, case of tie */
- {
- if (ntohl (nbpi->router_id) > ntohl (nbpj->router_id))
- {
- listnode_delete (candidate_list, nbpj);
- continue;
- }
- else if (ntohl (nbpi->router_id) < ntohl (nbpj->router_id))
- {
- listnode_delete (candidate_list, nbpi);
- continue;
- }
- else
- assert (0);
- }
- }
-
- if (!list_isempty (candidate_list))
- {
- assert (candidate_list->count == 1);
- n = listhead (candidate_list);
- nbr = (struct ospf6_neighbor *)getdata (n);
- bdr = nbr->router_id;
- }
- else
- bdr = 0;
-
-/* step_three: */
-
- /* Calculate Designated Router. */
- /* Make Candidate list */
- if (!list_isempty (candidate_list))
- list_delete_all_node (candidate_list);
- declare = 0;
- for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
- {
- nbpi = (struct ospf6_neighbor *)getdata (i);
- if (nbpi->priority == 0)
- continue;
- if (nbpi->state < NBS_TWOWAY)
- continue;
- if (nbpi->dr == nbpi->router_id)
- {
- declare++;
- listnode_add (candidate_list, nbpi);
- }
- }
- if (myself.priority)
- {
- if (myself.dr == myself.router_id)
- {
- declare++;
- listnode_add (candidate_list, &myself);
- }
- }
-
- /* Elect DR */
- if (declare == 0)
- {
- assert (list_isempty (candidate_list));
- /* No one declare but candidate_list not empty */
- dr = bdr;
- }
- else
- {
- assert (!list_isempty (candidate_list));
- for (i = listhead (candidate_list);
- candidate_list->count > 1;
- i = listhead (candidate_list))
- {
- j = i;
- nextnode (j);
- assert (j);
- nbpi = (struct ospf6_neighbor *)getdata (i);
- nbpj = (struct ospf6_neighbor *)getdata (j);
-
- if (nbpi->dr != nbpi->router_id)
- {
- list_delete_node (candidate_list, i);
- continue;
- }
- if (nbpj->dr != nbpj->router_id)
- {
- list_delete_node (candidate_list, j);
- continue;
- }
-
- if (nbpi->priority > nbpj->priority)
- {
- list_delete_node (candidate_list, j);
- continue;
- }
- else if (nbpi->priority < nbpj->priority)
- {
- list_delete_node (candidate_list, i);
- continue;
- }
- else /* equal, case of tie */
- {
- if (ntohl (nbpi->router_id) > ntohl (nbpj->router_id))
- {
- list_delete_node (candidate_list, j);
- continue;
- }
- else if (ntohl (nbpi->router_id) < ntohl (nbpj->router_id))
- {
- list_delete_node (candidate_list, i);
- continue;
- }
- else
- {
- zlog_warn ("!!!THE SAME ROUTER ID FOR DIFFERENT NEIGHBOR");
- zlog_warn ("!!!MISCONFIGURATION?");
- list_delete_node (candidate_list, i);
- continue;
- }
- }
- }
- if (!list_isempty (candidate_list))
- {
- assert (candidate_list->count == 1);
- n = listhead (candidate_list);
- nbr = (struct ospf6_neighbor *)getdata (n);
- dr = nbr->router_id;
- }
- else
- assert (0);
- }
-
-/* step_four: */
-
- if (gofive)
- goto step_five;
-
- if (dr != prevdr)
- {
- if ((dr == myself.router_id || prevdr == myself.router_id)
- && !(dr == myself.router_id && prevdr == myself.router_id))
- {
- myself.dr = dr;
- myself.bdr = bdr;
- gofive++;
- goto step_two;
- }
- }
- if (bdr != prevbdr)
- {
- if ((bdr == myself.router_id || prevbdr == myself.router_id)
- && !(bdr == myself.router_id && prevbdr == myself.router_id))
- {
- myself.dr = dr;
- myself.bdr = bdr;
- gofive++;
- goto step_two;
- }
- }
-
-step_five:
-
- ospf6_interface->dr = dr;
- ospf6_interface->bdr = bdr;
-
- if (prevdr != dr || prevbdr != bdr)
- {
- for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
- {
- nbpi = getdata (i);
- if (nbpi->state < NBS_TWOWAY)
- continue;
- /* Schedule or Execute AdjOK. which does "invoke" mean? */
- thread_add_event (master, adj_ok, nbpi, 0);
- }
- }
-
- list_delete (candidate_list);
-
- if (dr == myself.router_id)
- {
- assert (bdr != myself.router_id);
- return IFS_DR;
- }
- else if (bdr == myself.router_id)
- {
- assert (dr != myself.router_id);
- return IFS_BDR;
- }
- else
- return IFS_DROTHER;
-}
-
-