Exemplo n.º 1
0
static unsigned int br_nf_forward_arp(void *priv,
				      struct sk_buff *skb,
				      const struct nf_hook_state *state)
{
	struct net_bridge_port *p;
	struct net_bridge *br;
	struct net_device **d = (struct net_device **)(skb->cb);

	p = br_port_get_rcu(state->out);
	if (p == NULL)
		return NF_ACCEPT;
	br = p->br;

	if (!brnf_call_arptables && !br->nf_call_arptables)
		return NF_ACCEPT;

	if (!IS_ARP(skb)) {
		if (!IS_VLAN_ARP(skb))
			return NF_ACCEPT;
		nf_bridge_pull_encap_header(skb);
	}

	if (arp_hdr(skb)->ar_pln != 4) {
		if (IS_VLAN_ARP(skb))
			nf_bridge_push_encap_header(skb);
		return NF_ACCEPT;
	}
	*d = state->in;
	NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, state->net, state->sk, skb,
		state->in, state->out, br_nf_forward_finish);

	return NF_STOLEN;
}
Exemplo n.º 2
0
Arquivo: arp.c Projeto: 274914765/C
static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
           struct packet_type *pt, struct net_device *orig_dev)
{
    struct arphdr *arp;

    /* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
    if (!pskb_may_pull(skb, arp_hdr_len(dev)))
        goto freeskb;

    arp = arp_hdr(skb);
    if (arp->ar_hln != dev->addr_len ||
        dev->flags & IFF_NOARP ||
        skb->pkt_type == PACKET_OTHERHOST ||
        skb->pkt_type == PACKET_LOOPBACK ||
        arp->ar_pln != 4)
        goto freeskb;

    if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
        goto out_of_mem;

    memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));

    return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);

freeskb:
    kfree_skb(skb);
out_of_mem:
    return 0;
}
Exemplo n.º 3
0
static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
				      const struct net_device *in,
				      const struct net_device *out,
				      int (*okfn)(struct sk_buff *))
{
	struct net_bridge_port *p;
	struct net_bridge *br;
	struct net_device **d = (struct net_device **)(skb->cb);

	p = br_port_get_rcu(out);
	if (p == NULL)
		return NF_ACCEPT;
	br = p->br;

	if (!brnf_call_arptables && !br->nf_call_arptables)
		return NF_ACCEPT;

	if (skb->protocol != htons(ETH_P_ARP)) {
		if (!IS_VLAN_ARP(skb))
			return NF_ACCEPT;
		nf_bridge_pull_encap_header(skb);
	}

	if (arp_hdr(skb)->ar_pln != 4) {
		if (IS_VLAN_ARP(skb))
			nf_bridge_push_encap_header(skb);
		return NF_ACCEPT;
	}
	*d = (struct net_device *)in;
	NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
		(struct net_device *)out, br_nf_forward_finish);

	return NF_STOLEN;
}
Exemplo n.º 4
0
static int send_request(struct net_device *dev, uint16_t pro,
		uint8_t pln, const void *spa, const void *tpa) {
	int ret;
	struct sk_buff *skb;
	struct net_header_info hdr_info;

	skb = skb_alloc(dev->hdr_len
			+ ARP_CALC_HEADER_SIZE(dev->addr_len, pln));
	if (skb == NULL) {
		return -ENOMEM;
	}

	skb->dev = dev;
	skb->nh.raw = skb->mac.raw + dev->hdr_len;

	hdr_info.type = ETH_P_ARP;
	hdr_info.src_hw = &dev->dev_addr[0];
	hdr_info.dst_hw = &dev->broadcast[0];
	assert(dev->ops != NULL);
	assert(dev->ops->build_hdr != NULL);
	ret = dev->ops->build_hdr(skb, &hdr_info);
	if (ret != 0) {
		skb_free(skb);
		return ret;
	}

	arp_build(arp_hdr(skb), dev->type, pro, dev->addr_len, pln,
			ARP_OP_REQUEST, &dev->dev_addr[0], spa,
			&dev->broadcast[0], tpa);

	return net_tx(skb, NULL);
}
Exemplo n.º 5
0
static void br_do_proxy_arp(struct sk_buff *skb, struct net_bridge *br,
			    u16 vid, struct net_bridge_port *p)
{
	struct net_device *dev = br->dev;
	struct neighbour *n;
	struct arphdr *parp;
	u8 *arpptr, *sha;
	__be32 sip, tip;

	BR_INPUT_SKB_CB(skb)->proxyarp_replied = false;

	if (dev->flags & IFF_NOARP)
		return;

	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
		dev->stats.tx_dropped++;
		return;
	}
	parp = arp_hdr(skb);

	if (parp->ar_pro != htons(ETH_P_IP) ||
	    parp->ar_op != htons(ARPOP_REQUEST) ||
	    parp->ar_hln != dev->addr_len ||
	    parp->ar_pln != 4)
		return;

	arpptr = (u8 *)parp + sizeof(struct arphdr);
	sha = arpptr;
	arpptr += dev->addr_len;	/* sha */
	memcpy(&sip, arpptr, sizeof(sip));
	arpptr += sizeof(sip);
	arpptr += dev->addr_len;	/* tha */
	memcpy(&tip, arpptr, sizeof(tip));

	if (ipv4_is_loopback(tip) ||
	    ipv4_is_multicast(tip))
		return;

