struct isis_area * isis_area_create () { struct isis_area *area; area = calloc(1, sizeof (struct isis_area)); /* * The first instance is level-1-2 rest are level-1, unless otherwise * configured */ if (listcount (isis->area_list) > 0) area->is_type = IS_LEVEL_1; else area->is_type = IS_LEVEL_1_AND_2; /* * intialize the databases */ area->lspdb[0] = lsp_db_init (); area->lspdb[1] = lsp_db_init (); spftree_area_init (area); area->route_table[0] = route_table_init (); area->route_table[1] = route_table_init (); #ifdef ENABLE_IPV6 area->route_table6[0] = route_table_init (); area->route_table6[1] = route_table_init (); #endif /* ENABLE_IPV6 */ area->circuit_list = isis_list_new (); area->area_addrs = isis_list_new (); flags_initialize (&area->flags); /* * Default values */ area->max_lsp_lifetime[0] = MAX_AGE; /* 1200 */ area->max_lsp_lifetime[1] = MAX_AGE; /* 1200 */ area->lsp_gen_interval[0] = LSP_GEN_INTERVAL_DEFAULT; area->lsp_gen_interval[1] = LSP_GEN_INTERVAL_DEFAULT; area->lsp_refresh[0] = MAX_LSP_GEN_INTERVAL; /* 900 */ area->lsp_refresh[1] = MAX_LSP_GEN_INTERVAL; /* 900 */ area->min_spf_interval[0] = MINIMUM_SPF_INTERVAL; area->min_spf_interval[1] = MINIMUM_SPF_INTERVAL; area->dynhostname = 1; area->oldmetric = 1; area->lsp_frag_threshold = 90; /* FIXME: Think of a better way... */ area->min_bcast_mtu = 1497; return area; }
void isis_circuit_configure (struct isis_circuit *circuit, struct isis_area *area) { int i; circuit->area = area; /* * The level for the circuit is same as for the area, unless configured * otherwise. */ circuit->circuit_is_type = area->is_type; /* * Default values */ for (i = 0; i < 2; i++) { circuit->hello_interval[i] = HELLO_INTERVAL; circuit->hello_multiplier[i] = HELLO_MULTIPLIER; circuit->csnp_interval[i] = CSNP_INTERVAL; circuit->psnp_interval[i] = PSNP_INTERVAL; circuit->u.bc.priority[i] = DEFAULT_PRIORITY; } if (circuit->circ_type == CIRCUIT_T_BROADCAST) { circuit->u.bc.adjdb[0] = isis_list_new (); circuit->u.bc.adjdb[1] = isis_list_new (); circuit->u.bc.pad_hellos = 1; } circuit->lsp_interval = LSP_INTERVAL; /* * Add the circuit into area */ isis_listnode_add (area->circuit_list, circuit); circuit->idx = flags_get_index (&area->flags); circuit->lsp_queue = isis_list_new (); return; }
void isis_new (unsigned long process_id) { isis = calloc(1, sizeof (struct isis)); /* * Default values */ isis->max_area_addrs = 3; isis->process_id = process_id; isis->area_list = isis_list_new (); isis->init_circ_list = isis_list_new (); isis->uptime = time (NULL); isis->nexthops = isis_list_new (); #ifdef ENABLE_IPV6 isis->nexthops6 = isis_list_new (); #endif /* ENABLE_IPV6 */ /* * uncomment the next line for full debugs */ /* isis->debugs = 0xFFFF; */ }
void skinny_isis_daemon() { char errbuf[PCAP_ERRBUF_SIZE]; struct pcap_device device; struct pcap_isis_callback_data cb_data; struct host_addr addr; struct prefix_ipv4 *ipv4; struct plugin_requests req; int index, ret; char area_tag[] = "default"; struct isis_area *area; struct isis_circuit *circuit; struct interface interface; memset(&device, 0, sizeof(struct pcap_device)); memset(&cb_data, 0, sizeof(cb_data)); memset(&interface, 0, sizeof(interface)); memset(&isis_spf_deadline, 0, sizeof(isis_spf_deadline)); memset(&ime, 0, sizeof(ime)); memset(&req, 0, sizeof(req)); reload_map = FALSE; glob_isis_seq_num = 0; /* initializing IS-IS structures */ isis = NULL; isis_init(); dyn_cache_init(); /* thread master */ master = thread_master_create(); if (!config.nfacctd_isis_iface && !config.igp_daemon_map) { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): No 'isis_daemon_iface' and 'igp_daemon_map' values specified. Terminating thread.\n", config.name); exit_all(1); } else if (config.nfacctd_isis_iface && config.igp_daemon_map) { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): 'isis_daemon_iface' and 'igp_daemon_map' are mutually exclusive. Terminating thread.\n", config.name); exit_all(1); } if (config.nfacctd_isis_iface) { if ((device.dev_desc = pcap_open_live(config.nfacctd_isis_iface, 65535, 0, 1000, errbuf)) == NULL) { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): pcap_open_live(): %s\n", config.name, errbuf); exit(1); } device.link_type = pcap_datalink(device.dev_desc); for (index = 0; _isis_devices[index].link_type != -1; index++) { if (device.link_type == _isis_devices[index].link_type) device.data = &_isis_devices[index]; } if (device.data == NULL) { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): data link not supported: %d\n", config.name, device.link_type); return; } else { Log(LOG_INFO, "OK ( %s/core/ISIS ): link type is: %d\n", config.name, device.link_type); cb_data.device = &device; } } if (config.igp_daemon_map) { int igp_map_allocated = FALSE; glob_isis_seq_num++; req.key_value_table = (void *) &ime; memset(&sysid_fragment_table, 0, sizeof(sysid_fragment_table)); load_id_file(MAP_IGP, config.igp_daemon_map, NULL, &req, &igp_map_allocated); } area = isis_area_create(); area->area_tag = area_tag; area->is_type = IS_LEVEL_2; area->newmetric = TRUE; isis_listnode_add(isis->area_list, area); Log(LOG_DEBUG, "DEBUG ( %s/core/ISIS ): New IS-IS area instance %s\n", config.name, area->area_tag); if (config.nfacctd_isis_net) area_net_title(area, config.nfacctd_isis_net); else { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): 'isis_daemon_net' value is not specified. Terminating thread.\n", config.name); exit_all(1); } circuit = isis_circuit_new(); circuit->circ_type = CIRCUIT_T_P2P; if (config.nfacctd_isis_iface) { circuit->fd = pcap_fileno(device.dev_desc); circuit->tx = isis_send_pdu_p2p; } else { circuit->fd = 0; circuit->tx = NULL; } circuit->interface = &interface; circuit->state = C_STATE_UP; if (config.nfacctd_isis_ip) { trim_spaces(config.nfacctd_isis_ip); ret = str_to_addr(config.nfacctd_isis_ip, &addr); if (!ret) { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): 'isis_daemon_ip' value is not a valid IPv4/IPv6 address. Terminating thread.\n", config.name); exit_all(1); } } else { Log(LOG_ERR, "ERROR ( %s/core/ISIS ): 'isis_daemon_ip' value is not specified. Terminating thread.\n", config.name); exit_all(1); } circuit->ip_router = addr.address.ipv4.s_addr; ipv4 = isis_prefix_ipv4_new(); ipv4->prefixlen = 32; ipv4->prefix.s_addr = addr.address.ipv4.s_addr; circuit->ip_addrs = isis_list_new(); isis_listnode_add(circuit->ip_addrs, ipv4); circuit_update_nlpids(circuit); isis_circuit_configure(circuit, area); cb_data.circuit = circuit; area->ip_circuits = 1; if (config.nfacctd_isis_iface) { memcpy(circuit->interface->name, config.nfacctd_isis_iface, strlen(config.nfacctd_isis_iface)); circuit->interface->ifindex = if_nametoindex(config.nfacctd_isis_iface); } else { // XXX } if (!config.nfacctd_isis_mtu) config.nfacctd_isis_mtu = SNAPLEN_ISIS_DEFAULT; if (config.nfacctd_isis_iface) { for (;;) { /* XXX: should get a select() here at some stage? */ pcap_loop(device.dev_desc, -1, isis_pdu_runner, (u_char *) &cb_data); break; } pcap_close(device.dev_desc); } else if (config.igp_daemon_map) { for (;;) { sleep(3); if (reload_map) { int igp_map_allocated = FALSE; glob_isis_seq_num++; memset(&sysid_fragment_table, 0, sizeof(sysid_fragment_table)); load_id_file(MAP_IGP, config.igp_daemon_map, NULL, &req, &igp_map_allocated); reload_map = FALSE; } } } }