X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Farp.c;h=3981e8be9ab8f34e5504815c1f4b130ec068ee14;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=9b4b93364164057c6e41c87e860f53423994e13e;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 9b4b93364..3981e8be9 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1,4 +1,4 @@ -/* linux/net/inet/arp.c +/* linux/net/ipv4/arp.c * * Version: $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $ * @@ -79,13 +79,14 @@ #include #include #include -#include +#include #include #include #include #include #include #include +#include #include #include #include @@ -202,7 +203,7 @@ struct neigh_table arp_tbl = { .gc_thresh3 = 1024, }; -int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir) +int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) { switch (dev->type) { case ARPHRD_ETHER: @@ -233,7 +234,7 @@ static u32 arp_hash(const void *pkey, const struct net_device *dev) static int arp_constructor(struct neighbour *neigh) { - u32 addr = *(u32*)neigh->primary_key; + __be32 addr = *(__be32*)neigh->primary_key; struct net_device *dev = neigh->dev; struct in_device *in_dev; struct neigh_parms *parms; @@ -241,7 +242,7 @@ static int arp_constructor(struct neighbour *neigh) neigh->type = inet_addr_type(addr); rcu_read_lock(); - in_dev = rcu_dereference(__in_dev_get(dev)); + in_dev = __in_dev_get_rcu(dev); if (in_dev == NULL) { rcu_read_unlock(); return -EINVAL; @@ -329,10 +330,10 @@ static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb) static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) { - u32 saddr = 0; + __be32 saddr = 0; u8 *dst_ha = NULL; struct net_device *dev = neigh->dev; - u32 target = *(u32*)neigh->primary_key; + __be32 target = *(__be32*)neigh->primary_key; int probes = atomic_read(&neigh->probes); struct in_device *in_dev = in_dev_get(dev); @@ -384,7 +385,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) } static int arp_ignore(struct in_device *in_dev, struct net_device *dev, - u32 sip, u32 tip) + __be32 sip, __be32 tip) { int scope; @@ -419,7 +420,7 @@ static int arp_ignore(struct in_device *in_dev, struct net_device *dev, return !inet_confirm_addr(dev, sip, tip, scope); } -static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev) +static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) { struct flowi fl = { .nl_u = { .ip4_u = { .daddr = sip, .saddr = tip } } }; @@ -448,7 +449,7 @@ static int arp_filter(__u32 sip, __u32 tip, struct net_device *dev) * is allowed to use this function, it is scheduled to be removed. --ANK */ -static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, struct net_device * dev) +static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev) { switch (addr_hint) { case RTN_LOCAL: @@ -469,7 +470,7 @@ static int arp_set_predefined(int addr_hint, unsigned char * haddr, u32 paddr, s int arp_find(unsigned char *haddr, struct sk_buff *skb) { struct net_device *dev = skb->dev; - u32 paddr; + __be32 paddr; struct neighbour *n; if (!skb->dst) { @@ -510,7 +511,7 @@ int arp_bind_neighbour(struct dst_entry *dst) if (dev == NULL) return -EINVAL; if (n == NULL) { - u32 nexthop = ((struct rtable*)dst)->rt_gateway; + __be32 nexthop = ((struct rtable*)dst)->rt_gateway; if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT)) nexthop = 0; n = __neigh_lookup_errno( @@ -559,8 +560,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, struct rtable *rt) * Create an arp packet. If (dest_hw == NULL), we create a broadcast * message. */ -struct sk_buff *arp_create(int type, int ptype, u32 dest_ip, - struct net_device *dev, u32 src_ip, +struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, + struct net_device *dev, __be32 src_ip, unsigned char *dest_hw, unsigned char *src_hw, unsigned char *target_hw) { @@ -674,8 +675,8 @@ void arp_xmit(struct sk_buff *skb) /* * Create and send an arp packet. */ -void arp_send(int type, int ptype, u32 dest_ip, - struct net_device *dev, u32 src_ip, +void arp_send(int type, int ptype, __be32 dest_ip, + struct net_device *dev, __be32 src_ip, unsigned char *dest_hw, unsigned char *src_hw, unsigned char *target_hw) { @@ -697,12 +698,6 @@ void arp_send(int type, int ptype, u32 dest_ip, arp_xmit(skb); } -static void parp_redo(struct sk_buff *skb) -{ - nf_reset(skb); - arp_rcv(skb, skb->dev, NULL); -} - /* * Process an arp request. */ @@ -715,7 +710,7 @@ static int arp_process(struct sk_buff *skb) unsigned char *arp_ptr; struct rtable *rt; unsigned char *sha, *tha; - u32 sip, tip; + __be32 sip, tip; u16 dev_type = dev->type; int addr_type; struct neighbour *n; @@ -865,7 +860,7 @@ static int arp_process(struct sk_buff *skb) if (n) neigh_release(n); - if (skb->stamp.tv_sec == LOCALLY_ENQUEUED || + 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); @@ -883,16 +878,16 @@ static int arp_process(struct sk_buff *skb) n = __neigh_lookup(&arp_tbl, &sip, dev, 0); -#ifdef CONFIG_IP_ACCEPT_UNSOLICITED_ARP - /* 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(sip) == RTN_UNICAST) - n = __neigh_lookup(&arp_tbl, &sip, dev, -1); -#endif + if (ipv4_devconf.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(sip) == RTN_UNICAST) + n = __neigh_lookup(&arp_tbl, &sip, dev, -1); + } if (n) { int state = NUD_REACHABLE; @@ -922,12 +917,18 @@ out: return 0; } +static void parp_redo(struct sk_buff *skb) +{ + arp_process(skb); +} + /* * Receive an arp request from the device layer. */ -int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +static int arp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt, struct net_device *orig_dev) { struct arphdr *arp; @@ -948,6 +949,8 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) 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: @@ -966,13 +969,13 @@ out_of_mem: static int arp_req_set(struct arpreq *r, struct net_device * dev) { - u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; + __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; struct neighbour *neigh; int err; if (r->arp_flags&ATF_PUBL) { - u32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr; - if (mask && mask != 0xFFFFFFFF) + __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr; + if (mask && mask != htonl(0xFFFFFFFF)) return -EINVAL; if (!dev && (r->arp_flags & ATF_COM)) { dev = dev_getbyhwaddr(r->arp_ha.sa_family, r->arp_ha.sa_data); @@ -988,8 +991,8 @@ static int arp_req_set(struct arpreq *r, struct net_device * dev) ipv4_devconf.proxy_arp = 1; return 0; } - if (__in_dev_get(dev)) { - __in_dev_get(dev)->cnf.proxy_arp = 1; + if (__in_dev_get_rtnl(dev)) { + __in_dev_get_rtnl(dev)->cnf.proxy_arp = 1; return 0; } return -ENXIO; @@ -1060,7 +1063,7 @@ static unsigned arp_state_to_flags(struct neighbour *neigh) static int arp_req_get(struct arpreq *r, struct net_device *dev) { - u32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; + __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; struct neighbour *neigh; int err = -ENXIO; @@ -1081,21 +1084,21 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) static int arp_req_delete(struct arpreq *r, struct net_device * dev) { int err; - u32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; + __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; struct neighbour *neigh; if (r->arp_flags & ATF_PUBL) { - u32 mask = + __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr; - if (mask == 0xFFFFFFFF) + if (mask == htonl(0xFFFFFFFF)) return pneigh_delete(&arp_tbl, &ip, dev); if (mask == 0) { if (dev == NULL) { ipv4_devconf.proxy_arp = 0; return 0; } - if (__in_dev_get(dev)) { - __in_dev_get(dev)->cnf.proxy_arp = 0; + if (__in_dev_get_rtnl(dev)) { + __in_dev_get_rtnl(dev)->cnf.proxy_arp = 0; return 0; } return -ENXIO; @@ -1243,7 +1246,7 @@ void __init arp_init(void) arp_proc_init(); #ifdef CONFIG_SYSCTL neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, - NET_IPV4_NEIGH, "ipv4", NULL); + NET_IPV4_NEIGH, "ipv4", NULL, NULL); #endif register_netdevice_notifier(&arp_netdev_notifier); } @@ -1369,12 +1372,11 @@ static int arp_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; - memset(s, 0, sizeof(*s)); rc = seq_open(file, &arp_seq_ops); if (rc) goto out_kfree; @@ -1414,7 +1416,6 @@ static int __init arp_proc_init(void) EXPORT_SYMBOL(arp_broken_ops); EXPORT_SYMBOL(arp_find); -EXPORT_SYMBOL(arp_rcv); EXPORT_SYMBOL(arp_create); EXPORT_SYMBOL(arp_xmit); EXPORT_SYMBOL(arp_send);