📄 ospf6_lsa.c
字号:
if (slot == NULL) { if (IS_OSPF6_DUMP_LSA) zlog_info ("Registering LSA slot: no such slot: %#x", type); return -1; } if (IS_OSPF6_DUMP_LSA) zlog_info ("Unregistering LSA Slot: %#x %s", slot->type, slot->name); if (slot->prev) slot->prev->next = slot->next; if (slot->next) slot->next->prev = slot->prev; if (slot_head == slot) slot_head = slot->next; XFREE (MTYPE_OSPF6_LSA, slot); return 0;}char *ospf6_lsa_type_string (u_int16_t type, char *buf, int bufsize){ struct ospf6_lsa_slot *slot; slot = ospf6_lsa_slot_get (type); if (slot) snprintf (buf, bufsize, "%s", slot->name); else snprintf (buf, bufsize, "Type=0x%04x", ntohs (type)); return buf;}/*******************//* LSA Origination *//*******************/#define CONTINUE_IF_ADDRESS_LINKLOCAL(addr)\ if (IN6_IS_ADDR_LINKLOCAL (&(addr)->u.prefix6))\ {\ char buf[64];\ prefix2str (addr, buf, sizeof (buf));\ if (IS_OSPF6_DUMP_LSA)\ zlog_info (" Filter out Linklocal: %s", buf);\ continue;\ }#define CONTINUE_IF_ADDRESS_UNSPECIFIED(addr)\ if (IN6_IS_ADDR_UNSPECIFIED (&(addr)->u.prefix6))\ {\ char buf[64];\ prefix2str (addr, buf, sizeof (buf));\ if (IS_OSPF6_DUMP_LSA)\ zlog_info (" Filter out Unspecified: %s", buf);\ continue;\ }#define CONTINUE_IF_ADDRESS_LOOPBACK(addr)\ if (IN6_IS_ADDR_LOOPBACK (&(addr)->u.prefix6))\ {\ char buf[64];\ prefix2str (addr, buf, sizeof (buf));\ if (IS_OSPF6_DUMP_LSA)\ zlog_info (" Filter out Loopback: %s", buf);\ continue;\ }#define CONTINUE_IF_ADDRESS_V4COMPAT(addr)\ if (IN6_IS_ADDR_V4COMPAT (&(addr)->u.prefix6))\ {\ char buf[64];\ prefix2str (addr, buf, sizeof (buf));\ if (IS_OSPF6_DUMP_LSA)\ zlog_info (" Filter out V4Compat: %s", buf);\ continue;\ }#define CONTINUE_IF_ADDRESS_V4MAPPED(addr)\ if (IN6_IS_ADDR_V4MAPPED (&(addr)->u.prefix6))\ {\ char buf[64];\ prefix2str (addr, buf, sizeof (buf));\ if (IS_OSPF6_DUMP_LSA)\ zlog_info (" Filter out V4Mapped: %s", buf);\ continue;\ }/******************************//* RFC2740 3.4.3.1 Router-LSA *//******************************/char *ospf6_lsa_router_bits_string (u_char router_bits, char *buf, int size){ char w, v, e, b; w = (router_bits & OSPF6_ROUTER_LSA_BIT_W ? 'W' : '-'); v = (router_bits & OSPF6_ROUTER_LSA_BIT_V ? 'V' : '-'); e = (router_bits & OSPF6_ROUTER_LSA_BIT_E ? 'E' : '-'); b = (router_bits & OSPF6_ROUTER_LSA_BIT_B ? 'B' : '-'); snprintf (buf, size, "----%c%c%c%c", w, v, e, b); return buf;}intospf6_lsa_router_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; char buf[32], name[32], bits[32], options[32]; struct ospf6_router_lsa *router_lsa; struct ospf6_router_lsd *lsdesc; assert (lsa->header); router_lsa = (struct ospf6_router_lsa *) ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); ospf6_lsa_router_bits_string (router_lsa->bits, bits, sizeof (bits)); ospf6_options_string (router_lsa->options, options, sizeof (options)); vty_out (vty, " Bits: %s Options: %s%s", bits, options, VTY_NEWLINE); start = (char *) router_lsa + sizeof (struct ospf6_router_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current + sizeof (struct ospf6_router_lsd) <= end; current += sizeof (struct ospf6_router_lsd)) { lsdesc = (struct ospf6_router_lsd *) current; if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT) snprintf (name, sizeof (name), "Point-To-Point"); else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK) snprintf (name, sizeof (name), "Transit-Network"); else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_STUB_NETWORK) snprintf (name, sizeof (name), "Stub-Network"); else if (lsdesc->type == OSPF6_ROUTER_LSD_TYPE_VIRTUAL_LINK) snprintf (name, sizeof (name), "Virtual-Link"); else snprintf (name, sizeof (name), "Unknown (%#x)", lsdesc->type); vty_out (vty, " Type: %s Metric: %d%s", name, ntohs (lsdesc->metric), VTY_NEWLINE); vty_out (vty, " Interface ID: %s%s", inet_ntop (AF_INET, &lsdesc->interface_id, buf, sizeof (buf)), VTY_NEWLINE); vty_out (vty, " Neighbor Interface ID: %s%s", inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, buf, sizeof (buf)), VTY_NEWLINE); vty_out (vty, " Neighbor Router ID: %s%s", inet_ntop (AF_INET, &lsdesc->neighbor_router_id, buf, sizeof (buf)), VTY_NEWLINE); } return 0;}u_longospf6_lsa_has_elasped (u_int16_t type, u_int32_t id, u_int32_t adv_router, void *scope){ struct ospf6_lsa *old; struct timeval now; if (adv_router != ospf6->router_id) zlog_info ("LSA: Router-ID changed ?"); old = ospf6_lsdb_lookup (type, id, adv_router, scope); if (! old) return OSPF6_LSA_MAXAGE; gettimeofday (&now, NULL); return ((u_long) SEC_TVDIFF (&now, &old->originated));}intospf6_lsa_originate_router (struct thread *thread){ char buffer [MAXLSASIZE]; u_int16_t size; struct ospf6_area *o6a; int count; u_int32_t area_id; struct ospf6_router_lsa *router_lsa; struct ospf6_router_lsd *router_lsd; listnode i; struct ospf6_interface *o6i; struct ospf6_neighbor *o6n = NULL; area_id = (u_int32_t) THREAD_ARG (thread); o6a = ospf6_area_lookup (area_id, ospf6); if (! o6a) { inet_ntop (AF_INET, &area_id, buffer, sizeof (buffer)); if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: Update Router-LSA: No such area: %s", buffer); return 0; } /* clear thread */ o6a->thread_router_lsa = NULL; if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: originate Router-LSA for Area %s", o6a->str); size = sizeof (struct ospf6_router_lsa); memset (buffer, 0, sizeof (buffer)); router_lsa = (struct ospf6_router_lsa *) buffer; OSPF6_OPT_CLEAR_ALL (router_lsa->options); OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_V6); OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_E); OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_MC); OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_N); OSPF6_OPT_SET (router_lsa->options, OSPF6_OPT_R); OSPF6_OPT_CLEAR (router_lsa->options, OSPF6_OPT_DC); OSPF6_ROUTER_LSA_CLEAR_ALL_BITS (router_lsa); OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_B); if (ospf6_is_asbr (o6a->ospf6)) OSPF6_ROUTER_LSA_SET (router_lsa, OSPF6_ROUTER_LSA_BIT_E); else OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_E); OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_V); OSPF6_ROUTER_LSA_CLEAR (router_lsa, OSPF6_ROUTER_LSA_BIT_W); /* describe links for each interfaces */ router_lsd = (struct ospf6_router_lsd *) (router_lsa + 1); for (i = listhead (o6a->if_list); i; nextnode (i)) { o6i = (struct ospf6_interface *) getdata (i); assert (o6i); /* Interfaces in state Down or Loopback are not described */ if (o6i->state == IFS_DOWN || o6i->state == IFS_LOOPBACK) continue; /* Nor are interfaces without any full adjacencies described */ count = 0; o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state); if (count == 0) continue; /* Point-to-Point interfaces */ if (if_is_pointopoint (o6i->interface)) { if (listcount (o6i->neighbor_list) == 0) continue; if (listcount (o6i->neighbor_list) != 1) zlog_warn ("LSA: Multiple neighbors on PoinToPoint: %s", o6i->interface->name); o6n = (struct ospf6_neighbor *) getdata (listhead (o6i->neighbor_list)); assert (o6n); router_lsd->type = OSPF6_ROUTER_LSD_TYPE_POINTTOPOINT; router_lsd->metric = htons (o6i->cost); router_lsd->interface_id = htonl (o6i->if_id); router_lsd->neighbor_interface_id = htonl (o6n->ifid); router_lsd->neighbor_router_id = o6n->router_id; size += sizeof (struct ospf6_router_lsd); router_lsd ++; continue; } /* Broadcast and NBMA interfaces */ if (if_is_broadcast (o6i->interface)) { /* If this router is not DR, and If this router not fully adjacent with DR, this interface is not transit yet: ignore. */ if (o6i->state != IFS_DR) { o6n = ospf6_neighbor_lookup (o6i->dr, o6i); /* find DR */ if (o6n == NULL || o6n->state != NBS_FULL) continue; } else { count = 0; o6i->foreach_nei (o6i, &count, NBS_FULL, ospf6_count_state); if (count == 0) continue; } router_lsd->type = OSPF6_ROUTER_LSD_TYPE_TRANSIT_NETWORK; router_lsd->metric = htons (o6i->cost); router_lsd->interface_id = htonl (o6i->if_id); if (o6i->state != IFS_DR) { router_lsd->neighbor_interface_id = htonl (o6n->ifid); router_lsd->neighbor_router_id = o6n->router_id; } else { router_lsd->neighbor_interface_id = htonl (o6i->if_id); router_lsd->neighbor_router_id = o6i->area->ospf6->router_id; } size += sizeof (struct ospf6_router_lsd); router_lsd ++; continue; } /* Virtual links */ /* xxx */ /* Point-to-Multipoint interfaces */ /* xxx */ } ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_ROUTER), htonl (0), o6a->ospf6->router_id, (char *) router_lsa, size, o6a); return 0;}voidospf6_lsa_schedule_router (struct ospf6_area *area){ u_long elasped_time, time = 0; if (area->thread_router_lsa) { if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: schedule: Router-LSA for Area %s: another thread", area->str); return; } elasped_time = ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_ROUTER), htonl (0), area->ospf6->router_id, area); if (elasped_time < OSPF6_MIN_LS_INTERVAL) time = (u_long) (OSPF6_MIN_LS_INTERVAL - elasped_time); else time = 0; if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: schedule: Router-LSA for Area %s after %lu sec", area->str, time); if (time) area->thread_router_lsa = thread_add_timer (master, ospf6_lsa_originate_router, (void *) area->area_id, time); else area->thread_router_lsa = thread_add_event (master, ospf6_lsa_originate_router, (void *) area->area_id, 0);}intospf6_lsa_router_hook_neighbor (void *neighbor){ struct ospf6_neighbor *o6n = neighbor; if (o6n->ospf6_interface->area) ospf6_lsa_schedule_router (o6n->ospf6_interface->area); return 0;}intospf6_lsa_router_hook_interface (void *interface){ struct ospf6_interface *o6i = interface; if (o6i->area) ospf6_lsa_schedule_router (o6i->area); return 0;}intospf6_lsa_router_hook_area (void *area){ struct ospf6_area *o6a = area; ospf6_lsa_schedule_router (o6a); return 0;}intospf6_lsa_router_hook_top (void *ospf6){ struct ospf6 *o6 = ospf6; struct ospf6_area *o6a; listnode node; for (node = listhead (o6->area_list); node; nextnode (node)) { o6a = getdata (node); ospf6_lsa_schedule_router (o6a); } return 0;}intospf6_lsa_router_refresh (void *old){ struct ospf6_lsa *lsa = old; struct ospf6_area *o6a; o6a = lsa->scope; ospf6_lsa_schedule_router (o6a); return 0;}voidospf6_lsa_slot_register_router (){ struct ospf6_lsa_slot slot; struct ospf6_hook hook; memset (&slot, 0, sizeof (struct ospf6_lsa_slot)); slot.type = htons (OSPF6_LSA_TYPE_ROUTER); slot.name = "Router"; slot.func_show = ospf6_lsa_router_show; slot.func_refresh = ospf6_lsa_router_refresh; ospf6_lsa_slot_register (&slot); ospf6_lsdb_hook[OSPF6_LSA_TYPE_ROUTER & OSPF6_LSTYPE_CODE_MASK].hook = ospf6_spf_database_hook; memset (&hook, 0, sizeof (hook)); hook.name = "OriginateRouter"; hook.hook_change = ospf6_lsa_router_hook_neighbor; ospf6_hook_register (&hook, &neighbor_hook); memset (&hook, 0, sizeof (hook)); hook.name = "OriginateRouter"; hook.hook_change = ospf6_lsa_router_hook_interface; ospf6_hook_register (&hook, &interface_hook); memset (&hook, 0, sizeof (hook)); hook.name = "OriginateRouter"; hook.hook_change = ospf6_lsa_router_hook_area; ospf6_hook_register (&hook, &area_hook); memset (&hook, 0, sizeof (hook)); hook.name = "OriginateRouter"; hook.hook_change = ospf6_lsa_router_hook_top; ospf6_hook_register (&hook, &top_hook);}/*******************************//* RFC2740 3.4.3.2 Network-LSA *//*******************************/intospf6_lsa_network_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; struct ospf6_network_lsa *network_lsa; u_int32_t *router_id; char buf[128], options[32]; assert (lsa->header); network_lsa = (struct ospf6_network_lsa *) (lsa->header + 1); router_id = (u_int32_t *)(network_lsa + 1); ospf6_options_string (network_lsa->options, options, sizeof (options)); vty_out (vty, " Options: %s%s", options, VTY_NEWLINE); start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current + sizeof (u_int32_t) <= end; current += sizeof (u_int32_t)) { router_id = (u_int32_t *) current; inet_ntop (AF_INET, router_id, buf, sizeof (buf)); vty_out (vty, " Attached Router: %s%s", buf, VTY_NEWLINE); } return 0;}void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -