📄 ospf6_flood.c
字号:
/* (3) If the new LSA was received on this interface, and it was from DR or BDR, examin next interface */ if (from && from->ospf6_if == oi && (from->router_id == oi->drouter || from->router_id == oi->bdrouter)) { if (is_debug) zlog_info ("Received is from the I/F's DR or BDR, next interface"); return; } /* (4) If the new LSA was received on this interface, and the interface state is BDR, examin next interface */ if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR) { if (is_debug) zlog_info ("Received is from the I/F, itself BDR, next interface"); return; } /* (5) flood the LSA out the interface. */ if (is_debug) zlog_info ("Schedule flooding for the interface"); if (if_is_broadcast (oi->interface)) { ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list); if (oi->thread_send_lsupdate == NULL) oi->thread_send_lsupdate = thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0); } else { /* reschedule retransmissions to all neighbors */ for (node = listhead (oi->neighbor_list); node; nextnode (node)) { on = (struct ospf6_neighbor *) getdata (node); THREAD_OFF (on->thread_send_lsupdate); on->thread_send_lsupdate = thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0); } }}voidospf6_flood_area (struct ospf6_neighbor *from, struct ospf6_lsa *lsa, struct ospf6_area *oa){ listnode node; struct ospf6_interface *oi; for (node = listhead (oa->if_list); node; nextnode (node)) { oi = OSPF6_INTERFACE (getdata (node)); if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && oi != OSPF6_INTERFACE (lsa->lsdb->data)) continue;#if 0 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS && ospf6_is_interface_virtual_link (oi)) continue;#endif/*0*/ ospf6_flood_interface (from, lsa, oi); }}voidospf6_flood_process (struct ospf6_neighbor *from, struct ospf6_lsa *lsa, struct ospf6 *process){ listnode node; struct ospf6_area *oa; for (node = listhead (process->area_list); node; nextnode (node)) { oa = OSPF6_AREA (getdata (node)); if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA && oa != OSPF6_AREA (lsa->lsdb->data)) continue; if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && oa != OSPF6_INTERFACE (lsa->lsdb->data)->area) continue; if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && IS_AREA_STUB (oa)) continue; ospf6_flood_area (from, lsa, oa); }}voidospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa){ ospf6_flood_process (from, lsa, ospf6);}voidospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi){ listnode node; struct ospf6_neighbor *on; struct ospf6_lsa *rem; for (node = listhead (oi->neighbor_list); node; nextnode (node)) { on = OSPF6_NEIGHBOR (getdata (node)); rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id, lsa->header->adv_router, on->retrans_list); if (rem && ! ospf6_lsa_compare (rem, lsa)) { if (IS_OSPF6_DEBUG_FLOODING || IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) zlog_info ("Remove %s from retrans_list of %s", rem->name, on->name); ospf6_decrement_retrans_count (rem); ospf6_lsdb_remove (rem, on->retrans_list); } }}voidospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa){ listnode node; struct ospf6_interface *oi; for (node = listhead (oa->if_list); node; nextnode (node)) { oi = OSPF6_INTERFACE (getdata (node)); if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && oi != OSPF6_INTERFACE (lsa->lsdb->data)) continue;#if 0 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS && ospf6_is_interface_virtual_link (oi)) continue;#endif/*0*/ ospf6_flood_clear_interface (lsa, oi); }}voidospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process){ listnode node; struct ospf6_area *oa; for (node = listhead (process->area_list); node; nextnode (node)) { oa = OSPF6_AREA (getdata (node)); if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA && oa != OSPF6_AREA (lsa->lsdb->data)) continue; if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL && oa != OSPF6_INTERFACE (lsa->lsdb->data)->area) continue; if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL && IS_AREA_STUB (oa)) continue; ospf6_flood_clear_area (lsa, oa); }}voidospf6_flood_clear (struct ospf6_lsa *lsa){ ospf6_flood_clear_process (lsa, ospf6);}/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */static voidospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent, struct ospf6_neighbor *from){ struct ospf6_interface *oi; int is_debug = 0; if (IS_OSPF6_DEBUG_FLOODING || IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) is_debug++; assert (from && from->ospf6_if); oi = from->ospf6_if; /* LSA has been flood back out receiving interface. No acknowledgement sent. */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK)) { if (is_debug) zlog_info ("No acknowledgement (BDR & FloodBack)"); return; } /* LSA is more recent than database copy, but was not flooded back out receiving interface. Delayed acknowledgement sent if advertisement received from Designated Router, otherwide do nothing. */ if (ismore_recent < 0) { if (oi->drouter == from->router_id) { if (is_debug) zlog_info ("Delayed acknowledgement (BDR & MoreRecent & from DR)"); /* Delayed acknowledgement */ ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); if (oi->thread_send_lsack == NULL) oi->thread_send_lsack = thread_add_timer (master, ospf6_lsack_send_interface, oi, 3); } else { if (is_debug) zlog_info ("No acknowledgement (BDR & MoreRecent & ! from DR)"); } return; } /* LSA is a duplicate, and was treated as an implied acknowledgement. Delayed acknowledgement sent if advertisement received from Designated Router, otherwise do nothing */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) { if (oi->drouter == from->router_id) { if (is_debug) zlog_info ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)"); /* Delayed acknowledgement */ ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); if (oi->thread_send_lsack == NULL) oi->thread_send_lsack = thread_add_timer (master, ospf6_lsack_send_interface, oi, 3); } else { if (is_debug) zlog_info ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)"); } return; } /* LSA is a duplicate, and was not treated as an implied acknowledgement. Direct acknowledgement sent */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) { if (is_debug) zlog_info ("Direct acknowledgement (BDR & Duplicate)"); ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list); if (from->thread_send_lsack == NULL) from->thread_send_lsack = thread_add_event (master, ospf6_lsack_send_neighbor, from, 0); return; } /* LSA's LS age is equal to Maxage, and there is no current instance of the LSA in the link state database, and none of router's neighbors are in states Exchange or Loading */ /* Direct acknowledgement sent, but this case is handled in early of ospf6_receive_lsa () */}static voidospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent, struct ospf6_neighbor *from){ struct ospf6_interface *oi; int is_debug = 0; if (IS_OSPF6_DEBUG_FLOODING || IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type)) is_debug++; assert (from && from->ospf6_if); oi = from->ospf6_if; /* LSA has been flood back out receiving interface. No acknowledgement sent. */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK)) { if (is_debug) zlog_info ("No acknowledgement (AllOther & FloodBack)"); return; } /* LSA is more recent than database copy, but was not flooded back out receiving interface. Delayed acknowledgement sent. */ if (ismore_recent < 0) { if (is_debug) zlog_info ("Delayed acknowledgement (AllOther & MoreRecent)"); /* Delayed acknowledgement */ ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list); if (oi->thread_send_lsack == NULL) oi->thread_send_lsack = thread_add_timer (master, ospf6_lsack_send_interface, oi, 3); return; } /* LSA is a duplicate, and was treated as an implied acknowledgement. No acknowledgement sent. */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) { if (is_debug) zlog_info ("No acknowledgement (AllOther & Duplicate & ImpliedAck)"); return; } /* LSA is a duplicate, and was not treated as an implied acknowledgement. Direct acknowledgement sent */ if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) && ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK)) { if (is_debug) zlog_info ("Direct acknowledgement (AllOther & Duplicate)"); ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list); if (from->thread_send_lsack == NULL) from->thread_send_lsack = thread_add_event (master, ospf6_lsack_send_neighbor, from, 0); return; } /* LSA's LS age is equal to Maxage, and there is no current instance of the LSA in the link state database, and none of router's neighbors are in states Exchange or Loading */ /* Direct acknowledgement sent, but this case is handled in early of ospf6_receive_lsa () */}voidospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent, struct ospf6_neighbor *from){ struct ospf6_interface *oi; assert (from && from->ospf6_if); oi = from->ospf6_if; if (oi->state == OSPF6_INTERFACE_BDR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -