/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- wrepl_name_type_string
- wrepl_name_state_string
- test_assoc_ctx1
- test_assoc_ctx2
- display_entry
- test_wins_replication
- test_create_conflict_ctx
- test_wrepl_update_one
- test_wrepl_is_applied
- test_wrepl_mhomed_merged
- test_wrepl_sgroup_merged
- test_conflict_same_owner
- test_conflict_different_owner
- test_conflict_owned_released_vs_replica
- test_conflict_owned_active_vs_replica
- test_conflict_owned_active_vs_replica_handler_query
- test_conflict_owned_active_vs_replica_handler_release
- test_conflict_owned_active_vs_replica_handler
- torture_nbt_winsreplication_replica
- torture_nbt_winsreplication_owned
- torture_nbt_winsreplication
1 /*
2 Unix SMB/CIFS implementation.
3
4 WINS replication testing
5
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Stefan Metzmacher 2005
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "libcli/wrepl/winsrepl.h"
25 #include "lib/events/events.h"
26 #include "lib/socket/socket.h"
27 #include "libcli/resolve/resolve.h"
28 #include "system/network.h"
29 #include "lib/socket/netif.h"
30 #include "librpc/gen_ndr/ndr_nbt.h"
31 #include "torture/torture.h"
32 #include "torture/nbt/proto.h"
33 #include "param/param.h"
34
35 #define CHECK_STATUS(tctx, status, correct) \
36 torture_assert_ntstatus_equal(tctx, status, correct, \
37 "Incorrect status")
38
39 #define CHECK_VALUE(tctx, v, correct) \
40 torture_assert(tctx, (v) == (correct), \
41 talloc_asprintf(tctx, "Incorrect value %s=%d - should be %d\n", \
42 #v, v, correct))
43
44 #define CHECK_VALUE_UINT64(tctx, v, correct) \
45 torture_assert(tctx, (v) == (correct), \
46 talloc_asprintf(tctx, "Incorrect value %s=%llu - should be %llu\n", \
47 #v, (long long)v, (long long)correct))
48
49 #define CHECK_VALUE_STRING(tctx, v, correct) \
50 torture_assert_str_equal(tctx, v, correct, "Invalid value")
51
52 #define _NBT_NAME(n,t,s) {\
53 .name = n,\
54 .type = t,\
55 .scope = s\
56 }
57
58 static const char *wrepl_name_type_string(enum wrepl_name_type type)
/* [<][>][^][v][top][bottom][index][help] */
59 {
60 switch (type) {
61 case WREPL_TYPE_UNIQUE: return "UNIQUE";
62 case WREPL_TYPE_GROUP: return "GROUP";
63 case WREPL_TYPE_SGROUP: return "SGROUP";
64 case WREPL_TYPE_MHOMED: return "MHOMED";
65 }
66 return "UNKNOWN_TYPE";
67 }
68
69 static const char *wrepl_name_state_string(enum wrepl_name_state state)
/* [<][>][^][v][top][bottom][index][help] */
70 {
71 switch (state) {
72 case WREPL_STATE_ACTIVE: return "ACTIVE";
73 case WREPL_STATE_RELEASED: return "RELEASED";
74 case WREPL_STATE_TOMBSTONE: return "TOMBSTONE";
75 case WREPL_STATE_RESERVED: return "RESERVED";
76 }
77 return "UNKNOWN_STATE";
78 }
79
80 /*
81 test how assoc_ctx's are only usable on the connection
82 they are created on.
83 */
84 static bool test_assoc_ctx1(struct torture_context *tctx)
/* [<][>][^][v][top][bottom][index][help] */
85 {
86 bool ret = true;
87 struct wrepl_request *req;
88 struct wrepl_socket *wrepl_socket1;
89 struct wrepl_associate associate1;
90 struct wrepl_socket *wrepl_socket2;
91 struct wrepl_associate associate2;
92 struct wrepl_pull_table pull_table;
93 struct wrepl_packet packet;
94 struct wrepl_send_ctrl ctrl;
95 struct wrepl_packet *rep_packet;
96 struct wrepl_associate_stop assoc_stop;
97 NTSTATUS status;
98 struct nbt_name name;
99 const char *address;
100
101 if (!torture_nbt_get_name(tctx, &name, &address))
102 return false;
103
104 torture_comment(tctx, "Test if assoc_ctx is only valid on the conection it was created on\n");
105
106 wrepl_socket1 = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
107 wrepl_socket2 = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
108
109 torture_comment(tctx, "Setup 2 wrepl connections\n");
110 status = wrepl_connect(wrepl_socket1, wrepl_best_ip(tctx->lp_ctx, address), address);
111 CHECK_STATUS(tctx, status, NT_STATUS_OK);
112
113 status = wrepl_connect(wrepl_socket2, wrepl_best_ip(tctx->lp_ctx, address), address);
114 CHECK_STATUS(tctx, status, NT_STATUS_OK);
115
116 torture_comment(tctx, "Send a start association request (conn1)\n");
117 status = wrepl_associate(wrepl_socket1, &associate1);
118 CHECK_STATUS(tctx, status, NT_STATUS_OK);
119
120 torture_comment(tctx, "association context (conn1): 0x%x\n", associate1.out.assoc_ctx);
121
122 torture_comment(tctx, "Send a start association request (conn2)\n");
123 status = wrepl_associate(wrepl_socket2, &associate2);
124 CHECK_STATUS(tctx, status, NT_STATUS_OK);
125
126 torture_comment(tctx, "association context (conn2): 0x%x\n", associate2.out.assoc_ctx);
127
128 torture_comment(tctx, "Send a replication table query, with assoc 1 (conn2), the anwser should be on conn1\n");
129 ZERO_STRUCT(packet);
130 packet.opcode = WREPL_OPCODE_BITS;
131 packet.assoc_ctx = associate1.out.assoc_ctx;
132 packet.mess_type = WREPL_REPLICATION;
133 packet.message.replication.command = WREPL_REPL_TABLE_QUERY;
134 ZERO_STRUCT(ctrl);
135 ctrl.send_only = true;
136 req = wrepl_request_send(wrepl_socket2, &packet, &ctrl);
137 status = wrepl_request_recv(req, tctx, &rep_packet);
138 CHECK_STATUS(tctx, status, NT_STATUS_OK);
139
140 torture_comment(tctx, "Send a association request (conn2), to make sure the last request was ignored\n");
141 status = wrepl_associate(wrepl_socket2, &associate2);
142 CHECK_STATUS(tctx, status, NT_STATUS_OK);
143
144 torture_comment(tctx, "Send a replication table query, with invalid assoc (conn1), receive answer from conn2\n");
145 pull_table.in.assoc_ctx = 0;
146 req = wrepl_pull_table_send(wrepl_socket1, &pull_table);
147 status = wrepl_request_recv(req, tctx, &rep_packet);
148 CHECK_STATUS(tctx, status, NT_STATUS_OK);
149
150 torture_comment(tctx, "Send a association request (conn1), to make sure the last request was handled correct\n");
151 status = wrepl_associate(wrepl_socket1, &associate2);
152 CHECK_STATUS(tctx, status, NT_STATUS_OK);
153
154 assoc_stop.in.assoc_ctx = associate1.out.assoc_ctx;
155 assoc_stop.in.reason = 4;
156 torture_comment(tctx, "Send a association stop request (conn1), reson: %u\n", assoc_stop.in.reason);
157 status = wrepl_associate_stop(wrepl_socket1, &assoc_stop);
158 CHECK_STATUS(tctx, status, NT_STATUS_END_OF_FILE);
159
160 assoc_stop.in.assoc_ctx = associate2.out.assoc_ctx;
161 assoc_stop.in.reason = 0;
162 torture_comment(tctx, "Send a association stop request (conn2), reson: %u\n", assoc_stop.in.reason);
163 status = wrepl_associate_stop(wrepl_socket2, &assoc_stop);
164 CHECK_STATUS(tctx, status, NT_STATUS_OK);
165
166 torture_comment(tctx, "Close 2 wrepl connections\n");
167 talloc_free(wrepl_socket1);
168 talloc_free(wrepl_socket2);
169 return ret;
170 }
171
172 /*
173 test if we always get back the same assoc_ctx
174 */
175 static bool test_assoc_ctx2(struct torture_context *tctx)
/* [<][>][^][v][top][bottom][index][help] */
176 {
177 struct wrepl_socket *wrepl_socket;
178 struct wrepl_associate associate;
179 uint32_t assoc_ctx1;
180 struct nbt_name name;
181 NTSTATUS status;
182 const char *address;
183
184 if (!torture_nbt_get_name(tctx, &name, &address))
185 return false;
186
187 torture_comment(tctx, "Test if we always get back the same assoc_ctx\n");
188
189 wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
190
191 torture_comment(tctx, "Setup wrepl connections\n");
192 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
193 CHECK_STATUS(tctx, status, NT_STATUS_OK);
194
195 torture_comment(tctx, "Send 1st start association request\n");
196 status = wrepl_associate(wrepl_socket, &associate);
197 CHECK_STATUS(tctx, status, NT_STATUS_OK);
198 assoc_ctx1 = associate.out.assoc_ctx;
199 torture_comment(tctx, "1st association context: 0x%x\n", associate.out.assoc_ctx);
200
201 torture_comment(tctx, "Send 2nd start association request\n");
202 status = wrepl_associate(wrepl_socket, &associate);
203 torture_assert_ntstatus_ok(tctx, status, "2nd start association failed");
204 torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1,
205 "Different context returned");
206 torture_comment(tctx, "2nd association context: 0x%x\n", associate.out.assoc_ctx);
207
208 torture_comment(tctx, "Send 3rd start association request\n");
209 status = wrepl_associate(wrepl_socket, &associate);
210 torture_assert(tctx, associate.out.assoc_ctx == assoc_ctx1,
211 "Different context returned");
212 CHECK_STATUS(tctx, status, NT_STATUS_OK);
213 torture_comment(tctx, "3rd association context: 0x%x\n", associate.out.assoc_ctx);
214
215 torture_comment(tctx, "Close wrepl connections\n");
216 talloc_free(wrepl_socket);
217 return true;
218 }
219
220
221 /*
222 display a replication entry
223 */
224 static void display_entry(struct torture_context *tctx, struct wrepl_name *name)
/* [<][>][^][v][top][bottom][index][help] */
225 {
226 int i;
227
228 torture_comment(tctx, "%s\n", nbt_name_string(tctx, &name->name));
229 torture_comment(tctx, "\tTYPE:%u STATE:%u NODE:%u STATIC:%u VERSION_ID: %llu\n",
230 name->type, name->state, name->node, name->is_static, (long long)name->version_id);
231 torture_comment(tctx, "\tRAW_FLAGS: 0x%08X OWNER: %-15s\n",
232 name->raw_flags, name->owner);
233 for (i=0;i<name->num_addresses;i++) {
234 torture_comment(tctx, "\tADDR: %-15s OWNER: %-15s\n",
235 name->addresses[i].address, name->addresses[i].owner);
236 }
237 }
238
239 /*
240 test a full replication dump from a WINS server
241 */
242 static bool test_wins_replication(struct torture_context *tctx)
/* [<][>][^][v][top][bottom][index][help] */
243 {
244 struct wrepl_socket *wrepl_socket;
245 NTSTATUS status;
246 int i, j;
247 struct wrepl_associate associate;
248 struct wrepl_pull_table pull_table;
249 struct wrepl_pull_names pull_names;
250 struct nbt_name name;
251 const char *address;
252
253 if (!torture_nbt_get_name(tctx, &name, &address))
254 return false;
255
256 torture_comment(tctx, "Test one pull replication cycle\n");
257
258 wrepl_socket = wrepl_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
259
260 torture_comment(tctx, "Setup wrepl connections\n");
261 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, address), address);
262 CHECK_STATUS(tctx, status, NT_STATUS_OK);
263
264 torture_comment(tctx, "Send a start association request\n");
265
266 status = wrepl_associate(wrepl_socket, &associate);
267 CHECK_STATUS(tctx, status, NT_STATUS_OK);
268
269 torture_comment(tctx, "association context: 0x%x\n", associate.out.assoc_ctx);
270
271 torture_comment(tctx, "Send a replication table query\n");
272 pull_table.in.assoc_ctx = associate.out.assoc_ctx;
273
274 status = wrepl_pull_table(wrepl_socket, tctx, &pull_table);
275 if (NT_STATUS_EQUAL(NT_STATUS_NETWORK_ACCESS_DENIED,status)) {
276 struct wrepl_packet packet;
277 struct wrepl_request *req;
278
279 ZERO_STRUCT(packet);
280 packet.opcode = WREPL_OPCODE_BITS;
281 packet.assoc_ctx = associate.out.assoc_ctx;
282 packet.mess_type = WREPL_STOP_ASSOCIATION;
283 packet.message.stop.reason = 0;
284
285 req = wrepl_request_send(wrepl_socket, &packet, NULL);
286 talloc_free(req);
287
288 torture_fail(tctx, "We are not a valid pull partner for the server");
289 }
290 CHECK_STATUS(tctx, status, NT_STATUS_OK);
291
292 torture_comment(tctx, "Found %d replication partners\n", pull_table.out.num_partners);
293
294 for (i=0;i<pull_table.out.num_partners;i++) {
295 struct wrepl_wins_owner *partner = &pull_table.out.partners[i];
296 torture_comment(tctx, "%s max_version=%6llu min_version=%6llu type=%d\n",
297 partner->address,
298 (long long)partner->max_version,
299 (long long)partner->min_version,
300 partner->type);
301
302 pull_names.in.assoc_ctx = associate.out.assoc_ctx;
303 pull_names.in.partner = *partner;
304
305 status = wrepl_pull_names(wrepl_socket, tctx, &pull_names);
306 CHECK_STATUS(tctx, status, NT_STATUS_OK);
307
308 torture_comment(tctx, "Received %d names\n", pull_names.out.num_names);
309
310 for (j=0;j<pull_names.out.num_names;j++) {
311 display_entry(tctx, &pull_names.out.names[j]);
312 }
313 }
314
315 torture_comment(tctx, "Close wrepl connections\n");
316 talloc_free(wrepl_socket);
317 return true;
318 }
319
320 struct test_wrepl_conflict_conn {
321 const char *address;
322 struct wrepl_socket *pull;
323 uint32_t pull_assoc;
324
325 #define TEST_OWNER_A_ADDRESS "127.65.65.1"
326 #define TEST_ADDRESS_A_PREFIX "127.0.65"
327 #define TEST_OWNER_B_ADDRESS "127.66.66.1"
328 #define TEST_ADDRESS_B_PREFIX "127.0.66"
329 #define TEST_OWNER_X_ADDRESS "127.88.88.1"
330 #define TEST_ADDRESS_X_PREFIX "127.0.88"
331
332 struct wrepl_wins_owner a, b, c, x;
333
334 struct socket_address *myaddr;
335 struct socket_address *myaddr2;
336 struct nbt_name_socket *nbtsock;
337 struct nbt_name_socket *nbtsock2;
338
339 struct nbt_name_socket *nbtsock_srv;
340 struct nbt_name_socket *nbtsock_srv2;
341
342 uint32_t addresses_best_num;
343 struct wrepl_ip *addresses_best;
344
345 uint32_t addresses_best2_num;
346 struct wrepl_ip *addresses_best2;
347
348 uint32_t addresses_all_num;
349 struct wrepl_ip *addresses_all;
350
351 uint32_t addresses_mhomed_num;
352 struct wrepl_ip *addresses_mhomed;
353 };
354
355 static const struct wrepl_ip addresses_A_1[] = {
356 {
357 .owner = TEST_OWNER_A_ADDRESS,
358 .ip = TEST_ADDRESS_A_PREFIX".1"
359 }
360 };
361 static const struct wrepl_ip addresses_A_2[] = {
362 {
363 .owner = TEST_OWNER_A_ADDRESS,
364 .ip = TEST_ADDRESS_A_PREFIX".2"
365 }
366 };
367 static const struct wrepl_ip addresses_A_3_4[] = {
368 {
369 .owner = TEST_OWNER_A_ADDRESS,
370 .ip = TEST_ADDRESS_A_PREFIX".3"
371 },
372 {
373 .owner = TEST_OWNER_A_ADDRESS,
374 .ip = TEST_ADDRESS_A_PREFIX".4"
375 }
376 };
377 static const struct wrepl_ip addresses_A_3_4_X_3_4[] = {
378 {
379 .owner = TEST_OWNER_A_ADDRESS,
380 .ip = TEST_ADDRESS_A_PREFIX".3"
381 },
382 {
383 .owner = TEST_OWNER_A_ADDRESS,
384 .ip = TEST_ADDRESS_A_PREFIX".4"
385 },
386 {
387 .owner = TEST_OWNER_X_ADDRESS,
388 .ip = TEST_ADDRESS_X_PREFIX".3"
389 },
390 {
391 .owner = TEST_OWNER_X_ADDRESS,
392 .ip = TEST_ADDRESS_X_PREFIX".4"
393 }
394 };
395 static const struct wrepl_ip addresses_A_3_4_B_3_4[] = {
396 {
397 .owner = TEST_OWNER_A_ADDRESS,
398 .ip = TEST_ADDRESS_A_PREFIX".3"
399 },
400 {
401 .owner = TEST_OWNER_A_ADDRESS,
402 .ip = TEST_ADDRESS_A_PREFIX".4"
403 },
404 {
405 .owner = TEST_OWNER_B_ADDRESS,
406 .ip = TEST_ADDRESS_B_PREFIX".3"
407 },
408 {
409 .owner = TEST_OWNER_B_ADDRESS,
410 .ip = TEST_ADDRESS_B_PREFIX".4"
411 }
412 };
413 static const struct wrepl_ip addresses_A_3_4_OWNER_B[] = {
414 {
415 .owner = TEST_OWNER_B_ADDRESS,
416 .ip = TEST_ADDRESS_A_PREFIX".3"
417 },
418 {
419 .owner = TEST_OWNER_B_ADDRESS,
420 .ip = TEST_ADDRESS_A_PREFIX".4"
421 }
422 };
423 static const struct wrepl_ip addresses_A_3_4_X_3_4_OWNER_B[] = {
424 {
425 .owner = TEST_OWNER_B_ADDRESS,
426 .ip = TEST_ADDRESS_A_PREFIX".3"
427 },
428 {
429 .owner = TEST_OWNER_B_ADDRESS,
430 .ip = TEST_ADDRESS_A_PREFIX".4"
431 },
432 {
433 .owner = TEST_OWNER_B_ADDRESS,
434 .ip = TEST_ADDRESS_X_PREFIX".3"
435 },
436 {
437 .owner = TEST_OWNER_B_ADDRESS,
438 .ip = TEST_ADDRESS_X_PREFIX".4"
439 }
440 };
441
442 static const struct wrepl_ip addresses_A_3_4_X_1_2[] = {
443 {
444 .owner = TEST_OWNER_A_ADDRESS,
445 .ip = TEST_ADDRESS_A_PREFIX".3"
446 },
447 {
448 .owner = TEST_OWNER_A_ADDRESS,
449 .ip = TEST_ADDRESS_A_PREFIX".4"
450 },
451 {
452 .owner = TEST_OWNER_X_ADDRESS,
453 .ip = TEST_ADDRESS_X_PREFIX".1"
454 },
455 {
456 .owner = TEST_OWNER_X_ADDRESS,
457 .ip = TEST_ADDRESS_X_PREFIX".2"
458 }
459 };
460
461 static const struct wrepl_ip addresses_B_1[] = {
462 {
463 .owner = TEST_OWNER_B_ADDRESS,
464 .ip = TEST_ADDRESS_B_PREFIX".1"
465 }
466 };
467 static const struct wrepl_ip addresses_B_2[] = {
468 {
469 .owner = TEST_OWNER_B_ADDRESS,
470 .ip = TEST_ADDRESS_B_PREFIX".2"
471 }
472 };
473 static const struct wrepl_ip addresses_B_3_4[] = {
474 {
475 .owner = TEST_OWNER_B_ADDRESS,
476 .ip = TEST_ADDRESS_B_PREFIX".3"
477 },
478 {
479 .owner = TEST_OWNER_B_ADDRESS,
480 .ip = TEST_ADDRESS_B_PREFIX".4"
481 }
482 };
483 static const struct wrepl_ip addresses_B_3_4_X_3_4[] = {
484 {
485 .owner = TEST_OWNER_B_ADDRESS,
486 .ip = TEST_ADDRESS_B_PREFIX".3"
487 },
488 {
489 .owner = TEST_OWNER_B_ADDRESS,
490 .ip = TEST_ADDRESS_B_PREFIX".4"
491 },
492 {
493 .owner = TEST_OWNER_X_ADDRESS,
494 .ip = TEST_ADDRESS_X_PREFIX".3"
495 },
496 {
497 .owner = TEST_OWNER_X_ADDRESS,
498 .ip = TEST_ADDRESS_X_PREFIX".4"
499 }
500 };
501 static const struct wrepl_ip addresses_B_3_4_X_1_2[] = {
502 {
503 .owner = TEST_OWNER_B_ADDRESS,
504 .ip = TEST_ADDRESS_B_PREFIX".3"
505 },
506 {
507 .owner = TEST_OWNER_B_ADDRESS,
508 .ip = TEST_ADDRESS_B_PREFIX".4"
509 },
510 {
511 .owner = TEST_OWNER_X_ADDRESS,
512 .ip = TEST_ADDRESS_X_PREFIX".1"
513 },
514 {
515 .owner = TEST_OWNER_X_ADDRESS,
516 .ip = TEST_ADDRESS_X_PREFIX".2"
517 }
518 };
519
520 static const struct wrepl_ip addresses_X_1_2[] = {
521 {
522 .owner = TEST_OWNER_X_ADDRESS,
523 .ip = TEST_ADDRESS_X_PREFIX".1"
524 },
525 {
526 .owner = TEST_OWNER_X_ADDRESS,
527 .ip = TEST_ADDRESS_X_PREFIX".2"
528 }
529 };
530 static const struct wrepl_ip addresses_X_3_4[] = {
531 {
532 .owner = TEST_OWNER_X_ADDRESS,
533 .ip = TEST_ADDRESS_X_PREFIX".3"
534 },
535 {
536 .owner = TEST_OWNER_X_ADDRESS,
537 .ip = TEST_ADDRESS_X_PREFIX".4"
538 }
539 };
540
541 static struct test_wrepl_conflict_conn *test_create_conflict_ctx(
/* [<][>][^][v][top][bottom][index][help] */
542 struct torture_context *tctx, const char *address)
543 {
544 struct test_wrepl_conflict_conn *ctx;
545 struct wrepl_associate associate;
546 struct wrepl_pull_table pull_table;
547 struct socket_address *nbt_srv_addr;
548 NTSTATUS status;
549 uint32_t i;
550 struct interface *ifaces;
551
552 ctx = talloc_zero(tctx, struct test_wrepl_conflict_conn);
553 if (!ctx) return NULL;
554
555 ctx->address = address;
556 ctx->pull = wrepl_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
557 if (!ctx->pull) return NULL;
558
559 torture_comment(tctx, "Setup wrepl conflict pull connection\n");
560 status = wrepl_connect(ctx->pull, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
561 if (!NT_STATUS_IS_OK(status)) return NULL;
562
563 status = wrepl_associate(ctx->pull, &associate);
564 if (!NT_STATUS_IS_OK(status)) return NULL;
565
566 ctx->pull_assoc = associate.out.assoc_ctx;
567
568 ctx->a.address = TEST_OWNER_A_ADDRESS;
569 ctx->a.max_version = 0;
570 ctx->a.min_version = 0;
571 ctx->a.type = 1;
572
573 ctx->b.address = TEST_OWNER_B_ADDRESS;
574 ctx->b.max_version = 0;
575 ctx->b.min_version = 0;
576 ctx->b.type = 1;
577
578 ctx->x.address = TEST_OWNER_X_ADDRESS;
579 ctx->x.max_version = 0;
580 ctx->x.min_version = 0;
581 ctx->x.type = 1;
582
583 ctx->c.address = address;
584 ctx->c.max_version = 0;
585 ctx->c.min_version = 0;
586 ctx->c.type = 1;
587
588 pull_table.in.assoc_ctx = ctx->pull_assoc;
589 status = wrepl_pull_table(ctx->pull, ctx->pull, &pull_table);
590 if (!NT_STATUS_IS_OK(status)) return NULL;
591
592 for (i=0; i < pull_table.out.num_partners; i++) {
593 if (strcmp(TEST_OWNER_A_ADDRESS,pull_table.out.partners[i].address)==0) {
594 ctx->a.max_version = pull_table.out.partners[i].max_version;
595 ctx->a.min_version = pull_table.out.partners[i].min_version;
596 }
597 if (strcmp(TEST_OWNER_B_ADDRESS,pull_table.out.partners[i].address)==0) {
598 ctx->b.max_version = pull_table.out.partners[i].max_version;
599 ctx->b.min_version = pull_table.out.partners[i].min_version;
600 }
601 if (strcmp(TEST_OWNER_X_ADDRESS,pull_table.out.partners[i].address)==0) {
602 ctx->x.max_version = pull_table.out.partners[i].max_version;
603 ctx->x.min_version = pull_table.out.partners[i].min_version;
604 }
605 if (strcmp(address,pull_table.out.partners[i].address)==0) {
606 ctx->c.max_version = pull_table.out.partners[i].max_version;
607 ctx->c.min_version = pull_table.out.partners[i].min_version;
608 }
609 }
610
611 talloc_free(pull_table.out.partners);
612
613 ctx->nbtsock = nbt_name_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
614 if (!ctx->nbtsock) return NULL;
615
616 load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
617
618 ctx->myaddr = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_best_ip(ifaces, address), 0);
619 if (!ctx->myaddr) return NULL;
620
621 for (i = 0; i < iface_count(ifaces); i++) {
622 if (strcmp(ctx->myaddr->addr, iface_n_ip(ifaces, i)) == 0) continue;
623 ctx->myaddr2 = socket_address_from_strings(tctx, ctx->nbtsock->sock->backend_name, iface_n_ip(ifaces, i), 0);
624 if (!ctx->myaddr2) return NULL;
625 break;
626 }
627
628 status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0);
629 if (!NT_STATUS_IS_OK(status)) return NULL;
630
631 ctx->nbtsock_srv = nbt_name_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
632 if (!ctx->nbtsock_srv) return NULL;
633
634 /* Make a port 137 version of ctx->myaddr */
635 nbt_srv_addr = socket_address_from_strings(tctx, ctx->nbtsock_srv->sock->backend_name, ctx->myaddr->addr, lp_nbt_port(tctx->lp_ctx));
636 if (!nbt_srv_addr) return NULL;
637
638 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
639 status = socket_listen(ctx->nbtsock_srv->sock, nbt_srv_addr, 0, 0);
640 talloc_free(nbt_srv_addr);
641 if (!NT_STATUS_IS_OK(status)) {
642 /* this isn't fatal */
643 talloc_free(ctx->nbtsock_srv);
644 ctx->nbtsock_srv = NULL;
645 }
646
647 if (ctx->myaddr2 && ctx->nbtsock_srv) {
648 ctx->nbtsock2 = nbt_name_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
649 if (!ctx->nbtsock2) return NULL;
650
651 status = socket_listen(ctx->nbtsock2->sock, ctx->myaddr2, 0, 0);
652 if (!NT_STATUS_IS_OK(status)) return NULL;
653
654 ctx->nbtsock_srv2 = nbt_name_socket_init(ctx, ctx->nbtsock_srv->event_ctx, lp_iconv_convenience(tctx->lp_ctx));
655 if (!ctx->nbtsock_srv2) return NULL;
656
657 /* Make a port 137 version of ctx->myaddr2 */
658 nbt_srv_addr = socket_address_from_strings(tctx,
659 ctx->nbtsock_srv->sock->backend_name,
660 ctx->myaddr2->addr,
661 lp_nbt_port(tctx->lp_ctx));
662 if (!nbt_srv_addr) return NULL;
663
664 /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */
665 status = socket_listen(ctx->nbtsock_srv2->sock, ctx->myaddr2, 0, 0);
666 talloc_free(nbt_srv_addr);
667 if (!NT_STATUS_IS_OK(status)) {
668 /* this isn't fatal */
669 talloc_free(ctx->nbtsock_srv2);
670 ctx->nbtsock_srv2 = NULL;
671 }
672 }
673
674 ctx->addresses_best_num = 1;
675 ctx->addresses_best = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best_num);
676 if (!ctx->addresses_best) return NULL;
677 ctx->addresses_best[0].owner = ctx->b.address;
678 ctx->addresses_best[0].ip = ctx->myaddr->addr;
679
680 ctx->addresses_all_num = iface_count(ifaces);
681 ctx->addresses_all = talloc_array(ctx, struct wrepl_ip, ctx->addresses_all_num);
682 if (!ctx->addresses_all) return NULL;
683 for (i=0; i < ctx->addresses_all_num; i++) {
684 ctx->addresses_all[i].owner = ctx->b.address;
685 ctx->addresses_all[i].ip = talloc_strdup(ctx->addresses_all, iface_n_ip(ifaces, i));
686 if (!ctx->addresses_all[i].ip) return NULL;
687 }
688
689 if (ctx->nbtsock_srv2) {
690 ctx->addresses_best2_num = 1;
691 ctx->addresses_best2 = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best2_num);
692 if (!ctx->addresses_best2) return NULL;
693 ctx->addresses_best2[0].owner = ctx->b.address;
694 ctx->addresses_best2[0].ip = ctx->myaddr2->addr;
695
696 ctx->addresses_mhomed_num = 2;
697 ctx->addresses_mhomed = talloc_array(ctx, struct wrepl_ip, ctx->addresses_mhomed_num);
698 if (!ctx->addresses_mhomed) return NULL;
699 ctx->addresses_mhomed[0].owner = ctx->b.address;
700 ctx->addresses_mhomed[0].ip = ctx->myaddr->addr;
701 ctx->addresses_mhomed[1].owner = ctx->b.address;
702 ctx->addresses_mhomed[1].ip = ctx->myaddr2->addr;
703 }
704
705 return ctx;
706 }
707
708 static bool test_wrepl_update_one(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
709 struct test_wrepl_conflict_conn *ctx,
710 const struct wrepl_wins_owner *owner,
711 const struct wrepl_wins_name *name)
712 {
713 struct wrepl_socket *wrepl_socket;
714 struct wrepl_associate associate;
715 struct wrepl_packet update_packet, repl_send;
716 struct wrepl_table *update;
717 struct wrepl_wins_owner wrepl_wins_owners[1];
718 struct wrepl_packet *repl_recv;
719 struct wrepl_wins_owner *send_request;
720 struct wrepl_send_reply *send_reply;
721 struct wrepl_wins_name wrepl_wins_names[1];
722 uint32_t assoc_ctx;
723 NTSTATUS status;
724
725 wrepl_socket = wrepl_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
726
727 status = wrepl_connect(wrepl_socket, wrepl_best_ip(tctx->lp_ctx, ctx->address), ctx->address);
728 CHECK_STATUS(tctx, status, NT_STATUS_OK);
729
730 status = wrepl_associate(wrepl_socket, &associate);
731 CHECK_STATUS(tctx, status, NT_STATUS_OK);
732 assoc_ctx = associate.out.assoc_ctx;
733
734 /* now send a WREPL_REPL_UPDATE message */
735 ZERO_STRUCT(update_packet);
736 update_packet.opcode = WREPL_OPCODE_BITS;
737 update_packet.assoc_ctx = assoc_ctx;
738 update_packet.mess_type = WREPL_REPLICATION;
739 update_packet.message.replication.command = WREPL_REPL_UPDATE;
740 update = &update_packet.message.replication.info.table;
741
742 update->partner_count = ARRAY_SIZE(wrepl_wins_owners);
743 update->partners = wrepl_wins_owners;
744 update->initiator = "0.0.0.0";
745
746 wrepl_wins_owners[0] = *owner;
747
748 status = wrepl_request(wrepl_socket, wrepl_socket,
749 &update_packet, &repl_recv);
750 CHECK_STATUS(tctx, status, NT_STATUS_OK);
751 CHECK_VALUE(tctx, repl_recv->mess_type, WREPL_REPLICATION);
752 CHECK_VALUE(tctx, repl_recv->message.replication.command, WREPL_REPL_SEND_REQUEST);
753 send_request = &repl_recv->message.replication.info.owner;
754
755 ZERO_STRUCT(repl_send);
756 repl_send.opcode = WREPL_OPCODE_BITS;
757 repl_send.assoc_ctx = assoc_ctx;
758 repl_send.mess_type = WREPL_REPLICATION;
759 repl_send.message.replication.command = WREPL_REPL_SEND_REPLY;
760 send_reply = &repl_send.message.replication.info.reply;
761
762 send_reply->num_names = ARRAY_SIZE(wrepl_wins_names);
763 send_reply->names = wrepl_wins_names;
764
765 wrepl_wins_names[0] = *name;
766
767 status = wrepl_request(wrepl_socket, wrepl_socket,
768 &repl_send, &repl_recv);
769 CHECK_STATUS(tctx, status, NT_STATUS_OK);
770 CHECK_VALUE(tctx, repl_recv->mess_type, WREPL_STOP_ASSOCIATION);
771 CHECK_VALUE(tctx, repl_recv->message.stop.reason, 0);
772
773 talloc_free(wrepl_socket);
774 return true;
775 }
776
777 static bool test_wrepl_is_applied(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
778 struct test_wrepl_conflict_conn *ctx,
779 const struct wrepl_wins_owner *owner,
780 const struct wrepl_wins_name *name,
781 bool expected)
782 {
783 NTSTATUS status;
784 struct wrepl_pull_names pull_names;
785 struct wrepl_name *names;
786
787 pull_names.in.assoc_ctx = ctx->pull_assoc;
788 pull_names.in.partner = *owner;
789 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
790
791 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
792 CHECK_STATUS(tctx, status, NT_STATUS_OK);
793 torture_assert(tctx, pull_names.out.num_names == (expected?1:0),
794 talloc_asprintf(tctx, "Invalid number of records returned - expected %d got %d", expected, pull_names.out.num_names));
795
796 names = pull_names.out.names;
797
798 if (expected) {
799 uint32_t flags = WREPL_NAME_FLAGS(names[0].type,
800 names[0].state,
801 names[0].node,
802 names[0].is_static);
803 CHECK_VALUE(tctx, names[0].name.type, name->name->type);
804 CHECK_VALUE_STRING(tctx, names[0].name.name, name->name->name);
805 CHECK_VALUE_STRING(tctx, names[0].name.scope, name->name->scope);
806 CHECK_VALUE(tctx, flags, name->flags);
807 CHECK_VALUE_UINT64(tctx, names[0].version_id, name->id);
808
809 if (flags & 2) {
810 CHECK_VALUE(tctx, names[0].num_addresses,
811 name->addresses.addresses.num_ips);
812 } else {
813 CHECK_VALUE(tctx, names[0].num_addresses, 1);
814 CHECK_VALUE_STRING(tctx, names[0].addresses[0].address,
815 name->addresses.ip);
816 }
817 }
818 talloc_free(pull_names.out.names);
819 return true;
820 }
821
822 static bool test_wrepl_mhomed_merged(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
823 struct test_wrepl_conflict_conn *ctx,
824 const struct wrepl_wins_owner *owner1,
825 uint32_t num_ips1, const struct wrepl_ip *ips1,
826 const struct wrepl_wins_owner *owner2,
827 uint32_t num_ips2, const struct wrepl_ip *ips2,
828 const struct wrepl_wins_name *name2)
829 {
830 NTSTATUS status;
831 struct wrepl_pull_names pull_names;
832 struct wrepl_name *names;
833 uint32_t flags;
834 uint32_t i, j;
835 uint32_t num_ips = num_ips1 + num_ips2;
836
837 for (i = 0; i < num_ips2; i++) {
838 for (j = 0; j < num_ips1; j++) {
839 if (strcmp(ips2[i].ip,ips1[j].ip) == 0) {
840 num_ips--;
841 break;
842 }
843 }
844 }
845
846 pull_names.in.assoc_ctx = ctx->pull_assoc;
847 pull_names.in.partner = *owner2;
848 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
849
850 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
851 CHECK_STATUS(tctx, status, NT_STATUS_OK);
852 CHECK_VALUE(tctx, pull_names.out.num_names, 1);
853
854 names = pull_names.out.names;
855
856 flags = WREPL_NAME_FLAGS(names[0].type,
857 names[0].state,
858 names[0].node,
859 names[0].is_static);
860 CHECK_VALUE(tctx, names[0].name.type, name2->name->type);
861 CHECK_VALUE_STRING(tctx, names[0].name.name, name2->name->name);
862 CHECK_VALUE_STRING(tctx, names[0].name.scope, name2->name->scope);
863 CHECK_VALUE(tctx, flags, name2->flags | WREPL_TYPE_MHOMED);
864 CHECK_VALUE_UINT64(tctx, names[0].version_id, name2->id);
865
866 CHECK_VALUE(tctx, names[0].num_addresses, num_ips);
867
868 for (i = 0; i < names[0].num_addresses; i++) {
869 const char *addr = names[0].addresses[i].address;
870 const char *owner = names[0].addresses[i].owner;
871 bool found = false;
872
873 for (j = 0; j < num_ips2; j++) {
874 if (strcmp(addr, ips2[j].ip) == 0) {
875 found = true;
876 CHECK_VALUE_STRING(tctx, owner, owner2->address);
877 break;
878 }
879 }
880
881 if (found) continue;
882
883 for (j = 0; j < num_ips1; j++) {
884 if (strcmp(addr, ips1[j].ip) == 0) {
885 found = true;
886 CHECK_VALUE_STRING(tctx, owner, owner1->address);
887 break;
888 }
889 }
890
891 if (found) continue;
892
893 CHECK_VALUE_STRING(tctx, addr, "not found in address list");
894 }
895 talloc_free(pull_names.out.names);
896 return true;
897 }
898
899 static bool test_wrepl_sgroup_merged(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
900 struct test_wrepl_conflict_conn *ctx,
901 struct wrepl_wins_owner *merge_owner,
902 struct wrepl_wins_owner *owner1,
903 uint32_t num_ips1, const struct wrepl_ip *ips1,
904 struct wrepl_wins_owner *owner2,
905 uint32_t num_ips2, const struct wrepl_ip *ips2,
906 const struct wrepl_wins_name *name2)
907 {
908 NTSTATUS status;
909 struct wrepl_pull_names pull_names;
910 struct wrepl_name *names;
911 struct wrepl_name *name = NULL;
912 uint32_t flags;
913 uint32_t i, j;
914 uint32_t num_ips = num_ips1 + num_ips2;
915
916 if (!merge_owner) {
917 merge_owner = &ctx->c;
918 }
919
920 for (i = 0; i < num_ips1; i++) {
921 if (owner1 != &ctx->c && strcmp(ips1[i].owner,owner2->address) == 0) {
922 num_ips--;
923 continue;
924 }
925 for (j = 0; j < num_ips2; j++) {
926 if (strcmp(ips1[i].ip,ips2[j].ip) == 0) {
927 num_ips--;
928 break;
929 }
930 }
931 }
932
933
934 pull_names.in.assoc_ctx = ctx->pull_assoc;
935 pull_names.in.partner = *merge_owner;
936 pull_names.in.partner.min_version = pull_names.in.partner.max_version;
937 pull_names.in.partner.max_version = 0;
938
939 status = wrepl_pull_names(ctx->pull, ctx->pull, &pull_names);
940 CHECK_STATUS(tctx, status, NT_STATUS_OK);
941
942 names = pull_names.out.names;
943
944 for (i = 0; i < pull_names.out.num_names; i++) {
945 if (names[i].name.type != name2->name->type) continue;
946 if (!names[i].name.name) continue;
947 if (strcmp(names[i].name.name, name2->name->name) != 0) continue;
948 if (names[i].name.scope) continue;
949
950 name = &names[i];
951 }
952
953 if (pull_names.out.num_names > 0) {
954 merge_owner->max_version = names[pull_names.out.num_names-1].version_id;
955 }
956
957 if (!name) {
958 torture_comment(tctx, "%s: Name '%s' not found\n", __location__, nbt_name_string(ctx, name2->name));
959 return false;
960 }
961
962 flags = WREPL_NAME_FLAGS(name->type,
963 name->state,
964 name->node,
965 name->is_static);
966 CHECK_VALUE(tctx, name->name.type, name2->name->type);
967 CHECK_VALUE_STRING(tctx, name->name.name, name2->name->name);
968 CHECK_VALUE_STRING(tctx, name->name.scope, name2->name->scope);
969 CHECK_VALUE(tctx, flags, name2->flags);
970
971 CHECK_VALUE(tctx, name->num_addresses, num_ips);
972
973 for (i = 0; i < name->num_addresses; i++) {
974 const char *addr = name->addresses[i].address;
975 const char *owner = name->addresses[i].owner;
976 bool found = false;
977
978 for (j = 0; j < num_ips2; j++) {
979 if (strcmp(addr, ips2[j].ip) == 0) {
980 found = true;
981 CHECK_VALUE_STRING(tctx, owner, ips2[j].owner);
982 break;
983 }
984 }
985
986 if (found) continue;
987
988 for (j = 0; j < num_ips1; j++) {
989 if (strcmp(addr, ips1[j].ip) == 0) {
990 found = true;
991 if (owner1 == &ctx->c) {
992 CHECK_VALUE_STRING(tctx, owner, owner1->address);
993 } else {
994 CHECK_VALUE_STRING(tctx, owner, ips1[j].owner);
995 }
996 break;
997 }
998 }
999
1000 if (found) continue;
1001
1002 CHECK_VALUE_STRING(tctx, addr, "not found in address list");
1003 }
1004 talloc_free(pull_names.out.names);
1005 return true;
1006 }
1007
1008 static bool test_conflict_same_owner(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
1009 struct test_wrepl_conflict_conn *ctx)
1010 {
1011 static bool ret = true;
1012 struct nbt_name name;
1013 struct wrepl_wins_name wins_name1;
1014 struct wrepl_wins_name wins_name2;
1015 struct wrepl_wins_name *wins_name_tmp;
1016 struct wrepl_wins_name *wins_name_last;
1017 struct wrepl_wins_name *wins_name_cur;
1018 uint32_t i,j;
1019 uint8_t types[] = { 0x00, 0x1C };
1020 struct {
1021 enum wrepl_name_type type;
1022 enum wrepl_name_state state;
1023 enum wrepl_name_node node;
1024 bool is_static;
1025 uint32_t num_ips;
1026 const struct wrepl_ip *ips;
1027 } records[] = {
1028 {
1029 .type = WREPL_TYPE_GROUP,
1030 .state = WREPL_STATE_ACTIVE,
1031 .node = WREPL_NODE_B,
1032 .is_static = false,
1033 .num_ips = ARRAY_SIZE(addresses_A_1),
1034 .ips = addresses_A_1,
1035 },{
1036 .type = WREPL_TYPE_UNIQUE,
1037 .state = WREPL_STATE_ACTIVE,
1038 .node = WREPL_NODE_B,
1039 .is_static = false,
1040 .num_ips = ARRAY_SIZE(addresses_A_1),
1041 .ips = addresses_A_1,
1042 },{
1043 .type = WREPL_TYPE_UNIQUE,
1044 .state = WREPL_STATE_ACTIVE,
1045 .node = WREPL_NODE_B,
1046 .is_static = false,
1047 .num_ips = ARRAY_SIZE(addresses_A_2),
1048 .ips = addresses_A_2,
1049 },{
1050 .type = WREPL_TYPE_UNIQUE,
1051 .state = WREPL_STATE_ACTIVE,
1052 .node = WREPL_NODE_B,
1053 .is_static = true,
1054 .num_ips = ARRAY_SIZE(addresses_A_1),
1055 .ips = addresses_A_1,
1056 },{
1057 .type = WREPL_TYPE_UNIQUE,
1058 .state = WREPL_STATE_ACTIVE,
1059 .node = WREPL_NODE_B,
1060 .is_static = false,
1061 .num_ips = ARRAY_SIZE(addresses_A_2),
1062 .ips = addresses_A_2,
1063 },{
1064 .type = WREPL_TYPE_SGROUP,
1065 .state = WREPL_STATE_TOMBSTONE,
1066 .node = WREPL_NODE_B,
1067 .is_static = false,
1068 .num_ips = ARRAY_SIZE(addresses_A_2),
1069 .ips = addresses_A_2,
1070 },{
1071 .type = WREPL_TYPE_MHOMED,
1072 .state = WREPL_STATE_TOMBSTONE,
1073 .node = WREPL_NODE_B,
1074 .is_static = false,
1075 .num_ips = ARRAY_SIZE(addresses_A_1),
1076 .ips = addresses_A_1,
1077 },{
1078 .type = WREPL_TYPE_MHOMED,
1079 .state = WREPL_STATE_RELEASED,
1080 .node = WREPL_NODE_B,
1081 .is_static = false,
1082 .num_ips = ARRAY_SIZE(addresses_A_2),
1083 .ips = addresses_A_2,
1084 },{
1085 .type = WREPL_TYPE_SGROUP,
1086 .state = WREPL_STATE_ACTIVE,
1087 .node = WREPL_NODE_B,
1088 .is_static = false,
1089 .num_ips = ARRAY_SIZE(addresses_A_1),
1090 .ips = addresses_A_1,
1091 },{
1092 .type = WREPL_TYPE_SGROUP,
1093 .state = WREPL_STATE_ACTIVE,
1094 .node = WREPL_NODE_B,
1095 .is_static = false,
1096 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1097 .ips = addresses_A_3_4,
1098 },{
1099 .type = WREPL_TYPE_SGROUP,
1100 .state = WREPL_STATE_TOMBSTONE,
1101 .node = WREPL_NODE_B,
1102 .is_static = false,
1103 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1104 .ips = addresses_B_3_4,
1105 },{
1106 /* the last one should always be a unique,tomstone record! */
1107 .type = WREPL_TYPE_UNIQUE,
1108 .state = WREPL_STATE_TOMBSTONE,
1109 .node = WREPL_NODE_B,
1110 .is_static = false,
1111 .num_ips = ARRAY_SIZE(addresses_A_1),
1112 .ips = addresses_A_1,
1113 }
1114 };
1115
1116 name.name = "_SAME_OWNER_A";
1117 name.type = 0;
1118 name.scope = NULL;
1119
1120 wins_name_tmp = NULL;
1121 wins_name_last = &wins_name2;
1122 wins_name_cur = &wins_name1;
1123
1124 for (j=0; ret && j < ARRAY_SIZE(types); j++) {
1125 name.type = types[j];
1126 torture_comment(tctx, "Test Replica Conflicts with same owner[%s] for %s\n",
1127 nbt_name_string(ctx, &name), ctx->a.address);
1128
1129 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
1130 wins_name_tmp = wins_name_last;
1131 wins_name_last = wins_name_cur;
1132 wins_name_cur = wins_name_tmp;
1133
1134 if (i > 0) {
1135 torture_comment(tctx, "%s,%s%s vs. %s,%s%s with %s ip(s) => %s\n",
1136 wrepl_name_type_string(records[i-1].type),
1137 wrepl_name_state_string(records[i-1].state),
1138 (records[i-1].is_static?",static":""),
1139 wrepl_name_type_string(records[i].type),
1140 wrepl_name_state_string(records[i].state),
1141 (records[i].is_static?",static":""),
1142 (records[i-1].ips==records[i].ips?"same":"different"),
1143 "REPLACE");
1144 }
1145
1146 wins_name_cur->name = &name;
1147 wins_name_cur->flags = WREPL_NAME_FLAGS(records[i].type,
1148 records[i].state,
1149 records[i].node,
1150 records[i].is_static);
1151 wins_name_cur->id = ++ctx->a.max_version;
1152 if (wins_name_cur->flags & 2) {
1153 wins_name_cur->addresses.addresses.num_ips = records[i].num_ips;
1154 wins_name_cur->addresses.addresses.ips = discard_const(records[i].ips);
1155 } else {
1156 wins_name_cur->addresses.ip = records[i].ips[0].ip;
1157 }
1158 wins_name_cur->unknown = "255.255.255.255";
1159
1160 ret &= test_wrepl_update_one(tctx, ctx, &ctx->a,wins_name_cur);
1161 if (records[i].state == WREPL_STATE_RELEASED) {
1162 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_last, false);
1163 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_cur, false);
1164 } else {
1165 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->a, wins_name_cur, true);
1166 }
1167
1168 /* the first one is a cleanup run */
1169 if (!ret && i == 0) ret = true;
1170
1171 if (!ret) {
1172 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, __location__);
1173 return ret;
1174 }
1175 }
1176 }
1177 return ret;
1178 }
1179
1180 static bool test_conflict_different_owner(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
1181 struct test_wrepl_conflict_conn *ctx)
1182 {
1183 bool ret = true;
1184 struct wrepl_wins_name wins_name1;
1185 struct wrepl_wins_name wins_name2;
1186 struct wrepl_wins_name *wins_name_r1;
1187 struct wrepl_wins_name *wins_name_r2;
1188 uint32_t i;
1189 struct {
1190 const char *line; /* just better debugging */
1191 struct nbt_name name;
1192 const char *comment;
1193 bool extra; /* not the worst case, this is an extra test */
1194 bool cleanup;
1195 struct {
1196 struct wrepl_wins_owner *owner;
1197 enum wrepl_name_type type;
1198 enum wrepl_name_state state;
1199 enum wrepl_name_node node;
1200 bool is_static;
1201 uint32_t num_ips;
1202 const struct wrepl_ip *ips;
1203 bool apply_expected;
1204 bool sgroup_merge;
1205 struct wrepl_wins_owner *merge_owner;
1206 bool sgroup_cleanup;
1207 } r1, r2;
1208 } records[] = {
1209 /*
1210 * NOTE: the first record and the last applied one
1211 * needs to be from the same owner,
1212 * to not conflict in the next smbtorture run!!!
1213 */
1214 {
1215 .line = __location__,
1216 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1217 .cleanup= true,
1218 .r1 = {
1219 .owner = &ctx->b,
1220 .type = WREPL_TYPE_UNIQUE,
1221 .state = WREPL_STATE_TOMBSTONE,
1222 .node = WREPL_NODE_B,
1223 .is_static = false,
1224 .num_ips = ARRAY_SIZE(addresses_B_1),
1225 .ips = addresses_B_1,
1226 .apply_expected = true /* ignored */
1227 },
1228 .r2 = {
1229 .owner = &ctx->a,
1230 .type = WREPL_TYPE_UNIQUE,
1231 .state = WREPL_STATE_TOMBSTONE,
1232 .node = WREPL_NODE_B,
1233 .is_static = false,
1234 .num_ips = ARRAY_SIZE(addresses_A_1),
1235 .ips = addresses_A_1,
1236 .apply_expected = true /* ignored */
1237 }
1238 },
1239
1240 /*
1241 * unique vs unique section
1242 */
1243 /*
1244 * unique,active vs. unique,active
1245 * => should be replaced
1246 */
1247 {
1248 .line = __location__,
1249 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1250 .r1 = {
1251 .owner = &ctx->a,
1252 .type = WREPL_TYPE_UNIQUE,
1253 .state = WREPL_STATE_ACTIVE,
1254 .node = WREPL_NODE_B,
1255 .is_static = false,
1256 .num_ips = ARRAY_SIZE(addresses_A_1),
1257 .ips = addresses_A_1,
1258 .apply_expected = true
1259 },
1260 .r2 = {
1261 .owner = &ctx->b,
1262 .type = WREPL_TYPE_UNIQUE,
1263 .state = WREPL_STATE_ACTIVE,
1264 .node = WREPL_NODE_B,
1265 .is_static = false,
1266 .num_ips = ARRAY_SIZE(addresses_B_1),
1267 .ips = addresses_B_1,
1268 .apply_expected = true
1269 }
1270 },
1271
1272 /*
1273 * unique,active vs. unique,tombstone
1274 * => should NOT be replaced
1275 */
1276 {
1277 .line = __location__,
1278 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1279 .r1 = {
1280 .owner = &ctx->b,
1281 .type = WREPL_TYPE_UNIQUE,
1282 .state = WREPL_STATE_ACTIVE,
1283 .node = WREPL_NODE_B,
1284 .is_static = false,
1285 .num_ips = ARRAY_SIZE(addresses_B_1),
1286 .ips = addresses_B_1,
1287 .apply_expected = true
1288 },
1289 .r2 = {
1290 .owner = &ctx->a,
1291 .type = WREPL_TYPE_UNIQUE,
1292 .state = WREPL_STATE_TOMBSTONE,
1293 .node = WREPL_NODE_B,
1294 .is_static = false,
1295 .num_ips = ARRAY_SIZE(addresses_B_1),
1296 .ips = addresses_B_1,
1297 .apply_expected = false
1298 }
1299 },
1300
1301 /*
1302 * unique,released vs. unique,active
1303 * => should be replaced
1304 */
1305 {
1306 .line = __location__,
1307 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1308 .r1 = {
1309 .owner = &ctx->b,
1310 .type = WREPL_TYPE_UNIQUE,
1311 .state = WREPL_STATE_RELEASED,
1312 .node = WREPL_NODE_B,
1313 .is_static = false,
1314 .num_ips = ARRAY_SIZE(addresses_B_1),
1315 .ips = addresses_B_1,
1316 .apply_expected = false
1317 },
1318 .r2 = {
1319 .owner = &ctx->a,
1320 .type = WREPL_TYPE_UNIQUE,
1321 .state = WREPL_STATE_ACTIVE,
1322 .node = WREPL_NODE_B,
1323 .is_static = false,
1324 .num_ips = ARRAY_SIZE(addresses_A_1),
1325 .ips = addresses_A_1,
1326 .apply_expected = true
1327 }
1328 },
1329
1330 /*
1331 * unique,released vs. unique,tombstone
1332 * => should be replaced
1333 */
1334 {
1335 .line = __location__,
1336 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1337 .r1 = {
1338 .owner = &ctx->a,
1339 .type = WREPL_TYPE_UNIQUE,
1340 .state = WREPL_STATE_RELEASED,
1341 .node = WREPL_NODE_B,
1342 .is_static = false,
1343 .num_ips = ARRAY_SIZE(addresses_A_1),
1344 .ips = addresses_A_1,
1345 .apply_expected = false
1346 },
1347 .r2 = {
1348 .owner = &ctx->b,
1349 .type = WREPL_TYPE_UNIQUE,
1350 .state = WREPL_STATE_TOMBSTONE,
1351 .node = WREPL_NODE_B,
1352 .is_static = false,
1353 .num_ips = ARRAY_SIZE(addresses_B_1),
1354 .ips = addresses_B_1,
1355 .apply_expected = true
1356 }
1357 },
1358
1359 /*
1360 * unique,tombstone vs. unique,active
1361 * => should be replaced
1362 */
1363 {
1364 .line = __location__,
1365 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1366 .r1 = {
1367 .owner = &ctx->b,
1368 .type = WREPL_TYPE_UNIQUE,
1369 .state = WREPL_STATE_TOMBSTONE,
1370 .node = WREPL_NODE_B,
1371 .is_static = false,
1372 .num_ips = ARRAY_SIZE(addresses_B_1),
1373 .ips = addresses_B_1,
1374 .apply_expected = true
1375 },
1376 .r2 = {
1377 .owner = &ctx->a,
1378 .type = WREPL_TYPE_UNIQUE,
1379 .state = WREPL_STATE_ACTIVE,
1380 .node = WREPL_NODE_B,
1381 .is_static = false,
1382 .num_ips = ARRAY_SIZE(addresses_A_1),
1383 .ips = addresses_A_1,
1384 .apply_expected = true
1385 }
1386 },
1387
1388 /*
1389 * unique,tombstone vs. unique,tombstone
1390 * => should be replaced
1391 */
1392 {
1393 .line = __location__,
1394 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1395 .r1 = {
1396 .owner = &ctx->a,
1397 .type = WREPL_TYPE_UNIQUE,
1398 .state = WREPL_STATE_TOMBSTONE,
1399 .node = WREPL_NODE_B,
1400 .is_static = false,
1401 .num_ips = ARRAY_SIZE(addresses_A_1),
1402 .ips = addresses_A_1,
1403 .apply_expected = true
1404 },
1405 .r2 = {
1406 .owner = &ctx->b,
1407 .type = WREPL_TYPE_UNIQUE,
1408 .state = WREPL_STATE_TOMBSTONE,
1409 .node = WREPL_NODE_B,
1410 .is_static = false,
1411 .num_ips = ARRAY_SIZE(addresses_B_1),
1412 .ips = addresses_B_1,
1413 .apply_expected = true
1414 }
1415 },
1416
1417
1418 /*
1419 * unique vs normal groups section,
1420 */
1421 /*
1422 * unique,active vs. group,active
1423 * => should be replaced
1424 */
1425 {
1426 .line = __location__,
1427 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1428 .r1 = {
1429 .owner = &ctx->b,
1430 .type = WREPL_TYPE_UNIQUE,
1431 .state = WREPL_STATE_ACTIVE,
1432 .node = WREPL_NODE_B,
1433 .is_static = false,
1434 .num_ips = ARRAY_SIZE(addresses_B_1),
1435 .ips = addresses_B_1,
1436 .apply_expected = true
1437 },
1438 .r2 = {
1439 .owner = &ctx->a,
1440 .type = WREPL_TYPE_GROUP,
1441 .state = WREPL_STATE_ACTIVE,
1442 .node = WREPL_NODE_B,
1443 .is_static = false,
1444 .num_ips = ARRAY_SIZE(addresses_A_1),
1445 .ips = addresses_A_1,
1446 .apply_expected = true
1447 }
1448 },
1449
1450 /*
1451 * unique,active vs. group,tombstone
1452 * => should NOT be replaced
1453 */
1454 {
1455 .line = __location__,
1456 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1457 .r1 = {
1458 .owner = &ctx->a,
1459 .type = WREPL_TYPE_UNIQUE,
1460 .state = WREPL_STATE_ACTIVE,
1461 .node = WREPL_NODE_B,
1462 .is_static = false,
1463 .num_ips = ARRAY_SIZE(addresses_A_1),
1464 .ips = addresses_A_1,
1465 .apply_expected = true
1466 },
1467 .r2 = {
1468 .owner = &ctx->b,
1469 .type = WREPL_TYPE_GROUP,
1470 .state = WREPL_STATE_TOMBSTONE,
1471 .node = WREPL_NODE_B,
1472 .is_static = false,
1473 .num_ips = ARRAY_SIZE(addresses_A_1),
1474 .ips = addresses_A_1,
1475 .apply_expected = false
1476 }
1477 },
1478
1479 /*
1480 * unique,released vs. group,active
1481 * => should be replaced
1482 */
1483 {
1484 .line = __location__,
1485 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1486 .r1 = {
1487 .owner = &ctx->a,
1488 .type = WREPL_TYPE_UNIQUE,
1489 .state = WREPL_STATE_RELEASED,
1490 .node = WREPL_NODE_B,
1491 .is_static = false,
1492 .num_ips = ARRAY_SIZE(addresses_A_1),
1493 .ips = addresses_A_1,
1494 .apply_expected = false
1495 },
1496 .r2 = {
1497 .owner = &ctx->b,
1498 .type = WREPL_TYPE_GROUP,
1499 .state = WREPL_STATE_ACTIVE,
1500 .node = WREPL_NODE_B,
1501 .is_static = false,
1502 .num_ips = ARRAY_SIZE(addresses_B_1),
1503 .ips = addresses_B_1,
1504 .apply_expected = true
1505 }
1506 },
1507
1508 /*
1509 * unique,released vs. group,tombstone
1510 * => should be replaced
1511 */
1512 {
1513 .line = __location__,
1514 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1515 .r1 = {
1516 .owner = &ctx->b,
1517 .type = WREPL_TYPE_UNIQUE,
1518 .state = WREPL_STATE_RELEASED,
1519 .node = WREPL_NODE_B,
1520 .is_static = false,
1521 .num_ips = ARRAY_SIZE(addresses_B_1),
1522 .ips = addresses_B_1,
1523 .apply_expected = false
1524 },
1525 .r2 = {
1526 .owner = &ctx->a,
1527 .type = WREPL_TYPE_GROUP,
1528 .state = WREPL_STATE_TOMBSTONE,
1529 .node = WREPL_NODE_B,
1530 .is_static = false,
1531 .num_ips = ARRAY_SIZE(addresses_A_1),
1532 .ips = addresses_A_1,
1533 .apply_expected = true
1534 }
1535 },
1536
1537 /*
1538 * unique,tombstone vs. group,active
1539 * => should be replaced
1540 */
1541 {
1542 .line = __location__,
1543 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1544 .r1 = {
1545 .owner = &ctx->a,
1546 .type = WREPL_TYPE_UNIQUE,
1547 .state = WREPL_STATE_TOMBSTONE,
1548 .node = WREPL_NODE_B,
1549 .is_static = false,
1550 .num_ips = ARRAY_SIZE(addresses_A_1),
1551 .ips = addresses_A_1,
1552 .apply_expected = true
1553 },
1554 .r2 = {
1555 .owner = &ctx->b,
1556 .type = WREPL_TYPE_GROUP,
1557 .state = WREPL_STATE_ACTIVE,
1558 .node = WREPL_NODE_B,
1559 .is_static = false,
1560 .num_ips = ARRAY_SIZE(addresses_B_1),
1561 .ips = addresses_B_1,
1562 .apply_expected = true
1563 }
1564 },
1565
1566 /*
1567 * unique,tombstone vs. group,tombstone
1568 * => should be replaced
1569 */
1570 {
1571 .line = __location__,
1572 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1573 .r1 = {
1574 .owner = &ctx->b,
1575 .type = WREPL_TYPE_UNIQUE,
1576 .state = WREPL_STATE_TOMBSTONE,
1577 .node = WREPL_NODE_B,
1578 .is_static = false,
1579 .num_ips = ARRAY_SIZE(addresses_B_1),
1580 .ips = addresses_B_1,
1581 .apply_expected = true
1582 },
1583 .r2 = {
1584 .owner = &ctx->a,
1585 .type = WREPL_TYPE_GROUP,
1586 .state = WREPL_STATE_TOMBSTONE,
1587 .node = WREPL_NODE_B,
1588 .is_static = false,
1589 .num_ips = ARRAY_SIZE(addresses_A_1),
1590 .ips = addresses_A_1,
1591 .apply_expected = true
1592 }
1593 },
1594
1595 /*
1596 * unique vs special groups section,
1597 */
1598 /*
1599 * unique,active vs. sgroup,active
1600 * => should NOT be replaced
1601 */
1602 {
1603 .line = __location__,
1604 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1605 .r1 = {
1606 .owner = &ctx->a,
1607 .type = WREPL_TYPE_UNIQUE,
1608 .state = WREPL_STATE_ACTIVE,
1609 .node = WREPL_NODE_B,
1610 .is_static = false,
1611 .num_ips = ARRAY_SIZE(addresses_A_1),
1612 .ips = addresses_A_1,
1613 .apply_expected = true
1614 },
1615 .r2 = {
1616 .owner = &ctx->b,
1617 .type = WREPL_TYPE_SGROUP,
1618 .state = WREPL_STATE_ACTIVE,
1619 .node = WREPL_NODE_B,
1620 .is_static = false,
1621 .num_ips = ARRAY_SIZE(addresses_A_1),
1622 .ips = addresses_A_1,
1623 .apply_expected = false
1624 }
1625 },
1626
1627 /*
1628 * unique,active vs. sgroup,tombstone
1629 * => should NOT be replaced
1630 */
1631 {
1632 .line = __location__,
1633 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1634 .r1 = {
1635 .owner = &ctx->a,
1636 .type = WREPL_TYPE_UNIQUE,
1637 .state = WREPL_STATE_ACTIVE,
1638 .node = WREPL_NODE_B,
1639 .is_static = false,
1640 .num_ips = ARRAY_SIZE(addresses_A_1),
1641 .ips = addresses_A_1,
1642 .apply_expected = true
1643 },
1644 .r2 = {
1645 .owner = &ctx->b,
1646 .type = WREPL_TYPE_SGROUP,
1647 .state = WREPL_STATE_TOMBSTONE,
1648 .node = WREPL_NODE_B,
1649 .is_static = false,
1650 .num_ips = ARRAY_SIZE(addresses_A_1),
1651 .ips = addresses_A_1,
1652 .apply_expected = false
1653 }
1654 },
1655
1656 /*
1657 * unique,released vs. sgroup,active
1658 * => should be replaced
1659 */
1660 {
1661 .line = __location__,
1662 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1663 .r1 = {
1664 .owner = &ctx->a,
1665 .type = WREPL_TYPE_UNIQUE,
1666 .state = WREPL_STATE_RELEASED,
1667 .node = WREPL_NODE_B,
1668 .is_static = false,
1669 .num_ips = ARRAY_SIZE(addresses_A_1),
1670 .ips = addresses_A_1,
1671 .apply_expected = false
1672 },
1673 .r2 = {
1674 .owner = &ctx->b,
1675 .type = WREPL_TYPE_SGROUP,
1676 .state = WREPL_STATE_ACTIVE,
1677 .node = WREPL_NODE_B,
1678 .is_static = false,
1679 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1680 .ips = addresses_B_3_4,
1681 .apply_expected = true
1682 }
1683 },
1684
1685 /*
1686 * unique,released vs. sgroup,tombstone
1687 * => should be replaced
1688 */
1689 {
1690 .line = __location__,
1691 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1692 .r1 = {
1693 .owner = &ctx->b,
1694 .type = WREPL_TYPE_UNIQUE,
1695 .state = WREPL_STATE_RELEASED,
1696 .node = WREPL_NODE_B,
1697 .is_static = false,
1698 .num_ips = ARRAY_SIZE(addresses_B_1),
1699 .ips = addresses_B_1,
1700 .apply_expected = false
1701 },
1702 .r2 = {
1703 .owner = &ctx->a,
1704 .type = WREPL_TYPE_SGROUP,
1705 .state = WREPL_STATE_TOMBSTONE,
1706 .node = WREPL_NODE_B,
1707 .is_static = false,
1708 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1709 .ips = addresses_A_3_4,
1710 .apply_expected = true
1711 }
1712 },
1713
1714 /*
1715 * unique,tombstone vs. sgroup,active
1716 * => should be replaced
1717 */
1718 {
1719 .line = __location__,
1720 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1721 .r1 = {
1722 .owner = &ctx->a,
1723 .type = WREPL_TYPE_UNIQUE,
1724 .state = WREPL_STATE_TOMBSTONE,
1725 .node = WREPL_NODE_B,
1726 .is_static = false,
1727 .num_ips = ARRAY_SIZE(addresses_A_1),
1728 .ips = addresses_A_1,
1729 .apply_expected = true
1730 },
1731 .r2 = {
1732 .owner = &ctx->b,
1733 .type = WREPL_TYPE_SGROUP,
1734 .state = WREPL_STATE_ACTIVE,
1735 .node = WREPL_NODE_B,
1736 .is_static = false,
1737 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1738 .ips = addresses_B_3_4,
1739 .apply_expected = true
1740 }
1741 },
1742
1743 /*
1744 * unique,tombstone vs. sgroup,tombstone
1745 * => should be replaced
1746 */
1747 {
1748 .line = __location__,
1749 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1750 .r1 = {
1751 .owner = &ctx->b,
1752 .type = WREPL_TYPE_UNIQUE,
1753 .state = WREPL_STATE_TOMBSTONE,
1754 .node = WREPL_NODE_B,
1755 .is_static = false,
1756 .num_ips = ARRAY_SIZE(addresses_B_1),
1757 .ips = addresses_B_1,
1758 .apply_expected = true
1759 },
1760 .r2 = {
1761 .owner = &ctx->a,
1762 .type = WREPL_TYPE_SGROUP,
1763 .state = WREPL_STATE_TOMBSTONE,
1764 .node = WREPL_NODE_B,
1765 .is_static = false,
1766 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1767 .ips = addresses_A_3_4,
1768 .apply_expected = true
1769 }
1770 },
1771
1772 /*
1773 * unique vs multi homed section,
1774 */
1775 /*
1776 * unique,active vs. mhomed,active
1777 * => should be replaced
1778 */
1779 {
1780 .line = __location__,
1781 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1782 .r1 = {
1783 .owner = &ctx->a,
1784 .type = WREPL_TYPE_UNIQUE,
1785 .state = WREPL_STATE_ACTIVE,
1786 .node = WREPL_NODE_B,
1787 .is_static = false,
1788 .num_ips = ARRAY_SIZE(addresses_A_1),
1789 .ips = addresses_A_1,
1790 .apply_expected = true
1791 },
1792 .r2 = {
1793 .owner = &ctx->b,
1794 .type = WREPL_TYPE_MHOMED,
1795 .state = WREPL_STATE_ACTIVE,
1796 .node = WREPL_NODE_B,
1797 .is_static = false,
1798 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1799 .ips = addresses_B_3_4,
1800 .apply_expected = true
1801 }
1802 },
1803
1804 /*
1805 * unique,active vs. mhomed,tombstone
1806 * => should NOT be replaced
1807 */
1808 {
1809 .line = __location__,
1810 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1811 .r1 = {
1812 .owner = &ctx->b,
1813 .type = WREPL_TYPE_UNIQUE,
1814 .state = WREPL_STATE_ACTIVE,
1815 .node = WREPL_NODE_B,
1816 .is_static = false,
1817 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1818 .ips = addresses_B_3_4,
1819 .apply_expected = true
1820 },
1821 .r2 = {
1822 .owner = &ctx->a,
1823 .type = WREPL_TYPE_MHOMED,
1824 .state = WREPL_STATE_TOMBSTONE,
1825 .node = WREPL_NODE_B,
1826 .is_static = false,
1827 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1828 .ips = addresses_B_3_4,
1829 .apply_expected = false
1830 }
1831 },
1832
1833 /*
1834 * unique,released vs. mhomed,active
1835 * => should be replaced
1836 */
1837 {
1838 .line = __location__,
1839 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1840 .r1 = {
1841 .owner = &ctx->b,
1842 .type = WREPL_TYPE_UNIQUE,
1843 .state = WREPL_STATE_RELEASED,
1844 .node = WREPL_NODE_B,
1845 .is_static = false,
1846 .num_ips = ARRAY_SIZE(addresses_B_1),
1847 .ips = addresses_B_1,
1848 .apply_expected = false
1849 },
1850 .r2 = {
1851 .owner = &ctx->a,
1852 .type = WREPL_TYPE_MHOMED,
1853 .state = WREPL_STATE_ACTIVE,
1854 .node = WREPL_NODE_B,
1855 .is_static = false,
1856 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1857 .ips = addresses_A_3_4,
1858 .apply_expected = true
1859 }
1860 },
1861
1862 /*
1863 * unique,released vs. mhomed,tombstone
1864 * => should be replaced
1865 */
1866 {
1867 .line = __location__,
1868 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1869 .r1 = {
1870 .owner = &ctx->a,
1871 .type = WREPL_TYPE_UNIQUE,
1872 .state = WREPL_STATE_RELEASED,
1873 .node = WREPL_NODE_B,
1874 .is_static = false,
1875 .num_ips = ARRAY_SIZE(addresses_A_1),
1876 .ips = addresses_A_1,
1877 .apply_expected = false
1878 },
1879 .r2 = {
1880 .owner = &ctx->b,
1881 .type = WREPL_TYPE_MHOMED,
1882 .state = WREPL_STATE_TOMBSTONE,
1883 .node = WREPL_NODE_B,
1884 .is_static = false,
1885 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1886 .ips = addresses_B_3_4,
1887 .apply_expected = true
1888 }
1889 },
1890
1891 /*
1892 * unique,tombstone vs. mhomed,active
1893 * => should be replaced
1894 */
1895 {
1896 .line = __location__,
1897 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1898 .r1 = {
1899 .owner = &ctx->b,
1900 .type = WREPL_TYPE_UNIQUE,
1901 .state = WREPL_STATE_TOMBSTONE,
1902 .node = WREPL_NODE_B,
1903 .is_static = false,
1904 .num_ips = ARRAY_SIZE(addresses_B_1),
1905 .ips = addresses_B_1,
1906 .apply_expected = true
1907 },
1908 .r2 = {
1909 .owner = &ctx->a,
1910 .type = WREPL_TYPE_MHOMED,
1911 .state = WREPL_STATE_ACTIVE,
1912 .node = WREPL_NODE_B,
1913 .is_static = false,
1914 .num_ips = ARRAY_SIZE(addresses_A_3_4),
1915 .ips = addresses_A_3_4,
1916 .apply_expected = true
1917 }
1918 },
1919
1920 /*
1921 * unique,tombstone vs. mhomed,tombstone
1922 * => should be replaced
1923 */
1924 {
1925 .line = __location__,
1926 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1927 .r1 = {
1928 .owner = &ctx->a,
1929 .type = WREPL_TYPE_UNIQUE,
1930 .state = WREPL_STATE_TOMBSTONE,
1931 .node = WREPL_NODE_B,
1932 .is_static = false,
1933 .num_ips = ARRAY_SIZE(addresses_A_1),
1934 .ips = addresses_A_1,
1935 .apply_expected = true
1936 },
1937 .r2 = {
1938 .owner = &ctx->b,
1939 .type = WREPL_TYPE_MHOMED,
1940 .state = WREPL_STATE_TOMBSTONE,
1941 .node = WREPL_NODE_B,
1942 .is_static = false,
1943 .num_ips = ARRAY_SIZE(addresses_B_3_4),
1944 .ips = addresses_B_3_4,
1945 .apply_expected = true
1946 }
1947 },
1948
1949 /*
1950 * normal groups vs unique section,
1951 */
1952 /*
1953 * group,active vs. unique,active
1954 * => should NOT be replaced
1955 */
1956 {
1957 .line = __location__,
1958 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1959 .r1 = {
1960 .owner = &ctx->a,
1961 .type = WREPL_TYPE_GROUP,
1962 .state = WREPL_STATE_ACTIVE,
1963 .node = WREPL_NODE_B,
1964 .is_static = false,
1965 .num_ips = ARRAY_SIZE(addresses_A_1),
1966 .ips = addresses_A_1,
1967 .apply_expected = true
1968 },
1969 .r2 = {
1970 .owner = &ctx->b,
1971 .type = WREPL_TYPE_UNIQUE,
1972 .state = WREPL_STATE_ACTIVE,
1973 .node = WREPL_NODE_B,
1974 .is_static = false,
1975 .num_ips = ARRAY_SIZE(addresses_A_1),
1976 .ips = addresses_A_1,
1977 .apply_expected = false
1978 }
1979 },
1980
1981 /*
1982 * group,active vs. unique,tombstone
1983 * => should NOT be replaced
1984 */
1985 {
1986 .line = __location__,
1987 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
1988 .r1 = {
1989 .owner = &ctx->a,
1990 .type = WREPL_TYPE_GROUP,
1991 .state = WREPL_STATE_ACTIVE,
1992 .node = WREPL_NODE_B,
1993 .is_static = false,
1994 .num_ips = ARRAY_SIZE(addresses_A_1),
1995 .ips = addresses_A_1,
1996 .apply_expected = true
1997 },
1998 .r2 = {
1999 .owner = &ctx->b,
2000 .type = WREPL_TYPE_UNIQUE,
2001 .state = WREPL_STATE_TOMBSTONE,
2002 .node = WREPL_NODE_B,
2003 .is_static = false,
2004 .num_ips = ARRAY_SIZE(addresses_A_1),
2005 .ips = addresses_A_1,
2006 .apply_expected = false
2007 }
2008 },
2009
2010 /*
2011 * group,released vs. unique,active
2012 * => should NOT be replaced
2013 */
2014 {
2015 .line = __location__,
2016 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2017 .r1 = {
2018 .owner = &ctx->a,
2019 .type = WREPL_TYPE_GROUP,
2020 .state = WREPL_STATE_RELEASED,
2021 .node = WREPL_NODE_B,
2022 .is_static = false,
2023 .num_ips = ARRAY_SIZE(addresses_A_1),
2024 .ips = addresses_A_1,
2025 .apply_expected = false
2026 },
2027 .r2 = {
2028 .owner = &ctx->b,
2029 .type = WREPL_TYPE_UNIQUE,
2030 .state = WREPL_STATE_ACTIVE,
2031 .node = WREPL_NODE_B,
2032 .is_static = false,
2033 .num_ips = ARRAY_SIZE(addresses_A_1),
2034 .ips = addresses_A_1,
2035 .apply_expected = false
2036 }
2037 },
2038
2039 /*
2040 * group,released vs. unique,tombstone
2041 * => should NOT be replaced
2042 */
2043 {
2044 .line = __location__,
2045 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2046 .r1 = {
2047 .owner = &ctx->a,
2048 .type = WREPL_TYPE_GROUP,
2049 .state = WREPL_STATE_RELEASED,
2050 .node = WREPL_NODE_B,
2051 .is_static = false,
2052 .num_ips = ARRAY_SIZE(addresses_A_1),
2053 .ips = addresses_A_1,
2054 .apply_expected = false
2055 },
2056 .r2 = {
2057 .owner = &ctx->b,
2058 .type = WREPL_TYPE_UNIQUE,
2059 .state = WREPL_STATE_TOMBSTONE,
2060 .node = WREPL_NODE_B,
2061 .is_static = false,
2062 .num_ips = ARRAY_SIZE(addresses_A_1),
2063 .ips = addresses_A_1,
2064 .apply_expected = false
2065 }
2066 },
2067
2068 /*
2069 * group,tombstone vs. unique,active
2070 * => should NOT be replaced
2071 */
2072 {
2073 .line = __location__,
2074 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2075 .r1 = {
2076 .owner = &ctx->a,
2077 .type = WREPL_TYPE_GROUP,
2078 .state = WREPL_STATE_TOMBSTONE,
2079 .node = WREPL_NODE_B,
2080 .is_static = false,
2081 .num_ips = ARRAY_SIZE(addresses_A_1),
2082 .ips = addresses_A_1,
2083 .apply_expected = true
2084 },
2085 .r2 = {
2086 .owner = &ctx->b,
2087 .type = WREPL_TYPE_UNIQUE,
2088 .state = WREPL_STATE_ACTIVE,
2089 .node = WREPL_NODE_B,
2090 .is_static = false,
2091 .num_ips = ARRAY_SIZE(addresses_A_1),
2092 .ips = addresses_A_1,
2093 .apply_expected = false
2094 }
2095 },
2096
2097 /*
2098 * group,tombstone vs. unique,tombstone
2099 * => should NOT be replaced
2100 */
2101 {
2102 .line = __location__,
2103 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2104 .r1 = {
2105 .owner = &ctx->a,
2106 .type = WREPL_TYPE_GROUP,
2107 .state = WREPL_STATE_TOMBSTONE,
2108 .node = WREPL_NODE_B,
2109 .is_static = false,
2110 .num_ips = ARRAY_SIZE(addresses_A_1),
2111 .ips = addresses_A_1,
2112 .apply_expected = true
2113 },
2114 .r2 = {
2115 .owner = &ctx->b,
2116 .type = WREPL_TYPE_UNIQUE,
2117 .state = WREPL_STATE_TOMBSTONE,
2118 .node = WREPL_NODE_B,
2119 .is_static = false,
2120 .num_ips = ARRAY_SIZE(addresses_A_1),
2121 .ips = addresses_A_1,
2122 .apply_expected = false
2123 }
2124 },
2125
2126 /*
2127 * normal groups vs normal groups section,
2128 */
2129 /*
2130 * group,active vs. group,active
2131 * => should NOT be replaced
2132 */
2133 {
2134 .line = __location__,
2135 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2136 .r1 = {
2137 .owner = &ctx->a,
2138 .type = WREPL_TYPE_GROUP,
2139 .state = WREPL_STATE_ACTIVE,
2140 .node = WREPL_NODE_B,
2141 .is_static = false,
2142 .num_ips = ARRAY_SIZE(addresses_A_1),
2143 .ips = addresses_A_1,
2144 .apply_expected = true
2145 },
2146 .r2 = {
2147 .owner = &ctx->b,
2148 .type = WREPL_TYPE_GROUP,
2149 .state = WREPL_STATE_ACTIVE,
2150 .node = WREPL_NODE_B,
2151 .is_static = false,
2152 .num_ips = ARRAY_SIZE(addresses_A_1),
2153 .ips = addresses_A_1,
2154 .apply_expected = false
2155 }
2156 },
2157
2158 /*
2159 * group,active vs. group,tombstone
2160 * => should NOT be replaced
2161 */
2162 {
2163 .line = __location__,
2164 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2165 .r1 = {
2166 .owner = &ctx->a,
2167 .type = WREPL_TYPE_GROUP,
2168 .state = WREPL_STATE_ACTIVE,
2169 .node = WREPL_NODE_B,
2170 .is_static = false,
2171 .num_ips = ARRAY_SIZE(addresses_A_1),
2172 .ips = addresses_A_1,
2173 .apply_expected = true
2174 },
2175 .r2 = {
2176 .owner = &ctx->b,
2177 .type = WREPL_TYPE_GROUP,
2178 .state = WREPL_STATE_TOMBSTONE,
2179 .node = WREPL_NODE_B,
2180 .is_static = false,
2181 .num_ips = ARRAY_SIZE(addresses_A_1),
2182 .ips = addresses_A_1,
2183 .apply_expected = false
2184 }
2185 },
2186
2187 /*
2188 * group,released vs. group,active
2189 * => should be replaced
2190 */
2191 {
2192 .line = __location__,
2193 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2194 .r1 = {
2195 .owner = &ctx->a,
2196 .type = WREPL_TYPE_GROUP,
2197 .state = WREPL_STATE_RELEASED,
2198 .node = WREPL_NODE_B,
2199 .is_static = false,
2200 .num_ips = ARRAY_SIZE(addresses_A_1),
2201 .ips = addresses_A_1,
2202 .apply_expected = false
2203 },
2204 .r2 = {
2205 .owner = &ctx->b,
2206 .type = WREPL_TYPE_GROUP,
2207 .state = WREPL_STATE_ACTIVE,
2208 .node = WREPL_NODE_B,
2209 .is_static = false,
2210 .num_ips = ARRAY_SIZE(addresses_B_1),
2211 .ips = addresses_B_1,
2212 .apply_expected = true
2213 }
2214 },
2215
2216 /*
2217 * group,released vs. group,tombstone
2218 * => should be replaced
2219 */
2220 {
2221 .line = __location__,
2222 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2223 .r1 = {
2224 .owner = &ctx->a,
2225 .type = WREPL_TYPE_GROUP,
2226 .state = WREPL_STATE_RELEASED,
2227 .node = WREPL_NODE_B,
2228 .is_static = false,
2229 .num_ips = ARRAY_SIZE(addresses_A_1),
2230 .ips = addresses_A_1,
2231 .apply_expected = false
2232 },
2233 .r2 = {
2234 .owner = &ctx->b,
2235 .type = WREPL_TYPE_GROUP,
2236 .state = WREPL_STATE_TOMBSTONE,
2237 .node = WREPL_NODE_B,
2238 .is_static = false,
2239 .num_ips = ARRAY_SIZE(addresses_B_1),
2240 .ips = addresses_B_1,
2241 .apply_expected = true
2242 }
2243 },
2244
2245 /*
2246 * group,tombstone vs. group,active
2247 * => should be replaced
2248 */
2249 {
2250 .line = __location__,
2251 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2252 .r1 = {
2253 .owner = &ctx->b,
2254 .type = WREPL_TYPE_GROUP,
2255 .state = WREPL_STATE_TOMBSTONE,
2256 .node = WREPL_NODE_B,
2257 .is_static = false,
2258 .num_ips = ARRAY_SIZE(addresses_B_1),
2259 .ips = addresses_B_1,
2260 .apply_expected = true
2261 },
2262 .r2 = {
2263 .owner = &ctx->a,
2264 .type = WREPL_TYPE_GROUP,
2265 .state = WREPL_STATE_ACTIVE,
2266 .node = WREPL_NODE_B,
2267 .is_static = false,
2268 .num_ips = ARRAY_SIZE(addresses_A_1),
2269 .ips = addresses_A_1,
2270 .apply_expected = true
2271 }
2272 },
2273
2274 /*
2275 * group,tombstone vs. group,tombstone
2276 * => should be replaced
2277 */
2278 {
2279 .line = __location__,
2280 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2281 .r1 = {
2282 .owner = &ctx->a,
2283 .type = WREPL_TYPE_GROUP,
2284 .state = WREPL_STATE_TOMBSTONE,
2285 .node = WREPL_NODE_B,
2286 .is_static = false,
2287 .num_ips = ARRAY_SIZE(addresses_A_1),
2288 .ips = addresses_A_1,
2289 .apply_expected = true
2290 },
2291 .r2 = {
2292 .owner = &ctx->b,
2293 .type = WREPL_TYPE_GROUP,
2294 .state = WREPL_STATE_TOMBSTONE,
2295 .node = WREPL_NODE_B,
2296 .is_static = false,
2297 .num_ips = ARRAY_SIZE(addresses_B_1),
2298 .ips = addresses_B_1,
2299 .apply_expected = true
2300 }
2301 },
2302
2303 /*
2304 * normal groups vs special groups section,
2305 */
2306 /*
2307 * group,active vs. sgroup,active
2308 * => should NOT be replaced
2309 */
2310 {
2311 .line = __location__,
2312 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2313 .r1 = {
2314 .owner = &ctx->b,
2315 .type = WREPL_TYPE_GROUP,
2316 .state = WREPL_STATE_ACTIVE,
2317 .node = WREPL_NODE_B,
2318 .is_static = false,
2319 .num_ips = ARRAY_SIZE(addresses_B_1),
2320 .ips = addresses_B_1,
2321 .apply_expected = true
2322 },
2323 .r2 = {
2324 .owner = &ctx->a,
2325 .type = WREPL_TYPE_SGROUP,
2326 .state = WREPL_STATE_ACTIVE,
2327 .node = WREPL_NODE_B,
2328 .is_static = false,
2329 .num_ips = ARRAY_SIZE(addresses_B_1),
2330 .ips = addresses_B_1,
2331 .apply_expected = false
2332 }
2333 },
2334
2335 /*
2336 * group,active vs. sgroup,tombstone
2337 * => should NOT be replaced
2338 */
2339 {
2340 .line = __location__,
2341 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2342 .r1 = {
2343 .owner = &ctx->b,
2344 .type = WREPL_TYPE_GROUP,
2345 .state = WREPL_STATE_ACTIVE,
2346 .node = WREPL_NODE_B,
2347 .is_static = false,
2348 .num_ips = ARRAY_SIZE(addresses_B_1),
2349 .ips = addresses_B_1,
2350 .apply_expected = true
2351 },
2352 .r2 = {
2353 .owner = &ctx->a,
2354 .type = WREPL_TYPE_SGROUP,
2355 .state = WREPL_STATE_TOMBSTONE,
2356 .node = WREPL_NODE_B,
2357 .is_static = false,
2358 .num_ips = ARRAY_SIZE(addresses_B_1),
2359 .ips = addresses_B_1,
2360 .apply_expected = false
2361 }
2362 },
2363
2364 /*
2365 * group,released vs. sgroup,active
2366 * => should be replaced
2367 */
2368 {
2369 .line = __location__,
2370 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2371 .r1 = {
2372 .owner = &ctx->a,
2373 .type = WREPL_TYPE_GROUP,
2374 .state = WREPL_STATE_RELEASED,
2375 .node = WREPL_NODE_B,
2376 .is_static = false,
2377 .num_ips = ARRAY_SIZE(addresses_A_1),
2378 .ips = addresses_A_1,
2379 .apply_expected = false
2380 },
2381 .r2 = {
2382 .owner = &ctx->b,
2383 .type = WREPL_TYPE_SGROUP,
2384 .state = WREPL_STATE_ACTIVE,
2385 .node = WREPL_NODE_B,
2386 .is_static = false,
2387 .num_ips = ARRAY_SIZE(addresses_B_1),
2388 .ips = addresses_B_1,
2389 .apply_expected = true
2390 }
2391 },
2392
2393 /*
2394 * group,released vs. sgroup,tombstone
2395 * => should NOT be replaced
2396 */
2397 {
2398 .line = __location__,
2399 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2400 .r1 = {
2401 .owner = &ctx->b,
2402 .type = WREPL_TYPE_GROUP,
2403 .state = WREPL_STATE_RELEASED,
2404 .node = WREPL_NODE_B,
2405 .is_static = false,
2406 .num_ips = ARRAY_SIZE(addresses_B_1),
2407 .ips = addresses_B_1,
2408 .apply_expected = false
2409 },
2410 .r2 = {
2411 .owner = &ctx->a,
2412 .type = WREPL_TYPE_SGROUP,
2413 .state = WREPL_STATE_TOMBSTONE,
2414 .node = WREPL_NODE_B,
2415 .is_static = false,
2416 .num_ips = ARRAY_SIZE(addresses_B_1),
2417 .ips = addresses_B_1,
2418 .apply_expected = false
2419 }
2420 },
2421
2422 /*
2423 * group,tombstone vs. sgroup,active
2424 * => should be replaced
2425 */
2426 {
2427 .line = __location__,
2428 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2429 .r1 = {
2430 .owner = &ctx->b,
2431 .type = WREPL_TYPE_GROUP,
2432 .state = WREPL_STATE_TOMBSTONE,
2433 .node = WREPL_NODE_B,
2434 .is_static = false,
2435 .num_ips = ARRAY_SIZE(addresses_B_1),
2436 .ips = addresses_B_1,
2437 .apply_expected = true
2438 },
2439 .r2 = {
2440 .owner = &ctx->a,
2441 .type = WREPL_TYPE_SGROUP,
2442 .state = WREPL_STATE_ACTIVE,
2443 .node = WREPL_NODE_B,
2444 .is_static = false,
2445 .num_ips = ARRAY_SIZE(addresses_A_1),
2446 .ips = addresses_A_1,
2447 .apply_expected = true
2448 }
2449 },
2450
2451 /*
2452 * group,tombstone vs. sgroup,tombstone
2453 * => should be replaced
2454 */
2455 {
2456 .line = __location__,
2457 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2458 .r1 = {
2459 .owner = &ctx->a,
2460 .type = WREPL_TYPE_GROUP,
2461 .state = WREPL_STATE_TOMBSTONE,
2462 .node = WREPL_NODE_B,
2463 .is_static = false,
2464 .num_ips = ARRAY_SIZE(addresses_A_1),
2465 .ips = addresses_A_1,
2466 .apply_expected = true
2467 },
2468 .r2 = {
2469 .owner = &ctx->b,
2470 .type = WREPL_TYPE_SGROUP,
2471 .state = WREPL_STATE_TOMBSTONE,
2472 .node = WREPL_NODE_B,
2473 .is_static = false,
2474 .num_ips = ARRAY_SIZE(addresses_B_1),
2475 .ips = addresses_B_1,
2476 .apply_expected = true
2477 }
2478 },
2479
2480 /*
2481 * normal groups vs multi homed section,
2482 */
2483 /*
2484 * group,active vs. mhomed,active
2485 * => should NOT be replaced
2486 */
2487 {
2488 .line = __location__,
2489 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2490 .r1 = {
2491 .owner = &ctx->b,
2492 .type = WREPL_TYPE_GROUP,
2493 .state = WREPL_STATE_ACTIVE,
2494 .node = WREPL_NODE_B,
2495 .is_static = false,
2496 .num_ips = ARRAY_SIZE(addresses_B_1),
2497 .ips = addresses_B_1,
2498 .apply_expected = true
2499 },
2500 .r2 = {
2501 .owner = &ctx->a,
2502 .type = WREPL_TYPE_MHOMED,
2503 .state = WREPL_STATE_ACTIVE,
2504 .node = WREPL_NODE_B,
2505 .is_static = false,
2506 .num_ips = ARRAY_SIZE(addresses_B_1),
2507 .ips = addresses_B_1,
2508 .apply_expected = false
2509 }
2510 },
2511
2512 /*
2513 * group,active vs. mhomed,tombstone
2514 * => should NOT be replaced
2515 */
2516 {
2517 .line = __location__,
2518 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2519 .r1 = {
2520 .owner = &ctx->b,
2521 .type = WREPL_TYPE_GROUP,
2522 .state = WREPL_STATE_ACTIVE,
2523 .node = WREPL_NODE_B,
2524 .is_static = false,
2525 .num_ips = ARRAY_SIZE(addresses_B_1),
2526 .ips = addresses_B_1,
2527 .apply_expected = true
2528 },
2529 .r2 = {
2530 .owner = &ctx->a,
2531 .type = WREPL_TYPE_MHOMED,
2532 .state = WREPL_STATE_TOMBSTONE,
2533 .node = WREPL_NODE_B,
2534 .is_static = false,
2535 .num_ips = ARRAY_SIZE(addresses_B_1),
2536 .ips = addresses_B_1,
2537 .apply_expected = false
2538 }
2539 },
2540
2541 /*
2542 * group,released vs. mhomed,active
2543 * => should NOT be replaced
2544 */
2545 {
2546 .line = __location__,
2547 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2548 .r1 = {
2549 .owner = &ctx->b,
2550 .type = WREPL_TYPE_GROUP,
2551 .state = WREPL_STATE_RELEASED,
2552 .node = WREPL_NODE_B,
2553 .is_static = false,
2554 .num_ips = ARRAY_SIZE(addresses_B_1),
2555 .ips = addresses_B_1,
2556 .apply_expected = false
2557 },
2558 .r2 = {
2559 .owner = &ctx->a,
2560 .type = WREPL_TYPE_MHOMED,
2561 .state = WREPL_STATE_ACTIVE,
2562 .node = WREPL_NODE_B,
2563 .is_static = false,
2564 .num_ips = ARRAY_SIZE(addresses_B_1),
2565 .ips = addresses_B_1,
2566 .apply_expected = false
2567 }
2568 },
2569
2570 /*
2571 * group,released vs. mhomed,tombstone
2572 * => should NOT be replaced
2573 */
2574 {
2575 .line = __location__,
2576 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2577 .r1 = {
2578 .owner = &ctx->b,
2579 .type = WREPL_TYPE_GROUP,
2580 .state = WREPL_STATE_RELEASED,
2581 .node = WREPL_NODE_B,
2582 .is_static = false,
2583 .num_ips = ARRAY_SIZE(addresses_B_1),
2584 .ips = addresses_B_1,
2585 .apply_expected = false
2586 },
2587 .r2 = {
2588 .owner = &ctx->a,
2589 .type = WREPL_TYPE_MHOMED,
2590 .state = WREPL_STATE_TOMBSTONE,
2591 .node = WREPL_NODE_B,
2592 .is_static = false,
2593 .num_ips = ARRAY_SIZE(addresses_B_1),
2594 .ips = addresses_B_1,
2595 .apply_expected = false
2596 }
2597 },
2598
2599 /*
2600 * group,tombstone vs. mhomed,active
2601 * => should be replaced
2602 */
2603 {
2604 .line = __location__,
2605 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2606 .r1 = {
2607 .owner = &ctx->b,
2608 .type = WREPL_TYPE_GROUP,
2609 .state = WREPL_STATE_TOMBSTONE,
2610 .node = WREPL_NODE_B,
2611 .is_static = false,
2612 .num_ips = ARRAY_SIZE(addresses_B_1),
2613 .ips = addresses_B_1,
2614 .apply_expected = true
2615 },
2616 .r2 = {
2617 .owner = &ctx->a,
2618 .type = WREPL_TYPE_MHOMED,
2619 .state = WREPL_STATE_ACTIVE,
2620 .node = WREPL_NODE_B,
2621 .is_static = false,
2622 .num_ips = ARRAY_SIZE(addresses_A_1),
2623 .ips = addresses_A_1,
2624 .apply_expected = true
2625 }
2626 },
2627
2628 /*
2629 * group,tombstone vs. mhomed,tombstone
2630 * => should be replaced
2631 */
2632 {
2633 .line = __location__,
2634 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2635 .r1 = {
2636 .owner = &ctx->a,
2637 .type = WREPL_TYPE_GROUP,
2638 .state = WREPL_STATE_TOMBSTONE,
2639 .node = WREPL_NODE_B,
2640 .is_static = false,
2641 .num_ips = ARRAY_SIZE(addresses_A_1),
2642 .ips = addresses_A_1,
2643 .apply_expected = true
2644 },
2645 .r2 = {
2646 .owner = &ctx->b,
2647 .type = WREPL_TYPE_MHOMED,
2648 .state = WREPL_STATE_TOMBSTONE,
2649 .node = WREPL_NODE_B,
2650 .is_static = false,
2651 .num_ips = ARRAY_SIZE(addresses_B_1),
2652 .ips = addresses_B_1,
2653 .apply_expected = true
2654 }
2655 },
2656
2657 /*
2658 * special groups vs unique section,
2659 */
2660 /*
2661 * sgroup,active vs. unique,active
2662 * => should NOT be replaced
2663 */
2664 {
2665 .line = __location__,
2666 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2667 .r1 = {
2668 .owner = &ctx->b,
2669 .type = WREPL_TYPE_SGROUP,
2670 .state = WREPL_STATE_ACTIVE,
2671 .node = WREPL_NODE_B,
2672 .is_static = false,
2673 .num_ips = ARRAY_SIZE(addresses_B_1),
2674 .ips = addresses_B_1,
2675 .apply_expected = true
2676 },
2677 .r2 = {
2678 .owner = &ctx->a,
2679 .type = WREPL_TYPE_UNIQUE,
2680 .state = WREPL_STATE_ACTIVE,
2681 .node = WREPL_NODE_B,
2682 .is_static = false,
2683 .num_ips = ARRAY_SIZE(addresses_B_1),
2684 .ips = addresses_B_1,
2685 .apply_expected = false
2686 }
2687 },
2688
2689 /*
2690 * sgroup,active vs. unique,tombstone
2691 * => should NOT be replaced
2692 */
2693 {
2694 .line = __location__,
2695 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2696 .r1 = {
2697 .owner = &ctx->b,
2698 .type = WREPL_TYPE_SGROUP,
2699 .state = WREPL_STATE_ACTIVE,
2700 .node = WREPL_NODE_B,
2701 .is_static = false,
2702 .num_ips = ARRAY_SIZE(addresses_B_1),
2703 .ips = addresses_B_1,
2704 .apply_expected = true
2705 },
2706 .r2 = {
2707 .owner = &ctx->a,
2708 .type = WREPL_TYPE_UNIQUE,
2709 .state = WREPL_STATE_TOMBSTONE,
2710 .node = WREPL_NODE_B,
2711 .is_static = false,
2712 .num_ips = ARRAY_SIZE(addresses_B_1),
2713 .ips = addresses_B_1,
2714 .apply_expected = false
2715 }
2716 },
2717
2718 /*
2719 * sgroup,released vs. unique,active
2720 * => should be replaced
2721 */
2722 {
2723 .line = __location__,
2724 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2725 .r1 = {
2726 .owner = &ctx->b,
2727 .type = WREPL_TYPE_SGROUP,
2728 .state = WREPL_STATE_RELEASED,
2729 .node = WREPL_NODE_B,
2730 .is_static = false,
2731 .num_ips = ARRAY_SIZE(addresses_B_1),
2732 .ips = addresses_B_1,
2733 .apply_expected = false
2734 },
2735 .r2 = {
2736 .owner = &ctx->a,
2737 .type = WREPL_TYPE_UNIQUE,
2738 .state = WREPL_STATE_ACTIVE,
2739 .node = WREPL_NODE_B,
2740 .is_static = false,
2741 .num_ips = ARRAY_SIZE(addresses_A_1),
2742 .ips = addresses_A_1,
2743 .apply_expected = true
2744 }
2745 },
2746
2747 /*
2748 * sgroup,released vs. unique,tombstone
2749 * => should be replaced
2750 */
2751 {
2752 .line = __location__,
2753 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2754 .r1 = {
2755 .owner = &ctx->a,
2756 .type = WREPL_TYPE_SGROUP,
2757 .state = WREPL_STATE_RELEASED,
2758 .node = WREPL_NODE_B,
2759 .is_static = false,
2760 .num_ips = ARRAY_SIZE(addresses_A_1),
2761 .ips = addresses_A_1,
2762 .apply_expected = false
2763 },
2764 .r2 = {
2765 .owner = &ctx->b,
2766 .type = WREPL_TYPE_UNIQUE,
2767 .state = WREPL_STATE_TOMBSTONE,
2768 .node = WREPL_NODE_B,
2769 .is_static = false,
2770 .num_ips = ARRAY_SIZE(addresses_B_1),
2771 .ips = addresses_B_1,
2772 .apply_expected = true
2773 }
2774 },
2775
2776 /*
2777 * sgroup,tombstone vs. unique,active
2778 * => should be replaced
2779 */
2780 {
2781 .line = __location__,
2782 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2783 .r1 = {
2784 .owner = &ctx->a,
2785 .type = WREPL_TYPE_SGROUP,
2786 .state = WREPL_STATE_TOMBSTONE,
2787 .node = WREPL_NODE_B,
2788 .is_static = false,
2789 .num_ips = ARRAY_SIZE(addresses_A_1),
2790 .ips = addresses_A_1,
2791 .apply_expected = true
2792 },
2793 .r2 = {
2794 .owner = &ctx->b,
2795 .type = WREPL_TYPE_UNIQUE,
2796 .state = WREPL_STATE_ACTIVE,
2797 .node = WREPL_NODE_B,
2798 .is_static = false,
2799 .num_ips = ARRAY_SIZE(addresses_B_1),
2800 .ips = addresses_B_1,
2801 .apply_expected = true
2802 }
2803 },
2804
2805 /*
2806 * sgroup,tombstone vs. unique,tombstone
2807 * => should be replaced
2808 */
2809 {
2810 .line = __location__,
2811 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2812 .r1 = {
2813 .owner = &ctx->b,
2814 .type = WREPL_TYPE_SGROUP,
2815 .state = WREPL_STATE_TOMBSTONE,
2816 .node = WREPL_NODE_B,
2817 .is_static = false,
2818 .num_ips = ARRAY_SIZE(addresses_B_1),
2819 .ips = addresses_B_1,
2820 .apply_expected = true
2821 },
2822 .r2 = {
2823 .owner = &ctx->a,
2824 .type = WREPL_TYPE_UNIQUE,
2825 .state = WREPL_STATE_TOMBSTONE,
2826 .node = WREPL_NODE_B,
2827 .is_static = false,
2828 .num_ips = ARRAY_SIZE(addresses_A_1),
2829 .ips = addresses_A_1,
2830 .apply_expected = true
2831 }
2832 },
2833
2834 /*
2835 * special groups vs normal group section,
2836 */
2837 /*
2838 * sgroup,active vs. group,active
2839 * => should NOT be replaced
2840 */
2841 {
2842 .line = __location__,
2843 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2844 .r1 = {
2845 .owner = &ctx->a,
2846 .type = WREPL_TYPE_SGROUP,
2847 .state = WREPL_STATE_ACTIVE,
2848 .node = WREPL_NODE_B,
2849 .is_static = false,
2850 .num_ips = ARRAY_SIZE(addresses_A_1),
2851 .ips = addresses_A_1,
2852 .apply_expected = true
2853 },
2854 .r2 = {
2855 .owner = &ctx->b,
2856 .type = WREPL_TYPE_GROUP,
2857 .state = WREPL_STATE_ACTIVE,
2858 .node = WREPL_NODE_B,
2859 .is_static = false,
2860 .num_ips = ARRAY_SIZE(addresses_A_1),
2861 .ips = addresses_A_1,
2862 .apply_expected = false
2863 }
2864 },
2865
2866 /*
2867 * sgroup,active vs. group,tombstone
2868 * => should NOT be replaced
2869 */
2870 {
2871 .line = __location__,
2872 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2873 .r1 = {
2874 .owner = &ctx->a,
2875 .type = WREPL_TYPE_SGROUP,
2876 .state = WREPL_STATE_ACTIVE,
2877 .node = WREPL_NODE_B,
2878 .is_static = false,
2879 .num_ips = ARRAY_SIZE(addresses_A_1),
2880 .ips = addresses_A_1,
2881 .apply_expected = true
2882 },
2883 .r2 = {
2884 .owner = &ctx->b,
2885 .type = WREPL_TYPE_GROUP,
2886 .state = WREPL_STATE_TOMBSTONE,
2887 .node = WREPL_NODE_B,
2888 .is_static = false,
2889 .num_ips = ARRAY_SIZE(addresses_A_1),
2890 .ips = addresses_A_1,
2891 .apply_expected = false
2892 }
2893 },
2894
2895 /*
2896 * sgroup,released vs. group,active
2897 * => should be replaced
2898 */
2899 {
2900 .line = __location__,
2901 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2902 .r1 = {
2903 .owner = &ctx->a,
2904 .type = WREPL_TYPE_SGROUP,
2905 .state = WREPL_STATE_RELEASED,
2906 .node = WREPL_NODE_B,
2907 .is_static = false,
2908 .num_ips = ARRAY_SIZE(addresses_A_1),
2909 .ips = addresses_A_1,
2910 .apply_expected = false
2911 },
2912 .r2 = {
2913 .owner = &ctx->b,
2914 .type = WREPL_TYPE_GROUP,
2915 .state = WREPL_STATE_ACTIVE,
2916 .node = WREPL_NODE_B,
2917 .is_static = false,
2918 .num_ips = ARRAY_SIZE(addresses_B_1),
2919 .ips = addresses_B_1,
2920 .apply_expected = true
2921 }
2922 },
2923
2924 /*
2925 * sgroup,released vs. group,tombstone
2926 * => should be replaced
2927 */
2928 {
2929 .line = __location__,
2930 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2931 .r1 = {
2932 .owner = &ctx->b,
2933 .type = WREPL_TYPE_SGROUP,
2934 .state = WREPL_STATE_RELEASED,
2935 .node = WREPL_NODE_B,
2936 .is_static = false,
2937 .num_ips = ARRAY_SIZE(addresses_B_1),
2938 .ips = addresses_B_1,
2939 .apply_expected = false
2940 },
2941 .r2 = {
2942 .owner = &ctx->a,
2943 .type = WREPL_TYPE_GROUP,
2944 .state = WREPL_STATE_TOMBSTONE,
2945 .node = WREPL_NODE_B,
2946 .is_static = false,
2947 .num_ips = ARRAY_SIZE(addresses_A_1),
2948 .ips = addresses_A_1,
2949 .apply_expected = true
2950 }
2951 },
2952
2953 /*
2954 * sgroup,tombstone vs. group,active
2955 * => should NOT be replaced
2956 */
2957 {
2958 .line = __location__,
2959 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2960 .r1 = {
2961 .owner = &ctx->a,
2962 .type = WREPL_TYPE_SGROUP,
2963 .state = WREPL_STATE_TOMBSTONE,
2964 .node = WREPL_NODE_B,
2965 .is_static = false,
2966 .num_ips = ARRAY_SIZE(addresses_A_1),
2967 .ips = addresses_A_1,
2968 .apply_expected = true
2969 },
2970 .r2 = {
2971 .owner = &ctx->b,
2972 .type = WREPL_TYPE_GROUP,
2973 .state = WREPL_STATE_ACTIVE,
2974 .node = WREPL_NODE_B,
2975 .is_static = false,
2976 .num_ips = ARRAY_SIZE(addresses_B_1),
2977 .ips = addresses_B_1,
2978 .apply_expected = true
2979 }
2980 },
2981
2982 /*
2983 * sgroup,tombstone vs. group,tombstone
2984 * => should NOT be replaced
2985 */
2986 {
2987 .line = __location__,
2988 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
2989 .r1 = {
2990 .owner = &ctx->b,
2991 .type = WREPL_TYPE_SGROUP,
2992 .state = WREPL_STATE_TOMBSTONE,
2993 .node = WREPL_NODE_B,
2994 .is_static = false,
2995 .num_ips = ARRAY_SIZE(addresses_B_1),
2996 .ips = addresses_B_1,
2997 .apply_expected = true
2998 },
2999 .r2 = {
3000 .owner = &ctx->a,
3001 .type = WREPL_TYPE_GROUP,
3002 .state = WREPL_STATE_TOMBSTONE,
3003 .node = WREPL_NODE_B,
3004 .is_static = false,
3005 .num_ips = ARRAY_SIZE(addresses_A_1),
3006 .ips = addresses_A_1,
3007 .apply_expected = true
3008 }
3009 },
3010
3011 /*
3012 * special groups (not active) vs special group section,
3013 */
3014 /*
3015 * sgroup,released vs. sgroup,active
3016 * => should be replaced
3017 */
3018 {
3019 .line = __location__,
3020 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3021 .r1 = {
3022 .owner = &ctx->a,
3023 .type = WREPL_TYPE_SGROUP,
3024 .state = WREPL_STATE_RELEASED,
3025 .node = WREPL_NODE_B,
3026 .is_static = false,
3027 .num_ips = ARRAY_SIZE(addresses_A_1),
3028 .ips = addresses_A_1,
3029 .apply_expected = false
3030 },
3031 .r2 = {
3032 .owner = &ctx->b,
3033 .type = WREPL_TYPE_SGROUP,
3034 .state = WREPL_STATE_ACTIVE,
3035 .node = WREPL_NODE_B,
3036 .is_static = false,
3037 .num_ips = ARRAY_SIZE(addresses_B_1),
3038 .ips = addresses_B_1,
3039 .apply_expected = true
3040 }
3041 },
3042
3043 /*
3044 * sgroup,released vs. sgroup,tombstone
3045 * => should be replaced
3046 */
3047 {
3048 .line = __location__,
3049 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3050 .r1 = {
3051 .owner = &ctx->b,
3052 .type = WREPL_TYPE_SGROUP,
3053 .state = WREPL_STATE_RELEASED,
3054 .node = WREPL_NODE_B,
3055 .is_static = false,
3056 .num_ips = ARRAY_SIZE(addresses_B_1),
3057 .ips = addresses_B_1,
3058 .apply_expected = false
3059 },
3060 .r2 = {
3061 .owner = &ctx->a,
3062 .type = WREPL_TYPE_SGROUP,
3063 .state = WREPL_STATE_TOMBSTONE,
3064 .node = WREPL_NODE_B,
3065 .is_static = false,
3066 .num_ips = ARRAY_SIZE(addresses_A_1),
3067 .ips = addresses_A_1,
3068 .apply_expected = true
3069 }
3070 },
3071
3072 /*
3073 * sgroup,tombstone vs. sgroup,active
3074 * => should NOT be replaced
3075 */
3076 {
3077 .line = __location__,
3078 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3079 .r1 = {
3080 .owner = &ctx->a,
3081 .type = WREPL_TYPE_SGROUP,
3082 .state = WREPL_STATE_TOMBSTONE,
3083 .node = WREPL_NODE_B,
3084 .is_static = false,
3085 .num_ips = ARRAY_SIZE(addresses_A_1),
3086 .ips = addresses_A_1,
3087 .apply_expected = true
3088 },
3089 .r2 = {
3090 .owner = &ctx->b,
3091 .type = WREPL_TYPE_SGROUP,
3092 .state = WREPL_STATE_ACTIVE,
3093 .node = WREPL_NODE_B,
3094 .is_static = false,
3095 .num_ips = ARRAY_SIZE(addresses_B_1),
3096 .ips = addresses_B_1,
3097 .apply_expected = true
3098 }
3099 },
3100
3101 /*
3102 * sgroup,tombstone vs. sgroup,tombstone
3103 * => should NOT be replaced
3104 */
3105 {
3106 .line = __location__,
3107 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3108 .r1 = {
3109 .owner = &ctx->b,
3110 .type = WREPL_TYPE_SGROUP,
3111 .state = WREPL_STATE_TOMBSTONE,
3112 .node = WREPL_NODE_B,
3113 .is_static = false,
3114 .num_ips = ARRAY_SIZE(addresses_B_1),
3115 .ips = addresses_B_1,
3116 .apply_expected = true
3117 },
3118 .r2 = {
3119 .owner = &ctx->a,
3120 .type = WREPL_TYPE_SGROUP,
3121 .state = WREPL_STATE_TOMBSTONE,
3122 .node = WREPL_NODE_B,
3123 .is_static = false,
3124 .num_ips = ARRAY_SIZE(addresses_A_1),
3125 .ips = addresses_A_1,
3126 .apply_expected = true
3127 }
3128 },
3129
3130 /*
3131 * special groups vs multi homed section,
3132 */
3133 /*
3134 * sgroup,active vs. mhomed,active
3135 * => should NOT be replaced
3136 */
3137 {
3138 .line = __location__,
3139 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3140 .r1 = {
3141 .owner = &ctx->a,
3142 .type = WREPL_TYPE_SGROUP,
3143 .state = WREPL_STATE_ACTIVE,
3144 .node = WREPL_NODE_B,
3145 .is_static = false,
3146 .num_ips = ARRAY_SIZE(addresses_A_1),
3147 .ips = addresses_A_1,
3148 .apply_expected = true
3149 },
3150 .r2 = {
3151 .owner = &ctx->b,
3152 .type = WREPL_TYPE_MHOMED,
3153 .state = WREPL_STATE_ACTIVE,
3154 .node = WREPL_NODE_B,
3155 .is_static = false,
3156 .num_ips = ARRAY_SIZE(addresses_A_1),
3157 .ips = addresses_A_1,
3158 .apply_expected = false
3159 }
3160 },
3161
3162 /*
3163 * sgroup,active vs. mhomed,tombstone
3164 * => should NOT be replaced
3165 */
3166 {
3167 .line = __location__,
3168 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3169 .r1 = {
3170 .owner = &ctx->a,
3171 .type = WREPL_TYPE_SGROUP,
3172 .state = WREPL_STATE_ACTIVE,
3173 .node = WREPL_NODE_B,
3174 .is_static = false,
3175 .num_ips = ARRAY_SIZE(addresses_A_1),
3176 .ips = addresses_A_1,
3177 .apply_expected = true
3178 },
3179 .r2 = {
3180 .owner = &ctx->b,
3181 .type = WREPL_TYPE_MHOMED,
3182 .state = WREPL_STATE_TOMBSTONE,
3183 .node = WREPL_NODE_B,
3184 .is_static = false,
3185 .num_ips = ARRAY_SIZE(addresses_A_1),
3186 .ips = addresses_A_1,
3187 .apply_expected = false
3188 }
3189 },
3190
3191 /*
3192 * sgroup,released vs. mhomed,active
3193 * => should be replaced
3194 */
3195 {
3196 .line = __location__,
3197 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3198 .r1 = {
3199 .owner = &ctx->a,
3200 .type = WREPL_TYPE_SGROUP,
3201 .state = WREPL_STATE_RELEASED,
3202 .node = WREPL_NODE_B,
3203 .is_static = false,
3204 .num_ips = ARRAY_SIZE(addresses_A_1),
3205 .ips = addresses_A_1,
3206 .apply_expected = false
3207 },
3208 .r2 = {
3209 .owner = &ctx->b,
3210 .type = WREPL_TYPE_MHOMED,
3211 .state = WREPL_STATE_ACTIVE,
3212 .node = WREPL_NODE_B,
3213 .is_static = false,
3214 .num_ips = ARRAY_SIZE(addresses_B_1),
3215 .ips = addresses_B_1,
3216 .apply_expected = true
3217 }
3218 },
3219
3220 /*
3221 * sgroup,released vs. mhomed,tombstone
3222 * => should be replaced
3223 */
3224 {
3225 .line = __location__,
3226 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3227 .r1 = {
3228 .owner = &ctx->b,
3229 .type = WREPL_TYPE_SGROUP,
3230 .state = WREPL_STATE_RELEASED,
3231 .node = WREPL_NODE_B,
3232 .is_static = false,
3233 .num_ips = ARRAY_SIZE(addresses_B_1),
3234 .ips = addresses_B_1,
3235 .apply_expected = false
3236 },
3237 .r2 = {
3238 .owner = &ctx->a,
3239 .type = WREPL_TYPE_MHOMED,
3240 .state = WREPL_STATE_TOMBSTONE,
3241 .node = WREPL_NODE_B,
3242 .is_static = false,
3243 .num_ips = ARRAY_SIZE(addresses_A_1),
3244 .ips = addresses_A_1,
3245 .apply_expected = true
3246 }
3247 },
3248
3249 /*
3250 * sgroup,tombstone vs. mhomed,active
3251 * => should be replaced
3252 */
3253 {
3254 .line = __location__,
3255 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3256 .r1 = {
3257 .owner = &ctx->a,
3258 .type = WREPL_TYPE_SGROUP,
3259 .state = WREPL_STATE_TOMBSTONE,
3260 .node = WREPL_NODE_B,
3261 .is_static = false,
3262 .num_ips = ARRAY_SIZE(addresses_A_1),
3263 .ips = addresses_A_1,
3264 .apply_expected = true
3265 },
3266 .r2 = {
3267 .owner = &ctx->b,
3268 .type = WREPL_TYPE_MHOMED,
3269 .state = WREPL_STATE_ACTIVE,
3270 .node = WREPL_NODE_B,
3271 .is_static = false,
3272 .num_ips = ARRAY_SIZE(addresses_B_1),
3273 .ips = addresses_B_1,
3274 .apply_expected = true
3275 }
3276 },
3277
3278 /*
3279 * sgroup,tombstone vs. mhomed,tombstone
3280 * => should be replaced
3281 */
3282 {
3283 .line = __location__,
3284 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3285 .r1 = {
3286 .owner = &ctx->b,
3287 .type = WREPL_TYPE_SGROUP,
3288 .state = WREPL_STATE_TOMBSTONE,
3289 .node = WREPL_NODE_B,
3290 .is_static = false,
3291 .num_ips = ARRAY_SIZE(addresses_B_1),
3292 .ips = addresses_B_1,
3293 .apply_expected = true
3294 },
3295 .r2 = {
3296 .owner = &ctx->a,
3297 .type = WREPL_TYPE_MHOMED,
3298 .state = WREPL_STATE_TOMBSTONE,
3299 .node = WREPL_NODE_B,
3300 .is_static = false,
3301 .num_ips = ARRAY_SIZE(addresses_A_1),
3302 .ips = addresses_A_1,
3303 .apply_expected = true
3304 }
3305 },
3306
3307 /*
3308 * multi homed vs. unique section,
3309 */
3310 /*
3311 * mhomed,active vs. unique,active
3312 * => should be replaced
3313 */
3314 {
3315 .line = __location__,
3316 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3317 .r1 = {
3318 .owner = &ctx->a,
3319 .type = WREPL_TYPE_MHOMED,
3320 .state = WREPL_STATE_ACTIVE,
3321 .node = WREPL_NODE_B,
3322 .is_static = false,
3323 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3324 .ips = addresses_A_3_4,
3325 .apply_expected = true
3326 },
3327 .r2 = {
3328 .owner = &ctx->b,
3329 .type = WREPL_TYPE_UNIQUE,
3330 .state = WREPL_STATE_ACTIVE,
3331 .node = WREPL_NODE_B,
3332 .is_static = false,
3333 .num_ips = ARRAY_SIZE(addresses_B_1),
3334 .ips = addresses_B_1,
3335 .apply_expected = true
3336 }
3337 },
3338
3339 /*
3340 * mhomed,active vs. unique,tombstone
3341 * => should NOT be replaced
3342 */
3343 {
3344 .line = __location__,
3345 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3346 .r1 = {
3347 .owner = &ctx->b,
3348 .type = WREPL_TYPE_MHOMED,
3349 .state = WREPL_STATE_ACTIVE,
3350 .node = WREPL_NODE_B,
3351 .is_static = false,
3352 .num_ips = ARRAY_SIZE(addresses_B_1),
3353 .ips = addresses_B_1,
3354 .apply_expected = true
3355 },
3356 .r2 = {
3357 .owner = &ctx->a,
3358 .type = WREPL_TYPE_UNIQUE,
3359 .state = WREPL_STATE_TOMBSTONE,
3360 .node = WREPL_NODE_B,
3361 .is_static = false,
3362 .num_ips = ARRAY_SIZE(addresses_B_1),
3363 .ips = addresses_B_1,
3364 .apply_expected = false
3365 }
3366 },
3367
3368 /*
3369 * mhomed,released vs. unique,active
3370 * => should be replaced
3371 */
3372 {
3373 .line = __location__,
3374 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3375 .r1 = {
3376 .owner = &ctx->a,
3377 .type = WREPL_TYPE_MHOMED,
3378 .state = WREPL_STATE_RELEASED,
3379 .node = WREPL_NODE_B,
3380 .is_static = false,
3381 .num_ips = ARRAY_SIZE(addresses_A_1),
3382 .ips = addresses_A_1,
3383 .apply_expected = false
3384 },
3385 .r2 = {
3386 .owner = &ctx->b,
3387 .type = WREPL_TYPE_UNIQUE,
3388 .state = WREPL_STATE_ACTIVE,
3389 .node = WREPL_NODE_B,
3390 .is_static = false,
3391 .num_ips = ARRAY_SIZE(addresses_B_1),
3392 .ips = addresses_B_1,
3393 .apply_expected = true
3394 }
3395 },
3396
3397 /*
3398 * mhomed,released vs. uinique,tombstone
3399 * => should be replaced
3400 */
3401 {
3402 .line = __location__,
3403 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3404 .r1 = {
3405 .owner = &ctx->b,
3406 .type = WREPL_TYPE_MHOMED,
3407 .state = WREPL_STATE_RELEASED,
3408 .node = WREPL_NODE_B,
3409 .is_static = false,
3410 .num_ips = ARRAY_SIZE(addresses_B_1),
3411 .ips = addresses_B_1,
3412 .apply_expected = false
3413 },
3414 .r2 = {
3415 .owner = &ctx->a,
3416 .type = WREPL_TYPE_UNIQUE,
3417 .state = WREPL_STATE_TOMBSTONE,
3418 .node = WREPL_NODE_B,
3419 .is_static = false,
3420 .num_ips = ARRAY_SIZE(addresses_A_1),
3421 .ips = addresses_A_1,
3422 .apply_expected = true
3423 }
3424 },
3425
3426 /*
3427 * mhomed,tombstone vs. unique,active
3428 * => should be replaced
3429 */
3430 {
3431 .line = __location__,
3432 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3433 .r1 = {
3434 .owner = &ctx->a,
3435 .type = WREPL_TYPE_MHOMED,
3436 .state = WREPL_STATE_TOMBSTONE,
3437 .node = WREPL_NODE_B,
3438 .is_static = false,
3439 .num_ips = ARRAY_SIZE(addresses_A_1),
3440 .ips = addresses_A_1,
3441 .apply_expected = true
3442 },
3443 .r2 = {
3444 .owner = &ctx->b,
3445 .type = WREPL_TYPE_UNIQUE,
3446 .state = WREPL_STATE_ACTIVE,
3447 .node = WREPL_NODE_B,
3448 .is_static = false,
3449 .num_ips = ARRAY_SIZE(addresses_B_1),
3450 .ips = addresses_B_1,
3451 .apply_expected = true
3452 }
3453 },
3454
3455 /*
3456 * mhomed,tombstone vs. uinique,tombstone
3457 * => should be replaced
3458 */
3459 {
3460 .line = __location__,
3461 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3462 .r1 = {
3463 .owner = &ctx->b,
3464 .type = WREPL_TYPE_MHOMED,
3465 .state = WREPL_STATE_TOMBSTONE,
3466 .node = WREPL_NODE_B,
3467 .is_static = false,
3468 .num_ips = ARRAY_SIZE(addresses_B_1),
3469 .ips = addresses_B_1,
3470 .apply_expected = true
3471 },
3472 .r2 = {
3473 .owner = &ctx->a,
3474 .type = WREPL_TYPE_UNIQUE,
3475 .state = WREPL_STATE_TOMBSTONE,
3476 .node = WREPL_NODE_B,
3477 .is_static = false,
3478 .num_ips = ARRAY_SIZE(addresses_A_1),
3479 .ips = addresses_A_1,
3480 .apply_expected = true
3481 }
3482 },
3483
3484 /*
3485 * multi homed vs. normal group section,
3486 */
3487 /*
3488 * mhomed,active vs. group,active
3489 * => should be replaced
3490 */
3491 {
3492 .line = __location__,
3493 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3494 .r1 = {
3495 .owner = &ctx->a,
3496 .type = WREPL_TYPE_MHOMED,
3497 .state = WREPL_STATE_ACTIVE,
3498 .node = WREPL_NODE_B,
3499 .is_static = false,
3500 .num_ips = ARRAY_SIZE(addresses_A_1),
3501 .ips = addresses_A_1,
3502 .apply_expected = true
3503 },
3504 .r2 = {
3505 .owner = &ctx->b,
3506 .type = WREPL_TYPE_GROUP,
3507 .state = WREPL_STATE_ACTIVE,
3508 .node = WREPL_NODE_B,
3509 .is_static = false,
3510 .num_ips = ARRAY_SIZE(addresses_B_1),
3511 .ips = addresses_B_1,
3512 .apply_expected = true
3513 }
3514 },
3515
3516 /*
3517 * mhomed,active vs. group,tombstone
3518 * => should NOT be replaced
3519 */
3520 {
3521 .line = __location__,
3522 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3523 .r1 = {
3524 .owner = &ctx->b,
3525 .type = WREPL_TYPE_MHOMED,
3526 .state = WREPL_STATE_ACTIVE,
3527 .node = WREPL_NODE_B,
3528 .is_static = false,
3529 .num_ips = ARRAY_SIZE(addresses_B_1),
3530 .ips = addresses_B_1,
3531 .apply_expected = true
3532 },
3533 .r2 = {
3534 .owner = &ctx->a,
3535 .type = WREPL_TYPE_GROUP,
3536 .state = WREPL_STATE_TOMBSTONE,
3537 .node = WREPL_NODE_B,
3538 .is_static = false,
3539 .num_ips = ARRAY_SIZE(addresses_B_1),
3540 .ips = addresses_B_1,
3541 .apply_expected = false
3542 }
3543 },
3544
3545 /*
3546 * mhomed,released vs. group,active
3547 * => should be replaced
3548 */
3549 {
3550 .line = __location__,
3551 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3552 .r1 = {
3553 .owner = &ctx->b,
3554 .type = WREPL_TYPE_MHOMED,
3555 .state = WREPL_STATE_RELEASED,
3556 .node = WREPL_NODE_B,
3557 .is_static = false,
3558 .num_ips = ARRAY_SIZE(addresses_B_1),
3559 .ips = addresses_B_1,
3560 .apply_expected = false
3561 },
3562 .r2 = {
3563 .owner = &ctx->a,
3564 .type = WREPL_TYPE_GROUP,
3565 .state = WREPL_STATE_ACTIVE,
3566 .node = WREPL_NODE_B,
3567 .is_static = false,
3568 .num_ips = ARRAY_SIZE(addresses_A_1),
3569 .ips = addresses_A_1,
3570 .apply_expected = true
3571 }
3572 },
3573
3574 /*
3575 * mhomed,released vs. group,tombstone
3576 * => should be replaced
3577 */
3578 {
3579 .line = __location__,
3580 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3581 .r1 = {
3582 .owner = &ctx->a,
3583 .type = WREPL_TYPE_MHOMED,
3584 .state = WREPL_STATE_RELEASED,
3585 .node = WREPL_NODE_B,
3586 .is_static = false,
3587 .num_ips = ARRAY_SIZE(addresses_A_1),
3588 .ips = addresses_A_1,
3589 .apply_expected = false
3590 },
3591 .r2 = {
3592 .owner = &ctx->b,
3593 .type = WREPL_TYPE_GROUP,
3594 .state = WREPL_STATE_TOMBSTONE,
3595 .node = WREPL_NODE_B,
3596 .is_static = false,
3597 .num_ips = ARRAY_SIZE(addresses_B_1),
3598 .ips = addresses_B_1,
3599 .apply_expected = true
3600 }
3601 },
3602
3603 /*
3604 * mhomed,tombstone vs. group,active
3605 * => should be replaced
3606 */
3607 {
3608 .line = __location__,
3609 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3610 .r1 = {
3611 .owner = &ctx->b,
3612 .type = WREPL_TYPE_MHOMED,
3613 .state = WREPL_STATE_TOMBSTONE,
3614 .node = WREPL_NODE_B,
3615 .is_static = false,
3616 .num_ips = ARRAY_SIZE(addresses_B_1),
3617 .ips = addresses_B_1,
3618 .apply_expected = true
3619 },
3620 .r2 = {
3621 .owner = &ctx->a,
3622 .type = WREPL_TYPE_GROUP,
3623 .state = WREPL_STATE_ACTIVE,
3624 .node = WREPL_NODE_B,
3625 .is_static = false,
3626 .num_ips = ARRAY_SIZE(addresses_A_1),
3627 .ips = addresses_A_1,
3628 .apply_expected = true
3629 }
3630 },
3631
3632 /*
3633 * mhomed,tombstone vs. group,tombstone
3634 * => should be replaced
3635 */
3636 {
3637 .line = __location__,
3638 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3639 .r1 = {
3640 .owner = &ctx->a,
3641 .type = WREPL_TYPE_MHOMED,
3642 .state = WREPL_STATE_TOMBSTONE,
3643 .node = WREPL_NODE_B,
3644 .is_static = false,
3645 .num_ips = ARRAY_SIZE(addresses_A_1),
3646 .ips = addresses_A_1,
3647 .apply_expected = true
3648 },
3649 .r2 = {
3650 .owner = &ctx->b,
3651 .type = WREPL_TYPE_GROUP,
3652 .state = WREPL_STATE_TOMBSTONE,
3653 .node = WREPL_NODE_B,
3654 .is_static = false,
3655 .num_ips = ARRAY_SIZE(addresses_B_1),
3656 .ips = addresses_B_1,
3657 .apply_expected = true
3658 }
3659 },
3660
3661 /*
3662 * multi homed vs. special group section,
3663 */
3664 /*
3665 * mhomed,active vs. sgroup,active
3666 * => should NOT be replaced
3667 */
3668 {
3669 .line = __location__,
3670 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3671 .r1 = {
3672 .owner = &ctx->a,
3673 .type = WREPL_TYPE_MHOMED,
3674 .state = WREPL_STATE_ACTIVE,
3675 .node = WREPL_NODE_B,
3676 .is_static = false,
3677 .num_ips = ARRAY_SIZE(addresses_A_1),
3678 .ips = addresses_A_1,
3679 .apply_expected = true
3680 },
3681 .r2 = {
3682 .owner = &ctx->b,
3683 .type = WREPL_TYPE_SGROUP,
3684 .state = WREPL_STATE_ACTIVE,
3685 .node = WREPL_NODE_B,
3686 .is_static = false,
3687 .num_ips = ARRAY_SIZE(addresses_A_1),
3688 .ips = addresses_A_1,
3689 .apply_expected = false
3690 }
3691 },
3692
3693 /*
3694 * mhomed,active vs. sgroup,tombstone
3695 * => should NOT be replaced
3696 */
3697 {
3698 .line = __location__,
3699 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3700 .r1 = {
3701 .owner = &ctx->a,
3702 .type = WREPL_TYPE_MHOMED,
3703 .state = WREPL_STATE_ACTIVE,
3704 .node = WREPL_NODE_B,
3705 .is_static = false,
3706 .num_ips = ARRAY_SIZE(addresses_A_1),
3707 .ips = addresses_A_1,
3708 .apply_expected = true
3709 },
3710 .r2 = {
3711 .owner = &ctx->b,
3712 .type = WREPL_TYPE_SGROUP,
3713 .state = WREPL_STATE_TOMBSTONE,
3714 .node = WREPL_NODE_B,
3715 .is_static = false,
3716 .num_ips = ARRAY_SIZE(addresses_A_1),
3717 .ips = addresses_A_1,
3718 .apply_expected = false
3719 }
3720 },
3721
3722 /*
3723 * mhomed,released vs. sgroup,active
3724 * => should be replaced
3725 */
3726 {
3727 .line = __location__,
3728 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3729 .r1 = {
3730 .owner = &ctx->a,
3731 .type = WREPL_TYPE_MHOMED,
3732 .state = WREPL_STATE_RELEASED,
3733 .node = WREPL_NODE_B,
3734 .is_static = false,
3735 .num_ips = ARRAY_SIZE(addresses_A_1),
3736 .ips = addresses_A_1,
3737 .apply_expected = false
3738 },
3739 .r2 = {
3740 .owner = &ctx->b,
3741 .type = WREPL_TYPE_SGROUP,
3742 .state = WREPL_STATE_ACTIVE,
3743 .node = WREPL_NODE_B,
3744 .is_static = false,
3745 .num_ips = ARRAY_SIZE(addresses_B_1),
3746 .ips = addresses_B_1,
3747 .apply_expected = true
3748 }
3749 },
3750
3751 /*
3752 * mhomed,released vs. sgroup,tombstone
3753 * => should be replaced
3754 */
3755 {
3756 .line = __location__,
3757 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3758 .r1 = {
3759 .owner = &ctx->b,
3760 .type = WREPL_TYPE_MHOMED,
3761 .state = WREPL_STATE_RELEASED,
3762 .node = WREPL_NODE_B,
3763 .is_static = false,
3764 .num_ips = ARRAY_SIZE(addresses_B_1),
3765 .ips = addresses_B_1,
3766 .apply_expected = false
3767 },
3768 .r2 = {
3769 .owner = &ctx->a,
3770 .type = WREPL_TYPE_SGROUP,
3771 .state = WREPL_STATE_TOMBSTONE,
3772 .node = WREPL_NODE_B,
3773 .is_static = false,
3774 .num_ips = ARRAY_SIZE(addresses_A_1),
3775 .ips = addresses_A_1,
3776 .apply_expected = true
3777 }
3778 },
3779
3780 /*
3781 * mhomed,tombstone vs. sgroup,active
3782 * => should be replaced
3783 */
3784 {
3785 .line = __location__,
3786 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3787 .r1 = {
3788 .owner = &ctx->a,
3789 .type = WREPL_TYPE_MHOMED,
3790 .state = WREPL_STATE_TOMBSTONE,
3791 .node = WREPL_NODE_B,
3792 .is_static = false,
3793 .num_ips = ARRAY_SIZE(addresses_A_1),
3794 .ips = addresses_A_1,
3795 .apply_expected = true
3796 },
3797 .r2 = {
3798 .owner = &ctx->b,
3799 .type = WREPL_TYPE_SGROUP,
3800 .state = WREPL_STATE_ACTIVE,
3801 .node = WREPL_NODE_B,
3802 .is_static = false,
3803 .num_ips = ARRAY_SIZE(addresses_B_1),
3804 .ips = addresses_B_1,
3805 .apply_expected = true
3806 }
3807 },
3808
3809 /*
3810 * mhomed,tombstone vs. sgroup,tombstone
3811 * => should be replaced
3812 */
3813 {
3814 .line = __location__,
3815 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3816 .r1 = {
3817 .owner = &ctx->b,
3818 .type = WREPL_TYPE_MHOMED,
3819 .state = WREPL_STATE_TOMBSTONE,
3820 .node = WREPL_NODE_B,
3821 .is_static = false,
3822 .num_ips = ARRAY_SIZE(addresses_B_1),
3823 .ips = addresses_B_1,
3824 .apply_expected = true
3825 },
3826 .r2 = {
3827 .owner = &ctx->a,
3828 .type = WREPL_TYPE_SGROUP,
3829 .state = WREPL_STATE_TOMBSTONE,
3830 .node = WREPL_NODE_B,
3831 .is_static = false,
3832 .num_ips = ARRAY_SIZE(addresses_A_1),
3833 .ips = addresses_A_1,
3834 .apply_expected = true
3835 }
3836 },
3837
3838 /*
3839 * multi homed vs. mlti homed section,
3840 */
3841 /*
3842 * mhomed,active vs. mhomed,active
3843 * => should be replaced
3844 */
3845 {
3846 .line = __location__,
3847 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3848 .r1 = {
3849 .owner = &ctx->a,
3850 .type = WREPL_TYPE_MHOMED,
3851 .state = WREPL_STATE_ACTIVE,
3852 .node = WREPL_NODE_B,
3853 .is_static = false,
3854 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3855 .ips = addresses_A_3_4,
3856 .apply_expected = true
3857 },
3858 .r2 = {
3859 .owner = &ctx->b,
3860 .type = WREPL_TYPE_MHOMED,
3861 .state = WREPL_STATE_ACTIVE,
3862 .node = WREPL_NODE_B,
3863 .is_static = false,
3864 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3865 .ips = addresses_B_3_4,
3866 .apply_expected = true
3867 }
3868 },
3869
3870 /*
3871 * mhomed,active vs. mhomed,tombstone
3872 * => should NOT be replaced
3873 */
3874 {
3875 .line = __location__,
3876 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3877 .r1 = {
3878 .owner = &ctx->b,
3879 .type = WREPL_TYPE_MHOMED,
3880 .state = WREPL_STATE_ACTIVE,
3881 .node = WREPL_NODE_B,
3882 .is_static = false,
3883 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3884 .ips = addresses_B_3_4,
3885 .apply_expected = true
3886 },
3887 .r2 = {
3888 .owner = &ctx->a,
3889 .type = WREPL_TYPE_MHOMED,
3890 .state = WREPL_STATE_TOMBSTONE,
3891 .node = WREPL_NODE_B,
3892 .is_static = false,
3893 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3894 .ips = addresses_B_3_4,
3895 .apply_expected = false
3896 }
3897 },
3898
3899 /*
3900 * mhomed,released vs. mhomed,active
3901 * => should be replaced
3902 */
3903 {
3904 .line = __location__,
3905 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3906 .r1 = {
3907 .owner = &ctx->b,
3908 .type = WREPL_TYPE_MHOMED,
3909 .state = WREPL_STATE_RELEASED,
3910 .node = WREPL_NODE_B,
3911 .is_static = false,
3912 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3913 .ips = addresses_B_3_4,
3914 .apply_expected = false
3915 },
3916 .r2 = {
3917 .owner = &ctx->a,
3918 .type = WREPL_TYPE_MHOMED,
3919 .state = WREPL_STATE_ACTIVE,
3920 .node = WREPL_NODE_B,
3921 .is_static = false,
3922 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3923 .ips = addresses_A_3_4,
3924 .apply_expected = true
3925 }
3926 },
3927
3928 /*
3929 * mhomed,released vs. mhomed,tombstone
3930 * => should be replaced
3931 */
3932 {
3933 .line = __location__,
3934 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3935 .r1 = {
3936 .owner = &ctx->a,
3937 .type = WREPL_TYPE_MHOMED,
3938 .state = WREPL_STATE_RELEASED,
3939 .node = WREPL_NODE_B,
3940 .is_static = false,
3941 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3942 .ips = addresses_A_3_4,
3943 .apply_expected = false
3944 },
3945 .r2 = {
3946 .owner = &ctx->b,
3947 .type = WREPL_TYPE_MHOMED,
3948 .state = WREPL_STATE_TOMBSTONE,
3949 .node = WREPL_NODE_B,
3950 .is_static = false,
3951 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3952 .ips = addresses_B_3_4,
3953 .apply_expected = true
3954 }
3955 },
3956
3957 /*
3958 * mhomed,tombstone vs. mhomed,active
3959 * => should be replaced
3960 */
3961 {
3962 .line = __location__,
3963 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3964 .r1 = {
3965 .owner = &ctx->b,
3966 .type = WREPL_TYPE_MHOMED,
3967 .state = WREPL_STATE_TOMBSTONE,
3968 .node = WREPL_NODE_B,
3969 .is_static = false,
3970 .num_ips = ARRAY_SIZE(addresses_B_3_4),
3971 .ips = addresses_B_3_4,
3972 .apply_expected = true
3973 },
3974 .r2 = {
3975 .owner = &ctx->a,
3976 .type = WREPL_TYPE_MHOMED,
3977 .state = WREPL_STATE_ACTIVE,
3978 .node = WREPL_NODE_B,
3979 .is_static = false,
3980 .num_ips = ARRAY_SIZE(addresses_A_3_4),
3981 .ips = addresses_A_3_4,
3982 .apply_expected = true
3983 }
3984 },
3985
3986 /*
3987 * mhomed,tombstone vs. mhomed,tombstone
3988 * => should be replaced
3989 */
3990 {
3991 .line = __location__,
3992 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
3993 .r1 = {
3994 .owner = &ctx->a,
3995 .type = WREPL_TYPE_MHOMED,
3996 .state = WREPL_STATE_TOMBSTONE,
3997 .node = WREPL_NODE_B,
3998 .is_static = false,
3999 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4000 .ips = addresses_A_3_4,
4001 .apply_expected = true
4002 },
4003 .r2 = {
4004 .owner = &ctx->b,
4005 .type = WREPL_TYPE_MHOMED,
4006 .state = WREPL_STATE_TOMBSTONE,
4007 .node = WREPL_NODE_B,
4008 .is_static = false,
4009 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4010 .ips = addresses_B_3_4,
4011 .apply_expected = true
4012 }
4013 },
4014 {
4015 .line = __location__,
4016 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4017 .cleanup= true,
4018 .r1 = {
4019 .owner = &ctx->b,
4020 .type = WREPL_TYPE_UNIQUE,
4021 .state = WREPL_STATE_TOMBSTONE,
4022 .node = WREPL_NODE_B,
4023 .is_static = false,
4024 .num_ips = ARRAY_SIZE(addresses_B_1),
4025 .ips = addresses_B_1,
4026 .apply_expected = true,
4027 },
4028 .r2 = {
4029 .owner = &ctx->a,
4030 .type = WREPL_TYPE_UNIQUE,
4031 .state = WREPL_STATE_TOMBSTONE,
4032 .node = WREPL_NODE_B,
4033 .is_static = false,
4034 .num_ips = ARRAY_SIZE(addresses_A_1),
4035 .ips = addresses_A_1,
4036 .apply_expected = true,
4037 }
4038 },
4039 /*
4040 * special group vs special group section,
4041 */
4042 /*
4043 * sgroup,active vs. sgroup,active same addresses
4044 * => should be NOT replaced
4045 */
4046 {
4047 .line = __location__,
4048 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4049 .comment= "A:A_3_4 vs. B:A_3_4",
4050 .extra = true,
4051 .r1 = {
4052 .owner = &ctx->a,
4053 .type = WREPL_TYPE_SGROUP,
4054 .state = WREPL_STATE_ACTIVE,
4055 .node = WREPL_NODE_B,
4056 .is_static = false,
4057 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4058 .ips = addresses_A_3_4,
4059 .apply_expected = true
4060 },
4061 .r2 = {
4062 .owner = &ctx->b,
4063 .type = WREPL_TYPE_SGROUP,
4064 .state = WREPL_STATE_ACTIVE,
4065 .node = WREPL_NODE_B,
4066 .is_static = false,
4067 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4068 .ips = addresses_A_3_4,
4069 .apply_expected = false,
4070 .sgroup_cleanup = true
4071 }
4072 },
4073 /*
4074 * sgroup,active vs. sgroup,active same addresses
4075 * => should be NOT replaced
4076 */
4077 {
4078 .line = __location__,
4079 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4080 .comment= "A:A_3_4 vs. B:NULL",
4081 .extra = true,
4082 .r1 = {
4083 .owner = &ctx->a,
4084 .type = WREPL_TYPE_SGROUP,
4085 .state = WREPL_STATE_ACTIVE,
4086 .node = WREPL_NODE_B,
4087 .is_static = false,
4088 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4089 .ips = addresses_A_3_4,
4090 .apply_expected = true
4091 },
4092 .r2 = {
4093 .owner = &ctx->b,
4094 .type = WREPL_TYPE_SGROUP,
4095 .state = WREPL_STATE_ACTIVE,
4096 .node = WREPL_NODE_B,
4097 .is_static = false,
4098 .num_ips = 0,
4099 .ips = NULL,
4100 .apply_expected = false,
4101 .sgroup_cleanup = true
4102 }
4103 },
4104 /*
4105 * sgroup,active vs. sgroup,active subset addresses, special case...
4106 * => should NOT be replaced
4107 */
4108 {
4109 .line = __location__,
4110 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4111 .comment= "A:A_3_4_X_3_4 vs. B:A_3_4",
4112 .extra = true,
4113 .r1 = {
4114 .owner = &ctx->a,
4115 .type = WREPL_TYPE_SGROUP,
4116 .state = WREPL_STATE_ACTIVE,
4117 .node = WREPL_NODE_B,
4118 .is_static = false,
4119 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4),
4120 .ips = addresses_A_3_4_X_3_4,
4121 .apply_expected = true,
4122 },
4123 .r2 = {
4124 .owner = &ctx->b,
4125 .type = WREPL_TYPE_SGROUP,
4126 .state = WREPL_STATE_ACTIVE,
4127 .node = WREPL_NODE_B,
4128 .is_static = false,
4129 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4130 .ips = addresses_A_3_4,
4131 .apply_expected = false,
4132 }
4133 },
4134 {
4135 .line = __location__,
4136 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4137 .cleanup= true,
4138 .r1 = {
4139 .owner = &ctx->a,
4140 .type = WREPL_TYPE_SGROUP,
4141 .state = WREPL_STATE_ACTIVE,
4142 .node = WREPL_NODE_B,
4143 .is_static = false,
4144 .num_ips = 0,
4145 .ips = NULL,
4146 .apply_expected = false,
4147 },
4148 .r2 = {
4149 .owner = &ctx->x,
4150 .type = WREPL_TYPE_SGROUP,
4151 .state = WREPL_STATE_ACTIVE,
4152 .node = WREPL_NODE_B,
4153 .is_static = false,
4154 .num_ips = 0,
4155 .ips = NULL,
4156 .apply_expected = false,
4157 }
4158 },
4159 /*
4160 * sgroup,active vs. sgroup,active different addresses, but owner changed
4161 * => should be replaced
4162 */
4163 {
4164 .line = __location__,
4165 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4166 .comment= "A:B_3_4 vs. B:A_3_4",
4167 .extra = true,
4168 .r1 = {
4169 .owner = &ctx->a,
4170 .type = WREPL_TYPE_SGROUP,
4171 .state = WREPL_STATE_ACTIVE,
4172 .node = WREPL_NODE_B,
4173 .is_static = false,
4174 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4175 .ips = addresses_B_3_4,
4176 .apply_expected = true,
4177 },
4178 .r2 = {
4179 .owner = &ctx->b,
4180 .type = WREPL_TYPE_SGROUP,
4181 .state = WREPL_STATE_ACTIVE,
4182 .node = WREPL_NODE_B,
4183 .is_static = false,
4184 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4185 .ips = addresses_A_3_4,
4186 .apply_expected = true,
4187 .sgroup_cleanup = true
4188 }
4189 },
4190 /*
4191 * sgroup,active vs. sgroup,active different addresses, but owner changed
4192 * => should be replaced
4193 */
4194 {
4195 .line = __location__,
4196 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4197 .comment= "A:A_3_4 vs. B:A_3_4_OWNER_B",
4198 .extra = true,
4199 .r1 = {
4200 .owner = &ctx->a,
4201 .type = WREPL_TYPE_SGROUP,
4202 .state = WREPL_STATE_ACTIVE,
4203 .node = WREPL_NODE_B,
4204 .is_static = false,
4205 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4206 .ips = addresses_A_3_4,
4207 .apply_expected = true,
4208 },
4209 .r2 = {
4210 .owner = &ctx->b,
4211 .type = WREPL_TYPE_SGROUP,
4212 .state = WREPL_STATE_ACTIVE,
4213 .node = WREPL_NODE_B,
4214 .is_static = false,
4215 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4216 .ips = addresses_A_3_4_OWNER_B,
4217 .apply_expected = true,
4218 .sgroup_cleanup = true
4219 }
4220 },
4221 /*
4222 * sgroup,active vs. sgroup,active different addresses, but owner changed
4223 * => should be replaced
4224 */
4225 {
4226 .line = __location__,
4227 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4228 .comment= "A:A_3_4_OWNER_B vs. B:A_3_4",
4229 .extra = true,
4230 .r1 = {
4231 .owner = &ctx->a,
4232 .type = WREPL_TYPE_SGROUP,
4233 .state = WREPL_STATE_ACTIVE,
4234 .node = WREPL_NODE_B,
4235 .is_static = false,
4236 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4237 .ips = addresses_A_3_4_OWNER_B,
4238 .apply_expected = true,
4239 },
4240 .r2 = {
4241 .owner = &ctx->b,
4242 .type = WREPL_TYPE_SGROUP,
4243 .state = WREPL_STATE_ACTIVE,
4244 .node = WREPL_NODE_B,
4245 .is_static = false,
4246 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4247 .ips = addresses_A_3_4,
4248 .apply_expected = true,
4249 .sgroup_cleanup = true
4250 }
4251 },
4252 /*
4253 * sgroup,active vs. sgroup,active different addresses
4254 * => should be merged
4255 */
4256 {
4257 .line = __location__,
4258 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4259 .comment= "A:A_3_4 vs. B:B_3_4 => C:A_3_4_B_3_4",
4260 .extra = true,
4261 .r1 = {
4262 .owner = &ctx->a,
4263 .type = WREPL_TYPE_SGROUP,
4264 .state = WREPL_STATE_ACTIVE,
4265 .node = WREPL_NODE_B,
4266 .is_static = false,
4267 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4268 .ips = addresses_A_3_4,
4269 .apply_expected = true,
4270 },
4271 .r2 = {
4272 .owner = &ctx->b,
4273 .type = WREPL_TYPE_SGROUP,
4274 .state = WREPL_STATE_ACTIVE,
4275 .node = WREPL_NODE_B,
4276 .is_static = false,
4277 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4278 .ips = addresses_B_3_4,
4279 .sgroup_merge = true,
4280 .sgroup_cleanup = true,
4281 }
4282 },
4283 /*
4284 * sgroup,active vs. sgroup,active different addresses, special case...
4285 * => should be merged
4286 */
4287 {
4288 .line = __location__,
4289 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4290 .comment= "A:B_3_4_X_3_4 vs. B:A_3_4 => B:A_3_4_X_3_4",
4291 .extra = true,
4292 .r1 = {
4293 .owner = &ctx->a,
4294 .type = WREPL_TYPE_SGROUP,
4295 .state = WREPL_STATE_ACTIVE,
4296 .node = WREPL_NODE_B,
4297 .is_static = false,
4298 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4299 .ips = addresses_B_3_4_X_3_4,
4300 .apply_expected = true,
4301 },
4302 .r2 = {
4303 .owner = &ctx->b,
4304 .type = WREPL_TYPE_SGROUP,
4305 .state = WREPL_STATE_ACTIVE,
4306 .node = WREPL_NODE_B,
4307 .is_static = false,
4308 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4309 .ips = addresses_A_3_4,
4310 .sgroup_merge = true,
4311 .merge_owner = &ctx->b,
4312 .sgroup_cleanup = false
4313 }
4314 },
4315 {
4316 .line = __location__,
4317 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4318 .cleanup= true,
4319 .r1 = {
4320 .owner = &ctx->b,
4321 .type = WREPL_TYPE_SGROUP,
4322 .state = WREPL_STATE_ACTIVE,
4323 .node = WREPL_NODE_B,
4324 .is_static = false,
4325 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4_OWNER_B),
4326 .ips = addresses_A_3_4_X_3_4_OWNER_B,
4327 .apply_expected = true,
4328 },
4329 .r2 = {
4330 .owner = &ctx->b,
4331 .type = WREPL_TYPE_SGROUP,
4332 .state = WREPL_STATE_ACTIVE,
4333 .node = WREPL_NODE_B,
4334 .is_static = false,
4335 .num_ips = 0,
4336 .ips = NULL,
4337 .apply_expected = false,
4338 }
4339 },
4340 /*
4341 * sgroup,active vs. sgroup,active different addresses, special case...
4342 * => should be merged
4343 */
4344 {
4345 .line = __location__,
4346 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4347 .comment= "A:X_3_4 vs. B:A_3_4 => C:A_3_4_X_3_4",
4348 .extra = true,
4349 .r1 = {
4350 .owner = &ctx->a,
4351 .type = WREPL_TYPE_SGROUP,
4352 .state = WREPL_STATE_ACTIVE,
4353 .node = WREPL_NODE_B,
4354 .is_static = false,
4355 .num_ips = ARRAY_SIZE(addresses_X_3_4),
4356 .ips = addresses_X_3_4,
4357 .apply_expected = true,
4358 },
4359 .r2 = {
4360 .owner = &ctx->b,
4361 .type = WREPL_TYPE_SGROUP,
4362 .state = WREPL_STATE_ACTIVE,
4363 .node = WREPL_NODE_B,
4364 .is_static = false,
4365 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4366 .ips = addresses_A_3_4,
4367 .sgroup_merge = true,
4368 .sgroup_cleanup = false
4369 }
4370 },
4371 {
4372 .line = __location__,
4373 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4374 .cleanup= true,
4375 .r1 = {
4376 .owner = &ctx->a,
4377 .type = WREPL_TYPE_SGROUP,
4378 .state = WREPL_STATE_ACTIVE,
4379 .node = WREPL_NODE_B,
4380 .is_static = false,
4381 .num_ips = 0,
4382 .ips = NULL,
4383 .apply_expected = false,
4384 },
4385 .r2 = {
4386 .owner = &ctx->x,
4387 .type = WREPL_TYPE_SGROUP,
4388 .state = WREPL_STATE_ACTIVE,
4389 .node = WREPL_NODE_B,
4390 .is_static = false,
4391 .num_ips = 0,
4392 .ips = NULL,
4393 .apply_expected = false,
4394 }
4395 },
4396 /*
4397 * sgroup,active vs. sgroup,active different addresses, special case...
4398 * => should be merged
4399 */
4400 {
4401 .line = __location__,
4402 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4403 .comment= "A:A_3_4_X_3_4 vs. B:A_3_4_OWNER_B => B:A_3_4_OWNER_B_X_3_4",
4404 .extra = true,
4405 .r1 = {
4406 .owner = &ctx->a,
4407 .type = WREPL_TYPE_SGROUP,
4408 .state = WREPL_STATE_ACTIVE,
4409 .node = WREPL_NODE_B,
4410 .is_static = false,
4411 .num_ips = ARRAY_SIZE(addresses_A_3_4_X_3_4),
4412 .ips = addresses_A_3_4_X_3_4,
4413 .apply_expected = true,
4414 },
4415 .r2 = {
4416 .owner = &ctx->b,
4417 .type = WREPL_TYPE_SGROUP,
4418 .state = WREPL_STATE_ACTIVE,
4419 .node = WREPL_NODE_B,
4420 .is_static = false,
4421 .num_ips = ARRAY_SIZE(addresses_A_3_4_OWNER_B),
4422 .ips = addresses_A_3_4_OWNER_B,
4423 .sgroup_merge = true,
4424 .merge_owner = &ctx->b,
4425 }
4426 },
4427 {
4428 .line = __location__,
4429 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4430 .cleanup= true,
4431 .r1 = {
4432 .owner = &ctx->b,
4433 .type = WREPL_TYPE_SGROUP,
4434 .state = WREPL_STATE_ACTIVE,
4435 .node = WREPL_NODE_B,
4436 .is_static = false,
4437 .num_ips = 0,
4438 .ips = NULL,
4439 .apply_expected = false,
4440 },
4441 .r2 = {
4442 .owner = &ctx->x,
4443 .type = WREPL_TYPE_SGROUP,
4444 .state = WREPL_STATE_ACTIVE,
4445 .node = WREPL_NODE_B,
4446 .is_static = false,
4447 .num_ips = 0,
4448 .ips = NULL,
4449 .apply_expected = false,
4450 }
4451 },
4452 /*
4453 * sgroup,active vs. sgroup,active partly different addresses, special case...
4454 * => should be merged
4455 */
4456 {
4457 .line = __location__,
4458 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4459 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4_X_1_2 => C:B_3_4_X_1_2_3_4",
4460 .extra = true,
4461 .r1 = {
4462 .owner = &ctx->a,
4463 .type = WREPL_TYPE_SGROUP,
4464 .state = WREPL_STATE_ACTIVE,
4465 .node = WREPL_NODE_B,
4466 .is_static = false,
4467 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4468 .ips = addresses_B_3_4_X_3_4,
4469 .apply_expected = true,
4470 },
4471 .r2 = {
4472 .owner = &ctx->b,
4473 .type = WREPL_TYPE_SGROUP,
4474 .state = WREPL_STATE_ACTIVE,
4475 .node = WREPL_NODE_B,
4476 .is_static = false,
4477 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_1_2),
4478 .ips = addresses_B_3_4_X_1_2,
4479 .sgroup_merge = true,
4480 .sgroup_cleanup = false
4481 }
4482 },
4483 {
4484 .line = __location__,
4485 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4486 .cleanup= true,
4487 .r1 = {
4488 .owner = &ctx->b,
4489 .type = WREPL_TYPE_SGROUP,
4490 .state = WREPL_STATE_ACTIVE,
4491 .node = WREPL_NODE_B,
4492 .is_static = false,
4493 .num_ips = 0,
4494 .ips = NULL,
4495 .apply_expected = false,
4496 },
4497 .r2 = {
4498 .owner = &ctx->x,
4499 .type = WREPL_TYPE_SGROUP,
4500 .state = WREPL_STATE_ACTIVE,
4501 .node = WREPL_NODE_B,
4502 .is_static = false,
4503 .num_ips = 0,
4504 .ips = NULL,
4505 .apply_expected = false,
4506 }
4507 },
4508 /*
4509 * sgroup,active vs. sgroup,active different addresses, special case...
4510 * => should be merged
4511 */
4512 {
4513 .line = __location__,
4514 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4515 .comment= "A:A_3_4_B_3_4 vs. B:NULL => B:A_3_4",
4516 .extra = true,
4517 .r1 = {
4518 .owner = &ctx->a,
4519 .type = WREPL_TYPE_SGROUP,
4520 .state = WREPL_STATE_ACTIVE,
4521 .node = WREPL_NODE_B,
4522 .is_static = false,
4523 .num_ips = ARRAY_SIZE(addresses_A_3_4_B_3_4),
4524 .ips = addresses_A_3_4_B_3_4,
4525 .apply_expected = true,
4526 },
4527 .r2 = {
4528 .owner = &ctx->b,
4529 .type = WREPL_TYPE_SGROUP,
4530 .state = WREPL_STATE_ACTIVE,
4531 .node = WREPL_NODE_B,
4532 .is_static = false,
4533 .num_ips = 0,
4534 .ips = NULL,
4535 .sgroup_merge = true,
4536 .merge_owner = &ctx->b,
4537 .sgroup_cleanup = true
4538 }
4539 },
4540 {
4541 .line = __location__,
4542 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4543 .cleanup= true,
4544 .r1 = {
4545 .owner = &ctx->a,
4546 .type = WREPL_TYPE_SGROUP,
4547 .state = WREPL_STATE_ACTIVE,
4548 .node = WREPL_NODE_B,
4549 .is_static = false,
4550 .num_ips = 0,
4551 .ips = NULL,
4552 .apply_expected = false,
4553 },
4554 .r2 = {
4555 .owner = &ctx->a,
4556 .type = WREPL_TYPE_UNIQUE,
4557 .state = WREPL_STATE_TOMBSTONE,
4558 .node = WREPL_NODE_B,
4559 .is_static = false,
4560 .num_ips = ARRAY_SIZE(addresses_A_1),
4561 .ips = addresses_A_1,
4562 .apply_expected = true,
4563 }
4564 },
4565 /*
4566 * sgroup,active vs. sgroup,active different addresses, special case...
4567 * => should be merged
4568 */
4569 {
4570 .line = __location__,
4571 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4572 .comment= "A:B_3_4_X_3_4 vs. B:NULL => B:X_3_4",
4573 .extra = true,
4574 .r1 = {
4575 .owner = &ctx->a,
4576 .type = WREPL_TYPE_SGROUP,
4577 .state = WREPL_STATE_ACTIVE,
4578 .node = WREPL_NODE_B,
4579 .is_static = false,
4580 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4581 .ips = addresses_B_3_4_X_3_4,
4582 .apply_expected = true,
4583 },
4584 .r2 = {
4585 .owner = &ctx->b,
4586 .type = WREPL_TYPE_SGROUP,
4587 .state = WREPL_STATE_ACTIVE,
4588 .node = WREPL_NODE_B,
4589 .is_static = false,
4590 .num_ips = 0,
4591 .ips = NULL,
4592 .sgroup_merge = true,
4593 .merge_owner = &ctx->b,
4594 .sgroup_cleanup = true
4595 }
4596 },
4597 {
4598 .line = __location__,
4599 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4600 .cleanup= true,
4601 .r1 = {
4602 .owner = &ctx->x,
4603 .type = WREPL_TYPE_SGROUP,
4604 .state = WREPL_STATE_ACTIVE,
4605 .node = WREPL_NODE_B,
4606 .is_static = false,
4607 .num_ips = 0,
4608 .ips = NULL,
4609 .apply_expected = false,
4610 },
4611 .r2 = {
4612 .owner = &ctx->x,
4613 .type = WREPL_TYPE_UNIQUE,
4614 .state = WREPL_STATE_TOMBSTONE,
4615 .node = WREPL_NODE_B,
4616 .is_static = false,
4617 .num_ips = ARRAY_SIZE(addresses_A_1),
4618 .ips = addresses_A_1,
4619 .apply_expected = true,
4620 }
4621 },
4622
4623 /*
4624 * sgroup,active vs. sgroup,tombstone different no addresses, special
4625 * => should be replaced
4626 */
4627 {
4628 .line = __location__,
4629 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4630 .comment= "A:B_3_4_X_3_4 vs. B:NULL => B:NULL",
4631 .extra = true,
4632 .r1 = {
4633 .owner = &ctx->a,
4634 .type = WREPL_TYPE_SGROUP,
4635 .state = WREPL_STATE_ACTIVE,
4636 .node = WREPL_NODE_B,
4637 .is_static = false,
4638 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4639 .ips = addresses_B_3_4_X_3_4,
4640 .apply_expected = true,
4641 },
4642 .r2 = {
4643 .owner = &ctx->b,
4644 .type = WREPL_TYPE_SGROUP,
4645 .state = WREPL_STATE_TOMBSTONE,
4646 .node = WREPL_NODE_B,
4647 .is_static = false,
4648 .num_ips = 0,
4649 .ips = NULL,
4650 .apply_expected = true,
4651 }
4652 },
4653 /*
4654 * sgroup,active vs. sgroup,tombstone different addresses
4655 * => should be replaced
4656 */
4657 {
4658 .line = __location__,
4659 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4660 .comment= "A:B_3_4_X_3_4 vs. B:A_3_4 => B:A_3_4",
4661 .extra = true,
4662 .r1 = {
4663 .owner = &ctx->a,
4664 .type = WREPL_TYPE_SGROUP,
4665 .state = WREPL_STATE_ACTIVE,
4666 .node = WREPL_NODE_B,
4667 .is_static = false,
4668 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4669 .ips = addresses_B_3_4_X_3_4,
4670 .apply_expected = true,
4671 },
4672 .r2 = {
4673 .owner = &ctx->b,
4674 .type = WREPL_TYPE_SGROUP,
4675 .state = WREPL_STATE_TOMBSTONE,
4676 .node = WREPL_NODE_B,
4677 .is_static = false,
4678 .num_ips = ARRAY_SIZE(addresses_A_3_4),
4679 .ips = addresses_A_3_4,
4680 .apply_expected = true,
4681 }
4682 },
4683 /*
4684 * sgroup,active vs. sgroup,tombstone subset addresses
4685 * => should be replaced
4686 */
4687 {
4688 .line = __location__,
4689 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4690 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4 => B:B_3_4",
4691 .extra = true,
4692 .r1 = {
4693 .owner = &ctx->a,
4694 .type = WREPL_TYPE_SGROUP,
4695 .state = WREPL_STATE_ACTIVE,
4696 .node = WREPL_NODE_B,
4697 .is_static = false,
4698 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4699 .ips = addresses_B_3_4_X_3_4,
4700 .apply_expected = true,
4701 },
4702 .r2 = {
4703 .owner = &ctx->b,
4704 .type = WREPL_TYPE_SGROUP,
4705 .state = WREPL_STATE_TOMBSTONE,
4706 .node = WREPL_NODE_B,
4707 .is_static = false,
4708 .num_ips = ARRAY_SIZE(addresses_B_3_4),
4709 .ips = addresses_B_3_4,
4710 .apply_expected = true,
4711 }
4712 },
4713 /*
4714 * sgroup,active vs. sgroup,active same addresses
4715 * => should be replaced
4716 */
4717 {
4718 .line = __location__,
4719 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4720 .comment= "A:B_3_4_X_3_4 vs. B:B_3_4_X_3_4 => B:B_3_4_X_3_4",
4721 .extra = true,
4722 .r1 = {
4723 .owner = &ctx->a,
4724 .type = WREPL_TYPE_SGROUP,
4725 .state = WREPL_STATE_ACTIVE,
4726 .node = WREPL_NODE_B,
4727 .is_static = false,
4728 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4729 .ips = addresses_B_3_4_X_3_4,
4730 .apply_expected = true,
4731 },
4732 .r2 = {
4733 .owner = &ctx->b,
4734 .type = WREPL_TYPE_SGROUP,
4735 .state = WREPL_STATE_TOMBSTONE,
4736 .node = WREPL_NODE_B,
4737 .is_static = false,
4738 .num_ips = ARRAY_SIZE(addresses_B_3_4_X_3_4),
4739 .ips = addresses_B_3_4_X_3_4,
4740 .apply_expected = true,
4741 }
4742 },
4743
4744 /*
4745 * This should be the last record in this array,
4746 * we need to make sure the we leave a tombstoned unique entry
4747 * owned by OWNER_A
4748 */
4749 {
4750 .line = __location__,
4751 .name = _NBT_NAME("_DIFF_OWNER", 0x00, NULL),
4752 .cleanup= true,
4753 .r1 = {
4754 .owner = &ctx->a,
4755 .type = WREPL_TYPE_UNIQUE,
4756 .state = WREPL_STATE_TOMBSTONE,
4757 .node = WREPL_NODE_B,
4758 .is_static = false,
4759 .num_ips = ARRAY_SIZE(addresses_A_1),
4760 .ips = addresses_A_1,
4761 .apply_expected = true
4762 },
4763 .r2 = {
4764 .owner = &ctx->a,
4765 .type = WREPL_TYPE_UNIQUE,
4766 .state = WREPL_STATE_TOMBSTONE,
4767 .node = WREPL_NODE_B,
4768 .is_static = false,
4769 .num_ips = ARRAY_SIZE(addresses_A_1),
4770 .ips = addresses_A_1,
4771 .apply_expected = true
4772 }
4773 }}; /* do not add entries here, this should be the last record! */
4774
4775 wins_name_r1 = &wins_name1;
4776 wins_name_r2 = &wins_name2;
4777
4778 torture_comment(tctx, "Test Replica Conflicts with different owners\n");
4779
4780 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
4781
4782 if (!records[i].extra && !records[i].cleanup) {
4783 /* we should test the worst cases */
4784 if (records[i].r2.apply_expected && records[i].r1.ips==records[i].r2.ips) {
4785 torture_comment(tctx, "(%s) Programmer error, invalid record[%u]: %s\n",
4786 __location__, i, records[i].line);
4787 return false;
4788 } else if (!records[i].r2.apply_expected && records[i].r1.ips!=records[i].r2.ips) {
4789 torture_comment(tctx, "(%s) Programmer error, invalid record[%u]: %s\n",
4790 __location__, i, records[i].line);
4791 return false;
4792 }
4793 }
4794
4795 if (!records[i].cleanup) {
4796 const char *expected;
4797 const char *ips;
4798
4799 if (records[i].r2.sgroup_merge) {
4800 expected = "SGROUP_MERGE";
4801 } else if (records[i].r2.apply_expected) {
4802 expected = "REPLACE";
4803 } else {
4804 expected = "NOT REPLACE";
4805 }
4806
4807 if (!records[i].r1.ips && !records[i].r2.ips) {
4808 ips = "with no ip(s)";
4809 } else if (records[i].r1.ips==records[i].r2.ips) {
4810 ips = "with same ip(s)";
4811 } else {
4812 ips = "with different ip(s)";
4813 }
4814
4815 torture_comment(tctx, "%s,%s%s vs. %s,%s%s %s => %s\n",
4816 wrepl_name_type_string(records[i].r1.type),
4817 wrepl_name_state_string(records[i].r1.state),
4818 (records[i].r1.is_static?",static":""),
4819 wrepl_name_type_string(records[i].r2.type),
4820 wrepl_name_state_string(records[i].r2.state),
4821 (records[i].r2.is_static?",static":""),
4822 (records[i].comment?records[i].comment:ips),
4823 expected);
4824 }
4825
4826 /*
4827 * Setup R1
4828 */
4829 wins_name_r1->name = &records[i].name;
4830 wins_name_r1->flags = WREPL_NAME_FLAGS(records[i].r1.type,
4831 records[i].r1.state,
4832 records[i].r1.node,
4833 records[i].r1.is_static);
4834 wins_name_r1->id = ++records[i].r1.owner->max_version;
4835 if (wins_name_r1->flags & 2) {
4836 wins_name_r1->addresses.addresses.num_ips = records[i].r1.num_ips;
4837 wins_name_r1->addresses.addresses.ips = discard_const(records[i].r1.ips);
4838 } else {
4839 wins_name_r1->addresses.ip = records[i].r1.ips[0].ip;
4840 }
4841 wins_name_r1->unknown = "255.255.255.255";
4842
4843 /* now apply R1 */
4844 ret &= test_wrepl_update_one(tctx, ctx, records[i].r1.owner, wins_name_r1);
4845 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4846 wins_name_r1, records[i].r1.apply_expected);
4847
4848 /*
4849 * Setup R2
4850 */
4851 wins_name_r2->name = &records[i].name;
4852 wins_name_r2->flags = WREPL_NAME_FLAGS(records[i].r2.type,
4853 records[i].r2.state,
4854 records[i].r2.node,
4855 records[i].r2.is_static);
4856 wins_name_r2->id = ++records[i].r2.owner->max_version;
4857 if (wins_name_r2->flags & 2) {
4858 wins_name_r2->addresses.addresses.num_ips = records[i].r2.num_ips;
4859 wins_name_r2->addresses.addresses.ips = discard_const(records[i].r2.ips);
4860 } else {
4861 wins_name_r2->addresses.ip = records[i].r2.ips[0].ip;
4862 }
4863 wins_name_r2->unknown = "255.255.255.255";
4864
4865 /* now apply R2 */
4866 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4867 if (records[i].r1.state == WREPL_STATE_RELEASED) {
4868 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4869 wins_name_r1, false);
4870 } else if (records[i].r2.sgroup_merge) {
4871 ret &= test_wrepl_sgroup_merged(tctx, ctx, records[i].r2.merge_owner,
4872 records[i].r1.owner,
4873 records[i].r1.num_ips, records[i].r1.ips,
4874 records[i].r2.owner,
4875 records[i].r2.num_ips, records[i].r2.ips,
4876 wins_name_r2);
4877 } else if (records[i].r1.owner != records[i].r2.owner) {
4878 bool _expected;
4879 _expected = (records[i].r1.apply_expected && !records[i].r2.apply_expected);
4880 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r1.owner,
4881 wins_name_r1, _expected);
4882 }
4883 if (records[i].r2.state == WREPL_STATE_RELEASED) {
4884 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner,
4885 wins_name_r2, false);
4886 } else if (!records[i].r2.sgroup_merge) {
4887 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner,
4888 wins_name_r2, records[i].r2.apply_expected);
4889 }
4890
4891 if (records[i].r2.sgroup_cleanup) {
4892 if (!ret) {
4893 torture_comment(tctx, "failed before sgroup_cleanup record[%u]: %s\n", i, records[i].line);
4894 return ret;
4895 }
4896
4897 /* clean up the SGROUP record */
4898 wins_name_r1->name = &records[i].name;
4899 wins_name_r1->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4900 WREPL_STATE_ACTIVE,
4901 WREPL_NODE_B, false);
4902 wins_name_r1->id = ++records[i].r1.owner->max_version;
4903 wins_name_r1->addresses.addresses.num_ips = 0;
4904 wins_name_r1->addresses.addresses.ips = NULL;
4905 wins_name_r1->unknown = "255.255.255.255";
4906 ret &= test_wrepl_update_one(tctx, ctx, records[i].r1.owner, wins_name_r1);
4907
4908 /* here we test how names from an owner are deleted */
4909 if (records[i].r2.sgroup_merge && records[i].r2.num_ips) {
4910 ret &= test_wrepl_sgroup_merged(tctx, ctx, NULL,
4911 records[i].r2.owner,
4912 records[i].r2.num_ips, records[i].r2.ips,
4913 records[i].r1.owner,
4914 0, NULL,
4915 wins_name_r2);
4916 }
4917
4918 /* clean up the SGROUP record */
4919 wins_name_r2->name = &records[i].name;
4920 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4921 WREPL_STATE_ACTIVE,
4922 WREPL_NODE_B, false);
4923 wins_name_r2->id = ++records[i].r2.owner->max_version;
4924 wins_name_r2->addresses.addresses.num_ips = 0;
4925 wins_name_r2->addresses.addresses.ips = NULL;
4926 wins_name_r2->unknown = "255.255.255.255";
4927 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4928
4929 /* take ownership of the SGROUP record */
4930 wins_name_r2->name = &records[i].name;
4931 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4932 WREPL_STATE_ACTIVE,
4933 WREPL_NODE_B, false);
4934 wins_name_r2->id = ++records[i].r2.owner->max_version;
4935 wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
4936 wins_name_r2->addresses.addresses.ips = discard_const(addresses_B_1);
4937 wins_name_r2->unknown = "255.255.255.255";
4938 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4939 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
4940
4941 /* overwrite the SGROUP record with unique,tombstone */
4942 wins_name_r2->name = &records[i].name;
4943 wins_name_r2->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
4944 WREPL_STATE_TOMBSTONE,
4945 WREPL_NODE_B, false);
4946 wins_name_r2->id = ++records[i].r2.owner->max_version;
4947 wins_name_r2->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
4948 wins_name_r2->addresses.addresses.ips = discard_const(addresses_B_1);
4949 wins_name_r2->unknown = "255.255.255.255";
4950 ret &= test_wrepl_update_one(tctx, ctx, records[i].r2.owner, wins_name_r2);
4951 ret &= test_wrepl_is_applied(tctx, ctx, records[i].r2.owner, wins_name_r2, true);
4952
4953 if (!ret) {
4954 torture_comment(tctx, "failed in sgroup_cleanup record[%u]: %s\n", i, records[i].line);
4955 return ret;
4956 }
4957 }
4958
4959 /* the first one is a cleanup run */
4960 if (!ret && i == 0) ret = true;
4961
4962 if (!ret) {
4963 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
4964 return ret;
4965 }
4966 }
4967
4968 return ret;
4969 }
4970
4971 static bool test_conflict_owned_released_vs_replica(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
4972 struct test_wrepl_conflict_conn *ctx)
4973 {
4974 bool ret = true;
4975 NTSTATUS status;
4976 struct wrepl_wins_name wins_name_;
4977 struct wrepl_wins_name *wins_name = &wins_name_;
4978 struct nbt_name_register name_register_;
4979 struct nbt_name_register *name_register = &name_register_;
4980 struct nbt_name_release release_;
4981 struct nbt_name_release *release = &release_;
4982 uint32_t i;
4983 struct {
4984 const char *line; /* just better debugging */
4985 struct nbt_name name;
4986 struct {
4987 uint32_t nb_flags;
4988 bool mhomed;
4989 uint32_t num_ips;
4990 const struct wrepl_ip *ips;
4991 bool apply_expected;
4992 } wins;
4993 struct {
4994 enum wrepl_name_type type;
4995 enum wrepl_name_state state;
4996 enum wrepl_name_node node;
4997 bool is_static;
4998 uint32_t num_ips;
4999 const struct wrepl_ip *ips;
5000 bool apply_expected;
5001 } replica;
5002 } records[] = {
5003 /*
5004 * unique vs. unique section
5005 */
5006 /*
5007 * unique,released vs. unique,active with same ip(s)
5008 */
5009 {
5010 .line = __location__,
5011 .name = _NBT_NAME("_UR_UA_SI", 0x00, NULL),
5012 .wins = {
5013 .nb_flags = 0,
5014 .mhomed = false,
5015 .num_ips = ctx->addresses_best_num,
5016 .ips = ctx->addresses_best,
5017 .apply_expected = true
5018 },
5019 .replica= {
5020 .type = WREPL_TYPE_UNIQUE,
5021 .state = WREPL_STATE_ACTIVE,
5022 .node = WREPL_NODE_B,
5023 .is_static = false,
5024 .num_ips = ctx->addresses_best_num,
5025 .ips = ctx->addresses_best,
5026 .apply_expected = true
5027 },
5028 },
5029 /*
5030 * unique,released vs. unique,active with different ip(s)
5031 */
5032 {
5033 .line = __location__,
5034 .name = _NBT_NAME("_UR_UA_DI", 0x00, NULL),
5035 .wins = {
5036 .nb_flags = 0,
5037 .mhomed = false,
5038 .num_ips = ctx->addresses_best_num,
5039 .ips = ctx->addresses_best,
5040 .apply_expected = true
5041 },
5042 .replica= {
5043 .type = WREPL_TYPE_UNIQUE,
5044 .state = WREPL_STATE_ACTIVE,
5045 .node = WREPL_NODE_B,
5046 .is_static = false,
5047 .num_ips = ARRAY_SIZE(addresses_B_1),
5048 .ips = addresses_B_1,
5049 .apply_expected = true
5050 },
5051 },
5052 /*
5053 * unique,released vs. unique,tombstone with same ip(s)
5054 */
5055 {
5056 .line = __location__,
5057 .name = _NBT_NAME("_UR_UT_SI", 0x00, NULL),
5058 .wins = {
5059 .nb_flags = 0,
5060 .mhomed = false,
5061 .num_ips = ctx->addresses_best_num,
5062 .ips = ctx->addresses_best,
5063 .apply_expected = true
5064 },
5065 .replica= {
5066 .type = WREPL_TYPE_UNIQUE,
5067 .state = WREPL_STATE_TOMBSTONE,
5068 .node = WREPL_NODE_B,
5069 .is_static = false,
5070 .num_ips = ctx->addresses_best_num,
5071 .ips = ctx->addresses_best,
5072 .apply_expected = true
5073 },
5074 },
5075 /*
5076 * unique,released vs. unique,tombstone with different ip(s)
5077 */
5078 {
5079 .line = __location__,
5080 .name = _NBT_NAME("_UR_UT_DI", 0x00, NULL),
5081 .wins = {
5082 .nb_flags = 0,
5083 .mhomed = false,
5084 .num_ips = ctx->addresses_best_num,
5085 .ips = ctx->addresses_best,
5086 .apply_expected = true
5087 },
5088 .replica= {
5089 .type = WREPL_TYPE_UNIQUE,
5090 .state = WREPL_STATE_TOMBSTONE,
5091 .node = WREPL_NODE_B,
5092 .is_static = false,
5093 .num_ips = ARRAY_SIZE(addresses_B_1),
5094 .ips = addresses_B_1,
5095 .apply_expected = true
5096 },
5097 },
5098 /*
5099 * unique vs. group section
5100 */
5101 /*
5102 * unique,released vs. group,active with same ip(s)
5103 */
5104 {
5105 .line = __location__,
5106 .name = _NBT_NAME("_UR_GA_SI", 0x00, NULL),
5107 .wins = {
5108 .nb_flags = 0,
5109 .mhomed = false,
5110 .num_ips = ctx->addresses_best_num,
5111 .ips = ctx->addresses_best,
5112 .apply_expected = true
5113 },
5114 .replica= {
5115 .type = WREPL_TYPE_GROUP,
5116 .state = WREPL_STATE_ACTIVE,
5117 .node = WREPL_NODE_B,
5118 .is_static = false,
5119 .num_ips = ctx->addresses_best_num,
5120 .ips = ctx->addresses_best,
5121 .apply_expected = true
5122 },
5123 },
5124 /*
5125 * unique,released vs. group,active with different ip(s)
5126 */
5127 {
5128 .line = __location__,
5129 .name = _NBT_NAME("_UR_GA_DI", 0x00, NULL),
5130 .wins = {
5131 .nb_flags = 0,
5132 .mhomed = false,
5133 .num_ips = ctx->addresses_best_num,
5134 .ips = ctx->addresses_best,
5135 .apply_expected = true
5136 },
5137 .replica= {
5138 .type = WREPL_TYPE_GROUP,
5139 .state = WREPL_STATE_ACTIVE,
5140 .node = WREPL_NODE_B,
5141 .is_static = false,
5142 .num_ips = ARRAY_SIZE(addresses_B_1),
5143 .ips = addresses_B_1,
5144 .apply_expected = true
5145 },
5146 },
5147 /*
5148 * unique,released vs. group,tombstone with same ip(s)
5149 */
5150 {
5151 .line = __location__,
5152 .name = _NBT_NAME("_UR_GT_SI", 0x00, NULL),
5153 .wins = {
5154 .nb_flags = 0,
5155 .mhomed = false,
5156 .num_ips = ctx->addresses_best_num,
5157 .ips = ctx->addresses_best,
5158 .apply_expected = true
5159 },
5160 .replica= {
5161 .type = WREPL_TYPE_GROUP,
5162 .state = WREPL_STATE_TOMBSTONE,
5163 .node = WREPL_NODE_B,
5164 .is_static = false,
5165 .num_ips = ctx->addresses_best_num,
5166 .ips = ctx->addresses_best,
5167 .apply_expected = true
5168 },
5169 },
5170 /*
5171 * unique,released vs. group,tombstone with different ip(s)
5172 */
5173 {
5174 .line = __location__,
5175 .name = _NBT_NAME("_UR_GT_DI", 0x00, NULL),
5176 .wins = {
5177 .nb_flags = 0,
5178 .mhomed = false,
5179 .num_ips = ctx->addresses_best_num,
5180 .ips = ctx->addresses_best,
5181 .apply_expected = true
5182 },
5183 .replica= {
5184 .type = WREPL_TYPE_GROUP,
5185 .state = WREPL_STATE_TOMBSTONE,
5186 .node = WREPL_NODE_B,
5187 .is_static = false,
5188 .num_ips = ARRAY_SIZE(addresses_B_1),
5189 .ips = addresses_B_1,
5190 .apply_expected = true
5191 },
5192 },
5193 /*
5194 * unique vs. special group section
5195 */
5196 /*
5197 * unique,released vs. sgroup,active with same ip(s)
5198 */
5199 {
5200 .line = __location__,
5201 .name = _NBT_NAME("_UR_SA_SI", 0x00, NULL),
5202 .wins = {
5203 .nb_flags = 0,
5204 .mhomed = false,
5205 .num_ips = ctx->addresses_best_num,
5206 .ips = ctx->addresses_best,
5207 .apply_expected = true
5208 },
5209 .replica= {
5210 .type = WREPL_TYPE_SGROUP,
5211 .state = WREPL_STATE_ACTIVE,
5212 .node = WREPL_NODE_B,
5213 .is_static = false,
5214 .num_ips = ctx->addresses_best_num,
5215 .ips = ctx->addresses_best,
5216 .apply_expected = true
5217 },
5218 },
5219 /*
5220 * unique,released vs. sgroup,active with different ip(s)
5221 */
5222 {
5223 .line = __location__,
5224 .name = _NBT_NAME("_UR_SA_DI", 0x00, NULL),
5225 .wins = {
5226 .nb_flags = 0,
5227 .mhomed = false,
5228 .num_ips = ctx->addresses_best_num,
5229 .ips = ctx->addresses_best,
5230 .apply_expected = true
5231 },
5232 .replica= {
5233 .type = WREPL_TYPE_SGROUP,
5234 .state = WREPL_STATE_ACTIVE,
5235 .node = WREPL_NODE_B,
5236 .is_static = false,
5237 .num_ips = ARRAY_SIZE(addresses_B_1),
5238 .ips = addresses_B_1,
5239 .apply_expected = true
5240 },
5241 },
5242 /*
5243 * unique,released vs. sgroup,tombstone with same ip(s)
5244 */
5245 {
5246 .line = __location__,
5247 .name = _NBT_NAME("_UR_ST_SI", 0x00, NULL),
5248 .wins = {
5249 .nb_flags = 0,
5250 .mhomed = false,
5251 .num_ips = ctx->addresses_best_num,
5252 .ips = ctx->addresses_best,
5253 .apply_expected = true
5254 },
5255 .replica= {
5256 .type = WREPL_TYPE_SGROUP,
5257 .state = WREPL_STATE_TOMBSTONE,
5258 .node = WREPL_NODE_B,
5259 .is_static = false,
5260 .num_ips = ctx->addresses_best_num,
5261 .ips = ctx->addresses_best,
5262 .apply_expected = true
5263 },
5264 },
5265 /*
5266 * unique,released vs. sgroup,tombstone with different ip(s)
5267 */
5268 {
5269 .line = __location__,
5270 .name = _NBT_NAME("_UR_ST_DI", 0x00, NULL),
5271 .wins = {
5272 .nb_flags = 0,
5273 .mhomed = false,
5274 .num_ips = ctx->addresses_best_num,
5275 .ips = ctx->addresses_best,
5276 .apply_expected = true
5277 },
5278 .replica= {
5279 .type = WREPL_TYPE_SGROUP,
5280 .state = WREPL_STATE_TOMBSTONE,
5281 .node = WREPL_NODE_B,
5282 .is_static = false,
5283 .num_ips = ARRAY_SIZE(addresses_B_1),
5284 .ips = addresses_B_1,
5285 .apply_expected = true
5286 },
5287 },
5288 /*
5289 * unique vs. multi homed section
5290 */
5291 /*
5292 * unique,released vs. mhomed,active with same ip(s)
5293 */
5294 {
5295 .line = __location__,
5296 .name = _NBT_NAME("_UR_MA_SI", 0x00, NULL),
5297 .wins = {
5298 .nb_flags = 0,
5299 .mhomed = false,
5300 .num_ips = ctx->addresses_best_num,
5301 .ips = ctx->addresses_best,
5302 .apply_expected = true
5303 },
5304 .replica= {
5305 .type = WREPL_TYPE_MHOMED,
5306 .state = WREPL_STATE_ACTIVE,
5307 .node = WREPL_NODE_B,
5308 .is_static = false,
5309 .num_ips = ctx->addresses_best_num,
5310 .ips = ctx->addresses_best,
5311 .apply_expected = true
5312 },
5313 },
5314 /*
5315 * unique,released vs. mhomed,active with different ip(s)
5316 */
5317 {
5318 .line = __location__,
5319 .name = _NBT_NAME("_UR_MA_DI", 0x00, NULL),
5320 .wins = {
5321 .nb_flags = 0,
5322 .mhomed = false,
5323 .num_ips = ctx->addresses_best_num,
5324 .ips = ctx->addresses_best,
5325 .apply_expected = true
5326 },
5327 .replica= {
5328 .type = WREPL_TYPE_MHOMED,
5329 .state = WREPL_STATE_ACTIVE,
5330 .node = WREPL_NODE_B,
5331 .is_static = false,
5332 .num_ips = ARRAY_SIZE(addresses_B_1),
5333 .ips = addresses_B_1,
5334 .apply_expected = true
5335 },
5336 },
5337 /*
5338 * unique,released vs. mhomed,tombstone with same ip(s)
5339 */
5340 {
5341 .line = __location__,
5342 .name = _NBT_NAME("_UR_MT_SI", 0x00, NULL),
5343 .wins = {
5344 .nb_flags = 0,
5345 .mhomed = false,
5346 .num_ips = ctx->addresses_best_num,
5347 .ips = ctx->addresses_best,
5348 .apply_expected = true
5349 },
5350 .replica= {
5351 .type = WREPL_TYPE_MHOMED,
5352 .state = WREPL_STATE_TOMBSTONE,
5353 .node = WREPL_NODE_B,
5354 .is_static = false,
5355 .num_ips = ctx->addresses_best_num,
5356 .ips = ctx->addresses_best,
5357 .apply_expected = true
5358 },
5359 },
5360 /*
5361 * unique,released vs. mhomed,tombstone with different ip(s)
5362 */
5363 {
5364 .line = __location__,
5365 .name = _NBT_NAME("_UR_MT_DI", 0x00, NULL),
5366 .wins = {
5367 .nb_flags = 0,
5368 .mhomed = false,
5369 .num_ips = ctx->addresses_best_num,
5370 .ips = ctx->addresses_best,
5371 .apply_expected = true
5372 },
5373 .replica= {
5374 .type = WREPL_TYPE_MHOMED,
5375 .state = WREPL_STATE_TOMBSTONE,
5376 .node = WREPL_NODE_B,
5377 .is_static = false,
5378 .num_ips = ARRAY_SIZE(addresses_B_1),
5379 .ips = addresses_B_1,
5380 .apply_expected = true
5381 },
5382 },
5383 /*
5384 * group vs. unique section
5385 */
5386 /*
5387 * group,released vs. unique,active with same ip(s)
5388 */
5389 {
5390 .line = __location__,
5391 .name = _NBT_NAME("_GR_UA_SI", 0x00, NULL),
5392 .wins = {
5393 .nb_flags = NBT_NM_GROUP,
5394 .mhomed = false,
5395 .num_ips = ctx->addresses_best_num,
5396 .ips = ctx->addresses_best,
5397 .apply_expected = true
5398 },
5399 .replica= {
5400 .type = WREPL_TYPE_UNIQUE,
5401 .state = WREPL_STATE_ACTIVE,
5402 .node = WREPL_NODE_B,
5403 .is_static = false,
5404 .num_ips = ctx->addresses_best_num,
5405 .ips = ctx->addresses_best,
5406 .apply_expected = false
5407 },
5408 },
5409 /*
5410 * group,released vs. unique,active with different ip(s)
5411 */
5412 {
5413 .line = __location__,
5414 .name = _NBT_NAME("_GR_UA_DI", 0x00, NULL),
5415 .wins = {
5416 .nb_flags = NBT_NM_GROUP,
5417 .mhomed = false,
5418 .num_ips = ctx->addresses_best_num,
5419 .ips = ctx->addresses_best,
5420 .apply_expected = true
5421 },
5422 .replica= {
5423 .type = WREPL_TYPE_UNIQUE,
5424 .state = WREPL_STATE_ACTIVE,
5425 .node = WREPL_NODE_B,
5426 .is_static = false,
5427 .num_ips = ARRAY_SIZE(addresses_B_1),
5428 .ips = addresses_B_1,
5429 .apply_expected = false
5430 },
5431 },
5432 /*
5433 * group,released vs. unique,tombstone with same ip(s)
5434 */
5435 {
5436 .line = __location__,
5437 .name = _NBT_NAME("_GR_UT_SI", 0x00, NULL),
5438 .wins = {
5439 .nb_flags = NBT_NM_GROUP,
5440 .mhomed = false,
5441 .num_ips = ctx->addresses_best_num,
5442 .ips = ctx->addresses_best,
5443 .apply_expected = true
5444 },
5445 .replica= {
5446 .type = WREPL_TYPE_UNIQUE,
5447 .state = WREPL_STATE_TOMBSTONE,
5448 .node = WREPL_NODE_B,
5449 .is_static = false,
5450 .num_ips = ctx->addresses_best_num,
5451 .ips = ctx->addresses_best,
5452 .apply_expected = false
5453 },
5454 },
5455 /*
5456 * group,released vs. unique,tombstone with different ip(s)
5457 */
5458 {
5459 .line = __location__,
5460 .name = _NBT_NAME("_GR_UT_DI", 0x00, NULL),
5461 .wins = {
5462 .nb_flags = NBT_NM_GROUP,
5463 .mhomed = false,
5464 .num_ips = ctx->addresses_best_num,
5465 .ips = ctx->addresses_best,
5466 .apply_expected = true
5467 },
5468 .replica= {
5469 .type = WREPL_TYPE_UNIQUE,
5470 .state = WREPL_STATE_TOMBSTONE,
5471 .node = WREPL_NODE_B,
5472 .is_static = false,
5473 .num_ips = ARRAY_SIZE(addresses_B_1),
5474 .ips = addresses_B_1,
5475 .apply_expected = false
5476 },
5477 },
5478 /*
5479 * group vs. group section
5480 */
5481 /*
5482 * group,released vs. group,active with same ip(s)
5483 */
5484 {
5485 .line = __location__,
5486 .name = _NBT_NAME("_GR_GA_SI", 0x00, NULL),
5487 .wins = {
5488 .nb_flags = NBT_NM_GROUP,
5489 .mhomed = false,
5490 .num_ips = ctx->addresses_best_num,
5491 .ips = ctx->addresses_best,
5492 .apply_expected = true
5493 },
5494 .replica= {
5495 .type = WREPL_TYPE_GROUP,
5496 .state = WREPL_STATE_ACTIVE,
5497 .node = WREPL_NODE_B,
5498 .is_static = false,
5499 .num_ips = ctx->addresses_best_num,
5500 .ips = ctx->addresses_best,
5501 .apply_expected = true
5502 },
5503 },
5504 /*
5505 * group,released vs. group,active with different ip(s)
5506 */
5507 {
5508 .line = __location__,
5509 .name = _NBT_NAME("_GR_GA_DI", 0x00, NULL),
5510 .wins = {
5511 .nb_flags = NBT_NM_GROUP,
5512 .mhomed = false,
5513 .num_ips = ctx->addresses_best_num,
5514 .ips = ctx->addresses_best,
5515 .apply_expected = true
5516 },
5517 .replica= {
5518 .type = WREPL_TYPE_GROUP,
5519 .state = WREPL_STATE_ACTIVE,
5520 .node = WREPL_NODE_B,
5521 .is_static = false,
5522 .num_ips = ARRAY_SIZE(addresses_B_1),
5523 .ips = addresses_B_1,
5524 .apply_expected = true
5525 },
5526 },
5527 /*
5528 * group,released vs. group,tombstone with same ip(s)
5529 */
5530 {
5531 .line = __location__,
5532 .name = _NBT_NAME("_GR_GT_SI", 0x00, NULL),
5533 .wins = {
5534 .nb_flags = NBT_NM_GROUP,
5535 .mhomed = false,
5536 .num_ips = ctx->addresses_best_num,
5537 .ips = ctx->addresses_best,
5538 .apply_expected = true
5539 },
5540 .replica= {
5541 .type = WREPL_TYPE_GROUP,
5542 .state = WREPL_STATE_TOMBSTONE,
5543 .node = WREPL_NODE_B,
5544 .is_static = false,
5545 .num_ips = ctx->addresses_best_num,
5546 .ips = ctx->addresses_best,
5547 .apply_expected = true
5548 },
5549 },
5550 /*
5551 * group,released vs. group,tombstone with different ip(s)
5552 */
5553 {
5554 .line = __location__,
5555 .name = _NBT_NAME("_GR_GT_DI", 0x00, NULL),
5556 .wins = {
5557 .nb_flags = NBT_NM_GROUP,
5558 .mhomed = false,
5559 .num_ips = ctx->addresses_best_num,
5560 .ips = ctx->addresses_best,
5561 .apply_expected = true
5562 },
5563 .replica= {
5564 .type = WREPL_TYPE_GROUP,
5565 .state = WREPL_STATE_TOMBSTONE,
5566 .node = WREPL_NODE_B,
5567 .is_static = false,
5568 .num_ips = ARRAY_SIZE(addresses_B_1),
5569 .ips = addresses_B_1,
5570 .apply_expected = true
5571 },
5572 },
5573 /*
5574 * group vs. special group section
5575 */
5576 /*
5577 * group,released vs. sgroup,active with same ip(s)
5578 */
5579 {
5580 .line = __location__,
5581 .name = _NBT_NAME("_GR_SA_SI", 0x00, NULL),
5582 .wins = {
5583 .nb_flags = NBT_NM_GROUP,
5584 .mhomed = false,
5585 .num_ips = ctx->addresses_best_num,
5586 .ips = ctx->addresses_best,
5587 .apply_expected = true
5588 },
5589 .replica= {
5590 .type = WREPL_TYPE_SGROUP,
5591 .state = WREPL_STATE_ACTIVE,
5592 .node = WREPL_NODE_B,
5593 .is_static = false,
5594 .num_ips = ctx->addresses_best_num,
5595 .ips = ctx->addresses_best,
5596 .apply_expected = false
5597 },
5598 },
5599 /*
5600 * group,released vs. sgroup,active with different ip(s)
5601 */
5602 {
5603 .line = __location__,
5604 .name = _NBT_NAME("_GR_SA_DI", 0x00, NULL),
5605 .wins = {
5606 .nb_flags = NBT_NM_GROUP,
5607 .mhomed = false,
5608 .num_ips = ctx->addresses_best_num,
5609 .ips = ctx->addresses_best,
5610 .apply_expected = true
5611 },
5612 .replica= {
5613 .type = WREPL_TYPE_SGROUP,
5614 .state = WREPL_STATE_ACTIVE,
5615 .node = WREPL_NODE_B,
5616 .is_static = false,
5617 .num_ips = ARRAY_SIZE(addresses_B_1),
5618 .ips = addresses_B_1,
5619 .apply_expected = false
5620 },
5621 },
5622 /*
5623 * group,released vs. sgroup,tombstone with same ip(s)
5624 */
5625 {
5626 .line = __location__,
5627 .name = _NBT_NAME("_GR_ST_SI", 0x00, NULL),
5628 .wins = {
5629 .nb_flags = NBT_NM_GROUP,
5630 .mhomed = false,
5631 .num_ips = ctx->addresses_best_num,
5632 .ips = ctx->addresses_best,
5633 .apply_expected = true
5634 },
5635 .replica= {
5636 .type = WREPL_TYPE_SGROUP,
5637 .state = WREPL_STATE_TOMBSTONE,
5638 .node = WREPL_NODE_B,
5639 .is_static = false,
5640 .num_ips = ctx->addresses_best_num,
5641 .ips = ctx->addresses_best,
5642 .apply_expected = false
5643 },
5644 },
5645 /*
5646 * group,released vs. sgroup,tombstone with different ip(s)
5647 */
5648 {
5649 .line = __location__,
5650 .name = _NBT_NAME("_GR_ST_DI", 0x00, NULL),
5651 .wins = {
5652 .nb_flags = NBT_NM_GROUP,
5653 .mhomed = false,
5654 .num_ips = ctx->addresses_best_num,
5655 .ips = ctx->addresses_best,
5656 .apply_expected = true
5657 },
5658 .replica= {
5659 .type = WREPL_TYPE_SGROUP,
5660 .state = WREPL_STATE_TOMBSTONE,
5661 .node = WREPL_NODE_B,
5662 .is_static = false,
5663 .num_ips = ARRAY_SIZE(addresses_B_1),
5664 .ips = addresses_B_1,
5665 .apply_expected = false
5666 },
5667 },
5668 /*
5669 * group vs. multi homed section
5670 */
5671 /*
5672 * group,released vs. mhomed,active with same ip(s)
5673 */
5674 {
5675 .line = __location__,
5676 .name = _NBT_NAME("_GR_MA_SI", 0x00, NULL),
5677 .wins = {
5678 .nb_flags = NBT_NM_GROUP,
5679 .mhomed = false,
5680 .num_ips = ctx->addresses_best_num,
5681 .ips = ctx->addresses_best,
5682 .apply_expected = true
5683 },
5684 .replica= {
5685 .type = WREPL_TYPE_MHOMED,
5686 .state = WREPL_STATE_ACTIVE,
5687 .node = WREPL_NODE_B,
5688 .is_static = false,
5689 .num_ips = ctx->addresses_best_num,
5690 .ips = ctx->addresses_best,
5691 .apply_expected = false
5692 },
5693 },
5694 /*
5695 * group,released vs. mhomed,active with different ip(s)
5696 */
5697 {
5698 .line = __location__,
5699 .name = _NBT_NAME("_GR_MA_DI", 0x00, NULL),
5700 .wins = {
5701 .nb_flags = NBT_NM_GROUP,
5702 .mhomed = false,
5703 .num_ips = ctx->addresses_best_num,
5704 .ips = ctx->addresses_best,
5705 .apply_expected = true
5706 },
5707 .replica= {
5708 .type = WREPL_TYPE_MHOMED,
5709 .state = WREPL_STATE_ACTIVE,
5710 .node = WREPL_NODE_B,
5711 .is_static = false,
5712 .num_ips = ARRAY_SIZE(addresses_B_1),
5713 .ips = addresses_B_1,
5714 .apply_expected = false
5715 },
5716 },
5717 /*
5718 * group,released vs. mhomed,tombstone with same ip(s)
5719 */
5720 {
5721 .line = __location__,
5722 .name = _NBT_NAME("_GR_MT_SI", 0x00, NULL),
5723 .wins = {
5724 .nb_flags = NBT_NM_GROUP,
5725 .mhomed = false,
5726 .num_ips = ctx->addresses_best_num,
5727 .ips = ctx->addresses_best,
5728 .apply_expected = true
5729 },
5730 .replica= {
5731 .type = WREPL_TYPE_MHOMED,
5732 .state = WREPL_STATE_TOMBSTONE,
5733 .node = WREPL_NODE_B,
5734 .is_static = false,
5735 .num_ips = ctx->addresses_best_num,
5736 .ips = ctx->addresses_best,
5737 .apply_expected = false
5738 },
5739 },
5740 /*
5741 * group,released vs. mhomed,tombstone with different ip(s)
5742 */
5743 {
5744 .line = __location__,
5745 .name = _NBT_NAME("_GR_MT_DI", 0x00, NULL),
5746 .wins = {
5747 .nb_flags = NBT_NM_GROUP,
5748 .mhomed = false,
5749 .num_ips = ctx->addresses_best_num,
5750 .ips = ctx->addresses_best,
5751 .apply_expected = true
5752 },
5753 .replica= {
5754 .type = WREPL_TYPE_MHOMED,
5755 .state = WREPL_STATE_TOMBSTONE,
5756 .node = WREPL_NODE_B,
5757 .is_static = false,
5758 .num_ips = ARRAY_SIZE(addresses_B_1),
5759 .ips = addresses_B_1,
5760 .apply_expected = false
5761 },
5762 },
5763 /*
5764 * special group vs. unique section
5765 */
5766 /*
5767 * sgroup,released vs. unique,active with same ip(s)
5768 */
5769 {
5770 .line = __location__,
5771 .name = _NBT_NAME("_SR_UA_SI", 0x1C, NULL),
5772 .wins = {
5773 .nb_flags = NBT_NM_GROUP,
5774 .mhomed = false,
5775 .num_ips = ctx->addresses_best_num,
5776 .ips = ctx->addresses_best,
5777 .apply_expected = true
5778 },
5779 .replica= {
5780 .type = WREPL_TYPE_UNIQUE,
5781 .state = WREPL_STATE_ACTIVE,
5782 .node = WREPL_NODE_B,
5783 .is_static = false,
5784 .num_ips = ctx->addresses_best_num,
5785 .ips = ctx->addresses_best,
5786 .apply_expected = true
5787 },
5788 },
5789 /*
5790 * sgroup,released vs. unique,active with different ip(s)
5791 */
5792 {
5793 .line = __location__,
5794 .name = _NBT_NAME("_SR_UA_DI", 0x1C, NULL),
5795 .wins = {
5796 .nb_flags = NBT_NM_GROUP,
5797 .mhomed = false,
5798 .num_ips = ctx->addresses_best_num,
5799 .ips = ctx->addresses_best,
5800 .apply_expected = true
5801 },
5802 .replica= {
5803 .type = WREPL_TYPE_UNIQUE,
5804 .state = WREPL_STATE_ACTIVE,
5805 .node = WREPL_NODE_B,
5806 .is_static = false,
5807 .num_ips = ARRAY_SIZE(addresses_B_1),
5808 .ips = addresses_B_1,
5809 .apply_expected = true
5810 },
5811 },
5812 /*
5813 * sgroup,released vs. unique,tombstone with same ip(s)
5814 */
5815 {
5816 .line = __location__,
5817 .name = _NBT_NAME("_SR_UT_SI", 0x1C, NULL),
5818 .wins = {
5819 .nb_flags = NBT_NM_GROUP,
5820 .mhomed = false,
5821 .num_ips = ctx->addresses_best_num,
5822 .ips = ctx->addresses_best,
5823 .apply_expected = true
5824 },
5825 .replica= {
5826 .type = WREPL_TYPE_UNIQUE,
5827 .state = WREPL_STATE_TOMBSTONE,
5828 .node = WREPL_NODE_B,
5829 .is_static = false,
5830 .num_ips = ctx->addresses_best_num,
5831 .ips = ctx->addresses_best,
5832 .apply_expected = true
5833 },
5834 },
5835 /*
5836 * sgroup,released vs. unique,tombstone with different ip(s)
5837 */
5838 {
5839 .line = __location__,
5840 .name = _NBT_NAME("_SR_UT_DI", 0x1C, NULL),
5841 .wins = {
5842 .nb_flags = NBT_NM_GROUP,
5843 .mhomed = false,
5844 .num_ips = ctx->addresses_best_num,
5845 .ips = ctx->addresses_best,
5846 .apply_expected = true
5847 },
5848 .replica= {
5849 .type = WREPL_TYPE_UNIQUE,
5850 .state = WREPL_STATE_TOMBSTONE,
5851 .node = WREPL_NODE_B,
5852 .is_static = false,
5853 .num_ips = ARRAY_SIZE(addresses_B_1),
5854 .ips = addresses_B_1,
5855 .apply_expected = true
5856 },
5857 },
5858 /*
5859 * special group vs. group section
5860 */
5861 /*
5862 * sgroup,released vs. group,active with same ip(s)
5863 */
5864 {
5865 .line = __location__,
5866 .name = _NBT_NAME("_SR_GA_SI", 0x1C, NULL),
5867 .wins = {
5868 .nb_flags = NBT_NM_GROUP,
5869 .mhomed = false,
5870 .num_ips = ctx->addresses_best_num,
5871 .ips = ctx->addresses_best,
5872 .apply_expected = true
5873 },
5874 .replica= {
5875 .type = WREPL_TYPE_GROUP,
5876 .state = WREPL_STATE_ACTIVE,
5877 .node = WREPL_NODE_B,
5878 .is_static = false,
5879 .num_ips = ctx->addresses_best_num,
5880 .ips = ctx->addresses_best,
5881 .apply_expected = true
5882 },
5883 },
5884 /*
5885 * sgroup,released vs. group,active with different ip(s)
5886 */
5887 {
5888 .line = __location__,
5889 .name = _NBT_NAME("_SR_GA_DI", 0x1C, NULL),
5890 .wins = {
5891 .nb_flags = NBT_NM_GROUP,
5892 .mhomed = false,
5893 .num_ips = ctx->addresses_best_num,
5894 .ips = ctx->addresses_best,
5895 .apply_expected = true
5896 },
5897 .replica= {
5898 .type = WREPL_TYPE_GROUP,
5899 .state = WREPL_STATE_ACTIVE,
5900 .node = WREPL_NODE_B,
5901 .is_static = false,
5902 .num_ips = ARRAY_SIZE(addresses_B_1),
5903 .ips = addresses_B_1,
5904 .apply_expected = true
5905 },
5906 },
5907 /*
5908 * sgroup,released vs. group,tombstone with same ip(s)
5909 */
5910 {
5911 .line = __location__,
5912 .name = _NBT_NAME("_SR_GT_SI", 0x1C, NULL),
5913 .wins = {
5914 .nb_flags = NBT_NM_GROUP,
5915 .mhomed = false,
5916 .num_ips = ctx->addresses_best_num,
5917 .ips = ctx->addresses_best,
5918 .apply_expected = true
5919 },
5920 .replica= {
5921 .type = WREPL_TYPE_GROUP,
5922 .state = WREPL_STATE_TOMBSTONE,
5923 .node = WREPL_NODE_B,
5924 .is_static = false,
5925 .num_ips = ctx->addresses_best_num,
5926 .ips = ctx->addresses_best,
5927 .apply_expected = true
5928 },
5929 },
5930 /*
5931 * sgroup,released vs. group,tombstone with different ip(s)
5932 */
5933 {
5934 .line = __location__,
5935 .name = _NBT_NAME("_SR_GT_DI", 0x1C, NULL),
5936 .wins = {
5937 .nb_flags = NBT_NM_GROUP,
5938 .mhomed = false,
5939 .num_ips = ctx->addresses_best_num,
5940 .ips = ctx->addresses_best,
5941 .apply_expected = true
5942 },
5943 .replica= {
5944 .type = WREPL_TYPE_GROUP,
5945 .state = WREPL_STATE_TOMBSTONE,
5946 .node = WREPL_NODE_B,
5947 .is_static = false,
5948 .num_ips = ARRAY_SIZE(addresses_B_1),
5949 .ips = addresses_B_1,
5950 .apply_expected = true
5951 },
5952 },
5953 /*
5954 * special group vs. special group section
5955 */
5956 /*
5957 * sgroup,released vs. sgroup,active with same ip(s)
5958 */
5959 {
5960 .line = __location__,
5961 .name = _NBT_NAME("_SR_SA_SI", 0x1C, NULL),
5962 .wins = {
5963 .nb_flags = NBT_NM_GROUP,
5964 .mhomed = false,
5965 .num_ips = ctx->addresses_best_num,
5966 .ips = ctx->addresses_best,
5967 .apply_expected = true
5968 },
5969 .replica= {
5970 .type = WREPL_TYPE_SGROUP,
5971 .state = WREPL_STATE_ACTIVE,
5972 .node = WREPL_NODE_B,
5973 .is_static = false,
5974 .num_ips = ctx->addresses_best_num,
5975 .ips = ctx->addresses_best,
5976 .apply_expected = true
5977 },
5978 },
5979 /*
5980 * sgroup,released vs. sgroup,active with different ip(s)
5981 */
5982 {
5983 .line = __location__,
5984 .name = _NBT_NAME("_SR_SA_DI", 0x1C, NULL),
5985 .wins = {
5986 .nb_flags = NBT_NM_GROUP,
5987 .mhomed = false,
5988 .num_ips = ctx->addresses_best_num,
5989 .ips = ctx->addresses_best,
5990 .apply_expected = true
5991 },
5992 .replica= {
5993 .type = WREPL_TYPE_SGROUP,
5994 .state = WREPL_STATE_ACTIVE,
5995 .node = WREPL_NODE_B,
5996 .is_static = false,
5997 .num_ips = ARRAY_SIZE(addresses_B_1),
5998 .ips = addresses_B_1,
5999 .apply_expected = true
6000 },
6001 },
6002 /*
6003 * sgroup,released vs. sgroup,tombstone with same ip(s)
6004 */
6005 {
6006 .line = __location__,
6007 .name = _NBT_NAME("_SR_ST_SI", 0x1C, NULL),
6008 .wins = {
6009 .nb_flags = NBT_NM_GROUP,
6010 .mhomed = false,
6011 .num_ips = ctx->addresses_best_num,
6012 .ips = ctx->addresses_best,
6013 .apply_expected = true
6014 },
6015 .replica= {
6016 .type = WREPL_TYPE_SGROUP,
6017 .state = WREPL_STATE_TOMBSTONE,
6018 .node = WREPL_NODE_B,
6019 .is_static = false,
6020 .num_ips = ctx->addresses_best_num,
6021 .ips = ctx->addresses_best,
6022 .apply_expected = true
6023 },
6024 },
6025 /*
6026 * sgroup,released vs. sgroup,tombstone with different ip(s)
6027 */
6028 {
6029 .line = __location__,
6030 .name = _NBT_NAME("_SR_ST_DI", 0x1C, NULL),
6031 .wins = {
6032 .nb_flags = NBT_NM_GROUP,
6033 .mhomed = false,
6034 .num_ips = ctx->addresses_best_num,
6035 .ips = ctx->addresses_best,
6036 .apply_expected = true
6037 },
6038 .replica= {
6039 .type = WREPL_TYPE_SGROUP,
6040 .state = WREPL_STATE_TOMBSTONE,
6041 .node = WREPL_NODE_B,
6042 .is_static = false,
6043 .num_ips = ARRAY_SIZE(addresses_B_1),
6044 .ips = addresses_B_1,
6045 .apply_expected = true
6046 },
6047 },
6048 /*
6049 * special group vs. multi homed section
6050 */
6051 /*
6052 * sgroup,released vs. mhomed,active with same ip(s)
6053 */
6054 {
6055 .line = __location__,
6056 .name = _NBT_NAME("_SR_MA_SI", 0x1C, NULL),
6057 .wins = {
6058 .nb_flags = NBT_NM_GROUP,
6059 .mhomed = false,
6060 .num_ips = ctx->addresses_best_num,
6061 .ips = ctx->addresses_best,
6062 .apply_expected = true
6063 },
6064 .replica= {
6065 .type = WREPL_TYPE_MHOMED,
6066 .state = WREPL_STATE_ACTIVE,
6067 .node = WREPL_NODE_B,
6068 .is_static = false,
6069 .num_ips = ctx->addresses_best_num,
6070 .ips = ctx->addresses_best,
6071 .apply_expected = true
6072 },
6073 },
6074 /*
6075 * sgroup,released vs. mhomed,active with different ip(s)
6076 */
6077 {
6078 .line = __location__,
6079 .name = _NBT_NAME("_SR_MA_DI", 0x1C, NULL),
6080 .wins = {
6081 .nb_flags = NBT_NM_GROUP,
6082 .mhomed = false,
6083 .num_ips = ctx->addresses_best_num,
6084 .ips = ctx->addresses_best,
6085 .apply_expected = true
6086 },
6087 .replica= {
6088 .type = WREPL_TYPE_MHOMED,
6089 .state = WREPL_STATE_ACTIVE,
6090 .node = WREPL_NODE_B,
6091 .is_static = false,
6092 .num_ips = ARRAY_SIZE(addresses_B_1),
6093 .ips = addresses_B_1,
6094 .apply_expected = true
6095 },
6096 },
6097 /*
6098 * sgroup,released vs. mhomed,tombstone with same ip(s)
6099 */
6100 {
6101 .line = __location__,
6102 .name = _NBT_NAME("_SR_MT_SI", 0x1C, NULL),
6103 .wins = {
6104 .nb_flags = NBT_NM_GROUP,
6105 .mhomed = false,
6106 .num_ips = ctx->addresses_best_num,
6107 .ips = ctx->addresses_best,
6108 .apply_expected = true
6109 },
6110 .replica= {
6111 .type = WREPL_TYPE_MHOMED,
6112 .state = WREPL_STATE_TOMBSTONE,
6113 .node = WREPL_NODE_B,
6114 .is_static = false,
6115 .num_ips = ctx->addresses_best_num,
6116 .ips = ctx->addresses_best,
6117 .apply_expected = true
6118 },
6119 },
6120 /*
6121 * sgroup,released vs. mhomed,tombstone with different ip(s)
6122 */
6123 {
6124 .line = __location__,
6125 .name = _NBT_NAME("_SR_MT_DI", 0x1C, NULL),
6126 .wins = {
6127 .nb_flags = NBT_NM_GROUP,
6128 .mhomed = false,
6129 .num_ips = ctx->addresses_best_num,
6130 .ips = ctx->addresses_best,
6131 .apply_expected = true
6132 },
6133 .replica= {
6134 .type = WREPL_TYPE_MHOMED,
6135 .state = WREPL_STATE_TOMBSTONE,
6136 .node = WREPL_NODE_B,
6137 .is_static = false,
6138 .num_ips = ARRAY_SIZE(addresses_B_1),
6139 .ips = addresses_B_1,
6140 .apply_expected = true
6141 },
6142 },
6143 /*
6144 * multi homed vs. unique section
6145 */
6146 /*
6147 * mhomed,released vs. unique,active with same ip(s)
6148 */
6149 {
6150 .line = __location__,
6151 .name = _NBT_NAME("_MR_UA_SI", 0x00, NULL),
6152 .wins = {
6153 .nb_flags = 0,
6154 .mhomed = true,
6155 .num_ips = ctx->addresses_best_num,
6156 .ips = ctx->addresses_best,
6157 .apply_expected = true
6158 },
6159 .replica= {
6160 .type = WREPL_TYPE_UNIQUE,
6161 .state = WREPL_STATE_ACTIVE,
6162 .node = WREPL_NODE_B,
6163 .is_static = false,
6164 .num_ips = ctx->addresses_best_num,
6165 .ips = ctx->addresses_best,
6166 .apply_expected = true
6167 },
6168 },
6169 /*
6170 * mhomed,released vs. unique,active with different ip(s)
6171 */
6172 {
6173 .line = __location__,
6174 .name = _NBT_NAME("_MR_UA_DI", 0x00, NULL),
6175 .wins = {
6176 .nb_flags = 0,
6177 .mhomed = true,
6178 .num_ips = ctx->addresses_best_num,
6179 .ips = ctx->addresses_best,
6180 .apply_expected = true
6181 },
6182 .replica= {
6183 .type = WREPL_TYPE_UNIQUE,
6184 .state = WREPL_STATE_ACTIVE,
6185 .node = WREPL_NODE_B,
6186 .is_static = false,
6187 .num_ips = ARRAY_SIZE(addresses_B_1),
6188 .ips = addresses_B_1,
6189 .apply_expected = true
6190 },
6191 },
6192 /*
6193 * mhomed,released vs. unique,tombstone with same ip(s)
6194 */
6195 {
6196 .line = __location__,
6197 .name = _NBT_NAME("_MR_UT_SI", 0x00, NULL),
6198 .wins = {
6199 .nb_flags = 0,
6200 .mhomed = true,
6201 .num_ips = ctx->addresses_best_num,
6202 .ips = ctx->addresses_best,
6203 .apply_expected = true
6204 },
6205 .replica= {
6206 .type = WREPL_TYPE_UNIQUE,
6207 .state = WREPL_STATE_TOMBSTONE,
6208 .node = WREPL_NODE_B,
6209 .is_static = false,
6210 .num_ips = ctx->addresses_best_num,
6211 .ips = ctx->addresses_best,
6212 .apply_expected = true
6213 },
6214 },
6215 /*
6216 * mhomed,released vs. unique,tombstone with different ip(s)
6217 */
6218 {
6219 .line = __location__,
6220 .name = _NBT_NAME("_MR_UT_DI", 0x00, NULL),
6221 .wins = {
6222 .nb_flags = 0,
6223 .mhomed = true,
6224 .num_ips = ctx->addresses_best_num,
6225 .ips = ctx->addresses_best,
6226 .apply_expected = true
6227 },
6228 .replica= {
6229 .type = WREPL_TYPE_UNIQUE,
6230 .state = WREPL_STATE_TOMBSTONE,
6231 .node = WREPL_NODE_B,
6232 .is_static = false,
6233 .num_ips = ARRAY_SIZE(addresses_B_1),
6234 .ips = addresses_B_1,
6235 .apply_expected = true
6236 },
6237 },
6238 /*
6239 * multi homed vs. group section
6240 */
6241 /*
6242 * mhomed,released vs. group,active with same ip(s)
6243 */
6244 {
6245 .line = __location__,
6246 .name = _NBT_NAME("_MR_GA_SI", 0x00, NULL),
6247 .wins = {
6248 .nb_flags = 0,
6249 .mhomed = true,
6250 .num_ips = ctx->addresses_best_num,
6251 .ips = ctx->addresses_best,
6252 .apply_expected = true
6253 },
6254 .replica= {
6255 .type = WREPL_TYPE_GROUP,
6256 .state = WREPL_STATE_ACTIVE,
6257 .node = WREPL_NODE_B,
6258 .is_static = false,
6259 .num_ips = ctx->addresses_best_num,
6260 .ips = ctx->addresses_best,
6261 .apply_expected = true
6262 },
6263 },
6264 /*
6265 * mhomed,released vs. group,active with different ip(s)
6266 */
6267 {
6268 .line = __location__,
6269 .name = _NBT_NAME("_MR_GA_DI", 0x00, NULL),
6270 .wins = {
6271 .nb_flags = 0,
6272 .mhomed = true,
6273 .num_ips = ctx->addresses_best_num,
6274 .ips = ctx->addresses_best,
6275 .apply_expected = true
6276 },
6277 .replica= {
6278 .type = WREPL_TYPE_GROUP,
6279 .state = WREPL_STATE_ACTIVE,
6280 .node = WREPL_NODE_B,
6281 .is_static = false,
6282 .num_ips = ARRAY_SIZE(addresses_B_1),
6283 .ips = addresses_B_1,
6284 .apply_expected = true
6285 },
6286 },
6287 /*
6288 * mhomed,released vs. group,tombstone with same ip(s)
6289 */
6290 {
6291 .line = __location__,
6292 .name = _NBT_NAME("_MR_GT_SI", 0x00, NULL),
6293 .wins = {
6294 .nb_flags = 0,
6295 .mhomed = true,
6296 .num_ips = ctx->addresses_best_num,
6297 .ips = ctx->addresses_best,
6298 .apply_expected = true
6299 },
6300 .replica= {
6301 .type = WREPL_TYPE_GROUP,
6302 .state = WREPL_STATE_TOMBSTONE,
6303 .node = WREPL_NODE_B,
6304 .is_static = false,
6305 .num_ips = ctx->addresses_best_num,
6306 .ips = ctx->addresses_best,
6307 .apply_expected = true
6308 },
6309 },
6310 /*
6311 * mhomed,released vs. group,tombstone with different ip(s)
6312 */
6313 {
6314 .line = __location__,
6315 .name = _NBT_NAME("_MR_GT_DI", 0x00, NULL),
6316 .wins = {
6317 .nb_flags = 0,
6318 .mhomed = true,
6319 .num_ips = ctx->addresses_best_num,
6320 .ips = ctx->addresses_best,
6321 .apply_expected = true
6322 },
6323 .replica= {
6324 .type = WREPL_TYPE_GROUP,
6325 .state = WREPL_STATE_TOMBSTONE,
6326 .node = WREPL_NODE_B,
6327 .is_static = false,
6328 .num_ips = ARRAY_SIZE(addresses_B_1),
6329 .ips = addresses_B_1,
6330 .apply_expected = true
6331 },
6332 },
6333 /*
6334 * multi homed vs. special group section
6335 */
6336 /*
6337 * mhomed,released vs. sgroup,active with same ip(s)
6338 */
6339 {
6340 .line = __location__,
6341 .name = _NBT_NAME("_MR_SA_SI", 0x00, NULL),
6342 .wins = {
6343 .nb_flags = 0,
6344 .mhomed = true,
6345 .num_ips = ctx->addresses_best_num,
6346 .ips = ctx->addresses_best,
6347 .apply_expected = true
6348 },
6349 .replica= {
6350 .type = WREPL_TYPE_SGROUP,
6351 .state = WREPL_STATE_ACTIVE,
6352 .node = WREPL_NODE_B,
6353 .is_static = false,
6354 .num_ips = ctx->addresses_best_num,
6355 .ips = ctx->addresses_best,
6356 .apply_expected = true
6357 },
6358 },
6359 /*
6360 * mhomed,released vs. sgroup,active with different ip(s)
6361 */
6362 {
6363 .line = __location__,
6364 .name = _NBT_NAME("_MR_SA_DI", 0x00, NULL),
6365 .wins = {
6366 .nb_flags = 0,
6367 .mhomed = true,
6368 .num_ips = ctx->addresses_best_num,
6369 .ips = ctx->addresses_best,
6370 .apply_expected = true
6371 },
6372 .replica= {
6373 .type = WREPL_TYPE_SGROUP,
6374 .state = WREPL_STATE_ACTIVE,
6375 .node = WREPL_NODE_B,
6376 .is_static = false,
6377 .num_ips = ARRAY_SIZE(addresses_B_1),
6378 .ips = addresses_B_1,
6379 .apply_expected = true
6380 },
6381 },
6382 /*
6383 * mhomed,released vs. sgroup,tombstone with same ip(s)
6384 */
6385 {
6386 .line = __location__,
6387 .name = _NBT_NAME("_MR_ST_SI", 0x00, NULL),
6388 .wins = {
6389 .nb_flags = 0,
6390 .mhomed = true,
6391 .num_ips = ctx->addresses_best_num,
6392 .ips = ctx->addresses_best,
6393 .apply_expected = true
6394 },
6395 .replica= {
6396 .type = WREPL_TYPE_SGROUP,
6397 .state = WREPL_STATE_TOMBSTONE,
6398 .node = WREPL_NODE_B,
6399 .is_static = false,
6400 .num_ips = ctx->addresses_best_num,
6401 .ips = ctx->addresses_best,
6402 .apply_expected = true
6403 },
6404 },
6405 /*
6406 * mhomed,released vs. sgroup,tombstone with different ip(s)
6407 */
6408 {
6409 .line = __location__,
6410 .name = _NBT_NAME("_MR_ST_DI", 0x00, NULL),
6411 .wins = {
6412 .nb_flags = 0,
6413 .mhomed = true,
6414 .num_ips = ctx->addresses_best_num,
6415 .ips = ctx->addresses_best,
6416 .apply_expected = true
6417 },
6418 .replica= {
6419 .type = WREPL_TYPE_SGROUP,
6420 .state = WREPL_STATE_TOMBSTONE,
6421 .node = WREPL_NODE_B,
6422 .is_static = false,
6423 .num_ips = ARRAY_SIZE(addresses_B_1),
6424 .ips = addresses_B_1,
6425 .apply_expected = true
6426 },
6427 },
6428 /*
6429 * multi homed vs. multi homed section
6430 */
6431 /*
6432 * mhomed,released vs. mhomed,active with same ip(s)
6433 */
6434 {
6435 .line = __location__,
6436 .name = _NBT_NAME("_MR_MA_SI", 0x00, NULL),
6437 .wins = {
6438 .nb_flags = 0,
6439 .mhomed = true,
6440 .num_ips = ctx->addresses_best_num,
6441 .ips = ctx->addresses_best,
6442 .apply_expected = true
6443 },
6444 .replica= {
6445 .type = WREPL_TYPE_MHOMED,
6446 .state = WREPL_STATE_ACTIVE,
6447 .node = WREPL_NODE_B,
6448 .is_static = false,
6449 .num_ips = ctx->addresses_best_num,
6450 .ips = ctx->addresses_best,
6451 .apply_expected = true
6452 },
6453 },
6454 /*
6455 * mhomed,released vs. mhomed,active with different ip(s)
6456 */
6457 {
6458 .line = __location__,
6459 .name = _NBT_NAME("_MR_MA_DI", 0x00, NULL),
6460 .wins = {
6461 .nb_flags = 0,
6462 .mhomed = true,
6463 .num_ips = ctx->addresses_best_num,
6464 .ips = ctx->addresses_best,
6465 .apply_expected = true
6466 },
6467 .replica= {
6468 .type = WREPL_TYPE_MHOMED,
6469 .state = WREPL_STATE_ACTIVE,
6470 .node = WREPL_NODE_B,
6471 .is_static = false,
6472 .num_ips = ARRAY_SIZE(addresses_B_1),
6473 .ips = addresses_B_1,
6474 .apply_expected = true
6475 },
6476 },
6477 /*
6478 * mhomed,released vs. mhomed,tombstone with same ip(s)
6479 */
6480 {
6481 .line = __location__,
6482 .name = _NBT_NAME("_MR_MT_SI", 0x00, NULL),
6483 .wins = {
6484 .nb_flags = 0,
6485 .mhomed = true,
6486 .num_ips = ctx->addresses_best_num,
6487 .ips = ctx->addresses_best,
6488 .apply_expected = true
6489 },
6490 .replica= {
6491 .type = WREPL_TYPE_MHOMED,
6492 .state = WREPL_STATE_TOMBSTONE,
6493 .node = WREPL_NODE_B,
6494 .is_static = false,
6495 .num_ips = ctx->addresses_best_num,
6496 .ips = ctx->addresses_best,
6497 .apply_expected = true
6498 },
6499 },
6500 /*
6501 * mhomed,released vs. mhomed,tombstone with different ip(s)
6502 */
6503 {
6504 .line = __location__,
6505 .name = _NBT_NAME("_MR_MT_DI", 0x00, NULL),
6506 .wins = {
6507 .nb_flags = 0,
6508 .mhomed = true,
6509 .num_ips = ctx->addresses_best_num,
6510 .ips = ctx->addresses_best,
6511 .apply_expected = true
6512 },
6513 .replica= {
6514 .type = WREPL_TYPE_MHOMED,
6515 .state = WREPL_STATE_TOMBSTONE,
6516 .node = WREPL_NODE_B,
6517 .is_static = false,
6518 .num_ips = ARRAY_SIZE(addresses_B_1),
6519 .ips = addresses_B_1,
6520 .apply_expected = true
6521 },
6522 },
6523 };
6524
6525 torture_comment(tctx, "Test Replica records vs. owned released records\n");
6526
6527 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
6528 torture_comment(tctx, "%s => %s\n", nbt_name_string(ctx, &records[i].name),
6529 (records[i].replica.apply_expected?"REPLACE":"NOT REPLACE"));
6530
6531 /*
6532 * Setup Register
6533 */
6534 name_register->in.name = records[i].name;
6535 name_register->in.dest_addr = ctx->address;
6536 name_register->in.dest_port = lp_nbt_port(tctx->lp_ctx);
6537 name_register->in.address = records[i].wins.ips[0].ip;
6538 name_register->in.nb_flags = records[i].wins.nb_flags;
6539 name_register->in.register_demand= false;
6540 name_register->in.broadcast = false;
6541 name_register->in.multi_homed = records[i].wins.mhomed;
6542 name_register->in.ttl = 300000;
6543 name_register->in.timeout = 70;
6544 name_register->in.retries = 0;
6545
6546 status = nbt_name_register(ctx->nbtsock, ctx, name_register);
6547 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6548 torture_comment(tctx, "No response from %s for name register\n", ctx->address);
6549 ret = false;
6550 }
6551 if (!NT_STATUS_IS_OK(status)) {
6552 torture_comment(tctx, "Bad response from %s for name register - %s\n",
6553 ctx->address, nt_errstr(status));
6554 ret = false;
6555 }
6556 CHECK_VALUE(tctx, name_register->out.rcode, 0);
6557 CHECK_VALUE_STRING(tctx, name_register->out.reply_from, ctx->address);
6558 CHECK_VALUE(tctx, name_register->out.name.type, records[i].name.type);
6559 CHECK_VALUE_STRING(tctx, name_register->out.name.name, records[i].name.name);
6560 CHECK_VALUE_STRING(tctx, name_register->out.name.scope, records[i].name.scope);
6561 CHECK_VALUE_STRING(tctx, name_register->out.reply_addr, records[i].wins.ips[0].ip);
6562
6563 /* release the record */
6564 release->in.name = records[i].name;
6565 release->in.dest_port = lp_nbt_port(tctx->lp_ctx);
6566 release->in.dest_addr = ctx->address;
6567 release->in.address = records[i].wins.ips[0].ip;
6568 release->in.nb_flags = records[i].wins.nb_flags;
6569 release->in.broadcast = false;
6570 release->in.timeout = 30;
6571 release->in.retries = 0;
6572
6573 status = nbt_name_release(ctx->nbtsock, ctx, release);
6574 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6575 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
6576 return false;
6577 }
6578 if (!NT_STATUS_IS_OK(status)) {
6579 torture_comment(tctx, "Bad response from %s for name query - %s\n",
6580 ctx->address, nt_errstr(status));
6581 return false;
6582 }
6583 CHECK_VALUE(tctx, release->out.rcode, 0);
6584
6585 /*
6586 * Setup Replica
6587 */
6588 wins_name->name = &records[i].name;
6589 wins_name->flags = WREPL_NAME_FLAGS(records[i].replica.type,
6590 records[i].replica.state,
6591 records[i].replica.node,
6592 records[i].replica.is_static);
6593 wins_name->id = ++ctx->b.max_version;
6594 if (wins_name->flags & 2) {
6595 wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
6596 wins_name->addresses.addresses.ips = discard_const(records[i].replica.ips);
6597 } else {
6598 wins_name->addresses.ip = records[i].replica.ips[0].ip;
6599 }
6600 wins_name->unknown = "255.255.255.255";
6601
6602 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
6603 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name,
6604 records[i].replica.apply_expected);
6605
6606 if (records[i].replica.apply_expected) {
6607 wins_name->name = &records[i].name;
6608 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
6609 WREPL_STATE_TOMBSTONE,
6610 WREPL_NODE_B, false);
6611 wins_name->id = ++ctx->b.max_version;
6612 wins_name->addresses.ip = addresses_B_1[0].ip;
6613 wins_name->unknown = "255.255.255.255";
6614
6615 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
6616 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
6617 } else {
6618 release->in.name = records[i].name;
6619 release->in.dest_addr = ctx->address;
6620 release->in.dest_port = lp_nbt_port(tctx->lp_ctx);
6621 release->in.address = records[i].wins.ips[0].ip;
6622 release->in.nb_flags = records[i].wins.nb_flags;
6623 release->in.broadcast = false;
6624 release->in.timeout = 30;
6625 release->in.retries = 0;
6626
6627 status = nbt_name_release(ctx->nbtsock, ctx, release);
6628 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
6629 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
6630 return false;
6631 }
6632 if (!NT_STATUS_IS_OK(status)) {
6633 torture_comment(tctx, "Bad response from %s for name query - %s\n",
6634 ctx->address, nt_errstr(status));
6635 return false;
6636 }
6637 CHECK_VALUE(tctx, release->out.rcode, 0);
6638 }
6639 if (!ret) {
6640 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
6641 return ret;
6642 }
6643 }
6644
6645 return ret;
6646 }
6647
6648 struct test_conflict_owned_active_vs_replica_struct {
6649 const char *line; /* just better debugging */
6650 const char *section; /* just better debugging */
6651 struct nbt_name name;
6652 const char *comment;
6653 bool skip;
6654 struct {
6655 uint32_t nb_flags;
6656 bool mhomed;
6657 uint32_t num_ips;
6658 const struct wrepl_ip *ips;
6659 bool apply_expected;
6660 } wins;
6661 struct {
6662 uint32_t timeout;
6663 bool positive;
6664 bool expect_release;
6665 bool late_release;
6666 bool ret;
6667 /* when num_ips == 0, then .wins.ips are used */
6668 uint32_t num_ips;
6669 const struct wrepl_ip *ips;
6670 } defend;
6671 struct {
6672 enum wrepl_name_type type;
6673 enum wrepl_name_state state;
6674 enum wrepl_name_node node;
6675 bool is_static;
6676 uint32_t num_ips;
6677 const struct wrepl_ip *ips;
6678 bool apply_expected;
6679 bool mhomed_merge;
6680 bool sgroup_merge;
6681 } replica;
6682 };
6683
6684 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock,
6685 struct nbt_name_packet *req_packet,
6686 struct socket_address *src);
6687
6688 static bool test_conflict_owned_active_vs_replica(struct torture_context *tctx,
/* [<][>][^][v][top][bottom][index][help] */
6689 struct test_wrepl_conflict_conn *ctx)
6690 {
6691 bool ret = true;
6692 NTSTATUS status;
6693 struct wrepl_wins_name wins_name_;
6694 struct wrepl_wins_name *wins_name = &wins_name_;
6695 struct nbt_name_register name_register_;
6696 struct nbt_name_register *name_register = &name_register_;
6697 struct nbt_name_release release_;
6698 struct nbt_name_release *release = &release_;
6699 uint32_t i;
6700 struct test_conflict_owned_active_vs_replica_struct records[] = {
6701 /*
6702 * unique vs. unique section
6703 */
6704 /*
6705 * unique,active vs. unique,active with same ip(s), unchecked
6706 */
6707 {
6708 .line = __location__,
6709 .name = _NBT_NAME("_UA_UA_SI_U", 0x00, NULL),
6710 .wins = {
6711 .nb_flags = 0,
6712 .mhomed = false,
6713 .num_ips = ctx->addresses_best_num,
6714 .ips = ctx->addresses_best,
6715 .apply_expected = true
6716 },
6717 .defend = {
6718 .timeout = 0,
6719 },
6720 .replica= {
6721 .type = WREPL_TYPE_UNIQUE,
6722 .state = WREPL_STATE_ACTIVE,
6723 .node = WREPL_NODE_B,
6724 .is_static = false,
6725 .num_ips = ctx->addresses_best_num,
6726 .ips = ctx->addresses_best,
6727 .apply_expected = true
6728 },
6729 },
6730 /*
6731 * unique,active vs. unique,active with different ip(s), positive response
6732 */
6733 {
6734 .line = __location__,
6735 .name = _NBT_NAME("_UA_UA_DI_P", 0x00, NULL),
6736 .wins = {
6737 .nb_flags = 0,
6738 .mhomed = false,
6739 .num_ips = ctx->addresses_best_num,
6740 .ips = ctx->addresses_best,
6741 .apply_expected = true
6742 },
6743 .defend = {
6744 .timeout = 10,
6745 .positive = true,
6746 },
6747 .replica= {
6748 .type = WREPL_TYPE_UNIQUE,
6749 .state = WREPL_STATE_ACTIVE,
6750 .node = WREPL_NODE_B,
6751 .is_static = false,
6752 .num_ips = ARRAY_SIZE(addresses_B_1),
6753 .ips = addresses_B_1,
6754 .apply_expected = false
6755 },
6756 },
6757 /*
6758 * unique,active vs. unique,active with different ip(s), positive response other ips
6759 */
6760 {
6761 .line = __location__,
6762 .name = _NBT_NAME("_UA_UA_DI_O", 0x00, NULL),
6763 .wins = {
6764 .nb_flags = 0,
6765 .mhomed = false,
6766 .num_ips = ctx->addresses_best_num,
6767 .ips = ctx->addresses_best,
6768 .apply_expected = true
6769 },
6770 .defend = {
6771 .timeout = 10,
6772 .positive = true,
6773 .num_ips = ARRAY_SIZE(addresses_A_3_4),
6774 .ips = addresses_A_3_4,
6775 },
6776 .replica= {
6777 .type = WREPL_TYPE_UNIQUE,
6778 .state = WREPL_STATE_ACTIVE,
6779 .node = WREPL_NODE_B,
6780 .is_static = false,
6781 .num_ips = ARRAY_SIZE(addresses_B_1),
6782 .ips = addresses_B_1,
6783 .apply_expected = false
6784 },
6785 },
6786 /*
6787 * unique,active vs. unique,active with different ip(s), negative response
6788 */
6789 {
6790 .line = __location__,
6791 .name = _NBT_NAME("_UA_UA_DI_N", 0x00, NULL),
6792 .wins = {
6793 .nb_flags = 0,
6794 .mhomed = false,
6795 .num_ips = ctx->addresses_best_num,
6796 .ips = ctx->addresses_best,
6797 .apply_expected = true
6798 },
6799 .defend = {
6800 .timeout = 10,
6801 .positive = false,
6802 },
6803 .replica= {
6804 .type = WREPL_TYPE_UNIQUE,
6805 .state = WREPL_STATE_ACTIVE,
6806 .node = WREPL_NODE_B,
6807 .is_static = false,
6808 .num_ips = ARRAY_SIZE(addresses_B_1),
6809 .ips = addresses_B_1,
6810 .apply_expected = true
6811 },
6812 },
6813 /*
6814 * unique,active vs. unique,tombstone with same ip(s), unchecked
6815 */
6816 {
6817 .line = __location__,
6818 .name = _NBT_NAME("_UA_UT_SI_U", 0x00, NULL),
6819 .wins = {
6820 .nb_flags = 0,
6821 .mhomed = false,
6822 .num_ips = ctx->addresses_best_num,
6823 .ips = ctx->addresses_best,
6824 .apply_expected = true
6825 },
6826 .defend = {
6827 .timeout = 0,
6828 },
6829 .replica= {
6830 .type = WREPL_TYPE_UNIQUE,
6831 .state = WREPL_STATE_TOMBSTONE,
6832 .node = WREPL_NODE_B,
6833 .is_static = false,
6834 .num_ips = ctx->addresses_best_num,
6835 .ips = ctx->addresses_best,
6836 .apply_expected = false
6837 },
6838 },
6839 /*
6840 * unique,active vs. unique,tombstone with different ip(s), unchecked
6841 */
6842 {
6843 .line = __location__,
6844 .name = _NBT_NAME("_UA_UT_DI_U", 0x00, NULL),
6845 .wins = {
6846 .nb_flags = 0,
6847 .mhomed = false,
6848 .num_ips = ctx->addresses_best_num,
6849 .ips = ctx->addresses_best,
6850 .apply_expected = true
6851 },
6852 .defend = {
6853 .timeout = 0,
6854 },
6855 .replica= {
6856 .type = WREPL_TYPE_UNIQUE,
6857 .state = WREPL_STATE_TOMBSTONE,
6858 .node = WREPL_NODE_B,
6859 .is_static = false,
6860 .num_ips = ARRAY_SIZE(addresses_B_1),
6861 .ips = addresses_B_1,
6862 .apply_expected = false
6863 },
6864 },
6865 /*
6866 * unique vs. group section
6867 */
6868 /*
6869 * unique,active vs. group,active with same ip(s), release expected
6870 */
6871 {
6872 .line = __location__,
6873 .name = _NBT_NAME("_UA_GA_SI_R", 0x00, NULL),
6874 .wins = {
6875 .nb_flags = 0,
6876 .mhomed = false,
6877 .num_ips = ctx->addresses_best_num,
6878 .ips = ctx->addresses_best,
6879 .apply_expected = true
6880 },
6881 .defend = {
6882 .timeout = 10,
6883 .expect_release = true,
6884 },
6885 .replica= {
6886 .type = WREPL_TYPE_GROUP,
6887 .state = WREPL_STATE_ACTIVE,
6888 .node = WREPL_NODE_B,
6889 .is_static = false,
6890 .num_ips = ctx->addresses_best_num,
6891 .ips = ctx->addresses_best,
6892 .apply_expected = true
6893 },
6894 },
6895 /*
6896 * unique,active vs. group,active with different ip(s), release expected
6897 */
6898 {
6899 .line = __location__,
6900 .name = _NBT_NAME("_UA_GA_DI_R", 0x00, NULL),
6901 .wins = {
6902 .nb_flags = 0,
6903 .mhomed = false,
6904 .num_ips = ctx->addresses_best_num,
6905 .ips = ctx->addresses_best,
6906 .apply_expected = true
6907 },
6908 .defend = {
6909 .timeout = 10,
6910 .expect_release = true,
6911 },
6912 .replica= {
6913 .type = WREPL_TYPE_GROUP,
6914 .state = WREPL_STATE_ACTIVE,
6915 .node = WREPL_NODE_B,
6916 .is_static = false,
6917 .num_ips = ARRAY_SIZE(addresses_B_1),
6918 .ips = addresses_B_1,
6919 .apply_expected = true
6920 },
6921 },
6922 /*
6923 * unique,active vs. group,tombstone with same ip(s), unchecked
6924 */
6925 {
6926 .line = __location__,
6927 .name = _NBT_NAME("_UA_GT_SI_U", 0x00, NULL),
6928 .wins = {
6929 .nb_flags = 0,
6930 .mhomed = false,
6931 .num_ips = ctx->addresses_best_num,
6932 .ips = ctx->addresses_best,
6933 .apply_expected = true
6934 },
6935 .defend = {
6936 .timeout = 0,
6937 },
6938 .replica= {
6939 .type = WREPL_TYPE_GROUP,
6940 .state = WREPL_STATE_TOMBSTONE,
6941 .node = WREPL_NODE_B,
6942 .is_static = false,
6943 .num_ips = ctx->addresses_best_num,
6944 .ips = ctx->addresses_best,
6945 .apply_expected = false
6946 },
6947 },
6948 /*
6949 * unique,active vs. group,tombstone with different ip(s), unchecked
6950 */
6951 {
6952 .line = __location__,
6953 .name = _NBT_NAME("_UA_GT_DI_U", 0x00, NULL),
6954 .wins = {
6955 .nb_flags = 0,
6956 .mhomed = false,
6957 .num_ips = ctx->addresses_best_num,
6958 .ips = ctx->addresses_best,
6959 .apply_expected = true
6960 },
6961 .defend = {
6962 .timeout = 0,
6963 },
6964 .replica= {
6965 .type = WREPL_TYPE_GROUP,
6966 .state = WREPL_STATE_TOMBSTONE,
6967 .node = WREPL_NODE_B,
6968 .is_static = false,
6969 .num_ips = ARRAY_SIZE(addresses_B_1),
6970 .ips = addresses_B_1,
6971 .apply_expected = false
6972 },
6973 },
6974 /*
6975 * unique vs. special group section
6976 */
6977 /*
6978 * unique,active vs. sgroup,active with same ip(s), release expected
6979 */
6980 {
6981 .line = __location__,
6982 .name = _NBT_NAME("_UA_SA_SI_R", 0x00, NULL),
6983 .wins = {
6984 .nb_flags = 0,
6985 .mhomed = false,
6986 .num_ips = ctx->addresses_best_num,
6987 .ips = ctx->addresses_best,
6988 .apply_expected = true
6989 },
6990 .defend = {
6991 .timeout = 10,
6992 .expect_release = true,
6993 },
6994 .replica= {
6995 .type = WREPL_TYPE_SGROUP,
6996 .state = WREPL_STATE_ACTIVE,
6997 .node = WREPL_NODE_B,
6998 .is_static = false,
6999 .num_ips = ctx->addresses_best_num,
7000 .ips = ctx->addresses_best,
7001 .apply_expected = true
7002 },
7003 },
7004 /*
7005 * unique,active vs. group,active with different ip(s), release expected
7006 */
7007 {
7008 .line = __location__,
7009 .name = _NBT_NAME("_UA_SA_DI_R", 0x00, NULL),
7010 .wins = {
7011 .nb_flags = 0,
7012 .mhomed = false,
7013 .num_ips = ctx->addresses_best_num,
7014 .ips = ctx->addresses_best,
7015 .apply_expected = true
7016 },
7017 .defend = {
7018 .timeout = 10,
7019 .expect_release = true,
7020 },
7021 .replica= {
7022 .type = WREPL_TYPE_SGROUP,
7023 .state = WREPL_STATE_ACTIVE,
7024 .node = WREPL_NODE_B,
7025 .is_static = false,
7026 .num_ips = ARRAY_SIZE(addresses_B_1),
7027 .ips = addresses_B_1,
7028 .apply_expected = true
7029 },
7030 },
7031 /*
7032 * unique,active vs. sgroup,tombstone with same ip(s), unchecked
7033 */
7034 {
7035 .line = __location__,
7036 .name = _NBT_NAME("_UA_ST_SI_U", 0x00, NULL),
7037 .wins = {
7038 .nb_flags = 0,
7039 .mhomed = false,
7040 .num_ips = ctx->addresses_best_num,
7041 .ips = ctx->addresses_best,
7042 .apply_expected = true
7043 },
7044 .defend = {
7045 .timeout = 0,
7046 },
7047 .replica= {
7048 .type = WREPL_TYPE_SGROUP,
7049 .state = WREPL_STATE_TOMBSTONE,
7050 .node = WREPL_NODE_B,
7051 .is_static = false,
7052 .num_ips = ctx->addresses_best_num,
7053 .ips = ctx->addresses_best,
7054 .apply_expected = false
7055 },
7056 },
7057 /*
7058 * unique,active vs. sgroup,tombstone with different ip(s), unchecked
7059 */
7060 {
7061 .line = __location__,
7062 .name = _NBT_NAME("_UA_ST_DI_U", 0x00, NULL),
7063 .wins = {
7064 .nb_flags = 0,
7065 .mhomed = false,
7066 .num_ips = ctx->addresses_best_num,
7067 .ips = ctx->addresses_best,
7068 .apply_expected = true
7069 },
7070 .defend = {
7071 .timeout = 0,
7072 },
7073 .replica= {
7074 .type = WREPL_TYPE_SGROUP,
7075 .state = WREPL_STATE_TOMBSTONE,
7076 .node = WREPL_NODE_B,
7077 .is_static = false,
7078 .num_ips = ARRAY_SIZE(addresses_B_1),
7079 .ips = addresses_B_1,
7080 .apply_expected = false
7081 },
7082 },
7083 /*
7084 * unique vs. multi homed section
7085 */
7086 /*
7087 * unique,active vs. mhomed,active with same ip(s), unchecked
7088 */
7089 {
7090 .line = __location__,
7091 .name = _NBT_NAME("_UA_MA_SI_U", 0x00, NULL),
7092 .wins = {
7093 .nb_flags = 0,
7094 .mhomed = false,
7095 .num_ips = ctx->addresses_best_num,
7096 .ips = ctx->addresses_best,
7097 .apply_expected = true
7098 },
7099 .defend = {
7100 .timeout = 0,
7101 },
7102 .replica= {
7103 .type = WREPL_TYPE_MHOMED,
7104 .state = WREPL_STATE_ACTIVE,
7105 .node = WREPL_NODE_B,
7106 .is_static = false,
7107 .num_ips = ctx->addresses_best_num,
7108 .ips = ctx->addresses_best,
7109 .apply_expected = true
7110 },
7111 },
7112 /*
7113 * unique,active vs. mhomed,active with superset ip(s), unchecked
7114 */
7115 {
7116 .line = __location__,
7117 .name = _NBT_NAME("_UA_MA_SP_U", 0x00, NULL),
7118 .wins = {
7119 .nb_flags = 0,
7120 .mhomed = false,
7121 .num_ips = ctx->addresses_best_num,
7122 .ips = ctx->addresses_best,
7123 .apply_expected = true
7124 },
7125 .defend = {
7126 .timeout = 0,
7127 },
7128 .replica= {
7129 .type = WREPL_TYPE_MHOMED,
7130 .state = WREPL_STATE_ACTIVE,
7131 .node = WREPL_NODE_B,
7132 .is_static = false,
7133 .num_ips = ctx->addresses_all_num,
7134 .ips = ctx->addresses_all,
7135 .apply_expected = true
7136 },
7137 },
7138 /*
7139 * unique,active vs. mhomed,active with different ip(s), positive response
7140 */
7141 {
7142 .line = __location__,
7143 .name = _NBT_NAME("_UA_MA_DI_P", 0x00, NULL),
7144 .wins = {
7145 .nb_flags = 0,
7146 .mhomed = false,
7147 .num_ips = ctx->addresses_best_num,
7148 .ips = ctx->addresses_best,
7149 .apply_expected = true
7150 },
7151 .defend = {
7152 .timeout = 10,
7153 .positive = true,
7154 },
7155 .replica= {
7156 .type = WREPL_TYPE_MHOMED,
7157 .state = WREPL_STATE_ACTIVE,
7158 .node = WREPL_NODE_B,
7159 .is_static = false,
7160 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7161 .ips = addresses_B_3_4,
7162 .apply_expected = false
7163 },
7164 },
7165 /*
7166 * unique,active vs. mhomed,active with different ip(s), positive response other ips
7167 */
7168 {
7169 .line = __location__,
7170 .name = _NBT_NAME("_UA_MA_DI_O", 0x00, NULL),
7171 .wins = {
7172 .nb_flags = 0,
7173 .mhomed = false,
7174 .num_ips = ctx->addresses_best_num,
7175 .ips = ctx->addresses_best,
7176 .apply_expected = true
7177 },
7178 .defend = {
7179 .timeout = 10,
7180 .positive = true,
7181 .num_ips = ARRAY_SIZE(addresses_A_3_4),
7182 .ips = addresses_A_3_4,
7183 },
7184 .replica= {
7185 .type = WREPL_TYPE_MHOMED,
7186 .state = WREPL_STATE_ACTIVE,
7187 .node = WREPL_NODE_B,
7188 .is_static = false,
7189 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7190 .ips = addresses_B_3_4,
7191 .apply_expected = false
7192 },
7193 },
7194 /*
7195 * unique,active vs. mhomed,active with different ip(s), negative response
7196 */
7197 {
7198 .line = __location__,
7199 .name = _NBT_NAME("_UA_MA_DI_N", 0x00, NULL),
7200 .wins = {
7201 .nb_flags = 0,
7202 .mhomed = false,
7203 .num_ips = ctx->addresses_best_num,
7204 .ips = ctx->addresses_best,
7205 .apply_expected = true
7206 },
7207 .defend = {
7208 .timeout = 10,
7209 .positive = false,
7210 },
7211 .replica= {
7212 .type = WREPL_TYPE_MHOMED,
7213 .state = WREPL_STATE_ACTIVE,
7214 .node = WREPL_NODE_B,
7215 .is_static = false,
7216 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7217 .ips = addresses_B_3_4,
7218 .apply_expected = true
7219 },
7220 },
7221 /*
7222 * unique,active vs. mhomed,tombstone with same ip(s), unchecked
7223 */
7224 {
7225 .line = __location__,
7226 .name = _NBT_NAME("_UA_MT_SI_U", 0x00, NULL),
7227 .wins = {
7228 .nb_flags = 0,
7229 .mhomed = false,
7230 .num_ips = ctx->addresses_best_num,
7231 .ips = ctx->addresses_best,
7232 .apply_expected = true
7233 },
7234 .defend = {
7235 .timeout = 0,
7236 },
7237 .replica= {
7238 .type = WREPL_TYPE_MHOMED,
7239 .state = WREPL_STATE_TOMBSTONE,
7240 .node = WREPL_NODE_B,
7241 .is_static = false,
7242 .num_ips = ctx->addresses_best_num,
7243 .ips = ctx->addresses_best,
7244 .apply_expected = false
7245 },
7246 },
7247 /*
7248 * unique,active vs. mhomed,tombstone with different ip(s), unchecked
7249 */
7250 {
7251 .line = __location__,
7252 .name = _NBT_NAME("_UA_MT_DI_U", 0x00, NULL),
7253 .wins = {
7254 .nb_flags = 0,
7255 .mhomed = false,
7256 .num_ips = ctx->addresses_best_num,
7257 .ips = ctx->addresses_best,
7258 .apply_expected = true
7259 },
7260 .defend = {
7261 .timeout = 0,
7262 },
7263 .replica= {
7264 .type = WREPL_TYPE_MHOMED,
7265 .state = WREPL_STATE_TOMBSTONE,
7266 .node = WREPL_NODE_B,
7267 .is_static = false,
7268 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7269 .ips = addresses_B_3_4,
7270 .apply_expected = false
7271 },
7272 },
7273 /*
7274 * normal group vs. unique section
7275 */
7276 /*
7277 * group,active vs. unique,active with same ip(s), unchecked
7278 */
7279 {
7280 .line = __location__,
7281 .name = _NBT_NAME("_GA_UA_SI_U", 0x00, NULL),
7282 .wins = {
7283 .nb_flags = NBT_NM_GROUP,
7284 .mhomed = false,
7285 .num_ips = ctx->addresses_best_num,
7286 .ips = ctx->addresses_best,
7287 .apply_expected = true
7288 },
7289 .defend = {
7290 .timeout = 0,
7291 },
7292 .replica= {
7293 .type = WREPL_TYPE_UNIQUE,
7294 .state = WREPL_STATE_ACTIVE,
7295 .node = WREPL_NODE_B,
7296 .is_static = false,
7297 .num_ips = ctx->addresses_best_num,
7298 .ips = ctx->addresses_best,
7299 .apply_expected = false
7300 },
7301 },
7302 /*
7303 * group,active vs. unique,active with different ip(s), unchecked
7304 */
7305 {
7306 .line = __location__,
7307 .name = _NBT_NAME("_GA_UA_DI_U", 0x00, NULL),
7308 .wins = {
7309 .nb_flags = NBT_NM_GROUP,
7310 .mhomed = false,
7311 .num_ips = ctx->addresses_best_num,
7312 .ips = ctx->addresses_best,
7313 .apply_expected = true
7314 },
7315 .defend = {
7316 .timeout = 0,
7317 },
7318 .replica= {
7319 .type = WREPL_TYPE_UNIQUE,
7320 .state = WREPL_STATE_ACTIVE,
7321 .node = WREPL_NODE_B,
7322 .is_static = false,
7323 .num_ips = ARRAY_SIZE(addresses_B_1),
7324 .ips = addresses_B_1,
7325 .apply_expected = false
7326 },
7327 },
7328 /*
7329 * group,active vs. unique,tombstone with same ip(s), unchecked
7330 */
7331 {
7332 .line = __location__,
7333 .name = _NBT_NAME("_GA_UT_SI_U", 0x00, NULL),
7334 .wins = {
7335 .nb_flags = NBT_NM_GROUP,
7336 .mhomed = false,
7337 .num_ips = ctx->addresses_best_num,
7338 .ips = ctx->addresses_best,
7339 .apply_expected = true
7340 },
7341 .defend = {
7342 .timeout = 0,
7343 },
7344 .replica= {
7345 .type = WREPL_TYPE_UNIQUE,
7346 .state = WREPL_STATE_TOMBSTONE,
7347 .node = WREPL_NODE_B,
7348 .is_static = false,
7349 .num_ips = ctx->addresses_best_num,
7350 .ips = ctx->addresses_best,
7351 .apply_expected = false
7352 },
7353 },
7354 /*
7355 * group,active vs. unique,tombstone with different ip(s), unchecked
7356 */
7357 {
7358 .line = __location__,
7359 .name = _NBT_NAME("_GA_UT_DI_U", 0x00, NULL),
7360 .wins = {
7361 .nb_flags = NBT_NM_GROUP,
7362 .mhomed = false,
7363 .num_ips = ctx->addresses_best_num,
7364 .ips = ctx->addresses_best,
7365 .apply_expected = true
7366 },
7367 .defend = {
7368 .timeout = 0,
7369 },
7370 .replica= {
7371 .type = WREPL_TYPE_UNIQUE,
7372 .state = WREPL_STATE_TOMBSTONE,
7373 .node = WREPL_NODE_B,
7374 .is_static = false,
7375 .num_ips = ARRAY_SIZE(addresses_B_1),
7376 .ips = addresses_B_1,
7377 .apply_expected = false
7378 },
7379 },
7380 /*
7381 * normal group vs. normal group section
7382 */
7383 /*
7384 * group,active vs. group,active with same ip(s), unchecked
7385 */
7386 {
7387 .line = __location__,
7388 .name = _NBT_NAME("_GA_GA_SI_U", 0x00, NULL),
7389 .wins = {
7390 .nb_flags = NBT_NM_GROUP,
7391 .mhomed = false,
7392 .num_ips = ctx->addresses_best_num,
7393 .ips = ctx->addresses_best,
7394 .apply_expected = true
7395 },
7396 .defend = {
7397 .timeout = 0,
7398 },
7399 .replica= {
7400 .type = WREPL_TYPE_GROUP,
7401 .state = WREPL_STATE_ACTIVE,
7402 .node = WREPL_NODE_B,
7403 .is_static = false,
7404 .num_ips = ctx->addresses_best_num,
7405 .ips = ctx->addresses_best,
7406 .apply_expected = true
7407 },
7408 },
7409 /*
7410 * group,active vs. group,active with different ip(s), unchecked
7411 */
7412 {
7413 .line = __location__,
7414 .name = _NBT_NAME("_GA_GA_DI_U", 0x00, NULL),
7415 .wins = {
7416 .nb_flags = NBT_NM_GROUP,
7417 .mhomed = false,
7418 .num_ips = ctx->addresses_best_num,
7419 .ips = ctx->addresses_best,
7420 .apply_expected = true
7421 },
7422 .defend = {
7423 .timeout = 0,
7424 },
7425 .replica= {
7426 .type = WREPL_TYPE_GROUP,
7427 .state = WREPL_STATE_ACTIVE,
7428 .node = WREPL_NODE_B,
7429 .is_static = false,
7430 .num_ips = ARRAY_SIZE(addresses_B_1),
7431 .ips = addresses_B_1,
7432 .apply_expected = true
7433 },
7434 },
7435 /*
7436 * group,active vs. group,tombstone with same ip(s), unchecked
7437 */
7438 {
7439 .line = __location__,
7440 .name = _NBT_NAME("_GA_GT_SI_U", 0x00, NULL),
7441 .wins = {
7442 .nb_flags = NBT_NM_GROUP,
7443 .mhomed = false,
7444 .num_ips = ctx->addresses_best_num,
7445 .ips = ctx->addresses_best,
7446 .apply_expected = true
7447 },
7448 .defend = {
7449 .timeout = 0,
7450 },
7451 .replica= {
7452 .type = WREPL_TYPE_GROUP,
7453 .state = WREPL_STATE_TOMBSTONE,
7454 .node = WREPL_NODE_B,
7455 .is_static = false,
7456 .num_ips = ctx->addresses_best_num,
7457 .ips = ctx->addresses_best,
7458 .apply_expected = false
7459 },
7460 },
7461 /*
7462 * group,active vs. group,tombstone with different ip(s), unchecked
7463 */
7464 {
7465 .line = __location__,
7466 .name = _NBT_NAME("_GA_GT_DI_U", 0x00, NULL),
7467 .wins = {
7468 .nb_flags = NBT_NM_GROUP,
7469 .mhomed = false,
7470 .num_ips = ctx->addresses_best_num,
7471 .ips = ctx->addresses_best,
7472 .apply_expected = true
7473 },
7474 .defend = {
7475 .timeout = 0,
7476 },
7477 .replica= {
7478 .type = WREPL_TYPE_GROUP,
7479 .state = WREPL_STATE_TOMBSTONE,
7480 .node = WREPL_NODE_B,
7481 .is_static = false,
7482 .num_ips = ARRAY_SIZE(addresses_B_1),
7483 .ips = addresses_B_1,
7484 .apply_expected = false
7485 },
7486 },
7487 /*
7488 * normal group vs. special group section
7489 */
7490 /*
7491 * group,active vs. sgroup,active with same ip(s), unchecked
7492 */
7493 {
7494 .line = __location__,
7495 .name = _NBT_NAME("_GA_SA_SI_U", 0x00, NULL),
7496 .wins = {
7497 .nb_flags = NBT_NM_GROUP,
7498 .mhomed = false,
7499 .num_ips = ctx->addresses_best_num,
7500 .ips = ctx->addresses_best,
7501 .apply_expected = true
7502 },
7503 .defend = {
7504 .timeout = 0,
7505 },
7506 .replica= {
7507 .type = WREPL_TYPE_SGROUP,
7508 .state = WREPL_STATE_ACTIVE,
7509 .node = WREPL_NODE_B,
7510 .is_static = false,
7511 .num_ips = ctx->addresses_best_num,
7512 .ips = ctx->addresses_best,
7513 .apply_expected = false
7514 },
7515 },
7516 /*
7517 * group,active vs. sgroup,active with different ip(s), unchecked
7518 */
7519 {
7520 .line = __location__,
7521 .name = _NBT_NAME("_GA_SA_DI_U", 0x00, NULL),
7522 .wins = {
7523 .nb_flags = NBT_NM_GROUP,
7524 .mhomed = false,
7525 .num_ips = ctx->addresses_best_num,
7526 .ips = ctx->addresses_best,
7527 .apply_expected = true
7528 },
7529 .defend = {
7530 .timeout = 0,
7531 },
7532 .replica= {
7533 .type = WREPL_TYPE_SGROUP,
7534 .state = WREPL_STATE_ACTIVE,
7535 .node = WREPL_NODE_B,
7536 .is_static = false,
7537 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7538 .ips = addresses_B_3_4,
7539 .apply_expected = false
7540 },
7541 },
7542 /*
7543 * group,active vs. sgroup,tombstone with same ip(s), unchecked
7544 */
7545 {
7546 .line = __location__,
7547 .name = _NBT_NAME("_GA_ST_SI_U", 0x00, NULL),
7548 .wins = {
7549 .nb_flags = NBT_NM_GROUP,
7550 .mhomed = false,
7551 .num_ips = ctx->addresses_best_num,
7552 .ips = ctx->addresses_best,
7553 .apply_expected = true
7554 },
7555 .defend = {
7556 .timeout = 0,
7557 },
7558 .replica= {
7559 .type = WREPL_TYPE_SGROUP,
7560 .state = WREPL_STATE_TOMBSTONE,
7561 .node = WREPL_NODE_B,
7562 .is_static = false,
7563 .num_ips = ctx->addresses_best_num,
7564 .ips = ctx->addresses_best,
7565 .apply_expected = false
7566 },
7567 },
7568 /*
7569 * group,active vs. sgroup,tombstone with different ip(s), unchecked
7570 */
7571 {
7572 .line = __location__,
7573 .name = _NBT_NAME("_GA_ST_DI_U", 0x00, NULL),
7574 .wins = {
7575 .nb_flags = NBT_NM_GROUP,
7576 .mhomed = false,
7577 .num_ips = ctx->addresses_best_num,
7578 .ips = ctx->addresses_best,
7579 .apply_expected = true
7580 },
7581 .defend = {
7582 .timeout = 0,
7583 },
7584 .replica= {
7585 .type = WREPL_TYPE_SGROUP,
7586 .state = WREPL_STATE_TOMBSTONE,
7587 .node = WREPL_NODE_B,
7588 .is_static = false,
7589 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7590 .ips = addresses_B_3_4,
7591 .apply_expected = false
7592 },
7593 },
7594 /*
7595 * normal group vs. multi homed section
7596 */
7597 /*
7598 * group,active vs. mhomed,active with same ip(s), unchecked
7599 */
7600 {
7601 .line = __location__,
7602 .name = _NBT_NAME("_GA_MA_SI_U", 0x00, NULL),
7603 .wins = {
7604 .nb_flags = NBT_NM_GROUP,
7605 .mhomed = false,
7606 .num_ips = ctx->addresses_best_num,
7607 .ips = ctx->addresses_best,
7608 .apply_expected = true
7609 },
7610 .defend = {
7611 .timeout = 0,
7612 },
7613 .replica= {
7614 .type = WREPL_TYPE_MHOMED,
7615 .state = WREPL_STATE_ACTIVE,
7616 .node = WREPL_NODE_B,
7617 .is_static = false,
7618 .num_ips = ctx->addresses_best_num,
7619 .ips = ctx->addresses_best,
7620 .apply_expected = false
7621 },
7622 },
7623 /*
7624 * group,active vs. mhomed,active with different ip(s), unchecked
7625 */
7626 {
7627 .line = __location__,
7628 .name = _NBT_NAME("_GA_MA_DI_U", 0x00, NULL),
7629 .wins = {
7630 .nb_flags = NBT_NM_GROUP,
7631 .mhomed = false,
7632 .num_ips = ctx->addresses_best_num,
7633 .ips = ctx->addresses_best,
7634 .apply_expected = true
7635 },
7636 .defend = {
7637 .timeout = 0,
7638 },
7639 .replica= {
7640 .type = WREPL_TYPE_MHOMED,
7641 .state = WREPL_STATE_ACTIVE,
7642 .node = WREPL_NODE_B,
7643 .is_static = false,
7644 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7645 .ips = addresses_B_3_4,
7646 .apply_expected = false
7647 },
7648 },
7649 /*
7650 * group,active vs. mhomed,tombstone with same ip(s), unchecked
7651 */
7652 {
7653 .line = __location__,
7654 .name = _NBT_NAME("_GA_MT_SI_U", 0x00, NULL),
7655 .wins = {
7656 .nb_flags = NBT_NM_GROUP,
7657 .mhomed = false,
7658 .num_ips = ctx->addresses_best_num,
7659 .ips = ctx->addresses_best,
7660 .apply_expected = true
7661 },
7662 .defend = {
7663 .timeout = 0,
7664 },
7665 .replica= {
7666 .type = WREPL_TYPE_MHOMED,
7667 .state = WREPL_STATE_TOMBSTONE,
7668 .node = WREPL_NODE_B,
7669 .is_static = false,
7670 .num_ips = ctx->addresses_best_num,
7671 .ips = ctx->addresses_best,
7672 .apply_expected = false
7673 },
7674 },
7675 /*
7676 * group,active vs. mhomed,tombstone with different ip(s), unchecked
7677 */
7678 {
7679 .line = __location__,
7680 .name = _NBT_NAME("_GA_MT_DI_U", 0x00, NULL),
7681 .wins = {
7682 .nb_flags = NBT_NM_GROUP,
7683 .mhomed = false,
7684 .num_ips = ctx->addresses_best_num,
7685 .ips = ctx->addresses_best,
7686 .apply_expected = true
7687 },
7688 .defend = {
7689 .timeout = 0,
7690 },
7691 .replica= {
7692 .type = WREPL_TYPE_MHOMED,
7693 .state = WREPL_STATE_TOMBSTONE,
7694 .node = WREPL_NODE_B,
7695 .is_static = false,
7696 .num_ips = ARRAY_SIZE(addresses_B_3_4),
7697 .ips = addresses_B_3_4,
7698 .apply_expected = false
7699 },
7700 },
7701 /*
7702 * special group vs. unique section
7703 */
7704 /*
7705 * sgroup,active vs. unique,active with same ip(s), unchecked
7706 */
7707 {
7708 .line = __location__,
7709 .name = _NBT_NAME("_SA_UA_SI_U", 0x1C, NULL),
7710 .wins = {
7711 .nb_flags = NBT_NM_GROUP,
7712 .mhomed = false,
7713 .num_ips = ctx->addresses_best_num,
7714 .ips = ctx->addresses_best,
7715 .apply_expected = true
7716 },
7717 .defend = {
7718 .timeout = 0,
7719 },
7720 .replica= {
7721 .type = WREPL_TYPE_UNIQUE,
7722 .state = WREPL_STATE_ACTIVE,
7723 .node = WREPL_NODE_B,
7724 .is_static = false,
7725 .num_ips = ctx->addresses_best_num,
7726 .ips = ctx->addresses_best,
7727 .apply_expected = false
7728 },
7729 },
7730 /*
7731 * sgroup,active vs. unique,active with different ip(s), unchecked
7732 */
7733 {
7734 .line = __location__,
7735 .name = _NBT_NAME("_SA_UA_DI_U", 0x1C, NULL),
7736 .wins = {
7737 .nb_flags = NBT_NM_GROUP,
7738 .mhomed = false,
7739 .num_ips = ctx->addresses_best_num,
7740 .ips = ctx->addresses_best,
7741 .apply_expected = true
7742 },
7743 .defend = {
7744 .timeout = 0,
7745 },
7746 .replica= {
7747 .type = WREPL_TYPE_UNIQUE,
7748 .state = WREPL_STATE_ACTIVE,
7749 .node = WREPL_NODE_B,
7750 .is_static = false,
7751 .num_ips = ARRAY_SIZE(addresses_B_1),
7752 .ips = addresses_B_1,
7753 .apply_expected = false
7754 },
7755 },
7756 /*
7757 * sgroup,active vs. unique,tombstone with same ip(s), unchecked
7758 */
7759 {
7760 .line = __location__,
7761 .name = _NBT_NAME("_SA_UT_SI_U", 0x1C, NULL),
7762 .wins = {
7763 .nb_flags = NBT_NM_GROUP,
7764 .mhomed = false,
7765 .num_ips = ctx->addresses_best_num,
7766 .ips = ctx->addresses_best,
7767 .apply_expected = true
7768 },
7769 .defend = {
7770 .timeout = 0,
7771 },
7772 .replica= {
7773 .type = WREPL_TYPE_UNIQUE,
7774 .state = WREPL_STATE_TOMBSTONE,
7775 .node = WREPL_NODE_B,
7776 .is_static = false,
7777 .num_ips = ctx->addresses_best_num,
7778 .ips = ctx->addresses_best,
7779 .apply_expected = false
7780 },
7781 },
7782 /*
7783 * sgroup,active vs. unique,tombstone with different ip(s), unchecked
7784 */
7785 {
7786 .line = __location__,
7787 .name = _NBT_NAME("_SA_UT_DI_U", 0x1C, NULL),
7788 .wins = {
7789 .nb_flags = NBT_NM_GROUP,
7790 .mhomed = false,
7791 .num_ips = ctx->addresses_best_num,
7792 .ips = ctx->addresses_best,
7793 .apply_expected = true
7794 },
7795 .defend = {
7796 .timeout = 0,
7797 },
7798 .replica= {
7799 .type = WREPL_TYPE_UNIQUE,
7800 .state = WREPL_STATE_TOMBSTONE,
7801 .node = WREPL_NODE_B,
7802 .is_static = false,
7803 .num_ips = ARRAY_SIZE(addresses_B_1),
7804 .ips = addresses_B_1,
7805 .apply_expected = false
7806 },
7807 },
7808 /*
7809 * special group vs. normal group section
7810 */
7811 /*
7812 * sgroup,active vs. group,active with same ip(s), unchecked
7813 */
7814 {
7815 .line = __location__,
7816 .name = _NBT_NAME("_SA_GA_SI_U", 0x1C, NULL),
7817 .wins = {
7818 .nb_flags = NBT_NM_GROUP,
7819 .mhomed = false,
7820 .num_ips = ctx->addresses_best_num,
7821 .ips = ctx->addresses_best,
7822 .apply_expected = true
7823 },
7824 .defend = {
7825 .timeout = 0,
7826 },
7827 .replica= {
7828 .type = WREPL_TYPE_GROUP,
7829 .state = WREPL_STATE_ACTIVE,
7830 .node = WREPL_NODE_B,
7831 .is_static = false,
7832 .num_ips = ctx->addresses_best_num,
7833 .ips = ctx->addresses_best,
7834 .apply_expected = false
7835 },
7836 },
7837 /*
7838 * sgroup,active vs. group,active with different ip(s), unchecked
7839 */
7840 {
7841 .line = __location__,
7842 .name = _NBT_NAME("_SA_GA_DI_U", 0x1C, NULL),
7843 .wins = {
7844 .nb_flags = NBT_NM_GROUP,
7845 .mhomed = false,
7846 .num_ips = ctx->addresses_best_num,
7847 .ips = ctx->addresses_best,
7848 .apply_expected = true
7849 },
7850 .defend = {
7851 .timeout = 0,
7852 },
7853 .replica= {
7854 .type = WREPL_TYPE_GROUP,
7855 .state = WREPL_STATE_ACTIVE,
7856 .node = WREPL_NODE_B,
7857 .is_static = false,
7858 .num_ips = ARRAY_SIZE(addresses_B_1),
7859 .ips = addresses_B_1,
7860 .apply_expected = false
7861 },
7862 },
7863 /*
7864 * sgroup,active vs. group,tombstone with same ip(s), unchecked
7865 */
7866 {
7867 .line = __location__,
7868 .name = _NBT_NAME("_SA_GT_SI_U", 0x1C, NULL),
7869 .wins = {
7870 .nb_flags = NBT_NM_GROUP,
7871 .mhomed = false,
7872 .num_ips = ctx->addresses_best_num,
7873 .ips = ctx->addresses_best,
7874 .apply_expected = true
7875 },
7876 .defend = {
7877 .timeout = 0,
7878 },
7879 .replica= {
7880 .type = WREPL_TYPE_GROUP,
7881 .state = WREPL_STATE_TOMBSTONE,
7882 .node = WREPL_NODE_B,
7883 .is_static = false,
7884 .num_ips = ctx->addresses_best_num,
7885 .ips = ctx->addresses_best,
7886 .apply_expected = false
7887 },
7888 },
7889 /*
7890 * sgroup,active vs. group,tombstone with different ip(s), unchecked
7891 */
7892 {
7893 .line = __location__,
7894 .name = _NBT_NAME("_SA_GT_DI_U", 0x1C, NULL),
7895 .wins = {
7896 .nb_flags = NBT_NM_GROUP,
7897 .mhomed = false,
7898 .num_ips = ctx->addresses_best_num,
7899 .ips = ctx->addresses_best,
7900 .apply_expected = true
7901 },
7902 .defend = {
7903 .timeout = 0,
7904 },
7905 .replica= {
7906 .type = WREPL_TYPE_GROUP,
7907 .state = WREPL_STATE_TOMBSTONE,
7908 .node = WREPL_NODE_B,
7909 .is_static = false,
7910 .num_ips = ARRAY_SIZE(addresses_B_1),
7911 .ips = addresses_B_1,
7912 .apply_expected = false
7913 },
7914 },
7915 /*
7916 * special group vs. multi homed section
7917 */
7918 /*
7919 * sgroup,active vs. mhomed,active with same ip(s), unchecked
7920 */
7921 {
7922 .line = __location__,
7923 .name = _NBT_NAME("_SA_MA_SI_U", 0x1C, NULL),
7924 .wins = {
7925 .nb_flags = NBT_NM_GROUP,
7926 .mhomed = false,
7927 .num_ips = ctx->addresses_best_num,
7928 .ips = ctx->addresses_best,
7929 .apply_expected = true
7930 },
7931 .defend = {
7932 .timeout = 0,
7933 },
7934 .replica= {
7935 .type = WREPL_TYPE_MHOMED,
7936 .state = WREPL_STATE_ACTIVE,
7937 .node = WREPL_NODE_B,
7938 .is_static = false,
7939 .num_ips = ctx->addresses_best_num,
7940 .ips = ctx->addresses_best,
7941 .apply_expected = false
7942 },
7943 },
7944 /*
7945 * sgroup,active vs. mhomed,active with different ip(s), unchecked
7946 */
7947 {
7948 .line = __location__,
7949 .name = _NBT_NAME("_SA_MA_DI_U", 0x1C, NULL),
7950 .wins = {
7951 .nb_flags = NBT_NM_GROUP,
7952 .mhomed = false,
7953 .num_ips = ctx->addresses_best_num,
7954 .ips = ctx->addresses_best,
7955 .apply_expected = true
7956 },
7957 .defend = {
7958 .timeout = 0,
7959 },
7960 .replica= {
7961 .type = WREPL_TYPE_MHOMED,
7962 .state = WREPL_STATE_ACTIVE,
7963 .node = WREPL_NODE_B,
7964 .is_static = false,
7965 .num_ips = ARRAY_SIZE(addresses_B_1),
7966 .ips = addresses_B_1,
7967 .apply_expected = false
7968 },
7969 },
7970 /*
7971 * sgroup,active vs. mhomed,tombstone with same ip(s), unchecked
7972 */
7973 {
7974 .line = __location__,
7975 .name = _NBT_NAME("_SA_MT_SI_U", 0x1C, NULL),
7976 .wins = {
7977 .nb_flags = NBT_NM_GROUP,
7978 .mhomed = false,
7979 .num_ips = ctx->addresses_best_num,
7980 .ips = ctx->addresses_best,
7981 .apply_expected = true
7982 },
7983 .defend = {
7984 .timeout = 0,
7985 },
7986 .replica= {
7987 .type = WREPL_TYPE_MHOMED,
7988 .state = WREPL_STATE_TOMBSTONE,
7989 .node = WREPL_NODE_B,
7990 .is_static = false,
7991 .num_ips = ctx->addresses_best_num,
7992 .ips = ctx->addresses_best,
7993 .apply_expected = false
7994 },
7995 },
7996 /*
7997 * sgroup,active vs. mhomed,tombstone with different ip(s), unchecked
7998 */
7999 {
8000 .line = __location__,
8001 .name = _NBT_NAME("_SA_MT_DI_U", 0x1C, NULL),
8002 .wins = {
8003 .nb_flags = NBT_NM_GROUP,
8004 .mhomed = false,
8005 .num_ips = ctx->addresses_best_num,
8006 .ips = ctx->addresses_best,
8007 .apply_expected = true
8008 },
8009 .defend = {
8010 .timeout = 0,
8011 },
8012 .replica= {
8013 .type = WREPL_TYPE_MHOMED,
8014 .state = WREPL_STATE_TOMBSTONE,
8015 .node = WREPL_NODE_B,
8016 .is_static = false,
8017 .num_ips = ARRAY_SIZE(addresses_B_1),
8018 .ips = addresses_B_1,
8019 .apply_expected = false
8020 },
8021 },
8022 /*
8023 * multi homed vs. unique section
8024 */
8025 /*
8026 * mhomed,active vs. unique,active with same ip(s), unchecked
8027 */
8028 {
8029 .line = __location__,
8030 .name = _NBT_NAME("_MA_UA_SI_U", 0x00, NULL),
8031 .wins = {
8032 .nb_flags = 0,
8033 .mhomed = true,
8034 .num_ips = ctx->addresses_best_num,
8035 .ips = ctx->addresses_best,
8036 .apply_expected = true
8037 },
8038 .defend = {
8039 .timeout = 0,
8040 },
8041 .replica= {
8042 .type = WREPL_TYPE_UNIQUE,
8043 .state = WREPL_STATE_ACTIVE,
8044 .node = WREPL_NODE_B,
8045 .is_static = false,
8046 .num_ips = ctx->addresses_best_num,
8047 .ips = ctx->addresses_best,
8048 .apply_expected = true
8049 },
8050 },
8051 /*
8052 * mhomed,active vs. unique,active with different ip(s), positive response
8053 */
8054 {
8055 .line = __location__,
8056 .name = _NBT_NAME("_MA_UA_DI_P", 0x00, NULL),
8057 .wins = {
8058 .nb_flags = 0,
8059 .mhomed = true,
8060 .num_ips = ctx->addresses_best_num,
8061 .ips = ctx->addresses_best,
8062 .apply_expected = true
8063 },
8064 .defend = {
8065 .timeout = 10,
8066 .positive = true,
8067 },
8068 .replica= {
8069 .type = WREPL_TYPE_UNIQUE,
8070 .state = WREPL_STATE_ACTIVE,
8071 .node = WREPL_NODE_B,
8072 .is_static = false,
8073 .num_ips = ARRAY_SIZE(addresses_B_1),
8074 .ips = addresses_B_1,
8075 .apply_expected = false
8076 },
8077 },
8078 /*
8079 * mhomed,active vs. unique,active with different ip(s), positive response other ips
8080 */
8081 {
8082 .line = __location__,
8083 .name = _NBT_NAME("_MA_UA_DI_O", 0x00, NULL),
8084 .wins = {
8085 .nb_flags = 0,
8086 .mhomed = true,
8087 .num_ips = ctx->addresses_best_num,
8088 .ips = ctx->addresses_best,
8089 .apply_expected = true
8090 },
8091 .defend = {
8092 .timeout = 10,
8093 .positive = true,
8094 .num_ips = ARRAY_SIZE(addresses_A_3_4),
8095 .ips = addresses_A_3_4,
8096 },
8097 .replica= {
8098 .type = WREPL_TYPE_UNIQUE,
8099 .state = WREPL_STATE_ACTIVE,
8100 .node = WREPL_NODE_B,
8101 .is_static = false,
8102 .num_ips = ARRAY_SIZE(addresses_B_1),
8103 .ips = addresses_B_1,
8104 .apply_expected = false
8105 },
8106 },
8107 /*
8108 * mhomed,active vs. unique,active with different ip(s), negative response
8109 */
8110 {
8111 .line = __location__,
8112 .name = _NBT_NAME("_MA_UA_DI_N", 0x00, NULL),
8113 .wins = {
8114 .nb_flags = 0,
8115 .mhomed = true,
8116 .num_ips = ctx->addresses_best_num,
8117 .ips = ctx->addresses_best,
8118 .apply_expected = true
8119 },
8120 .defend = {
8121 .timeout = 10,
8122 .positive = false,
8123 },
8124 .replica= {
8125 .type = WREPL_TYPE_UNIQUE,
8126 .state = WREPL_STATE_ACTIVE,
8127 .node = WREPL_NODE_B,
8128 .is_static = false,
8129 .num_ips = ARRAY_SIZE(addresses_B_1),
8130 .ips = addresses_B_1,
8131 .apply_expected = true
8132 },
8133 },
8134 /*
8135 * mhomed,active vs. unique,tombstone with same ip(s), unchecked
8136 */
8137 {
8138 .line = __location__,
8139 .name = _NBT_NAME("_MA_UT_SI_U", 0x00, NULL),
8140 .wins = {
8141 .nb_flags = 0,
8142 .mhomed = true,
8143 .num_ips = ctx->addresses_best_num,
8144 .ips = ctx->addresses_best,
8145 .apply_expected = true
8146 },
8147 .defend = {
8148 .timeout = 0,
8149 },
8150 .replica= {
8151 .type = WREPL_TYPE_UNIQUE,
8152 .state = WREPL_STATE_TOMBSTONE,
8153 .node = WREPL_NODE_B,
8154 .is_static = false,
8155 .num_ips = ctx->addresses_best_num,
8156 .ips = ctx->addresses_best,
8157 .apply_expected = false
8158 },
8159 },
8160 /*
8161 * mhomed,active vs. unique,tombstone with different ip(s), unchecked
8162 */
8163 {
8164 .line = __location__,
8165 .name = _NBT_NAME("_MA_UT_DI_U", 0x00, NULL),
8166 .wins = {
8167 .nb_flags = 0,
8168 .mhomed = true,
8169 .num_ips = ctx->addresses_best_num,
8170 .ips = ctx->addresses_best,
8171 .apply_expected = true
8172 },
8173 .defend = {
8174 .timeout = 0,
8175 },
8176 .replica= {
8177 .type = WREPL_TYPE_UNIQUE,
8178 .state = WREPL_STATE_TOMBSTONE,
8179 .node = WREPL_NODE_B,
8180 .is_static = false,
8181 .num_ips = ARRAY_SIZE(addresses_B_1),
8182 .ips = addresses_B_1,
8183 .apply_expected = false
8184 },
8185 },
8186 /*
8187 * multi homed vs. normal group section
8188 */
8189 /*
8190 * mhomed,active vs. group,active with same ip(s), release expected
8191 */
8192 {
8193 .line = __location__,
8194 .name = _NBT_NAME("_MA_GA_SI_R", 0x00, NULL),
8195 .wins = {
8196 .nb_flags = 0,
8197 .mhomed = true,
8198 .num_ips = ctx->addresses_best_num,
8199 .ips = ctx->addresses_best,
8200 .apply_expected = true
8201 },
8202 .defend = {
8203 .timeout = 10,
8204 .expect_release = true,
8205 },
8206 .replica= {
8207 .type = WREPL_TYPE_GROUP,
8208 .state = WREPL_STATE_ACTIVE,
8209 .node = WREPL_NODE_B,
8210 .is_static = false,
8211 .num_ips = ctx->addresses_best_num,
8212 .ips = ctx->addresses_best,
8213 .apply_expected = true
8214 },
8215 },
8216 /*
8217 * mhomed,active vs. group,active with different ip(s), release expected
8218 */
8219 {
8220 .line = __location__,
8221 .name = _NBT_NAME("_MA_GA_DI_R", 0x00, NULL),
8222 .wins = {
8223 .nb_flags = 0,
8224 .mhomed = true,
8225 .num_ips = ctx->addresses_best_num,
8226 .ips = ctx->addresses_best,
8227 .apply_expected = true
8228 },
8229 .defend = {
8230 .timeout = 10,
8231 .expect_release = true,
8232 },
8233 .replica= {
8234 .type = WREPL_TYPE_GROUP,
8235 .state = WREPL_STATE_ACTIVE,
8236 .node = WREPL_NODE_B,
8237 .is_static = false,
8238 .num_ips = ARRAY_SIZE(addresses_B_1),
8239 .ips = addresses_B_1,
8240 .apply_expected = true
8241 },
8242 },
8243 /*
8244 * mhomed,active vs. group,tombstone with same ip(s), unchecked
8245 */
8246 {
8247 .line = __location__,
8248 .name = _NBT_NAME("_MA_GT_SI_U", 0x00, NULL),
8249 .wins = {
8250 .nb_flags = 0,
8251 .mhomed = true,
8252 .num_ips = ctx->addresses_best_num,
8253 .ips = ctx->addresses_best,
8254 .apply_expected = true
8255 },
8256 .defend = {
8257 .timeout = 0,
8258 },
8259 .replica= {
8260 .type = WREPL_TYPE_GROUP,
8261 .state = WREPL_STATE_TOMBSTONE,
8262 .node = WREPL_NODE_B,
8263 .is_static = false,
8264 .num_ips = ctx->addresses_best_num,
8265 .ips = ctx->addresses_best,
8266 .apply_expected = false
8267 },
8268 },
8269 /*
8270 * mhomed,active vs. group,tombstone with different ip(s), unchecked
8271 */
8272 {
8273 .line = __location__,
8274 .name = _NBT_NAME("_MA_GT_DI_U", 0x00, NULL),
8275 .wins = {
8276 .nb_flags = 0,
8277 .mhomed = true,
8278 .num_ips = ctx->addresses_best_num,
8279 .ips = ctx->addresses_best,
8280 .apply_expected = true
8281 },
8282 .defend = {
8283 .timeout = 0,
8284 },
8285 .replica= {
8286 .type = WREPL_TYPE_GROUP,
8287 .state = WREPL_STATE_TOMBSTONE,
8288 .node = WREPL_NODE_B,
8289 .is_static = false,
8290 .num_ips = ARRAY_SIZE(addresses_B_1),
8291 .ips = addresses_B_1,
8292 .apply_expected = false
8293 },
8294 },
8295 /*
8296 * multi homed vs. special group section
8297 */
8298 /*
8299 * mhomed,active vs. sgroup,active with same ip(s), release expected
8300 */
8301 {
8302 .line = __location__,
8303 .name = _NBT_NAME("_MA_SA_SI_R", 0x00, NULL),
8304 .wins = {
8305 .nb_flags = 0,
8306 .mhomed = true,
8307 .num_ips = ctx->addresses_best_num,
8308 .ips = ctx->addresses_best,
8309 .apply_expected = true
8310 },
8311 .defend = {
8312 .timeout = 10,
8313 .expect_release = true,
8314 },
8315 .replica= {
8316 .type = WREPL_TYPE_SGROUP,
8317 .state = WREPL_STATE_ACTIVE,
8318 .node = WREPL_NODE_B,
8319 .is_static = false,
8320 .num_ips = ctx->addresses_best_num,
8321 .ips = ctx->addresses_best,
8322 .apply_expected = true
8323 },
8324 },
8325 /*
8326 * mhomed,active vs. group,active with different ip(s), release expected
8327 */
8328 {
8329 .line = __location__,
8330 .name = _NBT_NAME("_MA_SA_DI_R", 0x00, NULL),
8331 .wins = {
8332 .nb_flags = 0,
8333 .mhomed = true,
8334 .num_ips = ctx->addresses_best_num,
8335 .ips = ctx->addresses_best,
8336 .apply_expected = true
8337 },
8338 .defend = {
8339 .timeout = 10,
8340 .expect_release = true,
8341 },
8342 .replica= {
8343 .type = WREPL_TYPE_SGROUP,
8344 .state = WREPL_STATE_ACTIVE,
8345 .node = WREPL_NODE_B,
8346 .is_static = false,
8347 .num_ips = ARRAY_SIZE(addresses_B_1),
8348 .ips = addresses_B_1,
8349 .apply_expected = true
8350 },
8351 },
8352 /*
8353 * mhomed,active vs. sgroup,tombstone with same ip(s), unchecked
8354 */
8355 {
8356 .line = __location__,
8357 .name = _NBT_NAME("_MA_ST_SI_U", 0x00, NULL),
8358 .wins = {
8359 .nb_flags = 0,
8360 .mhomed = true,
8361 .num_ips = ctx->addresses_best_num,
8362 .ips = ctx->addresses_best,
8363 .apply_expected = true
8364 },
8365 .defend = {
8366 .timeout = 0,
8367 },
8368 .replica= {
8369 .type = WREPL_TYPE_SGROUP,
8370 .state = WREPL_STATE_TOMBSTONE,
8371 .node = WREPL_NODE_B,
8372 .is_static = false,
8373 .num_ips = ctx->addresses_best_num,
8374 .ips = ctx->addresses_best,
8375 .apply_expected = false
8376 },
8377 },
8378 /*
8379 * mhomed,active vs. sgroup,tombstone with different ip(s), unchecked
8380 */
8381 {
8382 .line = __location__,
8383 .name = _NBT_NAME("_MA_ST_DI_U", 0x00, NULL),
8384 .wins = {
8385 .nb_flags = 0,
8386 .mhomed = true,
8387 .num_ips = ctx->addresses_best_num,
8388 .ips = ctx->addresses_best,
8389 .apply_expected = true
8390 },
8391 .defend = {
8392 .timeout = 0,
8393 },
8394 .replica= {
8395 .type = WREPL_TYPE_SGROUP,
8396 .state = WREPL_STATE_TOMBSTONE,
8397 .node = WREPL_NODE_B,
8398 .is_static = false,
8399 .num_ips = ARRAY_SIZE(addresses_B_1),
8400 .ips = addresses_B_1,
8401 .apply_expected = false
8402 },
8403 },
8404 /*
8405 * multi homed vs. multi homed section
8406 */
8407 /*
8408 * mhomed,active vs. mhomed,active with same ip(s), unchecked
8409 */
8410 {
8411 .line = __location__,
8412 .name = _NBT_NAME("_MA_MA_SI_U", 0x00, NULL),
8413 .wins = {
8414 .nb_flags = 0,
8415 .mhomed = true,
8416 .num_ips = ctx->addresses_best_num,
8417 .ips = ctx->addresses_best,
8418 .apply_expected = true
8419 },
8420 .defend = {
8421 .timeout = 0,
8422 },
8423 .replica= {
8424 .type = WREPL_TYPE_MHOMED,
8425 .state = WREPL_STATE_ACTIVE,
8426 .node = WREPL_NODE_B,
8427 .is_static = false,
8428 .num_ips = ctx->addresses_best_num,
8429 .ips = ctx->addresses_best,
8430 .apply_expected = true
8431 },
8432 },
8433 /*
8434 * mhomed,active vs. mhomed,active with superset ip(s), unchecked
8435 */
8436 {
8437 .line = __location__,
8438 .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL),
8439 .wins = {
8440 .nb_flags = 0,
8441 .mhomed = true,
8442 .num_ips = ctx->addresses_best_num,
8443 .ips = ctx->addresses_best,
8444 .apply_expected = true
8445 },
8446 .defend = {
8447 .timeout = 0,
8448 },
8449 .replica= {
8450 .type = WREPL_TYPE_MHOMED,
8451 .state = WREPL_STATE_ACTIVE,
8452 .node = WREPL_NODE_B,
8453 .is_static = false,
8454 .num_ips = ctx->addresses_all_num,
8455 .ips = ctx->addresses_all,
8456 .apply_expected = true
8457 },
8458 },
8459 /*
8460 * mhomed,active vs. mhomed,active with different ip(s), positive response
8461 */
8462 {
8463 .line = __location__,
8464 .name = _NBT_NAME("_MA_MA_DI_P", 0x00, NULL),
8465 .wins = {
8466 .nb_flags = 0,
8467 .mhomed = true,
8468 .num_ips = ctx->addresses_best_num,
8469 .ips = ctx->addresses_best,
8470 .apply_expected = true
8471 },
8472 .defend = {
8473 .timeout = 10,
8474 .positive = true,
8475 },
8476 .replica= {
8477 .type = WREPL_TYPE_MHOMED,
8478 .state = WREPL_STATE_ACTIVE,
8479 .node = WREPL_NODE_B,
8480 .is_static = false,
8481 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8482 .ips = addresses_B_3_4,
8483 .apply_expected = false
8484 },
8485 },
8486 /*
8487 * mhomed,active vs. mhomed,active with different ip(s), positive response other ips
8488 */
8489 {
8490 .line = __location__,
8491 .name = _NBT_NAME("_MA_MA_DI_O", 0x00, NULL),
8492 .wins = {
8493 .nb_flags = 0,
8494 .mhomed = true,
8495 .num_ips = ctx->addresses_best_num,
8496 .ips = ctx->addresses_best,
8497 .apply_expected = true
8498 },
8499 .defend = {
8500 .timeout = 10,
8501 .positive = true,
8502 .num_ips = ARRAY_SIZE(addresses_A_3_4),
8503 .ips = addresses_A_3_4,
8504 },
8505 .replica= {
8506 .type = WREPL_TYPE_MHOMED,
8507 .state = WREPL_STATE_ACTIVE,
8508 .node = WREPL_NODE_B,
8509 .is_static = false,
8510 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8511 .ips = addresses_B_3_4,
8512 .apply_expected = false
8513 },
8514 },
8515 /*
8516 * mhomed,active vs. mhomed,active with different ip(s), negative response
8517 */
8518 {
8519 .line = __location__,
8520 .name = _NBT_NAME("_MA_MA_DI_N", 0x00, NULL),
8521 .wins = {
8522 .nb_flags = 0,
8523 .mhomed = true,
8524 .num_ips = ctx->addresses_best_num,
8525 .ips = ctx->addresses_best,
8526 .apply_expected = true
8527 },
8528 .defend = {
8529 .timeout = 10,
8530 .positive = false,
8531 },
8532 .replica= {
8533 .type = WREPL_TYPE_MHOMED,
8534 .state = WREPL_STATE_ACTIVE,
8535 .node = WREPL_NODE_B,
8536 .is_static = false,
8537 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8538 .ips = addresses_B_3_4,
8539 .apply_expected = true
8540 },
8541 },
8542 /*
8543 * mhomed,active vs. mhomed,tombstone with same ip(s), unchecked
8544 */
8545 {
8546 .line = __location__,
8547 .name = _NBT_NAME("_MA_MT_SI_U", 0x00, NULL),
8548 .wins = {
8549 .nb_flags = 0,
8550 .mhomed = true,
8551 .num_ips = ctx->addresses_best_num,
8552 .ips = ctx->addresses_best,
8553 .apply_expected = true
8554 },
8555 .defend = {
8556 .timeout = 0,
8557 },
8558 .replica= {
8559 .type = WREPL_TYPE_MHOMED,
8560 .state = WREPL_STATE_TOMBSTONE,
8561 .node = WREPL_NODE_B,
8562 .is_static = false,
8563 .num_ips = ctx->addresses_best_num,
8564 .ips = ctx->addresses_best,
8565 .apply_expected = false
8566 },
8567 },
8568 /*
8569 * mhomed,active vs. mhomed,tombstone with different ip(s), unchecked
8570 */
8571 {
8572 .line = __location__,
8573 .name = _NBT_NAME("_MA_MT_DI_U", 0x00, NULL),
8574 .wins = {
8575 .nb_flags = 0,
8576 .mhomed = true,
8577 .num_ips = ctx->addresses_best_num,
8578 .ips = ctx->addresses_best,
8579 .apply_expected = true
8580 },
8581 .defend = {
8582 .timeout = 0,
8583 },
8584 .replica= {
8585 .type = WREPL_TYPE_MHOMED,
8586 .state = WREPL_STATE_TOMBSTONE,
8587 .node = WREPL_NODE_B,
8588 .is_static = false,
8589 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8590 .ips = addresses_B_3_4,
8591 .apply_expected = false
8592 },
8593 },
8594 /*
8595 * some more multi homed test, including merging
8596 */
8597 /*
8598 * mhomed,active vs. mhomed,active with superset ip(s), unchecked
8599 */
8600 {
8601 .line = __location__,
8602 .section= "Test Replica vs. owned active: some more MHOMED combinations",
8603 .name = _NBT_NAME("_MA_MA_SP_U", 0x00, NULL),
8604 .comment= "C:MHOMED vs. B:ALL => B:ALL",
8605 .skip = (ctx->addresses_all_num < 3),
8606 .wins = {
8607 .nb_flags = 0,
8608 .mhomed = true,
8609 .num_ips = ctx->addresses_mhomed_num,
8610 .ips = ctx->addresses_mhomed,
8611 .apply_expected = true
8612 },
8613 .defend = {
8614 .timeout = 0,
8615 },
8616 .replica= {
8617 .type = WREPL_TYPE_MHOMED,
8618 .state = WREPL_STATE_ACTIVE,
8619 .node = WREPL_NODE_B,
8620 .is_static = false,
8621 .num_ips = ctx->addresses_all_num,
8622 .ips = ctx->addresses_all,
8623 .apply_expected = true
8624 },
8625 },
8626 /*
8627 * mhomed,active vs. mhomed,active with same ips, unchecked
8628 */
8629 {
8630 .line = __location__,
8631 .name = _NBT_NAME("_MA_MA_SM_U", 0x00, NULL),
8632 .comment= "C:MHOMED vs. B:MHOMED => B:MHOMED",
8633 .skip = (ctx->addresses_mhomed_num < 2),
8634 .wins = {
8635 .nb_flags = 0,
8636 .mhomed = true,
8637 .num_ips = ctx->addresses_mhomed_num,
8638 .ips = ctx->addresses_mhomed,
8639 .apply_expected = true
8640 },
8641 .defend = {
8642 .timeout = 0,
8643 },
8644 .replica= {
8645 .type = WREPL_TYPE_MHOMED,
8646 .state = WREPL_STATE_ACTIVE,
8647 .node = WREPL_NODE_B,
8648 .is_static = false,
8649 .num_ips = ctx->addresses_mhomed_num,
8650 .ips = ctx->addresses_mhomed,
8651 .apply_expected = true
8652 },
8653 },
8654 /*
8655 * mhomed,active vs. mhomed,active with subset ip(s), positive response
8656 */
8657 {
8658 .line = __location__,
8659 .name = _NBT_NAME("_MA_MA_SB_P", 0x00, NULL),
8660 .comment= "C:MHOMED vs. B:BEST (C:MHOMED) => B:MHOMED",
8661 .skip = (ctx->addresses_mhomed_num < 2),
8662 .wins = {
8663 .nb_flags = 0,
8664 .mhomed = true,
8665 .num_ips = ctx->addresses_mhomed_num,
8666 .ips = ctx->addresses_mhomed,
8667 .apply_expected = true
8668 },
8669 .defend = {
8670 .timeout = 10,
8671 .positive = true
8672 },
8673 .replica= {
8674 .type = WREPL_TYPE_MHOMED,
8675 .state = WREPL_STATE_ACTIVE,
8676 .node = WREPL_NODE_B,
8677 .is_static = false,
8678 .num_ips = ctx->addresses_best_num,
8679 .ips = ctx->addresses_best,
8680 .mhomed_merge = true
8681 },
8682 },
8683 /*
8684 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with all addresses
8685 */
8686 {
8687 .line = __location__,
8688 .name = _NBT_NAME("_MA_MA_SB_A", 0x00, NULL),
8689 .comment= "C:MHOMED vs. B:BEST (C:ALL) => B:MHOMED",
8690 .skip = (ctx->addresses_all_num < 3),
8691 .wins = {
8692 .nb_flags = 0,
8693 .mhomed = true,
8694 .num_ips = ctx->addresses_mhomed_num,
8695 .ips = ctx->addresses_mhomed,
8696 .apply_expected = true
8697 },
8698 .defend = {
8699 .timeout = 10,
8700 .positive = true,
8701 .num_ips = ctx->addresses_all_num,
8702 .ips = ctx->addresses_all,
8703 },
8704 .replica= {
8705 .type = WREPL_TYPE_MHOMED,
8706 .state = WREPL_STATE_ACTIVE,
8707 .node = WREPL_NODE_B,
8708 .is_static = false,
8709 .num_ips = ctx->addresses_best_num,
8710 .ips = ctx->addresses_best,
8711 .mhomed_merge = true
8712 },
8713 },
8714 /*
8715 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with replicas addresses
8716 * TODO: check why the server sends a name release demand for one address?
8717 * the release demand has no effect to the database record...
8718 */
8719 {
8720 .line = __location__,
8721 .name = _NBT_NAME("_MA_MA_SB_PRA", 0x00, NULL),
8722 .comment= "C:MHOMED vs. B:BEST (C:BEST) => C:MHOMED",
8723 .skip = (ctx->addresses_all_num < 2),
8724 .wins = {
8725 .nb_flags = 0,
8726 .mhomed = true,
8727 .num_ips = ctx->addresses_mhomed_num,
8728 .ips = ctx->addresses_mhomed,
8729 .apply_expected = true
8730 },
8731 .defend = {
8732 .timeout = 10,
8733 .positive = true,
8734 .num_ips = ctx->addresses_best_num,
8735 .ips = ctx->addresses_best,
8736 .late_release = true
8737 },
8738 .replica= {
8739 .type = WREPL_TYPE_MHOMED,
8740 .state = WREPL_STATE_ACTIVE,
8741 .node = WREPL_NODE_B,
8742 .is_static = false,
8743 .num_ips = ctx->addresses_best_num,
8744 .ips = ctx->addresses_best,
8745 .apply_expected = false
8746 },
8747 },
8748 /*
8749 * mhomed,active vs. mhomed,active with subset ip(s), positive response, with other addresses
8750 */
8751 {
8752 .line = __location__,
8753 .name = _NBT_NAME("_MA_MA_SB_O", 0x00, NULL),
8754 .comment= "C:MHOMED vs. B:BEST (B:B_3_4) =>C:MHOMED",
8755 .skip = (ctx->addresses_all_num < 2),
8756 .wins = {
8757 .nb_flags = 0,
8758 .mhomed = true,
8759 .num_ips = ctx->addresses_mhomed_num,
8760 .ips = ctx->addresses_mhomed,
8761 .apply_expected = true
8762 },
8763 .defend = {
8764 .timeout = 10,
8765 .positive = true,
8766 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8767 .ips = addresses_B_3_4,
8768 },
8769 .replica= {
8770 .type = WREPL_TYPE_MHOMED,
8771 .state = WREPL_STATE_ACTIVE,
8772 .node = WREPL_NODE_B,
8773 .is_static = false,
8774 .num_ips = ctx->addresses_best_num,
8775 .ips = ctx->addresses_best,
8776 .apply_expected = false
8777 },
8778 },
8779 /*
8780 * mhomed,active vs. mhomed,active with subset ip(s), negative response
8781 */
8782 {
8783 .line = __location__,
8784 .name = _NBT_NAME("_MA_MA_SB_N", 0x00, NULL),
8785 .comment= "C:MHOMED vs. B:BEST (NEGATIVE) => B:BEST",
8786 .skip = (ctx->addresses_mhomed_num < 2),
8787 .wins = {
8788 .nb_flags = 0,
8789 .mhomed = true,
8790 .num_ips = ctx->addresses_mhomed_num,
8791 .ips = ctx->addresses_mhomed,
8792 .apply_expected = true
8793 },
8794 .defend = {
8795 .timeout = 10,
8796 .positive = false
8797 },
8798 .replica= {
8799 .type = WREPL_TYPE_MHOMED,
8800 .state = WREPL_STATE_ACTIVE,
8801 .node = WREPL_NODE_B,
8802 .is_static = false,
8803 .num_ips = ctx->addresses_best_num,
8804 .ips = ctx->addresses_best,
8805 .apply_expected = true
8806 },
8807 },
8808 /*
8809 * some more multi homed and unique test, including merging
8810 */
8811 /*
8812 * mhomed,active vs. unique,active with subset ip(s), positive response
8813 */
8814 {
8815 .line = __location__,
8816 .section= "Test Replica vs. owned active: some more UNIQUE,MHOMED combinations",
8817 .name = _NBT_NAME("_MA_UA_SB_P", 0x00, NULL),
8818 .comment= "C:MHOMED vs. B:UNIQUE,BEST (C:MHOMED) => B:MHOMED",
8819 .skip = (ctx->addresses_all_num < 2),
8820 .wins = {
8821 .nb_flags = 0,
8822 .mhomed = true,
8823 .num_ips = ctx->addresses_mhomed_num,
8824 .ips = ctx->addresses_mhomed,
8825 .apply_expected = true
8826 },
8827 .defend = {
8828 .timeout = 10,
8829 .positive = true,
8830 },
8831 .replica= {
8832 .type = WREPL_TYPE_UNIQUE,
8833 .state = WREPL_STATE_ACTIVE,
8834 .node = WREPL_NODE_B,
8835 .is_static = false,
8836 .num_ips = ctx->addresses_best_num,
8837 .ips = ctx->addresses_best,
8838 .mhomed_merge = true
8839 },
8840 },
8841 /*
8842 * unique,active vs. unique,active with different ip(s), positive response, with replicas address
8843 * TODO: check why the server sends a name release demand for one address?
8844 * the release demand has no effect to the database record...
8845 */
8846 {
8847 .line = __location__,
8848 .name = _NBT_NAME("_UA_UA_DI_PRA", 0x00, NULL),
8849 .comment= "C:BEST vs. B:BEST2 (C:BEST2,LR:BEST2) => C:BEST",
8850 .skip = (ctx->addresses_all_num < 2),
8851 .wins = {
8852 .nb_flags = 0,
8853 .mhomed = false,
8854 .num_ips = ctx->addresses_best_num,
8855 .ips = ctx->addresses_best,
8856 .apply_expected = true
8857 },
8858 .defend = {
8859 .timeout = 10,
8860 .positive = true,
8861 .num_ips = ctx->addresses_best2_num,
8862 .ips = ctx->addresses_best2,
8863 .late_release = true
8864 },
8865 .replica= {
8866 .type = WREPL_TYPE_UNIQUE,
8867 .state = WREPL_STATE_ACTIVE,
8868 .node = WREPL_NODE_B,
8869 .is_static = false,
8870 .num_ips = ctx->addresses_best2_num,
8871 .ips = ctx->addresses_best2,
8872 .apply_expected = false,
8873 },
8874 },
8875 /*
8876 * unique,active vs. unique,active with different ip(s), positive response, with all addresses
8877 */
8878 {
8879 .line = __location__,
8880 .name = _NBT_NAME("_UA_UA_DI_A", 0x00, NULL),
8881 .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED",
8882 .skip = (ctx->addresses_all_num < 3),
8883 .wins = {
8884 .nb_flags = 0,
8885 .mhomed = false,
8886 .num_ips = ctx->addresses_best_num,
8887 .ips = ctx->addresses_best,
8888 .apply_expected = true
8889 },
8890 .defend = {
8891 .timeout = 10,
8892 .positive = true,
8893 .num_ips = ctx->addresses_all_num,
8894 .ips = ctx->addresses_all,
8895 },
8896 .replica= {
8897 .type = WREPL_TYPE_UNIQUE,
8898 .state = WREPL_STATE_ACTIVE,
8899 .node = WREPL_NODE_B,
8900 .is_static = false,
8901 .num_ips = ctx->addresses_best2_num,
8902 .ips = ctx->addresses_best2,
8903 .mhomed_merge = true,
8904 },
8905 },
8906 /*
8907 * unique,active vs. mhomed,active with different ip(s), positive response, with all addresses
8908 */
8909 {
8910 .line = __location__,
8911 .name = _NBT_NAME("_UA_MA_DI_A", 0x00, NULL),
8912 .comment= "C:BEST vs. B:BEST2 (C:ALL) => B:MHOMED",
8913 .skip = (ctx->addresses_all_num < 3),
8914 .wins = {
8915 .nb_flags = 0,
8916 .mhomed = false,
8917 .num_ips = ctx->addresses_best_num,
8918 .ips = ctx->addresses_best,
8919 .apply_expected = true
8920 },
8921 .defend = {
8922 .timeout = 10,
8923 .positive = true,
8924 .num_ips = ctx->addresses_all_num,
8925 .ips = ctx->addresses_all,
8926 },
8927 .replica= {
8928 .type = WREPL_TYPE_MHOMED,
8929 .state = WREPL_STATE_ACTIVE,
8930 .node = WREPL_NODE_B,
8931 .is_static = false,
8932 .num_ips = ctx->addresses_best2_num,
8933 .ips = ctx->addresses_best2,
8934 .mhomed_merge = true,
8935 },
8936 },
8937 /*
8938 * special group vs. special group merging section
8939 */
8940 /*
8941 * sgroup,active vs. sgroup,active with different ip(s)
8942 */
8943 {
8944 .line = __location__,
8945 .section= "Test Replica vs. owned active: SGROUP vs. SGROUP tests",
8946 .name = _NBT_NAME("_SA_SA_DI_U", 0x1C, NULL),
8947 .skip = (ctx->addresses_all_num < 3),
8948 .wins = {
8949 .nb_flags = NBT_NM_GROUP,
8950 .mhomed = false,
8951 .num_ips = ctx->addresses_mhomed_num,
8952 .ips = ctx->addresses_mhomed,
8953 .apply_expected = true
8954 },
8955 .defend = {
8956 .timeout = 0,
8957 },
8958 .replica= {
8959 .type = WREPL_TYPE_SGROUP,
8960 .state = WREPL_STATE_ACTIVE,
8961 .node = WREPL_NODE_B,
8962 .is_static = false,
8963 .num_ips = ARRAY_SIZE(addresses_B_3_4),
8964 .ips = addresses_B_3_4,
8965 .sgroup_merge = true
8966 },
8967 },
8968 /*
8969 * sgroup,active vs. sgroup,active with same ip(s)
8970 */
8971 {
8972 .line = __location__,
8973 .name = _NBT_NAME("_SA_SA_SI_U", 0x1C, NULL),
8974 .skip = (ctx->addresses_all_num < 3),
8975 .wins = {
8976 .nb_flags = NBT_NM_GROUP,
8977 .mhomed = false,
8978 .num_ips = ctx->addresses_mhomed_num,
8979 .ips = ctx->addresses_mhomed,
8980 .apply_expected = true
8981 },
8982 .defend = {
8983 .timeout = 0,
8984 },
8985 .replica= {
8986 .type = WREPL_TYPE_SGROUP,
8987 .state = WREPL_STATE_ACTIVE,
8988 .node = WREPL_NODE_B,
8989 .is_static = false,
8990 .num_ips = ctx->addresses_mhomed_num,
8991 .ips = ctx->addresses_mhomed,
8992 .sgroup_merge = true
8993 },
8994 },
8995 /*
8996 * sgroup,active vs. sgroup,active with superset ip(s)
8997 */
8998 {
8999 .line = __location__,
9000 .name = _NBT_NAME("_SA_SA_SP_U", 0x1C, NULL),
9001 .skip = (ctx->addresses_all_num < 3),
9002 .wins = {
9003 .nb_flags = NBT_NM_GROUP,
9004 .mhomed = false,
9005 .num_ips = ctx->addresses_mhomed_num,
9006 .ips = ctx->addresses_mhomed,
9007 .apply_expected = true
9008 },
9009 .defend = {
9010 .timeout = 0,
9011 },
9012 .replica= {
9013 .type = WREPL_TYPE_SGROUP,
9014 .state = WREPL_STATE_ACTIVE,
9015 .node = WREPL_NODE_B,
9016 .is_static = false,
9017 .num_ips = ctx->addresses_all_num,
9018 .ips = ctx->addresses_all,
9019 .sgroup_merge = true
9020 },
9021 },
9022 /*
9023 * sgroup,active vs. sgroup,active with subset ip(s)
9024 */
9025 {
9026 .line = __location__,
9027 .name = _NBT_NAME("_SA_SA_SB_U", 0x1C, NULL),
9028 .skip = (ctx->addresses_all_num < 3),
9029 .wins = {
9030 .nb_flags = NBT_NM_GROUP,
9031 .mhomed = false,
9032 .num_ips = ctx->addresses_mhomed_num,
9033 .ips = ctx->addresses_mhomed,
9034 .apply_expected = true
9035 },
9036 .defend = {
9037 .timeout = 0,
9038 },
9039 .replica= {
9040 .type = WREPL_TYPE_SGROUP,
9041 .state = WREPL_STATE_ACTIVE,
9042 .node = WREPL_NODE_B,
9043 .is_static = false,
9044 .num_ips = ctx->addresses_best_num,
9045 .ips = ctx->addresses_best,
9046 .sgroup_merge = true
9047 },
9048 },
9049 /*
9050 * sgroup,active vs. sgroup,tombstone with different ip(s)
9051 */
9052 {
9053 .line = __location__,
9054 .name = _NBT_NAME("_SA_ST_DI_U", 0x1C, NULL),
9055 .skip = (ctx->addresses_all_num < 3),
9056 .wins = {
9057 .nb_flags = NBT_NM_GROUP,
9058 .mhomed = false,
9059 .num_ips = ctx->addresses_mhomed_num,
9060 .ips = ctx->addresses_mhomed,
9061 .apply_expected = true
9062 },
9063 .defend = {
9064 .timeout = 0,
9065 },
9066 .replica= {
9067 .type = WREPL_TYPE_SGROUP,
9068 .state = WREPL_STATE_TOMBSTONE,
9069 .node = WREPL_NODE_B,
9070 .is_static = false,
9071 .num_ips = ARRAY_SIZE(addresses_B_3_4),
9072 .ips = addresses_B_3_4,
9073 .apply_expected = false
9074 },
9075 },
9076 /*
9077 * sgroup,active vs. sgroup,tombstone with same ip(s)
9078 */
9079 {
9080 .line = __location__,
9081 .name = _NBT_NAME("_SA_ST_SI_U", 0x1C, NULL),
9082 .skip = (ctx->addresses_all_num < 3),
9083 .wins = {
9084 .nb_flags = NBT_NM_GROUP,
9085 .mhomed = false,
9086 .num_ips = ctx->addresses_mhomed_num,
9087 .ips = ctx->addresses_mhomed,
9088 .apply_expected = true
9089 },
9090 .defend = {
9091 .timeout = 0,
9092 },
9093 .replica= {
9094 .type = WREPL_TYPE_SGROUP,
9095 .state = WREPL_STATE_TOMBSTONE,
9096 .node = WREPL_NODE_B,
9097 .is_static = false,
9098 .num_ips = ctx->addresses_mhomed_num,
9099 .ips = ctx->addresses_mhomed,
9100 .apply_expected = false
9101 },
9102 },
9103 /*
9104 * sgroup,active vs. sgroup,tombstone with superset ip(s)
9105 */
9106 {
9107 .line = __location__,
9108 .name = _NBT_NAME("_SA_ST_SP_U", 0x1C, NULL),
9109 .skip = (ctx->addresses_all_num < 3),
9110 .wins = {
9111 .nb_flags = NBT_NM_GROUP,
9112 .mhomed = false,
9113 .num_ips = ctx->addresses_mhomed_num,
9114 .ips = ctx->addresses_mhomed,
9115 .apply_expected = true
9116 },
9117 .defend = {
9118 .timeout = 0,
9119 },
9120 .replica= {
9121 .type = WREPL_TYPE_SGROUP,
9122 .state = WREPL_STATE_TOMBSTONE,
9123 .node = WREPL_NODE_B,
9124 .is_static = false,
9125 .num_ips = ctx->addresses_all_num,
9126 .ips = ctx->addresses_all,
9127 .apply_expected = false
9128 },
9129 },
9130 /*
9131 * sgroup,active vs. sgroup,tombstone with subset ip(s)
9132 */
9133 {
9134 .line = __location__,
9135 .name = _NBT_NAME("_SA_ST_SB_U", 0x1C, NULL),
9136 .skip = (ctx->addresses_all_num < 3),
9137 .wins = {
9138 .nb_flags = NBT_NM_GROUP,
9139 .mhomed = false,
9140 .num_ips = ctx->addresses_mhomed_num,
9141 .ips = ctx->addresses_mhomed,
9142 .apply_expected = true
9143 },
9144 .defend = {
9145 .timeout = 0,
9146 },
9147 .replica= {
9148 .type = WREPL_TYPE_SGROUP,
9149 .state = WREPL_STATE_TOMBSTONE,
9150 .node = WREPL_NODE_B,
9151 .is_static = false,
9152 .num_ips = ctx->addresses_best_num,
9153 .ips = ctx->addresses_best,
9154 .apply_expected = false
9155 },
9156 },
9157 };
9158
9159 if (!ctx->nbtsock_srv) {
9160 torture_comment(tctx, "SKIP: Test Replica records vs. owned active records: not bound to port[%d]\n",
9161 lp_nbt_port(tctx->lp_ctx));
9162 return true;
9163 }
9164
9165 torture_comment(tctx, "Test Replica records vs. owned active records\n");
9166
9167 for(i=0; ret && i < ARRAY_SIZE(records); i++) {
9168 struct timeval end;
9169 struct test_conflict_owned_active_vs_replica_struct record = records[i];
9170 uint32_t j, count = 1;
9171 const char *action;
9172
9173 if (records[i].wins.mhomed || records[i].name.type == 0x1C) {
9174 count = records[i].wins.num_ips;
9175 }
9176
9177 if (records[i].section) {
9178 torture_comment(tctx, "%s\n", records[i].section);
9179 }
9180
9181 if (records[i].skip) {
9182 torture_comment(tctx, "%s => SKIPPED\n", nbt_name_string(ctx, &records[i].name));
9183 continue;
9184 }
9185
9186 if (records[i].replica.mhomed_merge) {
9187 action = "MHOMED_MERGE";
9188 } else if (records[i].replica.sgroup_merge) {
9189 action = "SGROUP_MERGE";
9190 } else if (records[i].replica.apply_expected) {
9191 action = "REPLACE";
9192 } else {
9193 action = "NOT REPLACE";
9194 }
9195
9196 torture_comment(tctx, "%s%s%s => %s\n",
9197 nbt_name_string(ctx, &records[i].name),
9198 (records[i].comment?": ":""),
9199 (records[i].comment?records[i].comment:""),
9200 action);
9201
9202 /* Prepare for multi homed registration */
9203 ZERO_STRUCT(records[i].defend);
9204 records[i].defend.timeout = 10;
9205 records[i].defend.positive = true;
9206 nbt_set_incoming_handler(ctx->nbtsock_srv,
9207 test_conflict_owned_active_vs_replica_handler,
9208 &records[i]);
9209 if (ctx->nbtsock_srv2) {
9210 nbt_set_incoming_handler(ctx->nbtsock_srv2,
9211 test_conflict_owned_active_vs_replica_handler,
9212 &records[i]);
9213 }
9214
9215 /*
9216 * Setup Register
9217 */
9218 for (j=0; j < count; j++) {
9219 struct nbt_name_request *req;
9220
9221 name_register->in.name = records[i].name;
9222 name_register->in.dest_addr = ctx->address;
9223 name_register->in.dest_port = lp_nbt_port(tctx->lp_ctx);
9224 name_register->in.address = records[i].wins.ips[j].ip;
9225 name_register->in.nb_flags = records[i].wins.nb_flags;
9226 name_register->in.register_demand= false;
9227 name_register->in.broadcast = false;
9228 name_register->in.multi_homed = records[i].wins.mhomed;
9229 name_register->in.ttl = 300000;
9230 name_register->in.timeout = 70;
9231 name_register->in.retries = 0;
9232
9233 req = nbt_name_register_send(ctx->nbtsock, name_register);
9234
9235 /* push the request on the wire */
9236 event_loop_once(ctx->nbtsock->event_ctx);
9237
9238 /*
9239 * if we register multiple addresses,
9240 * the server will do name queries to see if the old addresses
9241 * are still alive
9242 */
9243 if (records[i].wins.mhomed && j > 0) {
9244 end = timeval_current_ofs(records[i].defend.timeout,0);
9245 records[i].defend.ret = true;
9246 while (records[i].defend.timeout > 0) {
9247 event_loop_once(ctx->nbtsock_srv->event_ctx);
9248 if (timeval_expired(&end)) break;
9249 }
9250 ret &= records[i].defend.ret;
9251 }
9252
9253 status = nbt_name_register_recv(req, ctx, name_register);
9254 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
9255 torture_comment(tctx, "No response from %s for name register\n", ctx->address);
9256 ret = false;
9257 }
9258 if (!NT_STATUS_IS_OK(status)) {
9259 torture_comment(tctx, "Bad response from %s for name register - %s\n",
9260 ctx->address, nt_errstr(status));
9261 ret = false;
9262 }
9263 CHECK_VALUE(tctx, name_register->out.rcode, 0);
9264 CHECK_VALUE_STRING(tctx, name_register->out.reply_from, ctx->address);
9265 CHECK_VALUE(tctx, name_register->out.name.type, records[i].name.type);
9266 CHECK_VALUE_STRING(tctx, name_register->out.name.name, records[i].name.name);
9267 CHECK_VALUE_STRING(tctx, name_register->out.name.scope, records[i].name.scope);
9268 CHECK_VALUE_STRING(tctx, name_register->out.reply_addr, records[i].wins.ips[j].ip);
9269 }
9270
9271 /* Prepare for the current test */
9272 records[i].defend = record.defend;
9273 nbt_set_incoming_handler(ctx->nbtsock_srv,
9274 test_conflict_owned_active_vs_replica_handler,
9275 &records[i]);
9276 if (ctx->nbtsock_srv2) {
9277 nbt_set_incoming_handler(ctx->nbtsock_srv2,
9278 test_conflict_owned_active_vs_replica_handler,
9279 &records[i]);
9280 }
9281
9282 /*
9283 * Setup Replica
9284 */
9285 wins_name->name = &records[i].name;
9286 wins_name->flags = WREPL_NAME_FLAGS(records[i].replica.type,
9287 records[i].replica.state,
9288 records[i].replica.node,
9289 records[i].replica.is_static);
9290 wins_name->id = ++ctx->b.max_version;
9291 if (wins_name->flags & 2) {
9292 wins_name->addresses.addresses.num_ips = records[i].replica.num_ips;
9293 wins_name->addresses.addresses.ips = discard_const(records[i].replica.ips);
9294 } else {
9295 wins_name->addresses.ip = records[i].replica.ips[0].ip;
9296 }
9297 wins_name->unknown = "255.255.255.255";
9298
9299 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9300
9301 /*
9302 * wait for the name query, which is handled in
9303 * test_conflict_owned_active_vs_replica_handler()
9304 */
9305 end = timeval_current_ofs(records[i].defend.timeout,0);
9306 records[i].defend.ret = true;
9307 while (records[i].defend.timeout > 0) {
9308 event_loop_once(ctx->nbtsock_srv->event_ctx);
9309 if (timeval_expired(&end)) break;
9310 }
9311 ret &= records[i].defend.ret;
9312
9313 if (records[i].defend.late_release) {
9314 records[i].defend = record.defend;
9315 records[i].defend.expect_release = true;
9316 /*
9317 * wait for the name release demand, which is handled in
9318 * test_conflict_owned_active_vs_replica_handler()
9319 */
9320 end = timeval_current_ofs(records[i].defend.timeout,0);
9321 records[i].defend.ret = true;
9322 while (records[i].defend.timeout > 0) {
9323 event_loop_once(ctx->nbtsock_srv->event_ctx);
9324 if (timeval_expired(&end)) break;
9325 }
9326 ret &= records[i].defend.ret;
9327 }
9328
9329 if (records[i].replica.mhomed_merge) {
9330 ret &= test_wrepl_mhomed_merged(tctx, ctx, &ctx->c,
9331 records[i].wins.num_ips, records[i].wins.ips,
9332 &ctx->b,
9333 records[i].replica.num_ips, records[i].replica.ips,
9334 wins_name);
9335 } else if (records[i].replica.sgroup_merge) {
9336 ret &= test_wrepl_sgroup_merged(tctx, ctx, NULL,
9337 &ctx->c,
9338 records[i].wins.num_ips, records[i].wins.ips,
9339 &ctx->b,
9340 records[i].replica.num_ips, records[i].replica.ips,
9341 wins_name);
9342 } else {
9343 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name,
9344 records[i].replica.apply_expected);
9345 }
9346
9347 if (records[i].replica.apply_expected ||
9348 records[i].replica.mhomed_merge) {
9349 wins_name->name = &records[i].name;
9350 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
9351 WREPL_STATE_TOMBSTONE,
9352 WREPL_NODE_B, false);
9353 wins_name->id = ++ctx->b.max_version;
9354 wins_name->addresses.ip = addresses_B_1[0].ip;
9355 wins_name->unknown = "255.255.255.255";
9356
9357 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9358 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9359 } else {
9360 for (j=0; j < count; j++) {
9361 struct nbt_name_socket *nbtsock = ctx->nbtsock;
9362
9363 if (ctx->myaddr2 && strcmp(records[i].wins.ips[j].ip, ctx->myaddr2->addr) == 0) {
9364 nbtsock = ctx->nbtsock2;
9365 }
9366
9367 release->in.name = records[i].name;
9368 release->in.dest_addr = ctx->address;
9369 release->in.dest_port = lp_nbt_port(tctx->lp_ctx);
9370 release->in.address = records[i].wins.ips[j].ip;
9371 release->in.nb_flags = records[i].wins.nb_flags;
9372 release->in.broadcast = false;
9373 release->in.timeout = 30;
9374 release->in.retries = 0;
9375
9376 status = nbt_name_release(nbtsock, ctx, release);
9377 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
9378 torture_comment(tctx, "No response from %s for name release\n", ctx->address);
9379 return false;
9380 }
9381 if (!NT_STATUS_IS_OK(status)) {
9382 torture_comment(tctx, "Bad response from %s for name query - %s\n",
9383 ctx->address, nt_errstr(status));
9384 return false;
9385 }
9386 CHECK_VALUE(tctx, release->out.rcode, 0);
9387 }
9388
9389 if (records[i].replica.sgroup_merge) {
9390 /* clean up the SGROUP record */
9391 wins_name->name = &records[i].name;
9392 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
9393 WREPL_STATE_ACTIVE,
9394 WREPL_NODE_B, false);
9395 wins_name->id = ++ctx->b.max_version;
9396 wins_name->addresses.addresses.num_ips = 0;
9397 wins_name->addresses.addresses.ips = NULL;
9398 wins_name->unknown = "255.255.255.255";
9399 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9400
9401 /* take ownership of the SGROUP record */
9402 wins_name->name = &records[i].name;
9403 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_SGROUP,
9404 WREPL_STATE_ACTIVE,
9405 WREPL_NODE_B, false);
9406 wins_name->id = ++ctx->b.max_version;
9407 wins_name->addresses.addresses.num_ips = ARRAY_SIZE(addresses_B_1);
9408 wins_name->addresses.addresses.ips = discard_const(addresses_B_1);
9409 wins_name->unknown = "255.255.255.255";
9410 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9411 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9412
9413 /* overwrite the SGROUP record with unique,tombstone */
9414 wins_name->name = &records[i].name;
9415 wins_name->flags = WREPL_NAME_FLAGS(WREPL_TYPE_UNIQUE,
9416 WREPL_STATE_TOMBSTONE,
9417 WREPL_NODE_B, false);
9418 wins_name->id = ++ctx->b.max_version;
9419 wins_name->addresses.ip = addresses_A_1[0].ip;
9420 wins_name->unknown = "255.255.255.255";
9421 ret &= test_wrepl_update_one(tctx, ctx, &ctx->b, wins_name);
9422 ret &= test_wrepl_is_applied(tctx, ctx, &ctx->b, wins_name, true);
9423 }
9424 }
9425
9426 if (!ret) {
9427 torture_comment(tctx, "conflict handled wrong or record[%u]: %s\n", i, records[i].line);
9428 return ret;
9429 }
9430 }
9431
9432 return ret;
9433 }
9434
9435 #define _NBT_ASSERT(v, correct) do { \
9436 if ((v) != (correct)) { \
9437 printf("(%s) Incorrect value %s=%d - should be %s (%d)\n", \
9438 __location__, #v, v, #correct, correct); \
9439 return; \
9440 } \
9441 } while (0)
9442
9443 #define _NBT_ASSERT_STRING(v, correct) do { \
9444 if ( ((!v) && (correct)) || \
9445 ((v) && (!correct)) || \
9446 ((v) && (correct) && strcmp(v,correct) != 0)) { \
9447 printf("(%s) Incorrect value %s=%s - should be %s\n", \
9448 __location__, #v, v, correct); \
9449 return; \
9450 } \
9451 } while (0)
9452
9453 static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_socket *nbtsock,
/* [<][>][^][v][top][bottom][index][help] */
9454 struct nbt_name_packet *req_packet,
9455 struct socket_address *src)
9456 {
9457 struct nbt_name *name;
9458 struct nbt_name_packet *rep_packet;
9459 struct test_conflict_owned_active_vs_replica_struct *rec =
9460 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9461
9462 _NBT_ASSERT(req_packet->qdcount, 1);
9463 _NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
9464 _NBT_ASSERT(req_packet->questions[0].question_class, NBT_QCLASS_IP);
9465
9466 name = &req_packet->questions[0].name;
9467
9468 _NBT_ASSERT(name->type, rec->name.type);
9469 _NBT_ASSERT_STRING(name->name, rec->name.name);
9470 _NBT_ASSERT_STRING(name->scope, rec->name.scope);
9471
9472 _NBT_ASSERT(rec->defend.expect_release, false);
9473
9474 rep_packet = talloc_zero(nbtsock, struct nbt_name_packet);
9475 if (rep_packet == NULL) return;
9476
9477 rep_packet->name_trn_id = req_packet->name_trn_id;
9478 rep_packet->ancount = 1;
9479
9480 rep_packet->answers = talloc_array(rep_packet, struct nbt_res_rec, 1);
9481 if (rep_packet->answers == NULL) return;
9482
9483 rep_packet->answers[0].name = *name;
9484 rep_packet->answers[0].rr_class = NBT_QCLASS_IP;
9485 rep_packet->answers[0].ttl = 0;
9486
9487 if (rec->defend.positive) {
9488 uint32_t i, num_ips;
9489 const struct wrepl_ip *ips;
9490
9491 if (rec->defend.num_ips > 0) {
9492 num_ips = rec->defend.num_ips;
9493 ips = rec->defend.ips;
9494 } else {
9495 num_ips = rec->wins.num_ips;
9496 ips = rec->wins.ips;
9497 }
9498
9499 /* send a positive reply */
9500 rep_packet->operation =
9501 NBT_FLAG_REPLY |
9502 NBT_OPCODE_QUERY |
9503 NBT_FLAG_AUTHORITIVE |
9504 NBT_FLAG_RECURSION_DESIRED |
9505 NBT_FLAG_RECURSION_AVAIL;
9506
9507 rep_packet->answers[0].rr_type = NBT_QTYPE_NETBIOS;
9508
9509 rep_packet->answers[0].rdata.netbios.length = num_ips*6;
9510 rep_packet->answers[0].rdata.netbios.addresses =
9511 talloc_array(rep_packet->answers, struct nbt_rdata_address, num_ips);
9512 if (rep_packet->answers[0].rdata.netbios.addresses == NULL) return;
9513
9514 for (i=0; i < num_ips; i++) {
9515 struct nbt_rdata_address *addr =
9516 &rep_packet->answers[0].rdata.netbios.addresses[i];
9517 addr->nb_flags = rec->wins.nb_flags;
9518 addr->ipaddr = ips[i].ip;
9519 }
9520 DEBUG(2,("Sending positive name query reply for %s to %s:%d\n",
9521 nbt_name_string(rep_packet, name), src->addr, src->port));
9522 } else {
9523 /* send a negative reply */
9524 rep_packet->operation =
9525 NBT_FLAG_REPLY |
9526 NBT_OPCODE_QUERY |
9527 NBT_FLAG_AUTHORITIVE |
9528 NBT_RCODE_NAM;
9529
9530 rep_packet->answers[0].rr_type = NBT_QTYPE_NULL;
9531
9532 ZERO_STRUCT(rep_packet->answers[0].rdata);
9533
9534 DEBUG(2,("Sending negative name query reply for %s to %s:%d\n",
9535 nbt_name_string(rep_packet, name), src->addr, src->port));
9536 }
9537
9538 nbt_name_reply_send(nbtsock, src, rep_packet);
9539 talloc_free(rep_packet);
9540
9541 /* make sure we push the reply to the wire */
9542 while (nbtsock->send_queue) {
9543 event_loop_once(nbtsock->event_ctx);
9544 }
9545 msleep(1000);
9546
9547 rec->defend.timeout = 0;
9548 rec->defend.ret = true;
9549 }
9550
9551 static void test_conflict_owned_active_vs_replica_handler_release(
/* [<][>][^][v][top][bottom][index][help] */
9552 struct nbt_name_socket *nbtsock,
9553 struct nbt_name_packet *req_packet,
9554 struct socket_address *src)
9555 {
9556 struct nbt_name *name;
9557 struct nbt_name_packet *rep_packet;
9558 struct test_conflict_owned_active_vs_replica_struct *rec =
9559 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9560
9561 _NBT_ASSERT(req_packet->qdcount, 1);
9562 _NBT_ASSERT(req_packet->questions[0].question_type, NBT_QTYPE_NETBIOS);
9563 _NBT_ASSERT(req_packet->questions[0].question_class, NBT_QCLASS_IP);
9564
9565 name = &req_packet->questions[0].name;
9566
9567 _NBT_ASSERT(name->type, rec->name.type);
9568 _NBT_ASSERT_STRING(name->name, rec->name.name);
9569 _NBT_ASSERT_STRING(name->scope, rec->name.scope);
9570
9571 _NBT_ASSERT(rec->defend.expect_release, true);
9572
9573 rep_packet = talloc_zero(nbtsock, struct nbt_name_packet);
9574 if (rep_packet == NULL) return;
9575
9576 rep_packet->name_trn_id = req_packet->name_trn_id;
9577 rep_packet->ancount = 1;
9578 rep_packet->operation =
9579 NBT_FLAG_REPLY |
9580 NBT_OPCODE_RELEASE |
9581 NBT_FLAG_AUTHORITIVE;
9582
9583 rep_packet->answers = talloc_array(rep_packet, struct nbt_res_rec, 1);
9584 if (rep_packet->answers == NULL) return;
9585
9586 rep_packet->answers[0].name = *name;
9587 rep_packet->answers[0].rr_type = NBT_QTYPE_NETBIOS;
9588 rep_packet->answers[0].rr_class = NBT_QCLASS_IP;
9589 rep_packet->answers[0].ttl = req_packet->additional[0].ttl;
9590 rep_packet->answers[0].rdata = req_packet->additional[0].rdata;
9591
9592 DEBUG(2,("Sending name release reply for %s to %s:%d\n",
9593 nbt_name_string(rep_packet, name), src->addr, src->port));
9594
9595 nbt_name_reply_send(nbtsock, src, rep_packet);
9596 talloc_free(rep_packet);
9597
9598 /* make sure we push the reply to the wire */
9599 while (nbtsock->send_queue) {
9600 event_loop_once(nbtsock->event_ctx);
9601 }
9602 msleep(1000);
9603
9604 rec->defend.timeout = 0;
9605 rec->defend.ret = true;
9606 }
9607
9608 static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock,
/* [<][>][^][v][top][bottom][index][help] */
9609 struct nbt_name_packet *req_packet,
9610 struct socket_address *src)
9611 {
9612 struct test_conflict_owned_active_vs_replica_struct *rec =
9613 (struct test_conflict_owned_active_vs_replica_struct *)nbtsock->incoming.private_data;
9614
9615 rec->defend.ret = false;
9616
9617 switch (req_packet->operation & NBT_OPCODE) {
9618 case NBT_OPCODE_QUERY:
9619 test_conflict_owned_active_vs_replica_handler_query(nbtsock, req_packet, src);
9620 break;
9621 case NBT_OPCODE_RELEASE:
9622 test_conflict_owned_active_vs_replica_handler_release(nbtsock, req_packet, src);
9623 break;
9624 default:
9625 printf("%s: unexpected incoming packet\n", __location__);
9626 return;
9627 }
9628 }
9629
9630 /*
9631 test WINS replication replica conflicts operations
9632 */
9633 static bool torture_nbt_winsreplication_replica(struct torture_context *tctx)
/* [<][>][^][v][top][bottom][index][help] */
9634 {
9635 bool ret = true;
9636 struct test_wrepl_conflict_conn *ctx;
9637
9638 const char *address;
9639 struct nbt_name name;
9640
9641 if (!torture_nbt_get_name(tctx, &name, &address))
9642 return false;
9643
9644 ctx = test_create_conflict_ctx(tctx, address);
9645 if (!ctx) return false;
9646
9647 ret &= test_conflict_same_owner(tctx, ctx);
9648 ret &= test_conflict_different_owner(tctx, ctx);
9649
9650 return ret;
9651 }
9652
9653 /*
9654 test WINS replication owned conflicts operations
9655 */
9656 static bool torture_nbt_winsreplication_owned(struct torture_context *tctx)
/* [<][>][^][v][top][bottom][index][help] */
9657 {
9658 const char *address;
9659 struct nbt_name name;
9660 bool ret = true;
9661 struct test_wrepl_conflict_conn *ctx;
9662
9663 if (torture_setting_bool(tctx, "quick", false))
9664 torture_skip(tctx,
9665 "skip NBT-WINSREPLICATION-OWNED test in quick test mode\n");
9666
9667 if (!torture_nbt_get_name(tctx, &name, &address))
9668 return false;
9669
9670 ctx = test_create_conflict_ctx(tctx, address);
9671 torture_assert(tctx, ctx != NULL, "Creating context failed");
9672
9673 ret &= test_conflict_owned_released_vs_replica(tctx, ctx);
9674 ret &= test_conflict_owned_active_vs_replica(tctx, ctx);
9675
9676 return ret;
9677 }
9678
9679 /*
9680 test simple WINS replication operations
9681 */
9682 struct torture_suite *torture_nbt_winsreplication(TALLOC_CTX *mem_ctx)
/* [<][>][^][v][top][bottom][index][help] */
9683 {
9684 struct torture_suite *suite = torture_suite_create(
9685 mem_ctx, "WINSREPLICATION");
9686 struct torture_tcase *tcase;
9687
9688 tcase = torture_suite_add_simple_test(suite, "assoc_ctx1",
9689 test_assoc_ctx1);
9690 tcase->tests->dangerous = true;
9691
9692 torture_suite_add_simple_test(suite, "assoc_ctx2",
9693 test_assoc_ctx2);
9694
9695 torture_suite_add_simple_test(suite, "wins_replication",
9696 test_wins_replication);
9697
9698 torture_suite_add_simple_test(suite, "replica",
9699 torture_nbt_winsreplication_replica);
9700
9701 torture_suite_add_simple_test(suite, "owned",
9702 torture_nbt_winsreplication_owned);
9703
9704 return suite;
9705 }