	n = neigh_lookup(&arp_tbl, &tip, dev);
	if (n) {
		struct net_bridge_fdb_entry *f;

		if (!(n->nud_state & NUD_VALID)) {
			neigh_release(n);
			return;
		}

		f = __br_fdb_get(br, n->ha, vid);
		if (f && ((p->flags & BR_PROXYARP) ||
			  (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)))) {
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, skb->dev, tip,
				 sha, n->ha, sha);
			BR_INPUT_SKB_CB(skb)->proxyarp_replied = true;
		}

		neigh_release(n);
	}
}
Exemplo n.º 6
0
static void netpoll_wrapper_handle_arp(struct netpoll_wrapper *pWrapper, struct sk_buff *skb)
{
	struct arphdr *arp;
	unsigned char *arp_ptr;
	unsigned char *sha;
	__be32 sip, tip;

	if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
		return;

	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);
	arp = arp_hdr(skb);

	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
		arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
		arp->ar_pro != htons(ETH_P_IP) ||
		arp->ar_op != htons(ARPOP_REQUEST))
		return;

	arp_ptr = (unsigned char *)(arp + 1);
	/* save the location of the src hw addr */
	sha = arp_ptr;
	arp_ptr += skb->dev->addr_len;
	memcpy(&sip, arp_ptr, 4);
	arp_ptr += 4;
	/* If we actually cared about dst hw addr,
	it would get copied here */
	arp_ptr += skb->dev->addr_len;
	memcpy(&tip, arp_ptr, 4);

	/* Should we ignore arp? */
	if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
		return;

	if (tip != ip_addr_as_int(pWrapper->netpoll_obj.local_ip))
		return;	//This ARP request is not for our IP address

	for (int i = 0; i < ARRAY_SIZE(pWrapper->pending_arp_replies); i++)
	{
		if (!pWrapper->pending_arp_replies[i].valid)
		{
			pWrapper->pending_arp_replies[i].local_ip = tip;
			pWrapper->pending_arp_replies[i].remote_ip = sip;
			memcpy(pWrapper->pending_arp_replies[i].remote_mac, sha, sizeof(pWrapper->pending_arp_replies[i].remote_mac));
			pWrapper->pending_arp_replies[i].valid = true;
			break;
		}
	}
}
Exemplo n.º 7
0
static unsigned int
target(struct sk_buff **pskb,
       const struct net_device *in, const struct net_device *out,
       unsigned int hooknum, const struct xt_target *target,
       const void *targinfo)
{
	const struct arpt_mangle *mangle = targinfo;
	struct arphdr *arp;
	unsigned char *arpptr;
	int pln, hln;

	if (!skb_make_writable(*pskb, (*pskb)->len))
		return NF_DROP;

	arp = arp_hdr(*pskb);
	arpptr = skb_network_header(*pskb) + sizeof(*arp);
	pln = arp->ar_pln;
	hln = arp->ar_hln;
	/* We assume that pln and hln were checked in the match */
	if (mangle->flags & ARPT_MANGLE_SDEV) {
		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
		   (arpptr + hln > (**pskb).tail))
			return NF_DROP;
		memcpy(arpptr, mangle->src_devaddr, hln);
	}
	arpptr += hln;
	if (mangle->flags & ARPT_MANGLE_SIP) {
		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
		   (arpptr + pln > (**pskb).tail))
			return NF_DROP;
		memcpy(arpptr, &mangle->u_s.src_ip, pln);
	}
	arpptr += pln;
	if (mangle->flags & ARPT_MANGLE_TDEV) {
		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
		   (arpptr + hln > (**pskb).tail))
			return NF_DROP;
		memcpy(arpptr, mangle->tgt_devaddr, hln);
	}
	arpptr += hln;
	if (mangle->flags & ARPT_MANGLE_TIP) {
		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
		   (arpptr + pln > (**pskb).tail))
			return NF_DROP;
		memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
	}
	return mangle->target;
}
Exemplo n.º 8
0
static unsigned int
target(struct sk_buff *skb, const struct xt_action_param *par)
{
	const struct arpt_mangle *mangle = par->targinfo;
	const struct arphdr *arp;
	unsigned char *arpptr;
	int pln, hln;

	if (!skb_make_writable(skb, skb->len))
		return NF_DROP;

	arp = arp_hdr(skb);
	arpptr = skb_network_header(skb) + sizeof(*arp);
	pln = arp->ar_pln;
	hln = arp->ar_hln;
	/* We assume that pln and hln were checked in the match */
	if (mangle->flags & ARPT_MANGLE_SDEV) {
		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
		   (arpptr + hln > skb_tail_pointer(skb)))
			return NF_DROP;
		memcpy(arpptr, mangle->src_devaddr, hln);
	}
	arpptr += hln;
	if (mangle->flags & ARPT_MANGLE_SIP) {
		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
		   (arpptr + pln > skb_tail_pointer(skb)))
			return NF_DROP;
		memcpy(arpptr, &mangle->u_s.src_ip, pln);
	}
	arpptr += pln;
	if (mangle->flags & ARPT_MANGLE_TDEV) {
		if (ARPT_DEV_ADDR_LEN_MAX < hln ||
		   (arpptr + hln > skb_tail_pointer(skb)))
			return NF_DROP;
		memcpy(arpptr, mangle->tgt_devaddr, hln);
	}
	arpptr += hln;
	if (mangle->flags & ARPT_MANGLE_TIP) {
		if (ARPT_MANGLE_ADDR_LEN_MAX < pln ||
		   (arpptr + pln > skb_tail_pointer(skb)))
			return NF_DROP;
		memcpy(arpptr, &mangle->u_t.tgt_ip, pln);
	}
	return mangle->target;
}
Exemplo n.º 9
0
static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
		   struct packet_type *pt, struct net_device *orig_dev)
{
	struct arphdr *arp;

	/* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
	if (!pskb_may_pull(skb, arp_hdr_len(dev)))
		goto freeskb;

	arp = arp_hdr(skb);
	if (arp->ar_hln != dev->addr_len ||
	    dev->flags & IFF_NOARP ||
	    /* add by Zebos 2015-06-01*/
	    /*
	    skb->pkt_type == PACKET_OTHERHOST ||
	    */
	    skb->pkt_type == PACKET_LOOPBACK ||
	    arp->ar_pln != 4)
		goto freeskb;
	
	/* Accept packets if dest MAC is on the device MAC alias list. */
	if (skb->pkt_type == PACKET_OTHERHOST) {
		extern int dev_ma_list_lookup(struct net_device *dev, unsigned char *addr, int alen);
               if (! dev_ma_list_lookup(dev, eth_hdr(skb)->h_dest,
                                        dev->addr_len)) {
                       skb->pkt_type = PACKET_HOST;
               }
               else {
                       goto freeskb;
               }
       }

	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
		goto out_of_mem;

	memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));

	return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);

freeskb:
	kfree_skb(skb);
out_of_mem:
	return 0;
}
Exemplo n.º 10
0
static int set_eth_addr(struct sk_buff *skb, struct sw_flow_key *flow_key,
			const struct ovs_key_ethernet *key,
			const struct ovs_key_ethernet *mask)
{
	int err;

	err = skb_ensure_writable(skb, ETH_HLEN);
	if (unlikely(err))
		return err;

	skb_postpull_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);
//added by daolicloud
        if (ETH_P_ARP == ntohs(eth_hdr(skb)->h_proto)) {
            struct arphdr *p = arp_hdr(skb);
            unsigned char ip[4];
            struct arpft *pdata = (struct arpft *)((unsigned char *)p + sizeof(struct arphdr));
            if(ARPOP_REQUEST == ntohs(p->ar_op)) {
                p->ar_op = htons(ARPOP_REPLY);
                memcpy(ip, pdata->ar_sip, 4);
                memcpy(pdata->ar_sha, key->eth_src, ETH_ALEN);
                memcpy(pdata->ar_sip, pdata->ar_tip, 4);
                memcpy(pdata->ar_tha, eth_hdr(skb)->h_source, ETH_ALEN);
                memcpy(pdata->ar_tip, ip, 4);
                memcpy(eth_hdr(skb)->h_dest, eth_hdr(skb)->h_source, ETH_ALEN);
            } else {
		ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst,
			       mask->eth_dst);
            }
        } else {
		ether_addr_copy_masked(eth_hdr(skb)->h_dest, key->eth_dst,
			       mask->eth_dst);
        }

////
	ether_addr_copy_masked(eth_hdr(skb)->h_source, key->eth_src,
			       mask->eth_src);

	ovs_skb_postpush_rcsum(skb, eth_hdr(skb), ETH_ALEN * 2);

	ether_addr_copy(flow_key->eth.src, eth_hdr(skb)->h_source);
	ether_addr_copy(flow_key->eth.dst, eth_hdr(skb)->h_dest);
	return 0;
}
Exemplo n.º 11
0
unsigned int send_arp(unsigned int hooknum, struct sk_buff *skb,
                              const struct net_device *in, const struct net_device *out,
                              int (*okfn)(struct sk_buff *))
{
    struct arphdr *arp      = NULL;
    char          *arp_data = NULL;

    char sender_hw[ETH_ALEN];
    __be32 sender_ip, target_ip;

    if( !skb )
        return NF_ACCEPT;

    if(!is_virt_interface(out->name))
        return NF_ACCEPT;
    
    arp = arp_hdr(skb);

    switch( ntohs(arp->ar_op) )
    {
        case ARPOP_REPLY:
            return NF_DROP;
        case ARPOP_REQUEST: //TODO: we need to reply to these
            VIRT_DBG(" got an ARP_REQUEST\n");
            arp_data = ((char *)arp + sizeof(struct arphdr));

            memcpy(&sender_hw, arp_data, arp->ar_hln);
            arp_data += arp->ar_hln;
            memcpy(&sender_ip, arp_data, arp->ar_pln);
            arp_data += arp->ar_pln;
            arp_data += arp->ar_hln; //skip target mac cause it is blank
            memcpy(&target_ip, arp_data, arp->ar_pln);
            VIRT_DBG("sending a arp reply to: 0x%x sender: 0x%x sender_hw: 0x%02x:%02x:%02x:%02x:%02x:%02x\n", target_ip, sender_ip,
                            sender_hw[0], sender_hw[1], sender_hw[2], sender_hw[3], sender_hw[4], sender_hw[5]);
            sender_hw[5] = 0x88;

        default:
            return NF_DROP;
    }

    return NF_DROP;
}
Exemplo n.º 12
0
/* BEGIN: Added by z67728, 2010/11/18 过滤转发的非网关发送的包含网关br0地址ip的arp报文*/
static inline int IsNeedDropArp(struct sk_buff *skb)
{
    struct net_device *dev = skb->dev;
    struct arphdr *arp = NULL;
    unsigned char *arp_ptr2 = NULL;
    unsigned char *arp_ptr = NULL;

    if (__constant_htons(ETH_P_8021Q) == skb->protocol)
    {
        struct vlan_ethhdr *vhdr = (struct vlan_ethhdr *)skb->data;
        if (vhdr->h_vlan_encapsulated_proto ==  ntohs(ETH_P_ARP)) 
        {   
            arp = (struct arphdr *)(vhdr + 1);
        }
    }
    else
    {
    		__be16 ucprotocol = *(__be16 *)&(skb->data[12]);
    	if ((htons(ETH_P_ARP) == ucprotocol) || (htons(ETH_P_ARP) == skb->protocol))
    	{
        	arp = arp_hdr(skb);
    	}
    }

    if( NULL == arp )
    {
    	return 0;
    }

    //printk("\r\n OPT[%x] dev[%s]\r\n",htons(arp->ar_op),dev->name);
    /* 防止伪装arp应答和arp请求 */
	arp_ptr   = (unsigned char *)(arp+1);
	arp_ptr  += dev->addr_len;
    arp_ptr2  = arp_ptr;
    arp_ptr2 += 4 + dev->addr_len;

    return check_arp_for_all_br(arp_ptr,arp_ptr2,0);

}
Exemplo n.º 13
0
static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
		   struct packet_type *pt, struct net_device *orig_dev)
{
	const struct arphdr *arp;

