📄 ospf6_lsa.c
字号:
XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa)); memset (lsa, 0, sizeof (struct ospf6_lsa)); lsa->header = (struct ospf6_lsa_header *) new_header; SET_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY); /* dump string */ ospf6_lsa_printbuf (lsa, lsa->name, sizeof (lsa->name)); /* calculate birth of this lsa */ ospf6_lsa_age_set (lsa); return lsa;}voidospf6_lsa_delete (struct ospf6_lsa *lsa){ assert (lsa->lock == 0); /* cancel threads */ THREAD_OFF (lsa->expire); THREAD_OFF (lsa->refresh); /* do free */ XFREE (MTYPE_OSPF6_LSA, lsa->header); XFREE (MTYPE_OSPF6_LSA, lsa);}struct ospf6_lsa *ospf6_lsa_copy (struct ospf6_lsa *lsa){ struct ospf6_lsa *copy = NULL; ospf6_lsa_age_current (lsa); if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY)) copy = ospf6_lsa_create_headeronly (lsa->header); else copy = ospf6_lsa_create (lsa->header); assert (copy->lock == 0); copy->birth = lsa->birth; copy->originated = lsa->originated; copy->received = lsa->received; copy->installed = lsa->installed; copy->lsdb = lsa->lsdb; return copy;}/* increment reference counter of struct ospf6_lsa */voidospf6_lsa_lock (struct ospf6_lsa *lsa){ lsa->lock++; return;}/* decrement reference counter of struct ospf6_lsa */voidospf6_lsa_unlock (struct ospf6_lsa *lsa){ /* decrement reference counter */ assert (lsa->lock > 0); lsa->lock--; if (lsa->lock != 0) return; ospf6_lsa_delete (lsa);}/* ospf6 lsa expiry */intospf6_lsa_expire (struct thread *thread){ struct ospf6_lsa *lsa; lsa = (struct ospf6_lsa *) THREAD_ARG (thread); assert (lsa && lsa->header); assert (OSPF6_LSA_IS_MAXAGE (lsa)); assert (! lsa->refresh); lsa->expire = (struct thread *) NULL; if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type)) { zlog_info ("LSA Expire:"); ospf6_lsa_header_print (lsa); } if (CHECK_FLAG (lsa->flag, OSPF6_LSA_HEADERONLY)) return 0; /* dbexchange will do something ... */ /* reflood lsa */ ospf6_flood (NULL, lsa); /* reinstall lsa */ ospf6_install_lsa (lsa); /* schedule maxage remover */ ospf6_maxage_remove (ospf6); return 0;}intospf6_lsa_refresh (struct thread *thread){ struct ospf6_lsa *old, *self, *new; struct ospf6_lsdb *lsdb_self; assert (thread); old = (struct ospf6_lsa *) THREAD_ARG (thread); assert (old && old->header); old->refresh = (struct thread *) NULL; lsdb_self = ospf6_get_scoped_lsdb_self (old); self = ospf6_lsdb_lookup (old->header->type, old->header->id, old->header->adv_router, lsdb_self); if (self == NULL) { if (IS_OSPF6_DEBUG_LSA_TYPE (old->header->type)) zlog_info ("Refresh: could not find self LSA, flush %s", old->name); ospf6_lsa_premature_aging (old); return 0; } /* Reset age, increment LS sequence number. */ self->header->age = htons (0); self->header->seqnum = ospf6_new_ls_seqnum (self->header->type, self->header->id, self->header->adv_router, old->lsdb); ospf6_lsa_checksum (self->header); new = ospf6_lsa_create (self->header); new->lsdb = old->lsdb; new->refresh = thread_add_timer (master, ospf6_lsa_refresh, new, LS_REFRESH_TIME); /* store it in the LSDB for self-originated LSAs */ ospf6_lsdb_add (ospf6_lsa_copy (new), lsdb_self); if (IS_OSPF6_DEBUG_LSA_TYPE (new->header->type)) { zlog_info ("LSA Refresh:"); ospf6_lsa_header_print (new); } ospf6_flood_clear (old); ospf6_flood (NULL, new); ospf6_install_lsa (new); return 0;}/* enhanced Fletcher checksum algorithm, RFC1008 7.2 */#define MODX 4102#define LSA_CHECKSUM_OFFSET 15unsigned shortospf6_lsa_checksum (struct ospf6_lsa_header *lsa_header){ u_char *sp, *ep, *p, *q; int c0 = 0, c1 = 0; int x, y; u_int16_t length; lsa_header->checksum = 0; length = ntohs (lsa_header->length) - 2; sp = (u_char *) &lsa_header->type; for (ep = sp + length; sp < ep; sp = q) { q = sp + MODX; if (q > ep) q = ep; for (p = sp; p < q; p++) { c0 += *p; c1 += c0; } c0 %= 255; c1 %= 255; } /* r = (c1 << 8) + c0; */ x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255; if (x <= 0) x += 255; y = 510 - c0 - x; if (y > 255) y -= 255; lsa_header->checksum = htons ((x << 8) + y); return (lsa_header->checksum);}voidospf6_lsa_init (){ ospf6_lsa_handler_vector = vector_init (0); ospf6_install_lsa_handler (&unknown_handler);}char *ospf6_lsa_handler_name (struct ospf6_lsa_handler *h){ static char buf[64]; int i, size = strlen (h->name); if (h->name == "Unknown" && h->type != OSPF6_LSTYPE_UNKNOWN) { snprintf (buf, sizeof (buf), "%#04hx", h->type); return buf; } for (i = 0; i < MIN (size, sizeof (buf)); i++) { if (! islower (h->name[i])) buf[i] = tolower (h->name[i]); else buf[i] = h->name[i]; } buf[size] = '\0'; return buf;}DEFUN (debug_ospf6_lsa_type, debug_ospf6_lsa_hex_cmd, "debug ospf6 lsa XXXX/0xXXXX", DEBUG_STR OSPF6_STR "Debug Link State Advertisements (LSAs)\n" "Specify LS type as Hexadecimal\n" ){ int i; struct ospf6_lsa_handler *handler = NULL; unsigned long val; char *endptr = NULL; u_int16_t type = 0; assert (argc); if ((strlen (argv[0]) == 6 && ! strncmp (argv[0], "0x", 2)) || (strlen (argv[0]) == 4)) { val = strtoul (argv[0], &endptr, 16); if (*endptr == '\0') type = val; } for (i = 0; i < vector_max (ospf6_lsa_handler_vector); i++) { handler = vector_slot (ospf6_lsa_handler_vector, i); if (handler == NULL) continue; if (type && handler->type == type) break; if (! strcasecmp (argv[0], handler->name)) break; handler = NULL; } if (type && handler == NULL) { handler = (struct ospf6_lsa_handler *) malloc (sizeof (struct ospf6_lsa_handler)); memset (handler, 0, sizeof (struct ospf6_lsa_handler)); handler->type = type; handler->name = "Unknown"; handler->show = ospf6_unknown_lsa_show; vector_set_index (ospf6_lsa_handler_vector, handler->type & OSPF6_LSTYPE_FCODE_MASK, handler); } if (handler == NULL) handler = &unknown_handler; if (argc >= 2) { if (! strcmp (argv[1], "originate")) SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); if (! strcmp (argv[1], "examin")) SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN); if (! strcmp (argv[1], "flooding")) SET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD); } else SET_FLAG (handler->debug, OSPF6_LSA_DEBUG); return CMD_SUCCESS;}DEFUN (no_debug_ospf6_lsa_type, no_debug_ospf6_lsa_hex_cmd, "no debug ospf6 lsa XXXX/0xXXXX", NO_STR DEBUG_STR OSPF6_STR "Debug Link State Advertisements (LSAs)\n" "Specify LS type as Hexadecimal\n" ){ int i; struct ospf6_lsa_handler *handler = NULL; unsigned long val; char *endptr = NULL; u_int16_t type = 0; assert (argc); if ((strlen (argv[0]) == 6 && ! strncmp (argv[0], "0x", 2)) || (strlen (argv[0]) == 4)) { val = strtoul (argv[0], &endptr, 16); if (*endptr == '\0') type = val; } for (i = 0; i < vector_max (ospf6_lsa_handler_vector); i++) { handler = vector_slot (ospf6_lsa_handler_vector, i); if (handler == NULL) continue; if (type && handler->type == type) break; if (! strcasecmp (argv[0], handler->name)) break; } if (handler == NULL) return CMD_SUCCESS; if (argc >= 2) { if (! strcmp (argv[1], "originate")) UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE); if (! strcmp (argv[1], "examin")) UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN); if (! strcmp (argv[1], "flooding")) UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD); } else UNSET_FLAG (handler->debug, OSPF6_LSA_DEBUG); if (handler->debug == 0 && handler->name == "Unknown" && type != OSPF6_LSTYPE_UNKNOWN) { free (handler); vector_slot (ospf6_lsa_handler_vector, i) = NULL; } return CMD_SUCCESS;}struct cmd_element debug_ospf6_lsa_type_cmd;struct cmd_element debug_ospf6_lsa_type_detail_cmd;struct cmd_element no_debug_ospf6_lsa_type_cmd;struct cmd_element no_debug_ospf6_lsa_type_detail_cmd;voidinstall_element_ospf6_debug_lsa (){ int i; struct ospf6_lsa_handler *handler;#define STRSIZE 256#define DOCSIZE 1024 static char strbuf[STRSIZE]; static char docbuf[DOCSIZE]; static char detail_strbuf[STRSIZE]; static char detail_docbuf[DOCSIZE]; char *str, *no_str; char *doc, *no_doc; strbuf[0] = '\0'; no_str = &strbuf[strlen (strbuf)]; strncat (strbuf, "no ", STRSIZE - strlen (strbuf)); str = &strbuf[strlen (strbuf)]; strncat (strbuf, "debug ospf6 lsa (", STRSIZE - strlen (strbuf)); for (i = 0; i < vector_max (ospf6_lsa_handler_vector); i++) { handler = vector_slot (ospf6_lsa_handler_vector, i); if (handler == NULL) continue; strncat (strbuf, ospf6_lsa_handler_name (handler), STRSIZE - strlen (strbuf)); strncat (strbuf, "|", STRSIZE - strlen (strbuf)); } strbuf[strlen (strbuf) - 1] = ')'; strbuf[strlen (strbuf)] = '\0'; docbuf[0] = '\0'; no_doc = &docbuf[strlen (docbuf)]; strncat (docbuf, NO_STR, DOCSIZE - strlen (docbuf)); doc = &docbuf[strlen (docbuf)]; strncat (docbuf, DEBUG_STR, DOCSIZE - strlen (docbuf)); strncat (docbuf, OSPF6_STR, DOCSIZE - strlen (docbuf)); strncat (docbuf, "Debug Link State Advertisements (LSAs)\n", DOCSIZE - strlen (docbuf)); for (i = 0; i < vector_max (ospf6_lsa_handler_vector); i++) { handler = vector_slot (ospf6_lsa_handler_vector, i); if (handler == NULL) continue; strncat (docbuf, "Debug ", DOCSIZE - strlen (docbuf)); strncat (docbuf, handler->name, DOCSIZE - strlen (docbuf)); strncat (docbuf, "-LSA\n", DOCSIZE - strlen (docbuf)); } docbuf[strlen (docbuf)] = '\0'; debug_ospf6_lsa_type_cmd.string = str; debug_ospf6_lsa_type_cmd.func = debug_ospf6_lsa_type; debug_ospf6_lsa_type_cmd.doc = doc; no_debug_ospf6_lsa_type_cmd.string = no_str; no_debug_ospf6_lsa_type_cmd.func = no_debug_ospf6_lsa_type; no_debug_ospf6_lsa_type_cmd.doc = no_doc; strncpy (detail_strbuf, strbuf, STRSIZE); strncat (detail_strbuf, " (originate|examin|flooding)", STRSIZE - strlen (detail_strbuf)); detail_strbuf[strlen (detail_strbuf)] = '\0'; no_str = &detail_strbuf[0]; str = &detail_strbuf[strlen ("no ")]; strncpy (detail_docbuf, docbuf, DOCSIZE); strncat (detail_docbuf, "Debug Originating LSA\n", DOCSIZE - strlen (detail_docbuf)); strncat (detail_docbuf, "Debug Examining LSA\n", DOCSIZE - strlen (detail_docbuf)); strncat (detail_docbuf, "Debug Flooding LSA\n", DOCSIZE - strlen (detail_docbuf)); detail_docbuf[strlen (detail_docbuf)] = '\0'; no_doc = &detail_docbuf[0]; doc = &detail_docbuf[strlen (NO_STR)]; debug_ospf6_lsa_type_detail_cmd.string = str; debug_ospf6_lsa_type_detail_cmd.func = debug_ospf6_lsa_type; debug_ospf6_lsa_type_detail_cmd.doc = doc; no_debug_ospf6_lsa_type_detail_cmd.string = no_str; no_debug_ospf6_lsa_type_detail_cmd.func = no_debug_ospf6_lsa_type; no_debug_ospf6_lsa_type_detail_cmd.doc = no_doc; install_element (ENABLE_NODE, &debug_ospf6_lsa_hex_cmd); install_element (ENABLE_NODE, &debug_ospf6_lsa_type_cmd); install_element (ENABLE_NODE, &debug_ospf6_lsa_type_detail_cmd); install_element (ENABLE_NODE, &no_debug_ospf6_lsa_hex_cmd); install_element (ENABLE_NODE, &no_debug_ospf6_lsa_type_cmd); install_element (ENABLE_NODE, &no_debug_ospf6_lsa_type_detail_cmd); install_element (CONFIG_NODE, &debug_ospf6_lsa_hex_cmd); install_element (CONFIG_NODE, &debug_ospf6_lsa_type_cmd); install_element (CONFIG_NODE, &debug_ospf6_lsa_type_detail_cmd); install_element (CONFIG_NODE, &no_debug_ospf6_lsa_hex_cmd); install_element (CONFIG_NODE, &no_debug_ospf6_lsa_type_cmd); install_element (CONFIG_NODE, &no_debug_ospf6_lsa_type_detail_cmd);}intconfig_write_ospf6_debug_lsa (struct vty *vty){ int i; struct ospf6_lsa_handler *handler; for (i = 0; i < vector_max (ospf6_lsa_handler_vector); i++) { handler = vector_slot (ospf6_lsa_handler_vector, i); if (handler == NULL) continue; if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG)) vty_out (vty, "debug ospf6 lsa %s%s", ospf6_lsa_handler_name (handler), VNL); if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_ORIGINATE)) vty_out (vty, "debug ospf6 lsa %s originate%s", ospf6_lsa_handler_name (handler), VNL); if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_EXAMIN)) vty_out (vty, "debug ospf6 lsa %s examin%s", ospf6_lsa_handler_name (handler), VNL); if (CHECK_FLAG (handler->debug, OSPF6_LSA_DEBUG_FLOOD)) vty_out (vty, "debug ospf6 lsa %s flooding%s", ospf6_lsa_handler_name (handler), VNL); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -