diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/dev.c | 288 | ||||
| -rw-r--r-- | net/core/dev_mcast.c | 2 | ||||
| -rw-r--r-- | net/core/drop_monitor.c | 1 | ||||
| -rw-r--r-- | net/core/ethtool.c | 387 | ||||
| -rw-r--r-- | net/core/fib_rules.c | 2 | ||||
| -rw-r--r-- | net/core/filter.c | 8 | ||||
| -rw-r--r-- | net/core/neighbour.c | 18 | ||||
| -rw-r--r-- | net/core/net-sysfs.c | 3 | ||||
| -rw-r--r-- | net/core/netpoll.c | 169 | ||||
| -rw-r--r-- | net/core/pktgen.c | 3 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 135 | ||||
| -rw-r--r-- | net/core/scm.c | 2 | ||||
| -rw-r--r-- | net/core/sock.c | 19 |
13 files changed, 825 insertions, 212 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index be9924f60ec3..bcc490cc9452 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1113,19 +1113,7 @@ void dev_load(struct net *net, const char *name) | |||
| 1113 | } | 1113 | } |
| 1114 | EXPORT_SYMBOL(dev_load); | 1114 | EXPORT_SYMBOL(dev_load); |
| 1115 | 1115 | ||
| 1116 | /** | 1116 | static int __dev_open(struct net_device *dev) |
| 1117 | * dev_open - prepare an interface for use. | ||
| 1118 | * @dev: device to open | ||
| 1119 | * | ||
| 1120 | * Takes a device from down to up state. The device's private open | ||
| 1121 | * function is invoked and then the multicast lists are loaded. Finally | ||
| 1122 | * the device is moved into the up state and a %NETDEV_UP message is | ||
| 1123 | * sent to the netdev notifier chain. | ||
| 1124 | * | ||
| 1125 | * Calling this function on an active interface is a nop. On a failure | ||
| 1126 | * a negative errno code is returned. | ||
| 1127 | */ | ||
| 1128 | int dev_open(struct net_device *dev) | ||
| 1129 | { | 1117 | { |
| 1130 | const struct net_device_ops *ops = dev->netdev_ops; | 1118 | const struct net_device_ops *ops = dev->netdev_ops; |
| 1131 | int ret; | 1119 | int ret; |
| @@ -1133,13 +1121,6 @@ int dev_open(struct net_device *dev) | |||
| 1133 | ASSERT_RTNL(); | 1121 | ASSERT_RTNL(); |
| 1134 | 1122 | ||
| 1135 | /* | 1123 | /* |
| 1136 | * Is it already up? | ||
| 1137 | */ | ||
| 1138 | |||
| 1139 | if (dev->flags & IFF_UP) | ||
| 1140 | return 0; | ||
| 1141 | |||
| 1142 | /* | ||
| 1143 | * Is it even present? | 1124 | * Is it even present? |
| 1144 | */ | 1125 | */ |
| 1145 | if (!netif_device_present(dev)) | 1126 | if (!netif_device_present(dev)) |
| @@ -1187,36 +1168,57 @@ int dev_open(struct net_device *dev) | |||
| 1187 | * Wakeup transmit queue engine | 1168 | * Wakeup transmit queue engine |
| 1188 | */ | 1169 | */ |
| 1189 | dev_activate(dev); | 1170 | dev_activate(dev); |
| 1190 | |||
| 1191 | /* | ||
| 1192 | * ... and announce new interface. | ||
| 1193 | */ | ||
| 1194 | call_netdevice_notifiers(NETDEV_UP, dev); | ||
| 1195 | } | 1171 | } |
| 1196 | 1172 | ||
| 1197 | return ret; | 1173 | return ret; |
| 1198 | } | 1174 | } |
| 1199 | EXPORT_SYMBOL(dev_open); | ||
| 1200 | 1175 | ||
| 1201 | /** | 1176 | /** |
| 1202 | * dev_close - shutdown an interface. | 1177 | * dev_open - prepare an interface for use. |
| 1203 | * @dev: device to shutdown | 1178 | * @dev: device to open |
| 1204 | * | 1179 | * |
| 1205 | * This function moves an active device into down state. A | 1180 | * Takes a device from down to up state. The device's private open |
| 1206 | * %NETDEV_GOING_DOWN is sent to the netdev notifier chain. The device | 1181 | * function is invoked and then the multicast lists are loaded. Finally |
| 1207 | * is then deactivated and finally a %NETDEV_DOWN is sent to the notifier | 1182 | * the device is moved into the up state and a %NETDEV_UP message is |
| 1208 | * chain. | 1183 | * sent to the netdev notifier chain. |
| 1184 | * | ||
| 1185 | * Calling this function on an active interface is a nop. On a failure | ||
| 1186 | * a negative errno code is returned. | ||
| 1209 | */ | 1187 | */ |
| 1210 | int dev_close(struct net_device *dev) | 1188 | int dev_open(struct net_device *dev) |
| 1189 | { | ||
| 1190 | int ret; | ||
| 1191 | |||
| 1192 | /* | ||
| 1193 | * Is it already up? | ||
| 1194 | */ | ||
| 1195 | if (dev->flags & IFF_UP) | ||
| 1196 | return 0; | ||
| 1197 | |||
| 1198 | /* | ||
| 1199 | * Open device | ||
| 1200 | */ | ||
| 1201 | ret = __dev_open(dev); | ||
| 1202 | if (ret < 0) | ||
| 1203 | return ret; | ||
| 1204 | |||
| 1205 | /* | ||
| 1206 | * ... and announce new interface. | ||
| 1207 | */ | ||
| 1208 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); | ||
| 1209 | call_netdevice_notifiers(NETDEV_UP, dev); | ||
| 1210 | |||
| 1211 | return ret; | ||
| 1212 | } | ||
| 1213 | EXPORT_SYMBOL(dev_open); | ||
| 1214 | |||
| 1215 | static int __dev_close(struct net_device *dev) | ||
| 1211 | { | 1216 | { |
| 1212 | const struct net_device_ops *ops = dev->netdev_ops; | 1217 | const struct net_device_ops *ops = dev->netdev_ops; |
| 1213 | ASSERT_RTNL(); | ||
| 1214 | 1218 | ||
| 1219 | ASSERT_RTNL(); | ||
| 1215 | might_sleep(); | 1220 | might_sleep(); |
| 1216 | 1221 | ||
| 1217 | if (!(dev->flags & IFF_UP)) | ||
| 1218 | return 0; | ||
| 1219 | |||
| 1220 | /* | 1222 | /* |
| 1221 | * Tell people we are going down, so that they can | 1223 | * Tell people we are going down, so that they can |
| 1222 | * prepare to death, when device is still operating. | 1224 | * prepare to death, when device is still operating. |
| @@ -1252,14 +1254,34 @@ int dev_close(struct net_device *dev) | |||
| 1252 | dev->flags &= ~IFF_UP; | 1254 | dev->flags &= ~IFF_UP; |
| 1253 | 1255 | ||
| 1254 | /* | 1256 | /* |
| 1255 | * Tell people we are down | 1257 | * Shutdown NET_DMA |
| 1256 | */ | 1258 | */ |
| 1257 | call_netdevice_notifiers(NETDEV_DOWN, dev); | 1259 | net_dmaengine_put(); |
| 1260 | |||
| 1261 | return 0; | ||
| 1262 | } | ||
| 1263 | |||
| 1264 | /** | ||
| 1265 | * dev_close - shutdown an interface. | ||
| 1266 | * @dev: device to shutdown | ||
| 1267 | * | ||
| 1268 | * This function moves an active device into down state. A | ||
| 1269 | * %NETDEV_GOING_DOWN is sent to the netdev notifier chain. The device | ||
| 1270 | * is then deactivated and finally a %NETDEV_DOWN is sent to the notifier | ||
| 1271 | * chain. | ||
| 1272 | */ | ||
| 1273 | int dev_close(struct net_device *dev) | ||
| 1274 | { | ||
| 1275 | if (!(dev->flags & IFF_UP)) | ||
| 1276 | return 0; | ||
| 1277 | |||
| 1278 | __dev_close(dev); | ||
| 1258 | 1279 | ||
| 1259 | /* | 1280 | /* |
| 1260 | * Shutdown NET_DMA | 1281 | * Tell people we are down |
| 1261 | */ | 1282 | */ |
| 1262 | net_dmaengine_put(); | 1283 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); |
| 1284 | call_netdevice_notifiers(NETDEV_DOWN, dev); | ||
| 1263 | 1285 | ||
| 1264 | return 0; | 1286 | return 0; |
| 1265 | } | 1287 | } |
| @@ -1448,13 +1470,10 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) | |||
| 1448 | if (skb->len > (dev->mtu + dev->hard_header_len)) | 1470 | if (skb->len > (dev->mtu + dev->hard_header_len)) |
| 1449 | return NET_RX_DROP; | 1471 | return NET_RX_DROP; |
| 1450 | 1472 | ||
| 1451 | skb_dst_drop(skb); | 1473 | skb_set_dev(skb, dev); |
| 1452 | skb->tstamp.tv64 = 0; | 1474 | skb->tstamp.tv64 = 0; |
| 1453 | skb->pkt_type = PACKET_HOST; | 1475 | skb->pkt_type = PACKET_HOST; |
| 1454 | skb->protocol = eth_type_trans(skb, dev); | 1476 | skb->protocol = eth_type_trans(skb, dev); |
| 1455 | skb->mark = 0; | ||
| 1456 | secpath_reset(skb); | ||
| 1457 | nf_reset(skb); | ||
| 1458 | return netif_rx(skb); | 1477 | return netif_rx(skb); |
| 1459 | } | 1478 | } |
| 1460 | EXPORT_SYMBOL_GPL(dev_forward_skb); | 1479 | EXPORT_SYMBOL_GPL(dev_forward_skb); |
| @@ -1614,6 +1633,36 @@ static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) | |||
| 1614 | return false; | 1633 | return false; |
| 1615 | } | 1634 | } |
| 1616 | 1635 | ||
| 1636 | /** | ||
| 1637 | * skb_dev_set -- assign a new device to a buffer | ||
| 1638 | * @skb: buffer for the new device | ||
| 1639 | * @dev: network device | ||
| 1640 | * | ||
| 1641 | * If an skb is owned by a device already, we have to reset | ||
| 1642 | * all data private to the namespace a device belongs to | ||
| 1643 | * before assigning it a new device. | ||
| 1644 | */ | ||
| 1645 | #ifdef CONFIG_NET_NS | ||
| 1646 | void skb_set_dev(struct sk_buff *skb, struct net_device *dev) | ||
| 1647 | { | ||
| 1648 | skb_dst_drop(skb); | ||
| 1649 | if (skb->dev && !net_eq(dev_net(skb->dev), dev_net(dev))) { | ||
| 1650 | secpath_reset(skb); | ||
| 1651 | nf_reset(skb); | ||
| 1652 | skb_init_secmark(skb); | ||
| 1653 | skb->mark = 0; | ||
| 1654 | skb->priority = 0; | ||
| 1655 | skb->nf_trace = 0; | ||
| 1656 | skb->ipvs_property = 0; | ||
| 1657 | #ifdef CONFIG_NET_SCHED | ||
| 1658 | skb->tc_index = 0; | ||
| 1659 | #endif | ||
| 1660 | } | ||
| 1661 | skb->dev = dev; | ||
| 1662 | } | ||
| 1663 | EXPORT_SYMBOL(skb_set_dev); | ||
| 1664 | #endif /* CONFIG_NET_NS */ | ||
| 1665 | |||
| 1617 | /* | 1666 | /* |
| 1618 | * Invalidate hardware checksum when packet is to be mangled, and | 1667 | * Invalidate hardware checksum when packet is to be mangled, and |
| 1619 | * complete checksum manually on outgoing path. | 1668 | * complete checksum manually on outgoing path. |
| @@ -1853,6 +1902,14 @@ gso: | |||
| 1853 | 1902 | ||
| 1854 | skb->next = nskb->next; | 1903 | skb->next = nskb->next; |
| 1855 | nskb->next = NULL; | 1904 | nskb->next = NULL; |
| 1905 | |||
| 1906 | /* | ||
| 1907 | * If device doesnt need nskb->dst, release it right now while | ||
| 1908 | * its hot in this cpu cache | ||
| 1909 | */ | ||
| 1910 | if (dev->priv_flags & IFF_XMIT_DST_RELEASE) | ||
| 1911 | skb_dst_drop(nskb); | ||
| 1912 | |||
| 1856 | rc = ops->ndo_start_xmit(nskb, dev); | 1913 | rc = ops->ndo_start_xmit(nskb, dev); |
| 1857 | if (unlikely(rc != NETDEV_TX_OK)) { | 1914 | if (unlikely(rc != NETDEV_TX_OK)) { |
| 1858 | if (rc & ~NETDEV_TX_MASK) | 1915 | if (rc & ~NETDEV_TX_MASK) |
| @@ -1974,6 +2031,21 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, | |||
| 1974 | return rc; | 2031 | return rc; |
| 1975 | } | 2032 | } |
| 1976 | 2033 | ||
| 2034 | /* | ||
| 2035 | * Returns true if either: | ||
| 2036 | * 1. skb has frag_list and the device doesn't support FRAGLIST, or | ||
| 2037 | * 2. skb is fragmented and the device does not support SG, or if | ||
| 2038 | * at least one of fragments is in highmem and device does not | ||
| 2039 | * support DMA from it. | ||
| 2040 | */ | ||
| 2041 | static inline int skb_needs_linearize(struct sk_buff *skb, | ||
| 2042 | struct net_device *dev) | ||
| 2043 | { | ||
| 2044 | return (skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) || | ||
| 2045 | (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || | ||
| 2046 | illegal_highdma(dev, skb))); | ||
| 2047 | } | ||
| 2048 | |||
| 1977 | /** | 2049 | /** |
| 1978 | * dev_queue_xmit - transmit a buffer | 2050 | * dev_queue_xmit - transmit a buffer |
| 1979 | * @skb: buffer to transmit | 2051 | * @skb: buffer to transmit |
| @@ -2010,18 +2082,8 @@ int dev_queue_xmit(struct sk_buff *skb) | |||
| 2010 | if (netif_needs_gso(dev, skb)) | 2082 | if (netif_needs_gso(dev, skb)) |
| 2011 | goto gso; | 2083 | goto gso; |
| 2012 | 2084 | ||
| 2013 | if (skb_has_frags(skb) && | 2085 | /* Convert a paged skb to linear, if required */ |
| 2014 | !(dev->features & NETIF_F_FRAGLIST) && | 2086 | if (skb_needs_linearize(skb, dev) && __skb_linearize(skb)) |
| 2015 | __skb_linearize(skb)) | ||
| 2016 | goto out_kfree_skb; | ||
| 2017 | |||
| 2018 | /* Fragmented skb is linearized if device does not support SG, | ||
| 2019 | * or if at least one of fragments is in highmem and device | ||
| 2020 | * does not support DMA from it. | ||
| 2021 | */ | ||
| 2022 | if (skb_shinfo(skb)->nr_frags && | ||
| 2023 | (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) && | ||
| 2024 | __skb_linearize(skb)) | ||
| 2025 | goto out_kfree_skb; | 2087 | goto out_kfree_skb; |
| 2026 | 2088 | ||
| 2027 | /* If packet is not checksummed and device does not support | 2089 | /* If packet is not checksummed and device does not support |
| @@ -2041,7 +2103,7 @@ gso: | |||
| 2041 | rcu_read_lock_bh(); | 2103 | rcu_read_lock_bh(); |
| 2042 | 2104 | ||
| 2043 | txq = dev_pick_tx(dev, skb); | 2105 | txq = dev_pick_tx(dev, skb); |
| 2044 | q = rcu_dereference(txq->qdisc); | 2106 | q = rcu_dereference_bh(txq->qdisc); |
| 2045 | 2107 | ||
| 2046 | #ifdef CONFIG_NET_CLS_ACT | 2108 | #ifdef CONFIG_NET_CLS_ACT |
| 2047 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS); | 2109 | skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS); |
| @@ -2422,6 +2484,7 @@ int netif_receive_skb(struct sk_buff *skb) | |||
| 2422 | struct packet_type *ptype, *pt_prev; | 2484 | struct packet_type *ptype, *pt_prev; |
| 2423 | struct net_device *orig_dev; | 2485 | struct net_device *orig_dev; |
| 2424 | struct net_device *null_or_orig; | 2486 | struct net_device *null_or_orig; |
| 2487 | struct net_device *null_or_bond; | ||
| 2425 | int ret = NET_RX_DROP; | 2488 | int ret = NET_RX_DROP; |
| 2426 | __be16 type; | 2489 | __be16 type; |
| 2427 | 2490 | ||
| @@ -2487,12 +2550,24 @@ ncls: | |||
| 2487 | if (!skb) | 2550 | if (!skb) |
| 2488 | goto out; | 2551 | goto out; |
| 2489 | 2552 | ||
| 2553 | /* | ||
| 2554 | * Make sure frames received on VLAN interfaces stacked on | ||
| 2555 | * bonding interfaces still make their way to any base bonding | ||
| 2556 | * device that may have registered for a specific ptype. The | ||
| 2557 | * handler may have to adjust skb->dev and orig_dev. | ||
| 2558 | */ | ||
| 2559 | null_or_bond = NULL; | ||
| 2560 | if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) && | ||
| 2561 | (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) { | ||
| 2562 | null_or_bond = vlan_dev_real_dev(skb->dev); | ||
| 2563 | } | ||
| 2564 | |||
| 2490 | type = skb->protocol; | 2565 | type = skb->protocol; |
| 2491 | list_for_each_entry_rcu(ptype, | 2566 | list_for_each_entry_rcu(ptype, |
| 2492 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { | 2567 | &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) { |
| 2493 | if (ptype->type == type && | 2568 | if (ptype->type == type && (ptype->dev == null_or_orig || |
| 2494 | (ptype->dev == null_or_orig || ptype->dev == skb->dev || | 2569 | ptype->dev == skb->dev || ptype->dev == orig_dev || |
| 2495 | ptype->dev == orig_dev)) { | 2570 | ptype->dev == null_or_bond)) { |
| 2496 | if (pt_prev) | 2571 | if (pt_prev) |
| 2497 | ret = deliver_skb(skb, pt_prev, orig_dev); | 2572 | ret = deliver_skb(skb, pt_prev, orig_dev); |
| 2498 | pt_prev = ptype; | 2573 | pt_prev = ptype; |
| @@ -2561,7 +2636,7 @@ out: | |||
| 2561 | return netif_receive_skb(skb); | 2636 | return netif_receive_skb(skb); |
| 2562 | } | 2637 | } |
| 2563 | 2638 | ||
| 2564 | void napi_gro_flush(struct napi_struct *napi) | 2639 | static void napi_gro_flush(struct napi_struct *napi) |
| 2565 | { | 2640 | { |
| 2566 | struct sk_buff *skb, *next; | 2641 | struct sk_buff *skb, *next; |
| 2567 | 2642 | ||
| @@ -2574,7 +2649,6 @@ void napi_gro_flush(struct napi_struct *napi) | |||
| 2574 | napi->gro_count = 0; | 2649 | napi->gro_count = 0; |
| 2575 | napi->gro_list = NULL; | 2650 | napi->gro_list = NULL; |
| 2576 | } | 2651 | } |
| 2577 | EXPORT_SYMBOL(napi_gro_flush); | ||
| 2578 | 2652 | ||
| 2579 | enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 2653 | enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
| 2580 | { | 2654 | { |
| @@ -2761,7 +2835,7 @@ gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, | |||
| 2761 | switch (ret) { | 2835 | switch (ret) { |
| 2762 | case GRO_NORMAL: | 2836 | case GRO_NORMAL: |
| 2763 | case GRO_HELD: | 2837 | case GRO_HELD: |
| 2764 | skb->protocol = eth_type_trans(skb, napi->dev); | 2838 | skb->protocol = eth_type_trans(skb, skb->dev); |
| 2765 | 2839 | ||
| 2766 | if (ret == GRO_HELD) | 2840 | if (ret == GRO_HELD) |
| 2767 | skb_gro_pull(skb, -ETH_HLEN); | 2841 | skb_gro_pull(skb, -ETH_HLEN); |
| @@ -2966,7 +3040,7 @@ static void net_rx_action(struct softirq_action *h) | |||
| 2966 | * entries to the tail of this list, and only ->poll() | 3040 | * entries to the tail of this list, and only ->poll() |
| 2967 | * calls can remove this head entry from the list. | 3041 | * calls can remove this head entry from the list. |
| 2968 | */ | 3042 | */ |
| 2969 | n = list_entry(list->next, struct napi_struct, poll_list); | 3043 | n = list_first_entry(list, struct napi_struct, poll_list); |
| 2970 | 3044 | ||
| 2971 | have = netpoll_poll_lock(n); | 3045 | have = netpoll_poll_lock(n); |
| 2972 | 3046 | ||
| @@ -3185,7 +3259,7 @@ static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev) | |||
| 3185 | { | 3259 | { |
| 3186 | const struct net_device_stats *stats = dev_get_stats(dev); | 3260 | const struct net_device_stats *stats = dev_get_stats(dev); |
| 3187 | 3261 | ||
| 3188 | seq_printf(seq, "%6s:%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " | 3262 | seq_printf(seq, "%6s: %7lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu " |
| 3189 | "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", | 3263 | "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", |
| 3190 | dev->name, stats->rx_bytes, stats->rx_packets, | 3264 | dev->name, stats->rx_bytes, stats->rx_packets, |
| 3191 | stats->rx_errors, | 3265 | stats->rx_errors, |
| @@ -3640,10 +3714,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
| 3640 | /* Unicast addresses changes may only happen under the rtnl, | 3714 | /* Unicast addresses changes may only happen under the rtnl, |
| 3641 | * therefore calling __dev_set_promiscuity here is safe. | 3715 | * therefore calling __dev_set_promiscuity here is safe. |
| 3642 | */ | 3716 | */ |
| 3643 | if (dev->uc.count > 0 && !dev->uc_promisc) { | 3717 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { |
| 3644 | __dev_set_promiscuity(dev, 1); | 3718 | __dev_set_promiscuity(dev, 1); |
| 3645 | dev->uc_promisc = 1; | 3719 | dev->uc_promisc = 1; |
| 3646 | } else if (dev->uc.count == 0 && dev->uc_promisc) { | 3720 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { |
| 3647 | __dev_set_promiscuity(dev, -1); | 3721 | __dev_set_promiscuity(dev, -1); |
| 3648 | dev->uc_promisc = 0; | 3722 | dev->uc_promisc = 0; |
| 3649 | } | 3723 | } |
| @@ -4211,7 +4285,7 @@ static void dev_addr_discard(struct net_device *dev) | |||
| 4211 | netif_addr_lock_bh(dev); | 4285 | netif_addr_lock_bh(dev); |
| 4212 | 4286 | ||
| 4213 | __dev_addr_discard(&dev->mc_list); | 4287 | __dev_addr_discard(&dev->mc_list); |
| 4214 | dev->mc_count = 0; | 4288 | netdev_mc_count(dev) = 0; |
| 4215 | 4289 | ||
| 4216 | netif_addr_unlock_bh(dev); | 4290 | netif_addr_unlock_bh(dev); |
| 4217 | } | 4291 | } |
| @@ -4247,18 +4321,10 @@ unsigned dev_get_flags(const struct net_device *dev) | |||
| 4247 | } | 4321 | } |
| 4248 | EXPORT_SYMBOL(dev_get_flags); | 4322 | EXPORT_SYMBOL(dev_get_flags); |
| 4249 | 4323 | ||
| 4250 | /** | 4324 | int __dev_change_flags(struct net_device *dev, unsigned int flags) |
| 4251 | * dev_change_flags - change device settings | ||
| 4252 | * @dev: device | ||
| 4253 | * @flags: device state flags | ||
| 4254 | * | ||
| 4255 | * Change settings on device based state flags. The flags are | ||
| 4256 | * in the userspace exported format. | ||
| 4257 | */ | ||
| 4258 | int dev_change_flags(struct net_device *dev, unsigned flags) | ||
| 4259 | { | 4325 | { |
| 4260 | int ret, changes; | ||
| 4261 | int old_flags = dev->flags; | 4326 | int old_flags = dev->flags; |
| 4327 | int ret; | ||
| 4262 | 4328 | ||
| 4263 | ASSERT_RTNL(); | 4329 | ASSERT_RTNL(); |
| 4264 | 4330 | ||
| @@ -4289,17 +4355,12 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
| 4289 | 4355 | ||
| 4290 | ret = 0; | 4356 | ret = 0; |
| 4291 | if ((old_flags ^ flags) & IFF_UP) { /* Bit is different ? */ | 4357 | if ((old_flags ^ flags) & IFF_UP) { /* Bit is different ? */ |
| 4292 | ret = ((old_flags & IFF_UP) ? dev_close : dev_open)(dev); | 4358 | ret = ((old_flags & IFF_UP) ? __dev_close : __dev_open)(dev); |
| 4293 | 4359 | ||
| 4294 | if (!ret) | 4360 | if (!ret) |
| 4295 | dev_set_rx_mode(dev); | 4361 | dev_set_rx_mode(dev); |
| 4296 | } | 4362 | } |
| 4297 | 4363 | ||
| 4298 | if (dev->flags & IFF_UP && | ||
| 4299 | ((old_flags ^ dev->flags) & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | | ||
| 4300 | IFF_VOLATILE))) | ||
| 4301 | call_netdevice_notifiers(NETDEV_CHANGE, dev); | ||
| 4302 | |||
| 4303 | if ((flags ^ dev->gflags) & IFF_PROMISC) { | 4364 | if ((flags ^ dev->gflags) & IFF_PROMISC) { |
| 4304 | int inc = (flags & IFF_PROMISC) ? 1 : -1; | 4365 | int inc = (flags & IFF_PROMISC) ? 1 : -1; |
| 4305 | 4366 | ||
| @@ -4318,11 +4379,47 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
| 4318 | dev_set_allmulti(dev, inc); | 4379 | dev_set_allmulti(dev, inc); |
| 4319 | } | 4380 | } |
| 4320 | 4381 | ||
| 4321 | /* Exclude state transition flags, already notified */ | 4382 | return ret; |
| 4322 | changes = (old_flags ^ dev->flags) & ~(IFF_UP | IFF_RUNNING); | 4383 | } |
| 4384 | |||
| 4385 | void __dev_notify_flags(struct net_device *dev, unsigned int old_flags) | ||
| 4386 | { | ||
| 4387 | unsigned int changes = dev->flags ^ old_flags; | ||
| 4388 | |||
| 4389 | if (changes & IFF_UP) { | ||
| 4390 | if (dev->flags & IFF_UP) | ||
| 4391 | call_netdevice_notifiers(NETDEV_UP, dev); | ||
| 4392 | else | ||
| 4393 | call_netdevice_notifiers(NETDEV_DOWN, dev); | ||
| 4394 | } | ||
| 4395 | |||
| 4396 | if (dev->flags & IFF_UP && | ||
| 4397 | (changes & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI | IFF_VOLATILE))) | ||
| 4398 | call_netdevice_notifiers(NETDEV_CHANGE, dev); | ||
| 4399 | } | ||
| 4400 | |||
| 4401 | /** | ||
| 4402 | * dev_change_flags - change device settings | ||
| 4403 | * @dev: device | ||
| 4404 | * @flags: device state flags | ||
| 4405 | * | ||
| 4406 | * Change settings on device based state flags. The flags are | ||
| 4407 | * in the userspace exported format. | ||
| 4408 | */ | ||
| 4409 | int dev_change_flags(struct net_device *dev, unsigned flags) | ||
| 4410 | { | ||
| 4411 | int ret, changes; | ||
| 4412 | int old_flags = dev->flags; | ||
| 4413 | |||
| 4414 | ret = __dev_change_flags(dev, flags); | ||
| 4415 | if (ret < 0) | ||
| 4416 | return ret; | ||
| 4417 | |||
| 4418 | changes = old_flags ^ dev->flags; | ||
| 4323 | if (changes) | 4419 | if (changes) |
| 4324 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); | 4420 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); |
| 4325 | 4421 | ||
| 4422 | __dev_notify_flags(dev, old_flags); | ||
| 4326 | return ret; | 4423 | return ret; |
| 4327 | } | 4424 | } |
| 4328 | EXPORT_SYMBOL(dev_change_flags); | 4425 | EXPORT_SYMBOL(dev_change_flags); |
| @@ -4813,6 +4910,10 @@ static void rollback_registered_many(struct list_head *head) | |||
| 4813 | */ | 4910 | */ |
| 4814 | call_netdevice_notifiers(NETDEV_UNREGISTER, dev); | 4911 | call_netdevice_notifiers(NETDEV_UNREGISTER, dev); |
| 4815 | 4912 | ||
| 4913 | if (!dev->rtnl_link_ops || | ||
| 4914 | dev->rtnl_link_state == RTNL_LINK_INITIALIZED) | ||
| 4915 | rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); | ||
| 4916 | |||
| 4816 | /* | 4917 | /* |
| 4817 | * Flush the unicast and multicast chains | 4918 | * Flush the unicast and multicast chains |
| 4818 | */ | 4919 | */ |
| @@ -4830,7 +4931,7 @@ static void rollback_registered_many(struct list_head *head) | |||
| 4830 | } | 4931 | } |
| 4831 | 4932 | ||
| 4832 | /* Process any work delayed until the end of the batch */ | 4933 | /* Process any work delayed until the end of the batch */ |
| 4833 | dev = list_entry(head->next, struct net_device, unreg_list); | 4934 | dev = list_first_entry(head, struct net_device, unreg_list); |
| 4834 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); | 4935 | call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); |
| 4835 | 4936 | ||
| 4836 | synchronize_net(); | 4937 | synchronize_net(); |
| @@ -5039,7 +5140,9 @@ int register_netdevice(struct net_device *dev) | |||
| 5039 | * Prevent userspace races by waiting until the network | 5140 | * Prevent userspace races by waiting until the network |
| 5040 | * device is fully setup before sending notifications. | 5141 | * device is fully setup before sending notifications. |
| 5041 | */ | 5142 | */ |
| 5042 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | 5143 | if (!dev->rtnl_link_ops || |
| 5144 | dev->rtnl_link_state == RTNL_LINK_INITIALIZED) | ||
| 5145 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
| 5043 | 5146 | ||
| 5044 | out: | 5147 | out: |
| 5045 | return ret; | 5148 | return ret; |
| @@ -5216,7 +5319,7 @@ void netdev_run_todo(void) | |||
| 5216 | 5319 | ||
| 5217 | while (!list_empty(&list)) { | 5320 | while (!list_empty(&list)) { |
| 5218 | struct net_device *dev | 5321 | struct net_device *dev |
| 5219 | = list_entry(list.next, struct net_device, todo_list); | 5322 | = list_first_entry(&list, struct net_device, todo_list); |
| 5220 | list_del(&dev->todo_list); | 5323 | list_del(&dev->todo_list); |
| 5221 | 5324 | ||
| 5222 | if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { | 5325 | if (unlikely(dev->reg_state != NETREG_UNREGISTERING)) { |
| @@ -5367,6 +5470,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
| 5367 | 5470 | ||
| 5368 | netdev_init_queues(dev); | 5471 | netdev_init_queues(dev); |
| 5369 | 5472 | ||
| 5473 | INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); | ||
| 5474 | dev->ethtool_ntuple_list.count = 0; | ||
| 5370 | INIT_LIST_HEAD(&dev->napi_list); | 5475 | INIT_LIST_HEAD(&dev->napi_list); |
| 5371 | INIT_LIST_HEAD(&dev->unreg_list); | 5476 | INIT_LIST_HEAD(&dev->unreg_list); |
| 5372 | INIT_LIST_HEAD(&dev->link_watch_list); | 5477 | INIT_LIST_HEAD(&dev->link_watch_list); |
| @@ -5403,6 +5508,9 @@ void free_netdev(struct net_device *dev) | |||
| 5403 | /* Flush device addresses */ | 5508 | /* Flush device addresses */ |
| 5404 | dev_addr_flush(dev); | 5509 | dev_addr_flush(dev); |
| 5405 | 5510 | ||
| 5511 | /* Clear ethtool n-tuple list */ | ||
| 5512 | ethtool_ntuple_flush(dev); | ||
| 5513 | |||
| 5406 | list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) | 5514 | list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) |
| 5407 | netif_napi_del(p); | 5515 | netif_napi_del(p); |
| 5408 | 5516 | ||
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 9e2fa39f22a3..fd91569e2394 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c | |||
| @@ -96,6 +96,8 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) | |||
| 96 | int err; | 96 | int err; |
| 97 | 97 | ||
| 98 | netif_addr_lock_bh(dev); | 98 | netif_addr_lock_bh(dev); |
| 99 | if (alen != dev->addr_len) | ||
| 100 | return -EINVAL; | ||
| 99 | err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); | 101 | err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); |
| 100 | if (!err) | 102 | if (!err) |
| 101 | __dev_set_rx_mode(dev); | 103 | __dev_set_rx_mode(dev); |
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index b8e9d3a86887..f8c874975350 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -296,7 +296,6 @@ static int dropmon_net_event(struct notifier_block *ev_block, | |||
| 296 | 296 | ||
| 297 | new_stat->dev = dev; | 297 | new_stat->dev = dev; |
| 298 | new_stat->last_rx = jiffies; | 298 | new_stat->last_rx = jiffies; |
| 299 | INIT_RCU_HEAD(&new_stat->rcu); | ||
| 300 | spin_lock(&trace_state_lock); | 299 | spin_lock(&trace_state_lock); |
| 301 | list_add_rcu(&new_stat->list, &hw_stats_list); | 300 | list_add_rcu(&new_stat->list, &hw_stats_list); |
| 302 | spin_unlock(&trace_state_lock); | 301 | spin_unlock(&trace_state_lock); |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d8aee584e8d1..0f2f82185ec4 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
| @@ -120,7 +120,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data) | |||
| 120 | * NETIF_F_xxx values in include/linux/netdevice.h | 120 | * NETIF_F_xxx values in include/linux/netdevice.h |
| 121 | */ | 121 | */ |
| 122 | static const u32 flags_dup_features = | 122 | static const u32 flags_dup_features = |
| 123 | ETH_FLAG_LRO; | 123 | (ETH_FLAG_LRO | ETH_FLAG_NTUPLE); |
| 124 | 124 | ||
| 125 | u32 ethtool_op_get_flags(struct net_device *dev) | 125 | u32 ethtool_op_get_flags(struct net_device *dev) |
| 126 | { | 126 | { |
| @@ -134,19 +134,44 @@ u32 ethtool_op_get_flags(struct net_device *dev) | |||
| 134 | 134 | ||
| 135 | int ethtool_op_set_flags(struct net_device *dev, u32 data) | 135 | int ethtool_op_set_flags(struct net_device *dev, u32 data) |
| 136 | { | 136 | { |
| 137 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
| 138 | unsigned long features = dev->features; | ||
| 139 | |||
| 137 | if (data & ETH_FLAG_LRO) | 140 | if (data & ETH_FLAG_LRO) |
| 138 | dev->features |= NETIF_F_LRO; | 141 | features |= NETIF_F_LRO; |
| 139 | else | 142 | else |
| 140 | dev->features &= ~NETIF_F_LRO; | 143 | features &= ~NETIF_F_LRO; |
| 144 | |||
| 145 | if (data & ETH_FLAG_NTUPLE) { | ||
| 146 | if (!ops->set_rx_ntuple) | ||
| 147 | return -EOPNOTSUPP; | ||
| 148 | features |= NETIF_F_NTUPLE; | ||
| 149 | } else { | ||
| 150 | /* safe to clear regardless */ | ||
| 151 | features &= ~NETIF_F_NTUPLE; | ||
| 152 | } | ||
| 141 | 153 | ||
| 154 | dev->features = features; | ||
| 142 | return 0; | 155 | return 0; |
| 143 | } | 156 | } |
| 144 | 157 | ||
| 158 | void ethtool_ntuple_flush(struct net_device *dev) | ||
| 159 | { | ||
| 160 | struct ethtool_rx_ntuple_flow_spec_container *fsc, *f; | ||
| 161 | |||
| 162 | list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) { | ||
| 163 | list_del(&fsc->list); | ||
| 164 | kfree(fsc); | ||
| 165 | } | ||
| 166 | dev->ethtool_ntuple_list.count = 0; | ||
| 167 | } | ||
| 168 | EXPORT_SYMBOL(ethtool_ntuple_flush); | ||
| 169 | |||
| 145 | /* Handlers for each ethtool command */ | 170 | /* Handlers for each ethtool command */ |
| 146 | 171 | ||
| 147 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | 172 | static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) |
| 148 | { | 173 | { |
| 149 | struct ethtool_cmd cmd = { ETHTOOL_GSET }; | 174 | struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET }; |
| 150 | int err; | 175 | int err; |
| 151 | 176 | ||
| 152 | if (!dev->ethtool_ops->get_settings) | 177 | if (!dev->ethtool_ops->get_settings) |
| @@ -174,7 +199,10 @@ static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) | |||
| 174 | return dev->ethtool_ops->set_settings(dev, &cmd); | 199 | return dev->ethtool_ops->set_settings(dev, &cmd); |
| 175 | } | 200 | } |
| 176 | 201 | ||
| 177 | static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | 202 | /* |
| 203 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 204 | */ | ||
| 205 | static noinline int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | ||
| 178 | { | 206 | { |
| 179 | struct ethtool_drvinfo info; | 207 | struct ethtool_drvinfo info; |
| 180 | const struct ethtool_ops *ops = dev->ethtool_ops; | 208 | const struct ethtool_ops *ops = dev->ethtool_ops; |
| @@ -209,7 +237,10 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) | |||
| 209 | return 0; | 237 | return 0; |
| 210 | } | 238 | } |
| 211 | 239 | ||
| 212 | static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) | 240 | /* |
| 241 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 242 | */ | ||
| 243 | static noinline int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) | ||
| 213 | { | 244 | { |
| 214 | struct ethtool_rxnfc cmd; | 245 | struct ethtool_rxnfc cmd; |
| 215 | 246 | ||
| @@ -222,7 +253,10 @@ static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) | |||
| 222 | return dev->ethtool_ops->set_rxnfc(dev, &cmd); | 253 | return dev->ethtool_ops->set_rxnfc(dev, &cmd); |
| 223 | } | 254 | } |
| 224 | 255 | ||
| 225 | static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) | 256 | /* |
| 257 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 258 | */ | ||
| 259 | static noinline int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) | ||
| 226 | { | 260 | { |
| 227 | struct ethtool_rxnfc info; | 261 | struct ethtool_rxnfc info; |
| 228 | const struct ethtool_ops *ops = dev->ethtool_ops; | 262 | const struct ethtool_ops *ops = dev->ethtool_ops; |
| @@ -266,6 +300,315 @@ err_out: | |||
| 266 | return ret; | 300 | return ret; |
| 267 | } | 301 | } |
| 268 | 302 | ||
| 303 | static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, | ||
| 304 | struct ethtool_rx_ntuple_flow_spec *spec, | ||
| 305 | struct ethtool_rx_ntuple_flow_spec_container *fsc) | ||
| 306 | { | ||
| 307 | |||
| 308 | /* don't add filters forever */ | ||
| 309 | if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY) { | ||
| 310 | /* free the container */ | ||
| 311 | kfree(fsc); | ||
| 312 | return; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* Copy the whole filter over */ | ||
| 316 | fsc->fs.flow_type = spec->flow_type; | ||
| 317 | memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u)); | ||
| 318 | memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u)); | ||
| 319 | |||
| 320 | fsc->fs.vlan_tag = spec->vlan_tag; | ||
| 321 | fsc->fs.vlan_tag_mask = spec->vlan_tag_mask; | ||
| 322 | fsc->fs.data = spec->data; | ||
| 323 | fsc->fs.data_mask = spec->data_mask; | ||
| 324 | fsc->fs.action = spec->action; | ||
| 325 | |||
| 326 | /* add to the list */ | ||
| 327 | list_add_tail_rcu(&fsc->list, &list->list); | ||
| 328 | list->count++; | ||
| 329 | } | ||
| 330 | |||
| 331 | /* | ||
| 332 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 333 | */ | ||
| 334 | static noinline int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) | ||
| 335 | { | ||
| 336 | struct ethtool_rx_ntuple cmd; | ||
| 337 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
| 338 | struct ethtool_rx_ntuple_flow_spec_container *fsc = NULL; | ||
| 339 | int ret; | ||
| 340 | |||
| 341 | if (!(dev->features & NETIF_F_NTUPLE)) | ||
| 342 | return -EINVAL; | ||
| 343 | |||
| 344 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | ||
| 345 | return -EFAULT; | ||
| 346 | |||
| 347 | /* | ||
| 348 | * Cache filter in dev struct for GET operation only if | ||
| 349 | * the underlying driver doesn't have its own GET operation, and | ||
| 350 | * only if the filter was added successfully. First make sure we | ||
| 351 | * can allocate the filter, then continue if successful. | ||
| 352 | */ | ||
| 353 | if (!ops->get_rx_ntuple) { | ||
| 354 | fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC); | ||
| 355 | if (!fsc) | ||
| 356 | return -ENOMEM; | ||
| 357 | } | ||
| 358 | |||
| 359 | ret = ops->set_rx_ntuple(dev, &cmd); | ||
| 360 | if (ret) { | ||
| 361 | kfree(fsc); | ||
| 362 | return ret; | ||
| 363 | } | ||
| 364 | |||
| 365 | if (!ops->get_rx_ntuple) | ||
| 366 | __rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs, fsc); | ||
| 367 | |||
| 368 | return ret; | ||
| 369 | } | ||
| 370 | |||
| 371 | static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) | ||
| 372 | { | ||
| 373 | struct ethtool_gstrings gstrings; | ||
| 374 | const struct ethtool_ops *ops = dev->ethtool_ops; | ||
| 375 | struct ethtool_rx_ntuple_flow_spec_container *fsc; | ||
| 376 | u8 *data; | ||
| 377 | char *p; | ||
| 378 | int ret, i, num_strings = 0; | ||
| 379 | |||
| 380 | if (!ops->get_sset_count) | ||
| 381 | return -EOPNOTSUPP; | ||
| 382 | |||
| 383 | if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) | ||
| 384 | return -EFAULT; | ||
| 385 | |||
| 386 | ret = ops->get_sset_count(dev, gstrings.string_set); | ||
| 387 | if (ret < 0) | ||
| 388 | return ret; | ||
| 389 | |||
| 390 | gstrings.len = ret; | ||
| 391 | |||
| 392 | data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); | ||
| 393 | if (!data) | ||
| 394 | return -ENOMEM; | ||
| 395 | |||
| 396 | if (ops->get_rx_ntuple) { | ||
| 397 | /* driver-specific filter grab */ | ||
| 398 | ret = ops->get_rx_ntuple(dev, gstrings.string_set, data); | ||
| 399 | goto copy; | ||
| 400 | } | ||
| 401 | |||
| 402 | /* default ethtool filter grab */ | ||
| 403 | i = 0; | ||
| 404 | p = (char *)data; | ||
| 405 | list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) { | ||
| 406 | sprintf(p, "Filter %d:\n", i); | ||
| 407 | p += ETH_GSTRING_LEN; | ||
| 408 | num_strings++; | ||
| 409 | |||
| 410 | switch (fsc->fs.flow_type) { | ||
| 411 | case TCP_V4_FLOW: | ||
| 412 | sprintf(p, "\tFlow Type: TCP\n"); | ||
| 413 | p += ETH_GSTRING_LEN; | ||
| 414 | num_strings++; | ||
| 415 | break; | ||
| 416 | case UDP_V4_FLOW: | ||
| 417 | sprintf(p, "\tFlow Type: UDP\n"); | ||
| 418 | p += ETH_GSTRING_LEN; | ||
| 419 | num_strings++; | ||
| 420 | break; | ||
| 421 | case SCTP_V4_FLOW: | ||
| 422 | sprintf(p, "\tFlow Type: SCTP\n"); | ||
| 423 | p += ETH_GSTRING_LEN; | ||
| 424 | num_strings++; | ||
| 425 | break; | ||
| 426 | case AH_ESP_V4_FLOW: | ||
| 427 | sprintf(p, "\tFlow Type: AH ESP\n"); | ||
| 428 | p += ETH_GSTRING_LEN; | ||
| 429 | num_strings++; | ||
| 430 | break; | ||
| 431 | case ESP_V4_FLOW: | ||
| 432 | sprintf(p, "\tFlow Type: ESP\n"); | ||
| 433 | p += ETH_GSTRING_LEN; | ||
| 434 | num_strings++; | ||
| 435 | break; | ||
| 436 | case IP_USER_FLOW: | ||
| 437 | sprintf(p, "\tFlow Type: Raw IP\n"); | ||
| 438 | p += ETH_GSTRING_LEN; | ||
| 439 | num_strings++; | ||
| 440 | break; | ||
| 441 | case IPV4_FLOW: | ||
| 442 | sprintf(p, "\tFlow Type: IPv4\n"); | ||
| 443 | p += ETH_GSTRING_LEN; | ||
| 444 | num_strings++; | ||
| 445 | break; | ||
| 446 | default: | ||
| 447 | sprintf(p, "\tFlow Type: Unknown\n"); | ||
| 448 | p += ETH_GSTRING_LEN; | ||
| 449 | num_strings++; | ||
| 450 | goto unknown_filter; | ||
| 451 | }; | ||
| 452 | |||
| 453 | /* now the rest of the filters */ | ||
| 454 | switch (fsc->fs.flow_type) { | ||
| 455 | case TCP_V4_FLOW: | ||
| 456 | case UDP_V4_FLOW: | ||
| 457 | case SCTP_V4_FLOW: | ||
| 458 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
| 459 | fsc->fs.h_u.tcp_ip4_spec.ip4src); | ||
| 460 | p += ETH_GSTRING_LEN; | ||
| 461 | num_strings++; | ||
| 462 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
| 463 | fsc->fs.m_u.tcp_ip4_spec.ip4src); | ||
| 464 | p += ETH_GSTRING_LEN; | ||
| 465 | num_strings++; | ||
| 466 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
| 467 | fsc->fs.h_u.tcp_ip4_spec.ip4dst); | ||
| 468 | p += ETH_GSTRING_LEN; | ||
| 469 | num_strings++; | ||
| 470 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
| 471 | fsc->fs.m_u.tcp_ip4_spec.ip4dst); | ||
| 472 | p += ETH_GSTRING_LEN; | ||
| 473 | num_strings++; | ||
| 474 | sprintf(p, "\tSrc Port: %d, mask: 0x%x\n", | ||
| 475 | fsc->fs.h_u.tcp_ip4_spec.psrc, | ||
| 476 | fsc->fs.m_u.tcp_ip4_spec.psrc); | ||
| 477 | p += ETH_GSTRING_LEN; | ||
| 478 | num_strings++; | ||
| 479 | sprintf(p, "\tDest Port: %d, mask: 0x%x\n", | ||
| 480 | fsc->fs.h_u.tcp_ip4_spec.pdst, | ||
| 481 | fsc->fs.m_u.tcp_ip4_spec.pdst); | ||
| 482 | p += ETH_GSTRING_LEN; | ||
| 483 | num_strings++; | ||
| 484 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
| 485 | fsc->fs.h_u.tcp_ip4_spec.tos, | ||
| 486 | fsc->fs.m_u.tcp_ip4_spec.tos); | ||
| 487 | p += ETH_GSTRING_LEN; | ||
| 488 | num_strings++; | ||
| 489 | break; | ||
| 490 | case AH_ESP_V4_FLOW: | ||
| 491 | case ESP_V4_FLOW: | ||
| 492 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
| 493 | fsc->fs.h_u.ah_ip4_spec.ip4src); | ||
| 494 | p += ETH_GSTRING_LEN; | ||
| 495 | num_strings++; | ||
| 496 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
| 497 | fsc->fs.m_u.ah_ip4_spec.ip4src); | ||
| 498 | p += ETH_GSTRING_LEN; | ||
| 499 | num_strings++; | ||
| 500 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
| 501 | fsc->fs.h_u.ah_ip4_spec.ip4dst); | ||
| 502 | p += ETH_GSTRING_LEN; | ||
| 503 | num_strings++; | ||
| 504 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
| 505 | fsc->fs.m_u.ah_ip4_spec.ip4dst); | ||
| 506 | p += ETH_GSTRING_LEN; | ||
| 507 | num_strings++; | ||
| 508 | sprintf(p, "\tSPI: %d, mask: 0x%x\n", | ||
| 509 | fsc->fs.h_u.ah_ip4_spec.spi, | ||
| 510 | fsc->fs.m_u.ah_ip4_spec.spi); | ||
| 511 | p += ETH_GSTRING_LEN; | ||
| 512 | num_strings++; | ||
| 513 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
| 514 | fsc->fs.h_u.ah_ip4_spec.tos, | ||
| 515 | fsc->fs.m_u.ah_ip4_spec.tos); | ||
| 516 | p += ETH_GSTRING_LEN; | ||
| 517 | num_strings++; | ||
| 518 | break; | ||
| 519 | case IP_USER_FLOW: | ||
| 520 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
| 521 | fsc->fs.h_u.raw_ip4_spec.ip4src); | ||
| 522 | p += ETH_GSTRING_LEN; | ||
| 523 | num_strings++; | ||
| 524 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
| 525 | fsc->fs.m_u.raw_ip4_spec.ip4src); | ||
| 526 | p += ETH_GSTRING_LEN; | ||
| 527 | num_strings++; | ||
| 528 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
| 529 | fsc->fs.h_u.raw_ip4_spec.ip4dst); | ||
| 530 | p += ETH_GSTRING_LEN; | ||
| 531 | num_strings++; | ||
| 532 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
| 533 | fsc->fs.m_u.raw_ip4_spec.ip4dst); | ||
| 534 | p += ETH_GSTRING_LEN; | ||
| 535 | num_strings++; | ||
| 536 | break; | ||
| 537 | case IPV4_FLOW: | ||
| 538 | sprintf(p, "\tSrc IP addr: 0x%x\n", | ||
| 539 | fsc->fs.h_u.usr_ip4_spec.ip4src); | ||
| 540 | p += ETH_GSTRING_LEN; | ||
| 541 | num_strings++; | ||
| 542 | sprintf(p, "\tSrc IP mask: 0x%x\n", | ||
| 543 | fsc->fs.m_u.usr_ip4_spec.ip4src); | ||
| 544 | p += ETH_GSTRING_LEN; | ||
| 545 | num_strings++; | ||
| 546 | sprintf(p, "\tDest IP addr: 0x%x\n", | ||
| 547 | fsc->fs.h_u.usr_ip4_spec.ip4dst); | ||
| 548 | p += ETH_GSTRING_LEN; | ||
| 549 | num_strings++; | ||
| 550 | sprintf(p, "\tDest IP mask: 0x%x\n", | ||
| 551 | fsc->fs.m_u.usr_ip4_spec.ip4dst); | ||
| 552 | p += ETH_GSTRING_LEN; | ||
| 553 | num_strings++; | ||
| 554 | sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n", | ||
| 555 | fsc->fs.h_u.usr_ip4_spec.l4_4_bytes, | ||
| 556 | fsc->fs.m_u.usr_ip4_spec.l4_4_bytes); | ||
| 557 | p += ETH_GSTRING_LEN; | ||
| 558 | num_strings++; | ||
| 559 | sprintf(p, "\tTOS: %d, mask: 0x%x\n", | ||
| 560 | fsc->fs.h_u.usr_ip4_spec.tos, | ||
| 561 | fsc->fs.m_u.usr_ip4_spec.tos); | ||
| 562 | p += ETH_GSTRING_LEN; | ||
| 563 | num_strings++; | ||
| 564 | sprintf(p, "\tIP Version: %d, mask: 0x%x\n", | ||
| 565 | fsc->fs.h_u.usr_ip4_spec.ip_ver, | ||
| 566 | fsc->fs.m_u.usr_ip4_spec.ip_ver); | ||
| 567 | p += ETH_GSTRING_LEN; | ||
| 568 | num_strings++; | ||
| 569 | sprintf(p, "\tProtocol: %d, mask: 0x%x\n", | ||
| 570 | fsc->fs.h_u.usr_ip4_spec.proto, | ||
| 571 | fsc->fs.m_u.usr_ip4_spec.proto); | ||
| 572 | p += ETH_GSTRING_LEN; | ||
| 573 | num_strings++; | ||
| 574 | break; | ||
| 575 | }; | ||
| 576 | sprintf(p, "\tVLAN: %d, mask: 0x%x\n", | ||
| 577 | fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask); | ||
| 578 | p += ETH_GSTRING_LEN; | ||
| 579 | num_strings++; | ||
| 580 | sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data); | ||
| 581 | p += ETH_GSTRING_LEN; | ||
| 582 | num_strings++; | ||
| 583 | sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask); | ||
| 584 | p += ETH_GSTRING_LEN; | ||
| 585 | num_strings++; | ||
| 586 | if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) | ||
| 587 | sprintf(p, "\tAction: Drop\n"); | ||
| 588 | else | ||
| 589 | sprintf(p, "\tAction: Direct to queue %d\n", | ||
| 590 | fsc->fs.action); | ||
| 591 | p += ETH_GSTRING_LEN; | ||
| 592 | num_strings++; | ||
| 593 | unknown_filter: | ||
| 594 | i++; | ||
| 595 | } | ||
| 596 | copy: | ||
| 597 | /* indicate to userspace how many strings we actually have */ | ||
| 598 | gstrings.len = num_strings; | ||
| 599 | ret = -EFAULT; | ||
| 600 | if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) | ||
| 601 | goto out; | ||
| 602 | useraddr += sizeof(gstrings); | ||
| 603 | if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) | ||
| 604 | goto out; | ||
| 605 | ret = 0; | ||
| 606 | |||
| 607 | out: | ||
| 608 | kfree(data); | ||
| 609 | return ret; | ||
| 610 | } | ||
| 611 | |||
| 269 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) | 612 | static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) |
| 270 | { | 613 | { |
| 271 | struct ethtool_regs regs; | 614 | struct ethtool_regs regs; |
| @@ -324,7 +667,7 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr) | |||
| 324 | 667 | ||
| 325 | static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) | 668 | static int ethtool_get_wol(struct net_device *dev, char __user *useraddr) |
| 326 | { | 669 | { |
| 327 | struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; | 670 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; |
| 328 | 671 | ||
| 329 | if (!dev->ethtool_ops->get_wol) | 672 | if (!dev->ethtool_ops->get_wol) |
| 330 | return -EOPNOTSUPP; | 673 | return -EOPNOTSUPP; |
| @@ -456,9 +799,12 @@ static int ethtool_set_eeprom(struct net_device *dev, void __user *useraddr) | |||
| 456 | return ret; | 799 | return ret; |
| 457 | } | 800 | } |
| 458 | 801 | ||
| 459 | static int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) | 802 | /* |
| 803 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 804 | */ | ||
| 805 | static noinline int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) | ||
| 460 | { | 806 | { |
| 461 | struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; | 807 | struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE }; |
| 462 | 808 | ||
| 463 | if (!dev->ethtool_ops->get_coalesce) | 809 | if (!dev->ethtool_ops->get_coalesce) |
| 464 | return -EOPNOTSUPP; | 810 | return -EOPNOTSUPP; |
| @@ -470,7 +816,10 @@ static int ethtool_get_coalesce(struct net_device *dev, void __user *useraddr) | |||
| 470 | return 0; | 816 | return 0; |
| 471 | } | 817 | } |
| 472 | 818 | ||
| 473 | static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) | 819 | /* |
| 820 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 821 | */ | ||
| 822 | static noinline int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) | ||
| 474 | { | 823 | { |
| 475 | struct ethtool_coalesce coalesce; | 824 | struct ethtool_coalesce coalesce; |
| 476 | 825 | ||
| @@ -485,7 +834,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) | |||
| 485 | 834 | ||
| 486 | static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) | 835 | static int ethtool_get_ringparam(struct net_device *dev, void __user *useraddr) |
| 487 | { | 836 | { |
| 488 | struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; | 837 | struct ethtool_ringparam ringparam = { .cmd = ETHTOOL_GRINGPARAM }; |
| 489 | 838 | ||
| 490 | if (!dev->ethtool_ops->get_ringparam) | 839 | if (!dev->ethtool_ops->get_ringparam) |
| 491 | return -EOPNOTSUPP; | 840 | return -EOPNOTSUPP; |
| @@ -839,7 +1188,7 @@ static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr) | |||
| 839 | static int ethtool_get_value(struct net_device *dev, char __user *useraddr, | 1188 | static int ethtool_get_value(struct net_device *dev, char __user *useraddr, |
| 840 | u32 cmd, u32 (*actor)(struct net_device *)) | 1189 | u32 cmd, u32 (*actor)(struct net_device *)) |
| 841 | { | 1190 | { |
| 842 | struct ethtool_value edata = { cmd }; | 1191 | struct ethtool_value edata = { .cmd = cmd }; |
| 843 | 1192 | ||
| 844 | if (!actor) | 1193 | if (!actor) |
| 845 | return -EOPNOTSUPP; | 1194 | return -EOPNOTSUPP; |
| @@ -880,7 +1229,10 @@ static int ethtool_set_value(struct net_device *dev, char __user *useraddr, | |||
| 880 | return actor(dev, edata.data); | 1229 | return actor(dev, edata.data); |
| 881 | } | 1230 | } |
| 882 | 1231 | ||
| 883 | static int ethtool_flash_device(struct net_device *dev, char __user *useraddr) | 1232 | /* |
| 1233 | * noinline attribute so that gcc doesnt use too much stack in dev_ethtool() | ||
| 1234 | */ | ||
| 1235 | static noinline int ethtool_flash_device(struct net_device *dev, char __user *useraddr) | ||
| 884 | { | 1236 | { |
| 885 | struct ethtool_flash efl; | 1237 | struct ethtool_flash efl; |
| 886 | 1238 | ||
| @@ -927,6 +1279,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
| 927 | case ETHTOOL_GPERMADDR: | 1279 | case ETHTOOL_GPERMADDR: |
| 928 | case ETHTOOL_GUFO: | 1280 | case ETHTOOL_GUFO: |
| 929 | case ETHTOOL_GGSO: | 1281 | case ETHTOOL_GGSO: |
| 1282 | case ETHTOOL_GGRO: | ||
| 930 | case ETHTOOL_GFLAGS: | 1283 | case ETHTOOL_GFLAGS: |
| 931 | case ETHTOOL_GPFLAGS: | 1284 | case ETHTOOL_GPFLAGS: |
| 932 | case ETHTOOL_GRXFH: | 1285 | case ETHTOOL_GRXFH: |
| @@ -1112,6 +1465,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) | |||
| 1112 | case ETHTOOL_RESET: | 1465 | case ETHTOOL_RESET: |
| 1113 | rc = ethtool_reset(dev, useraddr); | 1466 | rc = ethtool_reset(dev, useraddr); |
| 1114 | break; | 1467 | break; |
| 1468 | case ETHTOOL_SRXNTUPLE: | ||
| 1469 | rc = ethtool_set_rx_ntuple(dev, useraddr); | ||
| 1470 | break; | ||
| 1471 | case ETHTOOL_GRXNTUPLE: | ||
| 1472 | rc = ethtool_get_rx_ntuple(dev, useraddr); | ||
| 1473 | break; | ||
| 1115 | default: | 1474 | default: |
| 1116 | rc = -EOPNOTSUPP; | 1475 | rc = -EOPNOTSUPP; |
| 1117 | } | 1476 | } |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 02a3b2c69c1e..9a24377146bf 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
| @@ -708,7 +708,7 @@ static struct notifier_block fib_rules_notifier = { | |||
| 708 | .notifier_call = fib_rules_event, | 708 | .notifier_call = fib_rules_event, |
| 709 | }; | 709 | }; |
| 710 | 710 | ||
| 711 | static int fib_rules_net_init(struct net *net) | 711 | static int __net_init fib_rules_net_init(struct net *net) |
| 712 | { | 712 | { |
| 713 | INIT_LIST_HEAD(&net->rules_ops); | 713 | INIT_LIST_HEAD(&net->rules_ops); |
| 714 | spin_lock_init(&net->rules_mod_lock); | 714 | spin_lock_init(&net->rules_mod_lock); |
diff --git a/net/core/filter.c b/net/core/filter.c index 08db7b9143a3..d38ef7fd50f0 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -86,7 +86,7 @@ int sk_filter(struct sock *sk, struct sk_buff *skb) | |||
| 86 | return err; | 86 | return err; |
| 87 | 87 | ||
| 88 | rcu_read_lock_bh(); | 88 | rcu_read_lock_bh(); |
| 89 | filter = rcu_dereference(sk->sk_filter); | 89 | filter = rcu_dereference_bh(sk->sk_filter); |
| 90 | if (filter) { | 90 | if (filter) { |
| 91 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, | 91 | unsigned int pkt_len = sk_run_filter(skb, filter->insns, |
| 92 | filter->len); | 92 | filter->len); |
| @@ -521,7 +521,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
| 521 | } | 521 | } |
| 522 | 522 | ||
| 523 | rcu_read_lock_bh(); | 523 | rcu_read_lock_bh(); |
| 524 | old_fp = rcu_dereference(sk->sk_filter); | 524 | old_fp = rcu_dereference_bh(sk->sk_filter); |
| 525 | rcu_assign_pointer(sk->sk_filter, fp); | 525 | rcu_assign_pointer(sk->sk_filter, fp); |
| 526 | rcu_read_unlock_bh(); | 526 | rcu_read_unlock_bh(); |
| 527 | 527 | ||
| @@ -529,6 +529,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
| 529 | sk_filter_delayed_uncharge(sk, old_fp); | 529 | sk_filter_delayed_uncharge(sk, old_fp); |
| 530 | return 0; | 530 | return 0; |
| 531 | } | 531 | } |
| 532 | EXPORT_SYMBOL_GPL(sk_attach_filter); | ||
| 532 | 533 | ||
| 533 | int sk_detach_filter(struct sock *sk) | 534 | int sk_detach_filter(struct sock *sk) |
| 534 | { | 535 | { |
| @@ -536,7 +537,7 @@ int sk_detach_filter(struct sock *sk) | |||
| 536 | struct sk_filter *filter; | 537 | struct sk_filter *filter; |
| 537 | 538 | ||
| 538 | rcu_read_lock_bh(); | 539 | rcu_read_lock_bh(); |
| 539 | filter = rcu_dereference(sk->sk_filter); | 540 | filter = rcu_dereference_bh(sk->sk_filter); |
| 540 | if (filter) { | 541 | if (filter) { |
| 541 | rcu_assign_pointer(sk->sk_filter, NULL); | 542 | rcu_assign_pointer(sk->sk_filter, NULL); |
| 542 | sk_filter_delayed_uncharge(sk, filter); | 543 | sk_filter_delayed_uncharge(sk, filter); |
| @@ -545,3 +546,4 @@ int sk_detach_filter(struct sock *sk) | |||
| 545 | rcu_read_unlock_bh(); | 546 | rcu_read_unlock_bh(); |
| 546 | return ret; | 547 | return ret; |
| 547 | } | 548 | } |
| 549 | EXPORT_SYMBOL_GPL(sk_detach_filter); | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index f35377b643e4..d102f6d9abdc 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -2417,8 +2417,7 @@ EXPORT_SYMBOL(neigh_seq_stop); | |||
| 2417 | 2417 | ||
| 2418 | static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos) | 2418 | static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos) |
| 2419 | { | 2419 | { |
| 2420 | struct proc_dir_entry *pde = seq->private; | 2420 | struct neigh_table *tbl = seq->private; |
| 2421 | struct neigh_table *tbl = pde->data; | ||
| 2422 | int cpu; | 2421 | int cpu; |
| 2423 | 2422 | ||
| 2424 | if (*pos == 0) | 2423 | if (*pos == 0) |
| @@ -2435,8 +2434,7 @@ static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos) | |||
| 2435 | 2434 | ||
| 2436 | static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 2435 | static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
| 2437 | { | 2436 | { |
| 2438 | struct proc_dir_entry *pde = seq->private; | 2437 | struct neigh_table *tbl = seq->private; |
| 2439 | struct neigh_table *tbl = pde->data; | ||
| 2440 | int cpu; | 2438 | int cpu; |
| 2441 | 2439 | ||
| 2442 | for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) { | 2440 | for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) { |
| @@ -2455,8 +2453,7 @@ static void neigh_stat_seq_stop(struct seq_file *seq, void *v) | |||
| 2455 | 2453 | ||
| 2456 | static int neigh_stat_seq_show(struct seq_file *seq, void *v) | 2454 | static int neigh_stat_seq_show(struct seq_file *seq, void *v) |
| 2457 | { | 2455 | { |
| 2458 | struct proc_dir_entry *pde = seq->private; | 2456 | struct neigh_table *tbl = seq->private; |
| 2459 | struct neigh_table *tbl = pde->data; | ||
| 2460 | struct neigh_statistics *st = v; | 2457 | struct neigh_statistics *st = v; |
| 2461 | 2458 | ||
| 2462 | if (v == SEQ_START_TOKEN) { | 2459 | if (v == SEQ_START_TOKEN) { |
| @@ -2501,7 +2498,7 @@ static int neigh_stat_seq_open(struct inode *inode, struct file *file) | |||
| 2501 | 2498 | ||
| 2502 | if (!ret) { | 2499 | if (!ret) { |
| 2503 | struct seq_file *sf = file->private_data; | 2500 | struct seq_file *sf = file->private_data; |
| 2504 | sf->private = PDE(inode); | 2501 | sf->private = PDE(inode)->data; |
| 2505 | } | 2502 | } |
| 2506 | return ret; | 2503 | return ret; |
| 2507 | }; | 2504 | }; |
| @@ -2559,9 +2556,11 @@ EXPORT_SYMBOL(neigh_app_ns); | |||
| 2559 | 2556 | ||
| 2560 | #ifdef CONFIG_SYSCTL | 2557 | #ifdef CONFIG_SYSCTL |
| 2561 | 2558 | ||
| 2559 | #define NEIGH_VARS_MAX 19 | ||
| 2560 | |||
| 2562 | static struct neigh_sysctl_table { | 2561 | static struct neigh_sysctl_table { |
| 2563 | struct ctl_table_header *sysctl_header; | 2562 | struct ctl_table_header *sysctl_header; |
| 2564 | struct ctl_table neigh_vars[__NET_NEIGH_MAX]; | 2563 | struct ctl_table neigh_vars[NEIGH_VARS_MAX]; |
| 2565 | char *dev_name; | 2564 | char *dev_name; |
| 2566 | } neigh_sysctl_template __read_mostly = { | 2565 | } neigh_sysctl_template __read_mostly = { |
| 2567 | .neigh_vars = { | 2566 | .neigh_vars = { |
| @@ -2678,8 +2677,7 @@ static struct neigh_sysctl_table { | |||
| 2678 | }; | 2677 | }; |
| 2679 | 2678 | ||
| 2680 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | 2679 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, |
| 2681 | int p_id, int pdev_id, char *p_name, | 2680 | char *p_name, proc_handler *handler) |
| 2682 | proc_handler *handler) | ||
| 2683 | { | 2681 | { |
| 2684 | struct neigh_sysctl_table *t; | 2682 | struct neigh_sysctl_table *t; |
| 2685 | const char *dev_name_source = NULL; | 2683 | const char *dev_name_source = NULL; |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index fbc1c7472c5e..099c753c4213 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -410,7 +410,8 @@ static ssize_t wireless_show(struct device *d, char *buf, | |||
| 410 | const struct iw_statistics *iw; | 410 | const struct iw_statistics *iw; |
| 411 | ssize_t ret = -EINVAL; | 411 | ssize_t ret = -EINVAL; |
| 412 | 412 | ||
| 413 | rtnl_lock(); | 413 | if (!rtnl_trylock()) |
| 414 | return restart_syscall(); | ||
| 414 | if (dev_isalive(dev)) { | 415 | if (dev_isalive(dev)) { |
| 415 | iw = get_wireless_stats(dev); | 416 | iw = get_wireless_stats(dev); |
| 416 | if (iw) | 417 | if (iw) |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 0b4d0d35ef40..7aa697253765 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -407,11 +407,24 @@ static void arp_reply(struct sk_buff *skb) | |||
| 407 | __be32 sip, tip; | 407 | __be32 sip, tip; |
| 408 | unsigned char *sha; | 408 | unsigned char *sha; |
| 409 | struct sk_buff *send_skb; | 409 | struct sk_buff *send_skb; |
| 410 | struct netpoll *np = NULL; | 410 | struct netpoll *np, *tmp; |
| 411 | unsigned long flags; | ||
| 412 | int hits = 0; | ||
| 413 | |||
| 414 | if (list_empty(&npinfo->rx_np)) | ||
| 415 | return; | ||
| 416 | |||
| 417 | /* Before checking the packet, we do some early | ||
| 418 | inspection whether this is interesting at all */ | ||
| 419 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
| 420 | list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) { | ||
| 421 | if (np->dev == skb->dev) | ||
| 422 | hits++; | ||
| 423 | } | ||
| 424 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
| 411 | 425 | ||
| 412 | if (npinfo->rx_np && npinfo->rx_np->dev == skb->dev) | 426 | /* No netpoll struct is using this dev */ |
| 413 | np = npinfo->rx_np; | 427 | if (!hits) |
| 414 | if (!np) | ||
| 415 | return; | 428 | return; |
| 416 | 429 | ||
| 417 | /* No arp on this interface */ | 430 | /* No arp on this interface */ |
| @@ -437,77 +450,91 @@ static void arp_reply(struct sk_buff *skb) | |||
| 437 | arp_ptr += skb->dev->addr_len; | 450 | arp_ptr += skb->dev->addr_len; |
| 438 | memcpy(&sip, arp_ptr, 4); | 451 | memcpy(&sip, arp_ptr, 4); |
| 439 | arp_ptr += 4; | 452 | arp_ptr += 4; |
| 440 | /* if we actually cared about dst hw addr, it would get copied here */ | 453 | /* If we actually cared about dst hw addr, |
| 454 | it would get copied here */ | ||
| 441 | arp_ptr += skb->dev->addr_len; | 455 | arp_ptr += skb->dev->addr_len; |
| 442 | memcpy(&tip, arp_ptr, 4); | 456 | memcpy(&tip, arp_ptr, 4); |
| 443 | 457 | ||
| 444 | /* Should we ignore arp? */ | 458 | /* Should we ignore arp? */ |
| 445 | if (tip != np->local_ip || | 459 | if (ipv4_is_loopback(tip) || ipv4_is_multicast(tip)) |
| 446 | ipv4_is_loopback(tip) || ipv4_is_multicast(tip)) | ||
| 447 | return; | 460 | return; |
| 448 | 461 | ||
| 449 | size = arp_hdr_len(skb->dev); | 462 | size = arp_hdr_len(skb->dev); |
| 450 | send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev), | ||
| 451 | LL_RESERVED_SPACE(np->dev)); | ||
| 452 | 463 | ||
| 453 | if (!send_skb) | 464 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
| 454 | return; | 465 | list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) { |
| 455 | 466 | if (tip != np->local_ip) | |
| 456 | skb_reset_network_header(send_skb); | 467 | continue; |
| 457 | arp = (struct arphdr *) skb_put(send_skb, size); | ||
| 458 | send_skb->dev = skb->dev; | ||
| 459 | send_skb->protocol = htons(ETH_P_ARP); | ||
| 460 | 468 | ||
| 461 | /* Fill the device header for the ARP frame */ | 469 | send_skb = find_skb(np, size + LL_ALLOCATED_SPACE(np->dev), |
| 462 | if (dev_hard_header(send_skb, skb->dev, ptype, | 470 | LL_RESERVED_SPACE(np->dev)); |
| 463 | sha, np->dev->dev_addr, | 471 | if (!send_skb) |
| 464 | send_skb->len) < 0) { | 472 | continue; |
| 465 | kfree_skb(send_skb); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | 473 | ||
| 469 | /* | 474 | skb_reset_network_header(send_skb); |
| 470 | * Fill out the arp protocol part. | 475 | arp = (struct arphdr *) skb_put(send_skb, size); |
| 471 | * | 476 | send_skb->dev = skb->dev; |
| 472 | * we only support ethernet device type, | 477 | send_skb->protocol = htons(ETH_P_ARP); |
| 473 | * which (according to RFC 1390) should always equal 1 (Ethernet). | ||
| 474 | */ | ||
| 475 | 478 | ||
| 476 | arp->ar_hrd = htons(np->dev->type); | 479 | /* Fill the device header for the ARP frame */ |
| 477 | arp->ar_pro = htons(ETH_P_IP); | 480 | if (dev_hard_header(send_skb, skb->dev, ptype, |
| 478 | arp->ar_hln = np->dev->addr_len; | 481 | sha, np->dev->dev_addr, |
| 479 | arp->ar_pln = 4; | 482 | send_skb->len) < 0) { |
| 480 | arp->ar_op = htons(type); | 483 | kfree_skb(send_skb); |
| 484 | continue; | ||
| 485 | } | ||
| 481 | 486 | ||
| 482 | arp_ptr=(unsigned char *)(arp + 1); | 487 | /* |
| 483 | memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len); | 488 | * Fill out the arp protocol part. |
| 484 | arp_ptr += np->dev->addr_len; | 489 | * |
| 485 | memcpy(arp_ptr, &tip, 4); | 490 | * we only support ethernet device type, |
| 486 | arp_ptr += 4; | 491 | * which (according to RFC 1390) should |
| 487 | memcpy(arp_ptr, sha, np->dev->addr_len); | 492 | * always equal 1 (Ethernet). |
| 488 | arp_ptr += np->dev->addr_len; | 493 | */ |
| 489 | memcpy(arp_ptr, &sip, 4); | ||
| 490 | 494 | ||
| 491 | netpoll_send_skb(np, send_skb); | 495 | arp->ar_hrd = htons(np->dev->type); |
| 496 | arp->ar_pro = htons(ETH_P_IP); | ||
| 497 | arp->ar_hln = np->dev->addr_len; | ||
| 498 | arp->ar_pln = 4; | ||
| 499 | arp->ar_op = htons(type); | ||
| 500 | |||
| 501 | arp_ptr = (unsigned char *)(arp + 1); | ||
| 502 | memcpy(arp_ptr, np->dev->dev_addr, np->dev->addr_len); | ||
| 503 | arp_ptr += np->dev->addr_len; | ||
| 504 | memcpy(arp_ptr, &tip, 4); | ||
| 505 | arp_ptr += 4; | ||
| 506 | memcpy(arp_ptr, sha, np->dev->addr_len); | ||
| 507 | arp_ptr += np->dev->addr_len; | ||
| 508 | memcpy(arp_ptr, &sip, 4); | ||
| 509 | |||
| 510 | netpoll_send_skb(np, send_skb); | ||
| 511 | |||
| 512 | /* If there are several rx_hooks for the same address, | ||
| 513 | we're fine by sending a single reply */ | ||
| 514 | break; | ||
| 515 | } | ||
| 516 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
| 492 | } | 517 | } |
| 493 | 518 | ||
| 494 | int __netpoll_rx(struct sk_buff *skb) | 519 | int __netpoll_rx(struct sk_buff *skb) |
| 495 | { | 520 | { |
| 496 | int proto, len, ulen; | 521 | int proto, len, ulen; |
| 522 | int hits = 0; | ||
| 497 | struct iphdr *iph; | 523 | struct iphdr *iph; |
| 498 | struct udphdr *uh; | 524 | struct udphdr *uh; |
| 499 | struct netpoll_info *npi = skb->dev->npinfo; | 525 | struct netpoll_info *npinfo = skb->dev->npinfo; |
| 500 | struct netpoll *np = npi->rx_np; | 526 | struct netpoll *np, *tmp; |
| 501 | 527 | ||
| 502 | if (!np) | 528 | if (list_empty(&npinfo->rx_np)) |
| 503 | goto out; | 529 | goto out; |
| 530 | |||
| 504 | if (skb->dev->type != ARPHRD_ETHER) | 531 | if (skb->dev->type != ARPHRD_ETHER) |
| 505 | goto out; | 532 | goto out; |
| 506 | 533 | ||
| 507 | /* check if netpoll clients need ARP */ | 534 | /* check if netpoll clients need ARP */ |
| 508 | if (skb->protocol == htons(ETH_P_ARP) && | 535 | if (skb->protocol == htons(ETH_P_ARP) && |
| 509 | atomic_read(&trapped)) { | 536 | atomic_read(&trapped)) { |
| 510 | skb_queue_tail(&npi->arp_tx, skb); | 537 | skb_queue_tail(&npinfo->arp_tx, skb); |
| 511 | return 1; | 538 | return 1; |
| 512 | } | 539 | } |
| 513 | 540 | ||
| @@ -551,16 +578,23 @@ int __netpoll_rx(struct sk_buff *skb) | |||
| 551 | goto out; | 578 | goto out; |
| 552 | if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr)) | 579 | if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr)) |
| 553 | goto out; | 580 | goto out; |
| 554 | if (np->local_ip && np->local_ip != iph->daddr) | ||
| 555 | goto out; | ||
| 556 | if (np->remote_ip && np->remote_ip != iph->saddr) | ||
| 557 | goto out; | ||
| 558 | if (np->local_port && np->local_port != ntohs(uh->dest)) | ||
| 559 | goto out; | ||
| 560 | 581 | ||
| 561 | np->rx_hook(np, ntohs(uh->source), | 582 | list_for_each_entry_safe(np, tmp, &npinfo->rx_np, rx) { |
| 562 | (char *)(uh+1), | 583 | if (np->local_ip && np->local_ip != iph->daddr) |
| 563 | ulen - sizeof(struct udphdr)); | 584 | continue; |
| 585 | if (np->remote_ip && np->remote_ip != iph->saddr) | ||
| 586 | continue; | ||
| 587 | if (np->local_port && np->local_port != ntohs(uh->dest)) | ||
| 588 | continue; | ||
| 589 | |||
| 590 | np->rx_hook(np, ntohs(uh->source), | ||
| 591 | (char *)(uh+1), | ||
| 592 | ulen - sizeof(struct udphdr)); | ||
| 593 | hits++; | ||
| 594 | } | ||
| 595 | |||
| 596 | if (!hits) | ||
| 597 | goto out; | ||
| 564 | 598 | ||
| 565 | kfree_skb(skb); | 599 | kfree_skb(skb); |
| 566 | return 1; | 600 | return 1; |
| @@ -684,6 +718,7 @@ int netpoll_setup(struct netpoll *np) | |||
| 684 | struct net_device *ndev = NULL; | 718 | struct net_device *ndev = NULL; |
| 685 | struct in_device *in_dev; | 719 | struct in_device *in_dev; |
| 686 | struct netpoll_info *npinfo; | 720 | struct netpoll_info *npinfo; |
| 721 | struct netpoll *npe, *tmp; | ||
| 687 | unsigned long flags; | 722 | unsigned long flags; |
| 688 | int err; | 723 | int err; |
| 689 | 724 | ||
| @@ -704,7 +739,7 @@ int netpoll_setup(struct netpoll *np) | |||
| 704 | } | 739 | } |
| 705 | 740 | ||
| 706 | npinfo->rx_flags = 0; | 741 | npinfo->rx_flags = 0; |
| 707 | npinfo->rx_np = NULL; | 742 | INIT_LIST_HEAD(&npinfo->rx_np); |
| 708 | 743 | ||
| 709 | spin_lock_init(&npinfo->rx_lock); | 744 | spin_lock_init(&npinfo->rx_lock); |
| 710 | skb_queue_head_init(&npinfo->arp_tx); | 745 | skb_queue_head_init(&npinfo->arp_tx); |
| @@ -785,7 +820,7 @@ int netpoll_setup(struct netpoll *np) | |||
| 785 | if (np->rx_hook) { | 820 | if (np->rx_hook) { |
| 786 | spin_lock_irqsave(&npinfo->rx_lock, flags); | 821 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
| 787 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; | 822 | npinfo->rx_flags |= NETPOLL_RX_ENABLED; |
| 788 | npinfo->rx_np = np; | 823 | list_add_tail(&np->rx, &npinfo->rx_np); |
| 789 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | 824 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); |
| 790 | } | 825 | } |
| 791 | 826 | ||
| @@ -801,9 +836,16 @@ int netpoll_setup(struct netpoll *np) | |||
| 801 | return 0; | 836 | return 0; |
| 802 | 837 | ||
| 803 | release: | 838 | release: |
| 804 | if (!ndev->npinfo) | 839 | if (!ndev->npinfo) { |
| 840 | spin_lock_irqsave(&npinfo->rx_lock, flags); | ||
| 841 | list_for_each_entry_safe(npe, tmp, &npinfo->rx_np, rx) { | ||
| 842 | npe->dev = NULL; | ||
| 843 | } | ||
| 844 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | ||
| 845 | |||
| 805 | kfree(npinfo); | 846 | kfree(npinfo); |
| 806 | np->dev = NULL; | 847 | } |
| 848 | |||
| 807 | dev_put(ndev); | 849 | dev_put(ndev); |
| 808 | return err; | 850 | return err; |
| 809 | } | 851 | } |
| @@ -823,10 +865,11 @@ void netpoll_cleanup(struct netpoll *np) | |||
| 823 | if (np->dev) { | 865 | if (np->dev) { |
| 824 | npinfo = np->dev->npinfo; | 866 | npinfo = np->dev->npinfo; |
| 825 | if (npinfo) { | 867 | if (npinfo) { |
| 826 | if (npinfo->rx_np == np) { | 868 | if (!list_empty(&npinfo->rx_np)) { |
| 827 | spin_lock_irqsave(&npinfo->rx_lock, flags); | 869 | spin_lock_irqsave(&npinfo->rx_lock, flags); |
| 828 | npinfo->rx_np = NULL; | 870 | list_del(&np->rx); |
| 829 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | 871 | if (list_empty(&npinfo->rx_np)) |
| 872 | npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; | ||
| 830 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | 873 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); |
| 831 | } | 874 | } |
| 832 | 875 | ||
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2e692afdc55d..43923811bd6a 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
| @@ -2188,12 +2188,13 @@ static inline int f_pick(struct pktgen_dev *pkt_dev) | |||
| 2188 | /* If there was already an IPSEC SA, we keep it as is, else | 2188 | /* If there was already an IPSEC SA, we keep it as is, else |
| 2189 | * we go look for it ... | 2189 | * we go look for it ... |
| 2190 | */ | 2190 | */ |
| 2191 | #define DUMMY_MARK 0 | ||
| 2191 | static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) | 2192 | static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) |
| 2192 | { | 2193 | { |
| 2193 | struct xfrm_state *x = pkt_dev->flows[flow].x; | 2194 | struct xfrm_state *x = pkt_dev->flows[flow].x; |
| 2194 | if (!x) { | 2195 | if (!x) { |
| 2195 | /*slow path: we dont already have xfrm_state*/ | 2196 | /*slow path: we dont already have xfrm_state*/ |
| 2196 | x = xfrm_stateonly_find(&init_net, | 2197 | x = xfrm_stateonly_find(&init_net, DUMMY_MARK, |
| 2197 | (xfrm_address_t *)&pkt_dev->cur_daddr, | 2198 | (xfrm_address_t *)&pkt_dev->cur_daddr, |
| 2198 | (xfrm_address_t *)&pkt_dev->cur_saddr, | 2199 | (xfrm_address_t *)&pkt_dev->cur_saddr, |
| 2199 | AF_INET, | 2200 | AF_INET, |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 794bcb897ff0..4568120d8533 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/security.h> | 35 | #include <linux/security.h> |
| 36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
| 37 | #include <linux/if_addr.h> | 37 | #include <linux/if_addr.h> |
| 38 | #include <linux/pci.h> | ||
| 38 | 39 | ||
| 39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
| 40 | #include <asm/system.h> | 41 | #include <asm/system.h> |
| @@ -89,6 +90,14 @@ int rtnl_is_locked(void) | |||
| 89 | } | 90 | } |
| 90 | EXPORT_SYMBOL(rtnl_is_locked); | 91 | EXPORT_SYMBOL(rtnl_is_locked); |
| 91 | 92 | ||
| 93 | #ifdef CONFIG_PROVE_LOCKING | ||
| 94 | int lockdep_rtnl_is_held(void) | ||
| 95 | { | ||
| 96 | return lockdep_is_held(&rtnl_mutex); | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL(lockdep_rtnl_is_held); | ||
| 99 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | ||
| 100 | |||
| 92 | static struct rtnl_link *rtnl_msg_handlers[NPROTO]; | 101 | static struct rtnl_link *rtnl_msg_handlers[NPROTO]; |
| 93 | 102 | ||
| 94 | static inline int rtm_msgindex(int msgtype) | 103 | static inline int rtm_msgindex(int msgtype) |
| @@ -548,6 +557,19 @@ static void set_operstate(struct net_device *dev, unsigned char transition) | |||
| 548 | } | 557 | } |
| 549 | } | 558 | } |
| 550 | 559 | ||
| 560 | static unsigned int rtnl_dev_combine_flags(const struct net_device *dev, | ||
| 561 | const struct ifinfomsg *ifm) | ||
| 562 | { | ||
| 563 | unsigned int flags = ifm->ifi_flags; | ||
| 564 | |||
| 565 | /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ | ||
| 566 | if (ifm->ifi_change) | ||
| 567 | flags = (flags & ifm->ifi_change) | | ||
| 568 | (dev->flags & ~ifm->ifi_change); | ||
| 569 | |||
| 570 | return flags; | ||
| 571 | } | ||
| 572 | |||
| 551 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | 573 | static void copy_rtnl_link_stats(struct rtnl_link_stats *a, |
| 552 | const struct net_device_stats *b) | 574 | const struct net_device_stats *b) |
| 553 | { | 575 | { |
| @@ -580,6 +602,15 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
| 580 | a->tx_compressed = b->tx_compressed; | 602 | a->tx_compressed = b->tx_compressed; |
| 581 | }; | 603 | }; |
| 582 | 604 | ||
| 605 | static inline int rtnl_vfinfo_size(const struct net_device *dev) | ||
| 606 | { | ||
| 607 | if (dev->dev.parent && dev_is_pci(dev->dev.parent)) | ||
| 608 | return dev_num_vf(dev->dev.parent) * | ||
| 609 | sizeof(struct ifla_vf_info); | ||
| 610 | else | ||
| 611 | return 0; | ||
| 612 | } | ||
| 613 | |||
| 583 | static inline size_t if_nlmsg_size(const struct net_device *dev) | 614 | static inline size_t if_nlmsg_size(const struct net_device *dev) |
| 584 | { | 615 | { |
| 585 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) | 616 | return NLMSG_ALIGN(sizeof(struct ifinfomsg)) |
| @@ -597,6 +628,8 @@ static inline size_t if_nlmsg_size(const struct net_device *dev) | |||
| 597 | + nla_total_size(4) /* IFLA_MASTER */ | 628 | + nla_total_size(4) /* IFLA_MASTER */ |
| 598 | + nla_total_size(1) /* IFLA_OPERSTATE */ | 629 | + nla_total_size(1) /* IFLA_OPERSTATE */ |
| 599 | + nla_total_size(1) /* IFLA_LINKMODE */ | 630 | + nla_total_size(1) /* IFLA_LINKMODE */ |
| 631 | + nla_total_size(4) /* IFLA_NUM_VF */ | ||
| 632 | + nla_total_size(rtnl_vfinfo_size(dev)) /* IFLA_VFINFO */ | ||
| 600 | + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ | 633 | + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ |
| 601 | } | 634 | } |
| 602 | 635 | ||
| @@ -665,6 +698,17 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 665 | stats = dev_get_stats(dev); | 698 | stats = dev_get_stats(dev); |
| 666 | copy_rtnl_link_stats(nla_data(attr), stats); | 699 | copy_rtnl_link_stats(nla_data(attr), stats); |
| 667 | 700 | ||
| 701 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { | ||
| 702 | int i; | ||
| 703 | struct ifla_vf_info ivi; | ||
| 704 | |||
| 705 | NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent)); | ||
| 706 | for (i = 0; i < dev_num_vf(dev->dev.parent); i++) { | ||
| 707 | if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) | ||
| 708 | break; | ||
| 709 | NLA_PUT(skb, IFLA_VFINFO, sizeof(ivi), &ivi); | ||
| 710 | } | ||
| 711 | } | ||
| 668 | if (dev->rtnl_link_ops) { | 712 | if (dev->rtnl_link_ops) { |
| 669 | if (rtnl_link_fill(skb, dev) < 0) | 713 | if (rtnl_link_fill(skb, dev) < 0) |
| 670 | goto nla_put_failure; | 714 | goto nla_put_failure; |
| @@ -725,6 +769,12 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = { | |||
| 725 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, | 769 | [IFLA_LINKINFO] = { .type = NLA_NESTED }, |
| 726 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, | 770 | [IFLA_NET_NS_PID] = { .type = NLA_U32 }, |
| 727 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, | 771 | [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, |
| 772 | [IFLA_VF_MAC] = { .type = NLA_BINARY, | ||
| 773 | .len = sizeof(struct ifla_vf_mac) }, | ||
| 774 | [IFLA_VF_VLAN] = { .type = NLA_BINARY, | ||
| 775 | .len = sizeof(struct ifla_vf_vlan) }, | ||
| 776 | [IFLA_VF_TX_RATE] = { .type = NLA_BINARY, | ||
| 777 | .len = sizeof(struct ifla_vf_tx_rate) }, | ||
| 728 | }; | 778 | }; |
| 729 | EXPORT_SYMBOL(ifla_policy); | 779 | EXPORT_SYMBOL(ifla_policy); |
| 730 | 780 | ||
| @@ -875,13 +925,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
| 875 | } | 925 | } |
| 876 | 926 | ||
| 877 | if (ifm->ifi_flags || ifm->ifi_change) { | 927 | if (ifm->ifi_flags || ifm->ifi_change) { |
| 878 | unsigned int flags = ifm->ifi_flags; | 928 | err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm)); |
| 879 | |||
| 880 | /* bugwards compatibility: ifi_change == 0 is treated as ~0 */ | ||
| 881 | if (ifm->ifi_change) | ||
| 882 | flags = (flags & ifm->ifi_change) | | ||
| 883 | (dev->flags & ~ifm->ifi_change); | ||
| 884 | err = dev_change_flags(dev, flags); | ||
| 885 | if (err < 0) | 929 | if (err < 0) |
| 886 | goto errout; | 930 | goto errout; |
| 887 | } | 931 | } |
| @@ -898,6 +942,41 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
| 898 | write_unlock_bh(&dev_base_lock); | 942 | write_unlock_bh(&dev_base_lock); |
| 899 | } | 943 | } |
| 900 | 944 | ||
| 945 | if (tb[IFLA_VF_MAC]) { | ||
| 946 | struct ifla_vf_mac *ivm; | ||
| 947 | ivm = nla_data(tb[IFLA_VF_MAC]); | ||
| 948 | err = -EOPNOTSUPP; | ||
| 949 | if (ops->ndo_set_vf_mac) | ||
| 950 | err = ops->ndo_set_vf_mac(dev, ivm->vf, ivm->mac); | ||
| 951 | if (err < 0) | ||
| 952 | goto errout; | ||
| 953 | modified = 1; | ||
| 954 | } | ||
| 955 | |||
| 956 | if (tb[IFLA_VF_VLAN]) { | ||
| 957 | struct ifla_vf_vlan *ivv; | ||
| 958 | ivv = nla_data(tb[IFLA_VF_VLAN]); | ||
| 959 | err = -EOPNOTSUPP; | ||
| 960 | if (ops->ndo_set_vf_vlan) | ||
| 961 | err = ops->ndo_set_vf_vlan(dev, ivv->vf, | ||
| 962 | ivv->vlan, | ||
| 963 | ivv->qos); | ||
| 964 | if (err < 0) | ||
| 965 | goto errout; | ||
| 966 | modified = 1; | ||
| 967 | } | ||
| 968 | err = 0; | ||
| 969 | |||
| 970 | if (tb[IFLA_VF_TX_RATE]) { | ||
| 971 | struct ifla_vf_tx_rate *ivt; | ||
| 972 | ivt = nla_data(tb[IFLA_VF_TX_RATE]); | ||
| 973 | err = -EOPNOTSUPP; | ||
| 974 | if (ops->ndo_set_vf_tx_rate) | ||
| 975 | err = ops->ndo_set_vf_tx_rate(dev, ivt->vf, ivt->rate); | ||
| 976 | if (err < 0) | ||
| 977 | goto errout; | ||
| 978 | modified = 1; | ||
| 979 | } | ||
| 901 | err = 0; | 980 | err = 0; |
| 902 | 981 | ||
| 903 | errout: | 982 | errout: |
| @@ -989,6 +1068,26 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 989 | return 0; | 1068 | return 0; |
| 990 | } | 1069 | } |
| 991 | 1070 | ||
| 1071 | int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm) | ||
| 1072 | { | ||
| 1073 | unsigned int old_flags; | ||
| 1074 | int err; | ||
| 1075 | |||
| 1076 | old_flags = dev->flags; | ||
| 1077 | if (ifm && (ifm->ifi_flags || ifm->ifi_change)) { | ||
| 1078 | err = __dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm)); | ||
| 1079 | if (err < 0) | ||
| 1080 | return err; | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | dev->rtnl_link_state = RTNL_LINK_INITIALIZED; | ||
| 1084 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
| 1085 | |||
| 1086 | __dev_notify_flags(dev, old_flags); | ||
| 1087 | return 0; | ||
| 1088 | } | ||
| 1089 | EXPORT_SYMBOL(rtnl_configure_link); | ||
| 1090 | |||
| 992 | struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | 1091 | struct net_device *rtnl_create_link(struct net *src_net, struct net *net, |
| 993 | char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) | 1092 | char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) |
| 994 | { | 1093 | { |
| @@ -1010,6 +1109,7 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net, | |||
| 1010 | 1109 | ||
| 1011 | dev_net_set(dev, net); | 1110 | dev_net_set(dev, net); |
| 1012 | dev->rtnl_link_ops = ops; | 1111 | dev->rtnl_link_ops = ops; |
| 1112 | dev->rtnl_link_state = RTNL_LINK_INITIALIZING; | ||
| 1013 | dev->real_num_tx_queues = real_num_queues; | 1113 | dev->real_num_tx_queues = real_num_queues; |
| 1014 | 1114 | ||
| 1015 | if (strchr(dev->name, '%')) { | 1115 | if (strchr(dev->name, '%')) { |
| @@ -1139,7 +1239,7 @@ replay: | |||
| 1139 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) | 1239 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) |
| 1140 | return -ENODEV; | 1240 | return -ENODEV; |
| 1141 | 1241 | ||
| 1142 | if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change) | 1242 | if (ifm->ifi_index) |
| 1143 | return -EOPNOTSUPP; | 1243 | return -EOPNOTSUPP; |
| 1144 | if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO]) | 1244 | if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO]) |
| 1145 | return -EOPNOTSUPP; | 1245 | return -EOPNOTSUPP; |
| @@ -1170,9 +1270,15 @@ replay: | |||
| 1170 | err = ops->newlink(net, dev, tb, data); | 1270 | err = ops->newlink(net, dev, tb, data); |
| 1171 | else | 1271 | else |
| 1172 | err = register_netdevice(dev); | 1272 | err = register_netdevice(dev); |
| 1173 | if (err < 0 && !IS_ERR(dev)) | 1273 | if (err < 0 && !IS_ERR(dev)) { |
| 1174 | free_netdev(dev); | 1274 | free_netdev(dev); |
| 1275 | goto out; | ||
| 1276 | } | ||
| 1175 | 1277 | ||
| 1278 | err = rtnl_configure_link(dev, ifm); | ||
| 1279 | if (err < 0) | ||
| 1280 | unregister_netdevice(dev); | ||
| 1281 | out: | ||
| 1176 | put_net(dest_net); | 1282 | put_net(dest_net); |
| 1177 | return err; | 1283 | return err; |
| 1178 | } | 1284 | } |
| @@ -1361,17 +1467,14 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi | |||
| 1361 | struct net_device *dev = ptr; | 1467 | struct net_device *dev = ptr; |
| 1362 | 1468 | ||
| 1363 | switch (event) { | 1469 | switch (event) { |
| 1364 | case NETDEV_UNREGISTER: | ||
| 1365 | rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); | ||
| 1366 | break; | ||
| 1367 | case NETDEV_UP: | 1470 | case NETDEV_UP: |
| 1368 | case NETDEV_DOWN: | 1471 | case NETDEV_DOWN: |
| 1369 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); | 1472 | case NETDEV_PRE_UP: |
| 1370 | break; | ||
| 1371 | case NETDEV_POST_INIT: | 1473 | case NETDEV_POST_INIT: |
| 1372 | case NETDEV_REGISTER: | 1474 | case NETDEV_REGISTER: |
| 1373 | case NETDEV_CHANGE: | 1475 | case NETDEV_CHANGE: |
| 1374 | case NETDEV_GOING_DOWN: | 1476 | case NETDEV_GOING_DOWN: |
| 1477 | case NETDEV_UNREGISTER: | ||
| 1375 | case NETDEV_UNREGISTER_BATCH: | 1478 | case NETDEV_UNREGISTER_BATCH: |
| 1376 | break; | 1479 | break; |
| 1377 | default: | 1480 | default: |
| @@ -1386,7 +1489,7 @@ static struct notifier_block rtnetlink_dev_notifier = { | |||
| 1386 | }; | 1489 | }; |
| 1387 | 1490 | ||
| 1388 | 1491 | ||
| 1389 | static int rtnetlink_net_init(struct net *net) | 1492 | static int __net_init rtnetlink_net_init(struct net *net) |
| 1390 | { | 1493 | { |
| 1391 | struct sock *sk; | 1494 | struct sock *sk; |
| 1392 | sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, | 1495 | sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX, |
| @@ -1397,7 +1500,7 @@ static int rtnetlink_net_init(struct net *net) | |||
| 1397 | return 0; | 1500 | return 0; |
| 1398 | } | 1501 | } |
| 1399 | 1502 | ||
| 1400 | static void rtnetlink_net_exit(struct net *net) | 1503 | static void __net_exit rtnetlink_net_exit(struct net *net) |
| 1401 | { | 1504 | { |
| 1402 | netlink_kernel_release(net->rtnl); | 1505 | netlink_kernel_release(net->rtnl); |
| 1403 | net->rtnl = NULL; | 1506 | net->rtnl = NULL; |
diff --git a/net/core/scm.c b/net/core/scm.c index b7ba91b074b3..9b264634acfd 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
| @@ -156,6 +156,8 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
| 156 | switch (cmsg->cmsg_type) | 156 | switch (cmsg->cmsg_type) |
| 157 | { | 157 | { |
| 158 | case SCM_RIGHTS: | 158 | case SCM_RIGHTS: |
| 159 | if (!sock->ops || sock->ops->family != PF_UNIX) | ||
| 160 | goto error; | ||
| 159 | err=scm_fp_copy(cmsg, &p->fp); | 161 | err=scm_fp_copy(cmsg, &p->fp); |
| 160 | if (err<0) | 162 | if (err<0) |
| 161 | goto error; | 163 | goto error; |
diff --git a/net/core/sock.c b/net/core/sock.c index e1f6f225f012..fcd397a762ff 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -741,7 +741,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
| 741 | struct timeval tm; | 741 | struct timeval tm; |
| 742 | } v; | 742 | } v; |
| 743 | 743 | ||
| 744 | unsigned int lv = sizeof(int); | 744 | int lv = sizeof(int); |
| 745 | int len; | 745 | int len; |
| 746 | 746 | ||
| 747 | if (get_user(len, optlen)) | 747 | if (get_user(len, optlen)) |
| @@ -1073,7 +1073,8 @@ static void __sk_free(struct sock *sk) | |||
| 1073 | if (sk->sk_destruct) | 1073 | if (sk->sk_destruct) |
| 1074 | sk->sk_destruct(sk); | 1074 | sk->sk_destruct(sk); |
| 1075 | 1075 | ||
| 1076 | filter = rcu_dereference(sk->sk_filter); | 1076 | filter = rcu_dereference_check(sk->sk_filter, |
| 1077 | atomic_read(&sk->sk_wmem_alloc) == 0); | ||
| 1077 | if (filter) { | 1078 | if (filter) { |
| 1078 | sk_filter_uncharge(sk, filter); | 1079 | sk_filter_uncharge(sk, filter); |
| 1079 | rcu_assign_pointer(sk->sk_filter, NULL); | 1080 | rcu_assign_pointer(sk->sk_filter, NULL); |
| @@ -2140,13 +2141,13 @@ int sock_prot_inuse_get(struct net *net, struct proto *prot) | |||
| 2140 | } | 2141 | } |
| 2141 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); | 2142 | EXPORT_SYMBOL_GPL(sock_prot_inuse_get); |
| 2142 | 2143 | ||
| 2143 | static int sock_inuse_init_net(struct net *net) | 2144 | static int __net_init sock_inuse_init_net(struct net *net) |
| 2144 | { | 2145 | { |
| 2145 | net->core.inuse = alloc_percpu(struct prot_inuse); | 2146 | net->core.inuse = alloc_percpu(struct prot_inuse); |
| 2146 | return net->core.inuse ? 0 : -ENOMEM; | 2147 | return net->core.inuse ? 0 : -ENOMEM; |
| 2147 | } | 2148 | } |
| 2148 | 2149 | ||
| 2149 | static void sock_inuse_exit_net(struct net *net) | 2150 | static void __net_exit sock_inuse_exit_net(struct net *net) |
| 2150 | { | 2151 | { |
| 2151 | free_percpu(net->core.inuse); | 2152 | free_percpu(net->core.inuse); |
| 2152 | } | 2153 | } |
| @@ -2228,13 +2229,10 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 2228 | } | 2229 | } |
| 2229 | 2230 | ||
| 2230 | if (prot->rsk_prot != NULL) { | 2231 | if (prot->rsk_prot != NULL) { |
| 2231 | static const char mask[] = "request_sock_%s"; | 2232 | prot->rsk_prot->slab_name = kasprintf(GFP_KERNEL, "request_sock_%s", prot->name); |
| 2232 | |||
| 2233 | prot->rsk_prot->slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); | ||
| 2234 | if (prot->rsk_prot->slab_name == NULL) | 2233 | if (prot->rsk_prot->slab_name == NULL) |
| 2235 | goto out_free_sock_slab; | 2234 | goto out_free_sock_slab; |
| 2236 | 2235 | ||
| 2237 | sprintf(prot->rsk_prot->slab_name, mask, prot->name); | ||
| 2238 | prot->rsk_prot->slab = kmem_cache_create(prot->rsk_prot->slab_name, | 2236 | prot->rsk_prot->slab = kmem_cache_create(prot->rsk_prot->slab_name, |
| 2239 | prot->rsk_prot->obj_size, 0, | 2237 | prot->rsk_prot->obj_size, 0, |
| 2240 | SLAB_HWCACHE_ALIGN, NULL); | 2238 | SLAB_HWCACHE_ALIGN, NULL); |
| @@ -2247,14 +2245,11 @@ int proto_register(struct proto *prot, int alloc_slab) | |||
| 2247 | } | 2245 | } |
| 2248 | 2246 | ||
| 2249 | if (prot->twsk_prot != NULL) { | 2247 | if (prot->twsk_prot != NULL) { |
| 2250 | static const char mask[] = "tw_sock_%s"; | 2248 | prot->twsk_prot->twsk_slab_name = kasprintf(GFP_KERNEL, "tw_sock_%s", prot->name); |
| 2251 | |||
| 2252 | prot->twsk_prot->twsk_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL); | ||
| 2253 | 2249 | ||
| 2254 | if (prot->twsk_prot->twsk_slab_name == NULL) | 2250 | if (prot->twsk_prot->twsk_slab_name == NULL) |
| 2255 | goto out_free_request_sock_slab; | 2251 | goto out_free_request_sock_slab; |
| 2256 | 2252 | ||
| 2257 | sprintf(prot->twsk_prot->twsk_slab_name, mask, prot->name); | ||
| 2258 | prot->twsk_prot->twsk_slab = | 2253 | prot->twsk_prot->twsk_slab = |
| 2259 | kmem_cache_create(prot->twsk_prot->twsk_slab_name, | 2254 | kmem_cache_create(prot->twsk_prot->twsk_slab_name, |
| 2260 | prot->twsk_prot->twsk_obj_size, | 2255 | prot->twsk_prot->twsk_obj_size, |