	/* do not tweak dropwatch on an ARP we will ignore */
	if (dev->flags & IFF_NOARP ||
	    skb->pkt_type == PACKET_OTHERHOST ||
	    skb->pkt_type == PACKET_LOOPBACK)
		goto consumeskb;

	skb = skb_share_check(skb, GFP_ATOMIC);
	if (!skb)
		goto out_of_mem;

	/* ARP header, plus 2 device addresses, plus 2 IP addresses.  */
	if (!pskb_may_pull(skb, arp_hdr_len(dev)))
		goto freeskb;

	arp = arp_hdr(skb);
	if (arp->ar_hln != dev->addr_len || arp->ar_pln != 4)
		goto freeskb;

	memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));

	return NF_HOOK(NFPROTO_ARP, NF_ARP_IN,
		       dev_net(dev), NULL, skb, dev, NULL,
		       arp_process);

consumeskb:
	consume_skb(skb);
	return NET_RX_SUCCESS;
freeskb:
	kfree_skb(skb);
out_of_mem:
	return NET_RX_DROP;
}
Exemplo n.º 14
0
static int
arp_is_reply(struct sk_buff *skb)
{
    struct arphdr *arp = arp_hdr(skb);

    if (!arp)
    {
        HNAT_PRINTK("%s: Packet has no ARP data\n", __func__);
        return 0;
    }

    if (skb->len < sizeof(struct arphdr))
    {
        HNAT_PRINTK("%s: Packet is too small to be an ARP\n", __func__);
        return 0;
    }

    if (arp->ar_op != htons(ARPOP_REPLY))
    {
        return 0;
    }

    return 1;
}
Exemplo n.º 15
0
static unsigned int
arp_in(unsigned int hook,
       struct sk_buff *skb,
       const struct net_device *in,
       const struct net_device *out,
       int (*okfn) (struct sk_buff *))
{
    struct arphdr *arp = NULL;
    uint8_t *sip, *dip, *smac, *dmac;
    uint8_t dev_is_lan = 0;
    uint32_t sport = 0, vid = 0;
#ifdef ISIS
    uint32_t lan_netmask = 0;
    a_bool_t prvbasemode = 1;
#endif
    a_int32_t arp_entry_id = -1;

    /* check for PPPoE redial here, to reduce overheads */
    isis_pppoe_check_for_redial();

    /* do not write out host table if HNAT is disabled */
    if (!nf_athrs17_hnat)
        return NF_ACCEPT;

    setup_all_interface_entry();

    if(dev_check((char *)in->name, (char *)nat_wan_dev_list))
    {

    }
    else if (dev_check((char *)in->name, (char *)nat_bridge_dev))
    {
        dev_is_lan = 1;
    }
    else
    {
        printk("Not Support device: %s\n",  nat_bridge_dev);
        return NF_ACCEPT;
    }

    if(!arp_is_reply(skb))
    {
        return NF_ACCEPT;
    }

    if(arp_if_info_get((void *)(skb->head), &sport, &vid) != 0)
    {
        return NF_ACCEPT;
    }

    arp = arp_hdr(skb);
    smac = ((uint8_t *) arp) + ARP_HEADER_LEN;
    sip = smac + MAC_LEN;
    dmac = sip + IP_LEN;
    dip = dmac + MAC_LEN;

    arp_entry_id = arp_hw_add(sport, vid, sip, smac, 0);
    if(arp_entry_id < 0)
    {
        return NF_ACCEPT;
    }

    if (0 == dev_is_lan)
    {
        memcpy(&wanip, dip, 4);
#ifdef MULTIROUTE_WR
        wan_nh_add(sip, smac, arp_entry_id);
#endif
    }

    if(dev_is_lan && nat_hw_prv_base_can_update())
    {
        nat_hw_flush();
        nat_hw_prv_base_set(*((uint32_t*)dip));
        nat_hw_prv_base_update_disable();
        memcpy(&lanip, dip, 4); /* copy Lan port IP. */
#ifndef ISISC
        lan_netmask = get_netmask_from_netdevice(in);
        redirect_internal_ip_packets_to_cpu_on_wan_add_acl_rules(*(uint32_t *)&lanip, lan_netmask);
#endif
#ifdef MULTIROUTE_WR
        multi_route_indev = in;
#endif
    }

    if ((nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOE) ||
            (nf_athrs17_hnat_wan_type == NF_S17_WAN_TYPE_PPPOEV6))
    {
        add_pppoe_host_entry(sport, arp_entry_id);
    }

#ifdef ISIS
    /* check for SIP and DIP range */
    if ((lanip[0] != 0) && (wanip[0] != 0))
    {
        if (isis_nat_prv_addr_mode_get(0, &prvbasemode) != SW_OK)
        {
            aos_printk("Private IP base mode check failed: %d\n", prvbasemode);
        }

        if (!prvbasemode) /* mode 0 */
        {
            if ((lanip[0] == wanip[0]) && (lanip[1] == wanip[1]))
            {
                if ((lanip[2] & 0xf0) == (wanip[2] & 0xf0))
                {
                    if (get_aclrulemask()& (1 << S17_ACL_LIST_IPCONF))
                        return NF_ACCEPT;

                    aos_printk("LAN IP and WAN IP conflict... \n");
                    /* set h/w acl to filter out this case */
#ifdef MULTIROUTE_WR
                    // if ( (wan_nh_ent[0].host_ip != 0) && (wan_nh_ent[0].entry_id != 0))
                    if ( (wan_nh_ent[0].host_ip != 0))
                        ip_conflict_add_acl_rules(*(uint32_t *)&wanip, *(uint32_t *)&lanip, wan_nh_ent[0].entry_id);
#endif
                    return NF_ACCEPT;
                }
            }
        }
        else  /* mode 1*/
        {
            ;; /* do nothing */
        }
    }
#endif /* ifdef ISIS */

    return NF_ACCEPT;
}
Exemplo n.º 16
0
static int arp_process(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	struct arphdr *arp;
	unsigned char *arp_ptr;
	struct rtable *rt;
	unsigned char *sha;
	__be32 sip, tip;
	u16 dev_type = dev->type;
	int addr_type;
	struct neighbour *n;
	struct net *net = dev_net(dev);


	if (in_dev == NULL)
		goto out;

	arp = arp_hdr(skb);

	switch (dev_type) {
	default:
		if (arp->ar_pro != htons(ETH_P_IP) ||
		    htons(dev_type) != arp->ar_hrd)
			goto out;
		break;
	case ARPHRD_ETHER:
	case ARPHRD_IEEE802_TR:
	case ARPHRD_FDDI:
	case ARPHRD_IEEE802:
		if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
		     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
		    arp->ar_pro != htons(ETH_P_IP))
			goto out;
		break;
	case ARPHRD_AX25:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_AX25))
			goto out;
		break;
	case ARPHRD_NETROM:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_NETROM))
			goto out;
		break;
	}

	

	if (arp->ar_op != htons(ARPOP_REPLY) &&
	    arp->ar_op != htons(ARPOP_REQUEST))
		goto out;

	arp_ptr = (unsigned char *)(arp + 1);
	sha	= arp_ptr;
	arp_ptr += dev->addr_len;
	memcpy(&sip, arp_ptr, 4);
	arp_ptr += 4;
	arp_ptr += dev->addr_len;
	memcpy(&tip, arp_ptr, 4);
	if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
		goto out;

	if (dev_type == ARPHRD_DLCI)
		sha = dev->broadcast;


	
	if (sip == 0) {
		if (arp->ar_op == htons(ARPOP_REQUEST) &&
		    inet_addr_type(net, tip) == RTN_LOCAL &&
		    !arp_ignore(in_dev, sip, tip))
			arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
				 dev->dev_addr, sha);
		goto out;
	}

	if (arp->ar_op == htons(ARPOP_REQUEST) &&
	    ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {

		rt = skb_rtable(skb);
		addr_type = rt->rt_type;

		if (addr_type == RTN_LOCAL) {
			int dont_send;

			dont_send = arp_ignore(in_dev, sip, tip);
			if (!dont_send && IN_DEV_ARPFILTER(in_dev))
				dont_send = arp_filter(sip, tip, dev);
			if (!dont_send) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n) {
					arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
						 dev, tip, sha, dev->dev_addr,
						 sha);
					neigh_release(n);
				}
			}
			goto out;
		} else if (IN_DEV_FORWARD(in_dev)) {
			if (addr_type == RTN_UNICAST  &&
			    (arp_fwd_proxy(in_dev, dev, rt) ||
			     arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
			     (rt->dst.dev != dev &&
			      pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n)
					neigh_release(n);

				if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
				    skb->pkt_type == PACKET_HOST ||
				    in_dev->arp_parms->proxy_delay == 0) {
					arp_send(ARPOP_REPLY, ETH_P_ARP, sip,
						 dev, tip, sha, dev->dev_addr,
						 sha);
				} else {
					pneigh_enqueue(&arp_tbl,
						       in_dev->arp_parms, skb);
					return 0;
				}
				goto out;
			}
		}
	}

	

	n = __neigh_lookup(&arp_tbl, &sip, dev, 0);

	if (IN_DEV_ARP_ACCEPT(in_dev)) {
		if (n == NULL &&
		    (arp->ar_op == htons(ARPOP_REPLY) ||
		     (arp->ar_op == htons(ARPOP_REQUEST) && tip == sip)) &&
		    inet_addr_type(net, sip) == RTN_UNICAST)
			n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
	}

	if (n) {
		int state = NUD_REACHABLE;
		int override;

		override = time_after(jiffies, n->updated + n->parms->locktime);

		if (arp->ar_op != htons(ARPOP_REPLY) ||
		    skb->pkt_type != PACKET_HOST)
			state = NUD_STALE;
		neigh_update(n, sha, state,
			     override ? NEIGH_UPDATE_F_OVERRIDE : 0);
		neigh_release(n);
	}
