📄 ospf6_intra.c
字号:
/* * Copyright (C) 2003 Yasuhiro Ohara * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <zebra.h>#include "log.h"#include "linklist.h"#include "thread.h"#include "memory.h"#include "if.h"#include "prefix.h"#include "table.h"#include "vty.h"#include "command.h"#include "ospf6_proto.h"#include "ospf6_message.h"#include "ospf6_route.h"#include "ospf6_lsa.h"#include "ospf6_lsdb.h"#include "ospf6_top.h"#include "ospf6_area.h"#include "ospf6_interface.h"#include "ospf6_neighbor.h"#include "ospf6_intra.h"#include "ospf6_asbr.h"#include "ospf6_abr.h"#include "ospf6_flood.h"#include "ospf6d.h"/******************************//* RFC2740 3.4.3.1 Router-LSA *//******************************/intospf6_router_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; char buf[32], name[32], bits[16], options[32]; struct ospf6_router_lsa *router_lsa; struct ospf6_router_lsdesc *lsdesc; router_lsa = (struct ospf6_router_lsa *) ((char *) lsa->header + sizeof (struct ospf6_lsa_header)); ospf6_capability_printbuf (router_lsa->bits, bits, sizeof (bits)); ospf6_options_printbuf (router_lsa->options, options, sizeof (options)); vty_out (vty, " Bits: %s Options: %s%s", bits, options, VNL); 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_lsdesc) <= end; current += sizeof (struct ospf6_router_lsdesc)) { lsdesc = (struct ospf6_router_lsdesc *) current; if (lsdesc->type == OSPF6_ROUTER_LSDESC_POINTTOPOINT) snprintf (name, sizeof (name), "Point-To-Point"); else if (lsdesc->type == OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK) snprintf (name, sizeof (name), "Transit-Network"); else if (lsdesc->type == OSPF6_ROUTER_LSDESC_STUB_NETWORK) snprintf (name, sizeof (name), "Stub-Network"); else if (lsdesc->type == OSPF6_ROUTER_LSDESC_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), VNL); vty_out (vty, " Interface ID: %s%s", inet_ntop (AF_INET, &lsdesc->interface_id, buf, sizeof (buf)), VNL); vty_out (vty, " Neighbor Interface ID: %s%s", inet_ntop (AF_INET, &lsdesc->neighbor_interface_id, buf, sizeof (buf)), VNL); vty_out (vty, " Neighbor Router ID: %s%s", inet_ntop (AF_INET, &lsdesc->neighbor_router_id, buf, sizeof (buf)), VNL); } return 0;}intospf6_router_lsa_originate (struct thread *thread){ struct ospf6_area *oa; char buffer [OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; struct ospf6_lsa *lsa; u_int32_t link_state_id = 0; listnode i, j; struct ospf6_interface *oi; struct ospf6_neighbor *on, *drouter = NULL; struct ospf6_router_lsa *router_lsa; struct ospf6_router_lsdesc *lsdesc; u_int16_t type; u_int32_t router; int count; oa = (struct ospf6_area *) THREAD_ARG (thread); oa->thread_router_lsa = NULL; if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) zlog_info ("Originate Router-LSA for Area %s", oa->name); memset (buffer, 0, sizeof (buffer)); lsa_header = (struct ospf6_lsa_header *) buffer; router_lsa = (struct ospf6_router_lsa *) ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); 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); if (ospf6_is_router_abr (ospf6)) SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); else UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_B); if (ospf6_asbr_is_asbr (ospf6)) SET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); else UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_E); UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_V); UNSET_FLAG (router_lsa->bits, OSPF6_ROUTER_BIT_W); /* describe links for each interfaces */ lsdesc = (struct ospf6_router_lsdesc *) ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)); for (i = listhead (oa->if_list); i; nextnode (i)) { oi = (struct ospf6_interface *) getdata (i); /* Interfaces in state Down or Loopback are not described */ if (oi->state == OSPF6_INTERFACE_DOWN || oi->state == OSPF6_INTERFACE_LOOPBACK) continue; /* Nor are interfaces without any full adjacencies described */ count = 0; for (j = listhead (oi->neighbor_list); j; nextnode (j)) { on = (struct ospf6_neighbor *) getdata (j); if (on->state == OSPF6_NEIGHBOR_FULL) count++; } if (count == 0) continue; /* Multiple Router-LSA instance according to size limit setting */ if (oa->router_lsa_size_limit != 0 && (caddr_t) lsdesc + sizeof (struct ospf6_router_lsdesc) - (caddr_t) buffer > oa->router_lsa_size_limit) { if ((caddr_t) lsdesc == (caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)) { if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) zlog_info ("Size limit setting for Router-LSA too short"); return 0; } /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_ROUTER); lsa_header->id = htonl (link_state_id); 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) lsdesc - (caddr_t) buffer); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_area (lsa, oa); /* Reset setting for consecutive origination */ memset ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa), 0, (caddr_t) lsdesc - (caddr_t) router_lsa); lsdesc = (struct ospf6_router_lsdesc *) ((caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)); link_state_id ++; } /* Point-to-Point interfaces */ if (if_is_pointopoint (oi->interface)) { for (j = listhead (oi->neighbor_list); j; nextnode (j)) { on = (struct ospf6_neighbor *) getdata (j); if (on->state != OSPF6_NEIGHBOR_FULL) continue; lsdesc->type = OSPF6_ROUTER_LSDESC_POINTTOPOINT; lsdesc->metric = htons (oi->cost); lsdesc->interface_id = htonl (oi->interface->ifindex); lsdesc->neighbor_interface_id = htonl (on->ifindex); lsdesc->neighbor_router_id = on->router_id; lsdesc++; } } /* Broadcast and NBMA interfaces */ if (if_is_broadcast (oi->interface)) { /* If this router is not DR, and If this router not fully adjacent with DR, this interface is not transit yet: ignore. */ if (oi->state != OSPF6_INTERFACE_DR) { drouter = ospf6_neighbor_lookup (oi->drouter, oi); if (drouter == NULL || drouter->state != OSPF6_NEIGHBOR_FULL) continue; } lsdesc->type = OSPF6_ROUTER_LSDESC_TRANSIT_NETWORK; lsdesc->metric = htons (oi->cost); lsdesc->interface_id = htonl (oi->interface->ifindex); if (oi->state != OSPF6_INTERFACE_DR) { lsdesc->neighbor_interface_id = htonl (drouter->ifindex); lsdesc->neighbor_router_id = drouter->router_id; } else { lsdesc->neighbor_interface_id = htonl (oi->interface->ifindex); lsdesc->neighbor_router_id = oi->area->ospf6->router_id; } lsdesc++; } /* Virtual links */ /* xxx */ /* Point-to-Multipoint interfaces */ /* xxx */ } if ((caddr_t) lsdesc != (caddr_t) router_lsa + sizeof (struct ospf6_router_lsa)) { /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_ROUTER); lsa_header->id = htonl (link_state_id); 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) lsdesc - (caddr_t) buffer); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_area (lsa, oa); link_state_id ++; } else { if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER)) zlog_info ("Nothing to describe in Router-LSA, suppress"); } /* Do premature-aging of rest, undesired Router-LSAs */ type = ntohs (OSPF6_LSTYPE_ROUTER); router = oa->ospf6->router_id; for (lsa = ospf6_lsdb_type_router_head (type, router, oa->lsdb); lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa)) { if (ntohl (lsa->header->id) < link_state_id) continue; ospf6_lsa_purge (lsa); } return 0;}/*******************************//* RFC2740 3.4.3.2 Network-LSA *//*******************************/intospf6_network_lsa_show (struct vty *vty, struct ospf6_lsa *lsa){ char *start, *end, *current; struct ospf6_network_lsa *network_lsa; struct ospf6_network_lsdesc *lsdesc; char buf[128], options[32]; network_lsa = (struct ospf6_network_lsa *) ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); ospf6_options_printbuf (network_lsa->options, options, sizeof (options)); vty_out (vty, " Options: %s%s", options, VNL); start = (char *) network_lsa + sizeof (struct ospf6_network_lsa); end = (char *) lsa->header + ntohs (lsa->header->length); for (current = start; current + sizeof (struct ospf6_network_lsdesc) <= end; current += sizeof (struct ospf6_network_lsdesc)) { lsdesc = (struct ospf6_network_lsdesc *) current; inet_ntop (AF_INET, &lsdesc->router_id, buf, sizeof (buf)); vty_out (vty, " Attached Router: %s%s", buf, VNL); } return 0;}intospf6_network_lsa_originate (struct thread *thread){ struct ospf6_interface *oi; char buffer [OSPF6_MAX_LSASIZE]; struct ospf6_lsa_header *lsa_header; int count; struct ospf6_lsa *old, *lsa; struct ospf6_network_lsa *network_lsa; struct ospf6_network_lsdesc *lsdesc; struct ospf6_neighbor *on; struct ospf6_link_lsa *link_lsa; listnode i; u_int16_t type; oi = (struct ospf6_interface *) THREAD_ARG (thread); oi->thread_network_lsa = NULL; /* The interface must be enabled until here. A Network-LSA of a disabled interface (but was once enabled) should be flushed by ospf6_lsa_refresh (), and does not come here. */ assert (oi->area); old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_NETWORK), htonl (oi->interface->ifindex), oi->area->ospf6->router_id, oi->area->lsdb); /* Do not originate Network-LSA if not DR */ if (oi->state != OSPF6_INTERFACE_DR) { if (old) ospf6_lsa_purge (old); return 0; } if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) zlog_info ("Originate Network-LSA for Interface %s", oi->interface->name); /* If none of neighbor is adjacent to us */ count = 0; for (i = listhead (oi->neighbor_list); i; nextnode (i)) { on = (struct ospf6_neighbor *) getdata (i); if (on->state == OSPF6_NEIGHBOR_FULL) count++; } if (count == 0) { if (IS_OSPF6_DEBUG_ORIGINATE (NETWORK)) zlog_info ("Interface stub, ignore"); if (old) ospf6_lsa_purge (old); return 0; } /* prepare buffer */ memset (buffer, 0, sizeof (buffer)); lsa_header = (struct ospf6_lsa_header *) buffer; network_lsa = (struct ospf6_network_lsa *) ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header)); /* Collect the interface's Link-LSAs to describe network's optional capabilities */ type = htons (OSPF6_LSTYPE_LINK); for (lsa = ospf6_lsdb_type_head (type, oi->lsdb); lsa; lsa = ospf6_lsdb_type_next (type, lsa)) { link_lsa = (struct ospf6_link_lsa *) ((caddr_t) lsa->header + sizeof (struct ospf6_lsa_header)); network_lsa->options[0] |= link_lsa->options[0]; network_lsa->options[1] |= link_lsa->options[1]; network_lsa->options[2] |= link_lsa->options[2]; } lsdesc = (struct ospf6_network_lsdesc *) ((caddr_t) network_lsa + sizeof (struct ospf6_network_lsa)); /* set Link Description to the router itself */ lsdesc->router_id = oi->area->ospf6->router_id; lsdesc++; /* Walk through the neighbors */ for (i = listhead (oi->neighbor_list); i; nextnode (i)) { on = (struct ospf6_neighbor *) getdata (i); if (on->state != OSPF6_NEIGHBOR_FULL) continue; /* set this neighbor's Router-ID to LSA */ lsdesc->router_id = on->router_id; lsdesc++; } /* Fill LSA Header */ lsa_header->age = 0; lsa_header->type = htons (OSPF6_LSTYPE_NETWORK); 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->area->lsdb); lsa_header->length = htons ((caddr_t) lsdesc - (caddr_t) buffer); /* LSA checksum */ ospf6_lsa_checksum (lsa_header); /* create LSA */ lsa = ospf6_lsa_create (lsa_header); /* Originate */ ospf6_lsa_originate_area (lsa, oi->area); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -