source: trunk/server/source4/torture/nbt/winsreplication.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

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