diff options
author | Ben Greear <greearb@candelatech.com> | 2011-06-01 03:18:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-05 17:16:28 -0400 |
commit | 827d978037d7d0bf0860481948c6d26ead10042f (patch) | |
tree | ddd6f73b342116f330694528d993a2fa373b3b36 /net/packet/af_packet.c | |
parent | 160ff18a07f3a505d452dcced8e45ecdd0a85506 (diff) |
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>
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r-- | net/packet/af_packet.c | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 636b75c15a63..67f6749a0a45 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -974,7 +974,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
974 | struct sk_buff *skb; | 974 | struct sk_buff *skb; |
975 | struct net_device *dev; | 975 | struct net_device *dev; |
976 | __be16 proto; | 976 | __be16 proto; |
977 | int ifindex, err, reserve = 0; | 977 | bool need_rls_dev = false; |
978 | int err, reserve = 0; | ||
978 | void *ph; | 979 | void *ph; |
979 | struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; | 980 | struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; |
980 | int tp_len, size_max; | 981 | int tp_len, size_max; |
@@ -986,7 +987,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
986 | 987 | ||
987 | err = -EBUSY; | 988 | err = -EBUSY; |
988 | if (saddr == NULL) { | 989 | if (saddr == NULL) { |
989 | ifindex = po->ifindex; | 990 | dev = po->prot_hook.dev; |
990 | proto = po->num; | 991 | proto = po->num; |
991 | addr = NULL; | 992 | addr = NULL; |
992 | } else { | 993 | } else { |
@@ -997,12 +998,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
997 | + offsetof(struct sockaddr_ll, | 998 | + offsetof(struct sockaddr_ll, |
998 | sll_addr))) | 999 | sll_addr))) |
999 | goto out; | 1000 | goto out; |
1000 | ifindex = saddr->sll_ifindex; | ||
1001 | proto = saddr->sll_protocol; | 1001 | proto = saddr->sll_protocol; |
1002 | addr = saddr->sll_addr; | 1002 | addr = saddr->sll_addr; |
1003 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | ||
1004 | need_rls_dev = true; | ||
1003 | } | 1005 | } |
1004 | 1006 | ||
1005 | dev = dev_get_by_index(sock_net(&po->sk), ifindex); | ||
1006 | err = -ENXIO; | 1007 | err = -ENXIO; |
1007 | if (unlikely(dev == NULL)) | 1008 | if (unlikely(dev == NULL)) |
1008 | goto out; | 1009 | goto out; |
@@ -1088,7 +1089,8 @@ out_status: | |||
1088 | __packet_set_status(po, ph, status); | 1089 | __packet_set_status(po, ph, status); |
1089 | kfree_skb(skb); | 1090 | kfree_skb(skb); |
1090 | out_put: | 1091 | out_put: |
1091 | dev_put(dev); | 1092 | if (need_rls_dev) |
1093 | dev_put(dev); | ||
1092 | out: | 1094 | out: |
1093 | mutex_unlock(&po->pg_vec_lock); | 1095 | mutex_unlock(&po->pg_vec_lock); |
1094 | return err; | 1096 | return err; |
@@ -1126,8 +1128,9 @@ static int packet_snd(struct socket *sock, | |||
1126 | struct sk_buff *skb; | 1128 | struct sk_buff *skb; |
1127 | struct net_device *dev; | 1129 | struct net_device *dev; |
1128 | __be16 proto; | 1130 | __be16 proto; |
1131 | bool need_rls_dev = false; | ||
1129 | unsigned char *addr; | 1132 | unsigned char *addr; |
1130 | int ifindex, err, reserve = 0; | 1133 | int err, reserve = 0; |
1131 | struct virtio_net_hdr vnet_hdr = { 0 }; | 1134 | struct virtio_net_hdr vnet_hdr = { 0 }; |
1132 | int offset = 0; | 1135 | int offset = 0; |
1133 | int vnet_hdr_len; | 1136 | int vnet_hdr_len; |
@@ -1139,7 +1142,7 @@ static int packet_snd(struct socket *sock, | |||
1139 | */ | 1142 | */ |
1140 | 1143 | ||
1141 | if (saddr == NULL) { | 1144 | if (saddr == NULL) { |
1142 | ifindex = po->ifindex; | 1145 | dev = po->prot_hook.dev; |
1143 | proto = po->num; | 1146 | proto = po->num; |
1144 | addr = NULL; | 1147 | addr = NULL; |
1145 | } else { | 1148 | } else { |
@@ -1148,13 +1151,12 @@ static int packet_snd(struct socket *sock, | |||
1148 | goto out; | 1151 | goto out; |
1149 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) | 1152 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) |
1150 | goto out; | 1153 | goto out; |
1151 | ifindex = saddr->sll_ifindex; | ||
1152 | proto = saddr->sll_protocol; | 1154 | proto = saddr->sll_protocol; |
1153 | addr = saddr->sll_addr; | 1155 | addr = saddr->sll_addr; |
1156 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); | ||
1157 | need_rls_dev = true; | ||
1154 | } | 1158 | } |
1155 | 1159 | ||
1156 | |||
1157 | dev = dev_get_by_index(sock_net(sk), ifindex); | ||
1158 | err = -ENXIO; | 1160 | err = -ENXIO; |
1159 | if (dev == NULL) | 1161 | if (dev == NULL) |
1160 | goto out_unlock; | 1162 | goto out_unlock; |
@@ -1285,14 +1287,15 @@ static int packet_snd(struct socket *sock, | |||
1285 | if (err > 0 && (err = net_xmit_errno(err)) != 0) | 1287 | if (err > 0 && (err = net_xmit_errno(err)) != 0) |
1286 | goto out_unlock; | 1288 | goto out_unlock; |
1287 | 1289 | ||
1288 | dev_put(dev); | 1290 | if (need_rls_dev) |
1291 | dev_put(dev); | ||
1289 | 1292 | ||
1290 | return len; | 1293 | return len; |
1291 | 1294 | ||
1292 | out_free: | 1295 | out_free: |
1293 | kfree_skb(skb); | 1296 | kfree_skb(skb); |
1294 | out_unlock: | 1297 | out_unlock: |
1295 | if (dev) | 1298 | if (dev && need_rls_dev) |
1296 | dev_put(dev); | 1299 | dev_put(dev); |
1297 | out: | 1300 | out: |
1298 | return err; | 1301 | return err; |