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: Ben Greear <greearb@candelatech.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
160ff18a07
Коммит
827d978037
|
@ -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)
|
||||||
|
|
||||||
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)
|
||||||
+ 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,7 +1089,8 @@ out_status:
|
||||||
__packet_set_status(po, ph, status);
|
__packet_set_status(po, ph, status);
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
out_put:
|
out_put:
|
||||||
dev_put(dev);
|
if (need_rls_dev)
|
||||||
|
dev_put(dev);
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&po->pg_vec_lock);
|
mutex_unlock(&po->pg_vec_lock);
|
||||||
return err;
|
return err;
|
||||||
|
@ -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,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
||||||
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,14 +1287,15 @@ 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;
|
||||||
|
|
||||||
dev_put(dev);
|
if (need_rls_dev)
|
||||||
|
dev_put(dev);
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче