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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'some-pktgen-fixes-improvments-part-ii'

Peter Seiderer says:

====================
Some pktgen fixes/improvments (part II)

While taking a look at '[PATCH net] pktgen: Avoid out-of-range in
get_imix_entries' ([1]) and '[PATCH net v2] pktgen: Avoid out-of-bounds
access in get_imix_entries' ([2], [3]) and doing some tests and code review
I detected that the /proc/net/pktgen/... parsing logic does not honour the
user given buffer bounds (resulting in out-of-bounds access).

This can be observed e.g. by the following simple test (sometimes the
old/'longer' previous value is re-read from the buffer):

$ echo add_device lo@0 > /proc/net/pktgen/kpktgend_0

$ echo "min_pkt_size 12345" > /proc/net/pktgen/lo\@0 && grep min_pkt_size /proc/net/pktgen/lo\@0
Params: count 1000 min_pkt_size: 12345 max_pkt_size: 0
Result: OK: min_pkt_size=12345

$ echo -n "min_pkt_size 123" > /proc/net/pktgen/lo\@0 && grep min_pkt_size /proc/net/pktgen/lo\@0
Params: count 1000 min_pkt_size: 12345 max_pkt_size: 0
Result: OK: min_pkt_size=12345

$ echo "min_pkt_size 123" > /proc/net/pktgen/lo\@0 && grep min_pkt_size /proc/net/pktgen/lo\@0
Params: count 1000 min_pkt_size: 123 max_pkt_size: 0
Result: OK: min_pkt_size=123

So fix the out-of-bounds access (and some minor findings) and add a simple
proc_net_pktgen selftest...

Patch set splited into part I (now already applied to net-next)

- net: pktgen: replace ENOTSUPP with EOPNOTSUPP
- net: pktgen: enable 'param=value' parsing
- net: pktgen: fix hex32_arg parsing for short reads
- net: pktgen: fix 'rate 0' error handling (return -EINVAL)
- net: pktgen: fix 'ratep 0' error handling (return -EINVAL)
- net: pktgen: fix ctrl interface command parsing
- net: pktgen: fix access outside of user given buffer in pktgen_thread_write()

nd part II (this one):

- net: pktgen: use defines for the various dec/hex number parsing digits lengths
- net: pktgen: fix mix of int/long
- net: pktgen: remove extra tmp variable (re-use len instead)
- net: pktgen: remove some superfluous variable initializing
- net: pktgen: fix mpls maximum labels list parsing
- net: pktgen: fix access outside of user given buffer in pktgen_if_write()
- net: pktgen: fix mpls reset parsing
- net: pktgen: remove all superfluous index assignements
- selftest: net: add proc_net_pktgen

[1] https://lore.kernel.org/netdev/20241006221221.3744995-1-artem.chernyshev@red-soft.ru/
[2] https://lore.kernel.org/netdev/20250109083039.14004-1-pchelkin@ispras.ru/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76201b5979768500bca362871db66d77cb4c225e
====================

Link: https://patch.msgid.link/20250227135604.40024-1-ps.report@gmx.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+805 -131
+157 -131
net/core/pktgen.c
··· 744 744 } 745 745 746 746 747 - static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, 748 - __u32 *num) 747 + static ssize_t hex32_arg(const char __user *user_buffer, size_t maxlen, 748 + __u32 *num) 749 749 { 750 - int i = 0; 750 + size_t i = 0; 751 + 751 752 *num = 0; 752 753 753 754 for (; i < maxlen; i++) { ··· 767 766 return i; 768 767 } 769 768 770 - static int count_trail_chars(const char __user * user_buffer, 771 - unsigned int maxlen) 769 + static ssize_t count_trail_chars(const char __user *user_buffer, size_t maxlen) 772 770 { 773 - int i; 771 + size_t i; 774 772 775 773 for (i = 0; i < maxlen; i++) { 776 774 char c; ··· 791 791 return i; 792 792 } 793 793 794 - static long num_arg(const char __user *user_buffer, unsigned long maxlen, 795 - unsigned long *num) 794 + static ssize_t num_arg(const char __user *user_buffer, size_t maxlen, 795 + unsigned long *num) 796 796 { 797 - int i; 797 + size_t i; 798 798 *num = 0; 799 799 800 800 for (i = 0; i < maxlen; i++) { ··· 810 810 return i; 811 811 } 812 812 813 - static int strn_len(const char __user * user_buffer, unsigned int maxlen) 813 + static ssize_t strn_len(const char __user *user_buffer, size_t maxlen) 814 814 { 815 - int i; 815 + size_t i; 816 816 817 817 for (i = 0; i < maxlen; i++) { 818 818 char c; ··· 840 840 * "size1,weight_1 size2,weight_2 ... size_n,weight_n" for example. 841 841 */ 842 842 static ssize_t get_imix_entries(const char __user *buffer, 843 + size_t maxlen, 843 844 struct pktgen_dev *pkt_dev) 844 845 { 845 - const int max_digits = 10; 846 - int i = 0; 847 - long len; 846 + size_t i = 0, max; 847 + ssize_t len; 848 848 char c; 849 849 850 850 pkt_dev->n_imix_entries = 0; ··· 856 856 if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES) 857 857 return -E2BIG; 858 858 859 - len = num_arg(&buffer[i], max_digits, &size); 859 + max = min(10, maxlen - i); 860 + len = num_arg(&buffer[i], max, &size); 860 861 if (len < 0) 861 862 return len; 862 863 i += len; 864 + if (i >= maxlen) 865 + return -EINVAL; 863 866 if (get_user(c, &buffer[i])) 864 867 return -EFAULT; 865 868 /* Check for comma between size_i and weight_i */ ··· 873 870 if (size < 14 + 20 + 8) 874 871 size = 14 + 20 + 8; 875 872 876 - len = num_arg(&buffer[i], max_digits, &weight); 873 + max = min(10, maxlen - i); 874 + len = num_arg(&buffer[i], max, &weight); 877 875 if (len < 0) 878 876 return len; 879 877 if (weight <= 0) ··· 884 880 pkt_dev->imix_entries[pkt_dev->n_imix_entries].weight = weight; 885 881 886 882 i += len; 883 + pkt_dev->n_imix_entries++; 884 + 885 + if (i >= maxlen) 886 + break; 887 887 if (get_user(c, &buffer[i])) 888 888 return -EFAULT; 889 - 890 889 i++; 891 - pkt_dev->n_imix_entries++; 892 890 } while (c == ' '); 893 891 894 892 return i; 895 893 } 896 894 897 - static ssize_t get_labels(const char __user *buffer, struct pktgen_dev *pkt_dev) 895 + static ssize_t get_labels(const char __user *buffer, 896 + size_t maxlen, struct pktgen_dev *pkt_dev) 898 897 { 899 898 unsigned int n = 0; 899 + size_t i = 0, max; 900 + ssize_t len; 900 901 char c; 901 - ssize_t i = 0; 902 - int len; 903 902 904 903 pkt_dev->nr_labels = 0; 905 904 do { 906 905 __u32 tmp; 907 - len = hex32_arg(&buffer[i], 8, &tmp); 908 - if (len <= 0) 906 + 907 + if (n >= MAX_MPLS_LABELS) 908 + return -E2BIG; 909 + 910 + max = min(8, maxlen - i); 911 + len = hex32_arg(&buffer[i], max, &tmp); 912 + if (len < 0) 909 913 return len; 914 + 915 + /* return empty list in case of invalid input or zero value */ 916 + if (len == 0 || tmp == 0) 917 + return maxlen; 918 + 910 919 pkt_dev->labels[n] = htonl(tmp); 911 920 if (pkt_dev->labels[n] & MPLS_STACK_BOTTOM) 912 921 pkt_dev->flags |= F_MPLS_RND; 913 922 i += len; 923 + n++; 924 + if (i >= maxlen) 925 + break; 914 926 if (get_user(c, &buffer[i])) 915 927 return -EFAULT; 916 928 i++; 917 - n++; 918 - if (n >= MAX_MPLS_LABELS) 919 - return -E2BIG; 920 929 } while (c == ','); 921 930 922 931 pkt_dev->nr_labels = n; ··· 971 954 { 972 955 struct seq_file *seq = file->private_data; 973 956 struct pktgen_dev *pkt_dev = seq->private; 974 - int i, max, len; 957 + size_t i, max; 958 + ssize_t len; 975 959 char name[16], valstr[32]; 976 960 unsigned long value = 0; 977 961 char *pg_result = NULL; 978 - int tmp = 0; 979 962 char buf[128]; 980 963 981 964 pg_result = &(pkt_dev->result[0]); ··· 986 969 } 987 970 988 971 max = count; 989 - tmp = count_trail_chars(user_buffer, max); 990 - if (tmp < 0) { 972 + len = count_trail_chars(user_buffer, max); 973 + if (len < 0) { 991 974 pr_warn("illegal format\n"); 992 - return tmp; 975 + return len; 993 976 } 994 - i = tmp; 977 + i = len; 995 978 996 979 /* Read variable name */ 997 - 998 - len = strn_len(&user_buffer[i], sizeof(name) - 1); 980 + max = min(sizeof(name) - 1, count - i); 981 + len = strn_len(&user_buffer[i], max); 999 982 if (len < 0) 1000 983 return len; 1001 984 ··· 1023 1006 } 1024 1007 1025 1008 if (!strcmp(name, "min_pkt_size")) { 1026 - len = num_arg(&user_buffer[i], 10, &value); 1009 + max = min(10, count - i); 1010 + len = num_arg(&user_buffer[i], max, &value); 1027 1011 if (len < 0) 1028 1012 return len; 1029 1013 1030 - i += len; 1031 1014 if (value < 14 + 20 + 8) 1032 1015 value = 14 + 20 + 8; 1033 1016 if (value != pkt_dev->min_pkt_size) { ··· 1040 1023 } 1041 1024 1042 1025 if (!strcmp(name, "max_pkt_size")) { 1043 - len = num_arg(&user_buffer[i], 10, &value); 1026 + max = min(10, count - i); 1027 + len = num_arg(&user_buffer[i], max, &value); 1044 1028 if (len < 0) 1045 1029 return len; 1046 1030 1047 - i += len; 1048 1031 if (value < 14 + 20 + 8) 1049 1032 value = 14 + 20 + 8; 1050 1033 if (value != pkt_dev->max_pkt_size) { ··· 1059 1042 /* Shortcut for min = max */ 1060 1043 1061 1044 if (!strcmp(name, "pkt_size")) { 1062 - len = num_arg(&user_buffer[i], 10, &value); 1045 + max = min(10, count - i); 1046 + len = num_arg(&user_buffer[i], max, &value); 1063 1047 if (len < 0) 1064 1048 return len; 1065 1049 1066 - i += len; 1067 1050 if (value < 14 + 20 + 8) 1068 1051 value = 14 + 20 + 8; 1069 1052 if (value != pkt_dev->min_pkt_size) { ··· 1079 1062 if (pkt_dev->clone_skb > 0) 1080 1063 return -EINVAL; 1081 1064 1082 - len = get_imix_entries(&user_buffer[i], pkt_dev); 1065 + max = count - i; 1066 + len = get_imix_entries(&user_buffer[i], max, pkt_dev); 1083 1067 if (len < 0) 1084 1068 return len; 1085 1069 1086 1070 fill_imix_distribution(pkt_dev); 1087 1071 1088 - i += len; 1089 1072 return count; 1090 1073 } 1091 1074 1092 1075 if (!strcmp(name, "debug")) { 1093 - len = num_arg(&user_buffer[i], 10, &value); 1076 + max = min(10, count - i); 1077 + len = num_arg(&user_buffer[i], max, &value); 1094 1078 if (len < 0) 1095 1079 return len; 1096 1080 1097 - i += len; 1098 1081 debug = value; 1099 1082 sprintf(pg_result, "OK: debug=%u", debug); 1100 1083 return count; 1101 1084 } 1102 1085 1103 1086 if (!strcmp(name, "frags")) { 1104 - len = num_arg(&user_buffer[i], 10, &value); 1087 + max = min(10, count - i); 1088 + len = num_arg(&user_buffer[i], max, &value); 1105 1089 if (len < 0) 1106 1090 return len; 1107 1091 1108 - i += len; 1109 1092 pkt_dev->nfrags = value; 1110 1093 sprintf(pg_result, "OK: frags=%d", pkt_dev->nfrags); 1111 1094 return count; 1112 1095 } 1113 1096 if (!strcmp(name, "delay")) { 1114 - len = num_arg(&user_buffer[i], 10, &value); 1097 + max = min(10, count - i); 1098 + len = num_arg(&user_buffer[i], max, &value); 1115 1099 if (len < 0) 1116 1100 return len; 1117 1101 1118 - i += len; 1119 1102 if (value == 0x7FFFFFFF) 1120 1103 pkt_dev->delay = ULLONG_MAX; 1121 1104 else ··· 1126 1109 return count; 1127 1110 } 1128 1111 if (!strcmp(name, "rate")) { 1129 - len = num_arg(&user_buffer[i], 10, &value); 1112 + max = min(10, count - i); 1113 + len = num_arg(&user_buffer[i], max, &value); 1130 1114 if (len < 0) 1131 1115 return len; 1132 1116 1133 - i += len; 1134 1117 if (!value) 1135 1118 return -EINVAL; 1136 1119 pkt_dev->delay = pkt_dev->min_pkt_size*8*NSEC_PER_USEC/value; ··· 1141 1124 return count; 1142 1125 } 1143 1126 if (!strcmp(name, "ratep")) { 1144 - len = num_arg(&user_buffer[i], 10, &value); 1127 + max = min(10, count - i); 1128 + len = num_arg(&user_buffer[i], max, &value); 1145 1129 if (len < 0) 1146 1130 return len; 1147 1131 1148 - i += len; 1149 1132 if (!value) 1150 1133 return -EINVAL; 1151 1134 pkt_dev->delay = NSEC_PER_SEC/value; ··· 1156 1139 return count; 1157 1140 } 1158 1141 if (!strcmp(name, "udp_src_min")) { 1159 - len = num_arg(&user_buffer[i], 10, &value); 1142 + max = min(10, count - i); 1143 + len = num_arg(&user_buffer[i], max, &value); 1160 1144 if (len < 0) 1161 1145 return len; 1162 1146 1163 - i += len; 1164 1147 if (value != pkt_dev->udp_src_min) { 1165 1148 pkt_dev->udp_src_min = value; 1166 1149 pkt_dev->cur_udp_src = value; ··· 1169 1152 return count; 1170 1153 } 1171 1154 if (!strcmp(name, "udp_dst_min")) { 1172 - len = num_arg(&user_buffer[i], 10, &value); 1155 + max = min(10, count - i); 1156 + len = num_arg(&user_buffer[i], max, &value); 1173 1157 if (len < 0) 1174 1158 return len; 1175 1159 1176 - i += len; 1177 1160 if (value != pkt_dev->udp_dst_min) { 1178 1161 pkt_dev->udp_dst_min = value; 1179 1162 pkt_dev->cur_udp_dst = value; ··· 1182 1165 return count; 1183 1166 } 1184 1167 if (!strcmp(name, "udp_src_max")) { 1185 - len = num_arg(&user_buffer[i], 10, &value); 1168 + max = min(10, count - i); 1169 + len = num_arg(&user_buffer[i], max, &value); 1186 1170 if (len < 0) 1187 1171 return len; 1188 1172 1189 - i += len; 1190 1173 if (value != pkt_dev->udp_src_max) { 1191 1174 pkt_dev->udp_src_max = value; 1192 1175 pkt_dev->cur_udp_src = value; ··· 1195 1178 return count; 1196 1179 } 1197 1180 if (!strcmp(name, "udp_dst_max")) { 1198 - len = num_arg(&user_buffer[i], 10, &value); 1181 + max = min(10, count - i); 1182 + len = num_arg(&user_buffer[i], max, &value); 1199 1183 if (len < 0) 1200 1184 return len; 1201 1185 1202 - i += len; 1203 1186 if (value != pkt_dev->udp_dst_max) { 1204 1187 pkt_dev->udp_dst_max = value; 1205 1188 pkt_dev->cur_udp_dst = value; ··· 1208 1191 return count; 1209 1192 } 1210 1193 if (!strcmp(name, "clone_skb")) { 1211 - len = num_arg(&user_buffer[i], 10, &value); 1194 + max = min(10, count - i); 1195 + len = num_arg(&user_buffer[i], max, &value); 1212 1196 if (len < 0) 1213 1197 return len; 1214 1198 /* clone_skb is not supported for netif_receive xmit_mode and ··· 1223 1205 !(pkt_dev->flags & F_SHARED))) 1224 1206 return -EINVAL; 1225 1207 1226 - i += len; 1227 1208 pkt_dev->clone_skb = value; 1228 1209 1229 1210 sprintf(pg_result, "OK: clone_skb=%d", pkt_dev->clone_skb); 1230 1211 return count; 1231 1212 } 1232 1213 if (!strcmp(name, "count")) { 1233 - len = num_arg(&user_buffer[i], 10, &value); 1214 + max = min(10, count - i); 1215 + len = num_arg(&user_buffer[i], max, &value); 1234 1216 if (len < 0) 1235 1217 return len; 1236 1218 1237 - i += len; 1238 1219 pkt_dev->count = value; 1239 1220 sprintf(pg_result, "OK: count=%llu", 1240 1221 (unsigned long long)pkt_dev->count); 1241 1222 return count; 1242 1223 } 1243 1224 if (!strcmp(name, "src_mac_count")) { 1244 - len = num_arg(&user_buffer[i], 10, &value); 1225 + max = min(10, count - i); 1226 + len = num_arg(&user_buffer[i], max, &value); 1245 1227 if (len < 0) 1246 1228 return len; 1247 1229 1248 - i += len; 1249 1230 if (pkt_dev->src_mac_count != value) { 1250 1231 pkt_dev->src_mac_count = value; 1251 1232 pkt_dev->cur_src_mac_offset = 0; ··· 1254 1237 return count; 1255 1238 } 1256 1239 if (!strcmp(name, "dst_mac_count")) { 1257 - len = num_arg(&user_buffer[i], 10, &value); 1240 + max = min(10, count - i); 1241 + len = num_arg(&user_buffer[i], max, &value); 1258 1242 if (len < 0) 1259 1243 return len; 1260 1244 1261 - i += len; 1262 1245 if (pkt_dev->dst_mac_count != value) { 1263 1246 pkt_dev->dst_mac_count = value; 1264 1247 pkt_dev->cur_dst_mac_offset = 0; ··· 1268 1251 return count; 1269 1252 } 1270 1253 if (!strcmp(name, "burst")) { 1271 - len = num_arg(&user_buffer[i], 10, &value); 1254 + max = min(10, count - i); 1255 + len = num_arg(&user_buffer[i], max, &value); 1272 1256 if (len < 0) 1273 1257 return len; 1274 1258 1275 - i += len; 1276 1259 if ((value > 1) && 1277 1260 ((pkt_dev->xmit_mode == M_QUEUE_XMIT) || 1278 1261 ((pkt_dev->xmit_mode == M_START_XMIT) && ··· 1287 1270 return count; 1288 1271 } 1289 1272 if (!strcmp(name, "node")) { 1290 - len = num_arg(&user_buffer[i], 10, &value); 1273 + max = min(10, count - i); 1274 + len = num_arg(&user_buffer[i], max, &value); 1291 1275 if (len < 0) 1292 1276 return len; 1293 - 1294 - i += len; 1295 1277 1296 1278 if (node_possible(value)) { 1297 1279 pkt_dev->node = value; ··· 1307 1291 if (!strcmp(name, "xmit_mode")) { 1308 1292 char f[32]; 1309 1293 1310 - memset(f, 0, 32); 1311 - len = strn_len(&user_buffer[i], sizeof(f) - 1); 1294 + max = min(sizeof(f) - 1, count - i); 1295 + len = strn_len(&user_buffer[i], max); 1312 1296 if (len < 0) 1313 1297 return len; 1314 1298 1299 + memset(f, 0, sizeof(f)); 1315 1300 if (copy_from_user(f, &user_buffer[i], len)) 1316 1301 return -EFAULT; 1317 - i += len; 1318 1302 1319 1303 if (strcmp(f, "start_xmit") == 0) { 1320 1304 pkt_dev->xmit_mode = M_START_XMIT; ··· 1347 1331 char f[32]; 1348 1332 char *end; 1349 1333 1350 - memset(f, 0, 32); 1351 - len = strn_len(&user_buffer[i], sizeof(f) - 1); 1334 + max = min(sizeof(f) - 1, count - i); 1335 + len = strn_len(&user_buffer[i], max); 1352 1336 if (len < 0) 1353 1337 return len; 1354 1338 1339 + memset(f, 0, 32); 1355 1340 if (copy_from_user(f, &user_buffer[i], len)) 1356 1341 return -EFAULT; 1357 - i += len; 1358 1342 1359 1343 flag = pktgen_read_flag(f, &disable); 1360 1344 if (flag) { ··· 1396 1380 return count; 1397 1381 } 1398 1382 if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) { 1399 - len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1); 1383 + max = min(sizeof(pkt_dev->dst_min) - 1, count - i); 1384 + len = strn_len(&user_buffer[i], max); 1400 1385 if (len < 0) 1401 1386 return len; 1402 1387 ··· 1412 1395 } 1413 1396 if (debug) 1414 1397 pr_debug("dst_min set to: %s\n", pkt_dev->dst_min); 1415 - i += len; 1398 + 1416 1399 sprintf(pg_result, "OK: dst_min=%s", pkt_dev->dst_min); 1417 1400 return count; 1418 1401 } 1419 1402 if (!strcmp(name, "dst_max")) { 1420 - len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1); 1403 + max = min(sizeof(pkt_dev->dst_max) - 1, count - i); 1404 + len = strn_len(&user_buffer[i], max); 1421 1405 if (len < 0) 1422 1406 return len; 1423 1407 ··· 1433 1415 } 1434 1416 if (debug) 1435 1417 pr_debug("dst_max set to: %s\n", pkt_dev->dst_max); 1436 - i += len; 1418 + 1437 1419 sprintf(pg_result, "OK: dst_max=%s", pkt_dev->dst_max); 1438 1420 return count; 1439 1421 } 1440 1422 if (!strcmp(name, "dst6")) { 1441 - len = strn_len(&user_buffer[i], sizeof(buf) - 1); 1423 + max = min(sizeof(buf) - 1, count - i); 1424 + len = strn_len(&user_buffer[i], max); 1442 1425 if (len < 0) 1443 1426 return len; 1444 1427 ··· 1457 1438 if (debug) 1458 1439 pr_debug("dst6 set to: %s\n", buf); 1459 1440 1460 - i += len; 1461 1441 sprintf(pg_result, "OK: dst6=%s", buf); 1462 1442 return count; 1463 1443 } 1464 1444 if (!strcmp(name, "dst6_min")) { 1465 - len = strn_len(&user_buffer[i], sizeof(buf) - 1); 1445 + max = min(sizeof(buf) - 1, count - i); 1446 + len = strn_len(&user_buffer[i], max); 1466 1447 if (len < 0) 1467 1448 return len; 1468 1449 ··· 1479 1460 if (debug) 1480 1461 pr_debug("dst6_min set to: %s\n", buf); 1481 1462 1482 - i += len; 1483 1463 sprintf(pg_result, "OK: dst6_min=%s", buf); 1484 1464 return count; 1485 1465 } 1486 1466 if (!strcmp(name, "dst6_max")) { 1487 - len = strn_len(&user_buffer[i], sizeof(buf) - 1); 1467 + max = min(sizeof(buf) - 1, count - i); 1468 + len = strn_len(&user_buffer[i], max); 1488 1469 if (len < 0) 1489 1470 return len; 1490 1471 ··· 1500 1481 if (debug) 1501 1482 pr_debug("dst6_max set to: %s\n", buf); 1502 1483 1503 - i += len; 1504 1484 sprintf(pg_result, "OK: dst6_max=%s", buf); 1505 1485 return count; 1506 1486 } 1507 1487 if (!strcmp(name, "src6")) { 1508 - len = strn_len(&user_buffer[i], sizeof(buf) - 1); 1488 + max = min(sizeof(buf) - 1, count - i); 1489 + len = strn_len(&user_buffer[i], max); 1509 1490 if (len < 0) 1510 1491 return len; 1511 1492 ··· 1523 1504 if (debug) 1524 1505 pr_debug("src6 set to: %s\n", buf); 1525 1506 1526 - i += len; 1527 1507 sprintf(pg_result, "OK: src6=%s", buf); 1528 1508 return count; 1529 1509 } 1530 1510 if (!strcmp(name, "src_min")) { 1531 - len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1); 1511 + max = min(sizeof(pkt_dev->src_min) - 1, count - i); 1512 + len = strn_len(&user_buffer[i], max); 1532 1513 if (len < 0) 1533 1514 return len; 1534 1515 ··· 1543 1524 } 1544 1525 if (debug) 1545 1526 pr_debug("src_min set to: %s\n", pkt_dev->src_min); 1546 - i += len; 1527 + 1547 1528 sprintf(pg_result, "OK: src_min=%s", pkt_dev->src_min); 1548 1529 return count; 1549 1530 } 1550 1531 if (!strcmp(name, "src_max")) { 1551 - len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1); 1532 + max = min(sizeof(pkt_dev->src_max) - 1, count - i); 1533 + len = strn_len(&user_buffer[i], max); 1552 1534 if (len < 0) 1553 1535 return len; 1554 1536 ··· 1564 1544 } 1565 1545 if (debug) 1566 1546 pr_debug("src_max set to: %s\n", pkt_dev->src_max); 1567 - i += len; 1547 + 1568 1548 sprintf(pg_result, "OK: src_max=%s", pkt_dev->src_max); 1569 1549 return count; 1570 1550 } 1571 1551 if (!strcmp(name, "dst_mac")) { 1572 - len = strn_len(&user_buffer[i], sizeof(valstr) - 1); 1552 + max = min(sizeof(valstr) - 1, count - i); 1553 + len = strn_len(&user_buffer[i], max); 1573 1554 if (len < 0) 1574 1555 return len; 1575 1556 ··· 1587 1566 return count; 1588 1567 } 1589 1568 if (!strcmp(name, "src_mac")) { 1590 - len = strn_len(&user_buffer[i], sizeof(valstr) - 1); 1569 + max = min(sizeof(valstr) - 1, count - i); 1570 + len = strn_len(&user_buffer[i], max); 1591 1571 if (len < 0) 1592 1572 return len; 1593 1573 ··· 1612 1590 } 1613 1591 1614 1592 if (!strcmp(name, "flows")) { 1615 - len = num_arg(&user_buffer[i], 10, &value); 1593 + max = min(10, count - i); 1594 + len = num_arg(&user_buffer[i], max, &value); 1616 1595 if (len < 0) 1617 1596 return len; 1618 1597 1619 - i += len; 1620 1598 if (value > MAX_CFLOWS) 1621 1599 value = MAX_CFLOWS; 1622 1600 ··· 1626 1604 } 1627 1605 #ifdef CONFIG_XFRM 1628 1606 if (!strcmp(name, "spi")) { 1629 - len = num_arg(&user_buffer[i], 10, &value); 1607 + max = min(10, count - i); 1608 + len = num_arg(&user_buffer[i], max, &value); 1630 1609 if (len < 0) 1631 1610 return len; 1632 1611 1633 - i += len; 1634 1612 pkt_dev->spi = value; 1635 1613 sprintf(pg_result, "OK: spi=%u", pkt_dev->spi); 1636 1614 return count; 1637 1615 } 1638 1616 #endif 1639 1617 if (!strcmp(name, "flowlen")) { 1640 - len = num_arg(&user_buffer[i], 10, &value); 1618 + max = min(10, count - i); 1619 + len = num_arg(&user_buffer[i], max, &value); 1641 1620 if (len < 0) 1642 1621 return len; 1643 1622 1644 - i += len; 1645 1623 pkt_dev->lflow = value; 1646 1624 sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow); 1647 1625 return count; 1648 1626 } 1649 1627 1650 1628 if (!strcmp(name, "queue_map_min")) { 1651 - len = num_arg(&user_buffer[i], 5, &value); 1629 + max = min(5, count - i); 1630 + len = num_arg(&user_buffer[i], max, &value); 1652 1631 if (len < 0) 1653 1632 return len; 1654 1633 1655 - i += len; 1656 1634 pkt_dev->queue_map_min = value; 1657 1635 sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min); 1658 1636 return count; 1659 1637 } 1660 1638 1661 1639 if (!strcmp(name, "queue_map_max")) { 1662 - len = num_arg(&user_buffer[i], 5, &value); 1640 + max = min(5, count - i); 1641 + len = num_arg(&user_buffer[i], max, &value); 1663 1642 if (len < 0) 1664 1643 return len; 1665 1644 1666 - i += len; 1667 1645 pkt_dev->queue_map_max = value; 1668 1646 sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max); 1669 1647 return count; ··· 1672 1650 if (!strcmp(name, "mpls")) { 1673 1651 unsigned int n, cnt; 1674 1652 1675 - len = get_labels(&user_buffer[i], pkt_dev); 1653 + max = count - i; 1654 + len = get_labels(&user_buffer[i], max, pkt_dev); 1676 1655 if (len < 0) 1677 1656 return len; 1678 - i += len; 1657 + 1679 1658 cnt = sprintf(pg_result, "OK: mpls="); 1680 1659 for (n = 0; n < pkt_dev->nr_labels; n++) 1681 1660 cnt += sprintf(pg_result + cnt, ··· 1694 1671 } 1695 1672 1696 1673 if (!strcmp(name, "vlan_id")) { 1697 - len = num_arg(&user_buffer[i], 4, &value); 1674 + max = min(4, count - i); 1675 + len = num_arg(&user_buffer[i], max, &value); 1698 1676 if (len < 0) 1699 1677 return len; 1700 1678 1701 - i += len; 1702 1679 if (value <= 4095) { 1703 1680 pkt_dev->vlan_id = value; /* turn on VLAN */ 1704 1681 ··· 1721 1698 } 1722 1699 1723 1700 if (!strcmp(name, "vlan_p")) { 1724 - len = num_arg(&user_buffer[i], 1, &value); 1701 + max = min(1, count - i); 1702 + len = num_arg(&user_buffer[i], max, &value); 1725 1703 if (len < 0) 1726 1704 return len; 1727 1705 1728 - i += len; 1729 1706 if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) { 1730 1707 pkt_dev->vlan_p = value; 1731 1708 sprintf(pg_result, "OK: vlan_p=%u", pkt_dev->vlan_p); ··· 1736 1713 } 1737 1714 1738 1715 if (!strcmp(name, "vlan_cfi")) { 1739 - len = num_arg(&user_buffer[i], 1, &value); 1716 + max = min(1, count - i); 1717 + len = num_arg(&user_buffer[i], max, &value); 1740 1718 if (len < 0) 1741 1719 return len; 1742 1720 1743 - i += len; 1744 1721 if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) { 1745 1722 pkt_dev->vlan_cfi = value; 1746 1723 sprintf(pg_result, "OK: vlan_cfi=%u", pkt_dev->vlan_cfi); ··· 1751 1728 } 1752 1729 1753 1730 if (!strcmp(name, "svlan_id")) { 1754 - len = num_arg(&user_buffer[i], 4, &value); 1731 + max = min(4, count - i); 1732 + len = num_arg(&user_buffer[i], max, &value); 1755 1733 if (len < 0) 1756 1734 return len; 1757 1735 1758 - i += len; 1759 1736 if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) { 1760 1737 pkt_dev->svlan_id = value; /* turn on SVLAN */ 1761 1738 ··· 1778 1755 } 1779 1756 1780 1757 if (!strcmp(name, "svlan_p")) { 1781 - len = num_arg(&user_buffer[i], 1, &value); 1758 + max = min(1, count - i); 1759 + len = num_arg(&user_buffer[i], max, &value); 1782 1760 if (len < 0) 1783 1761 return len; 1784 1762 1785 - i += len; 1786 1763 if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) { 1787 1764 pkt_dev->svlan_p = value; 1788 1765 sprintf(pg_result, "OK: svlan_p=%u", pkt_dev->svlan_p); ··· 1793 1770 } 1794 1771 1795 1772 if (!strcmp(name, "svlan_cfi")) { 1796 - len = num_arg(&user_buffer[i], 1, &value); 1773 + max = min(1, count - i); 1774 + len = num_arg(&user_buffer[i], max, &value); 1797 1775 if (len < 0) 1798 1776 return len; 1799 1777 1800 - i += len; 1801 1778 if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) { 1802 1779 pkt_dev->svlan_cfi = value; 1803 1780 sprintf(pg_result, "OK: svlan_cfi=%u", pkt_dev->svlan_cfi); ··· 1808 1785 } 1809 1786 1810 1787 if (!strcmp(name, "tos")) { 1811 - __u32 tmp_value = 0; 1812 - len = hex32_arg(&user_buffer[i], 2, &tmp_value); 1788 + __u32 tmp_value; 1789 + 1790 + max = min(2, count - i); 1791 + len = hex32_arg(&user_buffer[i], max, &tmp_value); 1813 1792 if (len < 0) 1814 1793 return len; 1815 1794 1816 - i += len; 1817 1795 if (len == 2) { 1818 1796 pkt_dev->tos = tmp_value; 1819 1797 sprintf(pg_result, "OK: tos=0x%02x", pkt_dev->tos); ··· 1825 1801 } 1826 1802 1827 1803 if (!strcmp(name, "traffic_class")) { 1828 - __u32 tmp_value = 0; 1829 - len = hex32_arg(&user_buffer[i], 2, &tmp_value); 1804 + __u32 tmp_value; 1805 + 1806 + max = min(2, count - i); 1807 + len = hex32_arg(&user_buffer[i], max, &tmp_value); 1830 1808 if (len < 0) 1831 1809 return len; 1832 1810 1833 - i += len; 1834 1811 if (len == 2) { 1835 1812 pkt_dev->traffic_class = tmp_value; 1836 1813 sprintf(pg_result, "OK: traffic_class=0x%02x", pkt_dev->traffic_class); ··· 1842 1817 } 1843 1818 1844 1819 if (!strcmp(name, "skb_priority")) { 1845 - len = num_arg(&user_buffer[i], 9, &value); 1820 + max = min(9, count - i); 1821 + len = num_arg(&user_buffer[i], max, &value); 1846 1822 if (len < 0) 1847 1823 return len; 1848 1824 1849 - i += len; 1850 1825 pkt_dev->skb_priority = value; 1851 1826 sprintf(pg_result, "OK: skb_priority=%i", 1852 1827 pkt_dev->skb_priority); ··· 1906 1881 { 1907 1882 struct seq_file *seq = file->private_data; 1908 1883 struct pktgen_thread *t = seq->private; 1909 - int i, max, len, ret; 1884 + size_t i, max; 1885 + ssize_t len, ret; 1910 1886 char name[40]; 1911 1887 char *pg_result; 1912 1888 ··· 1963 1937 } 1964 1938 if (copy_from_user(f, &user_buffer[i], len)) 1965 1939 return -EFAULT; 1966 - i += len; 1940 + 1967 1941 mutex_lock(&pktgen_thread_lock); 1968 1942 ret = pktgen_add_device(t, f); 1969 1943 mutex_unlock(&pktgen_thread_lock);
+1
tools/testing/selftests/net/Makefile
··· 104 104 TEST_PROGS += bpf_offload.py 105 105 TEST_PROGS += ipv6_route_update_soft_lockup.sh 106 106 TEST_PROGS += busy_poll_test.sh 107 + TEST_GEN_PROGS += proc_net_pktgen 107 108 108 109 # YNL files, must be before "include ..lib.mk" 109 110 YNL_GEN_FILES := busy_poller netlink-dumps
+1
tools/testing/selftests/net/config
··· 112 112 CONFIG_CAN_DEV=m 113 113 CONFIG_CAN_VXCAN=m 114 114 CONFIG_NETKIT=y 115 + CONFIG_NET_PKTGEN=m
+646
tools/testing/selftests/net/proc_net_pktgen.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * proc_net_pktgen: kselftest for /proc/net/pktgen interface 4 + * 5 + * Copyright (c) 2025 Peter Seiderer <ps.report@gmx.net> 6 + * 7 + */ 8 + #include <errno.h> 9 + #include <fcntl.h> 10 + #include <stdlib.h> 11 + #include <unistd.h> 12 + 13 + #include "../kselftest_harness.h" 14 + 15 + static const char ctrl_cmd_stop[] = "stop"; 16 + static const char ctrl_cmd_start[] = "start"; 17 + static const char ctrl_cmd_reset[] = "reset"; 18 + 19 + static const char wrong_ctrl_cmd[] = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; 20 + 21 + static const char thr_cmd_add_loopback_0[] = "add_device lo@0"; 22 + static const char thr_cmd_rm_loopback_0[] = "rem_device_all"; 23 + 24 + static const char wrong_thr_cmd[] = "forsureawrongcommand"; 25 + static const char legacy_thr_cmd[] = "max_before_softirq"; 26 + 27 + static const char wrong_dev_cmd[] = "forsurewrongcommand"; 28 + static const char dev_cmd_min_pkt_size_0[] = "min_pkt_size"; 29 + static const char dev_cmd_min_pkt_size_1[] = "min_pkt_size "; 30 + static const char dev_cmd_min_pkt_size_2[] = "min_pkt_size 0"; 31 + static const char dev_cmd_min_pkt_size_3[] = "min_pkt_size 1"; 32 + static const char dev_cmd_min_pkt_size_4[] = "min_pkt_size 100"; 33 + static const char dev_cmd_min_pkt_size_5[] = "min_pkt_size=1001"; 34 + static const char dev_cmd_min_pkt_size_6[] = "min_pkt_size =2002"; 35 + static const char dev_cmd_min_pkt_size_7[] = "min_pkt_size= 3003"; 36 + static const char dev_cmd_min_pkt_size_8[] = "min_pkt_size = 4004"; 37 + static const char dev_cmd_max_pkt_size_0[] = "max_pkt_size 200"; 38 + static const char dev_cmd_pkt_size_0[] = "pkt_size 300"; 39 + static const char dev_cmd_imix_weights_0[] = "imix_weights 0,7 576,4 1500,1"; 40 + static const char dev_cmd_imix_weights_1[] = "imix_weights 101,1 102,2 103,3 104,4 105,5 106,6 107,7 108,8 109,9 110,10 111,11 112,12 113,13 114,14 115,15 116,16 117,17 118,18 119,19 120,20"; 41 + static const char dev_cmd_imix_weights_2[] = "imix_weights 100,1 102,2 103,3 104,4 105,5 106,6 107,7 108,8 109,9 110,10 111,11 112,12 113,13 114,14 115,15 116,16 117,17 118,18 119,19 120,20 121,21"; 42 + static const char dev_cmd_debug_0[] = "debug 1"; 43 + static const char dev_cmd_debug_1[] = "debug 0"; 44 + static const char dev_cmd_frags_0[] = "frags 100"; 45 + static const char dev_cmd_delay_0[] = "delay 100"; 46 + static const char dev_cmd_delay_1[] = "delay 2147483647"; 47 + static const char dev_cmd_rate_0[] = "rate 0"; 48 + static const char dev_cmd_rate_1[] = "rate 100"; 49 + static const char dev_cmd_ratep_0[] = "ratep 0"; 50 + static const char dev_cmd_ratep_1[] = "ratep 200"; 51 + static const char dev_cmd_udp_src_min_0[] = "udp_src_min 1"; 52 + static const char dev_cmd_udp_dst_min_0[] = "udp_dst_min 2"; 53 + static const char dev_cmd_udp_src_max_0[] = "udp_src_max 3"; 54 + static const char dev_cmd_udp_dst_max_0[] = "udp_dst_max 4"; 55 + static const char dev_cmd_clone_skb_0[] = "clone_skb 1"; 56 + static const char dev_cmd_clone_skb_1[] = "clone_skb 0"; 57 + static const char dev_cmd_count_0[] = "count 100"; 58 + static const char dev_cmd_src_mac_count_0[] = "src_mac_count 100"; 59 + static const char dev_cmd_dst_mac_count_0[] = "dst_mac_count 100"; 60 + static const char dev_cmd_burst_0[] = "burst 0"; 61 + static const char dev_cmd_node_0[] = "node 100"; 62 + static const char dev_cmd_xmit_mode_0[] = "xmit_mode start_xmit"; 63 + static const char dev_cmd_xmit_mode_1[] = "xmit_mode netif_receive"; 64 + static const char dev_cmd_xmit_mode_2[] = "xmit_mode queue_xmit"; 65 + static const char dev_cmd_xmit_mode_3[] = "xmit_mode nonsense"; 66 + static const char dev_cmd_flag_0[] = "flag UDPCSUM"; 67 + static const char dev_cmd_flag_1[] = "flag !UDPCSUM"; 68 + static const char dev_cmd_flag_2[] = "flag nonsense"; 69 + static const char dev_cmd_dst_min_0[] = "dst_min 101.102.103.104"; 70 + static const char dev_cmd_dst_0[] = "dst 101.102.103.104"; 71 + static const char dev_cmd_dst_max_0[] = "dst_max 201.202.203.204"; 72 + static const char dev_cmd_dst6_0[] = "dst6 2001:db38:1234:0000:0000:0000:0000:0000"; 73 + static const char dev_cmd_dst6_min_0[] = "dst6_min 2001:db8:1234:0000:0000:0000:0000:0000"; 74 + static const char dev_cmd_dst6_max_0[] = "dst6_max 2001:db8:1234:0000:0000:0000:0000:0000"; 75 + static const char dev_cmd_src6_0[] = "src6 2001:db38:1234:0000:0000:0000:0000:0000"; 76 + static const char dev_cmd_src_min_0[] = "src_min 101.102.103.104"; 77 + static const char dev_cmd_src_max_0[] = "src_max 201.202.203.204"; 78 + static const char dev_cmd_dst_mac_0[] = "dst_mac 01:02:03:04:05:06"; 79 + static const char dev_cmd_src_mac_0[] = "src_mac 11:12:13:14:15:16"; 80 + static const char dev_cmd_clear_counters_0[] = "clear_counters"; 81 + static const char dev_cmd_flows_0[] = "flows 100"; 82 + static const char dev_cmd_spi_0[] = "spi 100"; 83 + static const char dev_cmd_flowlen_0[] = "flowlen 100"; 84 + static const char dev_cmd_queue_map_min_0[] = "queue_map_min 1"; 85 + static const char dev_cmd_queue_map_max_0[] = "queue_map_max 2"; 86 + static const char dev_cmd_mpls_0[] = "mpls 00000001"; 87 + static const char dev_cmd_mpls_1[] = "mpls 00000001,000000f2"; 88 + static const char dev_cmd_mpls_2[] = "mpls 00000f00,00000f01,00000f02,00000f03,00000f04,00000f05,00000f06,00000f07,00000f08,00000f09,00000f0a,00000f0b,00000f0c,00000f0d,00000f0e,00000f0f"; 89 + static const char dev_cmd_mpls_3[] = "mpls 00000f00,00000f01,00000f02,00000f03,00000f04,00000f05,00000f06,00000f07,00000f08,00000f09,00000f0a,00000f0b,00000f0c,00000f0d,00000f0e,00000f0f,00000f10"; 90 + static const char dev_cmd_vlan_id_0[] = "vlan_id 1"; 91 + static const char dev_cmd_vlan_p_0[] = "vlan_p 1"; 92 + static const char dev_cmd_vlan_cfi_0[] = "vlan_cfi 1"; 93 + static const char dev_cmd_vlan_id_1[] = "vlan_id 4096"; 94 + static const char dev_cmd_svlan_id_0[] = "svlan_id 1"; 95 + static const char dev_cmd_svlan_p_0[] = "svlan_p 1"; 96 + static const char dev_cmd_svlan_cfi_0[] = "svlan_cfi 1"; 97 + static const char dev_cmd_svlan_id_1[] = "svlan_id 4096"; 98 + static const char dev_cmd_tos_0[] = "tos 0"; 99 + static const char dev_cmd_tos_1[] = "tos 0f"; 100 + static const char dev_cmd_tos_2[] = "tos 0ff"; 101 + static const char dev_cmd_traffic_class_0[] = "traffic_class f0"; 102 + static const char dev_cmd_skb_priority_0[] = "skb_priority 999"; 103 + 104 + FIXTURE(proc_net_pktgen) { 105 + int ctrl_fd; 106 + int thr_fd; 107 + int dev_fd; 108 + }; 109 + 110 + FIXTURE_SETUP(proc_net_pktgen) { 111 + int r; 112 + ssize_t len; 113 + 114 + r = system("modprobe pktgen"); 115 + ASSERT_EQ(r, 0) TH_LOG("CONFIG_NET_PKTGEN not enabled, module pktgen not loaded?"); 116 + 117 + self->ctrl_fd = open("/proc/net/pktgen/pgctrl", O_RDWR); 118 + ASSERT_GE(self->ctrl_fd, 0) TH_LOG("CONFIG_NET_PKTGEN not enabled, module pktgen not loaded?"); 119 + 120 + self->thr_fd = open("/proc/net/pktgen/kpktgend_0", O_RDWR); 121 + ASSERT_GE(self->thr_fd, 0) TH_LOG("CONFIG_NET_PKTGEN not enabled, module pktgen not loaded?"); 122 + 123 + len = write(self->thr_fd, thr_cmd_add_loopback_0, sizeof(thr_cmd_add_loopback_0)); 124 + ASSERT_EQ(len, sizeof(thr_cmd_add_loopback_0)) TH_LOG("device lo@0 already registered?"); 125 + 126 + self->dev_fd = open("/proc/net/pktgen/lo@0", O_RDWR); 127 + ASSERT_GE(self->dev_fd, 0) TH_LOG("device entry for lo@0 missing?"); 128 + } 129 + 130 + FIXTURE_TEARDOWN(proc_net_pktgen) { 131 + int ret; 132 + ssize_t len; 133 + 134 + ret = close(self->dev_fd); 135 + EXPECT_EQ(ret, 0); 136 + 137 + len = write(self->thr_fd, thr_cmd_rm_loopback_0, sizeof(thr_cmd_rm_loopback_0)); 138 + EXPECT_EQ(len, sizeof(thr_cmd_rm_loopback_0)); 139 + 140 + ret = close(self->thr_fd); 141 + EXPECT_EQ(ret, 0); 142 + 143 + ret = close(self->ctrl_fd); 144 + EXPECT_EQ(ret, 0); 145 + } 146 + 147 + TEST_F(proc_net_pktgen, wrong_ctrl_cmd) { 148 + for (int i = 0; i <= sizeof(wrong_ctrl_cmd); i++) { 149 + ssize_t len; 150 + 151 + len = write(self->ctrl_fd, wrong_ctrl_cmd, i); 152 + EXPECT_EQ(len, -1); 153 + EXPECT_EQ(errno, EINVAL); 154 + } 155 + } 156 + 157 + TEST_F(proc_net_pktgen, ctrl_cmd) { 158 + ssize_t len; 159 + 160 + len = write(self->ctrl_fd, ctrl_cmd_stop, sizeof(ctrl_cmd_stop)); 161 + EXPECT_EQ(len, sizeof(ctrl_cmd_stop)); 162 + 163 + len = write(self->ctrl_fd, ctrl_cmd_stop, sizeof(ctrl_cmd_stop) - 1); 164 + EXPECT_EQ(len, sizeof(ctrl_cmd_stop) - 1); 165 + 166 + len = write(self->ctrl_fd, ctrl_cmd_start, sizeof(ctrl_cmd_start)); 167 + EXPECT_EQ(len, sizeof(ctrl_cmd_start)); 168 + 169 + len = write(self->ctrl_fd, ctrl_cmd_start, sizeof(ctrl_cmd_start) - 1); 170 + EXPECT_EQ(len, sizeof(ctrl_cmd_start) - 1); 171 + 172 + len = write(self->ctrl_fd, ctrl_cmd_reset, sizeof(ctrl_cmd_reset)); 173 + EXPECT_EQ(len, sizeof(ctrl_cmd_reset)); 174 + 175 + len = write(self->ctrl_fd, ctrl_cmd_reset, sizeof(ctrl_cmd_reset) - 1); 176 + EXPECT_EQ(len, sizeof(ctrl_cmd_reset) - 1); 177 + } 178 + 179 + TEST_F(proc_net_pktgen, wrong_thr_cmd) { 180 + for (int i = 0; i <= sizeof(wrong_thr_cmd); i++) { 181 + ssize_t len; 182 + 183 + len = write(self->thr_fd, wrong_thr_cmd, i); 184 + EXPECT_EQ(len, -1); 185 + EXPECT_EQ(errno, EINVAL); 186 + } 187 + } 188 + 189 + TEST_F(proc_net_pktgen, legacy_thr_cmd) { 190 + for (int i = 0; i <= sizeof(legacy_thr_cmd); i++) { 191 + ssize_t len; 192 + 193 + len = write(self->thr_fd, legacy_thr_cmd, i); 194 + if (i < (sizeof(legacy_thr_cmd) - 1)) { 195 + /* incomplete command string */ 196 + EXPECT_EQ(len, -1); 197 + EXPECT_EQ(errno, EINVAL); 198 + } else { 199 + /* complete command string without/with trailing '\0' */ 200 + EXPECT_EQ(len, i); 201 + } 202 + } 203 + } 204 + 205 + TEST_F(proc_net_pktgen, wrong_dev_cmd) { 206 + for (int i = 0; i <= sizeof(wrong_dev_cmd); i++) { 207 + ssize_t len; 208 + 209 + len = write(self->dev_fd, wrong_dev_cmd, i); 210 + EXPECT_EQ(len, -1); 211 + EXPECT_EQ(errno, EINVAL); 212 + } 213 + } 214 + 215 + TEST_F(proc_net_pktgen, dev_cmd_min_pkt_size) { 216 + ssize_t len; 217 + 218 + /* with trailing '\0' */ 219 + len = write(self->dev_fd, dev_cmd_min_pkt_size_0, sizeof(dev_cmd_min_pkt_size_0)); 220 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_0)); 221 + 222 + /* without trailing '\0' */ 223 + len = write(self->dev_fd, dev_cmd_min_pkt_size_0, sizeof(dev_cmd_min_pkt_size_0) - 1); 224 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_0) - 1); 225 + 226 + /* with trailing '\0' */ 227 + len = write(self->dev_fd, dev_cmd_min_pkt_size_1, sizeof(dev_cmd_min_pkt_size_1)); 228 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_1)); 229 + 230 + /* without trailing '\0' */ 231 + len = write(self->dev_fd, dev_cmd_min_pkt_size_1, sizeof(dev_cmd_min_pkt_size_1) - 1); 232 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_1) - 1); 233 + 234 + /* with trailing '\0' */ 235 + len = write(self->dev_fd, dev_cmd_min_pkt_size_2, sizeof(dev_cmd_min_pkt_size_2)); 236 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_2)); 237 + 238 + /* without trailing '\0' */ 239 + len = write(self->dev_fd, dev_cmd_min_pkt_size_2, sizeof(dev_cmd_min_pkt_size_2) - 1); 240 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_2) - 1); 241 + 242 + len = write(self->dev_fd, dev_cmd_min_pkt_size_3, sizeof(dev_cmd_min_pkt_size_3)); 243 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_3)); 244 + 245 + len = write(self->dev_fd, dev_cmd_min_pkt_size_4, sizeof(dev_cmd_min_pkt_size_4)); 246 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_4)); 247 + 248 + len = write(self->dev_fd, dev_cmd_min_pkt_size_5, sizeof(dev_cmd_min_pkt_size_5)); 249 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_5)); 250 + 251 + len = write(self->dev_fd, dev_cmd_min_pkt_size_6, sizeof(dev_cmd_min_pkt_size_6)); 252 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_6)); 253 + 254 + len = write(self->dev_fd, dev_cmd_min_pkt_size_7, sizeof(dev_cmd_min_pkt_size_7)); 255 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_7)); 256 + 257 + len = write(self->dev_fd, dev_cmd_min_pkt_size_8, sizeof(dev_cmd_min_pkt_size_8)); 258 + EXPECT_EQ(len, sizeof(dev_cmd_min_pkt_size_8)); 259 + } 260 + 261 + TEST_F(proc_net_pktgen, dev_cmd_max_pkt_size) { 262 + ssize_t len; 263 + 264 + len = write(self->dev_fd, dev_cmd_max_pkt_size_0, sizeof(dev_cmd_max_pkt_size_0)); 265 + EXPECT_EQ(len, sizeof(dev_cmd_max_pkt_size_0)); 266 + } 267 + 268 + TEST_F(proc_net_pktgen, dev_cmd_pkt_size) { 269 + ssize_t len; 270 + 271 + len = write(self->dev_fd, dev_cmd_pkt_size_0, sizeof(dev_cmd_pkt_size_0)); 272 + EXPECT_EQ(len, sizeof(dev_cmd_pkt_size_0)); 273 + } 274 + 275 + TEST_F(proc_net_pktgen, dev_cmd_imix_weights) { 276 + ssize_t len; 277 + 278 + len = write(self->dev_fd, dev_cmd_imix_weights_0, sizeof(dev_cmd_imix_weights_0)); 279 + EXPECT_EQ(len, sizeof(dev_cmd_imix_weights_0)); 280 + 281 + len = write(self->dev_fd, dev_cmd_imix_weights_1, sizeof(dev_cmd_imix_weights_1)); 282 + EXPECT_EQ(len, sizeof(dev_cmd_imix_weights_1)); 283 + 284 + len = write(self->dev_fd, dev_cmd_imix_weights_2, sizeof(dev_cmd_imix_weights_2)); 285 + EXPECT_EQ(len, -1); 286 + EXPECT_EQ(errno, E2BIG); 287 + } 288 + 289 + TEST_F(proc_net_pktgen, dev_cmd_debug) { 290 + ssize_t len; 291 + 292 + /* debug on */ 293 + len = write(self->dev_fd, dev_cmd_debug_0, sizeof(dev_cmd_debug_0)); 294 + EXPECT_EQ(len, sizeof(dev_cmd_debug_0)); 295 + 296 + /* debug off */ 297 + len = write(self->dev_fd, dev_cmd_debug_1, sizeof(dev_cmd_debug_1)); 298 + EXPECT_EQ(len, sizeof(dev_cmd_debug_1)); 299 + } 300 + 301 + TEST_F(proc_net_pktgen, dev_cmd_frags) { 302 + ssize_t len; 303 + 304 + len = write(self->dev_fd, dev_cmd_frags_0, sizeof(dev_cmd_frags_0)); 305 + EXPECT_EQ(len, sizeof(dev_cmd_frags_0)); 306 + } 307 + 308 + TEST_F(proc_net_pktgen, dev_cmd_delay) { 309 + ssize_t len; 310 + 311 + len = write(self->dev_fd, dev_cmd_delay_0, sizeof(dev_cmd_delay_0)); 312 + EXPECT_EQ(len, sizeof(dev_cmd_delay_0)); 313 + 314 + len = write(self->dev_fd, dev_cmd_delay_1, sizeof(dev_cmd_delay_1)); 315 + EXPECT_EQ(len, sizeof(dev_cmd_delay_1)); 316 + } 317 + 318 + TEST_F(proc_net_pktgen, dev_cmd_rate) { 319 + ssize_t len; 320 + 321 + len = write(self->dev_fd, dev_cmd_rate_0, sizeof(dev_cmd_rate_0)); 322 + EXPECT_EQ(len, -1); 323 + EXPECT_EQ(errno, EINVAL); 324 + 325 + len = write(self->dev_fd, dev_cmd_rate_1, sizeof(dev_cmd_rate_1)); 326 + EXPECT_EQ(len, sizeof(dev_cmd_rate_1)); 327 + } 328 + 329 + TEST_F(proc_net_pktgen, dev_cmd_ratep) { 330 + ssize_t len; 331 + 332 + len = write(self->dev_fd, dev_cmd_ratep_0, sizeof(dev_cmd_ratep_0)); 333 + EXPECT_EQ(len, -1); 334 + EXPECT_EQ(errno, EINVAL); 335 + 336 + len = write(self->dev_fd, dev_cmd_ratep_1, sizeof(dev_cmd_ratep_1)); 337 + EXPECT_EQ(len, sizeof(dev_cmd_ratep_1)); 338 + } 339 + 340 + TEST_F(proc_net_pktgen, dev_cmd_udp_src_min) { 341 + ssize_t len; 342 + 343 + len = write(self->dev_fd, dev_cmd_udp_src_min_0, sizeof(dev_cmd_udp_src_min_0)); 344 + EXPECT_EQ(len, sizeof(dev_cmd_udp_src_min_0)); 345 + } 346 + 347 + TEST_F(proc_net_pktgen, dev_cmd_udp_dst_min) { 348 + ssize_t len; 349 + 350 + len = write(self->dev_fd, dev_cmd_udp_dst_min_0, sizeof(dev_cmd_udp_dst_min_0)); 351 + EXPECT_EQ(len, sizeof(dev_cmd_udp_dst_min_0)); 352 + } 353 + 354 + TEST_F(proc_net_pktgen, dev_cmd_udp_src_max) { 355 + ssize_t len; 356 + 357 + len = write(self->dev_fd, dev_cmd_udp_src_max_0, sizeof(dev_cmd_udp_src_max_0)); 358 + EXPECT_EQ(len, sizeof(dev_cmd_udp_src_max_0)); 359 + } 360 + 361 + TEST_F(proc_net_pktgen, dev_cmd_udp_dst_max) { 362 + ssize_t len; 363 + 364 + len = write(self->dev_fd, dev_cmd_udp_dst_max_0, sizeof(dev_cmd_udp_dst_max_0)); 365 + EXPECT_EQ(len, sizeof(dev_cmd_udp_dst_max_0)); 366 + } 367 + 368 + TEST_F(proc_net_pktgen, dev_cmd_clone_skb) { 369 + ssize_t len; 370 + 371 + /* clone_skb on (gives EOPNOTSUPP on lo device) */ 372 + len = write(self->dev_fd, dev_cmd_clone_skb_0, sizeof(dev_cmd_clone_skb_0)); 373 + EXPECT_EQ(len, -1); 374 + EXPECT_EQ(errno, EOPNOTSUPP); 375 + 376 + /* clone_skb off */ 377 + len = write(self->dev_fd, dev_cmd_clone_skb_1, sizeof(dev_cmd_clone_skb_1)); 378 + EXPECT_EQ(len, sizeof(dev_cmd_clone_skb_1)); 379 + } 380 + 381 + TEST_F(proc_net_pktgen, dev_cmd_count) { 382 + ssize_t len; 383 + 384 + len = write(self->dev_fd, dev_cmd_count_0, sizeof(dev_cmd_count_0)); 385 + EXPECT_EQ(len, sizeof(dev_cmd_count_0)); 386 + } 387 + 388 + TEST_F(proc_net_pktgen, dev_cmd_src_mac_count) { 389 + ssize_t len; 390 + 391 + len = write(self->dev_fd, dev_cmd_src_mac_count_0, sizeof(dev_cmd_src_mac_count_0)); 392 + EXPECT_EQ(len, sizeof(dev_cmd_src_mac_count_0)); 393 + } 394 + 395 + TEST_F(proc_net_pktgen, dev_cmd_dst_mac_count) { 396 + ssize_t len; 397 + 398 + len = write(self->dev_fd, dev_cmd_dst_mac_count_0, sizeof(dev_cmd_dst_mac_count_0)); 399 + EXPECT_EQ(len, sizeof(dev_cmd_dst_mac_count_0)); 400 + } 401 + 402 + TEST_F(proc_net_pktgen, dev_cmd_burst) { 403 + ssize_t len; 404 + 405 + /* burst off */ 406 + len = write(self->dev_fd, dev_cmd_burst_0, sizeof(dev_cmd_burst_0)); 407 + EXPECT_EQ(len, sizeof(dev_cmd_burst_0)); 408 + } 409 + 410 + TEST_F(proc_net_pktgen, dev_cmd_node) { 411 + ssize_t len; 412 + 413 + len = write(self->dev_fd, dev_cmd_node_0, sizeof(dev_cmd_node_0)); 414 + EXPECT_EQ(len, sizeof(dev_cmd_node_0)); 415 + } 416 + 417 + TEST_F(proc_net_pktgen, dev_cmd_xmit_mode) { 418 + ssize_t len; 419 + 420 + len = write(self->dev_fd, dev_cmd_xmit_mode_0, sizeof(dev_cmd_xmit_mode_0)); 421 + EXPECT_EQ(len, sizeof(dev_cmd_xmit_mode_0)); 422 + 423 + len = write(self->dev_fd, dev_cmd_xmit_mode_1, sizeof(dev_cmd_xmit_mode_1)); 424 + EXPECT_EQ(len, sizeof(dev_cmd_xmit_mode_1)); 425 + 426 + len = write(self->dev_fd, dev_cmd_xmit_mode_2, sizeof(dev_cmd_xmit_mode_2)); 427 + EXPECT_EQ(len, sizeof(dev_cmd_xmit_mode_2)); 428 + 429 + len = write(self->dev_fd, dev_cmd_xmit_mode_3, sizeof(dev_cmd_xmit_mode_3)); 430 + EXPECT_EQ(len, sizeof(dev_cmd_xmit_mode_3)); 431 + } 432 + 433 + TEST_F(proc_net_pktgen, dev_cmd_flag) { 434 + ssize_t len; 435 + 436 + /* flag UDPCSUM on */ 437 + len = write(self->dev_fd, dev_cmd_flag_0, sizeof(dev_cmd_flag_0)); 438 + EXPECT_EQ(len, sizeof(dev_cmd_flag_0)); 439 + 440 + /* flag UDPCSUM off */ 441 + len = write(self->dev_fd, dev_cmd_flag_1, sizeof(dev_cmd_flag_1)); 442 + EXPECT_EQ(len, sizeof(dev_cmd_flag_1)); 443 + 444 + /* flag invalid */ 445 + len = write(self->dev_fd, dev_cmd_flag_2, sizeof(dev_cmd_flag_2)); 446 + EXPECT_EQ(len, sizeof(dev_cmd_flag_2)); 447 + } 448 + 449 + TEST_F(proc_net_pktgen, dev_cmd_dst_min) { 450 + ssize_t len; 451 + 452 + len = write(self->dev_fd, dev_cmd_dst_min_0, sizeof(dev_cmd_dst_min_0)); 453 + EXPECT_EQ(len, sizeof(dev_cmd_dst_min_0)); 454 + } 455 + 456 + TEST_F(proc_net_pktgen, dev_cmd_dst) { 457 + ssize_t len; 458 + 459 + len = write(self->dev_fd, dev_cmd_dst_0, sizeof(dev_cmd_dst_0)); 460 + EXPECT_EQ(len, sizeof(dev_cmd_dst_0)); 461 + } 462 + 463 + TEST_F(proc_net_pktgen, dev_cmd_dst_max) { 464 + ssize_t len; 465 + 466 + len = write(self->dev_fd, dev_cmd_dst_max_0, sizeof(dev_cmd_dst_max_0)); 467 + EXPECT_EQ(len, sizeof(dev_cmd_dst_max_0)); 468 + } 469 + 470 + TEST_F(proc_net_pktgen, dev_cmd_dst6) { 471 + ssize_t len; 472 + 473 + len = write(self->dev_fd, dev_cmd_dst6_0, sizeof(dev_cmd_dst6_0)); 474 + EXPECT_EQ(len, sizeof(dev_cmd_dst6_0)); 475 + } 476 + 477 + TEST_F(proc_net_pktgen, dev_cmd_dst6_min) { 478 + ssize_t len; 479 + 480 + len = write(self->dev_fd, dev_cmd_dst6_min_0, sizeof(dev_cmd_dst6_min_0)); 481 + EXPECT_EQ(len, sizeof(dev_cmd_dst6_min_0)); 482 + } 483 + 484 + TEST_F(proc_net_pktgen, dev_cmd_dst6_max) { 485 + ssize_t len; 486 + 487 + len = write(self->dev_fd, dev_cmd_dst6_max_0, sizeof(dev_cmd_dst6_max_0)); 488 + EXPECT_EQ(len, sizeof(dev_cmd_dst6_max_0)); 489 + } 490 + 491 + TEST_F(proc_net_pktgen, dev_cmd_src6) { 492 + ssize_t len; 493 + 494 + len = write(self->dev_fd, dev_cmd_src6_0, sizeof(dev_cmd_src6_0)); 495 + EXPECT_EQ(len, sizeof(dev_cmd_src6_0)); 496 + } 497 + 498 + TEST_F(proc_net_pktgen, dev_cmd_src_min) { 499 + ssize_t len; 500 + 501 + len = write(self->dev_fd, dev_cmd_src_min_0, sizeof(dev_cmd_src_min_0)); 502 + EXPECT_EQ(len, sizeof(dev_cmd_src_min_0)); 503 + } 504 + 505 + TEST_F(proc_net_pktgen, dev_cmd_src_max) { 506 + ssize_t len; 507 + 508 + len = write(self->dev_fd, dev_cmd_src_max_0, sizeof(dev_cmd_src_max_0)); 509 + EXPECT_EQ(len, sizeof(dev_cmd_src_max_0)); 510 + } 511 + 512 + TEST_F(proc_net_pktgen, dev_cmd_dst_mac) { 513 + ssize_t len; 514 + 515 + len = write(self->dev_fd, dev_cmd_dst_mac_0, sizeof(dev_cmd_dst_mac_0)); 516 + EXPECT_EQ(len, sizeof(dev_cmd_dst_mac_0)); 517 + } 518 + 519 + TEST_F(proc_net_pktgen, dev_cmd_src_mac) { 520 + ssize_t len; 521 + 522 + len = write(self->dev_fd, dev_cmd_src_mac_0, sizeof(dev_cmd_src_mac_0)); 523 + EXPECT_EQ(len, sizeof(dev_cmd_src_mac_0)); 524 + } 525 + 526 + TEST_F(proc_net_pktgen, dev_cmd_clear_counters) { 527 + ssize_t len; 528 + 529 + len = write(self->dev_fd, dev_cmd_clear_counters_0, sizeof(dev_cmd_clear_counters_0)); 530 + EXPECT_EQ(len, sizeof(dev_cmd_clear_counters_0)); 531 + } 532 + 533 + TEST_F(proc_net_pktgen, dev_cmd_flows) { 534 + ssize_t len; 535 + 536 + len = write(self->dev_fd, dev_cmd_flows_0, sizeof(dev_cmd_flows_0)); 537 + EXPECT_EQ(len, sizeof(dev_cmd_flows_0)); 538 + } 539 + 540 + TEST_F(proc_net_pktgen, dev_cmd_spi) { 541 + ssize_t len; 542 + 543 + len = write(self->dev_fd, dev_cmd_spi_0, sizeof(dev_cmd_spi_0)); 544 + EXPECT_EQ(len, sizeof(dev_cmd_spi_0)) TH_LOG("CONFIG_XFRM not enabled?"); 545 + } 546 + 547 + TEST_F(proc_net_pktgen, dev_cmd_flowlen) { 548 + ssize_t len; 549 + 550 + len = write(self->dev_fd, dev_cmd_flowlen_0, sizeof(dev_cmd_flowlen_0)); 551 + EXPECT_EQ(len, sizeof(dev_cmd_flowlen_0)); 552 + } 553 + 554 + TEST_F(proc_net_pktgen, dev_cmd_queue_map_min) { 555 + ssize_t len; 556 + 557 + len = write(self->dev_fd, dev_cmd_queue_map_min_0, sizeof(dev_cmd_queue_map_min_0)); 558 + EXPECT_EQ(len, sizeof(dev_cmd_queue_map_min_0)); 559 + } 560 + 561 + TEST_F(proc_net_pktgen, dev_cmd_queue_map_max) { 562 + ssize_t len; 563 + 564 + len = write(self->dev_fd, dev_cmd_queue_map_max_0, sizeof(dev_cmd_queue_map_max_0)); 565 + EXPECT_EQ(len, sizeof(dev_cmd_queue_map_max_0)); 566 + } 567 + 568 + TEST_F(proc_net_pktgen, dev_cmd_mpls) { 569 + ssize_t len; 570 + 571 + len = write(self->dev_fd, dev_cmd_mpls_0, sizeof(dev_cmd_mpls_0)); 572 + EXPECT_EQ(len, sizeof(dev_cmd_mpls_0)); 573 + 574 + len = write(self->dev_fd, dev_cmd_mpls_1, sizeof(dev_cmd_mpls_1)); 575 + EXPECT_EQ(len, sizeof(dev_cmd_mpls_1)); 576 + 577 + len = write(self->dev_fd, dev_cmd_mpls_2, sizeof(dev_cmd_mpls_2)); 578 + EXPECT_EQ(len, sizeof(dev_cmd_mpls_2)); 579 + 580 + len = write(self->dev_fd, dev_cmd_mpls_3, sizeof(dev_cmd_mpls_3)); 581 + EXPECT_EQ(len, -1); 582 + EXPECT_EQ(errno, E2BIG); 583 + } 584 + 585 + TEST_F(proc_net_pktgen, dev_cmd_vlan_id) { 586 + ssize_t len; 587 + 588 + len = write(self->dev_fd, dev_cmd_vlan_id_0, sizeof(dev_cmd_vlan_id_0)); 589 + EXPECT_EQ(len, sizeof(dev_cmd_vlan_id_0)); 590 + 591 + len = write(self->dev_fd, dev_cmd_vlan_p_0, sizeof(dev_cmd_vlan_p_0)); 592 + EXPECT_EQ(len, sizeof(dev_cmd_vlan_p_0)); 593 + 594 + len = write(self->dev_fd, dev_cmd_vlan_cfi_0, sizeof(dev_cmd_vlan_cfi_0)); 595 + EXPECT_EQ(len, sizeof(dev_cmd_vlan_cfi_0)); 596 + 597 + len = write(self->dev_fd, dev_cmd_vlan_id_1, sizeof(dev_cmd_vlan_id_1)); 598 + EXPECT_EQ(len, sizeof(dev_cmd_vlan_id_1)); 599 + } 600 + 601 + TEST_F(proc_net_pktgen, dev_cmd_svlan_id) { 602 + ssize_t len; 603 + 604 + len = write(self->dev_fd, dev_cmd_svlan_id_0, sizeof(dev_cmd_svlan_id_0)); 605 + EXPECT_EQ(len, sizeof(dev_cmd_svlan_id_0)); 606 + 607 + len = write(self->dev_fd, dev_cmd_svlan_p_0, sizeof(dev_cmd_svlan_p_0)); 608 + EXPECT_EQ(len, sizeof(dev_cmd_svlan_p_0)); 609 + 610 + len = write(self->dev_fd, dev_cmd_svlan_cfi_0, sizeof(dev_cmd_svlan_cfi_0)); 611 + EXPECT_EQ(len, sizeof(dev_cmd_svlan_cfi_0)); 612 + 613 + len = write(self->dev_fd, dev_cmd_svlan_id_1, sizeof(dev_cmd_svlan_id_1)); 614 + EXPECT_EQ(len, sizeof(dev_cmd_svlan_id_1)); 615 + } 616 + 617 + 618 + TEST_F(proc_net_pktgen, dev_cmd_tos) { 619 + ssize_t len; 620 + 621 + len = write(self->dev_fd, dev_cmd_tos_0, sizeof(dev_cmd_tos_0)); 622 + EXPECT_EQ(len, sizeof(dev_cmd_tos_0)); 623 + 624 + len = write(self->dev_fd, dev_cmd_tos_1, sizeof(dev_cmd_tos_1)); 625 + EXPECT_EQ(len, sizeof(dev_cmd_tos_1)); 626 + 627 + len = write(self->dev_fd, dev_cmd_tos_2, sizeof(dev_cmd_tos_2)); 628 + EXPECT_EQ(len, sizeof(dev_cmd_tos_2)); 629 + } 630 + 631 + 632 + TEST_F(proc_net_pktgen, dev_cmd_traffic_class) { 633 + ssize_t len; 634 + 635 + len = write(self->dev_fd, dev_cmd_traffic_class_0, sizeof(dev_cmd_traffic_class_0)); 636 + EXPECT_EQ(len, sizeof(dev_cmd_traffic_class_0)); 637 + } 638 + 639 + TEST_F(proc_net_pktgen, dev_cmd_skb_priority) { 640 + ssize_t len; 641 + 642 + len = write(self->dev_fd, dev_cmd_skb_priority_0, sizeof(dev_cmd_skb_priority_0)); 643 + EXPECT_EQ(len, sizeof(dev_cmd_skb_priority_0)); 644 + } 645 + 646 + TEST_HARNESS_MAIN