示例#1
0
static int dn_route_rx_long(struct sk_buff *skb)
{
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	unsigned char *ptr = skb->data;

	if (!pskb_may_pull(skb, 21)) /* 20 for long header, 1 for shortest nsp */
		goto drop_it;

	skb_pull(skb, 20);
	skb->h.raw = skb->data;

        /* Destination info */
        ptr += 2;
	cb->dst = dn_eth2dn(ptr);
        if (memcmp(ptr, dn_hiord_addr, 4) != 0)
                goto drop_it;
        ptr += 6;


        /* Source info */
        ptr += 2;
	cb->src = dn_eth2dn(ptr);
        if (memcmp(ptr, dn_hiord_addr, 4) != 0)
                goto drop_it;
        ptr += 6;
        /* Other junk */
        ptr++;
        cb->hops = *ptr++; /* Visit Count */

	return NF_HOOK(PF_DECnet, NF_DN_PRE_ROUTING, skb, skb->dev, NULL, dn_route_rx_packet);

drop_it:
	kfree_skb(skb);
	return NET_RX_DROP;
}
示例#2
0
/*
 * Endnode hello message received
 */
int dn_neigh_endnode_hello(struct sk_buff *skb)
{
    struct endnode_hello_message *msg = (struct endnode_hello_message *)skb->data;
    struct neighbour *neigh;
    struct dn_neigh *dn;
    dn_address src;

    src = dn_htons(dn_eth2dn(msg->id));

    neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);

    dn = (struct dn_neigh *)neigh;

    if (neigh) {
        write_lock(&neigh->lock);

        neigh->used = jiffies;

        if (!(neigh->nud_state & NUD_PERMANENT)) {
            neigh->updated = jiffies;

            if (neigh->dev->type == ARPHRD_ETHER)
                memcpy(neigh->ha, &skb->mac.ethernet->h_source, ETH_ALEN);
            dn->flags   &= ~(DN_NDFLAG_R1 | DN_NDFLAG_R2);
            dn->blksize  = dn_ntohs(msg->blksize);
            dn->priority = 0;
        }

        write_unlock(&neigh->lock);
        neigh_release(neigh);
    }

    kfree_skb(skb);
    return 0;
}
示例#3
0
/*
 * Ethernet router hello message received
 */
int dn_neigh_router_hello(struct sk_buff *skb)
{
    struct rtnode_hello_message *msg = (struct rtnode_hello_message *)skb->data;

    struct neighbour *neigh;
    struct dn_neigh *dn;
    struct dn_dev *dn_db;
    dn_address src;

    src = dn_htons(dn_eth2dn(msg->id));

    neigh = __neigh_lookup(&dn_neigh_table, &src, skb->dev, 1);

    dn = (struct dn_neigh *)neigh;

    if (neigh) {
        write_lock(&neigh->lock);

        neigh->used = jiffies;
        dn_db = (struct dn_dev *)neigh->dev->dn_ptr;

        if (!(neigh->nud_state & NUD_PERMANENT)) {
            neigh->updated = jiffies;

            if (neigh->dev->type == ARPHRD_ETHER)
                memcpy(neigh->ha, &skb->mac.ethernet->h_source, ETH_ALEN);

            dn->blksize  = dn_ntohs(msg->blksize);
            dn->priority = msg->priority;

            dn->flags &= ~DN_NDFLAG_P3;

            switch(msg->iinfo & DN_RT_INFO_TYPE) {
            case DN_RT_INFO_L1RT:
                dn->flags &=~DN_NDFLAG_R2;
                dn->flags |= DN_NDFLAG_R1;
                break;
            case DN_RT_INFO_L2RT:
                dn->flags |= DN_NDFLAG_R2;
            }
        }

        if (!dn_db->router) {
            dn_db->router = neigh_clone(neigh);
        } else {
            if (msg->priority > ((struct dn_neigh *)dn_db->router)->priority)
                neigh_release(xchg(&dn_db->router, neigh_clone(neigh)));
        }
        write_unlock(&neigh->lock);
        neigh_release(neigh);
    }

    kfree_skb(skb);
    return 0;
}