setsockopt-closed.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Author: Dmitry Safonov <dima@arista.com> */
  3. #include <inttypes.h>
  4. #include "../../../../include/linux/kernel.h"
  5. #include "aolib.h"
  6. static union tcp_addr tcp_md5_client;
  7. #define FILTER_TEST_NKEYS 16
  8. static int test_port = 7788;
  9. static void make_listen(int sk)
  10. {
  11. sockaddr_af addr;
  12. tcp_addr_to_sockaddr_in(&addr, &this_ip_addr, htons(test_port++));
  13. if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0)
  14. test_error("bind()");
  15. if (listen(sk, 1))
  16. test_error("listen()");
  17. }
  18. static void test_vefify_ao_info(int sk, struct tcp_ao_info_opt *info,
  19. const char *tst)
  20. {
  21. struct tcp_ao_info_opt tmp = {};
  22. socklen_t len = sizeof(tmp);
  23. if (getsockopt(sk, IPPROTO_TCP, TCP_AO_INFO, &tmp, &len))
  24. test_error("getsockopt(TCP_AO_INFO) failed");
  25. #define __cmp_ao(member) \
  26. do { \
  27. if (info->member != tmp.member) { \
  28. test_fail("%s: getsockopt(): " __stringify(member) " %" PRIu64 " != %" PRIu64, \
  29. tst, (uint64_t)info->member, (uint64_t)tmp.member); \
  30. return; \
  31. } \
  32. } while(0)
  33. if (info->set_current)
  34. __cmp_ao(current_key);
  35. if (info->set_rnext)
  36. __cmp_ao(rnext);
  37. if (info->set_counters) {
  38. __cmp_ao(pkt_good);
  39. __cmp_ao(pkt_bad);
  40. __cmp_ao(pkt_key_not_found);
  41. __cmp_ao(pkt_ao_required);
  42. __cmp_ao(pkt_dropped_icmp);
  43. }
  44. __cmp_ao(ao_required);
  45. __cmp_ao(accept_icmps);
  46. test_ok("AO info get: %s", tst);
  47. #undef __cmp_ao
  48. }
  49. static void __setsockopt_checked(int sk, int optname, bool get,
  50. void *optval, socklen_t *len,
  51. int err, const char *tst, const char *tst2)
  52. {
  53. int ret;
  54. if (!tst)
  55. tst = "";
  56. if (!tst2)
  57. tst2 = "";
  58. errno = 0;
  59. if (get)
  60. ret = getsockopt(sk, IPPROTO_TCP, optname, optval, len);
  61. else
  62. ret = setsockopt(sk, IPPROTO_TCP, optname, optval, *len);
  63. if (ret == -1) {
  64. if (errno == err)
  65. test_ok("%s%s", tst ?: "", tst2 ?: "");
  66. else
  67. test_fail("%s%s: %setsockopt() failed",
  68. tst, tst2, get ? "g" : "s");
  69. close(sk);
  70. return;
  71. }
  72. if (err) {
  73. test_fail("%s%s: %setsockopt() was expected to fail with %d",
  74. tst, tst2, get ? "g" : "s", err);
  75. } else {
  76. test_ok("%s%s", tst ?: "", tst2 ?: "");
  77. if (optname == TCP_AO_ADD_KEY) {
  78. test_verify_socket_key(sk, optval);
  79. } else if (optname == TCP_AO_INFO && !get) {
  80. test_vefify_ao_info(sk, optval, tst2);
  81. } else if (optname == TCP_AO_GET_KEYS) {
  82. if (*len != sizeof(struct tcp_ao_getsockopt))
  83. test_fail("%s%s: get keys returned wrong tcp_ao_getsockopt size",
  84. tst, tst2);
  85. }
  86. }
  87. close(sk);
  88. }
  89. static void setsockopt_checked(int sk, int optname, void *optval,
  90. int err, const char *tst)
  91. {
  92. const char *cmd = NULL;
  93. socklen_t len;
  94. switch (optname) {
  95. case TCP_AO_ADD_KEY:
  96. cmd = "key add: ";
  97. len = sizeof(struct tcp_ao_add);
  98. break;
  99. case TCP_AO_DEL_KEY:
  100. cmd = "key del: ";
  101. len = sizeof(struct tcp_ao_del);
  102. break;
  103. case TCP_AO_INFO:
  104. cmd = "AO info set: ";
  105. len = sizeof(struct tcp_ao_info_opt);
  106. break;
  107. default:
  108. break;
  109. }
  110. __setsockopt_checked(sk, optname, false, optval, &len, err, cmd, tst);
  111. }
  112. static int prepare_defs(int cmd, void *optval)
  113. {
  114. int sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
  115. if (sk < 0)
  116. test_error("socket()");
  117. switch (cmd) {
  118. case TCP_AO_ADD_KEY: {
  119. struct tcp_ao_add *add = optval;
  120. if (test_prepare_def_key(add, DEFAULT_TEST_PASSWORD, 0, this_ip_dest,
  121. -1, 0, 100, 100))
  122. test_error("prepare default tcp_ao_add");
  123. break;
  124. }
  125. case TCP_AO_DEL_KEY: {
  126. struct tcp_ao_del *del = optval;
  127. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
  128. DEFAULT_TEST_PREFIX, 100, 100))
  129. test_error("add default key");
  130. memset(del, 0, sizeof(struct tcp_ao_del));
  131. del->sndid = 100;
  132. del->rcvid = 100;
  133. del->prefix = DEFAULT_TEST_PREFIX;
  134. tcp_addr_to_sockaddr_in(&del->addr, &this_ip_dest, 0);
  135. break;
  136. }
  137. case TCP_AO_INFO: {
  138. struct tcp_ao_info_opt *info = optval;
  139. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
  140. DEFAULT_TEST_PREFIX, 100, 100))
  141. test_error("add default key");
  142. memset(info, 0, sizeof(struct tcp_ao_info_opt));
  143. break;
  144. }
  145. case TCP_AO_GET_KEYS: {
  146. struct tcp_ao_getsockopt *get = optval;
  147. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest,
  148. DEFAULT_TEST_PREFIX, 100, 100))
  149. test_error("add default key");
  150. memset(get, 0, sizeof(struct tcp_ao_getsockopt));
  151. get->nkeys = 1;
  152. get->get_all = 1;
  153. break;
  154. }
  155. default:
  156. test_error("unknown cmd");
  157. }
  158. return sk;
  159. }
  160. static void test_extend(int cmd, bool get, const char *tst, socklen_t under_size)
  161. {
  162. struct {
  163. union {
  164. struct tcp_ao_add add;
  165. struct tcp_ao_del del;
  166. struct tcp_ao_getsockopt get;
  167. struct tcp_ao_info_opt info;
  168. };
  169. char *extend[100];
  170. } tmp_opt;
  171. socklen_t extended_size = sizeof(tmp_opt);
  172. int sk;
  173. memset(&tmp_opt, 0, sizeof(tmp_opt));
  174. sk = prepare_defs(cmd, &tmp_opt);
  175. __setsockopt_checked(sk, cmd, get, &tmp_opt, &under_size,
  176. EINVAL, tst, ": minimum size");
  177. memset(&tmp_opt, 0, sizeof(tmp_opt));
  178. sk = prepare_defs(cmd, &tmp_opt);
  179. __setsockopt_checked(sk, cmd, get, &tmp_opt, &extended_size,
  180. 0, tst, ": extended size");
  181. memset(&tmp_opt, 0, sizeof(tmp_opt));
  182. sk = prepare_defs(cmd, &tmp_opt);
  183. __setsockopt_checked(sk, cmd, get, NULL, &extended_size,
  184. EFAULT, tst, ": null optval");
  185. if (get) {
  186. memset(&tmp_opt, 0, sizeof(tmp_opt));
  187. sk = prepare_defs(cmd, &tmp_opt);
  188. __setsockopt_checked(sk, cmd, get, &tmp_opt, NULL,
  189. EFAULT, tst, ": null optlen");
  190. }
  191. }
  192. static void extend_tests(void)
  193. {
  194. test_extend(TCP_AO_ADD_KEY, false, "AO add",
  195. offsetof(struct tcp_ao_add, key));
  196. test_extend(TCP_AO_DEL_KEY, false, "AO del",
  197. offsetof(struct tcp_ao_del, keyflags));
  198. test_extend(TCP_AO_INFO, false, "AO set info",
  199. offsetof(struct tcp_ao_info_opt, pkt_dropped_icmp));
  200. test_extend(TCP_AO_INFO, true, "AO get info", -1);
  201. test_extend(TCP_AO_GET_KEYS, true, "AO get keys", -1);
  202. }
  203. static void test_optmem_limit(void)
  204. {
  205. size_t i, keys_limit, current_optmem = test_get_optmem();
  206. struct tcp_ao_add ao;
  207. union tcp_addr net = {};
  208. int sk;
  209. if (inet_pton(TEST_FAMILY, TEST_NETWORK, &net) != 1)
  210. test_error("Can't convert ip address %s", TEST_NETWORK);
  211. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  212. keys_limit = current_optmem / KERNEL_TCP_AO_KEY_SZ_ROUND_UP;
  213. for (i = 0;; i++) {
  214. union tcp_addr key_peer;
  215. int err;
  216. key_peer = gen_tcp_addr(net, i + 1);
  217. tcp_addr_to_sockaddr_in(&ao.addr, &key_peer, 0);
  218. err = setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY,
  219. &ao, sizeof(ao));
  220. if (!err) {
  221. /*
  222. * TCP_AO_ADD_KEY should be the same order as the real
  223. * sizeof(struct tcp_ao_key) in kernel.
  224. */
  225. if (i <= keys_limit * 10)
  226. continue;
  227. test_fail("optmem limit test failed: added %zu key", i);
  228. break;
  229. }
  230. if (i < keys_limit) {
  231. test_fail("optmem limit test failed: couldn't add %zu key", i);
  232. break;
  233. }
  234. test_ok("optmem limit was hit on adding %zu key", i);
  235. break;
  236. }
  237. close(sk);
  238. }
  239. static void test_einval_add_key(void)
  240. {
  241. struct tcp_ao_add ao;
  242. int sk;
  243. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  244. ao.keylen = TCP_AO_MAXKEYLEN + 1;
  245. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big keylen");
  246. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  247. ao.reserved = 1;
  248. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved padding");
  249. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  250. ao.reserved2 = 1;
  251. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "using reserved2 padding");
  252. /* tcp_ao_verify_ipv{4,6}() checks */
  253. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  254. ao.addr.ss_family = AF_UNIX;
  255. memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  256. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "wrong address family");
  257. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  258. tcp_addr_to_sockaddr_in(&ao.addr, &this_ip_dest, 1234);
  259. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "port (unsupported)");
  260. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  261. ao.prefix = 0;
  262. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "no prefix, addr");
  263. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  264. ao.prefix = 0;
  265. memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  266. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "no prefix, any addr");
  267. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  268. ao.prefix = 32;
  269. memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  270. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "prefix, any addr");
  271. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  272. ao.prefix = 129;
  273. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too big prefix");
  274. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  275. ao.prefix = 2;
  276. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "too short prefix");
  277. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  278. ao.keyflags = (uint8_t)(-1);
  279. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "bad key flags");
  280. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  281. make_listen(sk);
  282. ao.set_current = 1;
  283. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current key on a listen socket");
  284. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  285. make_listen(sk);
  286. ao.set_rnext = 1;
  287. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add rnext key on a listen socket");
  288. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  289. make_listen(sk);
  290. ao.set_current = 1;
  291. ao.set_rnext = 1;
  292. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "add current+rnext key on a listen socket");
  293. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  294. ao.set_current = 1;
  295. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current");
  296. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  297. ao.set_rnext = 1;
  298. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as rnext");
  299. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  300. ao.set_current = 1;
  301. ao.set_rnext = 1;
  302. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, 0, "add key and set as current+rnext");
  303. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  304. ao.ifindex = 42;
  305. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL,
  306. "ifindex without TCP_AO_KEYF_IFNINDEX");
  307. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  308. ao.keyflags |= TCP_AO_KEYF_IFINDEX;
  309. ao.ifindex = 42;
  310. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EINVAL, "non-existent VRF");
  311. /*
  312. * tcp_md5_do_lookup{,_any_l3index}() are checked in unsigned-md5
  313. * see client_vrf_tests().
  314. */
  315. test_optmem_limit();
  316. /* tcp_ao_parse_crypto() */
  317. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  318. ao.maclen = 100;
  319. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EMSGSIZE, "maclen bigger than TCP hdr");
  320. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  321. strcpy(ao.alg_name, "imaginary hash algo");
  322. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, ENOENT, "bad algo");
  323. }
  324. static void test_einval_del_key(void)
  325. {
  326. struct tcp_ao_del del;
  327. int sk;
  328. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  329. del.reserved = 1;
  330. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved padding");
  331. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  332. del.reserved2 = 1;
  333. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "using reserved2 padding");
  334. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  335. make_listen(sk);
  336. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  337. test_error("add key");
  338. del.set_current = 1;
  339. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current key on a listen socket");
  340. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  341. make_listen(sk);
  342. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  343. test_error("add key");
  344. del.set_rnext = 1;
  345. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set rnext key on a listen socket");
  346. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  347. make_listen(sk);
  348. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  349. test_error("add key");
  350. del.set_current = 1;
  351. del.set_rnext = 1;
  352. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "del and set current+rnext key on a listen socket");
  353. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  354. del.keyflags = (uint8_t)(-1);
  355. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "bad key flags");
  356. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  357. del.ifindex = 42;
  358. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL,
  359. "ifindex without TCP_AO_KEYF_IFNINDEX");
  360. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  361. del.keyflags |= TCP_AO_KEYF_IFINDEX;
  362. del.ifindex = 42;
  363. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existent VRF");
  364. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  365. del.set_current = 1;
  366. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current key");
  367. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  368. del.set_rnext = 1;
  369. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing rnext key");
  370. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  371. del.set_current = 1;
  372. del.set_rnext = 1;
  373. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set non-existing current+rnext key");
  374. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  375. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  376. test_error("add key");
  377. del.set_current = 1;
  378. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current key");
  379. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  380. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  381. test_error("add key");
  382. del.set_rnext = 1;
  383. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set rnext key");
  384. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  385. if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, DEFAULT_TEST_PREFIX, 0, 0))
  386. test_error("add key");
  387. del.set_current = 1;
  388. del.set_rnext = 1;
  389. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "set current+rnext key");
  390. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  391. del.set_current = 1;
  392. del.current_key = 100;
  393. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current key to be removed");
  394. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  395. del.set_rnext = 1;
  396. del.rnext = 100;
  397. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as rnext key to be removed");
  398. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  399. del.set_current = 1;
  400. del.current_key = 100;
  401. del.set_rnext = 1;
  402. del.rnext = 100;
  403. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "set as current+rnext key to be removed");
  404. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  405. del.del_async = 1;
  406. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, EINVAL, "async on non-listen");
  407. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  408. del.sndid = 101;
  409. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing sndid");
  410. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  411. del.rcvid = 101;
  412. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "non-existing rcvid");
  413. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  414. tcp_addr_to_sockaddr_in(&del.addr, &this_ip_addr, 0);
  415. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, ENOENT, "incorrect addr");
  416. sk = prepare_defs(TCP_AO_DEL_KEY, &del);
  417. setsockopt_checked(sk, TCP_AO_DEL_KEY, &del, 0, "correct key delete");
  418. }
  419. static void test_einval_ao_info(void)
  420. {
  421. struct tcp_ao_info_opt info;
  422. int sk;
  423. sk = prepare_defs(TCP_AO_INFO, &info);
  424. make_listen(sk);
  425. info.set_current = 1;
  426. setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current key on a listen socket");
  427. sk = prepare_defs(TCP_AO_INFO, &info);
  428. make_listen(sk);
  429. info.set_rnext = 1;
  430. setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set rnext key on a listen socket");
  431. sk = prepare_defs(TCP_AO_INFO, &info);
  432. make_listen(sk);
  433. info.set_current = 1;
  434. info.set_rnext = 1;
  435. setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "set current+rnext key on a listen socket");
  436. sk = prepare_defs(TCP_AO_INFO, &info);
  437. info.reserved = 1;
  438. setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved padding");
  439. sk = prepare_defs(TCP_AO_INFO, &info);
  440. info.reserved2 = 1;
  441. setsockopt_checked(sk, TCP_AO_INFO, &info, EINVAL, "using reserved2 padding");
  442. sk = prepare_defs(TCP_AO_INFO, &info);
  443. info.accept_icmps = 1;
  444. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "accept_icmps");
  445. sk = prepare_defs(TCP_AO_INFO, &info);
  446. info.ao_required = 1;
  447. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "ao required");
  448. if (!should_skip_test("ao required with MD5 key", KCONFIG_TCP_MD5)) {
  449. sk = prepare_defs(TCP_AO_INFO, &info);
  450. info.ao_required = 1;
  451. if (test_set_md5(sk, tcp_md5_client, TEST_PREFIX, -1,
  452. "long long secret")) {
  453. test_error("setsockopt(TCP_MD5SIG_EXT)");
  454. close(sk);
  455. } else {
  456. setsockopt_checked(sk, TCP_AO_INFO, &info, EKEYREJECTED,
  457. "ao required with MD5 key");
  458. }
  459. }
  460. sk = prepare_defs(TCP_AO_INFO, &info);
  461. info.set_current = 1;
  462. setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current key");
  463. sk = prepare_defs(TCP_AO_INFO, &info);
  464. info.set_rnext = 1;
  465. setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing rnext key");
  466. sk = prepare_defs(TCP_AO_INFO, &info);
  467. info.set_current = 1;
  468. info.set_rnext = 1;
  469. setsockopt_checked(sk, TCP_AO_INFO, &info, ENOENT, "set non-existing current+rnext key");
  470. sk = prepare_defs(TCP_AO_INFO, &info);
  471. info.set_current = 1;
  472. info.current_key = 100;
  473. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current key");
  474. sk = prepare_defs(TCP_AO_INFO, &info);
  475. info.set_rnext = 1;
  476. info.rnext = 100;
  477. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set rnext key");
  478. sk = prepare_defs(TCP_AO_INFO, &info);
  479. info.set_current = 1;
  480. info.set_rnext = 1;
  481. info.current_key = 100;
  482. info.rnext = 100;
  483. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set current+rnext key");
  484. sk = prepare_defs(TCP_AO_INFO, &info);
  485. info.set_counters = 1;
  486. info.pkt_good = 321;
  487. info.pkt_bad = 888;
  488. info.pkt_key_not_found = 654;
  489. info.pkt_ao_required = 987654;
  490. info.pkt_dropped_icmp = 10000;
  491. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "set counters");
  492. sk = prepare_defs(TCP_AO_INFO, &info);
  493. setsockopt_checked(sk, TCP_AO_INFO, &info, 0, "no-op");
  494. }
  495. static void getsockopt_checked(int sk, struct tcp_ao_getsockopt *optval,
  496. int err, const char *tst)
  497. {
  498. socklen_t len = sizeof(struct tcp_ao_getsockopt);
  499. __setsockopt_checked(sk, TCP_AO_GET_KEYS, true, optval, &len, err,
  500. "get keys: ", tst);
  501. }
  502. static void test_einval_get_keys(void)
  503. {
  504. struct tcp_ao_getsockopt out;
  505. int sk;
  506. sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
  507. if (sk < 0)
  508. test_error("socket()");
  509. getsockopt_checked(sk, &out, ENOENT, "no ao_info");
  510. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  511. getsockopt_checked(sk, &out, 0, "proper tcp_ao_get_mkts()");
  512. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  513. out.pkt_good = 643;
  514. getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_good counter");
  515. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  516. out.pkt_bad = 94;
  517. getsockopt_checked(sk, &out, EINVAL, "set out-only pkt_bad counter");
  518. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  519. out.keyflags = (uint8_t)(-1);
  520. getsockopt_checked(sk, &out, EINVAL, "bad keyflags");
  521. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  522. out.ifindex = 42;
  523. getsockopt_checked(sk, &out, EINVAL,
  524. "ifindex without TCP_AO_KEYF_IFNINDEX");
  525. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  526. out.reserved = 1;
  527. getsockopt_checked(sk, &out, EINVAL, "using reserved field");
  528. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  529. out.get_all = 0;
  530. out.prefix = 0;
  531. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  532. getsockopt_checked(sk, &out, EINVAL, "no prefix, addr");
  533. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  534. out.get_all = 0;
  535. out.prefix = 0;
  536. memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  537. getsockopt_checked(sk, &out, 0, "no prefix, any addr");
  538. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  539. out.get_all = 0;
  540. out.prefix = 32;
  541. memcpy(&out.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  542. getsockopt_checked(sk, &out, EINVAL, "prefix, any addr");
  543. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  544. out.get_all = 0;
  545. out.prefix = 129;
  546. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  547. getsockopt_checked(sk, &out, EINVAL, "too big prefix");
  548. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  549. out.get_all = 0;
  550. out.prefix = 2;
  551. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  552. getsockopt_checked(sk, &out, EINVAL, "too short prefix");
  553. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  554. out.get_all = 0;
  555. out.prefix = DEFAULT_TEST_PREFIX;
  556. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  557. getsockopt_checked(sk, &out, 0, "prefix + addr");
  558. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  559. out.get_all = 1;
  560. out.prefix = DEFAULT_TEST_PREFIX;
  561. getsockopt_checked(sk, &out, EINVAL, "get_all + prefix");
  562. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  563. out.get_all = 1;
  564. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  565. getsockopt_checked(sk, &out, EINVAL, "get_all + addr");
  566. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  567. out.get_all = 1;
  568. out.sndid = 1;
  569. getsockopt_checked(sk, &out, EINVAL, "get_all + sndid");
  570. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  571. out.get_all = 1;
  572. out.rcvid = 1;
  573. getsockopt_checked(sk, &out, EINVAL, "get_all + rcvid");
  574. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  575. out.get_all = 0;
  576. out.is_current = 1;
  577. out.prefix = DEFAULT_TEST_PREFIX;
  578. getsockopt_checked(sk, &out, EINVAL, "current + prefix");
  579. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  580. out.get_all = 0;
  581. out.is_current = 1;
  582. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  583. getsockopt_checked(sk, &out, EINVAL, "current + addr");
  584. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  585. out.get_all = 0;
  586. out.is_current = 1;
  587. out.sndid = 1;
  588. getsockopt_checked(sk, &out, EINVAL, "current + sndid");
  589. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  590. out.get_all = 0;
  591. out.is_current = 1;
  592. out.rcvid = 1;
  593. getsockopt_checked(sk, &out, EINVAL, "current + rcvid");
  594. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  595. out.get_all = 0;
  596. out.is_rnext = 1;
  597. out.prefix = DEFAULT_TEST_PREFIX;
  598. getsockopt_checked(sk, &out, EINVAL, "rnext + prefix");
  599. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  600. out.get_all = 0;
  601. out.is_rnext = 1;
  602. tcp_addr_to_sockaddr_in(&out.addr, &this_ip_dest, 0);
  603. getsockopt_checked(sk, &out, EINVAL, "rnext + addr");
  604. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  605. out.get_all = 0;
  606. out.is_rnext = 1;
  607. out.sndid = 1;
  608. getsockopt_checked(sk, &out, EINVAL, "rnext + sndid");
  609. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  610. out.get_all = 0;
  611. out.is_rnext = 1;
  612. out.rcvid = 1;
  613. getsockopt_checked(sk, &out, EINVAL, "rnext + rcvid");
  614. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  615. out.get_all = 1;
  616. out.is_current = 1;
  617. getsockopt_checked(sk, &out, EINVAL, "get_all + current");
  618. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  619. out.get_all = 1;
  620. out.is_rnext = 1;
  621. getsockopt_checked(sk, &out, EINVAL, "get_all + rnext");
  622. sk = prepare_defs(TCP_AO_GET_KEYS, &out);
  623. out.get_all = 0;
  624. out.is_current = 1;
  625. out.is_rnext = 1;
  626. getsockopt_checked(sk, &out, 0, "current + rnext");
  627. }
  628. static void einval_tests(void)
  629. {
  630. test_einval_add_key();
  631. test_einval_del_key();
  632. test_einval_ao_info();
  633. test_einval_get_keys();
  634. }
  635. static void duplicate_tests(void)
  636. {
  637. union tcp_addr network_dup;
  638. struct tcp_ao_add ao, ao2;
  639. int sk;
  640. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  641. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  642. test_error("setsockopt()");
  643. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy");
  644. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  645. ao2 = ao;
  646. memcpy(&ao2.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  647. ao2.prefix = 0;
  648. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao2, sizeof(ao)))
  649. test_error("setsockopt()");
  650. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: any addr key on the socket");
  651. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  652. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  653. test_error("setsockopt()");
  654. memcpy(&ao.addr, &SOCKADDR_ANY, sizeof(SOCKADDR_ANY));
  655. ao.prefix = 0;
  656. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr key");
  657. if (inet_pton(TEST_FAMILY, TEST_NETWORK, &network_dup) != 1)
  658. test_error("Can't convert ip address %s", TEST_NETWORK);
  659. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  660. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  661. test_error("setsockopt()");
  662. if (test_prepare_def_key(&ao, "password", 0, network_dup,
  663. 16, 0, 100, 100))
  664. test_error("prepare default tcp_ao_add");
  665. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: add any addr for the same subnet");
  666. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  667. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  668. test_error("setsockopt()");
  669. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: full copy of a key");
  670. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  671. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  672. test_error("setsockopt()");
  673. ao.rcvid = 101;
  674. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: RecvID differs");
  675. sk = prepare_defs(TCP_AO_ADD_KEY, &ao);
  676. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &ao, sizeof(ao)))
  677. test_error("setsockopt()");
  678. ao.sndid = 101;
  679. setsockopt_checked(sk, TCP_AO_ADD_KEY, &ao, EEXIST, "duplicate: SendID differs");
  680. }
  681. static void fetch_all_keys(int sk, struct tcp_ao_getsockopt *keys)
  682. {
  683. socklen_t optlen = sizeof(struct tcp_ao_getsockopt);
  684. memset(keys, 0, sizeof(struct tcp_ao_getsockopt) * FILTER_TEST_NKEYS);
  685. keys[0].get_all = 1;
  686. keys[0].nkeys = FILTER_TEST_NKEYS;
  687. if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, &keys[0], &optlen))
  688. test_error("getsockopt");
  689. }
  690. static int prepare_test_keys(struct tcp_ao_getsockopt *keys)
  691. {
  692. const char *test_password = "Test password number ";
  693. struct tcp_ao_add test_ao[FILTER_TEST_NKEYS];
  694. char test_password_scratch[64] = {};
  695. u8 rcvid = 100, sndid = 100;
  696. int sk;
  697. sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
  698. if (sk < 0)
  699. test_error("socket()");
  700. for (int i = 0; i < FILTER_TEST_NKEYS; i++) {
  701. snprintf(test_password_scratch, 64, "%s %d", test_password, i);
  702. test_prepare_key(&test_ao[i], DEFAULT_TEST_ALGO, this_ip_dest,
  703. false, false, DEFAULT_TEST_PREFIX, 0, sndid++,
  704. rcvid++, 0, 0, strlen(test_password_scratch),
  705. test_password_scratch);
  706. }
  707. test_ao[0].set_current = 1;
  708. test_ao[1].set_rnext = 1;
  709. /* One key with a different addr and overlapping sndid, rcvid */
  710. tcp_addr_to_sockaddr_in(&test_ao[2].addr, &this_ip_addr, 0);
  711. test_ao[2].sndid = 100;
  712. test_ao[2].rcvid = 100;
  713. /* Add keys in a random order */
  714. for (int i = 0; i < FILTER_TEST_NKEYS; i++) {
  715. int randidx = rand() % (FILTER_TEST_NKEYS - i);
  716. if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY,
  717. &test_ao[randidx], sizeof(struct tcp_ao_add)))
  718. test_error("setsockopt()");
  719. memcpy(&test_ao[randidx], &test_ao[FILTER_TEST_NKEYS - 1 - i],
  720. sizeof(struct tcp_ao_add));
  721. }
  722. fetch_all_keys(sk, keys);
  723. return sk;
  724. }
  725. /* Assumes passwords are unique */
  726. static int compare_mkts(struct tcp_ao_getsockopt *expected, int nexpected,
  727. struct tcp_ao_getsockopt *actual, int nactual)
  728. {
  729. int matches = 0;
  730. for (int i = 0; i < nexpected; i++) {
  731. for (int j = 0; j < nactual; j++) {
  732. if (memcmp(expected[i].key, actual[j].key,
  733. TCP_AO_MAXKEYLEN) == 0)
  734. matches++;
  735. }
  736. }
  737. return nexpected - matches;
  738. }
  739. static void filter_keys_checked(int sk, struct tcp_ao_getsockopt *filter,
  740. struct tcp_ao_getsockopt *expected,
  741. unsigned int nexpected, const char *tst)
  742. {
  743. struct tcp_ao_getsockopt filtered_keys[FILTER_TEST_NKEYS] = {};
  744. struct tcp_ao_getsockopt all_keys[FILTER_TEST_NKEYS] = {};
  745. socklen_t len = sizeof(struct tcp_ao_getsockopt);
  746. fetch_all_keys(sk, all_keys);
  747. memcpy(&filtered_keys[0], filter, sizeof(struct tcp_ao_getsockopt));
  748. filtered_keys[0].nkeys = FILTER_TEST_NKEYS;
  749. if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, filtered_keys, &len))
  750. test_error("getsockopt");
  751. if (filtered_keys[0].nkeys != nexpected) {
  752. test_fail("wrong nr of keys, expected %u got %u", nexpected,
  753. filtered_keys[0].nkeys);
  754. goto out_close;
  755. }
  756. if (compare_mkts(expected, nexpected, filtered_keys,
  757. filtered_keys[0].nkeys)) {
  758. test_fail("got wrong keys back");
  759. goto out_close;
  760. }
  761. test_ok("filter keys: %s", tst);
  762. out_close:
  763. close(sk);
  764. memset(filter, 0, sizeof(struct tcp_ao_getsockopt));
  765. }
  766. static void filter_tests(void)
  767. {
  768. struct tcp_ao_getsockopt original_keys[FILTER_TEST_NKEYS];
  769. struct tcp_ao_getsockopt expected_keys[FILTER_TEST_NKEYS];
  770. struct tcp_ao_getsockopt filter = {};
  771. int sk, f, nmatches;
  772. socklen_t len;
  773. f = 2;
  774. sk = prepare_test_keys(original_keys);
  775. filter.rcvid = original_keys[f].rcvid;
  776. filter.sndid = original_keys[f].sndid;
  777. memcpy(&filter.addr, &original_keys[f].addr,
  778. sizeof(original_keys[f].addr));
  779. filter.prefix = original_keys[f].prefix;
  780. filter_keys_checked(sk, &filter, &original_keys[f], 1,
  781. "by sndid, rcvid, address");
  782. f = -1;
  783. sk = prepare_test_keys(original_keys);
  784. for (int i = 0; i < original_keys[0].nkeys; i++) {
  785. if (original_keys[i].is_current) {
  786. f = i;
  787. break;
  788. }
  789. }
  790. if (f < 0)
  791. test_error("No current key after adding one");
  792. filter.is_current = 1;
  793. filter_keys_checked(sk, &filter, &original_keys[f], 1, "by is_current");
  794. f = -1;
  795. sk = prepare_test_keys(original_keys);
  796. for (int i = 0; i < original_keys[0].nkeys; i++) {
  797. if (original_keys[i].is_rnext) {
  798. f = i;
  799. break;
  800. }
  801. }
  802. if (f < 0)
  803. test_error("No rnext key after adding one");
  804. filter.is_rnext = 1;
  805. filter_keys_checked(sk, &filter, &original_keys[f], 1, "by is_rnext");
  806. f = -1;
  807. nmatches = 0;
  808. sk = prepare_test_keys(original_keys);
  809. for (int i = 0; i < original_keys[0].nkeys; i++) {
  810. if (original_keys[i].sndid == 100) {
  811. f = i;
  812. memcpy(&expected_keys[nmatches], &original_keys[i],
  813. sizeof(struct tcp_ao_getsockopt));
  814. nmatches++;
  815. }
  816. }
  817. if (f < 0)
  818. test_error("No key for sndid 100");
  819. if (nmatches != 2)
  820. test_error("Should have 2 keys with sndid 100");
  821. filter.rcvid = original_keys[f].rcvid;
  822. filter.sndid = original_keys[f].sndid;
  823. filter.addr.ss_family = test_family;
  824. filter_keys_checked(sk, &filter, expected_keys, nmatches,
  825. "by sndid, rcvid");
  826. sk = prepare_test_keys(original_keys);
  827. filter.get_all = 1;
  828. filter.nkeys = FILTER_TEST_NKEYS / 2;
  829. len = sizeof(struct tcp_ao_getsockopt);
  830. if (getsockopt(sk, IPPROTO_TCP, TCP_AO_GET_KEYS, &filter, &len))
  831. test_error("getsockopt");
  832. if (filter.nkeys == FILTER_TEST_NKEYS)
  833. test_ok("filter keys: correct nkeys when in.nkeys < matches");
  834. else
  835. test_fail("filter keys: wrong nkeys, expected %u got %u",
  836. FILTER_TEST_NKEYS, filter.nkeys);
  837. }
  838. static void *client_fn(void *arg)
  839. {
  840. if (inet_pton(TEST_FAMILY, __TEST_CLIENT_IP(2), &tcp_md5_client) != 1)
  841. test_error("Can't convert ip address");
  842. extend_tests();
  843. einval_tests();
  844. filter_tests();
  845. duplicate_tests();
  846. return NULL;
  847. }
  848. int main(int argc, char *argv[])
  849. {
  850. test_init(126, client_fn, NULL);
  851. return 0;
  852. }