/*
 *	This handles all restart and diagnostic frames.
 */
void rose_link_rx_restart(struct sk_buff *skb, struct rose_neigh *neigh, unsigned short frametype)
{
	struct sk_buff *skbn;

	switch (frametype) {
	case ROSE_RESTART_REQUEST:
		rose_stop_t0timer(neigh);
		neigh->restarted = 1;
		neigh->dce_mode  = (skb->data[3] == ROSE_DTE_ORIGINATED);
		rose_transmit_restart_confirmation(neigh);
		break;

	case ROSE_RESTART_CONFIRMATION:
		rose_stop_t0timer(neigh);
		neigh->restarted = 1;
		break;

	case ROSE_DIAGNOSTIC:
		printk(KERN_WARNING "ROSE: received diagnostic #%d - %02X %02X %02X\n", skb->data[3], skb->data[4], skb->data[5], skb->data[6]);
		break;

	default:
		printk(KERN_WARNING "ROSE: received unknown %02X with LCI 000\n", frametype);
		break;
	}

	if (neigh->restarted) {
		while ((skbn = skb_dequeue(&neigh->queue)) != NULL)
			if (!rose_send_frame(skbn, neigh))
				kfree_skb(skbn);
	}
}
Exemple #2
0
/*
 * Caller is holding rose_neigh_list_lock.
 */
static void rose_remove_neigh(struct rose_neigh *rose_neigh)
{
    struct rose_neigh *s;

    rose_stop_ftimer(rose_neigh);
    rose_stop_t0timer(rose_neigh);

    skb_queue_purge(&rose_neigh->queue);

    spin_lock_bh(&rose_neigh_list_lock);

    if ((s = rose_neigh_list) == rose_neigh) {
        rose_neigh_list = rose_neigh->next;
        spin_unlock_bh(&rose_neigh_list_lock);
        if (rose_neigh->digipeat != NULL)
            kfree(rose_neigh->digipeat);
        kfree(rose_neigh);
        return;
    }

    while (s != NULL && s->next != NULL) {
        if (s->next == rose_neigh) {
            s->next = rose_neigh->next;
            spin_unlock_bh(&rose_neigh_list_lock);
            if (rose_neigh->digipeat != NULL)
                kfree(rose_neigh->digipeat);
            kfree(rose_neigh);
            return;
        }

        s = s->next;
    }
    spin_unlock_bh(&rose_neigh_list_lock);
}
Exemple #3
0
static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
{
    struct rose_route *rose_route, *s;

    rose_neigh->restarted = 0;

    rose_stop_t0timer(rose_neigh);
    rose_start_ftimer(rose_neigh);

    skb_queue_purge(&rose_neigh->queue);

    spin_lock_bh(&rose_route_list_lock);

    rose_route = rose_route_list;

    while (rose_route != NULL) {
        if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
                (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL)       ||
                (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
            s = rose_route->next;
            rose_remove_route(rose_route);
            rose_route = s;
            continue;
        }

        if (rose_route->neigh1 == rose_neigh) {
            rose_route->neigh1->use--;
            rose_route->neigh1 = NULL;
            rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
        }

        if (rose_route->neigh2 == rose_neigh) {
            rose_route->neigh2->use--;
            rose_route->neigh2 = NULL;
            rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
        }

        rose_route = rose_route->next;
    }
    spin_unlock_bh(&rose_route_list_lock);
}
Exemple #4
0
static void rose_del_route_by_neigh(struct rose_neigh *rose_neigh)
{
	struct rose_route *rose_route, *s;
	struct sk_buff    *skb;

	rose_neigh->restarted = 0;

	rose_stop_t0timer(rose_neigh);
	rose_start_ftimer(rose_neigh);

	while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL)
		kfree_skb(skb);

	rose_route = rose_route_list;

	while (rose_route != NULL) {
		if ((rose_route->neigh1 == rose_neigh && rose_route->neigh2 == rose_neigh) ||
		    (rose_route->neigh1 == rose_neigh && rose_route->neigh2 == NULL)       ||
		    (rose_route->neigh2 == rose_neigh && rose_route->neigh1 == NULL)) {
			s = rose_route->next;
			rose_remove_route(rose_route);
			rose_route = s;
			continue;
		}

		if (rose_route->neigh1 == rose_neigh) {
			rose_route->neigh1->use--;
			rose_route->neigh1 = NULL;
			rose_transmit_clear_request(rose_route->neigh2, rose_route->lci2, ROSE_OUT_OF_ORDER, 0);
		}

		if (rose_route->neigh2 == rose_neigh) {
			rose_route->neigh2->use--;
			rose_route->neigh2 = NULL;
			rose_transmit_clear_request(rose_route->neigh1, rose_route->lci1, ROSE_OUT_OF_ORDER, 0);
		}

		rose_route = rose_route->next;
	}
}
Exemple #5
0
static void rose_remove_neigh(struct rose_neigh *rose_neigh)
{
	struct rose_neigh *s;
	unsigned long flags;
	struct sk_buff *skb;

	rose_stop_ftimer(rose_neigh);
	rose_stop_t0timer(rose_neigh);

	while ((skb = skb_dequeue(&rose_neigh->queue)) != NULL)
		kfree_skb(skb);

	save_flags(flags); cli();

	if ((s = rose_neigh_list) == rose_neigh) {
		rose_neigh_list = rose_neigh->next;
		restore_flags(flags);
		if (rose_neigh->digipeat != NULL)
			kfree(rose_neigh->digipeat);
		kfree(rose_neigh);
		return;
	}

	while (s != NULL && s->next != NULL) {
		if (s->next == rose_neigh) {
			s->next = rose_neigh->next;
			restore_flags(flags);
			if (rose_neigh->digipeat != NULL)
				kfree(rose_neigh->digipeat);
			kfree(rose_neigh);
			return;
		}

		s = s->next;
	}

	restore_flags(flags);
}