Ejemplo n.º 1
0
/*
 * Things get complicated because we have to check if there's an egress
 * shortcut with suitable traffic parameters we could use. 
 */
static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry)
{
	uint32_t dst_ip = msg->content.in_info.in_dst_ip;
	struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip);
	eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client);

	if(eg_entry && eg_entry->shortcut){
		if(eg_entry->shortcut->qos.txtp.traffic_class &
		   msg->qos.txtp.traffic_class &
		   (qos ? qos->qos.txtp.traffic_class : ATM_UBR | ATM_CBR)){
			    if(eg_entry->shortcut->qos.txtp.traffic_class == ATM_UBR)
				    entry->shortcut = eg_entry->shortcut;
			    else if(eg_entry->shortcut->qos.txtp.max_pcr > 0)
				    entry->shortcut = eg_entry->shortcut;
		}
	 	if(entry->shortcut){
			dprintk("mpoa: (%s) using egress SVC to reach %u.%u.%u.%u\n",client->dev->name, NIPQUAD(dst_ip));
			client->eg_ops->put(eg_entry);
			return;
		}
	}
	if (eg_entry != NULL)
		client->eg_ops->put(eg_entry);

	/* No luck in the egress cache we must open an ingress SVC */
	msg->type = OPEN_INGRESS_SVC;
	if (qos && (qos->qos.txtp.traffic_class == msg->qos.txtp.traffic_class))
	{
		msg->qos = qos->qos;
		printk("mpoa: (%s) trying to get a CBR shortcut\n",client->dev->name);
    	}
	else memset(&msg->qos,0,sizeof(struct atm_qos));
	msg_to_mpoad(msg, client);
	return;
}
Ejemplo n.º 2
0
static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
{
	struct atm_mpoa_qos *qos;
	struct k_message msg;

	entry->count++;
	if (entry->entry_state == INGRESS_RESOLVED && entry->shortcut != NULL)
		return OPEN;

	if (entry->entry_state == INGRESS_REFRESHING) {
		if (entry->count > mpc->parameters.mpc_p1) {
			msg.type = SND_MPOA_RES_RQST;
			msg.content.in_info = entry->ctrl_info;
			memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
			qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
			if (qos != NULL)
				msg.qos = qos->qos;
			msg_to_mpoad(&msg, mpc);
			do_gettimeofday(&(entry->reply_wait));
			entry->entry_state = INGRESS_RESOLVING;
		}
		if (entry->shortcut != NULL)
			return OPEN;
		return CLOSED;
	}

	if (entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL)
		return OPEN;

	if (entry->count > mpc->parameters.mpc_p1 &&
	    entry->entry_state == INGRESS_INVALID) {
		dprintk("(%s) threshold exceeded for ip %pI4, sending MPOA res req\n",
			mpc->dev->name, &entry->ctrl_info.in_dst_ip);
		entry->entry_state = INGRESS_RESOLVING;
		msg.type = SND_MPOA_RES_RQST;
		memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
		msg.content.in_info = entry->ctrl_info;
		qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
		if (qos != NULL)
			msg.qos = qos->qos;
		msg_to_mpoad(&msg, mpc);
		do_gettimeofday(&(entry->reply_wait));
	}

	return CLOSED;
}
Ejemplo n.º 3
0
/* Call this every MPC-p4 seconds. */
static void check_resolving_entries(struct mpoa_client *client)
{

	struct atm_mpoa_qos *qos;
	in_cache_entry *entry;
	struct timeval now;
	struct k_message msg;

	do_gettimeofday(&now);

	read_lock_bh(&client->ingress_lock);
	entry = client->in_cache;
	while (entry != NULL) {
		if (entry->entry_state == INGRESS_RESOLVING) {
			if ((now.tv_sec - entry->hold_down.tv_sec) <
			    client->parameters.mpc_p6) {
				entry = entry->next;	/* Entry in hold down */
				continue;
			}
			if ((now.tv_sec - entry->reply_wait.tv_sec) >
			    entry->retry_time) {
				entry->retry_time = MPC_C1 * (entry->retry_time);
				/*
				 * Retry time maximum exceeded,
				 * put entry in hold down.
				 */
				if (entry->retry_time > client->parameters.mpc_p5) {
					do_gettimeofday(&(entry->hold_down));
					entry->retry_time = client->parameters.mpc_p4;
					entry = entry->next;
					continue;
				}
				/* Ask daemon to send a resolution request. */
				memset(&(entry->hold_down), 0, sizeof(struct timeval));
				msg.type = SND_MPOA_RES_RTRY;
				memcpy(msg.MPS_ctrl, client->mps_ctrl_addr, ATM_ESA_LEN);
				msg.content.in_info = entry->ctrl_info;
				qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
				if (qos != NULL)
					msg.qos = qos->qos;
				msg_to_mpoad(&msg, client);
				do_gettimeofday(&(entry->reply_wait));
			}
		}
		entry = entry->next;
	}
	read_unlock_bh(&client->ingress_lock);
}
Ejemplo n.º 4
0
static int parse_qos(const char *buff)
{
        /* possible lines look like this
         * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
         */
        unsigned char ip[4]; 
	int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
        uint32_t ipaddr;
	struct atm_qos qos; 
        
        memset(&qos, 0, sizeof(struct atm_qos));

	if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
			ip, ip+1, ip+2, ip+3) == 4) {
		ipaddr = *(uint32_t *)ip;
		return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
	}

	if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
			ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu) == 6) {
		rx_pcr = tx_pcr;
		rx_sdu = tx_sdu;
	} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
		ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
		return 0;

        ipaddr = *(uint32_t *)ip;
	qos.txtp.traffic_class = ATM_CBR;
	qos.txtp.max_pcr = tx_pcr;
	qos.txtp.max_sdu = tx_sdu;
	qos.rxtp.traffic_class = ATM_CBR;
	qos.rxtp.max_pcr = rx_pcr;
	qos.rxtp.max_sdu = rx_sdu;
        qos.aal = ATM_AAL5;
	dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
		qos.txtp.max_pcr,
		qos.txtp.max_sdu,
		qos.rxtp.max_pcr,
		qos.rxtp.max_sdu
		);

	atm_mpoa_add_qos(ipaddr, &qos);
	return 1;
}
Ejemplo n.º 5
0
static int parse_qos(const char *buff)
{
	/*                              
                                                            
  */
	unsigned char ip[4];
	int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
	__be32 ipaddr;
	struct atm_qos qos;

	memset(&qos, 0, sizeof(struct atm_qos));

	if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
			ip, ip+1, ip+2, ip+3) == 4) {
		ipaddr = *(__be32 *)ip;
		return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
	}

	if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
			ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu) == 6) {
		rx_pcr = tx_pcr;
		rx_sdu = tx_sdu;
	} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
		ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
		return 0;

	ipaddr = *(__be32 *)ip;
	qos.txtp.traffic_class = ATM_CBR;
	qos.txtp.max_pcr = tx_pcr;
	qos.txtp.max_sdu = tx_sdu;
	qos.rxtp.traffic_class = ATM_CBR;
	qos.rxtp.max_pcr = rx_pcr;
	qos.rxtp.max_sdu = rx_sdu;
	qos.aal = ATM_AAL5;
	dprintk("parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
		qos.txtp.max_pcr, qos.txtp.max_sdu,
		qos.rxtp.max_pcr, qos.rxtp.max_sdu);

	atm_mpoa_add_qos(ipaddr, &qos);
	return 1;
}
Ejemplo n.º 6
0
/*
 * Overwrites the old entry or makes a new one.
 */
struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos)
{
	struct atm_mpoa_qos *entry;

	entry = atm_mpoa_search_qos(dst_ip);
	if (entry != NULL) {
		entry->qos = *qos;
		return entry;
	}

	entry = kmalloc(sizeof(struct atm_mpoa_qos), GFP_KERNEL);
	if (entry == NULL) {
		printk("mpoa: atm_mpoa_add_qos: out of memory\n");
		return entry;
	}

	entry->ipaddr = dst_ip;
	entry->qos = *qos;

	entry->next = qos_head;
	qos_head = entry;

	return entry;
}
Ejemplo n.º 7
0
static int parse_qos(const char *buff, int len)
{
        /* possible lines look like this
         * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
         */
        
        int pos, i;
        uint32_t ipaddr;
        unsigned char ip[4]; 
        char cmd[4], temp[256];
        const char *tmp, *prev;
	struct atm_qos qos; 
	int value[5];
        
        memset(&qos, 0, sizeof(struct atm_qos));
        strncpy(cmd, buff, 3);
        if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
	        return 0;  /* not add or del */

	pos = 4;
        /* next parse ip */
        prev = buff + pos;
        for (i = 0; i < 3; i++) {
                tmp = strchr(prev, '.');
                if (tmp == NULL) return 0;
                memset(temp, '\0', 256);
                memcpy(temp, prev, tmp-prev);
                ip[i] = (char)simple_strtoul(temp, NULL, 0);
		tmp ++; 
		prev = tmp;
        }
	tmp = strchr(prev, ' ');
        if (tmp == NULL) return 0;
        memset(temp, '\0', 256);
        memcpy(temp, prev, tmp-prev);
        ip[i] = (char)simple_strtoul(temp, NULL, 0);
        ipaddr = *(uint32_t *)ip;
                
	if(!strncmp(cmd, "del", 3))
	         return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));

        /* next transmit values */
	tmp = strstr(buff, "tx=");
	if(tmp == NULL) return 0;
	tmp += 3;
	prev = tmp;
	for( i = 0; i < 1; i++){
	         tmp = strchr(prev, ',');
		 if (tmp == NULL) return 0;
		 memset(temp, '\0', 256);
		 memcpy(temp, prev, tmp-prev);
		 value[i] = (int)simple_strtoul(temp, NULL, 0);
		 tmp ++; 
		 prev = tmp;
	}
	tmp = strchr(prev, ' ');
        if (tmp == NULL) return 0;
	memset(temp, '\0', 256);
        memcpy(temp, prev, tmp-prev);
        value[i] = (int)simple_strtoul(temp, NULL, 0);
	qos.txtp.traffic_class = ATM_CBR;
	qos.txtp.max_pcr = value[0];
	qos.txtp.max_sdu = value[1];

        /* next receive values */
	tmp = strstr(buff, "rx=");
	if(tmp == NULL) return 0;
        if (strstr(buff, "rx=tx")) { /* rx == tx */
                qos.rxtp.traffic_class = qos.txtp.traffic_class;
                qos.rxtp.max_pcr = qos.txtp.max_pcr;
                qos.rxtp.max_cdv = qos.txtp.max_cdv;
                qos.rxtp.max_sdu = qos.txtp.max_sdu;
        } else {
                tmp += 3;
                prev = tmp;
                for( i = 0; i < 1; i++){
                        tmp = strchr(prev, ',');
                        if (tmp == NULL) return 0;
                        memset(temp, '\0', 256);
                        memcpy(temp, prev, tmp-prev);
                        value[i] = (int)simple_strtoul(temp, NULL, 0);
                        tmp ++; 
                        prev = tmp;
                }
                tmp = strchr(prev, '\0');
                if (tmp == NULL) return 0;
                memset(temp, '\0', 256);
                memcpy(temp, prev, tmp-prev);
                value[i] = (int)simple_strtoul(temp, NULL, 0);
                qos.rxtp.traffic_class = ATM_CBR;
                qos.rxtp.max_pcr = value[0];
                qos.rxtp.max_sdu = value[1];
        }
        qos.aal = ATM_AAL5;
	dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
		qos.txtp.max_pcr,
		qos.txtp.max_sdu,
		qos.rxtp.max_pcr,
		qos.rxtp.max_sdu
		);

	atm_mpoa_add_qos(ipaddr, &qos);
	return 1;
}