Commit 827d9780 authored by Ben Greear's avatar Ben Greear Committed by David S. Miller

af-packet: Use existing netdev reference for bound sockets.

This saves a network device lookup on each packet transmitted,
for sockets that are bound to a network device.
Signed-off-by: default avatarBen Greear <greearb@candelatech.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 160ff18a
...@@ -974,7 +974,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -974,7 +974,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
struct sk_buff *skb; struct sk_buff *skb;
struct net_device *dev; struct net_device *dev;
__be16 proto; __be16 proto;
int ifindex, err, reserve = 0; bool need_rls_dev = false;
int err, reserve = 0;
void *ph; void *ph;
struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name;
int tp_len, size_max; int tp_len, size_max;
...@@ -986,7 +987,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -986,7 +987,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
err = -EBUSY; err = -EBUSY;
if (saddr == NULL) { if (saddr == NULL) {
ifindex = po->ifindex; dev = po->prot_hook.dev;
proto = po->num; proto = po->num;
addr = NULL; addr = NULL;
} else { } else {
...@@ -997,12 +998,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -997,12 +998,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+ offsetof(struct sockaddr_ll, + offsetof(struct sockaddr_ll,
sll_addr))) sll_addr)))
goto out; goto out;
ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol; proto = saddr->sll_protocol;
addr = saddr->sll_addr; addr = saddr->sll_addr;
dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
need_rls_dev = true;
} }
dev = dev_get_by_index(sock_net(&po->sk), ifindex);
err = -ENXIO; err = -ENXIO;
if (unlikely(dev == NULL)) if (unlikely(dev == NULL))
goto out; goto out;
...@@ -1088,6 +1089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) ...@@ -1088,6 +1089,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
__packet_set_status(po, ph, status); __packet_set_status(po, ph, status);
kfree_skb(skb); kfree_skb(skb);
out_put: out_put:
if (need_rls_dev)
dev_put(dev); dev_put(dev);
out: out:
mutex_unlock(&po->pg_vec_lock); mutex_unlock(&po->pg_vec_lock);
...@@ -1126,8 +1128,9 @@ static int packet_snd(struct socket *sock, ...@@ -1126,8 +1128,9 @@ static int packet_snd(struct socket *sock,
struct sk_buff *skb; struct sk_buff *skb;
struct net_device *dev; struct net_device *dev;
__be16 proto; __be16 proto;
bool need_rls_dev = false;
unsigned char *addr; unsigned char *addr;
int ifindex, err, reserve = 0; int err, reserve = 0;
struct virtio_net_hdr vnet_hdr = { 0 }; struct virtio_net_hdr vnet_hdr = { 0 };
int offset = 0; int offset = 0;
int vnet_hdr_len; int vnet_hdr_len;
...@@ -1139,7 +1142,7 @@ static int packet_snd(struct socket *sock, ...@@ -1139,7 +1142,7 @@ static int packet_snd(struct socket *sock,
*/ */
if (saddr == NULL) { if (saddr == NULL) {
ifindex = po->ifindex; dev = po->prot_hook.dev;
proto = po->num; proto = po->num;
addr = NULL; addr = NULL;
} else { } else {
...@@ -1148,13 +1151,12 @@ static int packet_snd(struct socket *sock, ...@@ -1148,13 +1151,12 @@ static int packet_snd(struct socket *sock,
goto out; goto out;
if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
goto out; goto out;
ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol; proto = saddr->sll_protocol;
addr = saddr->sll_addr; addr = saddr->sll_addr;
dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
need_rls_dev = true;
} }
dev = dev_get_by_index(sock_net(sk), ifindex);
err = -ENXIO; err = -ENXIO;
if (dev == NULL) if (dev == NULL)
goto out_unlock; goto out_unlock;
...@@ -1285,6 +1287,7 @@ static int packet_snd(struct socket *sock, ...@@ -1285,6 +1287,7 @@ static int packet_snd(struct socket *sock,
if (err > 0 && (err = net_xmit_errno(err)) != 0) if (err > 0 && (err = net_xmit_errno(err)) != 0)
goto out_unlock; goto out_unlock;
if (need_rls_dev)
dev_put(dev); dev_put(dev);
return len; return len;
...@@ -1292,7 +1295,7 @@ static int packet_snd(struct socket *sock, ...@@ -1292,7 +1295,7 @@ static int packet_snd(struct socket *sock,
out_free: out_free:
kfree_skb(skb); kfree_skb(skb);
out_unlock: out_unlock:
if (dev) if (dev && need_rls_dev)
dev_put(dev); dev_put(dev);
out: out:
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment