diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 30 | ||||
-rw-r--r-- | net/core/dst.c | 23 | ||||
-rw-r--r-- | net/core/ethtool.c | 313 | ||||
-rw-r--r-- | net/core/fib_rules.c | 6 | ||||
-rw-r--r-- | net/core/flow.c | 2 | ||||
-rw-r--r-- | net/core/link_watch.c | 2 | ||||
-rw-r--r-- | net/core/neighbour.c | 191 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 2 | ||||
-rw-r--r-- | net/core/net-traces.c | 2 | ||||
-rw-r--r-- | net/core/net_namespace.c | 1 | ||||
-rw-r--r-- | net/core/netpoll.c | 13 | ||||
-rw-r--r-- | net/core/pktgen.c | 8 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 64 | ||||
-rw-r--r-- | net/core/skbuff.c | 84 | ||||
-rw-r--r-- | net/core/sock.c | 11 | ||||
-rw-r--r-- | net/core/timestamping.c | 2 |
16 files changed, 254 insertions, 500 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 9c58c1ec41a9..17d67b579beb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -199,6 +199,11 @@ static struct list_head ptype_all __read_mostly; /* Taps */ | |||
199 | DEFINE_RWLOCK(dev_base_lock); | 199 | DEFINE_RWLOCK(dev_base_lock); |
200 | EXPORT_SYMBOL(dev_base_lock); | 200 | EXPORT_SYMBOL(dev_base_lock); |
201 | 201 | ||
202 | static inline void dev_base_seq_inc(struct net *net) | ||
203 | { | ||
204 | while (++net->dev_base_seq == 0); | ||
205 | } | ||
206 | |||
202 | static inline struct hlist_head *dev_name_hash(struct net *net, const char *name) | 207 | static inline struct hlist_head *dev_name_hash(struct net *net, const char *name) |
203 | { | 208 | { |
204 | unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ)); | 209 | unsigned hash = full_name_hash(name, strnlen(name, IFNAMSIZ)); |
@@ -237,6 +242,9 @@ static int list_netdevice(struct net_device *dev) | |||
237 | hlist_add_head_rcu(&dev->index_hlist, | 242 | hlist_add_head_rcu(&dev->index_hlist, |
238 | dev_index_hash(net, dev->ifindex)); | 243 | dev_index_hash(net, dev->ifindex)); |
239 | write_unlock_bh(&dev_base_lock); | 244 | write_unlock_bh(&dev_base_lock); |
245 | |||
246 | dev_base_seq_inc(net); | ||
247 | |||
240 | return 0; | 248 | return 0; |
241 | } | 249 | } |
242 | 250 | ||
@@ -253,6 +261,8 @@ static void unlist_netdevice(struct net_device *dev) | |||
253 | hlist_del_rcu(&dev->name_hlist); | 261 | hlist_del_rcu(&dev->name_hlist); |
254 | hlist_del_rcu(&dev->index_hlist); | 262 | hlist_del_rcu(&dev->index_hlist); |
255 | write_unlock_bh(&dev_base_lock); | 263 | write_unlock_bh(&dev_base_lock); |
264 | |||
265 | dev_base_seq_inc(dev_net(dev)); | ||
256 | } | 266 | } |
257 | 267 | ||
258 | /* | 268 | /* |
@@ -2532,7 +2542,7 @@ __u32 __skb_get_rxhash(struct sk_buff *skb) | |||
2532 | goto done; | 2542 | goto done; |
2533 | 2543 | ||
2534 | ip = (const struct iphdr *) (skb->data + nhoff); | 2544 | ip = (const struct iphdr *) (skb->data + nhoff); |
2535 | if (ip->frag_off & htons(IP_MF | IP_OFFSET)) | 2545 | if (ip_is_fragment(ip)) |
2536 | ip_proto = 0; | 2546 | ip_proto = 0; |
2537 | else | 2547 | else |
2538 | ip_proto = ip->protocol; | 2548 | ip_proto = ip->protocol; |
@@ -4487,10 +4497,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
4487 | */ | 4497 | */ |
4488 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { | 4498 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { |
4489 | __dev_set_promiscuity(dev, 1); | 4499 | __dev_set_promiscuity(dev, 1); |
4490 | dev->uc_promisc = 1; | 4500 | dev->uc_promisc = true; |
4491 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { | 4501 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { |
4492 | __dev_set_promiscuity(dev, -1); | 4502 | __dev_set_promiscuity(dev, -1); |
4493 | dev->uc_promisc = 0; | 4503 | dev->uc_promisc = false; |
4494 | } | 4504 | } |
4495 | 4505 | ||
4496 | if (ops->ndo_set_multicast_list) | 4506 | if (ops->ndo_set_multicast_list) |
@@ -5199,7 +5209,7 @@ static void rollback_registered(struct net_device *dev) | |||
5199 | list_del(&single); | 5209 | list_del(&single); |
5200 | } | 5210 | } |
5201 | 5211 | ||
5202 | u32 netdev_fix_features(struct net_device *dev, u32 features) | 5212 | static u32 netdev_fix_features(struct net_device *dev, u32 features) |
5203 | { | 5213 | { |
5204 | /* Fix illegal checksum combinations */ | 5214 | /* Fix illegal checksum combinations */ |
5205 | if ((features & NETIF_F_HW_CSUM) && | 5215 | if ((features & NETIF_F_HW_CSUM) && |
@@ -5258,7 +5268,6 @@ u32 netdev_fix_features(struct net_device *dev, u32 features) | |||
5258 | 5268 | ||
5259 | return features; | 5269 | return features; |
5260 | } | 5270 | } |
5261 | EXPORT_SYMBOL(netdev_fix_features); | ||
5262 | 5271 | ||
5263 | int __netdev_update_features(struct net_device *dev) | 5272 | int __netdev_update_features(struct net_device *dev) |
5264 | { | 5273 | { |
@@ -5478,11 +5487,9 @@ int register_netdevice(struct net_device *dev) | |||
5478 | dev->features |= NETIF_F_NOCACHE_COPY; | 5487 | dev->features |= NETIF_F_NOCACHE_COPY; |
5479 | } | 5488 | } |
5480 | 5489 | ||
5481 | /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, | 5490 | /* Make NETIF_F_HIGHDMA inheritable to VLAN devices. |
5482 | * vlan_dev_init() will do the dev->features check, so these features | ||
5483 | * are enabled only if supported by underlying device. | ||
5484 | */ | 5491 | */ |
5485 | dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA); | 5492 | dev->vlan_features |= NETIF_F_HIGHDMA; |
5486 | 5493 | ||
5487 | ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); | 5494 | ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); |
5488 | ret = notifier_to_errno(ret); | 5495 | ret = notifier_to_errno(ret); |
@@ -5867,8 +5874,6 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
5867 | 5874 | ||
5868 | dev->gso_max_size = GSO_MAX_SIZE; | 5875 | dev->gso_max_size = GSO_MAX_SIZE; |
5869 | 5876 | ||
5870 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
5871 | dev->ethtool_ntuple_list.count = 0; | ||
5872 | INIT_LIST_HEAD(&dev->napi_list); | 5877 | INIT_LIST_HEAD(&dev->napi_list); |
5873 | INIT_LIST_HEAD(&dev->unreg_list); | 5878 | INIT_LIST_HEAD(&dev->unreg_list); |
5874 | INIT_LIST_HEAD(&dev->link_watch_list); | 5879 | INIT_LIST_HEAD(&dev->link_watch_list); |
@@ -5932,9 +5937,6 @@ void free_netdev(struct net_device *dev) | |||
5932 | /* Flush device addresses */ | 5937 | /* Flush device addresses */ |
5933 | dev_addr_flush(dev); | 5938 | dev_addr_flush(dev); |
5934 | 5939 | ||
5935 | /* Clear ethtool n-tuple list */ | ||
5936 | ethtool_ntuple_flush(dev); | ||
5937 | |||
5938 | list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) | 5940 | list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) |
5939 | netif_napi_del(p); | 5941 | netif_napi_del(p); |
5940 | 5942 | ||
diff --git a/net/core/dst.c b/net/core/dst.c index 9ccca038444f..14b33baf0733 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -171,8 +171,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
171 | dst_init_metrics(dst, dst_default_metrics, true); | 171 | dst_init_metrics(dst, dst_default_metrics, true); |
172 | dst->expires = 0UL; | 172 | dst->expires = 0UL; |
173 | dst->path = dst; | 173 | dst->path = dst; |
174 | dst->neighbour = NULL; | 174 | dst->_neighbour = NULL; |
175 | dst->hh = NULL; | ||
176 | #ifdef CONFIG_XFRM | 175 | #ifdef CONFIG_XFRM |
177 | dst->xfrm = NULL; | 176 | dst->xfrm = NULL; |
178 | #endif | 177 | #endif |
@@ -190,7 +189,8 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
190 | dst->lastuse = jiffies; | 189 | dst->lastuse = jiffies; |
191 | dst->flags = flags; | 190 | dst->flags = flags; |
192 | dst->next = NULL; | 191 | dst->next = NULL; |
193 | dst_entries_add(ops, 1); | 192 | if (!(flags & DST_NOCOUNT)) |
193 | dst_entries_add(ops, 1); | ||
194 | return dst; | 194 | return dst; |
195 | } | 195 | } |
196 | EXPORT_SYMBOL(dst_alloc); | 196 | EXPORT_SYMBOL(dst_alloc); |
@@ -225,25 +225,20 @@ struct dst_entry *dst_destroy(struct dst_entry * dst) | |||
225 | { | 225 | { |
226 | struct dst_entry *child; | 226 | struct dst_entry *child; |
227 | struct neighbour *neigh; | 227 | struct neighbour *neigh; |
228 | struct hh_cache *hh; | ||
229 | 228 | ||
230 | smp_rmb(); | 229 | smp_rmb(); |
231 | 230 | ||
232 | again: | 231 | again: |
233 | neigh = dst->neighbour; | 232 | neigh = dst->_neighbour; |
234 | hh = dst->hh; | ||
235 | child = dst->child; | 233 | child = dst->child; |
236 | 234 | ||
237 | dst->hh = NULL; | ||
238 | if (hh) | ||
239 | hh_cache_put(hh); | ||
240 | |||
241 | if (neigh) { | 235 | if (neigh) { |
242 | dst->neighbour = NULL; | 236 | dst->_neighbour = NULL; |
243 | neigh_release(neigh); | 237 | neigh_release(neigh); |
244 | } | 238 | } |
245 | 239 | ||
246 | dst_entries_add(dst->ops, -1); | 240 | if (!(dst->flags & DST_NOCOUNT)) |
241 | dst_entries_add(dst->ops, -1); | ||
247 | 242 | ||
248 | if (dst->ops->destroy) | 243 | if (dst->ops->destroy) |
249 | dst->ops->destroy(dst); | 244 | dst->ops->destroy(dst); |
@@ -368,8 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
368 | dst->dev = dev_net(dst->dev)->loopback_dev; | 363 | dst->dev = dev_net(dst->dev)->loopback_dev; |
369 | dev_hold(dst->dev); | 364 | dev_hold(dst->dev); |
370 | dev_put(dev); | 365 | dev_put(dev); |
371 | if (dst->neighbour && dst->neighbour->dev == dev) { | 366 | if (dst->_neighbour && dst->_neighbour->dev == dev) { |
372 | dst->neighbour->dev = dst->dev; | 367 | dst->_neighbour->dev = dst->dev; |
373 | dev_hold(dst->dev); | 368 | dev_hold(dst->dev); |
374 | dev_put(dev); | 369 | dev_put(dev); |
375 | } | 370 | } |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index fd14116ad7f0..6cdba5fc2bed 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -169,18 +169,6 @@ int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) | |||
169 | } | 169 | } |
170 | EXPORT_SYMBOL(ethtool_op_set_flags); | 170 | EXPORT_SYMBOL(ethtool_op_set_flags); |
171 | 171 | ||
172 | void ethtool_ntuple_flush(struct net_device *dev) | ||
173 | { | ||
174 | struct ethtool_rx_ntuple_flow_spec_container *fsc, *f; | ||
175 | |||
176 | list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) { | ||
177 | list_del(&fsc->list); | ||
178 | kfree(fsc); | ||
179 | } | ||
180 | dev->ethtool_ntuple_list.count = 0; | ||
181 | } | ||
182 | EXPORT_SYMBOL(ethtool_ntuple_flush); | ||
183 | |||
184 | /* Handlers for each ethtool command */ | 172 | /* Handlers for each ethtool command */ |
185 | 173 | ||
186 | #define ETHTOOL_DEV_FEATURE_WORDS 1 | 174 | #define ETHTOOL_DEV_FEATURE_WORDS 1 |
@@ -865,34 +853,6 @@ out: | |||
865 | return ret; | 853 | return ret; |
866 | } | 854 | } |
867 | 855 | ||
868 | static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, | ||
869 | struct ethtool_rx_ntuple_flow_spec *spec, | ||
870 | struct ethtool_rx_ntuple_flow_spec_container *fsc) | ||
871 | { | ||
872 | |||
873 | /* don't add filters forever */ | ||
874 | if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) { | ||
875 | /* free the container */ | ||
876 | kfree(fsc); | ||
877 | return; | ||
878 | } | ||
879 | |||
880 | /* Copy the whole filter over */ | ||
881 | fsc->fs.flow_type = spec->flow_type; | ||
882 | memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u)); | ||
883 | memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u)); | ||
884 | |||
885 | fsc->fs.vlan_tag = spec->vlan_tag; | ||
886 | fsc->fs.vlan_tag_mask = spec->vlan_tag_mask; | ||
887 | fsc->fs.data = spec->data; | ||
888 | fsc->fs.data_mask = spec->data_mask; | ||
889 | fsc->fs.action = spec->action; | ||
890 | |||
891 | /* add to the list */ | ||
892 | list_add_tail_rcu(&fsc->list, &list->list); | ||
893 | list->count++; | ||
894 | } | ||
895 | |||
896 | /* | 856 | /* |
897 | * ethtool does not (or did not) set masks for flow parameters that are | 857 | * ethtool does not (or did not) set masks for flow parameters that are |
898 | * not specified, so if both value and mask are 0 then this must be | 858 | * not specified, so if both value and mask are 0 then this must be |
@@ -930,8 +890,6 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, | |||
930 | { | 890 | { |
931 | struct ethtool_rx_ntuple cmd; | 891 | struct ethtool_rx_ntuple cmd; |
932 | const struct ethtool_ops *ops = dev->ethtool_ops; | 892 | const struct ethtool_ops *ops = dev->ethtool_ops; |
933 | struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL; | ||
934 | int ret; | ||
935 | 893 | ||
936 | if (!ops->set_rx_ntuple) | 894 | if (!ops->set_rx_ntuple) |
937 | return -EOPNOTSUPP; | 895 | return -EOPNOTSUPP; |
@@ -944,269 +902,7 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, | |||
944 | 902 | ||
945 | rx_ntuple_fix_masks(&cmd.fs); | 903 | rx_ntuple_fix_masks(&cmd.fs); |
946 | 904 | ||
947 | /* | 905 | return ops->set_rx_ntuple(dev, &cmd); |
948 | * Cache filter in dev struct for GET operation only if | ||
949 | * the underlying driver doesn't have its own GET operation, and | ||
950 | * only if the filter was added successfully. First make sure we | ||
951 | * can allocate the filter, then continue if successful. | ||
952 | */ | ||
953 | if (!ops->get_rx_ntuple) { | ||
954 | fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC); | ||
955 | if (!fsc) | ||
956 | return -ENOMEM; | ||
957 | } | ||
958 | |||
959 | ret = ops->set_rx_ntuple(dev, &cmd); | ||
960 | if (ret) { | ||
961 | kfree(fsc); | ||
962 | return ret; | ||
963 | } | ||
964 | |||
965 | if (!ops->get_rx_ntuple) | ||
966 | __rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc); | ||
967 | |||
968 | return ret; | ||
969 | } | ||
970 | |||
971 | static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) | ||
972 | { | ||
973 | struct ethtool_gstrings gstrings; | ||
974 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
975 | struct ethtool_rx_ntuple_flow_spec_container *fsc; | ||
976 | u8 *data; | ||
977 | char *p; | ||
978 | int ret, i, num_strings = 0; | ||
979 | |||
980 | if (!ops->get_sset_count) | ||
981 | return -EOPNOTSUPP; | ||
982 | |||
983 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) | ||
984 | return -EFAULT; | ||
985 | |||
986 | ret = ops->get_sset_count(dev, gstrings.string_set); | ||
987 | if (ret < 0) | ||
988 | return ret; | ||
989 | |||
990 | gstrings.len = ret; | ||
991 | |||
992 | data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); | ||
993 | if (!data) | ||
994 | return -ENOMEM; | ||
995 | |||
996 | if (ops->get_rx_ntuple) { | ||
997 | /* driver-specific filter grab */ | ||
998 | ret = ops->get_rx_ntuple(dev, gstrings.string_set, data); | ||
999 | goto copy; | ||
1000 | } | ||
1001 | |||
1002 | /* default ethtool filter grab */ | ||
1003 | i = 0; | ||
1004 | p = (char *)data; | ||
1005 | list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) { | ||
1006 | sprintf(p, "Filter %d:\n", i); | ||
1007 | p += ETH_GSTRING_LEN; | ||
1008 | num_strings++; | ||
1009 | |||
1010 | switch (fsc->fs.flow_type) { | ||
1011 | case TCP_V4_FLOW: | ||
1012 | sprintf(p, "\tFlow Type: TCP\n"); | ||
1013 | p += ETH_GSTRING_LEN; | ||
1014 | num_strings++; | ||
1015 | break; | ||
1016 | case UDP_V4_FLOW: | ||
1017 | sprintf(p, "\tFlow Type: UDP\n"); | ||
1018 | p += ETH_GSTRING_LEN; | ||
1019 | num_strings++; | ||
1020 | break; | ||
1021 | case SCTP_V4_FLOW: | ||
1022 | sprintf(p, "\tFlow Type: SCTP\n"); | ||
1023 | p += ETH_GSTRING_LEN; | ||
1024 | num_strings++; | ||
1025 | break; | ||
1026 | case AH_ESP_V4_FLOW: | ||
1027 | sprintf(p, "\tFlow Type: AH ESP\n"); | ||
1028 | p += ETH_GSTRING_LEN; | ||
1029 | num_strings++; | ||
1030 | break; | ||
1031 | case ESP_V4_FLOW: | ||
1032 | sprintf(p, "\tFlow Type: ESP\n"); | ||
1033 | p += ETH_GSTRING_LEN; | ||
1034 | num_strings++; | ||
1035 | break; | ||
1036 | case IP_USER_FLOW: | ||
1037 | sprintf(p, "\tFlow Type: Raw IP\n"); | ||
1038 | p += ETH_GSTRING_LEN; | ||
1039 | num_strings++; | ||
1040 | break; | ||
1041 | case IPV4_FLOW: | ||
1042 | sprintf(p, "\tFlow Type: IPv4\n"); | ||
1043 | p += ETH_GSTRING_LEN; | ||
1044 | num_strings++; | ||
1045 | break; | ||
1046 | default: | ||
1047 | sprintf(p, "\tFlow Type: Unknown\n"); | ||
1048 | p += ETH_GSTRING_LEN; | ||
1049 | num_strings++; | ||
1050 | goto unknown_filter; | ||
1051 | } | ||
1052 | |||
1053 | /* now the rest of the filters */ | ||
1054 | switch (fsc->fs.flow_type) { | ||
1055 | case TCP_V4_FLOW: | ||
1056 | case UDP_V4_FLOW: | ||
1057 | case SCTP_V4_FLOW: | ||
1058 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
1059 | fsc->fs.h_u.tcp_ip4_spec.ip4src); | ||
1060 | p += ETH_GSTRING_LEN; | ||
1061 | num_strings++; | ||
1062 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
1063 | fsc->fs.m_u.tcp_ip4_spec.ip4src); | ||
1064 | p += ETH_GSTRING_LEN; | ||
1065 | num_strings++; | ||
1066 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
1067 | fsc->fs.h_u.tcp_ip4_spec.ip4dst); | ||
1068 | p += ETH_GSTRING_LEN; | ||
1069 | num_strings++; | ||
1070 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
1071 | fsc->fs.m_u.tcp_ip4_spec.ip4dst); | ||
1072 | p += ETH_GSTRING_LEN; | ||
1073 | num_strings++; | ||
1074 | sprintf(p, "\tSrc Port: %d, mask: 0x%x\n", | ||
1075 | fsc->fs.h_u.tcp_ip4_spec.psrc, | ||
1076 | fsc->fs.m_u.tcp_ip4_spec.psrc); | ||
1077 | p += ETH_GSTRING_LEN; | ||
1078 | num_strings++; | ||
1079 | sprintf(p, "\tDest Port: %d, mask: 0x%x\n", | ||
1080 | fsc->fs.h_u.tcp_ip4_spec.pdst, | ||
1081 | fsc->fs.m_u.tcp_ip4_spec.pdst); | ||
1082 | p += ETH_GSTRING_LEN; | ||
1083 | num_strings++; | ||
1084 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
1085 | fsc->fs.h_u.tcp_ip4_spec.tos, | ||
1086 | fsc->fs.m_u.tcp_ip4_spec.tos); | ||
1087 | p += ETH_GSTRING_LEN; | ||
1088 | num_strings++; | ||
1089 | break; | ||
1090 | case AH_ESP_V4_FLOW: | ||
1091 | case ESP_V4_FLOW: | ||
1092 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
1093 | fsc->fs.h_u.ah_ip4_spec.ip4src); | ||
1094 | p += ETH_GSTRING_LEN; | ||
1095 | num_strings++; | ||
1096 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
1097 | fsc->fs.m_u.ah_ip4_spec.ip4src); | ||
1098 | p += ETH_GSTRING_LEN; | ||
1099 | num_strings++; | ||
1100 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
1101 | fsc->fs.h_u.ah_ip4_spec.ip4dst); | ||
1102 | p += ETH_GSTRING_LEN; | ||
1103 | num_strings++; | ||
1104 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
1105 | fsc->fs.m_u.ah_ip4_spec.ip4dst); | ||
1106 | p += ETH_GSTRING_LEN; | ||
1107 | num_strings++; | ||
1108 | sprintf(p, "\tSPI: %d, mask: 0x%x\n", | ||
1109 | fsc->fs.h_u.ah_ip4_spec.spi, | ||
1110 | fsc->fs.m_u.ah_ip4_spec.spi); | ||
1111 | p += ETH_GSTRING_LEN; | ||
1112 | num_strings++; | ||
1113 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
1114 | fsc->fs.h_u.ah_ip4_spec.tos, | ||
1115 | fsc->fs.m_u.ah_ip4_spec.tos); | ||
1116 | p += ETH_GSTRING_LEN; | ||
1117 | num_strings++; | ||
1118 | break; | ||
1119 | case IP_USER_FLOW: | ||
1120 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
1121 | fsc->fs.h_u.usr_ip4_spec.ip4src); | ||
1122 | p += ETH_GSTRING_LEN; | ||
1123 | num_strings++; | ||
1124 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
1125 | fsc->fs.m_u.usr_ip4_spec.ip4src); | ||
1126 | p += ETH_GSTRING_LEN; | ||
1127 | num_strings++; | ||
1128 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
1129 | fsc->fs.h_u.usr_ip4_spec.ip4dst); | ||
1130 | p += ETH_GSTRING_LEN; | ||
1131 | num_strings++; | ||
1132 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
1133 | fsc->fs.m_u.usr_ip4_spec.ip4dst); | ||
1134 | p += ETH_GSTRING_LEN; | ||
1135 | num_strings++; | ||
1136 | break; | ||
1137 | case IPV4_FLOW: | ||
1138 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
1139 | fsc->fs.h_u.usr_ip4_spec.ip4src); | ||
1140 | p += ETH_GSTRING_LEN; | ||
1141 | num_strings++; | ||
1142 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
1143 | fsc->fs.m_u.usr_ip4_spec.ip4src); | ||
1144 | p += ETH_GSTRING_LEN; | ||
1145 | num_strings++; | ||
1146 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
1147 | fsc->fs.h_u.usr_ip4_spec.ip4dst); | ||
1148 | p += ETH_GSTRING_LEN; | ||
1149 | num_strings++; | ||
1150 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
1151 | fsc->fs.m_u.usr_ip4_spec.ip4dst); | ||
1152 | p += ETH_GSTRING_LEN; | ||
1153 | num_strings++; | ||
1154 | sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n", | ||
1155 | fsc->fs.h_u.usr_ip4_spec.l4_4_bytes, | ||
1156 | fsc->fs.m_u.usr_ip4_spec.l4_4_bytes); | ||
1157 | p += ETH_GSTRING_LEN; | ||
1158 | num_strings++; | ||
1159 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
1160 | fsc->fs.h_u.usr_ip4_spec.tos, | ||
1161 | fsc->fs.m_u.usr_ip4_spec.tos); | ||
1162 | p += ETH_GSTRING_LEN; | ||
1163 | num_strings++; | ||
1164 | sprintf(p, "\tIP Version: %d, mask: 0x%x\n", | ||
1165 | fsc->fs.h_u.usr_ip4_spec.ip_ver, | ||
1166 | fsc->fs.m_u.usr_ip4_spec.ip_ver); | ||
1167 | p += ETH_GSTRING_LEN; | ||
1168 | num_strings++; | ||
1169 | sprintf(p, "\tProtocol: %d, mask: 0x%x\n", | ||
1170 | fsc->fs.h_u.usr_ip4_spec.proto, | ||
1171 | fsc->fs.m_u.usr_ip4_spec.proto); | ||
1172 | p += ETH_GSTRING_LEN; | ||
1173 | num_strings++; | ||
1174 | break; | ||
1175 | } | ||
1176 | sprintf(p, "\tVLAN: %d, mask: 0x%x\n", | ||
1177 | fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask); | ||
1178 | p += ETH_GSTRING_LEN; | ||
1179 | num_strings++; | ||
1180 | sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data); | ||
1181 | p += ETH_GSTRING_LEN; | ||
1182 | num_strings++; | ||
1183 | sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask); | ||
1184 | p += ETH_GSTRING_LEN; | ||
1185 | num_strings++; | ||
1186 | if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) | ||
1187 | sprintf(p, "\tAction: Drop\n"); | ||
1188 | else | ||
1189 | sprintf(p, "\tAction: Direct to queue %d\n", | ||
1190 | fsc->fs.action); | ||
1191 | p += ETH_GSTRING_LEN; | ||
1192 | num_strings++; | ||
1193 | unknown_filter: | ||
1194 | i++; | ||
1195 | } | ||
1196 | copy: | ||
1197 | /* indicate to userspace how many strings we actually have */ | ||
1198 | gstrings.len = num_strings; | ||
1199 | ret = -EFAULT; | ||
1200 | if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) | ||
1201 | goto out; | ||
1202 | useraddr += sizeof(gstrings); | ||
1203 | if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) | ||
1204 | goto out; | ||
1205 | ret = 0; | ||
1206 | |||
1207 | out: | ||
1208 | kfree(data); | ||
1209 | return ret; | ||
1210 | } | 906 | } |
1211 | 907 | ||
1212 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | 908 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
@@ -1227,7 +923,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
1227 | regs.len = reglen; | 923 | regs.len = reglen; |
1228 | 924 | ||
1229 | regbuf = vzalloc(reglen); | 925 | regbuf = vzalloc(reglen); |
1230 | if (!regbuf) | 926 | if (reglen && !regbuf) |
1231 | return -ENOMEM; | 927 | return -ENOMEM; |
1232 | 928 | ||
1233 | ops->get_regs(dev, ®s, regbuf); | 929 | ops->get_regs(dev, ®s, regbuf); |
@@ -1236,7 +932,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | |||
1236 | if (copy_to_user(useraddr, ®s, sizeof(regs))) | 932 | if (copy_to_user(useraddr, ®s, sizeof(regs))) |
1237 | goto out; | 933 | goto out; |
1238 | useraddr += offsetof(struct ethtool_regs, data); | 934 | useraddr += offsetof(struct ethtool_regs, data); |
1239 | if (copy_to_user(useraddr, regbuf, regs.len)) | 935 | if (regbuf && copy_to_user(useraddr, regbuf, regs.len)) |
1240 | goto out; | 936 | goto out; |
1241 | ret = 0; | 937 | ret = 0; |
1242 | 938 | ||
@@ -2101,9 +1797,6 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
2101 | case ETHTOOL_SRXNTUPLE: | 1797 | case ETHTOOL_SRXNTUPLE: |
2102 | rc = ethtool_set_rx_ntuple(dev, useraddr); | 1798 | rc = ethtool_set_rx_ntuple(dev, useraddr); |
2103 | break; | 1799 | break; |
2104 | case ETHTOOL_GRXNTUPLE: | ||
2105 | rc = ethtool_get_rx_ntuple(dev, useraddr); | ||
2106 | break; | ||
2107 | case ETHTOOL_GSSET_INFO: | 1800 | case ETHTOOL_GSSET_INFO: |
2108 | rc = ethtool_get_sset_info(dev, useraddr); | 1801 | rc = ethtool_get_sset_info(dev, useraddr); |
2109 | break; | 1802 | break; |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 008dc70b064b..e7ab0c0285b5 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -740,9 +740,9 @@ static struct pernet_operations fib_rules_net_ops = { | |||
740 | static int __init fib_rules_init(void) | 740 | static int __init fib_rules_init(void) |
741 | { | 741 | { |
742 | int err; | 742 | int err; |
743 | rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL); | 743 | rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, NULL); |
744 | rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL); | 744 | rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, NULL); |
745 | rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule); | 745 | rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, NULL); |
746 | 746 | ||
747 | err = register_pernet_subsys(&fib_rules_net_ops); | 747 | err = register_pernet_subsys(&fib_rules_net_ops); |
748 | if (err < 0) | 748 | if (err < 0) |
diff --git a/net/core/flow.c b/net/core/flow.c index 990703b8863b..bf32c33cad3b 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <net/flow.h> | 24 | #include <net/flow.h> |
25 | #include <asm/atomic.h> | 25 | #include <linux/atomic.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | 27 | ||
28 | struct flow_cache_entry { | 28 | struct flow_cache_entry { |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index a7b342131869..357bd4ee4baa 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) | |||
126 | return; | 126 | return; |
127 | 127 | ||
128 | /* It's already running which is good enough. */ | 128 | /* It's already running which is good enough. */ |
129 | if (!cancel_delayed_work(&linkwatch_work)) | 129 | if (!__cancel_delayed_work(&linkwatch_work)) |
130 | return; | 130 | return; |
131 | 131 | ||
132 | /* Otherwise we reschedule it again for immediate execution. */ | 132 | /* Otherwise we reschedule it again for immediate execution. */ |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 799f06e03a22..8fab9b0bb203 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -98,7 +98,7 @@ static const struct file_operations neigh_stat_seq_fops; | |||
98 | 98 | ||
99 | static DEFINE_RWLOCK(neigh_tbl_lock); | 99 | static DEFINE_RWLOCK(neigh_tbl_lock); |
100 | 100 | ||
101 | static int neigh_blackhole(struct sk_buff *skb) | 101 | static int neigh_blackhole(struct neighbour *neigh, struct sk_buff *skb) |
102 | { | 102 | { |
103 | kfree_skb(skb); | 103 | kfree_skb(skb); |
104 | return -ENETDOWN; | 104 | return -ENETDOWN; |
@@ -137,7 +137,7 @@ static int neigh_forced_gc(struct neigh_table *tbl) | |||
137 | write_lock_bh(&tbl->lock); | 137 | write_lock_bh(&tbl->lock); |
138 | nht = rcu_dereference_protected(tbl->nht, | 138 | nht = rcu_dereference_protected(tbl->nht, |
139 | lockdep_is_held(&tbl->lock)); | 139 | lockdep_is_held(&tbl->lock)); |
140 | for (i = 0; i <= nht->hash_mask; i++) { | 140 | for (i = 0; i < (1 << nht->hash_shift); i++) { |
141 | struct neighbour *n; | 141 | struct neighbour *n; |
142 | struct neighbour __rcu **np; | 142 | struct neighbour __rcu **np; |
143 | 143 | ||
@@ -210,7 +210,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) | |||
210 | nht = rcu_dereference_protected(tbl->nht, | 210 | nht = rcu_dereference_protected(tbl->nht, |
211 | lockdep_is_held(&tbl->lock)); | 211 | lockdep_is_held(&tbl->lock)); |
212 | 212 | ||
213 | for (i = 0; i <= nht->hash_mask; i++) { | 213 | for (i = 0; i < (1 << nht->hash_shift); i++) { |
214 | struct neighbour *n; | 214 | struct neighbour *n; |
215 | struct neighbour __rcu **np = &nht->hash_buckets[i]; | 215 | struct neighbour __rcu **np = &nht->hash_buckets[i]; |
216 | 216 | ||
@@ -297,6 +297,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) | |||
297 | n->updated = n->used = now; | 297 | n->updated = n->used = now; |
298 | n->nud_state = NUD_NONE; | 298 | n->nud_state = NUD_NONE; |
299 | n->output = neigh_blackhole; | 299 | n->output = neigh_blackhole; |
300 | seqlock_init(&n->hh.hh_lock); | ||
300 | n->parms = neigh_parms_clone(&tbl->parms); | 301 | n->parms = neigh_parms_clone(&tbl->parms); |
301 | setup_timer(&n->timer, neigh_timer_handler, (unsigned long)n); | 302 | setup_timer(&n->timer, neigh_timer_handler, (unsigned long)n); |
302 | 303 | ||
@@ -312,9 +313,9 @@ out_entries: | |||
312 | goto out; | 313 | goto out; |
313 | } | 314 | } |
314 | 315 | ||
315 | static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) | 316 | static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) |
316 | { | 317 | { |
317 | size_t size = entries * sizeof(struct neighbour *); | 318 | size_t size = (1 << shift) * sizeof(struct neighbour *); |
318 | struct neigh_hash_table *ret; | 319 | struct neigh_hash_table *ret; |
319 | struct neighbour __rcu **buckets; | 320 | struct neighbour __rcu **buckets; |
320 | 321 | ||
@@ -332,8 +333,9 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) | |||
332 | return NULL; | 333 | return NULL; |
333 | } | 334 | } |
334 | ret->hash_buckets = buckets; | 335 | ret->hash_buckets = buckets; |
335 | ret->hash_mask = entries - 1; | 336 | ret->hash_shift = shift; |
336 | get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); | 337 | get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); |
338 | ret->hash_rnd |= 1; | ||
337 | return ret; | 339 | return ret; |
338 | } | 340 | } |
339 | 341 | ||
@@ -342,7 +344,7 @@ static void neigh_hash_free_rcu(struct rcu_head *head) | |||
342 | struct neigh_hash_table *nht = container_of(head, | 344 | struct neigh_hash_table *nht = container_of(head, |
343 | struct neigh_hash_table, | 345 | struct neigh_hash_table, |
344 | rcu); | 346 | rcu); |
345 | size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); | 347 | size_t size = (1 << nht->hash_shift) * sizeof(struct neighbour *); |
346 | struct neighbour __rcu **buckets = nht->hash_buckets; | 348 | struct neighbour __rcu **buckets = nht->hash_buckets; |
347 | 349 | ||
348 | if (size <= PAGE_SIZE) | 350 | if (size <= PAGE_SIZE) |
@@ -353,21 +355,20 @@ static void neigh_hash_free_rcu(struct rcu_head *head) | |||
353 | } | 355 | } |
354 | 356 | ||
355 | static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, | 357 | static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, |
356 | unsigned long new_entries) | 358 | unsigned long new_shift) |
357 | { | 359 | { |
358 | unsigned int i, hash; | 360 | unsigned int i, hash; |
359 | struct neigh_hash_table *new_nht, *old_nht; | 361 | struct neigh_hash_table *new_nht, *old_nht; |
360 | 362 | ||
361 | NEIGH_CACHE_STAT_INC(tbl, hash_grows); | 363 | NEIGH_CACHE_STAT_INC(tbl, hash_grows); |
362 | 364 | ||
363 | BUG_ON(!is_power_of_2(new_entries)); | ||
364 | old_nht = rcu_dereference_protected(tbl->nht, | 365 | old_nht = rcu_dereference_protected(tbl->nht, |
365 | lockdep_is_held(&tbl->lock)); | 366 | lockdep_is_held(&tbl->lock)); |
366 | new_nht = neigh_hash_alloc(new_entries); | 367 | new_nht = neigh_hash_alloc(new_shift); |
367 | if (!new_nht) | 368 | if (!new_nht) |
368 | return old_nht; | 369 | return old_nht; |
369 | 370 | ||
370 | for (i = 0; i <= old_nht->hash_mask; i++) { | 371 | for (i = 0; i < (1 << old_nht->hash_shift); i++) { |
371 | struct neighbour *n, *next; | 372 | struct neighbour *n, *next; |
372 | 373 | ||
373 | for (n = rcu_dereference_protected(old_nht->hash_buckets[i], | 374 | for (n = rcu_dereference_protected(old_nht->hash_buckets[i], |
@@ -377,7 +378,7 @@ static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, | |||
377 | hash = tbl->hash(n->primary_key, n->dev, | 378 | hash = tbl->hash(n->primary_key, n->dev, |
378 | new_nht->hash_rnd); | 379 | new_nht->hash_rnd); |
379 | 380 | ||
380 | hash &= new_nht->hash_mask; | 381 | hash >>= (32 - new_nht->hash_shift); |
381 | next = rcu_dereference_protected(n->next, | 382 | next = rcu_dereference_protected(n->next, |
382 | lockdep_is_held(&tbl->lock)); | 383 | lockdep_is_held(&tbl->lock)); |
383 | 384 | ||
@@ -406,7 +407,7 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, | |||
406 | 407 | ||
407 | rcu_read_lock_bh(); | 408 | rcu_read_lock_bh(); |
408 | nht = rcu_dereference_bh(tbl->nht); | 409 | nht = rcu_dereference_bh(tbl->nht); |
409 | hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; | 410 | hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); |
410 | 411 | ||
411 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | 412 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); |
412 | n != NULL; | 413 | n != NULL; |
@@ -436,7 +437,7 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, | |||
436 | 437 | ||
437 | rcu_read_lock_bh(); | 438 | rcu_read_lock_bh(); |
438 | nht = rcu_dereference_bh(tbl->nht); | 439 | nht = rcu_dereference_bh(tbl->nht); |
439 | hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask; | 440 | hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) >> (32 - nht->hash_shift); |
440 | 441 | ||
441 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | 442 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); |
442 | n != NULL; | 443 | n != NULL; |
@@ -492,10 +493,10 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, | |||
492 | nht = rcu_dereference_protected(tbl->nht, | 493 | nht = rcu_dereference_protected(tbl->nht, |
493 | lockdep_is_held(&tbl->lock)); | 494 | lockdep_is_held(&tbl->lock)); |
494 | 495 | ||
495 | if (atomic_read(&tbl->entries) > (nht->hash_mask + 1)) | 496 | if (atomic_read(&tbl->entries) > (1 << nht->hash_shift)) |
496 | nht = neigh_hash_grow(tbl, (nht->hash_mask + 1) << 1); | 497 | nht = neigh_hash_grow(tbl, nht->hash_shift + 1); |
497 | 498 | ||
498 | hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; | 499 | hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); |
499 | 500 | ||
500 | if (n->parms->dead) { | 501 | if (n->parms->dead) { |
501 | rc = ERR_PTR(-EINVAL); | 502 | rc = ERR_PTR(-EINVAL); |
@@ -688,8 +689,6 @@ static void neigh_destroy_rcu(struct rcu_head *head) | |||
688 | */ | 689 | */ |
689 | void neigh_destroy(struct neighbour *neigh) | 690 | void neigh_destroy(struct neighbour *neigh) |
690 | { | 691 | { |
691 | struct hh_cache *hh; | ||
692 | |||
693 | NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); | 692 | NEIGH_CACHE_STAT_INC(neigh->tbl, destroys); |
694 | 693 | ||
695 | if (!neigh->dead) { | 694 | if (!neigh->dead) { |
@@ -702,16 +701,6 @@ void neigh_destroy(struct neighbour *neigh) | |||
702 | if (neigh_del_timer(neigh)) | 701 | if (neigh_del_timer(neigh)) |
703 | printk(KERN_WARNING "Impossible event.\n"); | 702 | printk(KERN_WARNING "Impossible event.\n"); |
704 | 703 | ||
705 | while ((hh = neigh->hh) != NULL) { | ||
706 | neigh->hh = hh->hh_next; | ||
707 | hh->hh_next = NULL; | ||
708 | |||
709 | write_seqlock_bh(&hh->hh_lock); | ||
710 | hh->hh_output = neigh_blackhole; | ||
711 | write_sequnlock_bh(&hh->hh_lock); | ||
712 | hh_cache_put(hh); | ||
713 | } | ||
714 | |||
715 | skb_queue_purge(&neigh->arp_queue); | 704 | skb_queue_purge(&neigh->arp_queue); |
716 | 705 | ||
717 | dev_put(neigh->dev); | 706 | dev_put(neigh->dev); |
@@ -731,14 +720,9 @@ EXPORT_SYMBOL(neigh_destroy); | |||
731 | */ | 720 | */ |
732 | static void neigh_suspect(struct neighbour *neigh) | 721 | static void neigh_suspect(struct neighbour *neigh) |
733 | { | 722 | { |
734 | struct hh_cache *hh; | ||
735 | |||
736 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); | 723 | NEIGH_PRINTK2("neigh %p is suspected.\n", neigh); |
737 | 724 | ||
738 | neigh->output = neigh->ops->output; | 725 | neigh->output = neigh->ops->output; |
739 | |||
740 | for (hh = neigh->hh; hh; hh = hh->hh_next) | ||
741 | hh->hh_output = neigh->ops->output; | ||
742 | } | 726 | } |
743 | 727 | ||
744 | /* Neighbour state is OK; | 728 | /* Neighbour state is OK; |
@@ -748,14 +732,9 @@ static void neigh_suspect(struct neighbour *neigh) | |||
748 | */ | 732 | */ |
749 | static void neigh_connect(struct neighbour *neigh) | 733 | static void neigh_connect(struct neighbour *neigh) |
750 | { | 734 | { |
751 | struct hh_cache *hh; | ||
752 | |||
753 | NEIGH_PRINTK2("neigh %p is connected.\n", neigh); | 735 | NEIGH_PRINTK2("neigh %p is connected.\n", neigh); |
754 | 736 | ||
755 | neigh->output = neigh->ops->connected_output; | 737 | neigh->output = neigh->ops->connected_output; |
756 | |||
757 | for (hh = neigh->hh; hh; hh = hh->hh_next) | ||
758 | hh->hh_output = neigh->ops->hh_output; | ||
759 | } | 738 | } |
760 | 739 | ||
761 | static void neigh_periodic_work(struct work_struct *work) | 740 | static void neigh_periodic_work(struct work_struct *work) |
@@ -784,7 +763,7 @@ static void neigh_periodic_work(struct work_struct *work) | |||
784 | neigh_rand_reach_time(p->base_reachable_time); | 763 | neigh_rand_reach_time(p->base_reachable_time); |
785 | } | 764 | } |
786 | 765 | ||
787 | for (i = 0 ; i <= nht->hash_mask; i++) { | 766 | for (i = 0 ; i < (1 << nht->hash_shift); i++) { |
788 | np = &nht->hash_buckets[i]; | 767 | np = &nht->hash_buckets[i]; |
789 | 768 | ||
790 | while ((n = rcu_dereference_protected(*np, | 769 | while ((n = rcu_dereference_protected(*np, |
@@ -1015,7 +994,7 @@ out_unlock_bh: | |||
1015 | } | 994 | } |
1016 | EXPORT_SYMBOL(__neigh_event_send); | 995 | EXPORT_SYMBOL(__neigh_event_send); |
1017 | 996 | ||
1018 | static void neigh_update_hhs(const struct neighbour *neigh) | 997 | static void neigh_update_hhs(struct neighbour *neigh) |
1019 | { | 998 | { |
1020 | struct hh_cache *hh; | 999 | struct hh_cache *hh; |
1021 | void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) | 1000 | void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) |
@@ -1025,7 +1004,8 @@ static void neigh_update_hhs(const struct neighbour *neigh) | |||
1025 | update = neigh->dev->header_ops->cache_update; | 1004 | update = neigh->dev->header_ops->cache_update; |
1026 | 1005 | ||
1027 | if (update) { | 1006 | if (update) { |
1028 | for (hh = neigh->hh; hh; hh = hh->hh_next) { | 1007 | hh = &neigh->hh; |
1008 | if (hh->hh_len) { | ||
1029 | write_seqlock_bh(&hh->hh_lock); | 1009 | write_seqlock_bh(&hh->hh_lock); |
1030 | update(hh, neigh->dev, neigh->ha); | 1010 | update(hh, neigh->dev, neigh->ha); |
1031 | write_sequnlock_bh(&hh->hh_lock); | 1011 | write_sequnlock_bh(&hh->hh_lock); |
@@ -1173,12 +1153,13 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1173 | 1153 | ||
1174 | while (neigh->nud_state & NUD_VALID && | 1154 | while (neigh->nud_state & NUD_VALID && |
1175 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { | 1155 | (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) { |
1176 | struct neighbour *n1 = neigh; | 1156 | struct dst_entry *dst = skb_dst(skb); |
1157 | struct neighbour *n2, *n1 = neigh; | ||
1177 | write_unlock_bh(&neigh->lock); | 1158 | write_unlock_bh(&neigh->lock); |
1178 | /* On shaper/eql skb->dst->neighbour != neigh :( */ | 1159 | /* On shaper/eql skb->dst->neighbour != neigh :( */ |
1179 | if (skb_dst(skb) && skb_dst(skb)->neighbour) | 1160 | if (dst && (n2 = dst_get_neighbour(dst)) != NULL) |
1180 | n1 = skb_dst(skb)->neighbour; | 1161 | n1 = n2; |
1181 | n1->output(skb); | 1162 | n1->output(n1, skb); |
1182 | write_lock_bh(&neigh->lock); | 1163 | write_lock_bh(&neigh->lock); |
1183 | } | 1164 | } |
1184 | skb_queue_purge(&neigh->arp_queue); | 1165 | skb_queue_purge(&neigh->arp_queue); |
@@ -1211,67 +1192,21 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, | |||
1211 | } | 1192 | } |
1212 | EXPORT_SYMBOL(neigh_event_ns); | 1193 | EXPORT_SYMBOL(neigh_event_ns); |
1213 | 1194 | ||
1214 | static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, | ||
1215 | __be16 protocol) | ||
1216 | { | ||
1217 | struct hh_cache *hh; | ||
1218 | |||
1219 | smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ | ||
1220 | for (hh = n->hh; hh; hh = hh->hh_next) { | ||
1221 | if (hh->hh_type == protocol) { | ||
1222 | atomic_inc(&hh->hh_refcnt); | ||
1223 | if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) | ||
1224 | hh_cache_put(hh); | ||
1225 | return true; | ||
1226 | } | ||
1227 | } | ||
1228 | return false; | ||
1229 | } | ||
1230 | |||
1231 | /* called with read_lock_bh(&n->lock); */ | 1195 | /* called with read_lock_bh(&n->lock); */ |
1232 | static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, | 1196 | static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst) |
1233 | __be16 protocol) | ||
1234 | { | 1197 | { |
1235 | struct hh_cache *hh; | ||
1236 | struct net_device *dev = dst->dev; | 1198 | struct net_device *dev = dst->dev; |
1237 | 1199 | __be16 prot = dst->ops->protocol; | |
1238 | if (likely(neigh_hh_lookup(n, dst, protocol))) | 1200 | struct hh_cache *hh = &n->hh; |
1239 | return; | ||
1240 | |||
1241 | /* slow path */ | ||
1242 | hh = kzalloc(sizeof(*hh), GFP_ATOMIC); | ||
1243 | if (!hh) | ||
1244 | return; | ||
1245 | |||
1246 | seqlock_init(&hh->hh_lock); | ||
1247 | hh->hh_type = protocol; | ||
1248 | atomic_set(&hh->hh_refcnt, 2); | ||
1249 | |||
1250 | if (dev->header_ops->cache(n, hh)) { | ||
1251 | kfree(hh); | ||
1252 | return; | ||
1253 | } | ||
1254 | 1201 | ||
1255 | write_lock_bh(&n->lock); | 1202 | write_lock_bh(&n->lock); |
1256 | 1203 | ||
1257 | /* must check if another thread already did the insert */ | 1204 | /* Only one thread can come in here and initialize the |
1258 | if (neigh_hh_lookup(n, dst, protocol)) { | 1205 | * hh_cache entry. |
1259 | kfree(hh); | 1206 | */ |
1260 | goto end; | 1207 | if (!hh->hh_len) |
1261 | } | 1208 | dev->header_ops->cache(n, hh, prot); |
1262 | |||
1263 | if (n->nud_state & NUD_CONNECTED) | ||
1264 | hh->hh_output = n->ops->hh_output; | ||
1265 | else | ||
1266 | hh->hh_output = n->ops->output; | ||
1267 | |||
1268 | hh->hh_next = n->hh; | ||
1269 | smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ | ||
1270 | n->hh = hh; | ||
1271 | 1209 | ||
1272 | if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) | ||
1273 | hh_cache_put(hh); | ||
1274 | end: | ||
1275 | write_unlock_bh(&n->lock); | 1210 | write_unlock_bh(&n->lock); |
1276 | } | 1211 | } |
1277 | 1212 | ||
@@ -1280,7 +1215,7 @@ end: | |||
1280 | * but resolution is not made yet. | 1215 | * but resolution is not made yet. |
1281 | */ | 1216 | */ |
1282 | 1217 | ||
1283 | int neigh_compat_output(struct sk_buff *skb) | 1218 | int neigh_compat_output(struct neighbour *neigh, struct sk_buff *skb) |
1284 | { | 1219 | { |
1285 | struct net_device *dev = skb->dev; | 1220 | struct net_device *dev = skb->dev; |
1286 | 1221 | ||
@@ -1297,13 +1232,12 @@ EXPORT_SYMBOL(neigh_compat_output); | |||
1297 | 1232 | ||
1298 | /* Slow and careful. */ | 1233 | /* Slow and careful. */ |
1299 | 1234 | ||
1300 | int neigh_resolve_output(struct sk_buff *skb) | 1235 | int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) |
1301 | { | 1236 | { |
1302 | struct dst_entry *dst = skb_dst(skb); | 1237 | struct dst_entry *dst = skb_dst(skb); |
1303 | struct neighbour *neigh; | ||
1304 | int rc = 0; | 1238 | int rc = 0; |
1305 | 1239 | ||
1306 | if (!dst || !(neigh = dst->neighbour)) | 1240 | if (!dst) |
1307 | goto discard; | 1241 | goto discard; |
1308 | 1242 | ||
1309 | __skb_pull(skb, skb_network_offset(skb)); | 1243 | __skb_pull(skb, skb_network_offset(skb)); |
@@ -1313,10 +1247,8 @@ int neigh_resolve_output(struct sk_buff *skb) | |||
1313 | struct net_device *dev = neigh->dev; | 1247 | struct net_device *dev = neigh->dev; |
1314 | unsigned int seq; | 1248 | unsigned int seq; |
1315 | 1249 | ||
1316 | if (dev->header_ops->cache && | 1250 | if (dev->header_ops->cache && !neigh->hh.hh_len) |
1317 | !dst->hh && | 1251 | neigh_hh_init(neigh, dst); |
1318 | !(dst->flags & DST_NOCACHE)) | ||
1319 | neigh_hh_init(neigh, dst, dst->ops->protocol); | ||
1320 | 1252 | ||
1321 | do { | 1253 | do { |
1322 | seq = read_seqbegin(&neigh->ha_lock); | 1254 | seq = read_seqbegin(&neigh->ha_lock); |
@@ -1325,7 +1257,7 @@ int neigh_resolve_output(struct sk_buff *skb) | |||
1325 | } while (read_seqretry(&neigh->ha_lock, seq)); | 1257 | } while (read_seqretry(&neigh->ha_lock, seq)); |
1326 | 1258 | ||
1327 | if (err >= 0) | 1259 | if (err >= 0) |
1328 | rc = neigh->ops->queue_xmit(skb); | 1260 | rc = dev_queue_xmit(skb); |
1329 | else | 1261 | else |
1330 | goto out_kfree_skb; | 1262 | goto out_kfree_skb; |
1331 | } | 1263 | } |
@@ -1333,7 +1265,7 @@ out: | |||
1333 | return rc; | 1265 | return rc; |
1334 | discard: | 1266 | discard: |
1335 | NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n", | 1267 | NEIGH_PRINTK1("neigh_resolve_output: dst=%p neigh=%p\n", |
1336 | dst, dst ? dst->neighbour : NULL); | 1268 | dst, neigh); |
1337 | out_kfree_skb: | 1269 | out_kfree_skb: |
1338 | rc = -EINVAL; | 1270 | rc = -EINVAL; |
1339 | kfree_skb(skb); | 1271 | kfree_skb(skb); |
@@ -1343,13 +1275,11 @@ EXPORT_SYMBOL(neigh_resolve_output); | |||
1343 | 1275 | ||
1344 | /* As fast as possible without hh cache */ | 1276 | /* As fast as possible without hh cache */ |
1345 | 1277 | ||
1346 | int neigh_connected_output(struct sk_buff *skb) | 1278 | int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb) |
1347 | { | 1279 | { |
1348 | int err; | ||
1349 | struct dst_entry *dst = skb_dst(skb); | ||
1350 | struct neighbour *neigh = dst->neighbour; | ||
1351 | struct net_device *dev = neigh->dev; | 1280 | struct net_device *dev = neigh->dev; |
1352 | unsigned int seq; | 1281 | unsigned int seq; |
1282 | int err; | ||
1353 | 1283 | ||
1354 | __skb_pull(skb, skb_network_offset(skb)); | 1284 | __skb_pull(skb, skb_network_offset(skb)); |
1355 | 1285 | ||
@@ -1360,7 +1290,7 @@ int neigh_connected_output(struct sk_buff *skb) | |||
1360 | } while (read_seqretry(&neigh->ha_lock, seq)); | 1290 | } while (read_seqretry(&neigh->ha_lock, seq)); |
1361 | 1291 | ||
1362 | if (err >= 0) | 1292 | if (err >= 0) |
1363 | err = neigh->ops->queue_xmit(skb); | 1293 | err = dev_queue_xmit(skb); |
1364 | else { | 1294 | else { |
1365 | err = -EINVAL; | 1295 | err = -EINVAL; |
1366 | kfree_skb(skb); | 1296 | kfree_skb(skb); |
@@ -1369,6 +1299,12 @@ int neigh_connected_output(struct sk_buff *skb) | |||
1369 | } | 1299 | } |
1370 | EXPORT_SYMBOL(neigh_connected_output); | 1300 | EXPORT_SYMBOL(neigh_connected_output); |
1371 | 1301 | ||
1302 | int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb) | ||
1303 | { | ||
1304 | return dev_queue_xmit(skb); | ||
1305 | } | ||
1306 | EXPORT_SYMBOL(neigh_direct_output); | ||
1307 | |||
1372 | static void neigh_proxy_process(unsigned long arg) | 1308 | static void neigh_proxy_process(unsigned long arg) |
1373 | { | 1309 | { |
1374 | struct neigh_table *tbl = (struct neigh_table *)arg; | 1310 | struct neigh_table *tbl = (struct neigh_table *)arg; |
@@ -1540,7 +1476,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1540 | panic("cannot create neighbour proc dir entry"); | 1476 | panic("cannot create neighbour proc dir entry"); |
1541 | #endif | 1477 | #endif |
1542 | 1478 | ||
1543 | RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(8)); | 1479 | RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(3)); |
1544 | 1480 | ||
1545 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); | 1481 | phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); |
1546 | tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); | 1482 | tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); |
@@ -1857,7 +1793,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, | |||
1857 | rcu_read_lock_bh(); | 1793 | rcu_read_lock_bh(); |
1858 | nht = rcu_dereference_bh(tbl->nht); | 1794 | nht = rcu_dereference_bh(tbl->nht); |
1859 | ndc.ndtc_hash_rnd = nht->hash_rnd; | 1795 | ndc.ndtc_hash_rnd = nht->hash_rnd; |
1860 | ndc.ndtc_hash_mask = nht->hash_mask; | 1796 | ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); |
1861 | rcu_read_unlock_bh(); | 1797 | rcu_read_unlock_bh(); |
1862 | 1798 | ||
1863 | NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); | 1799 | NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); |
@@ -2200,7 +2136,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, | |||
2200 | rcu_read_lock_bh(); | 2136 | rcu_read_lock_bh(); |
2201 | nht = rcu_dereference_bh(tbl->nht); | 2137 | nht = rcu_dereference_bh(tbl->nht); |
2202 | 2138 | ||
2203 | for (h = 0; h <= nht->hash_mask; h++) { | 2139 | for (h = 0; h < (1 << nht->hash_shift); h++) { |
2204 | if (h < s_h) | 2140 | if (h < s_h) |
2205 | continue; | 2141 | continue; |
2206 | if (h > s_h) | 2142 | if (h > s_h) |
@@ -2264,7 +2200,7 @@ void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void | |||
2264 | nht = rcu_dereference_bh(tbl->nht); | 2200 | nht = rcu_dereference_bh(tbl->nht); |
2265 | 2201 | ||
2266 | read_lock(&tbl->lock); /* avoid resizes */ | 2202 | read_lock(&tbl->lock); /* avoid resizes */ |
2267 | for (chain = 0; chain <= nht->hash_mask; chain++) { | 2203 | for (chain = 0; chain < (1 << nht->hash_shift); chain++) { |
2268 | struct neighbour *n; | 2204 | struct neighbour *n; |
2269 | 2205 | ||
2270 | for (n = rcu_dereference_bh(nht->hash_buckets[chain]); | 2206 | for (n = rcu_dereference_bh(nht->hash_buckets[chain]); |
@@ -2286,7 +2222,7 @@ void __neigh_for_each_release(struct neigh_table *tbl, | |||
2286 | 2222 | ||
2287 | nht = rcu_dereference_protected(tbl->nht, | 2223 | nht = rcu_dereference_protected(tbl->nht, |
2288 | lockdep_is_held(&tbl->lock)); | 2224 | lockdep_is_held(&tbl->lock)); |
2289 | for (chain = 0; chain <= nht->hash_mask; chain++) { | 2225 | for (chain = 0; chain < (1 << nht->hash_shift); chain++) { |
2290 | struct neighbour *n; | 2226 | struct neighbour *n; |
2291 | struct neighbour __rcu **np; | 2227 | struct neighbour __rcu **np; |
2292 | 2228 | ||
@@ -2323,7 +2259,7 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) | |||
2323 | int bucket = state->bucket; | 2259 | int bucket = state->bucket; |
2324 | 2260 | ||
2325 | state->flags &= ~NEIGH_SEQ_IS_PNEIGH; | 2261 | state->flags &= ~NEIGH_SEQ_IS_PNEIGH; |
2326 | for (bucket = 0; bucket <= nht->hash_mask; bucket++) { | 2262 | for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) { |
2327 | n = rcu_dereference_bh(nht->hash_buckets[bucket]); | 2263 | n = rcu_dereference_bh(nht->hash_buckets[bucket]); |
2328 | 2264 | ||
2329 | while (n) { | 2265 | while (n) { |
@@ -2390,7 +2326,7 @@ next: | |||
2390 | if (n) | 2326 | if (n) |
2391 | break; | 2327 | break; |
2392 | 2328 | ||
2393 | if (++state->bucket > nht->hash_mask) | 2329 | if (++state->bucket >= (1 << nht->hash_shift)) |
2394 | break; | 2330 | break; |
2395 | 2331 | ||
2396 | n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); | 2332 | n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); |
@@ -2909,12 +2845,13 @@ EXPORT_SYMBOL(neigh_sysctl_unregister); | |||
2909 | 2845 | ||
2910 | static int __init neigh_init(void) | 2846 | static int __init neigh_init(void) |
2911 | { | 2847 | { |
2912 | rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL); | 2848 | rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, NULL); |
2913 | rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL); | 2849 | rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, NULL); |
2914 | rtnl_register(PF_UNSPEC, RTM_GETNEIGH, NULL, neigh_dump_info); | 2850 | rtnl_register(PF_UNSPEC, RTM_GETNEIGH, NULL, neigh_dump_info, NULL); |
2915 | 2851 | ||
2916 | rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info); | 2852 | rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info, |
2917 | rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL); | 2853 | NULL); |
2854 | rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, NULL); | ||
2918 | 2855 | ||
2919 | return 0; | 2856 | return 0; |
2920 | } | 2857 | } |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 33d2a1fba131..1683e5db2f27 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -100,7 +100,6 @@ NETDEVICE_SHOW(addr_assign_type, fmt_dec); | |||
100 | NETDEVICE_SHOW(addr_len, fmt_dec); | 100 | NETDEVICE_SHOW(addr_len, fmt_dec); |
101 | NETDEVICE_SHOW(iflink, fmt_dec); | 101 | NETDEVICE_SHOW(iflink, fmt_dec); |
102 | NETDEVICE_SHOW(ifindex, fmt_dec); | 102 | NETDEVICE_SHOW(ifindex, fmt_dec); |
103 | NETDEVICE_SHOW(features, fmt_hex); | ||
104 | NETDEVICE_SHOW(type, fmt_dec); | 103 | NETDEVICE_SHOW(type, fmt_dec); |
105 | NETDEVICE_SHOW(link_mode, fmt_dec); | 104 | NETDEVICE_SHOW(link_mode, fmt_dec); |
106 | 105 | ||
@@ -312,7 +311,6 @@ static struct device_attribute net_class_attributes[] = { | |||
312 | __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), | 311 | __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), |
313 | __ATTR(iflink, S_IRUGO, show_iflink, NULL), | 312 | __ATTR(iflink, S_IRUGO, show_iflink, NULL), |
314 | __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), | 313 | __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), |
315 | __ATTR(features, S_IRUGO, show_features, NULL), | ||
316 | __ATTR(type, S_IRUGO, show_type, NULL), | 314 | __ATTR(type, S_IRUGO, show_type, NULL), |
317 | __ATTR(link_mode, S_IRUGO, show_link_mode, NULL), | 315 | __ATTR(link_mode, S_IRUGO, show_link_mode, NULL), |
318 | __ATTR(address, S_IRUGO, show_address, NULL), | 316 | __ATTR(address, S_IRUGO, show_address, NULL), |
diff --git a/net/core/net-traces.c b/net/core/net-traces.c index 7f1bb2aba03b..52380b1d552a 100644 --- a/net/core/net-traces.c +++ b/net/core/net-traces.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <trace/events/skb.h> | 28 | #include <trace/events/skb.h> |
29 | #include <trace/events/net.h> | 29 | #include <trace/events/net.h> |
30 | #include <trace/events/napi.h> | 30 | #include <trace/events/napi.h> |
31 | #include <trace/events/sock.h> | ||
32 | #include <trace/events/udp.h> | ||
31 | 33 | ||
32 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); | 34 | EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb); |
33 | 35 | ||
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index ea489db1bc23..5bbdbf0d3664 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -129,6 +129,7 @@ static __net_init int setup_net(struct net *net) | |||
129 | 129 | ||
130 | atomic_set(&net->count, 1); | 130 | atomic_set(&net->count, 1); |
131 | atomic_set(&net->passive, 1); | 131 | atomic_set(&net->passive, 1); |
132 | net->dev_base_seq = 1; | ||
132 | 133 | ||
133 | #ifdef NETNS_REFCNT_DEBUG | 134 | #ifdef NETNS_REFCNT_DEBUG |
134 | atomic_set(&net->use_count, 0); | 135 | atomic_set(&net->use_count, 0); |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 18d9cbda3a39..adf84dd8c7b5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -177,7 +177,7 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
177 | } | 177 | } |
178 | } | 178 | } |
179 | 179 | ||
180 | void netpoll_poll_dev(struct net_device *dev) | 180 | static void netpoll_poll_dev(struct net_device *dev) |
181 | { | 181 | { |
182 | const struct net_device_ops *ops; | 182 | const struct net_device_ops *ops; |
183 | 183 | ||
@@ -208,13 +208,6 @@ void netpoll_poll_dev(struct net_device *dev) | |||
208 | 208 | ||
209 | zap_completion_queue(); | 209 | zap_completion_queue(); |
210 | } | 210 | } |
211 | EXPORT_SYMBOL(netpoll_poll_dev); | ||
212 | |||
213 | void netpoll_poll(struct netpoll *np) | ||
214 | { | ||
215 | netpoll_poll_dev(np->dev); | ||
216 | } | ||
217 | EXPORT_SYMBOL(netpoll_poll); | ||
218 | 211 | ||
219 | static void refill_skbs(void) | 212 | static void refill_skbs(void) |
220 | { | 213 | { |
@@ -275,7 +268,7 @@ repeat: | |||
275 | 268 | ||
276 | if (!skb) { | 269 | if (!skb) { |
277 | if (++count < 10) { | 270 | if (++count < 10) { |
278 | netpoll_poll(np); | 271 | netpoll_poll_dev(np->dev); |
279 | goto repeat; | 272 | goto repeat; |
280 | } | 273 | } |
281 | return NULL; | 274 | return NULL; |
@@ -336,7 +329,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
336 | } | 329 | } |
337 | 330 | ||
338 | /* tickle device maybe there is some cleanup */ | 331 | /* tickle device maybe there is some cleanup */ |
339 | netpoll_poll(np); | 332 | netpoll_poll_dev(np->dev); |
340 | 333 | ||
341 | udelay(USEC_PER_POLL); | 334 | udelay(USEC_PER_POLL); |
342 | } | 335 | } |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index f76079cd750c..e35a6fbb8110 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -1070,7 +1070,9 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1070 | len = num_arg(&user_buffer[i], 10, &value); | 1070 | len = num_arg(&user_buffer[i], 10, &value); |
1071 | if (len < 0) | 1071 | if (len < 0) |
1072 | return len; | 1072 | return len; |
1073 | 1073 | if ((value > 0) && | |
1074 | (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) | ||
1075 | return -ENOTSUPP; | ||
1074 | i += len; | 1076 | i += len; |
1075 | pkt_dev->clone_skb = value; | 1077 | pkt_dev->clone_skb = value; |
1076 | 1078 | ||
@@ -3555,7 +3557,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3555 | pkt_dev->min_pkt_size = ETH_ZLEN; | 3557 | pkt_dev->min_pkt_size = ETH_ZLEN; |
3556 | pkt_dev->max_pkt_size = ETH_ZLEN; | 3558 | pkt_dev->max_pkt_size = ETH_ZLEN; |
3557 | pkt_dev->nfrags = 0; | 3559 | pkt_dev->nfrags = 0; |
3558 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
3559 | pkt_dev->delay = pg_delay_d; | 3560 | pkt_dev->delay = pg_delay_d; |
3560 | pkt_dev->count = pg_count_d; | 3561 | pkt_dev->count = pg_count_d; |
3561 | pkt_dev->sofar = 0; | 3562 | pkt_dev->sofar = 0; |
@@ -3563,7 +3564,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3563 | pkt_dev->udp_src_max = 9; | 3564 | pkt_dev->udp_src_max = 9; |
3564 | pkt_dev->udp_dst_min = 9; | 3565 | pkt_dev->udp_dst_min = 9; |
3565 | pkt_dev->udp_dst_max = 9; | 3566 | pkt_dev->udp_dst_max = 9; |
3566 | |||
3567 | pkt_dev->vlan_p = 0; | 3567 | pkt_dev->vlan_p = 0; |
3568 | pkt_dev->vlan_cfi = 0; | 3568 | pkt_dev->vlan_cfi = 0; |
3569 | pkt_dev->vlan_id = 0xffff; | 3569 | pkt_dev->vlan_id = 0xffff; |
@@ -3575,6 +3575,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3575 | err = pktgen_setup_dev(pkt_dev, ifname); | 3575 | err = pktgen_setup_dev(pkt_dev, ifname); |
3576 | if (err) | 3576 | if (err) |
3577 | goto out1; | 3577 | goto out1; |
3578 | if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) | ||
3579 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
3578 | 3580 | ||
3579 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, | 3581 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
3580 | &pktgen_if_fops, pkt_dev); | 3582 | &pktgen_if_fops, pkt_dev); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index abd936d8a716..99d9e953fe39 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -56,9 +56,11 @@ | |||
56 | struct rtnl_link { | 56 | struct rtnl_link { |
57 | rtnl_doit_func doit; | 57 | rtnl_doit_func doit; |
58 | rtnl_dumpit_func dumpit; | 58 | rtnl_dumpit_func dumpit; |
59 | rtnl_calcit_func calcit; | ||
59 | }; | 60 | }; |
60 | 61 | ||
61 | static DEFINE_MUTEX(rtnl_mutex); | 62 | static DEFINE_MUTEX(rtnl_mutex); |
63 | static u16 min_ifinfo_dump_size; | ||
62 | 64 | ||
63 | void rtnl_lock(void) | 65 | void rtnl_lock(void) |
64 | { | 66 | { |
@@ -144,12 +146,28 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | |||
144 | return tab ? tab[msgindex].dumpit : NULL; | 146 | return tab ? tab[msgindex].dumpit : NULL; |
145 | } | 147 | } |
146 | 148 | ||
149 | static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex) | ||
150 | { | ||
151 | struct rtnl_link *tab; | ||
152 | |||
153 | if (protocol <= RTNL_FAMILY_MAX) | ||
154 | tab = rtnl_msg_handlers[protocol]; | ||
155 | else | ||
156 | tab = NULL; | ||
157 | |||
158 | if (tab == NULL || tab[msgindex].calcit == NULL) | ||
159 | tab = rtnl_msg_handlers[PF_UNSPEC]; | ||
160 | |||
161 | return tab ? tab[msgindex].calcit : NULL; | ||
162 | } | ||
163 | |||
147 | /** | 164 | /** |
148 | * __rtnl_register - Register a rtnetlink message type | 165 | * __rtnl_register - Register a rtnetlink message type |
149 | * @protocol: Protocol family or PF_UNSPEC | 166 | * @protocol: Protocol family or PF_UNSPEC |
150 | * @msgtype: rtnetlink message type | 167 | * @msgtype: rtnetlink message type |
151 | * @doit: Function pointer called for each request message | 168 | * @doit: Function pointer called for each request message |
152 | * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message | 169 | * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message |
170 | * @calcit: Function pointer to calc size of dump message | ||
153 | * | 171 | * |
154 | * Registers the specified function pointers (at least one of them has | 172 | * Registers the specified function pointers (at least one of them has |
155 | * to be non-NULL) to be called whenever a request message for the | 173 | * to be non-NULL) to be called whenever a request message for the |
@@ -162,7 +180,8 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex) | |||
162 | * Returns 0 on success or a negative error code. | 180 | * Returns 0 on success or a negative error code. |
163 | */ | 181 | */ |
164 | int __rtnl_register(int protocol, int msgtype, | 182 | int __rtnl_register(int protocol, int msgtype, |
165 | rtnl_doit_func doit, rtnl_dumpit_func dumpit) | 183 | rtnl_doit_func doit, rtnl_dumpit_func dumpit, |
184 | rtnl_calcit_func calcit) | ||
166 | { | 185 | { |
167 | struct rtnl_link *tab; | 186 | struct rtnl_link *tab; |
168 | int msgindex; | 187 | int msgindex; |
@@ -185,6 +204,9 @@ int __rtnl_register(int protocol, int msgtype, | |||
185 | if (dumpit) | 204 | if (dumpit) |
186 | tab[msgindex].dumpit = dumpit; | 205 | tab[msgindex].dumpit = dumpit; |
187 | 206 | ||
207 | if (calcit) | ||
208 | tab[msgindex].calcit = calcit; | ||
209 | |||
188 | return 0; | 210 | return 0; |
189 | } | 211 | } |
190 | EXPORT_SYMBOL_GPL(__rtnl_register); | 212 | EXPORT_SYMBOL_GPL(__rtnl_register); |
@@ -199,9 +221,10 @@ EXPORT_SYMBOL_GPL(__rtnl_register); | |||
199 | * of memory implies no sense in continuing. | 221 | * of memory implies no sense in continuing. |
200 | */ | 222 | */ |
201 | void rtnl_register(int protocol, int msgtype, | 223 | void rtnl_register(int protocol, int msgtype, |
202 | rtnl_doit_func doit, rtnl_dumpit_func dumpit) | 224 | rtnl_doit_func doit, rtnl_dumpit_func dumpit, |
225 | rtnl_calcit_func calcit) | ||
203 | { | 226 | { |
204 | if (__rtnl_register(protocol, msgtype, doit, dumpit) < 0) | 227 | if (__rtnl_register(protocol, msgtype, doit, dumpit, calcit) < 0) |
205 | panic("Unable to register rtnetlink message handler, " | 228 | panic("Unable to register rtnetlink message handler, " |
206 | "protocol = %d, message type = %d\n", | 229 | "protocol = %d, message type = %d\n", |
207 | protocol, msgtype); | 230 | protocol, msgtype); |
@@ -1009,6 +1032,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1009 | s_idx = cb->args[1]; | 1032 | s_idx = cb->args[1]; |
1010 | 1033 | ||
1011 | rcu_read_lock(); | 1034 | rcu_read_lock(); |
1035 | cb->seq = net->dev_base_seq; | ||
1036 | |||
1012 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | 1037 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
1013 | idx = 0; | 1038 | idx = 0; |
1014 | head = &net->dev_index_head[h]; | 1039 | head = &net->dev_index_head[h]; |
@@ -1020,6 +1045,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1020 | cb->nlh->nlmsg_seq, 0, | 1045 | cb->nlh->nlmsg_seq, 0, |
1021 | NLM_F_MULTI) <= 0) | 1046 | NLM_F_MULTI) <= 0) |
1022 | goto out; | 1047 | goto out; |
1048 | |||
1049 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | ||
1023 | cont: | 1050 | cont: |
1024 | idx++; | 1051 | idx++; |
1025 | } | 1052 | } |
@@ -1818,6 +1845,11 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
1818 | return err; | 1845 | return err; |
1819 | } | 1846 | } |
1820 | 1847 | ||
1848 | static u16 rtnl_calcit(struct sk_buff *skb) | ||
1849 | { | ||
1850 | return min_ifinfo_dump_size; | ||
1851 | } | ||
1852 | |||
1821 | static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) | 1853 | static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) |
1822 | { | 1854 | { |
1823 | int idx; | 1855 | int idx; |
@@ -1847,11 +1879,14 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) | |||
1847 | struct net *net = dev_net(dev); | 1879 | struct net *net = dev_net(dev); |
1848 | struct sk_buff *skb; | 1880 | struct sk_buff *skb; |
1849 | int err = -ENOBUFS; | 1881 | int err = -ENOBUFS; |
1882 | size_t if_info_size; | ||
1850 | 1883 | ||
1851 | skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL); | 1884 | skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL); |
1852 | if (skb == NULL) | 1885 | if (skb == NULL) |
1853 | goto errout; | 1886 | goto errout; |
1854 | 1887 | ||
1888 | min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size); | ||
1889 | |||
1855 | err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0); | 1890 | err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0); |
1856 | if (err < 0) { | 1891 | if (err < 0) { |
1857 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ | 1892 | /* -EMSGSIZE implies BUG in if_nlmsg_size() */ |
@@ -1902,14 +1937,20 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1902 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 1937 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
1903 | struct sock *rtnl; | 1938 | struct sock *rtnl; |
1904 | rtnl_dumpit_func dumpit; | 1939 | rtnl_dumpit_func dumpit; |
1940 | rtnl_calcit_func calcit; | ||
1941 | u16 min_dump_alloc = 0; | ||
1905 | 1942 | ||
1906 | dumpit = rtnl_get_dumpit(family, type); | 1943 | dumpit = rtnl_get_dumpit(family, type); |
1907 | if (dumpit == NULL) | 1944 | if (dumpit == NULL) |
1908 | return -EOPNOTSUPP; | 1945 | return -EOPNOTSUPP; |
1946 | calcit = rtnl_get_calcit(family, type); | ||
1947 | if (calcit) | ||
1948 | min_dump_alloc = calcit(skb); | ||
1909 | 1949 | ||
1910 | __rtnl_unlock(); | 1950 | __rtnl_unlock(); |
1911 | rtnl = net->rtnl; | 1951 | rtnl = net->rtnl; |
1912 | err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL); | 1952 | err = netlink_dump_start(rtnl, skb, nlh, dumpit, |
1953 | NULL, min_dump_alloc); | ||
1913 | rtnl_lock(); | 1954 | rtnl_lock(); |
1914 | return err; | 1955 | return err; |
1915 | } | 1956 | } |
@@ -2019,12 +2060,13 @@ void __init rtnetlink_init(void) | |||
2019 | netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); | 2060 | netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); |
2020 | register_netdevice_notifier(&rtnetlink_dev_notifier); | 2061 | register_netdevice_notifier(&rtnetlink_dev_notifier); |
2021 | 2062 | ||
2022 | rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo); | 2063 | rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, |
2023 | rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL); | 2064 | rtnl_dump_ifinfo, rtnl_calcit); |
2024 | rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL); | 2065 | rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL, NULL); |
2025 | rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL); | 2066 | rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL, NULL); |
2067 | rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL); | ||
2026 | 2068 | ||
2027 | rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all); | 2069 | rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL); |
2028 | rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all); | 2070 | rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL); |
2029 | } | 2071 | } |
2030 | 2072 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 46cbd28f40f9..2beda824636e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -329,6 +329,18 @@ static void skb_release_data(struct sk_buff *skb) | |||
329 | put_page(skb_shinfo(skb)->frags[i].page); | 329 | put_page(skb_shinfo(skb)->frags[i].page); |
330 | } | 330 | } |
331 | 331 | ||
332 | /* | ||
333 | * If skb buf is from userspace, we need to notify the caller | ||
334 | * the lower device DMA has done; | ||
335 | */ | ||
336 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | ||
337 | struct ubuf_info *uarg; | ||
338 | |||
339 | uarg = skb_shinfo(skb)->destructor_arg; | ||
340 | if (uarg->callback) | ||
341 | uarg->callback(uarg); | ||
342 | } | ||
343 | |||
332 | if (skb_has_frag_list(skb)) | 344 | if (skb_has_frag_list(skb)) |
333 | skb_drop_fraglist(skb); | 345 | skb_drop_fraglist(skb); |
334 | 346 | ||
@@ -481,6 +493,9 @@ bool skb_recycle_check(struct sk_buff *skb, int skb_size) | |||
481 | if (irqs_disabled()) | 493 | if (irqs_disabled()) |
482 | return false; | 494 | return false; |
483 | 495 | ||
496 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) | ||
497 | return false; | ||
498 | |||
484 | if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) | 499 | if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE) |
485 | return false; | 500 | return false; |
486 | 501 | ||
@@ -596,6 +611,51 @@ struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src) | |||
596 | } | 611 | } |
597 | EXPORT_SYMBOL_GPL(skb_morph); | 612 | EXPORT_SYMBOL_GPL(skb_morph); |
598 | 613 | ||
614 | /* skb frags copy userspace buffers to kernel */ | ||
615 | static int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | ||
616 | { | ||
617 | int i; | ||
618 | int num_frags = skb_shinfo(skb)->nr_frags; | ||
619 | struct page *page, *head = NULL; | ||
620 | struct ubuf_info *uarg = skb_shinfo(skb)->destructor_arg; | ||
621 | |||
622 | for (i = 0; i < num_frags; i++) { | ||
623 | u8 *vaddr; | ||
624 | skb_frag_t *f = &skb_shinfo(skb)->frags[i]; | ||
625 | |||
626 | page = alloc_page(GFP_ATOMIC); | ||
627 | if (!page) { | ||
628 | while (head) { | ||
629 | struct page *next = (struct page *)head->private; | ||
630 | put_page(head); | ||
631 | head = next; | ||
632 | } | ||
633 | return -ENOMEM; | ||
634 | } | ||
635 | vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); | ||
636 | memcpy(page_address(page), | ||
637 | vaddr + f->page_offset, f->size); | ||
638 | kunmap_skb_frag(vaddr); | ||
639 | page->private = (unsigned long)head; | ||
640 | head = page; | ||
641 | } | ||
642 | |||
643 | /* skb frags release userspace buffers */ | ||
644 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
645 | put_page(skb_shinfo(skb)->frags[i].page); | ||
646 | |||
647 | uarg->callback(uarg); | ||
648 | |||
649 | /* skb frags point to kernel buffers */ | ||
650 | for (i = skb_shinfo(skb)->nr_frags; i > 0; i--) { | ||
651 | skb_shinfo(skb)->frags[i - 1].page_offset = 0; | ||
652 | skb_shinfo(skb)->frags[i - 1].page = head; | ||
653 | head = (struct page *)head->private; | ||
654 | } | ||
655 | return 0; | ||
656 | } | ||
657 | |||
658 | |||
599 | /** | 659 | /** |
600 | * skb_clone - duplicate an sk_buff | 660 | * skb_clone - duplicate an sk_buff |
601 | * @skb: buffer to clone | 661 | * @skb: buffer to clone |
@@ -614,6 +674,12 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) | |||
614 | { | 674 | { |
615 | struct sk_buff *n; | 675 | struct sk_buff *n; |
616 | 676 | ||
677 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | ||
678 | if (skb_copy_ubufs(skb, gfp_mask)) | ||
679 | return NULL; | ||
680 | skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; | ||
681 | } | ||
682 | |||
617 | n = skb + 1; | 683 | n = skb + 1; |
618 | if (skb->fclone == SKB_FCLONE_ORIG && | 684 | if (skb->fclone == SKB_FCLONE_ORIG && |
619 | n->fclone == SKB_FCLONE_UNAVAILABLE) { | 685 | n->fclone == SKB_FCLONE_UNAVAILABLE) { |
@@ -731,6 +797,14 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) | |||
731 | if (skb_shinfo(skb)->nr_frags) { | 797 | if (skb_shinfo(skb)->nr_frags) { |
732 | int i; | 798 | int i; |
733 | 799 | ||
800 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | ||
801 | if (skb_copy_ubufs(skb, gfp_mask)) { | ||
802 | kfree_skb(n); | ||
803 | n = NULL; | ||
804 | goto out; | ||
805 | } | ||
806 | skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; | ||
807 | } | ||
734 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | 808 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { |
735 | skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; | 809 | skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; |
736 | get_page(skb_shinfo(n)->frags[i].page); | 810 | get_page(skb_shinfo(n)->frags[i].page); |
@@ -788,7 +862,6 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
788 | fastpath = true; | 862 | fastpath = true; |
789 | else { | 863 | else { |
790 | int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; | 864 | int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; |
791 | |||
792 | fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; | 865 | fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; |
793 | } | 866 | } |
794 | 867 | ||
@@ -819,6 +892,12 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, | |||
819 | if (fastpath) { | 892 | if (fastpath) { |
820 | kfree(skb->head); | 893 | kfree(skb->head); |
821 | } else { | 894 | } else { |
895 | /* copy this zero copy skb frags */ | ||
896 | if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) { | ||
897 | if (skb_copy_ubufs(skb, gfp_mask)) | ||
898 | goto nofrags; | ||
899 | skb_shinfo(skb)->tx_flags &= ~SKBTX_DEV_ZEROCOPY; | ||
900 | } | ||
822 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 901 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) |
823 | get_page(skb_shinfo(skb)->frags[i].page); | 902 | get_page(skb_shinfo(skb)->frags[i].page); |
824 | 903 | ||
@@ -853,6 +932,8 @@ adjust_others: | |||
853 | atomic_set(&skb_shinfo(skb)->dataref, 1); | 932 | atomic_set(&skb_shinfo(skb)->dataref, 1); |
854 | return 0; | 933 | return 0; |
855 | 934 | ||
935 | nofrags: | ||
936 | kfree(data); | ||
856 | nodata: | 937 | nodata: |
857 | return -ENOMEM; | 938 | return -ENOMEM; |
858 | } | 939 | } |
@@ -1354,6 +1435,7 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | |||
1354 | } | 1435 | } |
1355 | start = end; | 1436 | start = end; |
1356 | } | 1437 | } |
1438 | |||
1357 | if (!len) | 1439 | if (!len) |
1358 | return 0; | 1440 | return 0; |
1359 | 1441 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 6e819780c232..bc745d00ea4d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -128,6 +128,8 @@ | |||
128 | 128 | ||
129 | #include <linux/filter.h> | 129 | #include <linux/filter.h> |
130 | 130 | ||
131 | #include <trace/events/sock.h> | ||
132 | |||
131 | #ifdef CONFIG_INET | 133 | #ifdef CONFIG_INET |
132 | #include <net/tcp.h> | 134 | #include <net/tcp.h> |
133 | #endif | 135 | #endif |
@@ -158,7 +160,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
158 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 160 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
159 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 161 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
160 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | 162 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
161 | "sk_lock-AF_MAX" | 163 | "sk_lock-AF_NFC" , "sk_lock-AF_MAX" |
162 | }; | 164 | }; |
163 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 165 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
164 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 166 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
@@ -174,7 +176,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
174 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 176 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
175 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 177 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
176 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | 178 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
177 | "slock-AF_MAX" | 179 | "slock-AF_NFC" , "slock-AF_MAX" |
178 | }; | 180 | }; |
179 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 181 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
180 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 182 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
@@ -190,7 +192,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
190 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 192 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
191 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 193 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
192 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | 194 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
193 | "clock-AF_MAX" | 195 | "clock-AF_NFC" , "clock-AF_MAX" |
194 | }; | 196 | }; |
195 | 197 | ||
196 | /* | 198 | /* |
@@ -292,6 +294,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
292 | if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= | 294 | if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= |
293 | (unsigned)sk->sk_rcvbuf) { | 295 | (unsigned)sk->sk_rcvbuf) { |
294 | atomic_inc(&sk->sk_drops); | 296 | atomic_inc(&sk->sk_drops); |
297 | trace_sock_rcvqueue_full(sk, skb); | ||
295 | return -ENOMEM; | 298 | return -ENOMEM; |
296 | } | 299 | } |
297 | 300 | ||
@@ -1736,6 +1739,8 @@ suppress_allocation: | |||
1736 | return 1; | 1739 | return 1; |
1737 | } | 1740 | } |
1738 | 1741 | ||
1742 | trace_sock_exceed_buf_limit(sk, prot, allocated); | ||
1743 | |||
1739 | /* Alas. Undo changes. */ | 1744 | /* Alas. Undo changes. */ |
1740 | sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; | 1745 | sk->sk_forward_alloc -= amt * SK_MEM_QUANTUM; |
1741 | atomic_long_sub(amt, prot->memory_allocated); | 1746 | atomic_long_sub(amt, prot->memory_allocated); |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 7e7ca375d431..98a52640e7cd 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -68,6 +68,7 @@ void skb_clone_tx_timestamp(struct sk_buff *skb) | |||
68 | break; | 68 | break; |
69 | } | 69 | } |
70 | } | 70 | } |
71 | EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp); | ||
71 | 72 | ||
72 | void skb_complete_tx_timestamp(struct sk_buff *skb, | 73 | void skb_complete_tx_timestamp(struct sk_buff *skb, |
73 | struct skb_shared_hwtstamps *hwtstamps) | 74 | struct skb_shared_hwtstamps *hwtstamps) |
@@ -121,6 +122,7 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) | |||
121 | 122 | ||
122 | return false; | 123 | return false; |
123 | } | 124 | } |
125 | EXPORT_SYMBOL_GPL(skb_defer_rx_timestamp); | ||
124 | 126 | ||
125 | void __init skb_timestamping_init(void) | 127 | void __init skb_timestamping_init(void) |
126 | { | 128 | { |