/* * Initialize the virtual interfaces, but do not install * them in the kernel. Start routing on all vifs that are * not down or disabled. */ void init_vifs(void) { vifi_t vifi; struct uvif *v; int enabled_vifs, enabled_phyints; extern char *configfilename; numvifs = 0; vifs_with_neighbors = 0; vifs_down = FALSE; /* * Configure the vifs based on the interface configuration of the * the kernel and the contents of the configuration file. * (Open a UDP socket for ioctl use in the config procedures if * the kernel can't handle IOCTL's on the IGMP socket.) */ #ifdef IOCTL_OK_ON_RAW_SOCKET udp_socket = igmp_socket; #else if ((udp_socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) logit(LOG_ERR, errno, "UDP socket"); #endif logit(LOG_INFO,0,"Getting vifs from kernel interfaces"); config_vifs_from_kernel(); logit(LOG_INFO,0,"Getting vifs from %s",configfilename); config_vifs_from_file(); /* * Quit if there are fewer than two enabled vifs. */ enabled_vifs = 0; enabled_phyints = 0; phys_vif = -1; for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (!(v->uv_flags & VIFF_DISABLED)) { ++enabled_vifs; if (!(v->uv_flags & VIFF_TUNNEL)) { if (phys_vif == -1) phys_vif = vifi; ++enabled_phyints; } } } if (enabled_vifs < 2) logit(LOG_ERR, 0, "Cannot forward: %s", enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif"); if (enabled_phyints == 0) logit(LOG_WARNING, 0, "No enabled interfaces, forwarding via tunnels only"); logit(LOG_INFO, 0, "Installing vifs in mrouted ..."); for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { if (!(v->uv_flags & VIFF_DISABLED)) { if (!(v->uv_flags & VIFF_DOWN)) { if (v->uv_flags & VIFF_TUNNEL) logit(LOG_INFO, 0, "vif #%d, tunnel %s -> %s", vifi, inet_fmt(v->uv_lcl_addr, s1, sizeof(s1)), inet_fmt(v->uv_rmt_addr, s2, sizeof(s2))); else logit(LOG_INFO, 0, "vif #%d, phyint %s", vifi, inet_fmt(v->uv_lcl_addr, s1, sizeof(s1))); start_vif2(vifi); } else { logit(LOG_INFO, 0, "%s is not yet up; vif #%u not in service", v->uv_name, vifi); } } } }
void init_vifs() { mifi_t vifi; struct uvif *v; int enabled_vifs; numvifs = 0; reg_vif_num = NO_VIF; /* * Configure the vifs based on the interface configuration of * the kernel and the contents of the configuration file. * (Open a UDP socket for ioctl use in the config procedures if * the kernel can't handle IOCTL's on the MLD socket.) */ #ifdef IOCTL_OK_ON_RAW_SOCKET udp_socket = mld6_socket; #else if ((udp_socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) log_msg(LOG_ERR, errno, "UDP6 socket"); #endif /* clean all the interfaces ... */ for (vifi = 0, v = uvifs; vifi < MAXMIFS; ++vifi, ++v) { memset(v, 0, sizeof(*v)); v->uv_metric = DEFAULT_METRIC; v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT; #ifdef HAVE_STRLCPY strlcpy(v->uv_name, "", IFNAMSIZ); #elif HAVE_STRNCPY strncpy(v->uv_name, "", IFNAMSIZ); #else strcpy(v->uv_name, ""); #endif v->uv_local_pref = default_source_preference; v->uv_local_metric = default_source_metric; v->uv_priority = PIM_DEFAULT_DR_PRIORITY; v->uv_mld_version = MLD6_DEFAULT_VERSION; v->uv_mld_robustness = MLD6_DEFAULT_ROBUSTNESS_VARIABLE; v->uv_mld_query_interval = MLD6_DEFAULT_QUERY_INTERVAL; v->uv_mld_query_rsp_interval = MLD6_DEFAULT_QUERY_RESPONSE_INTERVAL; v->uv_mld_llqi = MLD6_DEFAULT_LAST_LISTENER_QUERY_INTERVAL; } IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG, 0, "Interfaces world initialized..."); IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG, 0, "Getting vifs from %s", configfilename); /* read config from file */ if (cfparse(1, 0) != 0) log_msg(LOG_ERR, 0, "fatal error in parsing the config file"); enabled_vifs = 0; phys_vif = -1; IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG, 0, "Getting vifs from kernel"); config_vifs_from_kernel(); /* IPv6 PIM needs one global unicast address (at least for now) */ if (max_global_address() == NULL) log_msg(LOG_ERR, 0, "There's no global address available"); for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { struct phaddr *p; if (v->uv_flags & (VIFF_DISABLED | MIFF_REGISTER)) continue; enabled_vifs++; if (v->uv_flags & VIFF_DOWN) continue; if (v->uv_linklocal == NULL) log_msg(LOG_ERR, 0, "there is no link-local address on vif %s", v->uv_name); /* If this vif has a global address, set its id to phys_vif */ if (phys_vif != -1) continue; for (p = v->uv_addrs; p; p = p->pa_next) { if (!IN6_IS_ADDR_LINKLOCAL(&p->pa_addr.sin6_addr)) { phys_vif = vifi; break; } } } if (enabled_vifs < 2) log_msg(LOG_ERR, 0, "can't forward: %s", enabled_vifs == 0 ? "no enabled vifs" : "only one enabled vif"); memset(&if_nullset, 0, sizeof(if_nullset)); k_init_pim(mld6_socket); IF_DEBUG(DEBUG_PIM_DETAIL) log_msg(LOG_DEBUG, 0, "Pim kernel initialization done"); /* Add a dummy virtual interface to support Registers in the kernel. */ init_reg_vif(); start_all_vifs(); }