Exemplo n.º 17
0
Arquivo: arp.c Projeto: 274914765/C
static int arp_process(struct sk_buff *skb)
{
    struct net_device *dev = skb->dev;
    struct in_device *in_dev = in_dev_get(dev);
    struct arphdr *arp;
    unsigned char *arp_ptr;
    struct rtable *rt;
    unsigned char *sha;
    __be32 sip, tip;
    u16 dev_type = dev->type;
    int addr_type;
    struct neighbour *n;
    struct net *net = dev_net(dev);

    /* arp_rcv below verifies the ARP header and verifies the device
     * is ARP'able.
     */

    if (in_dev == NULL)
        goto out;

    arp = arp_hdr(skb);

    switch (dev_type) {
    default:
        if (arp->ar_pro != htons(ETH_P_IP) ||
            htons(dev_type) != arp->ar_hrd)
            goto out;
        break;
    case ARPHRD_ETHER:
    case ARPHRD_IEEE802_TR:
    case ARPHRD_FDDI:
    case ARPHRD_IEEE802:
        /*
         * ETHERNET, Token Ring and Fibre Channel (which are IEEE 802
         * devices, according to RFC 2625) devices will accept ARP
         * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2).
         * This is the case also of FDDI, where the RFC 1390 says that
         * FDDI devices should accept ARP hardware of (1) Ethernet,
         * however, to be more robust, we'll accept both 1 (Ethernet)
         * or 6 (IEEE 802.2)
         */
        if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
             arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
            arp->ar_pro != htons(ETH_P_IP))
            goto out;
        break;
    case ARPHRD_AX25:
        if (arp->ar_pro != htons(AX25_P_IP) ||
            arp->ar_hrd != htons(ARPHRD_AX25))
            goto out;
        break;
    case ARPHRD_NETROM:
        if (arp->ar_pro != htons(AX25_P_IP) ||
            arp->ar_hrd != htons(ARPHRD_NETROM))
            goto out;
        break;
    }

    /* Understand only these message types */

    if (arp->ar_op != htons(ARPOP_REPLY) &&
        arp->ar_op != htons(ARPOP_REQUEST))
        goto out;

/*
 *    Extract fields
 */
    arp_ptr= (unsigned char *)(arp+1);
    sha    = arp_ptr;
    arp_ptr += dev->addr_len;
    memcpy(&sip, arp_ptr, 4);
    arp_ptr += 4;
    arp_ptr += dev->addr_len;
    memcpy(&tip, arp_ptr, 4);
/*
 *    Check for bad requests for 127.x.x.x and requests for multicast
 *    addresses.  If this is one such, delete it.
 */
    if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
        goto out;

/*
 *     Special case: We must set Frame Relay source Q.922 address
 */
    if (dev_type == ARPHRD_DLCI)
        sha = dev->broadcast;

/*
 *  Process entry.  The idea here is we want to send a reply if it is a
 *  request for us or if it is a request for someone else that we hold
 *  a proxy for.  We want to add an entry to our cache if it is a reply
 *  to us or if it is a request for our address.
 *  (The assumption for this last is that if someone is requesting our
 *  address, they are probably intending to talk to us, so it saves time
 *  if we cache their address.  Their address is also probably not in
 *  our cache, since ours is not in their cache.)
 *
 *  Putting this another way, we only care about replies if they are to
 *  us, in which case we add them to the cache.  For requests, we care
 *  about those for us and those for our proxies.  We reply to both,
 *  and in the case of requests for us we add the requester to the arp
 *  cache.
 */

    /* Special case: IPv4 duplicate address detection packet (RFC2131) */
    if (sip == 0) {
        if (arp->ar_op == htons(ARPOP_REQUEST) &&
            inet_addr_type(net, tip) == RTN_LOCAL &&
            !arp_ignore(in_dev, sip, tip))
            arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha,
                 dev->dev_addr, sha);
        goto out;
    }

    if (arp->ar_op == htons(ARPOP_REQUEST) &&
        ip_route_input(skb, tip, sip, 0, dev) == 0) {

        rt = skb->rtable;
        addr_type = rt->rt_type;

        if (addr_type == RTN_LOCAL) {
            n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
            if (n) {
                int dont_send = 0;

                if (!dont_send)
                    dont_send |= arp_ignore(in_dev,sip,tip);
                if (!dont_send && IN_DEV_ARPFILTER(in_dev))
                    dont_send |= arp_filter(sip,tip,dev);
                if (!dont_send)
                    arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);

                neigh_release(n);
            }
            goto out;
        } else if (IN_DEV_FORWARD(in_dev)) {
                if (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
                 (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) {
                n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
                if (n)
                    neigh_release(n);

                if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
                    skb->pkt_type == PACKET_HOST ||
                    in_dev->arp_parms->proxy_delay == 0) {
                    arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
                } else {
                    pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb);
                    in_dev_put(in_dev);
                    return 0;
                }
                goto out;
            }
        }
    }

    /* Update our ARP tables */

    n = __neigh_lookup(&arp_tbl, &sip, dev, 0);

    if (IPV4_DEVCONF_ALL(dev_net(dev), ARP_ACCEPT)) {
        /* Unsolicited ARP is not accepted by default.
           It is possible, that this option should be enabled for some
           devices (strip is candidate)
         */
        if (n == NULL &&
            arp->ar_op == htons(ARPOP_REPLY) &&
            inet_addr_type(net, sip) == RTN_UNICAST)
            n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
    }

    if (n) {
        int state = NUD_REACHABLE;
        int override;

        /* If several different ARP replies follows back-to-back,
           use the FIRST one. It is possible, if several proxy
           agents are active. Taking the first reply prevents
           arp trashing and chooses the fastest router.
         */
        override = time_after(jiffies, n->updated + n->parms->locktime);

        /* Broadcast replies and request packets
           do not assert neighbour reachability.
         */
        if (arp->ar_op != htons(ARPOP_REPLY) ||
            skb->pkt_type != PACKET_HOST)
            state = NUD_STALE;
        neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0);
        neigh_release(n);
    }
Exemplo n.º 18
0
static void arp_reply(struct sk_buff *skb)
{
	struct netpoll_info *npinfo = skb->dev->npinfo;
	struct arphdr *arp;
	unsigned char *arp_ptr;
	int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
	__be32 sip, tip;
	unsigned char *sha;
	struct sk_buff *send_skb;
	struct netpoll *np = NULL;

	if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev)
		np = npinfo->rx_np;
	if (!np)
		return;

	/* No arp on this interface */
	if (skb->dev->flags & IFF_NOARP)
		return;

	if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
				 (2 * skb->dev->addr_len) +
				 (2 * sizeof(u32)))))
		return;

	skb_reset_network_header(skb);
	skb_reset_transport_header(skb);
	arp = arp_hdr(skb);

	if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
	     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
	    arp->ar_pro != htons(ETH_P_IP) ||
	    arp->ar_op != htons(ARPOP_REQUEST))
		return;

	arp_ptr = (unsigned char *)(arp+1);
	/* save the location of the src hw addr */
	sha = arp_ptr;
	arp_ptr += skb->dev->addr_len;
	memcpy(&sip, arp_ptr, 4);
	arp_ptr += 4;
	/* if we actually cared about dst hw addr, it would get copied here */
	arp_ptr += skb->dev->addr_len;
	memcpy(&tip, arp_ptr, 4);

	/* Should we ignore arp? */
	if (tip != htonl(np->local_ip) || LOOPBACK(tip) || MULTICAST(tip))
		return;

	size = sizeof(struct arphdr) + 2 * (skb->dev->addr_len + 4);
	send_skb = find_skb(np, size + LL_RESERVED_SPACE(np->dev),
			    LL_RESERVED_SPACE(np->dev));

	if (!send_skb)
		return;

	skb_reset_network_header(send_skb);
	arp = (struct arphdr *) skb_put(send_skb, size);
	send_skb->dev = skb->dev;
	send_skb->protocol = htons(ETH_P_ARP);

	/* Fill the device header for the ARP frame */

	if (np->dev->hard_header &&
	    np->dev->hard_header(send_skb, skb->dev, ptype,
				 sha, np->local_mac,
				 send_skb->len) < 0) {
		kfree_skb(send_skb);
		return;
	}

	/*
	 * Fill out the arp protocol part.
	 *
	 * we only support ethernet device type,
	 * which (according to RFC 1390) should always equal 1 (Ethernet).
	 */

	arp->ar_hrd = htons(np->dev->type);
	arp->ar_pro = htons(ETH_P_IP);
	arp->ar_hln = np->dev->addr_len;
	arp->ar_pln = 4;
	arp->ar_op = htons(type);

	arp_ptr=(unsigned char *)(arp + 1);
	memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len);
	arp_ptr += np->dev->addr_len;
	memcpy(arp_ptr, &tip, 4);
	arp_ptr += 4;
	memcpy(arp_ptr, sha, np->dev->addr_len);
	arp_ptr += np->dev->addr_len;
	memcpy(arp_ptr, &sip, 4);

	netpoll_send_skb(np, send_skb);
}
	 * Ensure we load private-> members after we've fetched the base
	 * pointer.
	 */
	smp_read_barrier_depends();
	table_base = private->entries[smp_processor_id()];

	e = get_entry(table_base, private->hook_entry[hook]);
	back = get_entry(table_base, private->underflow[hook]);

	acpar.in      = in;
	acpar.out     = out;
	acpar.hooknum = hook;
	acpar.family  = NFPROTO_ARP;
	acpar.hotdrop = false;

	arp = arp_hdr(skb);
	do {
		const struct xt_entry_target *t;

		if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
			e = arpt_next_entry(e);
			continue;
		}

		ADD_COUNTER(e->counters, arp_hdr_len(skb->dev), 1);

		t = arpt_get_target_c(e);

		/* Standard target? */
		if (!t->u.kernel.target->target) {
			int v;
Exemplo n.º 20
0
static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	struct arphdr *arp;
	unsigned char *arp_ptr;
	struct rtable *rt;
	unsigned char *sha;
	unsigned char *tha = NULL;
	__be32 sip, tip;
	u16 dev_type = dev->type;
	int addr_type;
	struct neighbour *n;
	struct dst_entry *reply_dst = NULL;
	bool is_garp = false;

	/* arp_rcv below verifies the ARP header and verifies the device
	 * is ARP'able.
	 */

	if (!in_dev)
		goto out_free_skb;

	arp = arp_hdr(skb);

	switch (dev_type) {
	default:
		if (arp->ar_pro != htons(ETH_P_IP) ||
		    htons(dev_type) != arp->ar_hrd)
			goto out_free_skb;
		break;
	case ARPHRD_ETHER:
	case ARPHRD_FDDI:
	case ARPHRD_IEEE802:
		/*
		 * ETHERNET, and Fibre Channel (which are IEEE 802
		 * devices, according to RFC 2625) devices will accept ARP
		 * hardware types of either 1 (Ethernet) or 6 (IEEE 802.2).
		 * This is the case also of FDDI, where the RFC 1390 says that
		 * FDDI devices should accept ARP hardware of (1) Ethernet,
		 * however, to be more robust, we'll accept both 1 (Ethernet)
		 * or 6 (IEEE 802.2)
		 */
		if ((arp->ar_hrd != htons(ARPHRD_ETHER) &&
		     arp->ar_hrd != htons(ARPHRD_IEEE802)) ||
		    arp->ar_pro != htons(ETH_P_IP))
			goto out_free_skb;
		break;
	case ARPHRD_AX25:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_AX25))
			goto out_free_skb;
		break;
	case ARPHRD_NETROM:
		if (arp->ar_pro != htons(AX25_P_IP) ||
		    arp->ar_hrd != htons(ARPHRD_NETROM))
			goto out_free_skb;
		break;
	}

	/* Understand only these message types */

	if (arp->ar_op != htons(ARPOP_REPLY) &&
	    arp->ar_op != htons(ARPOP_REQUEST))
		goto out_free_skb;

/*
 *	Extract fields
 */
	arp_ptr = (unsigned char *)(arp + 1);
	sha	= arp_ptr;
	arp_ptr += dev->addr_len;
	memcpy(&sip, arp_ptr, 4);
	arp_ptr += 4;
	switch (dev_type) {
#if IS_ENABLED(CONFIG_FIREWIRE_NET)
	case ARPHRD_IEEE1394:
		break;
#endif
	default:
		tha = arp_ptr;
		arp_ptr += dev->addr_len;
	}
	memcpy(&tip, arp_ptr, 4);
/*
 *	Check for bad requests for 127.x.x.x and requests for multicast
 *	addresses.  If this is one such, delete it.
 */
	if (ipv4_is_multicast(tip) ||
	    (!IN_DEV_ROUTE_LOCALNET(in_dev) && ipv4_is_loopback(tip)))
		goto out_free_skb;

 /*
  *	For some 802.11 wireless deployments (and possibly other networks),
  *	there will be an ARP proxy and gratuitous ARP frames are attacks
  *	and thus should not be accepted.
  */
	if (sip == tip && IN_DEV_ORCONF(in_dev, DROP_GRATUITOUS_ARP))
		goto out_free_skb;

/*
 *     Special case: We must set Frame Relay source Q.922 address
 */
	if (dev_type == ARPHRD_DLCI)
		sha = dev->broadcast;

/*
 *  Process entry.  The idea here is we want to send a reply if it is a
 *  request for us or if it is a request for someone else that we hold
 *  a proxy for.  We want to add an entry to our cache if it is a reply
 *  to us or if it is a request for our address.
 *  (The assumption for this last is that if someone is requesting our
 *  address, they are probably intending to talk to us, so it saves time
 *  if we cache their address.  Their address is also probably not in
 *  our cache, since ours is not in their cache.)
 *
 *  Putting this another way, we only care about replies if they are to
 *  us, in which case we add them to the cache.  For requests, we care
 *  about those for us and those for our proxies.  We reply to both,
 *  and in the case of requests for us we add the requester to the arp
 *  cache.
 */

	if (arp->ar_op == htons(ARPOP_REQUEST) && skb_metadata_dst(skb))
		reply_dst = (struct dst_entry *)
			    iptunnel_metadata_reply(skb_metadata_dst(skb),
						    GFP_ATOMIC);

	/* Special case: IPv4 duplicate address detection packet (RFC2131) */
	if (sip == 0) {
		if (arp->ar_op == htons(ARPOP_REQUEST) &&
		    inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL &&
		    !arp_ignore(in_dev, sip, tip))
			arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
				     sha, dev->dev_addr, sha, reply_dst);
		goto out_consume_skb;
	}

	if (arp->ar_op == htons(ARPOP_REQUEST) &&
	    ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {

		rt = skb_rtable(skb);
		addr_type = rt->rt_type;

		if (addr_type == RTN_LOCAL) {
			int dont_send;

			dont_send = arp_ignore(in_dev, sip, tip);
			if (!dont_send && IN_DEV_ARPFILTER(in_dev))
				dont_send = arp_filter(sip, tip, dev);
			if (!dont_send) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n) {
					arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
						     sip, dev, tip, sha,
						     dev->dev_addr, sha,
						     reply_dst);
					neigh_release(n);
				}
			}
			goto out_consume_skb;
		} else if (IN_DEV_FORWARD(in_dev)) {
			if (addr_type == RTN_UNICAST  &&
			    (arp_fwd_proxy(in_dev, dev, rt) ||
			     arp_fwd_pvlan(in_dev, dev, rt, sip, tip) ||
			     (rt->dst.dev != dev &&
			      pneigh_lookup(&arp_tbl, net, &tip, dev, 0)))) {
				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
				if (n)
					neigh_release(n);

				if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
				    skb->pkt_type == PACKET_HOST ||
				    NEIGH_VAR(in_dev->arp_parms, PROXY_DELAY) == 0) {
					arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
						     sip, dev, tip, sha,
						     dev->dev_addr, sha,
						     reply_dst);
				} else {
					pneigh_enqueue(&arp_tbl,
						       in_dev->arp_parms, skb);
					goto out_free_dst;
				}
				goto out_consume_skb;
			}
		}
	}

	/* Update our ARP tables */

	n = __neigh_lookup(&arp_tbl, &sip, dev, 0);

	addr_type = -1;
	if (n || IN_DEV_ARP_ACCEPT(in_dev)) {
		is_garp = arp_is_garp(net, dev, &addr_type, arp->ar_op,
				      sip, tip, sha, tha);
	}

	if (IN_DEV_ARP_ACCEPT(in_dev)) {
		/* Unsolicited ARP is not accepted by default.
		   It is possible, that this option should be enabled for some
		   devices (strip is candidate)
		 */
		if (!n &&
		    (is_garp ||
		     (arp->ar_op == htons(ARPOP_REPLY) &&
		      (addr_type == RTN_UNICAST ||
		       (addr_type < 0 &&
			/* postpone calculation to as late as possible */
			inet_addr_type_dev_table(net, dev, sip) ==
				RTN_UNICAST)))))
			n = __neigh_lookup(&arp_tbl, &sip, dev, 1);
	}

	if (n) {
		int state = NUD_REACHABLE;
		int override;

		/* If several different ARP replies follows back-to-back,
		   use the FIRST one. It is possible, if several proxy
		   agents are active. Taking the first reply prevents
		   arp trashing and chooses the fastest router.
		 */
		override = time_after(jiffies,
				      n->updated +
				      NEIGH_VAR(n->parms, LOCKTIME)) ||
			   is_garp;

		/* Broadcast replies and request packets
		   do not assert neighbour reachability.
		 */
		if (arp->ar_op != htons(ARPOP_REPLY) ||
		    skb->pkt_type != PACKET_HOST)
			state = NUD_STALE;
		neigh_update(n, sha, state,
			     override ? NEIGH_UPDATE_F_OVERRIDE : 0, 0);
		neigh_release(n);
	}