summaryrefslogtreecommitdiffstats
path: root/drivers/net/geneve.c
diff options
context:
space:
mode:
authorGirish Moodalbail <girish.moodalbail@oracle.com>2017-08-09 04:09:28 -0400
committerDavid S. Miller <davem@davemloft.net>2017-08-11 16:45:02 -0400
commitc5ebc4409f2bb2c0b053c204ba197c6b71527eed (patch)
tree1dc3df096515f9e0c369af693e19fcab3a04002e /drivers/net/geneve.c
parentb50db91987fb1d4288ac8fdb7ba7487b352be6b5 (diff)
geneve: use netlink_ext_ack for error reporting in rtnl operations
Add extack error messages for failure paths while creating/modifying geneve devices. Once extack support is added to iproute2, more meaningful and helpful error messages will be displayed making it easy for users to discern what went wrong. Before: ======= $ ip link add gen1 address 0:1:2:3:4:5:6 type geneve id 200 \ remote 192.168.13.2 RTNETLINK answers: Invalid argument After: ====== $ ip link add gen1 address 0:1:2:3:4:5:6 type geneve id 200 \ remote 192.168.13.2 Error: Provided link layer address is not Ethernet Also, netdev_dbg() calls used to log errors associated with Netlink request have been removed. Signed-off-by: Girish Moodalbail <girish.moodalbail@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/geneve.c')
-rw-r--r--drivers/net/geneve.c128
1 files changed, 92 insertions, 36 deletions
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
index 8b8565dd2afb..f6404074b7b0 100644
--- a/drivers/net/geneve.c
+++ b/drivers/net/geneve.c
@@ -1086,21 +1086,33 @@ static int geneve_validate(struct nlattr *tb[], struct nlattr *data[],
1086 struct netlink_ext_ack *extack) 1086 struct netlink_ext_ack *extack)
1087{ 1087{
1088 if (tb[IFLA_ADDRESS]) { 1088 if (tb[IFLA_ADDRESS]) {
1089 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) 1089 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN) {
1090 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_ADDRESS],
1091 "Provided link layer address is not Ethernet");
1090 return -EINVAL; 1092 return -EINVAL;
1093 }
1091 1094
1092 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) 1095 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) {
1096 NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_ADDRESS],
1097 "Provided Ethernet address is not unicast");
1093 return -EADDRNOTAVAIL; 1098 return -EADDRNOTAVAIL;
1099 }
1094 } 1100 }
1095 1101
1096 if (!data) 1102 if (!data) {
1103 NL_SET_ERR_MSG(extack,
1104 "Not enough attributes provided to perform the operation");
1097 return -EINVAL; 1105 return -EINVAL;
1106 }
1098 1107
1099 if (data[IFLA_GENEVE_ID]) { 1108 if (data[IFLA_GENEVE_ID]) {
1100 __u32 vni = nla_get_u32(data[IFLA_GENEVE_ID]); 1109 __u32 vni = nla_get_u32(data[IFLA_GENEVE_ID]);
1101 1110
1102 if (vni >= GENEVE_N_VID) 1111 if (vni >= GENEVE_N_VID) {
1112 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_ID],
1113 "Geneve ID must be lower than 16777216");
1103 return -ERANGE; 1114 return -ERANGE;
1115 }
1104 } 1116 }
1105 1117
1106 return 0; 1118 return 0;
@@ -1158,6 +1170,7 @@ static bool geneve_dst_addr_equal(struct ip_tunnel_info *a,
1158} 1170}
1159 1171
1160static int geneve_configure(struct net *net, struct net_device *dev, 1172static int geneve_configure(struct net *net, struct net_device *dev,
1173 struct netlink_ext_ack *extack,
1161 const struct ip_tunnel_info *info, 1174 const struct ip_tunnel_info *info,
1162 bool metadata, bool ipv6_rx_csum) 1175 bool metadata, bool ipv6_rx_csum)
1163{ 1176{
@@ -1166,8 +1179,11 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1166 bool tun_collect_md, tun_on_same_port; 1179 bool tun_collect_md, tun_on_same_port;
1167 int err, encap_len; 1180 int err, encap_len;
1168 1181
1169 if (metadata && !is_tnl_info_zero(info)) 1182 if (metadata && !is_tnl_info_zero(info)) {
1183 NL_SET_ERR_MSG(extack,
1184 "Device is externally controlled, so attributes (VNI, Port, and so on) must not be specified");
1170 return -EINVAL; 1185 return -EINVAL;
1186 }
1171 1187
1172 geneve->net = net; 1188 geneve->net = net;
1173 geneve->dev = dev; 1189 geneve->dev = dev;
@@ -1188,11 +1204,17 @@ static int geneve_configure(struct net *net, struct net_device *dev,
1188 dev->needed_headroom = encap_len + ETH_HLEN; 1204 dev->needed_headroom = encap_len + ETH_HLEN;
1189 1205
1190 if (metadata) { 1206 if (metadata) {
1191 if (tun_on_same_port) 1207 if (tun_on_same_port) {
1208 NL_SET_ERR_MSG(extack,
1209 "There can be only one externally controlled device on a destination port");
1192 return -EPERM; 1210 return -EPERM;
1211 }
1193 } else { 1212 } else {
1194 if (tun_collect_md) 1213 if (tun_collect_md) {
1214 NL_SET_ERR_MSG(extack,
1215 "There already exists an externally controlled device on this destination port");
1195 return -EPERM; 1216 return -EPERM;
1217 }
1196 } 1218 }
1197 1219
1198 dst_cache_reset(&geneve->info.dst_cache); 1220 dst_cache_reset(&geneve->info.dst_cache);
@@ -1214,31 +1236,41 @@ static void init_tnl_info(struct ip_tunnel_info *info, __u16 dst_port)
1214 info->key.tp_dst = htons(dst_port); 1236 info->key.tp_dst = htons(dst_port);
1215} 1237}
1216 1238
1217static int geneve_nl2info(struct net_device *dev, struct nlattr *tb[], 1239static int geneve_nl2info(struct nlattr *tb[], struct nlattr *data[],
1218 struct nlattr *data[], struct ip_tunnel_info *info, 1240 struct netlink_ext_ack *extack,
1219 bool *metadata, bool *use_udp6_rx_checksums, 1241 struct ip_tunnel_info *info, bool *metadata,
1220 bool changelink) 1242 bool *use_udp6_rx_checksums, bool changelink)
1221{ 1243{
1222 if (data[IFLA_GENEVE_REMOTE] && data[IFLA_GENEVE_REMOTE6]) 1244 int attrtype;
1245
1246 if (data[IFLA_GENEVE_REMOTE] && data[IFLA_GENEVE_REMOTE6]) {
1247 NL_SET_ERR_MSG(extack,
1248 "Cannot specify both IPv4 and IPv6 Remote addresses");
1223 return -EINVAL; 1249 return -EINVAL;
1250 }
1224 1251
1225 if (data[IFLA_GENEVE_REMOTE]) { 1252 if (data[IFLA_GENEVE_REMOTE]) {
1226 if (changelink && (ip_tunnel_info_af(info) == AF_INET6)) 1253 if (changelink && (ip_tunnel_info_af(info) == AF_INET6)) {
1227 return -EOPNOTSUPP; 1254 attrtype = IFLA_GENEVE_REMOTE;
1255 goto change_notsup;
1256 }
1228 1257
1229 info->key.u.ipv4.dst = 1258 info->key.u.ipv4.dst =
1230 nla_get_in_addr(data[IFLA_GENEVE_REMOTE]); 1259 nla_get_in_addr(data[IFLA_GENEVE_REMOTE]);
1231 1260
1232 if (IN_MULTICAST(ntohl(info->key.u.ipv4.dst))) { 1261 if (IN_MULTICAST(ntohl(info->key.u.ipv4.dst))) {
1233 netdev_dbg(dev, "multicast remote is unsupported\n"); 1262 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_REMOTE],
1263 "Remote IPv4 address cannot be Multicast");
1234 return -EINVAL; 1264 return -EINVAL;
1235 } 1265 }
1236 } 1266 }
1237 1267
1238 if (data[IFLA_GENEVE_REMOTE6]) { 1268 if (data[IFLA_GENEVE_REMOTE6]) {
1239 #if IS_ENABLED(CONFIG_IPV6) 1269 #if IS_ENABLED(CONFIG_IPV6)
1240 if (changelink && (ip_tunnel_info_af(info) == AF_INET)) 1270 if (changelink && (ip_tunnel_info_af(info) == AF_INET)) {
1241 return -EOPNOTSUPP; 1271 attrtype = IFLA_GENEVE_REMOTE6;
1272 goto change_notsup;
1273 }
1242 1274
1243 info->mode = IP_TUNNEL_INFO_IPV6; 1275 info->mode = IP_TUNNEL_INFO_IPV6;
1244 info->key.u.ipv6.dst = 1276 info->key.u.ipv6.dst =
@@ -1246,16 +1278,20 @@ static int geneve_nl2info(struct net_device *dev, struct nlattr *tb[],
1246 1278
1247 if (ipv6_addr_type(&info->key.u.ipv6.dst) & 1279 if (ipv6_addr_type(&info->key.u.ipv6.dst) &
1248 IPV6_ADDR_LINKLOCAL) { 1280 IPV6_ADDR_LINKLOCAL) {
1249 netdev_dbg(dev, "link-local remote is unsupported\n"); 1281 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_REMOTE6],
1282 "Remote IPv6 address cannot be link-local");
1250 return -EINVAL; 1283 return -EINVAL;
1251 } 1284 }
1252 if (ipv6_addr_is_multicast(&info->key.u.ipv6.dst)) { 1285 if (ipv6_addr_is_multicast(&info->key.u.ipv6.dst)) {
1253 netdev_dbg(dev, "multicast remote is unsupported\n"); 1286 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_REMOTE6],
1287 "Remote IPv6 address cannot be Multicast");
1254 return -EINVAL; 1288 return -EINVAL;
1255 } 1289 }
1256 info->key.tun_flags |= TUNNEL_CSUM; 1290 info->key.tun_flags |= TUNNEL_CSUM;
1257 *use_udp6_rx_checksums = true; 1291 *use_udp6_rx_checksums = true;
1258#else 1292#else
1293 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_REMOTE6],
1294 "IPv6 support not enabled in the kernel");
1259 return -EPFNOSUPPORT; 1295 return -EPFNOSUPPORT;
1260#endif 1296#endif
1261 } 1297 }
@@ -1271,8 +1307,10 @@ static int geneve_nl2info(struct net_device *dev, struct nlattr *tb[],
1271 tvni[2] = vni & 0x000000ff; 1307 tvni[2] = vni & 0x000000ff;
1272 1308
1273 tunid = vni_to_tunnel_id(tvni); 1309 tunid = vni_to_tunnel_id(tvni);
1274 if (changelink && (tunid != info->key.tun_id)) 1310 if (changelink && (tunid != info->key.tun_id)) {
1275 return -EOPNOTSUPP; 1311 attrtype = IFLA_GENEVE_ID;
1312 goto change_notsup;
1313 }
1276 info->key.tun_id = tunid; 1314 info->key.tun_id = tunid;
1277 } 1315 }
1278 1316
@@ -1285,44 +1323,61 @@ static int geneve_nl2info(struct net_device *dev, struct nlattr *tb[],
1285 if (data[IFLA_GENEVE_LABEL]) { 1323 if (data[IFLA_GENEVE_LABEL]) {
1286 info->key.label = nla_get_be32(data[IFLA_GENEVE_LABEL]) & 1324 info->key.label = nla_get_be32(data[IFLA_GENEVE_LABEL]) &
1287 IPV6_FLOWLABEL_MASK; 1325 IPV6_FLOWLABEL_MASK;
1288 if (info->key.label && (!(info->mode & IP_TUNNEL_INFO_IPV6))) 1326 if (info->key.label && (!(info->mode & IP_TUNNEL_INFO_IPV6))) {
1327 NL_SET_ERR_MSG_ATTR(extack, data[IFLA_GENEVE_LABEL],
1328 "Label attribute only applies for IPv6 Geneve devices");
1289 return -EINVAL; 1329 return -EINVAL;
1330 }
1290 } 1331 }
1291 1332
1292 if (data[IFLA_GENEVE_PORT]) { 1333 if (data[IFLA_GENEVE_PORT]) {
1293 if (changelink) 1334 if (changelink) {
1294 return -EOPNOTSUPP; 1335 attrtype = IFLA_GENEVE_PORT;
1336 goto change_notsup;
1337 }
1295 info->key.tp_dst = nla_get_be16(data[IFLA_GENEVE_PORT]); 1338 info->key.tp_dst = nla_get_be16(data[IFLA_GENEVE_PORT]);
1296 } 1339 }
1297 1340
1298 if (data[IFLA_GENEVE_COLLECT_METADATA]) { 1341 if (data[IFLA_GENEVE_COLLECT_METADATA]) {
1299 if (changelink) 1342 if (changelink) {
1300 return -EOPNOTSUPP; 1343 attrtype = IFLA_GENEVE_COLLECT_METADATA;
1344 goto change_notsup;
1345 }
1301 *metadata = true; 1346 *metadata = true;
1302 } 1347 }
1303 1348
1304 if (data[IFLA_GENEVE_UDP_CSUM]) { 1349 if (data[IFLA_GENEVE_UDP_CSUM]) {
1305 if (changelink) 1350 if (changelink) {
1306 return -EOPNOTSUPP; 1351 attrtype = IFLA_GENEVE_UDP_CSUM;
1352 goto change_notsup;
1353 }
1307 if (nla_get_u8(data[IFLA_GENEVE_UDP_CSUM])) 1354 if (nla_get_u8(data[IFLA_GENEVE_UDP_CSUM]))
1308 info->key.tun_flags |= TUNNEL_CSUM; 1355 info->key.tun_flags |= TUNNEL_CSUM;
1309 } 1356 }
1310 1357
1311 if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]) { 1358 if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]) {
1312 if (changelink) 1359 if (changelink) {
1313 return -EOPNOTSUPP; 1360 attrtype = IFLA_GENEVE_UDP_ZERO_CSUM6_TX;
1361 goto change_notsup;
1362 }
1314 if (nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX])) 1363 if (nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]))
1315 info->key.tun_flags &= ~TUNNEL_CSUM; 1364 info->key.tun_flags &= ~TUNNEL_CSUM;
1316 } 1365 }
1317 1366
1318 if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]) { 1367 if (data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]) {
1319 if (changelink) 1368 if (changelink) {
1320 return -EOPNOTSUPP; 1369 attrtype = IFLA_GENEVE_UDP_ZERO_CSUM6_RX;
1370 goto change_notsup;
1371 }
1321 if (nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX])) 1372 if (nla_get_u8(data[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]))
1322 *use_udp6_rx_checksums = false; 1373 *use_udp6_rx_checksums = false;
1323 } 1374 }
1324 1375
1325 return 0; 1376 return 0;
1377change_notsup:
1378 NL_SET_ERR_MSG_ATTR(extack, data[attrtype],
1379 "Changing VNI, Port, endpoint IP address family, external, and UDP checksum attributes are not supported");
1380 return -EOPNOTSUPP;
1326} 1381}
1327 1382
1328static int geneve_newlink(struct net *net, struct net_device *dev, 1383static int geneve_newlink(struct net *net, struct net_device *dev,
@@ -1335,12 +1390,13 @@ static int geneve_newlink(struct net *net, struct net_device *dev,
1335 int err; 1390 int err;
1336 1391
1337 init_tnl_info(&info, GENEVE_UDP_PORT); 1392 init_tnl_info(&info, GENEVE_UDP_PORT);
1338 err = geneve_nl2info(dev, tb, data, &info, &metadata, 1393 err = geneve_nl2info(tb, data, extack, &info, &metadata,
1339 &use_udp6_rx_checksums, false); 1394 &use_udp6_rx_checksums, false);
1340 if (err) 1395 if (err)
1341 return err; 1396 return err;
1342 1397
1343 return geneve_configure(net, dev, &info, metadata, use_udp6_rx_checksums); 1398 return geneve_configure(net, dev, extack, &info, metadata,
1399 use_udp6_rx_checksums);
1344} 1400}
1345 1401
1346/* Quiesces the geneve device data path for both TX and RX. 1402/* Quiesces the geneve device data path for both TX and RX.
@@ -1409,7 +1465,7 @@ static int geneve_changelink(struct net_device *dev, struct nlattr *tb[],
1409 memcpy(&info, &geneve->info, sizeof(info)); 1465 memcpy(&info, &geneve->info, sizeof(info));
1410 metadata = geneve->collect_md; 1466 metadata = geneve->collect_md;
1411 use_udp6_rx_checksums = geneve->use_udp6_rx_checksums; 1467 use_udp6_rx_checksums = geneve->use_udp6_rx_checksums;
1412 err = geneve_nl2info(dev, tb, data, &info, &metadata, 1468 err = geneve_nl2info(tb, data, extack, &info, &metadata,
1413 &use_udp6_rx_checksums, true); 1469 &use_udp6_rx_checksums, true);
1414 if (err) 1470 if (err)
1415 return err; 1471 return err;
@@ -1536,7 +1592,7 @@ struct net_device *geneve_dev_create_fb(struct net *net, const char *name,
1536 return dev; 1592 return dev;
1537 1593
1538 init_tnl_info(&info, dst_port); 1594 init_tnl_info(&info, dst_port);
1539 err = geneve_configure(net, dev, &info, true, true); 1595 err = geneve_configure(net, dev, NULL, &info, true, true);
1540 if (err) { 1596 if (err) {
1541 free_netdev(dev); 1597 free_netdev(dev);
1542 return ERR_PTR(err); 1598 return ERR_PTR(err);