diff options
| author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2015-11-17 08:16:52 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2015-11-17 15:25:44 -0500 |
| commit | b22b941b2c253a20e1d000c671594c4f3f0a3858 (patch) | |
| tree | 3ce06dfe41611a60d5dbdc21c5eac1ae7869cebe | |
| parent | 19125c1a4fd873421698876f34a06dbe18d25f17 (diff) | |
rtnetlink: fix frame size warning in rtnl_fill_ifinfo
Fix the following warning:
CC net/core/rtnetlink.o
net/core/rtnetlink.c: In function ‘rtnl_fill_ifinfo’:
net/core/rtnetlink.c:1308:1: warning: the frame size of 2864 bytes is larger than 2048 bytes [-Wframe-larger-than=]
}
^
by splitting up the huge rtnl_fill_ifinfo into some smaller ones, so we
don't have the huge frame allocations at the same time.
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/core/rtnetlink.c | 274 |
1 files changed, 152 insertions, 122 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 504bd17b7456..34ba7a08876d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -1045,15 +1045,156 @@ static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev) | |||
| 1045 | return 0; | 1045 | return 0; |
| 1046 | } | 1046 | } |
| 1047 | 1047 | ||
| 1048 | static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, | ||
| 1049 | struct net_device *dev) | ||
| 1050 | { | ||
| 1051 | const struct rtnl_link_stats64 *stats; | ||
| 1052 | struct rtnl_link_stats64 temp; | ||
| 1053 | struct nlattr *attr; | ||
| 1054 | |||
| 1055 | stats = dev_get_stats(dev, &temp); | ||
| 1056 | |||
| 1057 | attr = nla_reserve(skb, IFLA_STATS, | ||
| 1058 | sizeof(struct rtnl_link_stats)); | ||
| 1059 | if (!attr) | ||
| 1060 | return -EMSGSIZE; | ||
| 1061 | |||
| 1062 | copy_rtnl_link_stats(nla_data(attr), stats); | ||
| 1063 | |||
| 1064 | attr = nla_reserve(skb, IFLA_STATS64, | ||
| 1065 | sizeof(struct rtnl_link_stats64)); | ||
| 1066 | if (!attr) | ||
| 1067 | return -EMSGSIZE; | ||
| 1068 | |||
| 1069 | copy_rtnl_link_stats64(nla_data(attr), stats); | ||
| 1070 | |||
| 1071 | return 0; | ||
| 1072 | } | ||
| 1073 | |||
| 1074 | static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, | ||
| 1075 | struct net_device *dev, | ||
| 1076 | int vfs_num, | ||
| 1077 | struct nlattr *vfinfo) | ||
| 1078 | { | ||
| 1079 | struct ifla_vf_rss_query_en vf_rss_query_en; | ||
| 1080 | struct ifla_vf_link_state vf_linkstate; | ||
| 1081 | struct ifla_vf_spoofchk vf_spoofchk; | ||
| 1082 | struct ifla_vf_tx_rate vf_tx_rate; | ||
| 1083 | struct ifla_vf_stats vf_stats; | ||
| 1084 | struct ifla_vf_trust vf_trust; | ||
| 1085 | struct ifla_vf_vlan vf_vlan; | ||
| 1086 | struct ifla_vf_rate vf_rate; | ||
| 1087 | struct nlattr *vf, *vfstats; | ||
| 1088 | struct ifla_vf_mac vf_mac; | ||
| 1089 | struct ifla_vf_info ivi; | ||
| 1090 | |||
| 1091 | /* Not all SR-IOV capable drivers support the | ||
| 1092 | * spoofcheck and "RSS query enable" query. Preset to | ||
| 1093 | * -1 so the user space tool can detect that the driver | ||
| 1094 | * didn't report anything. | ||
| 1095 | */ | ||
| 1096 | ivi.spoofchk = -1; | ||
| 1097 | ivi.rss_query_en = -1; | ||
| 1098 | ivi.trusted = -1; | ||
| 1099 | memset(ivi.mac, 0, sizeof(ivi.mac)); | ||
| 1100 | /* The default value for VF link state is "auto" | ||
| 1101 | * IFLA_VF_LINK_STATE_AUTO which equals zero | ||
| 1102 | */ | ||
| 1103 | ivi.linkstate = 0; | ||
| 1104 | if (dev->netdev_ops->ndo_get_vf_config(dev, vfs_num, &ivi)) | ||
| 1105 | return 0; | ||
| 1106 | |||
| 1107 | vf_mac.vf = | ||
| 1108 | vf_vlan.vf = | ||
| 1109 | vf_rate.vf = | ||
| 1110 | vf_tx_rate.vf = | ||
| 1111 | vf_spoofchk.vf = | ||
| 1112 | vf_linkstate.vf = | ||
| 1113 | vf_rss_query_en.vf = | ||
| 1114 | vf_trust.vf = ivi.vf; | ||
| 1115 | |||
| 1116 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); | ||
| 1117 | vf_vlan.vlan = ivi.vlan; | ||
| 1118 | vf_vlan.qos = ivi.qos; | ||
| 1119 | vf_tx_rate.rate = ivi.max_tx_rate; | ||
| 1120 | vf_rate.min_tx_rate = ivi.min_tx_rate; | ||
| 1121 | vf_rate.max_tx_rate = ivi.max_tx_rate; | ||
| 1122 | vf_spoofchk.setting = ivi.spoofchk; | ||
| 1123 | vf_linkstate.link_state = ivi.linkstate; | ||
| 1124 | vf_rss_query_en.setting = ivi.rss_query_en; | ||
| 1125 | vf_trust.setting = ivi.trusted; | ||
| 1126 | vf = nla_nest_start(skb, IFLA_VF_INFO); | ||
| 1127 | if (!vf) { | ||
| 1128 | nla_nest_cancel(skb, vfinfo); | ||
| 1129 | return -EMSGSIZE; | ||
| 1130 | } | ||
| 1131 | if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || | ||
| 1132 | nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || | ||
| 1133 | nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), | ||
| 1134 | &vf_rate) || | ||
| 1135 | nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), | ||
| 1136 | &vf_tx_rate) || | ||
| 1137 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), | ||
| 1138 | &vf_spoofchk) || | ||
| 1139 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), | ||
| 1140 | &vf_linkstate) || | ||
| 1141 | nla_put(skb, IFLA_VF_RSS_QUERY_EN, | ||
| 1142 | sizeof(vf_rss_query_en), | ||
| 1143 | &vf_rss_query_en) || | ||
| 1144 | nla_put(skb, IFLA_VF_TRUST, | ||
| 1145 | sizeof(vf_trust), &vf_trust)) | ||
| 1146 | return -EMSGSIZE; | ||
| 1147 | memset(&vf_stats, 0, sizeof(vf_stats)); | ||
| 1148 | if (dev->netdev_ops->ndo_get_vf_stats) | ||
| 1149 | dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num, | ||
| 1150 | &vf_stats); | ||
| 1151 | vfstats = nla_nest_start(skb, IFLA_VF_STATS); | ||
| 1152 | if (!vfstats) { | ||
| 1153 | nla_nest_cancel(skb, vf); | ||
| 1154 | nla_nest_cancel(skb, vfinfo); | ||
| 1155 | return -EMSGSIZE; | ||
| 1156 | } | ||
| 1157 | if (nla_put_u64(skb, IFLA_VF_STATS_RX_PACKETS, | ||
| 1158 | vf_stats.rx_packets) || | ||
| 1159 | nla_put_u64(skb, IFLA_VF_STATS_TX_PACKETS, | ||
| 1160 | vf_stats.tx_packets) || | ||
| 1161 | nla_put_u64(skb, IFLA_VF_STATS_RX_BYTES, | ||
| 1162 | vf_stats.rx_bytes) || | ||
| 1163 | nla_put_u64(skb, IFLA_VF_STATS_TX_BYTES, | ||
| 1164 | vf_stats.tx_bytes) || | ||
| 1165 | nla_put_u64(skb, IFLA_VF_STATS_BROADCAST, | ||
| 1166 | vf_stats.broadcast) || | ||
| 1167 | nla_put_u64(skb, IFLA_VF_STATS_MULTICAST, | ||
| 1168 | vf_stats.multicast)) | ||
| 1169 | return -EMSGSIZE; | ||
| 1170 | nla_nest_end(skb, vfstats); | ||
| 1171 | nla_nest_end(skb, vf); | ||
| 1172 | return 0; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | static int rtnl_fill_link_ifmap(struct sk_buff *skb, struct net_device *dev) | ||
| 1176 | { | ||
| 1177 | struct rtnl_link_ifmap map = { | ||
| 1178 | .mem_start = dev->mem_start, | ||
| 1179 | .mem_end = dev->mem_end, | ||
| 1180 | .base_addr = dev->base_addr, | ||
| 1181 | .irq = dev->irq, | ||
| 1182 | .dma = dev->dma, | ||
| 1183 | .port = dev->if_port, | ||
| 1184 | }; | ||
| 1185 | if (nla_put(skb, IFLA_MAP, sizeof(map), &map)) | ||
| 1186 | return -EMSGSIZE; | ||
| 1187 | |||
| 1188 | return 0; | ||
| 1189 | } | ||
| 1190 | |||
| 1048 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | 1191 | static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, |
| 1049 | int type, u32 pid, u32 seq, u32 change, | 1192 | int type, u32 pid, u32 seq, u32 change, |
| 1050 | unsigned int flags, u32 ext_filter_mask) | 1193 | unsigned int flags, u32 ext_filter_mask) |
| 1051 | { | 1194 | { |
| 1052 | struct ifinfomsg *ifm; | 1195 | struct ifinfomsg *ifm; |
| 1053 | struct nlmsghdr *nlh; | 1196 | struct nlmsghdr *nlh; |
| 1054 | struct rtnl_link_stats64 temp; | 1197 | struct nlattr *af_spec; |
| 1055 | const struct rtnl_link_stats64 *stats; | ||
| 1056 | struct nlattr *attr, *af_spec; | ||
| 1057 | struct rtnl_af_ops *af_ops; | 1198 | struct rtnl_af_ops *af_ops; |
| 1058 | struct net_device *upper_dev = netdev_master_upper_dev_get(dev); | 1199 | struct net_device *upper_dev = netdev_master_upper_dev_get(dev); |
| 1059 | 1200 | ||
| @@ -1096,18 +1237,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1096 | nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) | 1237 | nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) |
| 1097 | goto nla_put_failure; | 1238 | goto nla_put_failure; |
| 1098 | 1239 | ||
| 1099 | if (1) { | 1240 | if (rtnl_fill_link_ifmap(skb, dev)) |
| 1100 | struct rtnl_link_ifmap map = { | 1241 | goto nla_put_failure; |
| 1101 | .mem_start = dev->mem_start, | ||
| 1102 | .mem_end = dev->mem_end, | ||
| 1103 | .base_addr = dev->base_addr, | ||
| 1104 | .irq = dev->irq, | ||
| 1105 | .dma = dev->dma, | ||
| 1106 | .port = dev->if_port, | ||
| 1107 | }; | ||
| 1108 | if (nla_put(skb, IFLA_MAP, sizeof(map), &map)) | ||
| 1109 | goto nla_put_failure; | ||
| 1110 | } | ||
| 1111 | 1242 | ||
| 1112 | if (dev->addr_len) { | 1243 | if (dev->addr_len) { |
| 1113 | if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) || | 1244 | if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) || |
| @@ -1124,128 +1255,27 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
| 1124 | if (rtnl_phys_switch_id_fill(skb, dev)) | 1255 | if (rtnl_phys_switch_id_fill(skb, dev)) |
| 1125 | goto nla_put_failure; | 1256 | goto nla_put_failure; |
| 1126 | 1257 | ||
| 1127 | attr = nla_reserve(skb, IFLA_STATS, | 1258 | if (rtnl_fill_stats(skb, dev)) |
| 1128 | sizeof(struct rtnl_link_stats)); | ||
| 1129 | if (attr == NULL) | ||
| 1130 | goto nla_put_failure; | ||
| 1131 | |||
| 1132 | stats = dev_get_stats(dev, &temp); | ||
| 1133 | copy_rtnl_link_stats(nla_data(attr), stats); | ||
| 1134 | |||
| 1135 | attr = nla_reserve(skb, IFLA_STATS64, | ||
| 1136 | sizeof(struct rtnl_link_stats64)); | ||
| 1137 | if (attr == NULL) | ||
| 1138 | goto nla_put_failure; | 1259 | goto nla_put_failure; |
| 1139 | copy_rtnl_link_stats64(nla_data(attr), stats); | ||
| 1140 | 1260 | ||
| 1141 | if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) && | 1261 | if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF) && |
| 1142 | nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent))) | 1262 | nla_put_u32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent))) |
| 1143 | goto nla_put_failure; | 1263 | goto nla_put_failure; |
| 1144 | 1264 | ||
| 1145 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent | 1265 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent && |
| 1146 | && (ext_filter_mask & RTEXT_FILTER_VF)) { | 1266 | ext_filter_mask & RTEXT_FILTER_VF) { |
| 1147 | int i; | 1267 | int i; |
| 1148 | 1268 | struct nlattr *vfinfo; | |
| 1149 | struct nlattr *vfinfo, *vf, *vfstats; | ||
| 1150 | int num_vfs = dev_num_vf(dev->dev.parent); | 1269 | int num_vfs = dev_num_vf(dev->dev.parent); |
| 1151 | 1270 | ||
| 1152 | vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); | 1271 | vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); |
| 1153 | if (!vfinfo) | 1272 | if (!vfinfo) |
| 1154 | goto nla_put_failure; | 1273 | goto nla_put_failure; |
| 1155 | for (i = 0; i < num_vfs; i++) { | 1274 | for (i = 0; i < num_vfs; i++) { |
| 1156 | struct ifla_vf_info ivi; | 1275 | if (rtnl_fill_vfinfo(skb, dev, i, vfinfo)) |
| 1157 | struct ifla_vf_mac vf_mac; | ||
| 1158 | struct ifla_vf_vlan vf_vlan; | ||
| 1159 | struct ifla_vf_rate vf_rate; | ||
| 1160 | struct ifla_vf_tx_rate vf_tx_rate; | ||
| 1161 | struct ifla_vf_spoofchk vf_spoofchk; | ||
| 1162 | struct ifla_vf_link_state vf_linkstate; | ||
| 1163 | struct ifla_vf_rss_query_en vf_rss_query_en; | ||
| 1164 | struct ifla_vf_stats vf_stats; | ||
| 1165 | struct ifla_vf_trust vf_trust; | ||
| 1166 | |||
| 1167 | /* | ||
| 1168 | * Not all SR-IOV capable drivers support the | ||
| 1169 | * spoofcheck and "RSS query enable" query. Preset to | ||
| 1170 | * -1 so the user space tool can detect that the driver | ||
| 1171 | * didn't report anything. | ||
| 1172 | */ | ||
| 1173 | ivi.spoofchk = -1; | ||
| 1174 | ivi.rss_query_en = -1; | ||
| 1175 | ivi.trusted = -1; | ||
| 1176 | memset(ivi.mac, 0, sizeof(ivi.mac)); | ||
| 1177 | /* The default value for VF link state is "auto" | ||
| 1178 | * IFLA_VF_LINK_STATE_AUTO which equals zero | ||
| 1179 | */ | ||
| 1180 | ivi.linkstate = 0; | ||
| 1181 | if (dev->netdev_ops->ndo_get_vf_config(dev, i, &ivi)) | ||
| 1182 | break; | ||
| 1183 | vf_mac.vf = | ||
| 1184 | vf_vlan.vf = | ||
| 1185 | vf_rate.vf = | ||
| 1186 | vf_tx_rate.vf = | ||
| 1187 | vf_spoofchk.vf = | ||
| 1188 | vf_linkstate.vf = | ||
| 1189 | vf_rss_query_en.vf = | ||
| 1190 | vf_trust.vf = ivi.vf; | ||
| 1191 | |||
| 1192 | memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac)); | ||
| 1193 | vf_vlan.vlan = ivi.vlan; | ||
| 1194 | vf_vlan.qos = ivi.qos; | ||
| 1195 | vf_tx_rate.rate = ivi.max_tx_rate; | ||
| 1196 | vf_rate.min_tx_rate = ivi.min_tx_rate; | ||
| 1197 | vf_rate.max_tx_rate = ivi.max_tx_rate; | ||
| 1198 | vf_spoofchk.setting = ivi.spoofchk; | ||
| 1199 | vf_linkstate.link_state = ivi.linkstate; | ||
| 1200 | vf_rss_query_en.setting = ivi.rss_query_en; | ||
| 1201 | vf_trust.setting = ivi.trusted; | ||
| 1202 | vf = nla_nest_start(skb, IFLA_VF_INFO); | ||
| 1203 | if (!vf) { | ||
| 1204 | nla_nest_cancel(skb, vfinfo); | ||
| 1205 | goto nla_put_failure; | ||
| 1206 | } | ||
| 1207 | if (nla_put(skb, IFLA_VF_MAC, sizeof(vf_mac), &vf_mac) || | ||
| 1208 | nla_put(skb, IFLA_VF_VLAN, sizeof(vf_vlan), &vf_vlan) || | ||
| 1209 | nla_put(skb, IFLA_VF_RATE, sizeof(vf_rate), | ||
| 1210 | &vf_rate) || | ||
| 1211 | nla_put(skb, IFLA_VF_TX_RATE, sizeof(vf_tx_rate), | ||
| 1212 | &vf_tx_rate) || | ||
| 1213 | nla_put(skb, IFLA_VF_SPOOFCHK, sizeof(vf_spoofchk), | ||
| 1214 | &vf_spoofchk) || | ||
| 1215 | nla_put(skb, IFLA_VF_LINK_STATE, sizeof(vf_linkstate), | ||
| 1216 | &vf_linkstate) || | ||
| 1217 | nla_put(skb, IFLA_VF_RSS_QUERY_EN, | ||
| 1218 | sizeof(vf_rss_query_en), | ||
| 1219 | &vf_rss_query_en) || | ||
| 1220 | nla_put(skb, IFLA_VF_TRUST, | ||
| 1221 | sizeof(vf_trust), &vf_trust)) | ||
| 1222 | goto nla_put_failure; | 1276 | goto nla_put_failure; |
| 1223 | memset(&vf_stats, 0, sizeof(vf_stats)); | ||
| 1224 | if (dev->netdev_ops->ndo_get_vf_stats) | ||
| 1225 | dev->netdev_ops->ndo_get_vf_stats(dev, i, | ||
| 1226 | &vf_stats); | ||
| 1227 | vfstats = nla_nest_start(skb, IFLA_VF_STATS); | ||
| 1228 | if (!vfstats) { | ||
| 1229 | nla_nest_cancel(skb, vf); | ||
| 1230 | nla_nest_cancel(skb, vfinfo); | ||
| 1231 | goto nla_put_failure; | ||
| 1232 | } | ||
| 1233 | if (nla_put_u64(skb, IFLA_VF_STATS_RX_PACKETS, | ||
| 1234 | vf_stats.rx_packets) || | ||
| 1235 | nla_put_u64(skb, IFLA_VF_STATS_TX_PACKETS, | ||
| 1236 | vf_stats.tx_packets) || | ||
| 1237 | nla_put_u64(skb, IFLA_VF_STATS_RX_BYTES, | ||
| 1238 | vf_stats.rx_bytes) || | ||
| 1239 | nla_put_u64(skb, IFLA_VF_STATS_TX_BYTES, | ||
| 1240 | vf_stats.tx_bytes) || | ||
| 1241 | nla_put_u64(skb, IFLA_VF_STATS_BROADCAST, | ||
| 1242 | vf_stats.broadcast) || | ||
| 1243 | nla_put_u64(skb, IFLA_VF_STATS_MULTICAST, | ||
| 1244 | vf_stats.multicast)) | ||
| 1245 | goto nla_put_failure; | ||
| 1246 | nla_nest_end(skb, vfstats); | ||
| 1247 | nla_nest_end(skb, vf); | ||
| 1248 | } | 1277 | } |
| 1278 | |||
| 1249 | nla_nest_end(skb, vfinfo); | 1279 | nla_nest_end(skb, vfinfo); |
| 1250 | } | 1280 | } |
| 1251 | 1281 | ||
