/* * Start routing on all virtual interfaces that are not down or * administratively disabled. */ void init_installvifs(void) { vifi_t vifi; struct uvif *v; logit(LOG_INFO, 0, "Installing vifs in kernel..."); 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))); } k_add_vif(vifi, &uvifs[vifi]); } else { logit(LOG_INFO, 0, "%s is not yet up; vif #%u not in service", v->uv_name, vifi); } } } }
/* * Initialize the vif and add to the kernel. The vif can be either * physical, register or tunnel (tunnels will be used in the future * when this code becomes PIM multicast boarder router. */ void start_vif (mifi_t vifi) { struct uvif *v; v = &uvifs[vifi]; /* Initialy no router on any vif */ if( v-> uv_flags & MIFF_REGISTER) v->uv_flags = v->uv_flags & ~VIFF_DOWN; else { v->uv_flags = (v->uv_flags | VIFF_NONBRS) & ~ VIFF_DOWN; v->uv_pim_hello_timer = 1 + RANDOM() % pim_hello_period; v->uv_jp_timer = 1 + RANDOM() % pim_join_prune_period; v->uv_genid = RANDOM() & 0xffffffff; } /* Tell kernel to add, i.e. start this vif */ k_add_vif(mld6_socket,vifi,&uvifs[vifi]); IF_DEBUG(DEBUG_IF) log_msg(LOG_DEBUG,0,"%s comes up ,vif #%u now in service",v->uv_name,vifi); if (!(v->uv_flags & MIFF_REGISTER)) { /* * Join the PIM multicast group on the interface. */ k_join(pim6_socket, &allpim6routers_group.sin6_addr, v->uv_ifindex); /* * Join the ALL-ROUTERS multicast group on the interface. * This allows mtrace requests to loop back if they are run * on the multicast router.this allow receiving mld6 messages too. */ k_join(mld6_socket, &allrouters_group.sin6_addr, v->uv_ifindex); /* * Until neighbors are discovered, assume responsibility for sending * periodic group membership queries to the subnet. Send the first * query. */ v->uv_flags |= VIFF_QUERIER; if (!v->uv_querier) { v->uv_querier = (struct listaddr *)malloc(sizeof(struct listaddr)); memset(v->uv_querier, 0, sizeof(struct listaddr)); } v->uv_querier->al_addr = v->uv_linklocal->pa_addr; v->uv_querier->al_timer = MLD6_OTHER_QUERIER_PRESENT_INTERVAL; time(&v->uv_querier->al_ctime); /* reset timestamp */ v->uv_stquery_cnt = MLD6_STARTUP_QUERY_COUNT; #ifdef HAVE_MLDV2 if (v->uv_mld_version & MLDv2) query_groupsV2(v); else #endif if (v->uv_mld_version & MLDv1) query_groups(v); /* * Send a probe via the new vif to look for neighbors. */ send_pim6_hello(v, pim_hello_holdtime); } }