📄 ospf6_intra.c
字号:
/****************************//* RFC2740 3.4.3.6 Link-LSA *//****************************/intospf6_link_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; struct ospf6_link_lsa *link_lsa; int prefixnum; char buf[128], options[32]; struct ospf6_prefix *prefix; char *p, *mc, *la, *nu; struct in6_addr in6; link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); ospf6_options_printbuf (link_lsa->options, options, sizeof (options)); inet_ntop (AF_INET6, &link_lsa->linklocal_addr, buf, sizeof (buf)); prefixnum = ntohl (link_lsa->prefix_num); vty_out (vty, " Priority: %d Options: %s%s", link_lsa->priority, options, VNL); vty_out (vty, " LinkLocal Address: %s%s", buf, VNL); vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL); start = (char *) link_lsa + sizeof (struct ospf6_link_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) { prefix = (struct ospf6_prefix *) current; if (prefix->prefix_length == 0 || current + OSPF6_PREFIX_SIZE (prefix) > end) break; p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? "P" : "--"); mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? "MC" : "--"); la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? "LA" : "--"); nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? "NU" : "--"); vty_out (vty, " Prefix Options: %s|%s|%s|%s%s", p, mc, la, nu, VNL); memset (&in6, 0, sizeof (in6)); memcpy (&in6, OSPF6_PREFIX_BODY (prefix), OSPF6_PREFIX_SPACE (prefix->prefix_length)); inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); vty_out (vty, " Prefix: %s/%d%s", buf, prefix->prefix_length, VNL); } return 0;}intospf6_link_lsa_originate (struct thread *thread){ struct ospf6_interface *oi; char buffer[OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; struct ospf6_lsa *old, *lsa; struct ospf6_link_lsa *link_lsa; struct ospf6_route *route; struct ospf6_prefix *op; oi = (struct ospf6_interface *) THREAD_ARG (thread); oi->thread_link_lsa = NULL; assert (oi->area); /* find previous LSA */ old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_LINK), htonl (oi->interface->ifindex), oi->area->ospf6->router_id, oi->lsdb); if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) { if (old) ospf6_lsa_purge (old); return 0; } if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) zlog_info ("Originate Link-LSA for Interface %s", oi->interface->name); /* can't make Link-LSA if linklocal address not set */ if (oi->linklocal_addr == NULL) { if (IS_OSPF6_DEBUG_ORIGINATE (LINK)) zlog_info ("No Linklocal address on %s, defer originating", oi->interface->name); if (old) ospf6_lsa_purge (old); return 0; } /* prepare buffer */ memset (buffer, 0, sizeof (buffer)); lsa_header = (struct ospf6_lsa_header *) buffer; link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); /* Fill Link-LSA */ link_lsa->priority = oi->priority; memcpy (link_lsa->options, oi->area->options, 3); memcpy (&link_lsa->linklocal_addr, oi->linklocal_addr, sizeof (struct in6_addr)); link_lsa->prefix_num = htonl (oi->route_connected->count); op = (struct ospf6_prefix *) ((caddr_t) link_lsa + sizeof (struct ospf6_link_lsa)); /* connected prefix to advertise */ for (route = ospf6_route_head (oi->route_connected); route; route = ospf6_route_next (route)) { op->prefix_length = route->prefix.prefixlen; op->prefix_options = route->path.prefix_options; op->prefix_metric = htons (0); memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, OSPF6_PREFIX_SPACE (op->prefix_length)); op = OSPF6_PREFIX_NEXT (op); } /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_LINK); lsa_header->id = htonl (oi->interface->ifindex); lsa_header->adv_router = oi->area->ospf6->router_id; lsa_header->seqnum = ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, lsa_header->adv_router, oi->lsdb); lsa_header->length = htons ((caddr_t) op - (caddr_t) buffer); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_interface (lsa, oi); return 0;}/*****************************************//* RFC2740 3.4.3.7 Intra-Area-Prefix-LSA *//*****************************************/intospf6_intra_prefix_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; struct ospf6_intra_prefix_lsa *intra_prefix_lsa; int prefixnum; char buf[128]; struct ospf6_prefix *prefix; char id[16], adv_router[16]; char *p, *mc, *la, *nu; struct in6_addr in6; intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); prefixnum = ntohs (intra_prefix_lsa->prefix_num); vty_out (vty, " Number of Prefix: %d%s", prefixnum, VNL); inet_ntop (AF_INET, &intra_prefix_lsa->ref_id, id, sizeof (id)); inet_ntop (AF_INET, &intra_prefix_lsa->ref_adv_router, adv_router, sizeof (adv_router)); vty_out (vty, " Reference: %s Id: %s Adv: %s%s", ospf6_lstype_name (intra_prefix_lsa->ref_type), id, adv_router, VNL); start = (char *) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current < end; current += OSPF6_PREFIX_SIZE (prefix)) { prefix = (struct ospf6_prefix *) current; if (prefix->prefix_length == 0 || current + OSPF6_PREFIX_SIZE (prefix) > end) break; p = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_P) ? "P" : "--"); mc = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_MC) ? "MC" : "--"); la = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_LA) ? "LA" : "--"); nu = (CHECK_FLAG (prefix->prefix_options, OSPF6_PREFIX_OPTION_NU) ? "NU" : "--"); vty_out (vty, " Prefix Options: %s|%s|%s|%s%s", p, mc, la, nu, VNL); memset (&in6, 0, sizeof (in6)); memcpy (&in6, OSPF6_PREFIX_BODY (prefix), OSPF6_PREFIX_SPACE (prefix->prefix_length)); inet_ntop (AF_INET6, &in6, buf, sizeof (buf)); vty_out (vty, " Prefix: %s/%d%s", buf, prefix->prefix_length, VNL); } return 0;}intospf6_intra_prefix_lsa_originate_stub (struct thread *thread){ struct ospf6_area *oa; char buffer[OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; struct ospf6_lsa *old, *lsa; struct ospf6_intra_prefix_lsa *intra_prefix_lsa; struct ospf6_interface *oi; struct ospf6_neighbor *on; struct ospf6_route *route; struct ospf6_prefix *op; listnode i, j; int full_count = 0; unsigned short prefix_num = 0; char buf[BUFSIZ]; struct ospf6_route_table *route_advertise; oa = (struct ospf6_area *) THREAD_ARG (thread); oa->thread_intra_prefix_lsa = NULL; /* find previous LSA */ old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX), htonl (0), oa->ospf6->router_id, oa->lsdb); if (! IS_AREA_ENABLED (oa)) { if (old) ospf6_lsa_purge (old); return 0; } if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info ("Originate Intra-Area-Prefix-LSA for area %s's stub prefix", oa->name); /* prepare buffer */ memset (buffer, 0, sizeof (buffer)); lsa_header = (struct ospf6_lsa_header *) buffer; intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_ROUTER); intra_prefix_lsa->ref_id = htonl (0); intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id; route_advertise = ospf6_route_table_create (); for (i = listhead (oa->if_list); i; nextnode (i)) { oi = (struct ospf6_interface *) getdata (i); if (oi->state == OSPF6_INTERFACE_DOWN) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Interface %s is down, ignore", oi->interface->name); continue; } full_count = 0; for (j = listhead (oi->neighbor_list); j; nextnode (j)) { on = (struct ospf6_neighbor *) getdata (j); if (on->state == OSPF6_NEIGHBOR_FULL) full_count++; } if (oi->state != OSPF6_INTERFACE_LOOPBACK && oi->state != OSPF6_INTERFACE_POINTTOPOINT && full_count != 0) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Interface %s is not stub, ignore", oi->interface->name); continue; } if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Interface %s:", oi->interface->name); /* connected prefix to advertise */ for (route = ospf6_route_head (oi->route_connected); route; route = ospf6_route_best_next (route)) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) { prefix2str (&route->prefix, buf, sizeof (buf)); zlog_info (" include %s", buf); } ospf6_route_add (ospf6_route_copy (route), route_advertise); } } if (route_advertise->count == 0) { if (old) ospf6_lsa_purge (old); ospf6_route_table_delete (route_advertise); return 0; } /* put prefixes to advertise */ prefix_num = 0; op = (struct ospf6_prefix *) ((caddr_t) intra_prefix_lsa + sizeof (struct ospf6_intra_prefix_lsa)); for (route = ospf6_route_head (route_advertise); route; route = ospf6_route_best_next (route)) { op->prefix_length = route->prefix.prefixlen; op->prefix_options = route->path.prefix_options; op->prefix_metric = htons (route->path.cost); memcpy (OSPF6_PREFIX_BODY (op), &route->prefix.u.prefix6, OSPF6_PREFIX_SPACE (op->prefix_length)); op = OSPF6_PREFIX_NEXT (op); prefix_num++; } ospf6_route_table_delete (route_advertise); if (prefix_num == 0) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info ("Quit to Advertise Intra-Prefix: no route to advertise"); return 0; } intra_prefix_lsa->prefix_num = htons (prefix_num); /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_INTRA_PREFIX); lsa_header->id = htonl (0); lsa_header->adv_router = oa->ospf6->router_id; lsa_header->seqnum = ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id, lsa_header->adv_router, oa->lsdb); lsa_header->length = htons ((caddr_t) op - (caddr_t) lsa_header); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_area (lsa, oa); return 0;}intospf6_intra_prefix_lsa_originate_transit (struct thread *thread){ struct ospf6_interface *oi; char buffer[OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; struct ospf6_lsa *old, *lsa; struct ospf6_intra_prefix_lsa *intra_prefix_lsa; struct ospf6_neighbor *on; struct ospf6_route *route; struct ospf6_prefix *op; listnode i; int full_count = 0; unsigned short prefix_num = 0; struct ospf6_route_table *route_advertise; struct ospf6_link_lsa *link_lsa; char *start, *end, *current; u_int16_t type; char buf[BUFSIZ]; oi = (struct ospf6_interface *) THREAD_ARG (thread); oi->thread_intra_prefix_lsa = NULL; assert (oi->area); /* find previous LSA */ old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_INTRA_PREFIX), htonl (oi->interface->ifindex), oi->area->ospf6->router_id, oi->area->lsdb); if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) { if (old) ospf6_lsa_purge (old); return 0; } if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info ("Originate Intra-Area-Prefix-LSA for interface %s's prefix", oi->interface->name); /* prepare buffer */ memset (buffer, 0, sizeof (buffer)); lsa_header = (struct ospf6_lsa_header *) buffer; intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons (OSPF6_LSTYPE_NETWORK); intra_prefix_lsa->ref_id = htonl (oi->interface->ifindex); intra_prefix_lsa->ref_adv_router = oi->area->ospf6->router_id; if (oi->state != OSPF6_INTERFACE_DR) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Interface is not DR"); if (old) ospf6_lsa_purge (old); return 0; } full_count = 0; for (i = listhead (oi->neighbor_list); i; nextnode (i)) { on = (struct ospf6_neighbor *) getdata (i); if (on->state == OSPF6_NEIGHBOR_FULL) full_count++; } if (full_count == 0) { if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX)) zlog_info (" Interface is stub"); if (old) ospf6_lsa_purge (old); return 0; } /* connected prefix to advertise */ route_advertise = ospf6_route_table_create (); type = ntohs (OSPF6_LSTYPE_LINK); for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; lsa = ospf6_lsdb_type_next (type, lsa)) { if (OSPF6_LSA_IS_MAXAGE (lsa)) continue; if (IS_OSPF6_DEBUG_ORIGINATE (INTRA_PREFIX))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -