Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Ben Greear and committed by
David S. Miller
827d9780 160ff18a

+15 -12
+15 -12
net/packet/af_packet.c
··· 974 974 struct sk_buff *skb; 975 975 struct net_device *dev; 976 976 __be16 proto; 977 - int ifindex, err, reserve = 0; 977 + bool need_rls_dev = false; 978 + int err, reserve = 0; 978 979 void *ph; 979 980 struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; 980 981 int tp_len, size_max; ··· 987 986 988 987 err = -EBUSY; 989 988 if (saddr == NULL) { 990 - ifindex = po->ifindex; 989 + dev = po->prot_hook.dev; 991 990 proto = po->num; 992 991 addr = NULL; 993 992 } else { ··· 998 997 + offsetof(struct sockaddr_ll, 999 998 sll_addr))) 1000 999 goto out; 1001 - ifindex = saddr->sll_ifindex; 1002 1000 proto = saddr->sll_protocol; 1003 1001 addr = saddr->sll_addr; 1002 + dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); 1003 + need_rls_dev = true; 1004 1004 } 1005 1005 1006 - dev = dev_get_by_index(sock_net(&po->sk), ifindex); 1007 1006 err = -ENXIO; 1008 1007 if (unlikely(dev == NULL)) 1009 1008 goto out; ··· 1089 1088 __packet_set_status(po, ph, status); 1090 1089 kfree_skb(skb); 1091 1090 out_put: 1092 - dev_put(dev); 1091 + if (need_rls_dev) 1092 + dev_put(dev); 1093 1093 out: 1094 1094 mutex_unlock(&po->pg_vec_lock); 1095 1095 return err; ··· 1128 1126 struct sk_buff *skb; 1129 1127 struct net_device *dev; 1130 1128 __be16 proto; 1129 + bool need_rls_dev = false; 1131 1130 unsigned char *addr; 1132 - int ifindex, err, reserve = 0; 1131 + int err, reserve = 0; 1133 1132 struct virtio_net_hdr vnet_hdr = { 0 }; 1134 1133 int offset = 0; 1135 1134 int vnet_hdr_len; ··· 1142 1139 */ 1143 1140 1144 1141 if (saddr == NULL) { 1145 - ifindex = po->ifindex; 1142 + dev = po->prot_hook.dev; 1146 1143 proto = po->num; 1147 1144 addr = NULL; 1148 1145 } else { ··· 1151 1148 goto out; 1152 1149 if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) 1153 1150 goto out; 1154 - ifindex = saddr->sll_ifindex; 1155 1151 proto = saddr->sll_protocol; 1156 1152 addr = saddr->sll_addr; 1153 + dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); 1154 + need_rls_dev = true; 1157 1155 } 1158 1156 1159 - 1160 - dev = dev_get_by_index(sock_net(sk), ifindex); 1161 1157 err = -ENXIO; 1162 1158 if (dev == NULL) 1163 1159 goto out_unlock; ··· 1287 1285 if (err > 0 && (err = net_xmit_errno(err)) != 0) 1288 1286 goto out_unlock; 1289 1287 1290 - dev_put(dev); 1288 + if (need_rls_dev) 1289 + dev_put(dev); 1291 1290 1292 1291 return len; 1293 1292 1294 1293 out_free: 1295 1294 kfree_skb(skb); 1296 1295 out_unlock: 1297 - if (dev) 1296 + if (dev && need_rls_dev) 1298 1297 dev_put(dev); 1299 1298 out: 1300 1299 return err;