Ejemplo n.º 1
0
static int prefha_iterator(void *data, void *args,
	     struct in6_addr *addr, 
	     unsigned long *pref)
{
	struct mipv6_halist_entry *entry =
		(struct mipv6_halist_entry *)data;
	struct prefha_iterator_args *state =
		(struct prefha_iterator_args *)args;

	if (mipv6_prefix_compare(&entry->global_addr, &state->prefix, state->plen)) {
		state->entry = entry;
		return ITERATOR_STOP;
	}
	return ITERATOR_CONT;
}
Ejemplo n.º 2
0
/**
 * mn_handoff - called for every bul entry to send BU to CN
 * @rawentry: bul entry
 * @args: handoff event
 * @hashkey:
 * @sortkey:
 *
 * Since MN can have many home addresses and home networks, every BUL entry 
 * needs to be checked   
 **/
static int mn_handoff(void *rawentry, void *args,
		 struct in6_addr *hashkey,
		 unsigned long *sortkey)
{
	__u32 lifetime;
	int athome;
	struct mipv6_bul_entry *entry = (struct mipv6_bul_entry *)rawentry;
	struct handoff *ho = (struct handoff *)args;
	int pfixlen = 64; /* Get the prefixlength instead of fixed 64 bits */
	athome = mipv6_prefix_compare(&ho->rtr_new.raddr, &entry->home_addr, 
				      pfixlen);

	if (!athome) {
		lifetime = mipv6_mn_get_bulifetime(&entry->home_addr, 
						   &ho->rtr_new.CoA,
						   entry->flags);
	}
	else {
		lifetime = 0;
		entry->flags = entry->flags | MIPV6_BU_F_DEREG;
	}

	if (entry->flags & MIPV6_BU_F_HOME) {
		DEBUG((DBG_INFO, "Sending home de ? %d registration for "
		       "home address: %x:%x:%x:%x:%x:%x:%x:%x\n" 
		       "to home agent %x:%x:%x:%x:%x:%x:%x:%x, "
		       "with lifetime %ld, prefixlength %d", athome,  
		       NIPV6ADDR(&entry->home_addr), 
		       NIPV6ADDR(&entry->cn_addr), lifetime, entry->prefix));
		mipv6_send_upd_option(
			&entry->home_addr, &entry->cn_addr, HA_BU_DELAY, 
			INITIAL_BINDACK_TIMEOUT, MAX_BINDACK_TIMEOUT, 1,
			entry->flags, entry->prefix, lifetime, NULL);
	}
	else {
		DEBUG((DBG_INFO, "Sending BU for home address: %x:%x:%x:%x:%x:%x:%x:%x \n" 
		       "to CN: %x:%x:%x:%x:%x:%x:%x:%x, "
		       "with lifetime %ld",   NIPV6ADDR(&entry->home_addr), 
		       NIPV6ADDR(&entry->cn_addr), lifetime));
		mipv6_send_upd_option(
			&entry->home_addr, &entry->cn_addr, CN_BU_DELAY, 
			INITIAL_BINDACK_TIMEOUT, MAX_BINDACK_TIMEOUT, 1,
			entry->flags, entry->prefix, lifetime, NULL);
	}

	return ITERATOR_CONT;
}
Ejemplo n.º 3
0
/**
 * init_home_registration - start Home Registration process
 * @hinfo: mn_info entry for the home address
 * @coa: care-of address
 *
 * Checks whether we have a Home Agent address for this home address.
 * If not starts Dynamic Home Agent Address Discovery.  Otherwise
 * tries to register with home agent if not already registered.
 **/
int init_home_registration(struct mn_info *hinfo, struct in6_addr *coa)
{
	__u32 lifetime;

	if (mipv6_prefix_compare(&hinfo->home_addr, coa, hinfo->home_plen)) { 
		hinfo->is_at_home = 1;
		DEBUG((DBG_INFO, "Adding home address, MN at home"));
		return 0;
	}

	if (ipv6_addr_any(&hinfo->ha)) {
		DEBUG((DBG_INFO, "Home Agent address not set, initiating DHAAD"));
		mipv6_mn_dhaad_send_req(&hinfo->home_addr, hinfo->home_plen, &hinfo->dhaad_id);
	} else {
		struct mipv6_bul_entry *bul = mipv6_bul_get(&hinfo->ha);
		if (bul) {
			if (!ipv6_addr_cmp(&bul->home_addr, &hinfo->home_addr)){
				DEBUG((DBG_INFO, "BU already sent to HA"));
				mipv6_bul_put(bul);
				return 0;
			}
			mipv6_bul_put(bul);
		}
		lifetime = mipv6_mn_get_bulifetime(
			&hinfo->home_addr, coa, 
			MIPV6_BU_F_HOME | MIPV6_BU_F_ACK);
		DEBUG((DBG_INFO, "Sending initial home registration for "
		       "home address: %x:%x:%x:%x:%x:%x:%x:%x\n" 
		       "to home agent %x:%x:%x:%x:%x:%x:%x:%x, "
		       "with lifetime %ld, prefixlength %d",   
		       NIPV6ADDR(&hinfo->home_addr), 
		       NIPV6ADDR(&hinfo->ha), lifetime, 0));
		mipv6_send_upd_option(
			&hinfo->home_addr, &hinfo->ha, 
			HA_BU_DELAY, 
			INITIAL_BINDACK_DAD_TIMEOUT, 
			MAX_BINDACK_TIMEOUT, 1,
			MIPV6_BU_F_HOME | MIPV6_BU_F_ACK | MIPV6_BU_F_DAD, 
			0, lifetime, NULL);
	}
	return 0;
}
Ejemplo n.º 4
0
/**
 * mipv6_mobile_node_moved - Sends BUs to all HAs and CNs
 * @ho: handoff structure contains the new and previous routers
 **/  
int mipv6_mobile_node_moved(struct handoff *ho)
{
	struct mn_info *hinfo = NULL;
	unsigned long lifetime = 1234;
	int bu_to_prev_router = 1;
	int dummy;

	DEBUG_FUNC();
	if (!mipv6_is_initialized)
		return 0;

	ma_ctl_upd_iface(ho->rtr_new.ifindex, 
			 MA_IFACE_CURRENT | MA_IFACE_HAS_ROUTER, &dummy);

	/* First send BUs to all nodes which are on BU list */
	bul_iterate(mn_handoff, (void *)ho);

	/* Then go through the home infos to see if there's a new one
	 * which has not been registered
	 */
	/* TODO: Should the previous router acting as a HA and the
	 * previous CoA be also added to the mn_info list
	 */
	read_lock_bh(&mn_info_lock);
	for (hinfo = mn_info_base; hinfo; hinfo = hinfo->next) {
		if (mipv6_prefix_compare(&hinfo->home_addr, 
					&ho->rtr_new.raddr, 
					 hinfo->home_plen)) {
			if (!hinfo->is_at_home) 
				hinfo->is_at_home = 1;
		}
		else {
			hinfo->is_at_home = 0;
			if (!hinfo->has_home_reg) {
				init_home_registration(hinfo, 
						       &ho->rtr_new.CoA);
			}
		}
		/* Check here whether the previous CoA is in fact a regular 
		 * home address, which is being registered in any case
		 * TODO: Add a mn_info for the previous router and purge it 
		 * or do DHAAD after the lifetime of the HA expires. Remove the
		 * comparison between home agent address and prev. router address 
		 * after bul can handle multiple entries for same CN!
		 */
		if (ho->has_rtr_prev && (!ipv6_addr_cmp(&hinfo->home_addr, 
							&ho->rtr_prev.CoA) || 
					 !ipv6_addr_cmp(&hinfo->ha, &ho->rtr_prev.raddr))) 
			
			bu_to_prev_router = 0;
	}
	read_unlock_bh(&mn_info_lock);		     
	
	
	/* Send BU to previous router if it acts as a HA 
	 * TODO: Should the previous CoA be added to the mn_info list?
	 */
	
	if (ho->has_rtr_prev && ho->rtr_prev.flags & ND_RA_FLAG_HA && 
		    ho->rtr_prev.glob_addr && bu_to_prev_router) {
		lifetime = mipv6_mn_get_bulifetime(&ho->rtr_prev.CoA, 
						   &ho->rtr_new.CoA, 
						   MIPV6_BU_F_HOME | 
						   MIPV6_BU_F_ACK);
		mipv6_send_upd_option(
			&ho->rtr_prev.CoA, &ho->rtr_prev.raddr, HA_BU_DELAY, 
			INITIAL_BINDACK_DAD_TIMEOUT, MAX_BINDACK_TIMEOUT, 1,
			MIPV6_BU_F_HOME | MIPV6_BU_F_ACK, 0, lifetime, NULL);
		}
	
	return 0;		
}