📄 ospf6_lsa.c
字号:
vty_out (vty, " "); snprintf (byte, sizeof (byte), "%02x", *current); vty_out (vty, "%s", byte); } vty_out (vty, "%s%s", VTY_NEWLINE, VTY_NEWLINE);}/* OSPFv3 LSA creation/deletion function *//* calculate LS sequence number for my new LSA. return value is network byte order */static signed longospf6_lsa_seqnum_new (u_int16_t type, u_int32_t id, u_int32_t adv_router, void *scope){ struct ospf6_lsa *lsa; signed long seqnum; /* get current database copy */ lsa = ospf6_lsdb_lookup (type, id, adv_router, scope); /* if current database copy not found, return InitialSequenceNumber */ if (!lsa) seqnum = INITIAL_SEQUENCE_NUMBER; else seqnum = (signed long) ntohl (lsa->header->seqnum) + 1; return (htonl (seqnum));}#if 0static voidospf6_lsa_header_set (u_int16_t type, u_int32_t ls_id, u_int32_t advrtr, struct ospf6_lsa_header *lsa_header, int bodysize){ /* fill LSA header */ lsa_header->age = 0; lsa_header->type = type; lsa_header->ls_id = ls_id; lsa_header->advrtr = advrtr; lsa_header->seqnum = ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id, lsa_header->advrtr); lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + bodysize); /* LSA checksum */ ospf6_lsa_checksum (lsa_header);}#endif /*0*/struct ospf6_lsa *ospf6_lsa_create (struct ospf6_lsa_header *source){ struct ospf6_lsa *lsa = NULL; struct ospf6_lsa_header *lsa_header = NULL; u_int16_t lsa_size = 0; char buf_router[16], buf_id[16], typebuf[32]; /* whole length of this LSA */ lsa_size = ntohs (source->length); /* allocate memory for this LSA */ lsa_header = (struct ospf6_lsa_header *) XMALLOC (MTYPE_OSPF6_LSA, lsa_size); if (! lsa_header) { zlog_err ("Can't allocate memory for LSA Header"); return (struct ospf6_lsa *) NULL; } memset (lsa_header, 0, lsa_size); /* copy LSA from source */ memcpy (lsa_header, source, lsa_size); /* LSA information structure */ /* allocate memory */ lsa = (struct ospf6_lsa *) XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa)); memset (lsa, 0, sizeof (struct ospf6_lsa)); lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header; lsa->header = (struct ospf6_lsa_header__ *) lsa_header; lsa->summary = 0; /* this is not LSA summary */ /* dump string */ inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id)); inet_ntop (AF_INET, &lsa->header->adv_router, buf_router, sizeof (buf_router)); snprintf (lsa->str, sizeof (lsa->str), "[%s ID=%s Adv=%s]", ospf6_lsa_type_string (lsa_header->type, typebuf, sizeof (typebuf)), buf_id, buf_router); /* calculate birth, expire and refresh of this lsa */ ospf6_lsa_age_set (lsa);#ifdef DEBUG if (IS_OSPF6_DUMP_LSA) zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);#endif /*DEBUG*/ return lsa;}struct ospf6_lsa *ospf6_lsa_summary_create (struct ospf6_lsa_header__ *source){ struct ospf6_lsa *lsa = NULL; struct ospf6_lsa_header *lsa_header = NULL; u_int16_t lsa_size = 0; char buf_router[16], buf_id[16], typebuf[16]; /* LSA summary contains LSA Header only */ lsa_size = sizeof (struct ospf6_lsa_header); /* allocate memory for this LSA */ lsa_header = (struct ospf6_lsa_header *) XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, lsa_size); memset (lsa_header, 0, lsa_size); /* copy LSA from source */ memcpy (lsa_header, source, lsa_size); /* LSA information structure */ /* allocate memory */ lsa = (struct ospf6_lsa *) XMALLOC (MTYPE_OSPF6_LSA_SUMMARY, sizeof (struct ospf6_lsa)); memset (lsa, 0, sizeof (struct ospf6_lsa)); lsa->lsa_hdr = (struct ospf6_lsa_hdr *) lsa_header; lsa->header = (struct ospf6_lsa_header__ *) lsa_header; lsa->summary = 1; /* this is LSA summary */ /* dump string */ inet_ntop (AF_INET, &lsa->header->id, buf_id, sizeof (buf_id)); inet_ntop (AF_INET, &lsa->header->adv_router, buf_router, sizeof (buf_router)); snprintf (lsa->str, sizeof (lsa->str), "[%s Summary ID=%s Adv=%s]", ospf6_lsa_type_string (lsa->header->type, typebuf, sizeof (typebuf)), buf_id, buf_router); /* calculate birth, expire and refresh of this lsa */ ospf6_lsa_age_set (lsa);#ifdef DEBUG if (IS_OSPF6_DUMP_LSA) zlog_info ("Create: %s (%p/%p)", lsa->str, lsa, lsa->header);#endif /*DEBUG*/ return lsa;}voidospf6_lsa_delete (struct ospf6_lsa *lsa){ /* just to make sure */ if (lsa->lock != 0) { zlog_err ("Can't delete %s: lock: %ld", lsa->str, lsa->lock); return; } /* cancel threads */ if (lsa->expire) thread_cancel (lsa->expire); lsa->expire = (struct thread *) NULL; if (lsa->refresh) thread_cancel (lsa->refresh); lsa->refresh = (struct thread *) NULL;#ifdef DEBUG if (IS_OSPF6_DUMP_LSA) zlog_info ("Delete %s (%p/%p)", lsa->str, lsa, lsa->header);#endif /*DEBUG*/ /* do free */ if (lsa->summary) XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa->header); else XFREE (MTYPE_OSPF6_LSA, lsa->header); lsa->header = NULL; if (lsa->summary) XFREE (MTYPE_OSPF6_LSA_SUMMARY, lsa); else XFREE (MTYPE_OSPF6_LSA, lsa);}/* 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 */ if (lsa->lock > 0) lsa->lock--; else zlog_warn ("Can't unlock %s: already no lock", lsa->str); if (lsa->lock == 0) ospf6_lsa_delete (lsa);}voidospf6_lsa_originate (u_int16_t type, u_int32_t id, u_int32_t adv_router, char *data, int data_len, void *scope){ char buffer[MAXLSASIZE]; struct ospf6_lsa_header *lsa_header; struct ospf6_lsa *lsa; struct ospf6_lsa *old; assert (data_len <= sizeof (buffer) - sizeof (struct ospf6_lsa_header)); lsa_header = (struct ospf6_lsa_header *) buffer; /* Copy LSA Body */ memcpy (buffer + sizeof (struct ospf6_lsa_header), data, data_len); /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = type; lsa_header->ls_id = id; lsa_header->advrtr = adv_router; lsa_header->seqnum = ospf6_lsa_seqnum_new (lsa_header->type, lsa_header->ls_id, lsa_header->advrtr, scope); lsa_header->length = htons (sizeof (struct ospf6_lsa_header) + data_len); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create ((struct ospf6_lsa_header *) buffer); lsa->scope = scope; /* find previous LSA */ old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, lsa->header->adv_router, lsa->scope); if (old) { /* Check if this is neither different instance nor refresh, return */ if (! CHECK_FLAG (old->flag, OSPF6_LSA_FLAG_REFRESH) && ! ospf6_lsa_differ (lsa, old)) { if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: Suppress updating %s", lsa->str); ospf6_lsa_delete (lsa); return; } } lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa, OSPF6_LS_REFRESH_TIME); gettimeofday (&lsa->originated, NULL); //if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: originate %s seq: %#x age: %hu %ld.%06ld", lsa->str, ntohl (lsa->header->seqnum), ospf6_lsa_age_current (lsa), lsa->originated.tv_sec, lsa->originated.tv_usec); ospf6_dbex_remove_from_all_retrans_list (lsa); ospf6_dbex_flood (lsa, NULL); ospf6_lsdb_install (lsa);}/* ospf6_lsa expired */intospf6_lsa_expire (struct thread *thread){ struct ospf6_lsa *lsa; struct ospf6_lsdb *lsdb = NULL; void (*hook) (struct ospf6_lsa *, struct ospf6_lsa *); lsa = (struct ospf6_lsa *) THREAD_ARG (thread); assert (lsa && lsa->lsa_hdr); /* assertion */ assert (IS_LSA_MAXAGE (lsa)); assert (!lsa->refresh); lsa->expire = (struct thread *) NULL; /* log */ if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: Expire: %s", lsa->str); if (!lsa->summary) { /* reflood lsa */ ospf6_dbex_flood (lsa, NULL); /* get scoped lsdb, call remove hook */ if (OSPF6_LSA_IS_SCOPE_LINKLOCAL (ntohs (lsa->header->type))) lsdb = ((struct ospf6_interface *) lsa->scope)->lsdb; else if (OSPF6_LSA_IS_SCOPE_AREA (ntohs (lsa->header->type))) lsdb = ((struct ospf6_area *) lsa->scope)->lsdb; else if (OSPF6_LSA_IS_SCOPE_AS (ntohs (lsa->header->type))) lsdb = ((struct ospf6 *) lsa->scope)->lsdb; else assert (0); /* call LSDB hook to re-process LSA */ hook = ospf6_lsdb_hook[ntohs (lsa->header->type) & OSPF6_LSTYPE_CODE_MASK].hook; if (hook) (*hook) (NULL, lsa); /* do not free LSA, and do nothing about lslists. wait event (ospf6_lsdb_check_maxage) */ } return 0;}intospf6_lsa_refresh (struct thread *thread){ struct ospf6_lsa *lsa; struct ospf6_lsa_slot *slot; assert (thread); lsa = (struct ospf6_lsa *) THREAD_ARG (thread); assert (lsa && lsa->lsa_hdr); /* this will be used later as flag to decide really originate */ lsa->refresh = (struct thread *) NULL; SET_FLAG (lsa->flag, OSPF6_LSA_FLAG_REFRESH); /* log */ if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA Refresh: %s", lsa->str); slot = ospf6_lsa_slot_get (lsa->header->type); if (slot) { zlog_info ("LSA Refresh: %s", slot->name); (*slot->func_refresh) (lsa); return 0; } zlog_warn ("Can't Refresh LSA: Unknown type: %#x", ntohs (lsa->header->type)); return 1;}/* 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 = (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);}intospf6_lsa_is_known_type (struct ospf6_lsa_header *lsa_header){ struct ospf6_lsa_slot *slot; slot = ospf6_lsa_slot_get (lsa_header->type); if (slot) return 1; return 0;}struct ospf6_lsa_slot *slot_head = NULL;struct ospf6_lsa_slot *ospf6_lsa_slot_get (u_int16_t type){ struct ospf6_lsa_slot *slot; for (slot = slot_head; slot; slot = slot->next) { if (slot->type == type) return slot; } return NULL;}intospf6_lsa_slot_register (struct ospf6_lsa_slot *src){ struct ospf6_lsa_slot *new, *slot; slot = ospf6_lsa_slot_get (src->type); if (slot) { if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: Slot register: already exists: %#x %s", slot->type, slot->name); return -1; } new = (struct ospf6_lsa_slot *) XMALLOC (MTYPE_OSPF6_LSA, sizeof (struct ospf6_lsa_slot)); if (! new) { zlog_err ("Can't allocate memory for LSA slot: %s", strerror (errno)); return -1; } memset (new, 0, sizeof (struct ospf6_lsa_slot)); memcpy (new, src, sizeof (struct ospf6_lsa_slot)); if (IS_OSPF6_DUMP_LSA) zlog_info ("LSA: Slot register: %#x %s", slot->type, slot->name); if (slot_head == NULL) { new->prev = NULL; new->next = NULL; slot_head = new; return 0; } slot = slot_head; while (slot->next) slot = slot->next; slot->next = new; new->prev = slot; return 0;}intospf6_lsa_slot_unregister (u_int16_t type){ struct ospf6_lsa_slot *slot; slot = ospf6_lsa_slot_get (type);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -