Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150533
b: refs/heads/master
c: 5615968
h: refs/heads/master
i:
  150531: 8f92840
v: v3
  • Loading branch information
David S. Miller committed May 27, 2009
1 parent 3f915a5 commit edf1418
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 385a154cac8763284f65cdfa25f6796c9eb1ca21
refs/heads/master: 5615968a70845157adaffc11062c997d045339ee
40 changes: 32 additions & 8 deletions trunk/drivers/net/appletalk/ipddp.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n";

static struct ipddp_route *ipddp_route_list;
static DEFINE_SPINLOCK(ipddp_route_lock);

#ifdef CONFIG_IPDDP_ENCAP
static int ipddp_mode = IPDDP_ENCAP;
Expand All @@ -50,7 +51,7 @@ static int ipddp_mode = IPDDP_DECAP;
static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
static int ipddp_create(struct ipddp_route *new_rt);
static int ipddp_delete(struct ipddp_route *rt);
static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);

static const struct net_device_ops ipddp_netdev_ops = {
Expand Down Expand Up @@ -119,6 +120,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
struct ipddp_route *rt;
struct atalk_addr *our_addr;

spin_lock(&ipddp_route_lock);

/*
* Find appropriate route to use, based only on IP number.
*/
Expand All @@ -127,8 +130,10 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
if(rt->ip == paddr)
break;
}
if(rt == NULL)
if(rt == NULL) {
spin_unlock(&ipddp_route_lock);
return 0;
}

our_addr = atalk_find_dev_addr(rt->dev);

Expand Down Expand Up @@ -174,6 +179,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
dev_kfree_skb(skb);

spin_unlock(&ipddp_route_lock);

return 0;
}

Expand All @@ -196,14 +203,18 @@ static int ipddp_create(struct ipddp_route *new_rt)
return -ENETUNREACH;
}

if (ipddp_find_route(rt)) {
spin_lock_bh(&ipddp_route_lock);
if (__ipddp_find_route(rt)) {
spin_unlock_bh(&ipddp_route_lock);
kfree(rt);
return -EEXIST;
}

rt->next = ipddp_route_list;
ipddp_route_list = rt;

spin_unlock_bh(&ipddp_route_lock);

return 0;
}

Expand All @@ -216,26 +227,29 @@ static int ipddp_delete(struct ipddp_route *rt)
struct ipddp_route **r = &ipddp_route_list;
struct ipddp_route *tmp;

spin_lock_bh(&ipddp_route_lock);
while((tmp = *r) != NULL)
{
if(tmp->ip == rt->ip
&& tmp->at.s_net == rt->at.s_net
&& tmp->at.s_node == rt->at.s_node)
{
*r = tmp->next;
spin_unlock_bh(&ipddp_route_lock);
kfree(tmp);
return 0;
}
r = &tmp->next;
}

spin_unlock_bh(&ipddp_route_lock);
return (-ENOENT);
}

/*
* Find a routing entry, we only return a FULL match
*/
static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
{
struct ipddp_route *f;

Expand All @@ -253,7 +267,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct ipddp_route __user *rt = ifr->ifr_data;
struct ipddp_route rcp;
struct ipddp_route rcp, rcp2, *rp;

if(!capable(CAP_NET_ADMIN))
return -EPERM;
Expand All @@ -267,9 +281,19 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return (ipddp_create(&rcp));

case SIOCFINDIPDDPRT:
if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
return -EFAULT;
return 0;
spin_lock_bh(&ipddp_route_lock);
rp = __ipddp_find_route(&rcp);
if (rp)
memcpy(&rcp2, rp, sizeof(rcp2));
spin_unlock_bh(&ipddp_route_lock);

if (rp) {
if (copy_to_user(rt, &rcp2,
sizeof(struct ipddp_route)))
return -EFAULT;
return 0;
} else
return -ENOENT;

case SIOCDELIPDDPRT:
return (ipddp_delete(&rcp));
Expand Down

0 comments on commit edf1418

Please sign in to comment.