aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2011-06-01 03:18:53 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-05 17:16:28 -0400
commit827d978037d7d0bf0860481948c6d26ead10042f (patch)
treeddd6f73b342116f330694528d993a2fa373b3b36 /net/packet
parent160ff18a07f3a505d452dcced8e45ecdd0a85506 (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')
-rw-r--r--net/packet/af_packet.c27
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);
1090out_put: 1091out_put:
1091 dev_put(dev); 1092 if (need_rls_dev)
1093 dev_put(dev);
1092out: 1094out:
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
1292out_free: 1295out_free:
1293 kfree_skb(skb); 1296 kfree_skb(skb);
1294out_unlock: 1297out_unlock:
1295 if (dev) 1298 if (dev && need_rls_dev)
1296 dev_put(dev); 1299 dev_put(dev);
1297out: 1300out:
1298 return err; 1301 return err;