Browse code

daemon: report IPAM status for Swarm networks

As the Engine API requests may be directed at a non-leader Swarm
manager, the information needs to be tunneled through the Swarm API.

Signed-off-by: Cory Snider <csnider@mirantis.com>

Cory Snider authored on 2025/09/10 00:47:52
Showing 31 changed files
... ...
@@ -21,7 +21,7 @@ type ClusterStatus interface {
21 21
 
22 22
 // NetworkManager provides methods to manage networks
23 23
 type NetworkManager interface {
24
-	GetNetwork(input string) (network.Inspect, error)
25
-	GetNetworks(dnetwork.Filter) ([]network.Inspect, error)
24
+	GetNetwork(input string, withStatus bool) (network.Inspect, error)
25
+	GetNetworks(filter dnetwork.Filter, withStatus bool) ([]network.Inspect, error)
26 26
 	RemoveNetwork(input string) error
27 27
 }
28 28
new file mode 100644
... ...
@@ -0,0 +1,733 @@
0
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
1
+// source: extra.proto
2
+
3
+package netextra
4
+
5
+import (
6
+	fmt "fmt"
7
+	proto "github.com/gogo/protobuf/proto"
8
+	io "io"
9
+	math "math"
10
+	math_bits "math/bits"
11
+)
12
+
13
+// Reference imports to suppress errors if they are not otherwise used.
14
+var _ = proto.Marshal
15
+var _ = fmt.Errorf
16
+var _ = math.Inf
17
+
18
+// This is a compile-time assertion to ensure that this generated file
19
+// is compatible with the proto package it is being compiled against.
20
+// A compilation error at this line likely means your copy of the
21
+// proto package needs to be updated.
22
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
23
+
24
+type GetNetworkExtraOptions struct {
25
+	WithIPAMStatus bool `protobuf:"varint,1,opt,name=WithIPAMStatus,proto3" json:"WithIPAMStatus,omitempty"`
26
+}
27
+
28
+func (m *GetNetworkExtraOptions) Reset()         { *m = GetNetworkExtraOptions{} }
29
+func (m *GetNetworkExtraOptions) String() string { return proto.CompactTextString(m) }
30
+func (*GetNetworkExtraOptions) ProtoMessage()    {}
31
+func (*GetNetworkExtraOptions) Descriptor() ([]byte, []int) {
32
+	return fileDescriptor_b57530d56b910c1d, []int{0}
33
+}
34
+func (m *GetNetworkExtraOptions) XXX_Unmarshal(b []byte) error {
35
+	return m.Unmarshal(b)
36
+}
37
+func (m *GetNetworkExtraOptions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
38
+	if deterministic {
39
+		return xxx_messageInfo_GetNetworkExtraOptions.Marshal(b, m, deterministic)
40
+	} else {
41
+		b = b[:cap(b)]
42
+		n, err := m.MarshalToSizedBuffer(b)
43
+		if err != nil {
44
+			return nil, err
45
+		}
46
+		return b[:n], nil
47
+	}
48
+}
49
+func (m *GetNetworkExtraOptions) XXX_Merge(src proto.Message) {
50
+	xxx_messageInfo_GetNetworkExtraOptions.Merge(m, src)
51
+}
52
+func (m *GetNetworkExtraOptions) XXX_Size() int {
53
+	return m.Size()
54
+}
55
+func (m *GetNetworkExtraOptions) XXX_DiscardUnknown() {
56
+	xxx_messageInfo_GetNetworkExtraOptions.DiscardUnknown(m)
57
+}
58
+
59
+var xxx_messageInfo_GetNetworkExtraOptions proto.InternalMessageInfo
60
+
61
+func (m *GetNetworkExtraOptions) GetWithIPAMStatus() bool {
62
+	if m != nil {
63
+		return m.WithIPAMStatus
64
+	}
65
+	return false
66
+}
67
+
68
+type Extra struct {
69
+	IPAMStatus []*IPAMStatus `protobuf:"bytes,1,rep,name=IPAMStatus,proto3" json:"IPAMStatus,omitempty"`
70
+}
71
+
72
+func (m *Extra) Reset()         { *m = Extra{} }
73
+func (m *Extra) String() string { return proto.CompactTextString(m) }
74
+func (*Extra) ProtoMessage()    {}
75
+func (*Extra) Descriptor() ([]byte, []int) {
76
+	return fileDescriptor_b57530d56b910c1d, []int{1}
77
+}
78
+func (m *Extra) XXX_Unmarshal(b []byte) error {
79
+	return m.Unmarshal(b)
80
+}
81
+func (m *Extra) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
82
+	if deterministic {
83
+		return xxx_messageInfo_Extra.Marshal(b, m, deterministic)
84
+	} else {
85
+		b = b[:cap(b)]
86
+		n, err := m.MarshalToSizedBuffer(b)
87
+		if err != nil {
88
+			return nil, err
89
+		}
90
+		return b[:n], nil
91
+	}
92
+}
93
+func (m *Extra) XXX_Merge(src proto.Message) {
94
+	xxx_messageInfo_Extra.Merge(m, src)
95
+}
96
+func (m *Extra) XXX_Size() int {
97
+	return m.Size()
98
+}
99
+func (m *Extra) XXX_DiscardUnknown() {
100
+	xxx_messageInfo_Extra.DiscardUnknown(m)
101
+}
102
+
103
+var xxx_messageInfo_Extra proto.InternalMessageInfo
104
+
105
+func (m *Extra) GetIPAMStatus() []*IPAMStatus {
106
+	if m != nil {
107
+		return m.IPAMStatus
108
+	}
109
+	return nil
110
+}
111
+
112
+type IPAMStatus struct {
113
+	Subnet              []byte `protobuf:"bytes,1,opt,name=Subnet,proto3" json:"Subnet,omitempty"`
114
+	IPsInUse            uint64 `protobuf:"varint,2,opt,name=IPsInUse,proto3" json:"IPsInUse,omitempty"`
115
+	DynamicIPsAvailable uint64 `protobuf:"varint,3,opt,name=DynamicIPsAvailable,proto3" json:"DynamicIPsAvailable,omitempty"`
116
+}
117
+
118
+func (m *IPAMStatus) Reset()         { *m = IPAMStatus{} }
119
+func (m *IPAMStatus) String() string { return proto.CompactTextString(m) }
120
+func (*IPAMStatus) ProtoMessage()    {}
121
+func (*IPAMStatus) Descriptor() ([]byte, []int) {
122
+	return fileDescriptor_b57530d56b910c1d, []int{2}
123
+}
124
+func (m *IPAMStatus) XXX_Unmarshal(b []byte) error {
125
+	return m.Unmarshal(b)
126
+}
127
+func (m *IPAMStatus) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
128
+	if deterministic {
129
+		return xxx_messageInfo_IPAMStatus.Marshal(b, m, deterministic)
130
+	} else {
131
+		b = b[:cap(b)]
132
+		n, err := m.MarshalToSizedBuffer(b)
133
+		if err != nil {
134
+			return nil, err
135
+		}
136
+		return b[:n], nil
137
+	}
138
+}
139
+func (m *IPAMStatus) XXX_Merge(src proto.Message) {
140
+	xxx_messageInfo_IPAMStatus.Merge(m, src)
141
+}
142
+func (m *IPAMStatus) XXX_Size() int {
143
+	return m.Size()
144
+}
145
+func (m *IPAMStatus) XXX_DiscardUnknown() {
146
+	xxx_messageInfo_IPAMStatus.DiscardUnknown(m)
147
+}
148
+
149
+var xxx_messageInfo_IPAMStatus proto.InternalMessageInfo
150
+
151
+func (m *IPAMStatus) GetSubnet() []byte {
152
+	if m != nil {
153
+		return m.Subnet
154
+	}
155
+	return nil
156
+}
157
+
158
+func (m *IPAMStatus) GetIPsInUse() uint64 {
159
+	if m != nil {
160
+		return m.IPsInUse
161
+	}
162
+	return 0
163
+}
164
+
165
+func (m *IPAMStatus) GetDynamicIPsAvailable() uint64 {
166
+	if m != nil {
167
+		return m.DynamicIPsAvailable
168
+	}
169
+	return 0
170
+}
171
+
172
+func init() {
173
+	proto.RegisterType((*GetNetworkExtraOptions)(nil), "docker.engine.netextra.GetNetworkExtraOptions")
174
+	proto.RegisterType((*Extra)(nil), "docker.engine.netextra.Extra")
175
+	proto.RegisterType((*IPAMStatus)(nil), "docker.engine.netextra.IPAMStatus")
176
+}
177
+
178
+func init() { proto.RegisterFile("extra.proto", fileDescriptor_b57530d56b910c1d) }
179
+
180
+var fileDescriptor_b57530d56b910c1d = []byte{
181
+	// 243 bytes of a gzipped FileDescriptorProto
182
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4e, 0xad, 0x28, 0x29,
183
+	0x4a, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x4b, 0xc9, 0x4f, 0xce, 0x4e, 0x2d, 0xd2,
184
+	0x4b, 0xcd, 0x4b, 0xcf, 0xcc, 0x4b, 0xd5, 0xcb, 0x4b, 0x2d, 0x01, 0xcb, 0x2a, 0x39, 0x70, 0x89,
185
+	0xb9, 0xa7, 0x96, 0xf8, 0xa5, 0x96, 0x94, 0xe7, 0x17, 0x65, 0xbb, 0x82, 0x84, 0xfc, 0x0b, 0x4a,
186
+	0x32, 0xf3, 0xf3, 0x8a, 0x85, 0xd4, 0xb8, 0xf8, 0xc2, 0x33, 0x4b, 0x32, 0x3c, 0x03, 0x1c, 0x7d,
187
+	0x83, 0x4b, 0x12, 0x4b, 0x4a, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x82, 0xd0, 0x44, 0x95,
188
+	0xbc, 0xb9, 0x58, 0xc1, 0xfa, 0x84, 0x9c, 0xb8, 0xb8, 0x50, 0x14, 0x33, 0x6b, 0x70, 0x1b, 0x29,
189
+	0xe9, 0x61, 0xb7, 0x57, 0x0f, 0xa1, 0x32, 0x08, 0x49, 0x97, 0x52, 0x11, 0xb2, 0x19, 0x42, 0x62,
190
+	0x5c, 0x6c, 0xc1, 0xa5, 0x49, 0x79, 0xa9, 0x25, 0x60, 0xab, 0x79, 0x82, 0xa0, 0x3c, 0x21, 0x29,
191
+	0x2e, 0x0e, 0xcf, 0x80, 0x62, 0xcf, 0xbc, 0xd0, 0xe2, 0x54, 0x09, 0x26, 0x05, 0x46, 0x0d, 0x96,
192
+	0x20, 0x38, 0x5f, 0xc8, 0x80, 0x4b, 0xd8, 0xa5, 0x32, 0x2f, 0x31, 0x37, 0x33, 0xd9, 0x33, 0xa0,
193
+	0xd8, 0xb1, 0x2c, 0x31, 0x33, 0x27, 0x31, 0x29, 0x27, 0x55, 0x82, 0x19, 0xac, 0x0c, 0x9b, 0x94,
194
+	0x93, 0xd2, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1,
195
+	0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x71, 0xc0, 0x9c, 0x9b,
196
+	0xc4, 0x06, 0x0e, 0x45, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x87, 0x0a, 0xcc, 0xc8, 0x54,
197
+	0x01, 0x00, 0x00,
198
+}
199
+
200
+func (m *GetNetworkExtraOptions) Marshal() (dAtA []byte, err error) {
201
+	size := m.Size()
202
+	dAtA = make([]byte, size)
203
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
204
+	if err != nil {
205
+		return nil, err
206
+	}
207
+	return dAtA[:n], nil
208
+}
209
+
210
+func (m *GetNetworkExtraOptions) MarshalTo(dAtA []byte) (int, error) {
211
+	size := m.Size()
212
+	return m.MarshalToSizedBuffer(dAtA[:size])
213
+}
214
+
215
+func (m *GetNetworkExtraOptions) MarshalToSizedBuffer(dAtA []byte) (int, error) {
216
+	i := len(dAtA)
217
+	_ = i
218
+	var l int
219
+	_ = l
220
+	if m.WithIPAMStatus {
221
+		i--
222
+		if m.WithIPAMStatus {
223
+			dAtA[i] = 1
224
+		} else {
225
+			dAtA[i] = 0
226
+		}
227
+		i--
228
+		dAtA[i] = 0x8
229
+	}
230
+	return len(dAtA) - i, nil
231
+}
232
+
233
+func (m *Extra) Marshal() (dAtA []byte, err error) {
234
+	size := m.Size()
235
+	dAtA = make([]byte, size)
236
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
237
+	if err != nil {
238
+		return nil, err
239
+	}
240
+	return dAtA[:n], nil
241
+}
242
+
243
+func (m *Extra) MarshalTo(dAtA []byte) (int, error) {
244
+	size := m.Size()
245
+	return m.MarshalToSizedBuffer(dAtA[:size])
246
+}
247
+
248
+func (m *Extra) MarshalToSizedBuffer(dAtA []byte) (int, error) {
249
+	i := len(dAtA)
250
+	_ = i
251
+	var l int
252
+	_ = l
253
+	if len(m.IPAMStatus) > 0 {
254
+		for iNdEx := len(m.IPAMStatus) - 1; iNdEx >= 0; iNdEx-- {
255
+			{
256
+				size, err := m.IPAMStatus[iNdEx].MarshalToSizedBuffer(dAtA[:i])
257
+				if err != nil {
258
+					return 0, err
259
+				}
260
+				i -= size
261
+				i = encodeVarintExtra(dAtA, i, uint64(size))
262
+			}
263
+			i--
264
+			dAtA[i] = 0xa
265
+		}
266
+	}
267
+	return len(dAtA) - i, nil
268
+}
269
+
270
+func (m *IPAMStatus) Marshal() (dAtA []byte, err error) {
271
+	size := m.Size()
272
+	dAtA = make([]byte, size)
273
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
274
+	if err != nil {
275
+		return nil, err
276
+	}
277
+	return dAtA[:n], nil
278
+}
279
+
280
+func (m *IPAMStatus) MarshalTo(dAtA []byte) (int, error) {
281
+	size := m.Size()
282
+	return m.MarshalToSizedBuffer(dAtA[:size])
283
+}
284
+
285
+func (m *IPAMStatus) MarshalToSizedBuffer(dAtA []byte) (int, error) {
286
+	i := len(dAtA)
287
+	_ = i
288
+	var l int
289
+	_ = l
290
+	if m.DynamicIPsAvailable != 0 {
291
+		i = encodeVarintExtra(dAtA, i, uint64(m.DynamicIPsAvailable))
292
+		i--
293
+		dAtA[i] = 0x18
294
+	}
295
+	if m.IPsInUse != 0 {
296
+		i = encodeVarintExtra(dAtA, i, uint64(m.IPsInUse))
297
+		i--
298
+		dAtA[i] = 0x10
299
+	}
300
+	if len(m.Subnet) > 0 {
301
+		i -= len(m.Subnet)
302
+		copy(dAtA[i:], m.Subnet)
303
+		i = encodeVarintExtra(dAtA, i, uint64(len(m.Subnet)))
304
+		i--
305
+		dAtA[i] = 0xa
306
+	}
307
+	return len(dAtA) - i, nil
308
+}
309
+
310
+func encodeVarintExtra(dAtA []byte, offset int, v uint64) int {
311
+	offset -= sovExtra(v)
312
+	base := offset
313
+	for v >= 1<<7 {
314
+		dAtA[offset] = uint8(v&0x7f | 0x80)
315
+		v >>= 7
316
+		offset++
317
+	}
318
+	dAtA[offset] = uint8(v)
319
+	return base
320
+}
321
+func (m *GetNetworkExtraOptions) Size() (n int) {
322
+	if m == nil {
323
+		return 0
324
+	}
325
+	var l int
326
+	_ = l
327
+	if m.WithIPAMStatus {
328
+		n += 2
329
+	}
330
+	return n
331
+}
332
+
333
+func (m *Extra) Size() (n int) {
334
+	if m == nil {
335
+		return 0
336
+	}
337
+	var l int
338
+	_ = l
339
+	if len(m.IPAMStatus) > 0 {
340
+		for _, e := range m.IPAMStatus {
341
+			l = e.Size()
342
+			n += 1 + l + sovExtra(uint64(l))
343
+		}
344
+	}
345
+	return n
346
+}
347
+
348
+func (m *IPAMStatus) Size() (n int) {
349
+	if m == nil {
350
+		return 0
351
+	}
352
+	var l int
353
+	_ = l
354
+	l = len(m.Subnet)
355
+	if l > 0 {
356
+		n += 1 + l + sovExtra(uint64(l))
357
+	}
358
+	if m.IPsInUse != 0 {
359
+		n += 1 + sovExtra(uint64(m.IPsInUse))
360
+	}
361
+	if m.DynamicIPsAvailable != 0 {
362
+		n += 1 + sovExtra(uint64(m.DynamicIPsAvailable))
363
+	}
364
+	return n
365
+}
366
+
367
+func sovExtra(x uint64) (n int) {
368
+	return (math_bits.Len64(x|1) + 6) / 7
369
+}
370
+func sozExtra(x uint64) (n int) {
371
+	return sovExtra(uint64((x << 1) ^ uint64((int64(x) >> 63))))
372
+}
373
+func (m *GetNetworkExtraOptions) Unmarshal(dAtA []byte) error {
374
+	l := len(dAtA)
375
+	iNdEx := 0
376
+	for iNdEx < l {
377
+		preIndex := iNdEx
378
+		var wire uint64
379
+		for shift := uint(0); ; shift += 7 {
380
+			if shift >= 64 {
381
+				return ErrIntOverflowExtra
382
+			}
383
+			if iNdEx >= l {
384
+				return io.ErrUnexpectedEOF
385
+			}
386
+			b := dAtA[iNdEx]
387
+			iNdEx++
388
+			wire |= uint64(b&0x7F) << shift
389
+			if b < 0x80 {
390
+				break
391
+			}
392
+		}
393
+		fieldNum := int32(wire >> 3)
394
+		wireType := int(wire & 0x7)
395
+		if wireType == 4 {
396
+			return fmt.Errorf("proto: GetNetworkExtraOptions: wiretype end group for non-group")
397
+		}
398
+		if fieldNum <= 0 {
399
+			return fmt.Errorf("proto: GetNetworkExtraOptions: illegal tag %d (wire type %d)", fieldNum, wire)
400
+		}
401
+		switch fieldNum {
402
+		case 1:
403
+			if wireType != 0 {
404
+				return fmt.Errorf("proto: wrong wireType = %d for field WithIPAMStatus", wireType)
405
+			}
406
+			var v int
407
+			for shift := uint(0); ; shift += 7 {
408
+				if shift >= 64 {
409
+					return ErrIntOverflowExtra
410
+				}
411
+				if iNdEx >= l {
412
+					return io.ErrUnexpectedEOF
413
+				}
414
+				b := dAtA[iNdEx]
415
+				iNdEx++
416
+				v |= int(b&0x7F) << shift
417
+				if b < 0x80 {
418
+					break
419
+				}
420
+			}
421
+			m.WithIPAMStatus = bool(v != 0)
422
+		default:
423
+			iNdEx = preIndex
424
+			skippy, err := skipExtra(dAtA[iNdEx:])
425
+			if err != nil {
426
+				return err
427
+			}
428
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
429
+				return ErrInvalidLengthExtra
430
+			}
431
+			if (iNdEx + skippy) > l {
432
+				return io.ErrUnexpectedEOF
433
+			}
434
+			iNdEx += skippy
435
+		}
436
+	}
437
+
438
+	if iNdEx > l {
439
+		return io.ErrUnexpectedEOF
440
+	}
441
+	return nil
442
+}
443
+func (m *Extra) Unmarshal(dAtA []byte) error {
444
+	l := len(dAtA)
445
+	iNdEx := 0
446
+	for iNdEx < l {
447
+		preIndex := iNdEx
448
+		var wire uint64
449
+		for shift := uint(0); ; shift += 7 {
450
+			if shift >= 64 {
451
+				return ErrIntOverflowExtra
452
+			}
453
+			if iNdEx >= l {
454
+				return io.ErrUnexpectedEOF
455
+			}
456
+			b := dAtA[iNdEx]
457
+			iNdEx++
458
+			wire |= uint64(b&0x7F) << shift
459
+			if b < 0x80 {
460
+				break
461
+			}
462
+		}
463
+		fieldNum := int32(wire >> 3)
464
+		wireType := int(wire & 0x7)
465
+		if wireType == 4 {
466
+			return fmt.Errorf("proto: Extra: wiretype end group for non-group")
467
+		}
468
+		if fieldNum <= 0 {
469
+			return fmt.Errorf("proto: Extra: illegal tag %d (wire type %d)", fieldNum, wire)
470
+		}
471
+		switch fieldNum {
472
+		case 1:
473
+			if wireType != 2 {
474
+				return fmt.Errorf("proto: wrong wireType = %d for field IPAMStatus", wireType)
475
+			}
476
+			var msglen int
477
+			for shift := uint(0); ; shift += 7 {
478
+				if shift >= 64 {
479
+					return ErrIntOverflowExtra
480
+				}
481
+				if iNdEx >= l {
482
+					return io.ErrUnexpectedEOF
483
+				}
484
+				b := dAtA[iNdEx]
485
+				iNdEx++
486
+				msglen |= int(b&0x7F) << shift
487
+				if b < 0x80 {
488
+					break
489
+				}
490
+			}
491
+			if msglen < 0 {
492
+				return ErrInvalidLengthExtra
493
+			}
494
+			postIndex := iNdEx + msglen
495
+			if postIndex < 0 {
496
+				return ErrInvalidLengthExtra
497
+			}
498
+			if postIndex > l {
499
+				return io.ErrUnexpectedEOF
500
+			}
501
+			m.IPAMStatus = append(m.IPAMStatus, &IPAMStatus{})
502
+			if err := m.IPAMStatus[len(m.IPAMStatus)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
503
+				return err
504
+			}
505
+			iNdEx = postIndex
506
+		default:
507
+			iNdEx = preIndex
508
+			skippy, err := skipExtra(dAtA[iNdEx:])
509
+			if err != nil {
510
+				return err
511
+			}
512
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
513
+				return ErrInvalidLengthExtra
514
+			}
515
+			if (iNdEx + skippy) > l {
516
+				return io.ErrUnexpectedEOF
517
+			}
518
+			iNdEx += skippy
519
+		}
520
+	}
521
+
522
+	if iNdEx > l {
523
+		return io.ErrUnexpectedEOF
524
+	}
525
+	return nil
526
+}
527
+func (m *IPAMStatus) Unmarshal(dAtA []byte) error {
528
+	l := len(dAtA)
529
+	iNdEx := 0
530
+	for iNdEx < l {
531
+		preIndex := iNdEx
532
+		var wire uint64
533
+		for shift := uint(0); ; shift += 7 {
534
+			if shift >= 64 {
535
+				return ErrIntOverflowExtra
536
+			}
537
+			if iNdEx >= l {
538
+				return io.ErrUnexpectedEOF
539
+			}
540
+			b := dAtA[iNdEx]
541
+			iNdEx++
542
+			wire |= uint64(b&0x7F) << shift
543
+			if b < 0x80 {
544
+				break
545
+			}
546
+		}
547
+		fieldNum := int32(wire >> 3)
548
+		wireType := int(wire & 0x7)
549
+		if wireType == 4 {
550
+			return fmt.Errorf("proto: IPAMStatus: wiretype end group for non-group")
551
+		}
552
+		if fieldNum <= 0 {
553
+			return fmt.Errorf("proto: IPAMStatus: illegal tag %d (wire type %d)", fieldNum, wire)
554
+		}
555
+		switch fieldNum {
556
+		case 1:
557
+			if wireType != 2 {
558
+				return fmt.Errorf("proto: wrong wireType = %d for field Subnet", wireType)
559
+			}
560
+			var byteLen int
561
+			for shift := uint(0); ; shift += 7 {
562
+				if shift >= 64 {
563
+					return ErrIntOverflowExtra
564
+				}
565
+				if iNdEx >= l {
566
+					return io.ErrUnexpectedEOF
567
+				}
568
+				b := dAtA[iNdEx]
569
+				iNdEx++
570
+				byteLen |= int(b&0x7F) << shift
571
+				if b < 0x80 {
572
+					break
573
+				}
574
+			}
575
+			if byteLen < 0 {
576
+				return ErrInvalidLengthExtra
577
+			}
578
+			postIndex := iNdEx + byteLen
579
+			if postIndex < 0 {
580
+				return ErrInvalidLengthExtra
581
+			}
582
+			if postIndex > l {
583
+				return io.ErrUnexpectedEOF
584
+			}
585
+			m.Subnet = append(m.Subnet[:0], dAtA[iNdEx:postIndex]...)
586
+			if m.Subnet == nil {
587
+				m.Subnet = []byte{}
588
+			}
589
+			iNdEx = postIndex
590
+		case 2:
591
+			if wireType != 0 {
592
+				return fmt.Errorf("proto: wrong wireType = %d for field IPsInUse", wireType)
593
+			}
594
+			m.IPsInUse = 0
595
+			for shift := uint(0); ; shift += 7 {
596
+				if shift >= 64 {
597
+					return ErrIntOverflowExtra
598
+				}
599
+				if iNdEx >= l {
600
+					return io.ErrUnexpectedEOF
601
+				}
602
+				b := dAtA[iNdEx]
603
+				iNdEx++
604
+				m.IPsInUse |= uint64(b&0x7F) << shift
605
+				if b < 0x80 {
606
+					break
607
+				}
608
+			}
609
+		case 3:
610
+			if wireType != 0 {
611
+				return fmt.Errorf("proto: wrong wireType = %d for field DynamicIPsAvailable", wireType)
612
+			}
613
+			m.DynamicIPsAvailable = 0
614
+			for shift := uint(0); ; shift += 7 {
615
+				if shift >= 64 {
616
+					return ErrIntOverflowExtra
617
+				}
618
+				if iNdEx >= l {
619
+					return io.ErrUnexpectedEOF
620
+				}
621
+				b := dAtA[iNdEx]
622
+				iNdEx++
623
+				m.DynamicIPsAvailable |= uint64(b&0x7F) << shift
624
+				if b < 0x80 {
625
+					break
626
+				}
627
+			}
628
+		default:
629
+			iNdEx = preIndex
630
+			skippy, err := skipExtra(dAtA[iNdEx:])
631
+			if err != nil {
632
+				return err
633
+			}
634
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
635
+				return ErrInvalidLengthExtra
636
+			}
637
+			if (iNdEx + skippy) > l {
638
+				return io.ErrUnexpectedEOF
639
+			}
640
+			iNdEx += skippy
641
+		}
642
+	}
643
+
644
+	if iNdEx > l {
645
+		return io.ErrUnexpectedEOF
646
+	}
647
+	return nil
648
+}
649
+func skipExtra(dAtA []byte) (n int, err error) {
650
+	l := len(dAtA)
651
+	iNdEx := 0
652
+	depth := 0
653
+	for iNdEx < l {
654
+		var wire uint64
655
+		for shift := uint(0); ; shift += 7 {
656
+			if shift >= 64 {
657
+				return 0, ErrIntOverflowExtra
658
+			}
659
+			if iNdEx >= l {
660
+				return 0, io.ErrUnexpectedEOF
661
+			}
662
+			b := dAtA[iNdEx]
663
+			iNdEx++
664
+			wire |= (uint64(b) & 0x7F) << shift
665
+			if b < 0x80 {
666
+				break
667
+			}
668
+		}
669
+		wireType := int(wire & 0x7)
670
+		switch wireType {
671
+		case 0:
672
+			for shift := uint(0); ; shift += 7 {
673
+				if shift >= 64 {
674
+					return 0, ErrIntOverflowExtra
675
+				}
676
+				if iNdEx >= l {
677
+					return 0, io.ErrUnexpectedEOF
678
+				}
679
+				iNdEx++
680
+				if dAtA[iNdEx-1] < 0x80 {
681
+					break
682
+				}
683
+			}
684
+		case 1:
685
+			iNdEx += 8
686
+		case 2:
687
+			var length int
688
+			for shift := uint(0); ; shift += 7 {
689
+				if shift >= 64 {
690
+					return 0, ErrIntOverflowExtra
691
+				}
692
+				if iNdEx >= l {
693
+					return 0, io.ErrUnexpectedEOF
694
+				}
695
+				b := dAtA[iNdEx]
696
+				iNdEx++
697
+				length |= (int(b) & 0x7F) << shift
698
+				if b < 0x80 {
699
+					break
700
+				}
701
+			}
702
+			if length < 0 {
703
+				return 0, ErrInvalidLengthExtra
704
+			}
705
+			iNdEx += length
706
+		case 3:
707
+			depth++
708
+		case 4:
709
+			if depth == 0 {
710
+				return 0, ErrUnexpectedEndOfGroupExtra
711
+			}
712
+			depth--
713
+		case 5:
714
+			iNdEx += 4
715
+		default:
716
+			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
717
+		}
718
+		if iNdEx < 0 {
719
+			return 0, ErrInvalidLengthExtra
720
+		}
721
+		if depth == 0 {
722
+			return iNdEx, nil
723
+		}
724
+	}
725
+	return 0, io.ErrUnexpectedEOF
726
+}
727
+
728
+var (
729
+	ErrInvalidLengthExtra        = fmt.Errorf("proto: negative length found during unmarshaling")
730
+	ErrIntOverflowExtra          = fmt.Errorf("proto: integer overflow")
731
+	ErrUnexpectedEndOfGroupExtra = fmt.Errorf("proto: unexpected end of group")
732
+)
0 733
new file mode 100644
... ...
@@ -0,0 +1,19 @@
0
+syntax = "proto3";
1
+
2
+package docker.engine.netextra;
3
+
4
+option go_package = "netextra";
5
+
6
+message GetNetworkExtraOptions {
7
+	bool WithIPAMStatus = 1;
8
+}
9
+
10
+message Extra {
11
+	repeated IPAMStatus IPAMStatus = 1;
12
+}
13
+
14
+message IPAMStatus {
15
+	bytes Subnet = 1; // netip.Prefix marshaled to binary
16
+	uint64 IPsInUse = 2;
17
+	uint64 DynamicIPsAvailable = 3;
18
+}
0 19
new file mode 100644
... ...
@@ -0,0 +1,84 @@
0
+//go:generate protoc --gogofaster_out=. extra.proto
1
+
2
+package netextra
3
+
4
+import (
5
+	"net/netip"
6
+
7
+	"github.com/gogo/protobuf/types"
8
+	"github.com/moby/moby/api/types/network"
9
+)
10
+
11
+func OptionsFrom(typeurl string, value []byte) (GetNetworkExtraOptions, error) {
12
+	if typeurl == "" {
13
+		return GetNetworkExtraOptions{}, nil
14
+	}
15
+	appdata := &types.Any{TypeUrl: typeurl, Value: value}
16
+
17
+	var xo GetNetworkExtraOptions
18
+	if !types.Is(appdata, &xo) {
19
+		// Forward-compatibility: ignore unknown message types
20
+		return GetNetworkExtraOptions{}, nil
21
+	}
22
+	if err := types.UnmarshalAny(appdata, &xo); err != nil {
23
+		return GetNetworkExtraOptions{}, err
24
+	}
25
+	return xo, nil
26
+}
27
+
28
+func StatusFrom(extra *types.Any) (*network.Status, error) {
29
+	if extra == nil {
30
+		return nil, nil
31
+	}
32
+
33
+	var x Extra
34
+	if !types.Is(extra, &x) {
35
+		// Forward-compatibility: ignore unknown message types
36
+		return nil, nil
37
+	}
38
+	if err := types.UnmarshalAny(extra, &x); err != nil {
39
+		return nil, err
40
+	}
41
+
42
+	status := network.Status{
43
+		IPAM: network.IPAMStatus{
44
+			Subnets: make(map[netip.Prefix]network.SubnetStatus, len(x.IPAMStatus)),
45
+		},
46
+	}
47
+
48
+	for _, s := range x.IPAMStatus {
49
+		var pfx netip.Prefix
50
+		err := pfx.UnmarshalBinary(s.Subnet)
51
+		if err != nil {
52
+			return nil, err
53
+		}
54
+		status.IPAM.Subnets[pfx] = network.SubnetStatus{
55
+			IPsInUse:            s.IPsInUse,
56
+			DynamicIPsAvailable: s.DynamicIPsAvailable,
57
+		}
58
+	}
59
+
60
+	return &status, nil
61
+}
62
+
63
+func MarshalStatus(status *network.Status) (*types.Any, error) {
64
+	if status == nil {
65
+		return nil, nil
66
+	}
67
+
68
+	var ipam []*IPAMStatus
69
+	for subnet, s := range status.IPAM.Subnets {
70
+		bpfx, err := subnet.MarshalBinary()
71
+		if err != nil {
72
+			return nil, err
73
+		}
74
+		ipam = append(ipam, &IPAMStatus{
75
+			Subnet:              bpfx,
76
+			IPsInUse:            s.IPsInUse,
77
+			DynamicIPsAvailable: s.DynamicIPsAvailable,
78
+		})
79
+	}
80
+	return types.MarshalAny(&Extra{
81
+		IPAMStatus: ipam,
82
+	})
83
+}
... ...
@@ -7,6 +7,7 @@ import (
7 7
 	gogotypes "github.com/gogo/protobuf/types"
8 8
 	"github.com/moby/moby/api/types/network"
9 9
 	types "github.com/moby/moby/api/types/swarm"
10
+	"github.com/moby/moby/v2/daemon/cluster/convert/netextra"
10 11
 	"github.com/moby/moby/v2/daemon/libnetwork/scope"
11 12
 	swarmapi "github.com/moby/swarmkit/v2/api"
12 13
 )
... ...
@@ -185,6 +186,17 @@ func BasicNetworkFromGRPC(n swarmapi.Network) network.Network {
185 185
 	return nr
186 186
 }
187 187
 
188
+func NetworkInspectFromGRPC(n swarmapi.Network) (network.Inspect, error) {
189
+	ni := network.Inspect{
190
+		Network:    BasicNetworkFromGRPC(n),
191
+		Containers: make(map[string]network.EndpointResource),
192
+	}
193
+
194
+	var err error
195
+	ni.Status, err = netextra.StatusFrom(n.Extra)
196
+	return ni, err
197
+}
198
+
188 199
 // BasicNetworkCreateToGRPC converts a NetworkCreateRequest to a grpc NetworkSpec.
189 200
 func BasicNetworkCreateToGRPC(create network.CreateRequest) swarmapi.NetworkSpec {
190 201
 	ns := swarmapi.NetworkSpec{
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"context"
5 5
 	"fmt"
6 6
 
7
+	"github.com/gogo/protobuf/types"
7 8
 	"github.com/moby/moby/v2/errdefs"
8 9
 	swarmapi "github.com/moby/swarmkit/v2/api"
9 10
 	"github.com/pkg/errors"
... ...
@@ -211,9 +212,9 @@ func getConfig(ctx context.Context, c swarmapi.ControlClient, input string) (*sw
211 211
 	return rl.Configs[0], nil
212 212
 }
213 213
 
214
-func getNetwork(ctx context.Context, c swarmapi.ControlClient, input string) (*swarmapi.Network, error) {
214
+func getNetwork(ctx context.Context, c swarmapi.ControlClient, input string, appdata *types.Any) (*swarmapi.Network, error) {
215 215
 	// GetNetwork to match via full ID.
216
-	if rg, err := c.GetNetwork(ctx, &swarmapi.GetNetworkRequest{NetworkID: input}); err == nil {
216
+	if rg, err := c.GetNetwork(ctx, &swarmapi.GetNetworkRequest{NetworkID: input, Appdata: appdata}); err == nil {
217 217
 		return rg.Network, nil
218 218
 	}
219 219
 
... ...
@@ -222,12 +223,14 @@ func getNetwork(ctx context.Context, c swarmapi.ControlClient, input string) (*s
222 222
 		Filters: &swarmapi.ListNetworksRequest_Filters{
223 223
 			Names: []string{input},
224 224
 		},
225
+		Appdata: appdata,
225 226
 	})
226 227
 	if err != nil || len(rl.Networks) == 0 {
227 228
 		rl, err = c.ListNetworks(ctx, &swarmapi.ListNetworksRequest{
228 229
 			Filters: &swarmapi.ListNetworksRequest_Filters{
229 230
 				IDPrefixes: []string{input},
230 231
 			},
232
+			Appdata: appdata,
231 233
 		})
232 234
 	}
233 235
 	if err != nil {
... ...
@@ -5,9 +5,11 @@ import (
5 5
 	"fmt"
6 6
 
7 7
 	"github.com/containerd/log"
8
+	gogotypes "github.com/gogo/protobuf/types"
8 9
 	"github.com/moby/moby/api/types/network"
9 10
 	types "github.com/moby/moby/api/types/swarm"
10 11
 	"github.com/moby/moby/v2/daemon/cluster/convert"
12
+	"github.com/moby/moby/v2/daemon/cluster/convert/netextra"
11 13
 	networkSettings "github.com/moby/moby/v2/daemon/network"
12 14
 	"github.com/moby/moby/v2/errdefs"
13 15
 	swarmapi "github.com/moby/swarmkit/v2/api"
... ...
@@ -15,7 +17,7 @@ import (
15 15
 )
16 16
 
17 17
 // GetNetworks returns all current cluster managed networks.
18
-func (c *Cluster) GetNetworks(filter networkSettings.Filter) ([]network.Inspect, error) {
18
+func (c *Cluster) GetNetworks(filter networkSettings.Filter, withStatus bool) ([]network.Inspect, error) {
19 19
 	// Swarmkit API's filters are too limited to express the Moby filter
20 20
 	// semantics with much fidelity. It only supports filtering on one of:
21 21
 	//  - Names (exact match)
... ...
@@ -26,7 +28,7 @@ func (c *Cluster) GetNetworks(filter networkSettings.Filter) ([]network.Inspect,
26 26
 	// semantics are to match on any substring of the network name or ID. We
27 27
 	// therefore need to request all networks from Swarmkit and filter them
28 28
 	// ourselves.
29
-	list, err := c.listNetworks(context.TODO(), nil)
29
+	list, err := c.listNetworks(context.TODO(), nil, withStatus)
30 30
 	if err != nil {
31 31
 		return nil, err
32 32
 	}
... ...
@@ -36,10 +38,11 @@ func (c *Cluster) GetNetworks(filter networkSettings.Filter) ([]network.Inspect,
36 36
 			continue
37 37
 		}
38 38
 		if filter.Matches(convert.FilterNetwork{N: n}) {
39
-			filtered = append(filtered, network.Inspect{
40
-				Network:    convert.BasicNetworkFromGRPC(*n),
41
-				Containers: map[string]network.EndpointResource{},
42
-			})
39
+			nn, err := convert.NetworkInspectFromGRPC(*n)
40
+			if err != nil {
41
+				return nil, fmt.Errorf("%s: failed to convert swarmapi.Network to network.Inspect: %w", n.ID, err)
42
+			}
43
+			filtered = append(filtered, nn)
43 44
 		}
44 45
 	}
45 46
 
... ...
@@ -47,7 +50,7 @@ func (c *Cluster) GetNetworks(filter networkSettings.Filter) ([]network.Inspect,
47 47
 }
48 48
 
49 49
 func (c *Cluster) GetNetworkSummaries(filter networkSettings.Filter) ([]network.Summary, error) {
50
-	list, err := c.listNetworks(context.TODO(), nil)
50
+	list, err := c.listNetworks(context.TODO(), nil, false)
51 51
 	if err != nil {
52 52
 		return nil, err
53 53
 	}
... ...
@@ -64,10 +67,21 @@ func (c *Cluster) GetNetworkSummaries(filter networkSettings.Filter) ([]network.
64 64
 	return filtered, nil
65 65
 }
66 66
 
67
-func (c *Cluster) listNetworks(ctx context.Context, filters *swarmapi.ListNetworksRequest_Filters) ([]*swarmapi.Network, error) {
67
+func (c *Cluster) listNetworks(ctx context.Context, filters *swarmapi.ListNetworksRequest_Filters, withStatus bool) ([]*swarmapi.Network, error) {
68
+	var appdata *gogotypes.Any
69
+	if withStatus {
70
+		var err error
71
+		appdata, err = gogotypes.MarshalAny(&netextra.GetNetworkExtraOptions{
72
+			WithIPAMStatus: withStatus,
73
+		})
74
+		if err != nil {
75
+			return nil, fmt.Errorf("failed to marshal GetNetworkExtraOptions: %w", err)
76
+		}
77
+	}
78
+
68 79
 	var list []*swarmapi.Network
69 80
 	err := c.lockedManagerAction(ctx, func(ctx context.Context, state nodeState) error {
70
-		l, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters})
81
+		l, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters, Appdata: appdata})
71 82
 		if err != nil {
72 83
 			return err
73 84
 		}
... ...
@@ -78,11 +92,21 @@ func (c *Cluster) listNetworks(ctx context.Context, filters *swarmapi.ListNetwor
78 78
 }
79 79
 
80 80
 // GetNetwork returns a cluster network by an ID.
81
-func (c *Cluster) GetNetwork(input string) (network.Inspect, error) {
82
-	var nw *swarmapi.Network
81
+func (c *Cluster) GetNetwork(input string, withStatus bool) (network.Inspect, error) {
82
+	var appdata *gogotypes.Any
83
+	if withStatus {
84
+		var err error
85
+		appdata, err = gogotypes.MarshalAny(&netextra.GetNetworkExtraOptions{
86
+			WithIPAMStatus: withStatus,
87
+		})
88
+		if err != nil {
89
+			return network.Inspect{}, fmt.Errorf("failed to marshal GetNetworkExtraOptions: %w", err)
90
+		}
91
+	}
83 92
 
93
+	var nw *swarmapi.Network
84 94
 	if err := c.lockedManagerAction(context.TODO(), func(ctx context.Context, state nodeState) error {
85
-		n, err := getNetwork(ctx, state.controlClient, input)
95
+		n, err := getNetwork(ctx, state.controlClient, input, appdata)
86 96
 		if err != nil {
87 97
 			return err
88 98
 		}
... ...
@@ -91,10 +115,7 @@ func (c *Cluster) GetNetwork(input string) (network.Inspect, error) {
91 91
 	}); err != nil {
92 92
 		return network.Inspect{}, err
93 93
 	}
94
-	return network.Inspect{
95
-		Network:    convert.BasicNetworkFromGRPC(*nw),
96
-		Containers: map[string]network.EndpointResource{},
97
-	}, nil
94
+	return convert.NetworkInspectFromGRPC(*nw)
98 95
 }
99 96
 
100 97
 // GetNetworksByName returns cluster managed networks by name.
... ...
@@ -104,7 +125,7 @@ func (c *Cluster) GetNetworksByName(name string) ([]network.Network, error) {
104 104
 	// So we cannot just use that with c.GetNetwork.
105 105
 	list, err := c.listNetworks(context.TODO(), &swarmapi.ListNetworksRequest_Filters{
106 106
 		Names: []string{name},
107
-	})
107
+	}, false)
108 108
 	if err != nil {
109 109
 		return nil, err
110 110
 	}
... ...
@@ -296,7 +317,7 @@ func (c *Cluster) CreateNetwork(s network.CreateRequest) (string, error) {
296 296
 // RemoveNetwork removes a cluster network.
297 297
 func (c *Cluster) RemoveNetwork(input string) error {
298 298
 	return c.lockedManagerAction(context.TODO(), func(ctx context.Context, state nodeState) error {
299
-		nw, err := getNetwork(ctx, state.controlClient, input)
299
+		nw, err := getNetwork(ctx, state.controlClient, input, nil)
300 300
 		if err != nil {
301 301
 			return err
302 302
 		}
... ...
@@ -314,13 +335,13 @@ func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.Control
314 314
 		networks = s.Networks //nolint:staticcheck // ignore SA1019: field is deprecated.
315 315
 	}
316 316
 	for i, nw := range networks {
317
-		apiNetwork, err := getNetwork(ctx, client, nw.Target)
317
+		apiNetwork, err := getNetwork(ctx, client, nw.Target, nil)
318 318
 		if err != nil {
319 319
 			ln, _ := c.config.Backend.FindNetwork(nw.Target)
320 320
 			if ln != nil && networkSettings.IsPredefined(ln.Name()) {
321 321
 				// Need to retrieve the corresponding predefined swarm network
322 322
 				// and use its id for the request.
323
-				apiNetwork, err = getNetwork(ctx, client, ln.Name())
323
+				apiNetwork, err = getNetwork(ctx, client, ln.Name(), nil)
324 324
 				if err != nil {
325 325
 					return errors.Wrap(errdefs.NotFound(err), "could not find the corresponding predefined swarm network")
326 326
 				}
327 327
new file mode 100644
... ...
@@ -0,0 +1,66 @@
0
+package cnmallocator
1
+
2
+import (
3
+	"context"
4
+	"fmt"
5
+	"net/netip"
6
+
7
+	networktypes "github.com/moby/moby/api/types/network"
8
+	"github.com/moby/moby/v2/daemon/cluster/convert/netextra"
9
+	"github.com/moby/moby/v2/daemon/libnetwork/ipamapi"
10
+	"github.com/moby/swarmkit/v2/api"
11
+	"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
12
+)
13
+
14
+var _ networkallocator.OnGetNetworker = &cnmNetworkAllocator{}
15
+
16
+// OnGetNetwork augments Swarm networks with operational status.
17
+func (na *cnmNetworkAllocator) OnGetNetwork(ctx context.Context, swarmnet *api.Network, typeurl string, appdata []byte) error {
18
+	opts, err := netextra.OptionsFrom(typeurl, appdata)
19
+	if err != nil {
20
+		return fmt.Errorf("cnmallocator: bad appdata provided to OnGetNetwork: %w", err)
21
+	}
22
+	if !opts.WithIPAMStatus {
23
+		return nil
24
+	}
25
+
26
+	n := na.getNetwork(swarmnet.ID)
27
+	if n == nil {
28
+		return fmt.Errorf("cnmallocator: network %s not found", swarmnet.ID)
29
+	}
30
+
31
+	ipamdriver, _, _, err := na.resolveIPAM(swarmnet)
32
+	if err != nil {
33
+		return fmt.Errorf("cnmallocator: failed to resolve IPAM driver for network %s: %w", swarmnet.ID, err)
34
+	}
35
+
36
+	ipam, ok := ipamdriver.(ipamapi.PoolStatuser)
37
+	if !ok {
38
+		// IPAM driver does not support reporting operational status.
39
+		return nil
40
+	}
41
+
42
+	status := networktypes.Status{
43
+		IPAM: networktypes.IPAMStatus{
44
+			Subnets: make(map[netip.Prefix]networktypes.SubnetStatus),
45
+		},
46
+	}
47
+	for subnet, poolID := range n.pools {
48
+		pstat, err := ipam.PoolStatus(poolID)
49
+		if err != nil {
50
+			return fmt.Errorf("cnmallocator: failed to get pool status for network %s: %w", swarmnet.ID, err)
51
+		}
52
+		status.IPAM.Subnets[subnet] = networktypes.SubnetStatus{
53
+			IPsInUse:            pstat.IPsInUse,
54
+			DynamicIPsAvailable: pstat.DynamicIPsAvailable,
55
+		}
56
+	}
57
+
58
+	extra, err := netextra.MarshalStatus(&status)
59
+	if err != nil {
60
+		return fmt.Errorf("cnmallocator: failed to marshal network status for network %s: %w", swarmnet.ID, err)
61
+	}
62
+	swarmnet.Extra = extra
63
+
64
+	return nil
65
+}
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"context"
5 5
 	"fmt"
6 6
 	"net"
7
+	"net/netip"
7 8
 	"slices"
8 9
 	"strings"
9 10
 
... ...
@@ -66,7 +67,7 @@ type network struct {
66 66
 
67 67
 	// pools is used to save the internal poolIDs needed when
68 68
 	// releasing the pool.
69
-	pools map[string]string
69
+	pools map[netip.Prefix]string
70 70
 
71 71
 	// endpoints is a map of endpoint IP to the poolID from which it
72 72
 	// was allocated.
... ...
@@ -834,7 +835,7 @@ func (na *cnmNetworkAllocator) resolveIPAM(n *api.Network) (ipamapi.Ipam, string
834 834
 	return ipam, dName, dOptions, nil
835 835
 }
836 836
 
837
-func (na *cnmNetworkAllocator) freePools(n *api.Network, pools map[string]string) error {
837
+func (na *cnmNetworkAllocator) freePools(n *api.Network, pools map[netip.Prefix]string) error {
838 838
 	ipam, _, _, err := na.resolveIPAM(n)
839 839
 	if err != nil {
840 840
 		return errors.Wrapf(err, "failed to resolve IPAM while freeing pools for network %s", n.ID)
... ...
@@ -844,9 +845,14 @@ func (na *cnmNetworkAllocator) freePools(n *api.Network, pools map[string]string
844 844
 	return nil
845 845
 }
846 846
 
847
-func releasePools(ipam ipamapi.Ipam, icList []*api.IPAMConfig, pools map[string]string) {
847
+func releasePools(ipam ipamapi.Ipam, icList []*api.IPAMConfig, pools map[netip.Prefix]string) {
848 848
 	for _, ic := range icList {
849
-		if err := ipam.ReleaseAddress(pools[ic.Subnet], net.ParseIP(ic.Gateway)); err != nil {
849
+		subnet, err := netip.ParsePrefix(ic.Subnet)
850
+		if err != nil {
851
+			log.G(context.TODO()).WithError(err).Errorf("Failed to parse subnet %q when releasing pools", ic.Subnet)
852
+			continue
853
+		}
854
+		if err := ipam.ReleaseAddress(pools[subnet], net.ParseIP(ic.Gateway)); err != nil {
850 855
 			log.G(context.TODO()).WithError(err).Errorf("Failed to release address %s", ic.Subnet)
851 856
 		}
852 857
 	}
... ...
@@ -858,7 +864,7 @@ func releasePools(ipam ipamapi.Ipam, icList []*api.IPAMConfig, pools map[string]
858 858
 	}
859 859
 }
860 860
 
861
-func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string, error) {
861
+func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[netip.Prefix]string, error) {
862 862
 	ipam, dName, dOptions, err := na.resolveIPAM(n)
863 863
 	if err != nil {
864 864
 		return nil, err
... ...
@@ -871,7 +877,7 @@ func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string,
871 871
 		return nil, err
872 872
 	}
873 873
 
874
-	pools := make(map[string]string)
874
+	pools := make(map[netip.Prefix]string)
875 875
 
876 876
 	var ipamConfigs []*api.IPAMConfig
877 877
 
... ...
@@ -908,7 +914,7 @@ func (na *cnmNetworkAllocator) allocatePools(n *api.Network) (map[string]string,
908 908
 			releasePools(ipam, ipamConfigs[:i], pools)
909 909
 			return nil, err
910 910
 		}
911
-		pools[alloc.Pool.String()] = alloc.PoolID
911
+		pools[alloc.Pool] = alloc.PoolID
912 912
 
913 913
 		// The IPAM contract allows the IPAM driver to autonomously
914 914
 		// provide a network gateway in response to the pool request.
... ...
@@ -136,7 +136,7 @@ func (daemon *Daemon) clusterNetworksPrune(ctx context.Context, pruneFilters dne
136 136
 		return rep, nil
137 137
 	}
138 138
 
139
-	networks, err := cluster.GetNetworks(pruneFilters)
139
+	networks, err := cluster.GetNetworks(pruneFilters, false)
140 140
 	if err != nil {
141 141
 		return rep, err
142 142
 	}
... ...
@@ -24,9 +24,9 @@ type Backend interface {
24 24
 // ClusterBackend is all the methods that need to be implemented
25 25
 // to provide cluster network specific functionality.
26 26
 type ClusterBackend interface {
27
-	GetNetworks(dnetwork.Filter) ([]network.Inspect, error)
27
+	GetNetworks(filter dnetwork.Filter, withStatus bool) ([]network.Inspect, error)
28 28
 	GetNetworkSummaries(dnetwork.Filter) ([]network.Summary, error)
29
-	GetNetwork(name string) (network.Inspect, error)
29
+	GetNetwork(name string, withStatus bool) (network.Inspect, error)
30 30
 	GetNetworksByName(name string) ([]network.Network, error)
31 31
 	CreateNetwork(nc network.CreateRequest) (string, error)
32 32
 	RemoveNetwork(name string) error
... ...
@@ -35,7 +35,7 @@ func (n *networkRouter) getNetworksList(ctx context.Context, w http.ResponseWrit
35 35
 	}
36 36
 
37 37
 	if versions.LessThan(httputils.VersionFromContext(ctx), "1.28") {
38
-		list, _ := n.cluster.GetNetworks(filter)
38
+		list, _ := n.cluster.GetNetworks(filter, false)
39 39
 		var idx map[string]bool
40 40
 		if len(list) > 0 {
41 41
 			idx = make(map[string]bool, len(list))
... ...
@@ -146,9 +146,10 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
146 146
 	}
147 147
 	filter.IDAlsoMatchesName = true
148 148
 
149
+	withStatus := versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.52")
149 150
 	networks, _ := n.backend.GetNetworks(filter, backend.NetworkListConfig{
150 151
 		WithServices: verbose,
151
-		WithStatus:   versions.GreaterThanOrEqualTo(httputils.VersionFromContext(ctx), "1.52"),
152
+		WithStatus:   withStatus,
152 153
 	})
153 154
 	for _, nw := range networks {
154 155
 		if nw.ID == term {
... ...
@@ -166,7 +167,7 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
166 166
 		}
167 167
 	}
168 168
 
169
-	nwk, err := n.cluster.GetNetwork(term)
169
+	nwk, err := n.cluster.GetNetwork(term, withStatus)
170 170
 	if err == nil {
171 171
 		// If the get network is passed with a specific network ID / partial network ID
172 172
 		// or if the get network was passed with a network name and scope as swarm
... ...
@@ -174,17 +175,20 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
174 174
 		// is not set which would be case if the client API v1.30
175 175
 		if strings.HasPrefix(nwk.ID, term) || networkScope == scope.Swarm {
176 176
 			// If we have a previous match "backend", return it
177
+			// along with the Status from the Swarm leader.
177 178
 			// ex: overlay/partial_ID or name/swarm_scope
178 179
 			if nwv, ok := listByPartialID[nwk.ID]; ok {
180
+				nwv.Status = nwk.Status
179 181
 				nwk = nwv
180 182
 			} else if nwv, ok = listByFullName[nwk.ID]; ok {
183
+				nwv.Status = nwk.Status
181 184
 				nwk = nwv
182 185
 			}
183 186
 			return httputils.WriteJSON(w, http.StatusOK, nwk)
184 187
 		}
185 188
 	}
186 189
 
187
-	networks, _ = n.cluster.GetNetworks(filter)
190
+	networks, _ = n.cluster.GetNetworks(filter, withStatus)
188 191
 	for _, nw := range networks {
189 192
 		if nw.ID == term {
190 193
 			return httputils.WriteJSON(w, http.StatusOK, nw)
... ...
@@ -193,7 +197,10 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
193 193
 			// Check the ID collision as we are in swarm scope here, and
194 194
 			// the map (of the listByFullName) may have already had a
195 195
 			// network with the same ID (from local scope previously)
196
-			if _, ok := listByFullName[nw.ID]; !ok {
196
+			if nwk, ok := listByFullName[nw.ID]; ok {
197
+				nwk.Status = nw.Status
198
+				listByFullName[nw.ID] = nwk
199
+			} else {
197 200
 				listByFullName[nw.ID] = nw
198 201
 			}
199 202
 		}
... ...
@@ -201,7 +208,10 @@ func (n *networkRouter) getNetwork(ctx context.Context, w http.ResponseWriter, r
201 201
 			// Check the ID collision as we are in swarm scope here, and
202 202
 			// the map (of the listByPartialID) may have already had a
203 203
 			// network with the same ID (from local scope previously)
204
-			if _, ok := listByPartialID[nw.ID]; !ok {
204
+			if nwk, ok := listByPartialID[nw.ID]; ok {
205
+				nwk.Status = nw.Status
206
+				listByPartialID[nw.ID] = nwk
207
+			} else {
205 208
 				listByPartialID[nw.ID] = nw
206 209
 			}
207 210
 		}
... ...
@@ -376,7 +386,7 @@ func (n *networkRouter) findUniqueNetwork(term string) (network.Inspect, error)
376 376
 		}
377 377
 	}
378 378
 
379
-	networks, _ = n.cluster.GetNetworks(filter)
379
+	networks, _ = n.cluster.GetNetworks(filter, false)
380 380
 	for _, nw := range networks {
381 381
 		if nw.ID == term {
382 382
 			return nw, nil
... ...
@@ -66,7 +66,7 @@ require (
66 66
 	github.com/moby/profiles/apparmor v0.1.0
67 67
 	github.com/moby/profiles/seccomp v0.1.0
68 68
 	github.com/moby/pubsub v1.0.0
69
-	github.com/moby/swarmkit/v2 v2.0.0
69
+	github.com/moby/swarmkit/v2 v2.1.0
70 70
 	github.com/moby/sys/atomicwriter v0.1.0
71 71
 	github.com/moby/sys/mount v0.3.4
72 72
 	github.com/moby/sys/mountinfo v0.7.2
... ...
@@ -414,8 +414,8 @@ github.com/moby/profiles/seccomp v0.1.0 h1:kVf1lc5ytNB1XPxEdZUVF+oPpbBYJHR50eEvP
414 414
 github.com/moby/profiles/seccomp v0.1.0/go.mod h1:Kqk57vxH6/wuOc5bmqRiSXJ6iEz8Pvo3LQRkv0ytFWs=
415 415
 github.com/moby/pubsub v1.0.0 h1:jkp/imWsmJz2f6LyFsk7EkVeN2HxR/HTTOY8kHrsxfA=
416 416
 github.com/moby/pubsub v1.0.0/go.mod h1:bXSO+3h5MNXXCaEG+6/NlAIk7MMZbySZlnB+cUQhKKc=
417
-github.com/moby/swarmkit/v2 v2.0.0 h1:jkWQKQaJ4ltA61/mC9UdPe1McLma55RUcacTO+pPweY=
418
-github.com/moby/swarmkit/v2 v2.0.0/go.mod h1:mTTGIAz/59OGZR5Qe+QByIe3Nxc+sSuJkrsStFhr6Lg=
417
+github.com/moby/swarmkit/v2 v2.1.0 h1:u+cJ5hSyF3HnzsyI+NtegYxdIPQIuibk7IbpXNxuISM=
418
+github.com/moby/swarmkit/v2 v2.1.0/go.mod h1:mTTGIAz/59OGZR5Qe+QByIe3Nxc+sSuJkrsStFhr6Lg=
419 419
 github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
420 420
 github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
421 421
 github.com/moby/sys/mount v0.3.4 h1:yn5jq4STPztkkzSKpZkLcmjue+bZJ0u2AuQY1iNI1Ww=
... ...
@@ -148,6 +148,13 @@ func ServiceWithMaxReplicas(n uint64) ServiceSpecOpt {
148 148
 	}
149 149
 }
150 150
 
151
+func ServiceWithPlacementConstraints(constraints ...string) ServiceSpecOpt {
152
+	return func(spec *swarmtypes.ServiceSpec) {
153
+		ensurePlacement(spec)
154
+		spec.TaskTemplate.Placement.Constraints = constraints
155
+	}
156
+}
157
+
151 158
 // ServiceWithName sets the name of the service
152 159
 func ServiceWithName(name string) ServiceSpecOpt {
153 160
 	return func(spec *swarmtypes.ServiceSpec) {
... ...
@@ -61,8 +61,9 @@ func RunningTasksCount(ctx context.Context, apiClient client.ServiceAPIClient, s
61 61
 			switch task.Status.State {
62 62
 			case swarmtypes.TaskStateRunning:
63 63
 				running++
64
-			case swarmtypes.TaskStateFailed:
64
+			case swarmtypes.TaskStateFailed, swarmtypes.TaskStateRejected:
65 65
 				if task.Status.Err != "" {
66
+					log.Logf("task %v on node %v %v: %v", task.ID, task.NodeID, task.Status.State, task.Status.Err)
66 67
 					taskError = task.Status.Err
67 68
 				}
68 69
 			default:
... ...
@@ -160,3 +161,20 @@ func JobComplete(ctx context.Context, apiClient client.ServiceAPIClient, service
160 160
 		}
161 161
 	}
162 162
 }
163
+
164
+func HasLeader(ctx context.Context, apiClient client.NodeAPIClient) func(log poll.LogT) poll.Result {
165
+	return func(log poll.LogT) poll.Result {
166
+		nodes, err := apiClient.NodeList(ctx, client.NodeListOptions{
167
+			Filters: filters.NewArgs(filters.Arg("role", "manager")),
168
+		})
169
+		if err != nil {
170
+			return poll.Error(err)
171
+		}
172
+		for _, node := range nodes {
173
+			if node.ManagerStatus != nil && node.ManagerStatus.Leader {
174
+				return poll.Success()
175
+			}
176
+		}
177
+		return poll.Continue("no leader elected yet")
178
+	}
179
+}
... ...
@@ -1,13 +1,19 @@
1 1
 package network
2 2
 
3 3
 import (
4
+	"net/netip"
5
+	"strconv"
4 6
 	"testing"
5 7
 
8
+	"github.com/moby/moby/api/types/filters"
9
+	networktypes "github.com/moby/moby/api/types/network"
6 10
 	"github.com/moby/moby/client"
7 11
 	"github.com/moby/moby/v2/integration/internal/network"
8 12
 	"github.com/moby/moby/v2/integration/internal/swarm"
9 13
 	"github.com/moby/moby/v2/internal/testutil"
14
+	"github.com/moby/moby/v2/internal/testutil/daemon"
10 15
 	"gotest.tools/v3/assert"
16
+	is "gotest.tools/v3/assert/cmp"
11 17
 	"gotest.tools/v3/poll"
12 18
 	"gotest.tools/v3/skip"
13 19
 )
... ...
@@ -17,26 +23,65 @@ func TestInspectNetwork(t *testing.T) {
17 17
 	skip.If(t, testEnv.IsRootless, "rootless mode doesn't support Swarm-mode")
18 18
 	ctx := setupTest(t)
19 19
 
20
-	d := swarm.NewSwarm(ctx, t, testEnv)
21
-	defer d.Stop(t)
22
-	c := d.NewClientT(t)
23
-	defer c.Close()
20
+	var mgr [3]*daemon.Daemon
21
+	mgr[0] = swarm.NewSwarm(ctx, t, testEnv, daemon.WithSwarmListenAddr("127.0.0.2"))
22
+	defer mgr[0].Stop(t)
23
+
24
+	for i := range mgr {
25
+		if i != 0 {
26
+			mgr[i] = daemon.New(t, daemon.WithSwarmListenAddr("127.0.0."+strconv.Itoa(i+2)))
27
+			mgr[i].StartAndSwarmJoin(ctx, t, mgr[0], true)
28
+			defer mgr[i].Stop(t)
29
+		}
30
+		t.Logf("Daemon %s is Swarm Node %s", mgr[i].ID(), mgr[i].NodeID())
31
+	}
32
+
33
+	c1 := mgr[0].NewClientT(t)
34
+	defer c1.Close()
35
+
36
+	worker1 := daemon.New(t, daemon.WithSwarmListenAddr("127.0.0."+strconv.Itoa(len(mgr)+2)))
37
+	worker1.StartAndSwarmJoin(ctx, t, mgr[0], false)
38
+	defer worker1.Stop(t)
39
+	t.Logf("Daemon %s is Swarm Node %s", worker1.ID(), worker1.NodeID())
40
+
41
+	w1 := worker1.NewClientT(t)
42
+	defer w1.Close()
24 43
 
25 44
 	networkName := "Overlay" + t.Name()
26
-	overlayID := network.CreateNoError(ctx, t, c, networkName,
45
+	cidrv4 := netip.MustParsePrefix("192.168.0.0/24")
46
+	const ipv4Range = "192.168.0.0/25"
47
+
48
+	overlayID := network.CreateNoError(ctx, t, c1, networkName,
27 49
 		network.WithDriver("overlay"),
50
+		network.WithIPAMConfig(networktypes.IPAMConfig{
51
+			Subnet:  cidrv4.String(),
52
+			IPRange: ipv4Range,
53
+		}),
28 54
 	)
55
+	// Other tests fail unless the network is removed, even though they run
56
+	// on a new daemon. This is due to the vxlan link (the netlink kernel
57
+	// object) leaking, which prevents other daemons on the same kernel from
58
+	// creating a new vxlan link with the same VNI.
59
+	defer func() {
60
+		assert.NilError(t, c1.NetworkRemove(ctx, overlayID))
61
+		poll.WaitOn(t, network.IsRemoved(ctx, w1, overlayID), swarm.NetworkPoll)
62
+	}()
29 63
 
30
-	var instances uint64 = 2
64
+	const instances = 2
31 65
 	serviceName := "TestService" + t.Name()
32 66
 
33
-	serviceID := swarm.CreateService(ctx, t, d,
67
+	serviceID := swarm.CreateService(ctx, t, mgr[0],
34 68
 		swarm.ServiceWithReplicas(instances),
69
+		swarm.ServiceWithPlacementConstraints("node.role == worker"),
35 70
 		swarm.ServiceWithName(serviceName),
36 71
 		swarm.ServiceWithNetwork(networkName),
37 72
 	)
73
+	defer func() {
74
+		assert.NilError(t, c1.ServiceRemove(ctx, serviceID))
75
+		poll.WaitOn(t, swarm.NoTasksForService(ctx, c1, serviceID), swarm.ServicePoll)
76
+	}()
38 77
 
39
-	poll.WaitOn(t, swarm.RunningTasksCount(ctx, c, serviceID, instances), swarm.ServicePoll)
78
+	poll.WaitOn(t, swarm.RunningTasksCount(ctx, c1, serviceID, instances), swarm.ServicePoll)
40 79
 
41 80
 	tests := []struct {
42 81
 		name    string
... ...
@@ -73,30 +118,87 @@ func TestInspectNetwork(t *testing.T) {
73 73
 			},
74 74
 		},
75 75
 	}
76
-	for _, tc := range tests {
77
-		t.Run(tc.name, func(t *testing.T) {
78
-			ctx := testutil.StartSpan(ctx, t)
79
-			nw, err := c.NetworkInspect(ctx, tc.network, tc.opts)
80
-			assert.NilError(t, err)
81
-
82
-			if service, ok := nw.Services[serviceName]; ok {
83
-				assert.Equal(t, len(service.Tasks), int(instances))
84
-			}
76
+	checkNetworkInspect := func(t *testing.T) {
77
+		for _, tc := range tests {
78
+			t.Run(tc.name, func(t *testing.T) {
79
+				ctx := testutil.StartSpan(ctx, t)
85 80
 
86
-			assert.Assert(t, nw.IPAM.Config != nil)
81
+				for _, d := range append([]*daemon.Daemon{worker1}, mgr[:]...) {
82
+					t.Logf("--- Node %s (%s) ---", d.ID(), d.NodeID())
83
+					c := d.NewClientT(t)
84
+					nw, err := c.NetworkInspect(ctx, tc.network, tc.opts)
85
+					if !assert.Check(t, err) {
86
+						continue
87
+					}
87 88
 
88
-			for _, cfg := range nw.IPAM.Config {
89
-				assert.Assert(t, cfg.Gateway != "")
90
-				assert.Assert(t, cfg.Subnet != "")
91
-			}
89
+					assert.Check(t, nw.IPAM.Config != nil)
90
+					for _, cfg := range nw.IPAM.Config {
91
+						assert.Assert(t, cfg.Gateway != "")
92
+						assert.Assert(t, cfg.Subnet != "")
93
+					}
94
+
95
+					if d.CachedInfo.Swarm.ControlAvailable {
96
+						// The global view of the network status is only available from manager nodes.
97
+						if assert.Check(t, nw.Status != nil) {
98
+							wantSubnetStatus := map[netip.Prefix]networktypes.SubnetStatus{
99
+								cidrv4: {
100
+									IPsInUse:            uint64(1 + instances + len(mgr) + 1),
101
+									DynamicIPsAvailable: uint64(128 - (instances + len(mgr) + 1)),
102
+								},
103
+							}
104
+							assert.Check(t, is.DeepEqual(wantSubnetStatus, nw.Status.IPAM.Subnets))
105
+						}
106
+					} else {
107
+						// Services are only inspectable on nodes that have the network instantiated in
108
+						// libnetwork, i.e. nodes with tasks attached to the network. In this test, only
109
+						// the one worker node has tasks assigned.
110
+						if assert.Check(t, is.Contains(nw.Services, serviceName)) {
111
+							assert.Check(t, is.Len(nw.Services[serviceName].Tasks, instances))
112
+						}
113
+					}
114
+					c.Close()
115
+				}
116
+			})
117
+		}
118
+	}
119
+
120
+	t.Run("BeforeLeaderChange", checkNetworkInspect)
121
+
122
+	leaderID := func() string {
123
+		ls, err := c1.NodeList(ctx, client.NodeListOptions{
124
+			Filters: filters.NewArgs(filters.Arg("role", "manager")),
92 125
 		})
126
+		assert.NilError(t, err)
127
+		for _, node := range ls {
128
+			if node.ManagerStatus != nil && node.ManagerStatus.Leader {
129
+				return node.ID
130
+			}
131
+		}
132
+		t.Fatal("could not find current leader")
133
+		return ""
93 134
 	}
94 135
 
95
-	// TODO find out why removing networks is needed; other tests fail if the network is not removed, even though they run on a new daemon.
96
-	err := c.ServiceRemove(ctx, serviceID)
97
-	assert.NilError(t, err)
98
-	poll.WaitOn(t, swarm.NoTasksForService(ctx, c, serviceID), swarm.ServicePoll)
99
-	err = c.NetworkRemove(ctx, overlayID)
100
-	assert.NilError(t, err)
101
-	poll.WaitOn(t, network.IsRemoved(ctx, c, overlayID), swarm.NetworkPoll)
136
+	t.Run("AfterLeaderChange", func(t *testing.T) {
137
+		oldLeader := leaderID()
138
+		var leader *daemon.Daemon
139
+		for _, d := range mgr {
140
+			if d.NodeID() == oldLeader {
141
+				leader = d
142
+				break
143
+			}
144
+		}
145
+		assert.Assert(t, leader != nil)
146
+		// Force a leader change
147
+		for range 3 {
148
+			leader.RestartNode(t)
149
+			poll.WaitOn(t, swarm.HasLeader(ctx, c1), swarm.NetworkPoll)
150
+			if leaderID() != oldLeader {
151
+				break
152
+			}
153
+			t.Log("Restarting the node did not trigger a leader change")
154
+		}
155
+		assert.Assert(t, leaderID() != oldLeader, "leader did not change")
156
+
157
+		checkNetworkInspect(t)
158
+	})
102 159
 }
... ...
@@ -45,7 +45,11 @@ func (d *Daemon) RestartNode(t testing.TB) {
45 45
 // StartAndSwarmInit starts the daemon (with busybox) and init the swarm
46 46
 func (d *Daemon) StartAndSwarmInit(ctx context.Context, t testing.TB) {
47 47
 	d.StartNodeWithBusybox(ctx, t)
48
-	d.SwarmInit(ctx, t, swarm.InitRequest{})
48
+	var req swarm.InitRequest
49
+	if d.swarmListenAddr != defaultSwarmListenAddr {
50
+		req.AdvertiseAddr = d.swarmListenAddr
51
+	}
52
+	d.SwarmInit(ctx, t, req)
49 53
 }
50 54
 
51 55
 // StartAndSwarmJoin starts the daemon (with busybox) and join the specified swarm as worker or manager
... ...
@@ -59,10 +63,14 @@ func (d *Daemon) StartAndSwarmJoin(ctx context.Context, t testing.TB, leader *Da
59 59
 		token = tokens.Manager
60 60
 	}
61 61
 	t.Logf("[%s] joining swarm manager [%s]@%s, swarm listen addr %s", d.id, leader.id, leader.SwarmListenAddr(), d.SwarmListenAddr())
62
-	d.SwarmJoin(ctx, t, swarm.JoinRequest{
62
+	req := swarm.JoinRequest{
63 63
 		RemoteAddrs: []string{leader.SwarmListenAddr()},
64 64
 		JoinToken:   token,
65
-	})
65
+	}
66
+	if d.swarmListenAddr != defaultSwarmListenAddr {
67
+		req.AdvertiseAddr = d.swarmListenAddr
68
+	}
69
+	d.SwarmJoin(ctx, t, req)
66 70
 }
67 71
 
68 72
 // SpecConstructor defines a swarm spec constructor
... ...
@@ -7215,6 +7215,14 @@ file {
7215 7215
       type: TYPE_BOOL
7216 7216
       json_name: "pendingDelete"
7217 7217
     }
7218
+    field {
7219
+      name: "extra"
7220
+      number: 7
7221
+      label: LABEL_OPTIONAL
7222
+      type: TYPE_MESSAGE
7223
+      type_name: ".google.protobuf.Any"
7224
+      json_name: "extra"
7225
+    }
7218 7226
     options {
7219 7227
       70001 {
7220 7228
         1 {
... ...
@@ -8296,6 +8304,14 @@ file {
8296 8296
       type: TYPE_STRING
8297 8297
       json_name: "networkId"
8298 8298
     }
8299
+    field {
8300
+      name: "appdata"
8301
+      number: 3
8302
+      label: LABEL_OPTIONAL
8303
+      type: TYPE_MESSAGE
8304
+      type_name: ".google.protobuf.Any"
8305
+      json_name: "appdata"
8306
+    }
8299 8307
   }
8300 8308
   message_type {
8301 8309
     name: "GetNetworkResponse"
... ...
@@ -8338,6 +8354,14 @@ file {
8338 8338
       type_name: ".docker.swarmkit.v1.ListNetworksRequest.Filters"
8339 8339
       json_name: "filters"
8340 8340
     }
8341
+    field {
8342
+      name: "appdata"
8343
+      number: 2
8344
+      label: LABEL_OPTIONAL
8345
+      type: TYPE_MESSAGE
8346
+      type_name: ".google.protobuf.Any"
8347
+      json_name: "appdata"
8348
+    }
8341 8349
     nested_type {
8342 8350
       name: "Filters"
8343 8351
       field {
... ...
@@ -1285,6 +1285,8 @@ var xxx_messageInfo_CreateNetworkResponse proto.InternalMessageInfo
1285 1285
 type GetNetworkRequest struct {
1286 1286
 	Name      string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
1287 1287
 	NetworkID string `protobuf:"bytes,2,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"`
1288
+	// Application-specific message for the NetworkAllocator's OnGetNetwork callback.
1289
+	Appdata *types.Any `protobuf:"bytes,3,opt,name=appdata,proto3" json:"appdata,omitempty"`
1288 1290
 }
1289 1291
 
1290 1292
 func (m *GetNetworkRequest) Reset()      { *m = GetNetworkRequest{} }
... ...
@@ -1429,6 +1431,8 @@ var xxx_messageInfo_RemoveNetworkResponse proto.InternalMessageInfo
1429 1429
 
1430 1430
 type ListNetworksRequest struct {
1431 1431
 	Filters *ListNetworksRequest_Filters `protobuf:"bytes,1,opt,name=filters,proto3" json:"filters,omitempty"`
1432
+	// Application-specific message for the NetworkAllocator's OnGetNetwork callback.
1433
+	Appdata *types.Any `protobuf:"bytes,2,opt,name=appdata,proto3" json:"appdata,omitempty"`
1432 1434
 }
1433 1435
 
1434 1436
 func (m *ListNetworksRequest) Reset()      { *m = ListNetworksRequest{} }
... ...
@@ -3859,195 +3863,197 @@ func init() {
3859 3859
 }
3860 3860
 
3861 3861
 var fileDescriptor_b37401dd08bf8930 = []byte{
3862
-	// 3006 bytes of a gzipped FileDescriptorProto
3863
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0x4b, 0x6f, 0x1c, 0xc7,
3864
-	0xf1, 0xe7, 0x3e, 0xc8, 0xdd, 0xad, 0xe5, 0x4b, 0x2d, 0x4a, 0x5e, 0xaf, 0xfd, 0x27, 0x85, 0x91,
3865
-	0x25, 0xad, 0xf4, 0x57, 0x76, 0x6d, 0x3a, 0x8e, 0x15, 0x3f, 0x92, 0x88, 0xa2, 0x2c, 0xaf, 0x65,
3866
-	0x4b, 0xc6, 0x50, 0x12, 0x92, 0x43, 0x40, 0x2c, 0x77, 0x5b, 0xf4, 0x98, 0xcb, 0x99, 0xcd, 0xcc,
3867
-	0xac, 0x6c, 0x22, 0x48, 0x90, 0x87, 0x73, 0x0c, 0x90, 0x4b, 0x90, 0x20, 0x87, 0x00, 0x39, 0x05,
3868
-	0x48, 0x80, 0x20, 0xc8, 0x21, 0xc8, 0x21, 0x1f, 0xc0, 0xc8, 0xc9, 0x47, 0x5f, 0xc2, 0xc4, 0x34,
3869
-	0x02, 0xe4, 0x94, 0xaf, 0x90, 0x60, 0xba, 0xab, 0xe7, 0xb5, 0x3d, 0x3d, 0xb3, 0x0f, 0x80, 0x3e,
3870
-	0x91, 0xdb, 0xf3, 0xab, 0xae, 0xea, 0xae, 0x9a, 0x5f, 0xf5, 0x74, 0x15, 0x5c, 0xdf, 0x37, 0xdc,
3871
-	0xf7, 0x86, 0x7b, 0xcd, 0xae, 0x75, 0xd8, 0xea, 0x59, 0xdd, 0x03, 0x6a, 0xb7, 0x9c, 0x0f, 0x3a,
3872
-	0xf6, 0xe1, 0x81, 0xe1, 0xb6, 0x3a, 0x03, 0xa3, 0xd5, 0xb5, 0x4c, 0xd7, 0xb6, 0xfa, 0xcd, 0x81,
3873
-	0x6d, 0xb9, 0x16, 0x21, 0x1c, 0xd2, 0x14, 0x90, 0xe6, 0x93, 0x17, 0xea, 0xd7, 0x52, 0x66, 0x70,
3874
-	0x06, 0xb4, 0xeb, 0x70, 0xf9, 0x7a, 0x9a, 0x36, 0x6b, 0xef, 0x7d, 0xda, 0x75, 0x05, 0x3a, 0x6d,
3875
-	0x66, 0xf7, 0x68, 0x40, 0x05, 0x76, 0x6d, 0xdf, 0xda, 0xb7, 0xd8, 0xbf, 0x2d, 0xef, 0x3f, 0x1c,
3876
-	0x7d, 0x7a, 0xdf, 0xb2, 0xf6, 0xfb, 0xb4, 0xc5, 0x7e, 0xed, 0x0d, 0x1f, 0xb7, 0x3a, 0xe6, 0x11,
3877
-	0x3e, 0x7a, 0x59, 0x31, 0xb9, 0x0f, 0x1f, 0xf4, 0x87, 0xfb, 0x86, 0x89, 0x7f, 0xb8, 0xa0, 0xf6,
3878
-	0x12, 0x2c, 0xdf, 0xa1, 0xee, 0x3d, 0xab, 0x47, 0x75, 0xfa, 0x9d, 0x21, 0x75, 0x5c, 0x72, 0x11,
3879
-	0x4a, 0xa6, 0xd5, 0xa3, 0xbb, 0x46, 0xaf, 0x96, 0xbb, 0x90, 0x6b, 0x54, 0xb6, 0xe0, 0xe4, 0x78,
3880
-	0x63, 0xc1, 0x43, 0xb4, 0xb7, 0xf5, 0x05, 0xef, 0x51, 0xbb, 0xa7, 0x7d, 0x1d, 0x56, 0x7c, 0x31,
3881
-	0x67, 0x60, 0x99, 0x0e, 0x25, 0xd7, 0xa1, 0xe8, 0x3d, 0x64, 0x42, 0xd5, 0xcd, 0x5a, 0x73, 0x74,
3882
-	0x73, 0x9b, 0x0c, 0xcf, 0x50, 0xda, 0x47, 0xf3, 0xb0, 0xfa, 0xb6, 0xe1, 0xb0, 0x29, 0x1c, 0xa1,
3883
-	0xfa, 0x0d, 0x28, 0x3d, 0x36, 0xfa, 0x2e, 0xb5, 0x1d, 0x9c, 0xe5, 0xba, 0x6c, 0x96, 0xb8, 0x58,
3884
-	0xf3, 0x0d, 0x2e, 0xa3, 0x0b, 0xe1, 0xfa, 0x6f, 0x8b, 0x50, 0xc2, 0x41, 0xb2, 0x06, 0xf3, 0x66,
3885
-	0xe7, 0x90, 0x7a, 0x33, 0x16, 0x1a, 0x15, 0x9d, 0xff, 0x20, 0x2d, 0xa8, 0x1a, 0xbd, 0xdd, 0x81,
3886
-	0x4d, 0x1f, 0x1b, 0x1f, 0x52, 0xa7, 0x96, 0xf7, 0x9e, 0x6d, 0x2d, 0x9f, 0x1c, 0x6f, 0x40, 0x7b,
3887
-	0xfb, 0x5d, 0x1c, 0xd5, 0xc1, 0xe8, 0x89, 0xff, 0xc9, 0xbb, 0xb0, 0xd0, 0xef, 0xec, 0xd1, 0xbe,
3888
-	0x53, 0x2b, 0x5c, 0x28, 0x34, 0xaa, 0x9b, 0x37, 0xc6, 0xb1, 0xac, 0xf9, 0x36, 0x13, 0xbd, 0x6d,
3889
-	0xba, 0xf6, 0x91, 0x8e, 0xf3, 0x90, 0x6f, 0x43, 0x95, 0xed, 0x33, 0x4e, 0x5b, 0x62, 0xd3, 0xbe,
3890
-	0x36, 0xd6, 0xb4, 0xde, 0x60, 0x78, 0x6a, 0x30, 0xfd, 0x01, 0xf2, 0x0e, 0x54, 0x0f, 0xe9, 0xe1,
3891
-	0x1e, 0xb5, 0x9d, 0xf7, 0x8c, 0x81, 0x53, 0x2b, 0x5e, 0x28, 0x34, 0x96, 0x37, 0xaf, 0x24, 0x79,
3892
-	0x65, 0x67, 0x40, 0xbb, 0xcd, 0x77, 0x7c, 0xfc, 0x56, 0x7e, 0x75, 0x4e, 0x0f, 0xcb, 0x93, 0xaf,
3893
-	0xc0, 0xbc, 0x6d, 0xf5, 0xa9, 0x53, 0x9b, 0x67, 0x13, 0x3d, 0x9b, 0xe8, 0x5e, 0xab, 0x4f, 0x99,
3894
-	0x34, 0x87, 0x93, 0x8b, 0xb0, 0xe4, 0xed, 0x78, 0xb0, 0xd5, 0x0b, 0xcc, 0x0d, 0x8b, 0xde, 0xa0,
3895
-	0xd8, 0xdc, 0xfa, 0x57, 0xa1, 0x1a, 0x5a, 0x06, 0x59, 0x85, 0xc2, 0x01, 0x3d, 0xe2, 0xd1, 0xa7,
3896
-	0x7b, 0xff, 0x7a, 0x4e, 0x7c, 0xd2, 0xe9, 0x0f, 0x69, 0x2d, 0xcf, 0xc6, 0xf8, 0x8f, 0x57, 0xf2,
3897
-	0x37, 0x72, 0xf5, 0xd7, 0x61, 0x25, 0xb6, 0x0b, 0xe3, 0x88, 0x6b, 0xb7, 0xe0, 0x4c, 0x68, 0x77,
3898
-	0x31, 0x92, 0x9b, 0x30, 0xef, 0x6d, 0x24, 0x0f, 0x19, 0x55, 0x28, 0x73, 0x98, 0xf6, 0xbb, 0x1c,
3899
-	0x9c, 0x79, 0x38, 0xe8, 0x75, 0x5c, 0x3a, 0xee, 0x7b, 0x44, 0xbe, 0x06, 0x8b, 0x0c, 0xf4, 0x84,
3900
-	0xda, 0x8e, 0x61, 0x99, 0xcc, 0xc0, 0xea, 0xe6, 0x33, 0x32, 0x8d, 0x8f, 0x38, 0x44, 0x67, 0x51,
3901
-	0x83, 0x3f, 0xc8, 0xf3, 0x50, 0xf4, 0x18, 0xa9, 0x56, 0x60, 0x72, 0xcf, 0xaa, 0xdc, 0xab, 0x33,
3902
-	0xa4, 0xb6, 0x05, 0x24, 0x6c, 0xeb, 0x44, 0x2f, 0xef, 0x3d, 0x38, 0xa3, 0xd3, 0x43, 0xeb, 0xc9,
3903
-	0xf8, 0xeb, 0x5d, 0x83, 0xf9, 0xc7, 0x96, 0xdd, 0xe5, 0x9e, 0x28, 0xeb, 0xfc, 0x87, 0xb6, 0x06,
3904
-	0x24, 0x3c, 0x1f, 0xb7, 0x09, 0xa9, 0xe9, 0x41, 0xc7, 0x39, 0x08, 0xa9, 0x70, 0x3b, 0xce, 0x41,
3905
-	0x4c, 0x85, 0x87, 0xf0, 0x54, 0x78, 0x8f, 0x7c, 0x6a, 0xe2, 0x62, 0xc1, 0xea, 0xbc, 0x87, 0xaa,
3906
-	0xd5, 0x31, 0x3c, 0x43, 0x69, 0x37, 0xc4, 0xea, 0xc6, 0x56, 0xed, 0xaf, 0x23, 0xac, 0x5d, 0xfb,
3907
-	0x6b, 0x91, 0x53, 0x9d, 0x37, 0x38, 0x01, 0xd5, 0x85, 0xc5, 0x46, 0xa9, 0xee, 0x1f, 0x85, 0xd3,
3908
-	0xa3, 0x3a, 0x99, 0x65, 0x52, 0xaa, 0x6b, 0x41, 0xd5, 0xa1, 0xf6, 0x13, 0xa3, 0xeb, 0x45, 0x07,
3909
-	0xe7, 0x22, 0x34, 0x61, 0x87, 0x0f, 0xb7, 0xb7, 0x1d, 0x1d, 0x10, 0xd2, 0xee, 0x39, 0xe4, 0x32,
3910
-	0x94, 0x31, 0x96, 0x38, 0xe1, 0x54, 0xb6, 0xaa, 0x27, 0xc7, 0x1b, 0x25, 0x1e, 0x4c, 0x8e, 0x5e,
3911
-	0xe2, 0xd1, 0xe4, 0x90, 0x37, 0x61, 0xb9, 0x47, 0x1d, 0xc3, 0xa6, 0xbd, 0x5d, 0xc7, 0xed, 0xb8,
3912
-	0x48, 0x2f, 0xcb, 0x9b, 0xff, 0x97, 0xe4, 0xe2, 0x1d, 0x0f, 0xc5, 0xf8, 0x69, 0x09, 0x05, 0xd9,
3913
-	0x88, 0x84, 0xa7, 0x4a, 0xa3, 0x3c, 0x45, 0xea, 0x50, 0xb6, 0x87, 0xa6, 0x6b, 0x78, 0x7b, 0x5c,
3914
-	0x61, 0xcf, 0xfd, 0xdf, 0xe4, 0x59, 0x80, 0xe1, 0x60, 0xd7, 0xb5, 0x76, 0xbd, 0x77, 0xab, 0x56,
3915
-	0x66, 0xe1, 0x5d, 0x1e, 0x0e, 0x1e, 0x58, 0xdb, 0x1d, 0x97, 0x4e, 0xc1, 0x70, 0x82, 0xa2, 0x70,
3916
-	0xb3, 0x03, 0x8a, 0xf2, 0x62, 0x4e, 0x49, 0x51, 0x2c, 0x08, 0x39, 0x4c, 0xbb, 0x0b, 0x6b, 0xb7,
3917
-	0x6c, 0xda, 0x71, 0x29, 0x6e, 0xb8, 0x08, 0xc3, 0x17, 0x91, 0x3f, 0x78, 0x0c, 0x6e, 0xc8, 0xa6,
3918
-	0x41, 0x89, 0x10, 0x85, 0xdc, 0x83, 0x73, 0xb1, 0xc9, 0xd0, 0xaa, 0x97, 0xa0, 0x84, 0x4e, 0xc4,
3919
-	0x09, 0x9f, 0x51, 0x4c, 0xa8, 0x0b, 0xac, 0xf6, 0x3e, 0x9c, 0xb9, 0x43, 0xdd, 0x98, 0x65, 0xd7,
3920
-	0x01, 0x82, 0x98, 0xc1, 0x77, 0x6e, 0xe9, 0xe4, 0x78, 0xa3, 0xe2, 0x87, 0x8c, 0x5e, 0xf1, 0x23,
3921
-	0x86, 0x5c, 0x81, 0x15, 0xc3, 0x74, 0xa8, 0xed, 0xee, 0xf6, 0xe8, 0xe3, 0xce, 0xb0, 0xef, 0x3a,
3922
-	0xc8, 0x30, 0xcb, 0x7c, 0x78, 0x1b, 0x47, 0xb5, 0xbb, 0x40, 0xc2, 0xba, 0xa6, 0x33, 0xfc, 0x4f,
3923
-	0x79, 0x58, 0xe3, 0x64, 0x3a, 0x95, 0xf1, 0xdb, 0xb0, 0x22, 0xd0, 0x63, 0xe4, 0x81, 0x65, 0x94,
3924
-	0x11, 0xa9, 0xe0, 0xc5, 0x48, 0x2a, 0xc8, 0xe6, 0x4a, 0xf2, 0x0e, 0x94, 0x6d, 0xab, 0xdf, 0xdf,
3925
-	0xeb, 0x74, 0x0f, 0x6a, 0xc5, 0x0b, 0xb9, 0xc6, 0xf2, 0xe6, 0x0b, 0x32, 0x41, 0xd9, 0x22, 0x9b,
3926
-	0x3a, 0x0a, 0xea, 0xfe, 0x14, 0x9a, 0x06, 0x65, 0x31, 0x4a, 0xca, 0x50, 0xbc, 0x77, 0xff, 0xde,
3927
-	0xed, 0xd5, 0x39, 0xb2, 0x08, 0xe5, 0x77, 0xf5, 0xdb, 0x8f, 0xda, 0xf7, 0x1f, 0xee, 0xac, 0xe6,
3928
-	0xbc, 0xe8, 0x89, 0x4d, 0x37, 0x9d, 0x13, 0xb6, 0x61, 0x8d, 0x93, 0xee, 0x34, 0x3e, 0xd0, 0x9e,
3929
-	0x82, 0x73, 0xb1, 0x59, 0x90, 0xbd, 0x3f, 0x2a, 0xc0, 0x59, 0xef, 0xfd, 0xc3, 0x71, 0x9f, 0xc0,
3930
-	0xdb, 0x71, 0x02, 0x6f, 0x25, 0xd1, 0x64, 0x4c, 0x72, 0x94, 0xc3, 0x7f, 0x93, 0x9f, 0x39, 0x87,
3931
-	0xef, 0xc4, 0x38, 0xfc, 0xd5, 0x31, 0x8d, 0x93, 0xd2, 0xf8, 0x08, 0x47, 0x16, 0x53, 0x38, 0x72,
3932
-	0x3e, 0xca, 0x91, 0xd3, 0xb0, 0xe0, 0x7d, 0x58, 0x8b, 0x9a, 0x8b, 0x41, 0xf3, 0x32, 0x94, 0xd1,
3933
-	0x89, 0x82, 0x0b, 0x95, 0x51, 0xe3, 0x83, 0xb5, 0x1b, 0x50, 0x0f, 0x4d, 0xe8, 0x65, 0x81, 0xa1,
3934
-	0x13, 0x78, 0xb7, 0x1e, 0x9b, 0xb6, 0x12, 0x92, 0xfc, 0x7d, 0x1e, 0x9e, 0x91, 0x8a, 0xa2, 0x49,
3935
-	0xdf, 0x82, 0xb2, 0x83, 0x63, 0x68, 0xd2, 0xeb, 0x29, 0xbb, 0x1f, 0x9f, 0xa2, 0x19, 0x19, 0xd7,
3936
-	0xfd, 0xe9, 0xea, 0x7f, 0xcc, 0xc1, 0x52, 0xe4, 0xd9, 0x98, 0x4c, 0x73, 0x11, 0x44, 0xda, 0xdb,
3937
-	0xe5, 0xe9, 0xc3, 0xdb, 0xe7, 0xa2, 0xbe, 0x88, 0x83, 0x2c, 0xc7, 0x78, 0x20, 0x7b, 0x68, 0x9a,
3938
-	0x86, 0xb9, 0x8f, 0xa0, 0x02, 0x07, 0xe1, 0x20, 0x07, 0x5d, 0x81, 0x95, 0xae, 0x75, 0x38, 0xe8,
3939
-	0x53, 0xd7, 0x9f, 0xab, 0xc8, 0x60, 0xcb, 0xfe, 0xf0, 0x83, 0x68, 0xe6, 0xb9, 0x47, 0xdd, 0x0f,
3940
-	0x2c, 0xfb, 0x60, 0x8c, 0xcc, 0x83, 0x12, 0xb2, 0xcc, 0xe3, 0x4f, 0x16, 0x70, 0x87, 0xc9, 0x87,
3941
-	0x54, 0xdc, 0x21, 0xa4, 0x04, 0x56, 0x7b, 0xc8, 0x32, 0x4f, 0xcc, 0x32, 0x02, 0x45, 0x2f, 0xa2,
3942
-	0x31, 0x2e, 0xd9, 0xff, 0xde, 0x36, 0xa3, 0x8c, 0xb7, 0xcd, 0xf9, 0x60, 0x9b, 0x51, 0xd6, 0xdb,
3943
-	0x66, 0x04, 0xb4, 0x7b, 0x98, 0x64, 0x66, 0x64, 0xe3, 0x37, 0x05, 0xbf, 0xcd, 0xdc, 0x4c, 0x9f,
3944
-	0xf3, 0x62, 0x96, 0x6a, 0xff, 0xce, 0x73, 0xce, 0xc3, 0xf1, 0x09, 0x38, 0x2f, 0x26, 0x39, 0xca,
3945
-	0x79, 0x3f, 0x39, 0x45, 0xce, 0x4b, 0x30, 0x6e, 0x62, 0xce, 0x9b, 0x01, 0xaf, 0x05, 0x26, 0x05,
3946
-	0xbc, 0x86, 0x8e, 0x52, 0xf2, 0x9a, 0xf0, 0x9c, 0x0f, 0xd6, 0x6e, 0xb2, 0x90, 0xbe, 0xd5, 0x1f,
3947
-	0x3a, 0x2e, 0xb5, 0x43, 0xb9, 0xb0, 0xcb, 0x47, 0x62, 0x2c, 0x81, 0x38, 0x2f, 0x2e, 0x10, 0xe0,
3948
-	0x87, 0xaf, 0x3f, 0x45, 0x10, 0xbe, 0x08, 0x51, 0x85, 0xaf, 0x90, 0x12, 0x58, 0x3f, 0x96, 0xf0,
3949
-	0xc1, 0x04, 0xb1, 0x14, 0x93, 0xfc, 0x62, 0xc5, 0x52, 0x82, 0x71, 0xa7, 0x19, 0x4b, 0x81, 0x49,
3950
-	0x41, 0x2c, 0xa1, 0x37, 0x94, 0xb1, 0x24, 0x5c, 0xe7, 0x83, 0xb5, 0x9f, 0xe7, 0xa0, 0x7a, 0x97,
3951
-	0x1e, 0xe9, 0x96, 0xdb, 0x71, 0xbd, 0x23, 0xe6, 0x35, 0x38, 0xe3, 0x05, 0x19, 0xb5, 0x77, 0xdf,
3952
-	0xb7, 0x0c, 0x73, 0xd7, 0xb5, 0x0e, 0xa8, 0xc9, 0x4c, 0x2b, 0xeb, 0x2b, 0xfc, 0xc1, 0x5b, 0x96,
3953
-	0x61, 0x3e, 0xf0, 0x86, 0xc9, 0x75, 0x20, 0x87, 0x1d, 0xb3, 0xb3, 0x1f, 0x05, 0xf3, 0x43, 0xf9,
3954
-	0x2a, 0x3e, 0x91, 0xa2, 0x87, 0x66, 0xdf, 0xea, 0x1e, 0xec, 0x7a, 0xab, 0x2e, 0x44, 0xd0, 0x0f,
3955
-	0xd9, 0x83, 0xbb, 0xf4, 0x48, 0xfb, 0x91, 0x7f, 0xee, 0x9e, 0x26, 0xce, 0xbd, 0x73, 0xb7, 0x40,
3956
-	0x8f, 0x73, 0xee, 0x46, 0x99, 0x31, 0xce, 0xdd, 0xa8, 0x3d, 0x74, 0xee, 0xbe, 0xe9, 0x9d, 0xbb,
3957
-	0xf9, 0xae, 0xb2, 0xbc, 0x99, 0x20, 0x18, 0xda, 0xfc, 0xad, 0xe2, 0xc7, 0xc7, 0x1b, 0x73, 0xba,
3958
-	0x2f, 0x16, 0x9c, 0xa3, 0x67, 0xf4, 0xa2, 0xbe, 0x0e, 0xab, 0xec, 0xcb, 0xa8, 0x6b, 0x53, 0x57,
3959
-	0xec, 0xe7, 0x55, 0xa8, 0x38, 0x6c, 0x20, 0xd8, 0xce, 0xc5, 0x93, 0xe3, 0x8d, 0x32, 0x47, 0xb5,
3960
-	0xb7, 0xbd, 0x53, 0x11, 0xfb, 0xaf, 0xa7, 0xdd, 0xc1, 0x8f, 0x38, 0x2e, 0x8e, 0xa6, 0x6c, 0xc2,
3961
-	0x02, 0x07, 0xa0, 0x25, 0x75, 0xf9, 0xd9, 0x8c, 0xc9, 0x20, 0x52, 0xfb, 0x4b, 0x0e, 0xce, 0x8a,
3962
-	0x0f, 0x84, 0xc9, 0x6c, 0x21, 0x5b, 0xb0, 0x8c, 0xd0, 0x31, 0xfc, 0xba, 0xc4, 0x45, 0x84, 0x5b,
3963
-	0x37, 0x23, 0x6e, 0x5d, 0x4f, 0x36, 0x3c, 0x74, 0x3c, 0x79, 0x2b, 0xf8, 0x1c, 0x9c, 0x7a, 0x1b,
3964
-	0xfe, 0x95, 0x07, 0xc2, 0x8f, 0x88, 0xde, 0x4f, 0x9f, 0x36, 0xdf, 0x8c, 0xd3, 0x66, 0x33, 0xf9,
3965
-	0x6c, 0x19, 0x16, 0x1c, 0x65, 0xcd, 0x8f, 0x66, 0xcf, 0x9a, 0x7a, 0x8c, 0x35, 0x5f, 0x19, 0xcf,
3966
-	0xb6, 0x53, 0x21, 0xcd, 0xbb, 0xe2, 0xf3, 0x0e, 0x2d, 0x42, 0x97, 0x7d, 0xd9, 0xfb, 0x18, 0x65,
3967
-	0x43, 0x48, 0x99, 0x2a, 0x9f, 0x09, 0xa8, 0xd6, 0x86, 0xb3, 0xe2, 0x66, 0x24, 0x1c, 0xba, 0x9b,
3968
-	0x91, 0xb3, 0x6e, 0xe6, 0x58, 0x8a, 0x4e, 0x35, 0x45, 0x2c, 0x7d, 0x03, 0xce, 0x8a, 0x8f, 0xdb,
3969
-	0x09, 0xdf, 0xee, 0xf3, 0xc1, 0x47, 0x76, 0xd8, 0x1a, 0x24, 0x8d, 0x5b, 0x96, 0xf9, 0xd8, 0xd8,
3970
-	0x0f, 0x4d, 0xdb, 0x65, 0x03, 0xb1, 0x69, 0x39, 0xca, 0x9b, 0x96, 0x3f, 0xf6, 0x49, 0x43, 0x88,
3971
-	0x07, 0x2b, 0xe4, 0x00, 0xd5, 0x0a, 0x51, 0x06, 0x91, 0x21, 0xd2, 0x98, 0xd4, 0x16, 0x8f, 0x34,
3972
-	0x10, 0x3a, 0x0e, 0x69, 0x70, 0x91, 0x31, 0x48, 0x83, 0x6b, 0x96, 0x91, 0xc6, 0x0c, 0xb6, 0x41,
3973
-	0x90, 0x06, 0x1f, 0x9e, 0x80, 0x34, 0xa2, 0x82, 0x5f, 0x2c, 0xd2, 0x90, 0xdb, 0x76, 0x9a, 0xa4,
3974
-	0xe1, 0x5b, 0x14, 0x90, 0x06, 0x77, 0x84, 0x92, 0x34, 0xd0, 0x67, 0x02, 0x1a, 0x90, 0x46, 0x34,
3975
-	0x74, 0x33, 0x90, 0x86, 0x2c, 0x96, 0xa2, 0x53, 0x4d, 0x11, 0x4b, 0x3e, 0x69, 0x4c, 0xfc, 0x76,
3976
-	0xfb, 0xa4, 0x11, 0xb5, 0x46, 0xfb, 0x1e, 0x9c, 0xe7, 0x56, 0xde, 0xfe, 0xd0, 0xa5, 0x26, 0x7b,
3977
-	0x8f, 0x70, 0xf2, 0x9b, 0x50, 0xed, 0x98, 0x26, 0x9e, 0x70, 0x1c, 0xd5, 0xdd, 0xc0, 0xcd, 0x00,
3978
-	0xa6, 0x87, 0x65, 0xc8, 0x05, 0xa8, 0xf6, 0xa8, 0xd3, 0xb5, 0x8d, 0x81, 0x2b, 0xde, 0xe1, 0x8a,
3979
-	0x1e, 0x1e, 0xd2, 0x1e, 0xc1, 0x53, 0x23, 0xea, 0x71, 0x9f, 0x5e, 0x85, 0x0a, 0x15, 0x83, 0xa8,
3980
-	0x5d, 0x5a, 0x4a, 0x08, 0x24, 0x03, 0xbc, 0xf6, 0x36, 0x9c, 0xe7, 0xcb, 0x1d, 0x59, 0xd6, 0x26,
3981
-	0x2c, 0xfa, 0xb0, 0x60, 0xdb, 0x56, 0x4e, 0x8e, 0x37, 0xaa, 0x3e, 0xb6, 0xbd, 0xad, 0x57, 0x7d,
3982
-	0x50, 0xbb, 0xa7, 0x3d, 0x0d, 0x4f, 0x8d, 0xcc, 0x86, 0xfb, 0xd7, 0x86, 0xb3, 0x77, 0xa8, 0x3b,
3983
-	0x13, 0x2d, 0x3b, 0xb0, 0x16, 0x9d, 0x6a, 0x16, 0x1b, 0xf1, 0xeb, 0x9c, 0xb8, 0xa6, 0xd1, 0xa9,
3984
-	0x63, 0x0d, 0xed, 0xe0, 0x4e, 0x76, 0x06, 0xfe, 0x25, 0x50, 0x3c, 0x30, 0x4c, 0xbc, 0xdc, 0xd0,
3985
-	0xd9, 0xff, 0xa4, 0x09, 0xa5, 0x41, 0xe7, 0xa8, 0x6f, 0x75, 0x7a, 0xc8, 0xbc, 0x6b, 0x4d, 0xde,
3986
-	0x2a, 0xd1, 0x14, 0xbd, 0x0f, 0xcd, 0x9b, 0xe6, 0x91, 0x2e, 0x40, 0x9a, 0x2e, 0x02, 0x30, 0xb0,
3987
-	0x0f, 0xd7, 0x7d, 0x03, 0xca, 0x36, 0x8e, 0xa1, 0x75, 0xd2, 0x9a, 0xaa, 0x2f, 0xe7, 0xa3, 0xb5,
3988
-	0x37, 0xc5, 0x65, 0x4a, 0x7c, 0xcd, 0x2d, 0xa8, 0x0a, 0x50, 0xe0, 0x15, 0x46, 0x88, 0x02, 0xd9,
3989
-	0xde, 0xd6, 0x41, 0x40, 0xda, 0x3d, 0xad, 0x26, 0xe2, 0x28, 0x6e, 0x9d, 0xf6, 0xe3, 0xbc, 0x38,
3990
-	0xf3, 0x4f, 0xab, 0x84, 0xbc, 0x01, 0xab, 0xbe, 0xc0, 0x18, 0xf9, 0x6e, 0x45, 0x08, 0x89, 0x8c,
3991
-	0x17, 0xf3, 0x68, 0x61, 0x02, 0x8f, 0x86, 0xbc, 0x57, 0xcc, 0xe8, 0xbd, 0xf8, 0x26, 0x4c, 0xed,
3992
-	0xbd, 0xdb, 0xec, 0xca, 0x63, 0x6a, 0xd7, 0xdd, 0x67, 0x6f, 0xe6, 0x0c, 0xed, 0xfa, 0x6f, 0x9e,
3993
-	0x7f, 0xd3, 0x8b, 0x47, 0x7e, 0x4a, 0x7f, 0x2b, 0x9e, 0xd2, 0x9f, 0x4f, 0x4a, 0x9b, 0x71, 0xd1,
3994
-	0xd1, 0xa4, 0xfe, 0xab, 0xd9, 0x27, 0xf5, 0x07, 0xb1, 0xa4, 0xfe, 0xda, 0xb8, 0xd6, 0x4d, 0x5e,
3995
-	0x80, 0x10, 0x04, 0x31, 0x1f, 0x10, 0xc4, 0x34, 0xa9, 0x7e, 0x07, 0xce, 0xc5, 0xec, 0x44, 0xa7,
3996
-	0xbe, 0x02, 0x15, 0xe1, 0x26, 0x91, 0xee, 0xd5, 0x5e, 0x0d, 0xe0, 0x41, 0xca, 0x7f, 0x64, 0xf5,
3997
-	0x87, 0x87, 0x74, 0x8c, 0x94, 0xcf, 0x05, 0x64, 0x29, 0x5f, 0x4c, 0x15, 0xa4, 0xfc, 0x27, 0x6c,
3998
-	0x44, 0x95, 0xf2, 0x51, 0x06, 0x91, 0x78, 0x9a, 0x8f, 0xda, 0x74, 0x15, 0x2a, 0xfc, 0x69, 0x2c,
3999
-	0xdf, 0x73, 0x94, 0x97, 0xef, 0xf9, 0x63, 0xff, 0x34, 0x3f, 0x03, 0x3b, 0x82, 0xd3, 0xfc, 0xa4,
4000
-	0xb6, 0x78, 0xa7, 0x79, 0x84, 0x8e, 0x73, 0x9a, 0xe7, 0x22, 0x63, 0x9c, 0xe6, 0x65, 0xee, 0x88,
4001
-	0x5a, 0x3e, 0xc5, 0x36, 0xfc, 0xa2, 0xc0, 0x4f, 0xf3, 0x7c, 0x78, 0x82, 0xd3, 0x7c, 0x54, 0x70,
4002
-	0xf4, 0xc5, 0xff, 0xf3, 0x29, 0x9e, 0xe6, 0xe5, 0xb6, 0x4d, 0xfe, 0xda, 0x9f, 0x87, 0x85, 0x7d,
4003
-	0xdb, 0x1a, 0x0e, 0x44, 0xd5, 0x11, 0x7f, 0x91, 0x1a, 0x94, 0x7a, 0xb6, 0xe1, 0x05, 0x01, 0xb6,
4004
-	0x9e, 0x89, 0x9f, 0x33, 0x38, 0xff, 0xfb, 0x6b, 0x08, 0xce, 0xff, 0xdc, 0x75, 0xca, 0xf3, 0x3f,
4005
-	0x7a, 0x59, 0x40, 0xb5, 0x47, 0xe2, 0xa0, 0x3d, 0x71, 0xb0, 0xcb, 0xbb, 0xaa, 0xfc, 0xe3, 0x77,
4006
-	0x34, 0x14, 0x37, 0xff, 0xde, 0x80, 0xd2, 0x2d, 0xde, 0x08, 0x4b, 0x0c, 0x28, 0x61, 0x1f, 0x27,
4007
-	0xd1, 0x64, 0xb6, 0x46, 0x7b, 0x43, 0xeb, 0x17, 0x95, 0x18, 0x3c, 0xa5, 0x9c, 0xfb, 0xdb, 0x1f,
4008
-	0xfe, 0xf3, 0xcb, 0xfc, 0x0a, 0x2c, 0x31, 0xd0, 0x97, 0xf0, 0xf6, 0x96, 0x58, 0x50, 0xf1, 0x5b,
4009
-	0xed, 0xc8, 0x73, 0x59, 0xfa, 0x1c, 0xeb, 0x97, 0x52, 0x50, 0x6a, 0x85, 0x36, 0x40, 0xd0, 0xe9,
4010
-	0x46, 0x2e, 0x25, 0xf7, 0x35, 0x84, 0x57, 0x78, 0x39, 0x0d, 0x96, 0xaa, 0x33, 0xe8, 0x64, 0x93,
4011
-	0xeb, 0x1c, 0xe9, 0x9c, 0x93, 0xeb, 0x94, 0x34, 0xc4, 0x25, 0xe8, 0xe4, 0x3e, 0x7c, 0xd0, 0x71,
4012
-	0x0e, 0x12, 0x7d, 0x18, 0xea, 0x64, 0x4b, 0xf4, 0x61, 0xa4, 0x67, 0x4d, 0xed, 0x43, 0x5e, 0x02,
4013
-	0x7e, 0x2e, 0x4b, 0x5f, 0x58, 0xb2, 0x0f, 0x23, 0x0d, 0x4d, 0xa9, 0xfb, 0xc9, 0x96, 0xa7, 0xd8,
4014
-	0xcf, 0xf0, 0x0a, 0x2f, 0xa7, 0xc1, 0x52, 0x75, 0x06, 0x2d, 0x42, 0x72, 0x9d, 0x23, 0xed, 0x4a,
4015
-	0x72, 0x9d, 0xa3, 0x9d, 0x46, 0x49, 0x3a, 0x3f, 0x84, 0xc5, 0x70, 0x7b, 0x03, 0xb9, 0x92, 0xb1,
4016
-	0x5f, 0xa3, 0xde, 0x48, 0x07, 0xaa, 0x35, 0x7f, 0x17, 0x96, 0x22, 0xcd, 0x5c, 0x44, 0x3a, 0xa3,
4017
-	0xac, 0x79, 0xac, 0x7e, 0x35, 0x03, 0x32, 0x55, 0x79, 0xa4, 0x17, 0x48, 0xae, 0x5c, 0xd6, 0x7d,
4018
-	0x24, 0x57, 0x2e, 0x6d, 0x2c, 0x52, 0x28, 0x8f, 0xb4, 0xfc, 0xc8, 0x95, 0xcb, 0x7a, 0x8b, 0xe4,
4019
-	0xca, 0xe5, 0xfd, 0x43, 0x09, 0xca, 0x7f, 0x9a, 0x8b, 0xb4, 0x15, 0x89, 0x0e, 0x10, 0xd2, 0xcc,
4020
-	0xdc, 0x2a, 0xc2, 0x2d, 0x69, 0x8d, 0xd9, 0x5a, 0xa2, 0x0e, 0x7a, 0x2c, 0x27, 0x27, 0x06, 0x7d,
4021
-	0xb4, 0x05, 0x21, 0x31, 0xe8, 0xe3, 0xfd, 0x04, 0xea, 0xa0, 0x17, 0xb5, 0xef, 0xe4, 0xa0, 0x8f,
4022
-	0x15, 0xec, 0x93, 0x83, 0x3e, 0x5e, 0x46, 0x4f, 0x0d, 0x7a, 0xb1, 0x60, 0x45, 0xd0, 0xc7, 0xd6,
4023
-	0x7c, 0x35, 0x03, 0x32, 0x63, 0xdc, 0x29, 0x95, 0xcb, 0x7a, 0x3e, 0x54, 0x71, 0x97, 0x51, 0x39,
4024
-	0xf7, 0x33, 0x16, 0xff, 0x12, 0xfd, 0x1c, 0x2d, 0xab, 0x26, 0xfa, 0x39, 0x56, 0x79, 0x4c, 0xf1,
4025
-	0xb3, 0xa8, 0x4b, 0x27, 0xfb, 0x39, 0x56, 0x4c, 0x4f, 0xf6, 0x73, 0xbc, 0xc4, 0x9d, 0xca, 0x2f,
4026
-	0x62, 0xc1, 0x0a, 0x7e, 0x89, 0xad, 0xf9, 0x6a, 0x06, 0x64, 0x6a, 0xb2, 0xf4, 0x2b, 0xa2, 0xf2,
4027
-	0x64, 0x19, 0xaf, 0xb7, 0xd6, 0x2f, 0xa5, 0xa0, 0x52, 0xf7, 0x39, 0x5c, 0x7e, 0x94, 0xef, 0xb3,
4028
-	0xa4, 0xb4, 0x5a, 0x6f, 0xa4, 0x03, 0xd5, 0x9a, 0x87, 0x50, 0x0d, 0x15, 0xd1, 0xc8, 0xe5, 0x6c,
4029
-	0x75, 0xbf, 0xfa, 0x95, 0x54, 0x5c, 0xea, 0x82, 0xc3, 0x35, 0x32, 0xf9, 0x82, 0x25, 0x05, 0xb9,
4030
-	0x7a, 0x23, 0x1d, 0x98, 0xaa, 0x39, 0x5c, 0x0f, 0x93, 0x6b, 0x96, 0xd4, 0xdc, 0xea, 0x8d, 0x74,
4031
-	0x60, 0x96, 0xa8, 0xe2, 0x37, 0xea, 0x89, 0x51, 0x15, 0xb9, 0xb2, 0x4f, 0x8c, 0xaa, 0xd8, 0xb5,
4032
-	0x7c, 0x5a, 0x54, 0xa1, 0x4e, 0x45, 0x54, 0x45, 0xd5, 0x36, 0xd2, 0x81, 0x99, 0xa2, 0x0a, 0xab,
4033
-	0x2c, 0xc9, 0x51, 0x15, 0x2d, 0x0c, 0x25, 0x47, 0x55, 0xac, 0x5c, 0x93, 0x1a, 0x55, 0xaa, 0x05,
4034
-	0x4b, 0x2a, 0x36, 0xaa, 0xa8, 0xca, 0xbc, 0xd5, 0xe1, 0x82, 0x89, 0x2a, 0xaa, 0x32, 0x68, 0x96,
4035
-	0xd6, 0x5e, 0x92, 0x35, 0x87, 0xeb, 0x00, 0x72, 0xcd, 0x92, 0xa2, 0x83, 0x5c, 0xb3, 0xac, 0xa4,
4036
-	0x90, 0xa4, 0xf9, 0x87, 0x39, 0x58, 0x89, 0x95, 0x63, 0xc8, 0xb5, 0xe4, 0x8d, 0x1c, 0x31, 0xe0,
4037
-	0xff, 0x33, 0x61, 0xd3, 0x6d, 0x88, 0x15, 0x5b, 0xe4, 0x36, 0xc8, 0xeb, 0x3b, 0x72, 0x1b, 0x92,
4038
-	0xaa, 0x37, 0xc9, 0xc1, 0x1e, 0xba, 0x3a, 0x26, 0x49, 0x29, 0x37, 0x76, 0x45, 0x5d, 0xbf, 0x92,
4039
-	0x8a, 0x53, 0xab, 0xfd, 0x3e, 0x2c, 0x47, 0x2f, 0xd3, 0x89, 0x22, 0xf1, 0xc5, 0x95, 0x5f, 0xcb,
4040
-	0x02, 0x4d, 0xcd, 0xd0, 0x91, 0xeb, 0x55, 0xd2, 0xc8, 0x7a, 0x53, 0x2c, 0xcf, 0xd0, 0xd2, 0xbb,
4041
-	0x5a, 0xc5, 0xe2, 0xa3, 0x75, 0x20, 0xa2, 0x38, 0xdd, 0x65, 0x5a, 0xbc, 0xbc, 0xac, 0xa4, 0xd0,
4042
-	0x1f, 0xad, 0xf4, 0x10, 0xc5, 0x01, 0x2f, 0x93, 0xfe, 0x84, 0xc2, 0x51, 0x1a, 0xd3, 0xf1, 0x1b,
4043
-	0x22, 0x15, 0xd3, 0x45, 0xee, 0xa6, 0x54, 0x4c, 0x17, 0xbd, 0x6c, 0x52, 0x67, 0x31, 0x54, 0x9b,
4044
-	0x94, 0xc5, 0xa2, 0x3a, 0x2f, 0xa5, 0xa0, 0x32, 0x66, 0x31, 0xd5, 0x52, 0x25, 0x77, 0xce, 0xaa,
4045
-	0x2c, 0x96, 0x4d, 0x33, 0x66, 0x31, 0xbc, 0x2b, 0x4c, 0xce, 0x62, 0xd1, 0x0b, 0xd1, 0xe4, 0x2c,
4046
-	0x16, 0xbb, 0x74, 0x4c, 0xcd, 0x25, 0xaa, 0x05, 0x4b, 0xee, 0x1d, 0x55, 0xb9, 0x24, 0xd3, 0x82,
4047
-	0xb7, 0x9e, 0xfb, 0xf8, 0xb3, 0xf5, 0xb9, 0x4f, 0x3f, 0x5b, 0x9f, 0xfb, 0xc1, 0xc9, 0x7a, 0xee,
4048
-	0xe3, 0x93, 0xf5, 0xdc, 0x27, 0x27, 0xeb, 0xb9, 0x7f, 0x9e, 0xac, 0xe7, 0x7e, 0xf6, 0xf9, 0xfa,
4049
-	0xdc, 0x27, 0x9f, 0xaf, 0xcf, 0x7d, 0xfa, 0xf9, 0xfa, 0xdc, 0xde, 0x02, 0x2b, 0xee, 0xbd, 0xf8,
4050
-	0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x56, 0xde, 0x67, 0x4f, 0xb3, 0x3f, 0x00, 0x00,
3862
+	// 3029 bytes of a gzipped FileDescriptorProto
3863
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5a, 0xcd, 0x6f, 0x24, 0x47,
3864
+	0x15, 0xf7, 0x8c, 0xc7, 0x9e, 0x99, 0x37, 0xfe, 0xda, 0x5a, 0xef, 0xc6, 0x99, 0x04, 0x7b, 0xd5,
3865
+	0x9b, 0xdd, 0xf5, 0x2e, 0xcb, 0x38, 0x71, 0x08, 0x59, 0xf2, 0x01, 0xac, 0xd7, 0x9b, 0xcd, 0x64,
3866
+	0x93, 0xdd, 0xa8, 0xbd, 0x59, 0xc1, 0x01, 0x59, 0xe3, 0x99, 0x5a, 0xa7, 0xe3, 0x71, 0xf7, 0xd0,
3867
+	0xdd, 0xb3, 0x89, 0x85, 0x40, 0x7c, 0x24, 0x47, 0x24, 0x2e, 0x88, 0x88, 0x03, 0x12, 0x27, 0x24,
3868
+	0x90, 0x10, 0xe2, 0x80, 0x38, 0xf0, 0x07, 0x44, 0x9c, 0x72, 0xcc, 0x05, 0x43, 0x1c, 0x21, 0x71,
3869
+	0xe2, 0x5f, 0x00, 0x55, 0xd5, 0xab, 0xfe, 0x9a, 0xea, 0xea, 0x9e, 0x0f, 0xc9, 0x9c, 0xec, 0xa9,
3870
+	0xfe, 0xbd, 0x8f, 0xaa, 0xf7, 0xfa, 0xf7, 0xaa, 0xeb, 0x15, 0x5c, 0xdf, 0xb7, 0xfc, 0x77, 0xfb,
3871
+	0x7b, 0x8d, 0xb6, 0x73, 0xb8, 0xd1, 0x71, 0xda, 0x07, 0xd4, 0xdd, 0xf0, 0xde, 0x6f, 0xb9, 0x87,
3872
+	0x07, 0x96, 0xbf, 0xd1, 0xea, 0x59, 0x1b, 0x6d, 0xc7, 0xf6, 0x5d, 0xa7, 0xdb, 0xe8, 0xb9, 0x8e,
3873
+	0xef, 0x10, 0x22, 0x20, 0x0d, 0x09, 0x69, 0x3c, 0x7e, 0xae, 0x7e, 0x2d, 0x43, 0x83, 0xd7, 0xa3,
3874
+	0x6d, 0x4f, 0xc8, 0xd7, 0xb3, 0xac, 0x39, 0x7b, 0xef, 0xd1, 0xb6, 0x2f, 0xd1, 0x59, 0x9a, 0xfd,
3875
+	0xa3, 0x1e, 0x95, 0xd8, 0xe5, 0x7d, 0x67, 0xdf, 0xe1, 0xff, 0x6e, 0xb0, 0xff, 0x70, 0xf4, 0xc9,
3876
+	0x7d, 0xc7, 0xd9, 0xef, 0xd2, 0x0d, 0xfe, 0x6b, 0xaf, 0xff, 0x68, 0xa3, 0x65, 0x1f, 0xe1, 0xa3,
3877
+	0x17, 0x35, 0xca, 0x03, 0x78, 0xaf, 0xdb, 0xdf, 0xb7, 0x6c, 0xfc, 0x23, 0x04, 0x8d, 0x17, 0x60,
3878
+	0xe1, 0x0e, 0xf5, 0xef, 0x39, 0x1d, 0x6a, 0xd2, 0xef, 0xf5, 0xa9, 0xe7, 0x93, 0x8b, 0x50, 0xb6,
3879
+	0x9d, 0x0e, 0xdd, 0xb5, 0x3a, 0x2b, 0x85, 0x0b, 0x85, 0xf5, 0xea, 0x16, 0x9c, 0x1c, 0xaf, 0xcd,
3880
+	0x32, 0x44, 0x73, 0xdb, 0x9c, 0x65, 0x8f, 0x9a, 0x1d, 0xe3, 0x9b, 0xb0, 0x18, 0x88, 0x79, 0x3d,
3881
+	0xc7, 0xf6, 0x28, 0xb9, 0x0e, 0x25, 0xf6, 0x90, 0x0b, 0xd5, 0x36, 0x57, 0x1a, 0x83, 0x8b, 0xdb,
3882
+	0xe0, 0x78, 0x8e, 0x32, 0x3e, 0x9c, 0x81, 0xa5, 0x37, 0x2d, 0x8f, 0xab, 0xf0, 0xa4, 0xe9, 0xd7,
3883
+	0xa0, 0xfc, 0xc8, 0xea, 0xfa, 0xd4, 0xf5, 0x50, 0xcb, 0x75, 0x95, 0x96, 0xa4, 0x58, 0xe3, 0x35,
3884
+	0x21, 0x63, 0x4a, 0xe1, 0xfa, 0x6f, 0x4b, 0x50, 0xc6, 0x41, 0xb2, 0x0c, 0x33, 0x76, 0xeb, 0x90,
3885
+	0x32, 0x8d, 0xd3, 0xeb, 0x55, 0x53, 0xfc, 0x20, 0x1b, 0x50, 0xb3, 0x3a, 0xbb, 0x3d, 0x97, 0x3e,
3886
+	0xb2, 0x3e, 0xa0, 0xde, 0x4a, 0x91, 0x3d, 0xdb, 0x5a, 0x38, 0x39, 0x5e, 0x83, 0xe6, 0xf6, 0xdb,
3887
+	0x38, 0x6a, 0x82, 0xd5, 0x91, 0xff, 0x93, 0xb7, 0x61, 0xb6, 0xdb, 0xda, 0xa3, 0x5d, 0x6f, 0x65,
3888
+	0xfa, 0xc2, 0xf4, 0x7a, 0x6d, 0xf3, 0xc6, 0x30, 0x9e, 0x35, 0xde, 0xe4, 0xa2, 0xb7, 0x6d, 0xdf,
3889
+	0x3d, 0x32, 0x51, 0x0f, 0xf9, 0x2e, 0xd4, 0xf8, 0x3a, 0xa3, 0xda, 0x32, 0x57, 0xfb, 0xca, 0x50,
3890
+	0x6a, 0xd9, 0x60, 0x54, 0x35, 0xd8, 0xc1, 0x00, 0x79, 0x0b, 0x6a, 0x87, 0xf4, 0x70, 0x8f, 0xba,
3891
+	0xde, 0xbb, 0x56, 0xcf, 0x5b, 0x29, 0x5d, 0x98, 0x5e, 0x5f, 0xd8, 0xbc, 0x92, 0x16, 0x95, 0x9d,
3892
+	0x1e, 0x6d, 0x37, 0xde, 0x0a, 0xf0, 0x5b, 0xc5, 0xa5, 0x29, 0x33, 0x2a, 0x4f, 0xbe, 0x06, 0x33,
3893
+	0xae, 0xd3, 0xa5, 0xde, 0xca, 0x0c, 0x57, 0xf4, 0x74, 0x6a, 0x78, 0x9d, 0x2e, 0xe5, 0xd2, 0x02,
3894
+	0x4e, 0x2e, 0xc2, 0x3c, 0x5b, 0xf1, 0x70, 0xa9, 0x67, 0x79, 0x18, 0xe6, 0xd8, 0xa0, 0x5c, 0xdc,
3895
+	0xfa, 0xd7, 0xa1, 0x16, 0x99, 0x06, 0x59, 0x82, 0xe9, 0x03, 0x7a, 0x24, 0xb2, 0xcf, 0x64, 0xff,
3896
+	0xb2, 0x20, 0x3e, 0x6e, 0x75, 0xfb, 0x74, 0xa5, 0xc8, 0xc7, 0xc4, 0x8f, 0x97, 0x8a, 0x37, 0x0a,
3897
+	0xf5, 0x57, 0x61, 0x31, 0xb1, 0x0a, 0xc3, 0x88, 0x1b, 0xb7, 0xe0, 0x4c, 0x64, 0x75, 0x31, 0x93,
3898
+	0x1b, 0x30, 0xc3, 0x16, 0x52, 0xa4, 0x8c, 0x2e, 0x95, 0x05, 0xcc, 0xf8, 0x5d, 0x01, 0xce, 0xbc,
3899
+	0xd3, 0xeb, 0xb4, 0x7c, 0x3a, 0xec, 0x7b, 0x44, 0xbe, 0x01, 0x73, 0x1c, 0xf4, 0x98, 0xba, 0x9e,
3900
+	0xe5, 0xd8, 0xdc, 0xc1, 0xda, 0xe6, 0x53, 0x2a, 0x8b, 0x0f, 0x05, 0xc4, 0xe4, 0x59, 0x83, 0x3f,
3901
+	0xc8, 0xb3, 0x50, 0x62, 0x8c, 0xb4, 0x32, 0xcd, 0xe5, 0x9e, 0xd6, 0x85, 0xd7, 0xe4, 0x48, 0x63,
3902
+	0x0b, 0x48, 0xd4, 0xd7, 0x91, 0x5e, 0xde, 0x7b, 0x70, 0xc6, 0xa4, 0x87, 0xce, 0xe3, 0xe1, 0xe7,
3903
+	0xbb, 0x0c, 0x33, 0x8f, 0x1c, 0xb7, 0x2d, 0x22, 0x51, 0x31, 0xc5, 0x0f, 0x63, 0x19, 0x48, 0x54,
3904
+	0x9f, 0xf0, 0x09, 0xa9, 0xe9, 0x41, 0xcb, 0x3b, 0x88, 0x98, 0xf0, 0x5b, 0xde, 0x41, 0xc2, 0x04,
3905
+	0x43, 0x30, 0x13, 0xec, 0x51, 0x40, 0x4d, 0x42, 0x2c, 0x9c, 0x1d, 0x7b, 0xa8, 0x9b, 0x1d, 0xc7,
3906
+	0x73, 0x94, 0x71, 0x43, 0xce, 0x6e, 0x68, 0xd3, 0xc1, 0x3c, 0xa2, 0xd6, 0x8d, 0xbf, 0x96, 0x04,
3907
+	0xd5, 0xb1, 0xc1, 0x11, 0xa8, 0x2e, 0x2a, 0x36, 0x48, 0x75, 0xff, 0x98, 0x3e, 0x3d, 0xaa, 0x53,
3908
+	0x79, 0xa6, 0xa4, 0xba, 0x0d, 0xa8, 0x79, 0xd4, 0x7d, 0x6c, 0xb5, 0x59, 0x76, 0x08, 0x2e, 0x42,
3909
+	0x17, 0x76, 0xc4, 0x70, 0x73, 0xdb, 0x33, 0x01, 0x21, 0xcd, 0x8e, 0x47, 0x2e, 0x43, 0x05, 0x73,
3910
+	0x49, 0x10, 0x4e, 0x75, 0xab, 0x76, 0x72, 0xbc, 0x56, 0x16, 0xc9, 0xe4, 0x99, 0x65, 0x91, 0x4d,
3911
+	0x1e, 0x79, 0x1d, 0x16, 0x3a, 0xd4, 0xb3, 0x5c, 0xda, 0xd9, 0xf5, 0xfc, 0x96, 0x8f, 0xf4, 0xb2,
3912
+	0xb0, 0xf9, 0xa5, 0xb4, 0x10, 0xef, 0x30, 0x14, 0xe7, 0xa7, 0x79, 0x14, 0xe4, 0x23, 0x0a, 0x9e,
3913
+	0x2a, 0x0f, 0xf2, 0x14, 0xa9, 0x43, 0xc5, 0xed, 0xdb, 0xbe, 0xc5, 0xd6, 0xb8, 0xca, 0x9f, 0x07,
3914
+	0xbf, 0xc9, 0xd3, 0x00, 0xfd, 0xde, 0xae, 0xef, 0xec, 0xb2, 0x77, 0x6b, 0xa5, 0xc2, 0xd3, 0xbb,
3915
+	0xd2, 0xef, 0x3d, 0x70, 0xb6, 0x5b, 0x3e, 0x1d, 0x83, 0xe1, 0x24, 0x45, 0xe1, 0x62, 0x87, 0x14,
3916
+	0xc5, 0x72, 0x4e, 0x4b, 0x51, 0x3c, 0x09, 0x05, 0xcc, 0xb8, 0x0b, 0xcb, 0xb7, 0x5c, 0xda, 0xf2,
3917
+	0x29, 0x2e, 0xb8, 0x4c, 0xc3, 0xe7, 0x91, 0x3f, 0x44, 0x0e, 0xae, 0xa9, 0xd4, 0xa0, 0x44, 0x84,
3918
+	0x42, 0xee, 0xc1, 0xb9, 0x84, 0x32, 0xf4, 0xea, 0x05, 0x28, 0x63, 0x10, 0x51, 0xe1, 0x53, 0x1a,
3919
+	0x85, 0xa6, 0xc4, 0x1a, 0xef, 0xc1, 0x99, 0x3b, 0xd4, 0x4f, 0x78, 0x76, 0x1d, 0x20, 0xcc, 0x19,
3920
+	0x7c, 0xe7, 0xe6, 0x4f, 0x8e, 0xd7, 0xaa, 0x41, 0xca, 0x98, 0xd5, 0x20, 0x63, 0xc8, 0x15, 0x58,
3921
+	0xb4, 0x6c, 0x8f, 0xba, 0xfe, 0x6e, 0x87, 0x3e, 0x6a, 0xf5, 0xbb, 0xbe, 0x87, 0x0c, 0xb3, 0x20,
3922
+	0x86, 0xb7, 0x71, 0xd4, 0xb8, 0x0b, 0x24, 0x6a, 0x6b, 0x3c, 0xc7, 0xff, 0x54, 0x84, 0x65, 0x41,
3923
+	0xa6, 0x63, 0x39, 0xbf, 0x0d, 0x8b, 0x12, 0x3d, 0x44, 0x1d, 0x58, 0x40, 0x19, 0x59, 0x0a, 0x9e,
3924
+	0x8f, 0x95, 0x82, 0x7c, 0xa1, 0x24, 0x6f, 0x41, 0xc5, 0x75, 0xba, 0xdd, 0xbd, 0x56, 0xfb, 0x60,
3925
+	0xa5, 0x74, 0xa1, 0xb0, 0xbe, 0xb0, 0xf9, 0x9c, 0x4a, 0x50, 0x35, 0xc9, 0x86, 0x89, 0x82, 0x66,
3926
+	0xa0, 0xc2, 0x30, 0xa0, 0x22, 0x47, 0x49, 0x05, 0x4a, 0xf7, 0xee, 0xdf, 0xbb, 0xbd, 0x34, 0x45,
3927
+	0xe6, 0xa0, 0xf2, 0xb6, 0x79, 0xfb, 0x61, 0xf3, 0xfe, 0x3b, 0x3b, 0x4b, 0x05, 0x96, 0x3d, 0x09,
3928
+	0x75, 0xe3, 0x05, 0x61, 0x1b, 0x96, 0x05, 0xe9, 0x8e, 0x13, 0x03, 0xe3, 0x09, 0x38, 0x97, 0xd0,
3929
+	0x82, 0xec, 0xfd, 0xe1, 0x34, 0x9c, 0x65, 0xef, 0x1f, 0x8e, 0x07, 0x04, 0xde, 0x4c, 0x12, 0xf8,
3930
+	0x46, 0x1a, 0x4d, 0x26, 0x24, 0x07, 0x39, 0xfc, 0x37, 0xc5, 0x89, 0x73, 0xf8, 0x4e, 0x82, 0xc3,
3931
+	0x5f, 0x1e, 0xd2, 0x39, 0x25, 0x8d, 0x0f, 0x70, 0x64, 0x29, 0x83, 0x23, 0x67, 0xe2, 0x1c, 0x39,
3932
+	0x0e, 0x0b, 0xde, 0x87, 0xe5, 0xb8, 0xbb, 0x98, 0x34, 0x2f, 0x42, 0x05, 0x83, 0x28, 0xb9, 0x50,
3933
+	0x9b, 0x35, 0x01, 0xd8, 0xb8, 0x01, 0xf5, 0x88, 0x42, 0x56, 0x05, 0xfa, 0x5e, 0x18, 0xdd, 0x7a,
3934
+	0x42, 0x6d, 0x35, 0x22, 0xf9, 0xfb, 0x22, 0x3c, 0xa5, 0x14, 0x45, 0x97, 0xbe, 0x03, 0x15, 0x0f,
3935
+	0xc7, 0xd0, 0xa5, 0x57, 0x33, 0x56, 0x3f, 0xa9, 0xa2, 0x11, 0x1b, 0x37, 0x03, 0x75, 0xf5, 0x3f,
3936
+	0x16, 0x60, 0x3e, 0xf6, 0x6c, 0x48, 0xa6, 0xb9, 0x08, 0xb2, 0xec, 0xed, 0x8a, 0xf2, 0xc1, 0xd6,
3937
+	0xb9, 0x64, 0xce, 0xe1, 0x20, 0xaf, 0x31, 0x0c, 0xe4, 0xf6, 0x6d, 0xdb, 0xb2, 0xf7, 0x11, 0x34,
3938
+	0x2d, 0x40, 0x38, 0x28, 0x40, 0x57, 0x60, 0xb1, 0xed, 0x1c, 0xf6, 0xba, 0xd4, 0x0f, 0x74, 0x95,
3939
+	0x38, 0x6c, 0x21, 0x18, 0x7e, 0x10, 0xaf, 0x3c, 0xf7, 0xa8, 0xff, 0xbe, 0xe3, 0x1e, 0x0c, 0x51,
3940
+	0x79, 0x50, 0x42, 0x55, 0x79, 0x02, 0x65, 0x21, 0x77, 0xd8, 0x62, 0x48, 0xc7, 0x1d, 0x52, 0x4a,
3941
+	0x62, 0x8d, 0x8f, 0x0a, 0xbc, 0xf4, 0x24, 0x5c, 0x23, 0x50, 0x62, 0x29, 0x8d, 0x89, 0xc9, 0xff,
3942
+	0x67, 0xeb, 0x8c, 0x42, 0x6c, 0x9d, 0x8b, 0xe1, 0x3a, 0xa3, 0x2c, 0x5b, 0x67, 0x04, 0x34, 0x3b,
3943
+	0xa4, 0x01, 0xe5, 0x56, 0x8f, 0x91, 0x5c, 0x0b, 0xe9, 0x78, 0xb9, 0x21, 0xbe, 0xdd, 0x1b, 0xf2,
3944
+	0x63, 0xbc, 0x71, 0xd3, 0x3e, 0x32, 0x25, 0x08, 0xab, 0xd2, 0x84, 0x26, 0xf5, 0x6d, 0x49, 0x88,
3945
+	0x93, 0x9e, 0x56, 0x48, 0x92, 0x09, 0x4f, 0x8d, 0x8f, 0x91, 0x24, 0x71, 0x7c, 0x04, 0x92, 0x4c,
3946
+	0x48, 0x0e, 0x90, 0x64, 0x74, 0x49, 0x8b, 0x39, 0x96, 0xb4, 0xfe, 0xd1, 0x29, 0x92, 0x6a, 0xca,
3947
+	0x64, 0x46, 0x26, 0xd5, 0x09, 0x10, 0x67, 0xe8, 0x52, 0x48, 0x9c, 0x18, 0x58, 0x2d, 0x71, 0xca,
3948
+	0x48, 0x07, 0x60, 0xe3, 0x26, 0x7f, 0x65, 0x6e, 0x75, 0xfb, 0x9e, 0x4f, 0xdd, 0x48, 0xb1, 0x6d,
3949
+	0x8b, 0x91, 0x04, 0x0d, 0x21, 0x8e, 0xe5, 0x11, 0x02, 0x9a, 0x1d, 0x4c, 0xf7, 0x40, 0x45, 0x98,
3950
+	0xee, 0x08, 0xd1, 0xa5, 0xbb, 0x94, 0x92, 0x58, 0xe3, 0xdf, 0x45, 0x91, 0x7b, 0xf8, 0x60, 0x84,
3951
+	0xdc, 0x4b, 0x48, 0x0e, 0x16, 0xe8, 0xd3, 0xcc, 0xa5, 0x14, 0xe7, 0x4e, 0x33, 0x97, 0x42, 0x97,
3952
+	0xc2, 0x5c, 0xc2, 0x68, 0x68, 0x73, 0x49, 0x86, 0x2e, 0x00, 0x1b, 0xbf, 0x28, 0x40, 0xed, 0x2e,
3953
+	0x3d, 0x32, 0x1d, 0xbf, 0xe5, 0xb3, 0x3d, 0xec, 0x35, 0x38, 0xc3, 0x92, 0x8c, 0xba, 0xbb, 0xef,
3954
+	0x39, 0x96, 0xbd, 0xeb, 0x3b, 0x07, 0xd4, 0xe6, 0xae, 0x55, 0xcc, 0x45, 0xf1, 0xe0, 0x0d, 0xc7,
3955
+	0xb2, 0x1f, 0xb0, 0x61, 0x72, 0x1d, 0xc8, 0x61, 0xcb, 0x6e, 0xed, 0xc7, 0xc1, 0x62, 0xd7, 0xbf,
3956
+	0x84, 0x4f, 0x94, 0xe8, 0xbe, 0xdd, 0x75, 0xda, 0x07, 0xbb, 0x6c, 0xd6, 0xd3, 0x31, 0xf4, 0x3b,
3957
+	0xfc, 0xc1, 0x5d, 0x7a, 0x64, 0xfc, 0x24, 0xd8, 0xd8, 0x8f, 0x93, 0xe7, 0x6c, 0x63, 0x2f, 0xd1,
3958
+	0xc3, 0x6c, 0xec, 0x51, 0x66, 0x88, 0x8d, 0x3d, 0x5a, 0x8f, 0x6c, 0xec, 0x6f, 0xb2, 0x8d, 0xbd,
3959
+	0x58, 0x55, 0x5e, 0x98, 0x53, 0x04, 0x23, 0x8b, 0xbf, 0x55, 0xfa, 0xe4, 0x78, 0x6d, 0xca, 0x0c,
3960
+	0xc4, 0xc2, 0x8d, 0xfa, 0x84, 0x5e, 0xd4, 0x57, 0x61, 0x89, 0x7f, 0x7a, 0xb5, 0x5d, 0xea, 0xcb,
3961
+	0xf5, 0xbc, 0x0a, 0x55, 0x8f, 0x0f, 0x84, 0xcb, 0x39, 0x77, 0x72, 0xbc, 0x56, 0x11, 0xa8, 0xe6,
3962
+	0x36, 0xdb, 0x76, 0xf1, 0xff, 0x3a, 0xc6, 0x1d, 0xfc, 0x4a, 0x14, 0xe2, 0xe8, 0xca, 0x26, 0xcc,
3963
+	0x0a, 0x00, 0x7a, 0x52, 0x57, 0x6f, 0xfe, 0xb8, 0x0c, 0x22, 0x8d, 0xbf, 0x14, 0xe0, 0xac, 0xfc,
3964
+	0x02, 0x19, 0xcd, 0x17, 0xb2, 0x05, 0x0b, 0x08, 0x1d, 0x22, 0xae, 0xf3, 0x42, 0x44, 0x86, 0x75,
3965
+	0x33, 0x16, 0xd6, 0xd5, 0x74, 0xc7, 0x23, 0xfb, 0x9f, 0x37, 0xc2, 0xef, 0xcd, 0xb1, 0x97, 0xe1,
3966
+	0x5f, 0x45, 0x20, 0x62, 0x0f, 0xca, 0x7e, 0x06, 0xb4, 0xf9, 0x7a, 0x92, 0x36, 0x1b, 0xe9, 0x9b,
3967
+	0xd7, 0xa8, 0xe0, 0x20, 0x6b, 0x7e, 0x38, 0x79, 0xd6, 0x34, 0x13, 0xac, 0xf9, 0xd2, 0x70, 0xbe,
3968
+	0x9d, 0x0a, 0x69, 0xde, 0x95, 0xdf, 0x8f, 0xe8, 0x11, 0x86, 0xec, 0xab, 0xec, 0x6b, 0x97, 0x0f,
3969
+	0x21, 0x65, 0xea, 0x62, 0x26, 0xa1, 0x46, 0x13, 0xce, 0xca, 0xa3, 0x97, 0x68, 0xea, 0x6e, 0xc6,
3970
+	0x36, 0xd3, 0xb9, 0x73, 0x29, 0xae, 0x6a, 0x8c, 0x5c, 0xfa, 0x16, 0x9c, 0x95, 0x5f, 0xcf, 0x23,
3971
+	0xbe, 0xdd, 0xe7, 0xc3, 0xaf, 0xf8, 0xa8, 0x37, 0x48, 0x1a, 0xb7, 0x1c, 0xfb, 0x91, 0xb5, 0x1f,
3972
+	0x51, 0xdb, 0xe6, 0x03, 0x09, 0xb5, 0x02, 0xc5, 0xd4, 0x8a, 0xc7, 0x01, 0x69, 0x48, 0xf1, 0x70,
3973
+	0x86, 0x02, 0xa0, 0x9b, 0x21, 0xca, 0x20, 0x32, 0x42, 0x1a, 0xa3, 0xfa, 0xc2, 0x48, 0x03, 0xa1,
3974
+	0xc3, 0x90, 0x86, 0x10, 0x19, 0x82, 0x34, 0x84, 0x65, 0x15, 0x69, 0x4c, 0x60, 0x19, 0x24, 0x69,
3975
+	0x88, 0xe1, 0x11, 0x48, 0x23, 0x2e, 0xf8, 0xff, 0x45, 0x1a, 0x6a, 0xdf, 0x4e, 0x93, 0x34, 0x02,
3976
+	0x8f, 0x42, 0xd2, 0x10, 0x81, 0xd0, 0x92, 0x06, 0xc6, 0x4c, 0x42, 0x43, 0xd2, 0x88, 0xa7, 0x6e,
3977
+	0x0e, 0xd2, 0x50, 0xe5, 0x52, 0x5c, 0xd5, 0x18, 0xb9, 0x14, 0x90, 0xc6, 0xc8, 0x6f, 0x77, 0x40,
3978
+	0x1a, 0x71, 0x6f, 0x8c, 0x1f, 0xc0, 0x79, 0xe1, 0xe5, 0xed, 0x0f, 0x7c, 0x6a, 0xf3, 0xf7, 0x08,
3979
+	0x95, 0xdf, 0x84, 0x5a, 0xcb, 0xb6, 0x71, 0x87, 0xe3, 0xe9, 0x0e, 0x1f, 0x6e, 0x86, 0x30, 0x33,
3980
+	0x2a, 0x43, 0x2e, 0x40, 0xad, 0x43, 0xbd, 0xb6, 0x6b, 0xf5, 0x7c, 0xf9, 0x0e, 0x57, 0xcd, 0xe8,
3981
+	0x90, 0xf1, 0x10, 0x9e, 0x18, 0x30, 0x8f, 0xeb, 0xf4, 0x32, 0x54, 0xa9, 0x1c, 0x44, 0xeb, 0xca,
3982
+	0x5e, 0x45, 0x28, 0x19, 0xe2, 0x8d, 0x37, 0xe1, 0xbc, 0x98, 0xee, 0xc0, 0xb4, 0x36, 0x61, 0x2e,
3983
+	0x80, 0x85, 0xcb, 0xb6, 0x78, 0x72, 0xbc, 0x56, 0x0b, 0xb0, 0xcd, 0x6d, 0xb3, 0x16, 0x80, 0x9a,
3984
+	0x1d, 0xe3, 0x49, 0x78, 0x62, 0x40, 0x1b, 0xae, 0x5f, 0x13, 0xce, 0xde, 0xa1, 0xfe, 0x44, 0xac,
3985
+	0xec, 0xc0, 0x72, 0x5c, 0xd5, 0x24, 0x16, 0xe2, 0xd7, 0x05, 0x79, 0x0e, 0x64, 0x52, 0xcf, 0xe9,
3986
+	0xbb, 0xe1, 0xa1, 0xef, 0x04, 0xe2, 0x4b, 0xa0, 0x74, 0x60, 0xd9, 0x78, 0x18, 0x62, 0xf2, 0xff,
3987
+	0x49, 0x03, 0xca, 0xbd, 0xd6, 0x51, 0xd7, 0x69, 0x75, 0xf4, 0xe7, 0x39, 0x08, 0x32, 0x4c, 0x99,
3988
+	0x80, 0xa1, 0x7f, 0x38, 0xef, 0x1b, 0x50, 0x71, 0x71, 0x0c, 0xbd, 0x53, 0x36, 0x6d, 0x03, 0xb9,
3989
+	0x00, 0x6d, 0xbc, 0x2e, 0x0f, 0x5f, 0x92, 0x73, 0xde, 0x80, 0x9a, 0x04, 0x85, 0x51, 0xe1, 0x84,
3990
+	0x28, 0x91, 0xcd, 0x6d, 0x13, 0x24, 0xa4, 0xd9, 0x31, 0x56, 0x64, 0x1e, 0x25, 0xbd, 0x33, 0x7e,
3991
+	0x5a, 0x94, 0x7b, 0xfe, 0x71, 0x8d, 0x90, 0xd7, 0x60, 0x29, 0x10, 0x18, 0xa2, 0xde, 0x2d, 0x4a,
3992
+	0x21, 0x59, 0xf1, 0x12, 0x11, 0x9d, 0x1e, 0x21, 0xa2, 0x91, 0xe8, 0x95, 0x72, 0x46, 0x2f, 0xb9,
3993
+	0x08, 0x63, 0x47, 0xef, 0x36, 0x3f, 0xf2, 0x18, 0x3b, 0x74, 0xf7, 0xf9, 0x9b, 0x39, 0x41, 0xbf,
3994
+	0xfe, 0x5b, 0x14, 0xdf, 0xf4, 0xf2, 0x51, 0x50, 0xd2, 0xdf, 0x48, 0x96, 0xf4, 0x67, 0xd3, 0xca,
3995
+	0x66, 0x52, 0x74, 0xb0, 0xa8, 0xff, 0x6a, 0xf2, 0x45, 0xfd, 0x41, 0xa2, 0xa8, 0xbf, 0x32, 0xac,
3996
+	0x77, 0xa3, 0x77, 0x38, 0x24, 0x41, 0xcc, 0x84, 0x04, 0x31, 0x4e, 0xa9, 0xdf, 0x81, 0x73, 0x09,
3997
+	0x3f, 0x31, 0xa8, 0x2f, 0x41, 0x55, 0x86, 0x49, 0x96, 0x7b, 0x7d, 0x54, 0x43, 0x78, 0x58, 0xf2,
3998
+	0x1f, 0x3a, 0xdd, 0xfe, 0x21, 0x1d, 0xa2, 0xe4, 0x0b, 0x01, 0x55, 0xc9, 0x97, 0xaa, 0xc2, 0x92,
3999
+	0xff, 0x98, 0x8f, 0xe8, 0x4a, 0x3e, 0xca, 0x20, 0x12, 0x77, 0xf3, 0x71, 0x9f, 0xae, 0x42, 0x55,
4000
+	0x3c, 0x4d, 0xd4, 0x7b, 0x81, 0x62, 0xf5, 0x5e, 0x3c, 0x0e, 0x76, 0xf3, 0x13, 0xf0, 0x23, 0xdc,
4001
+	0xcd, 0x8f, 0xea, 0x0b, 0xdb, 0xcd, 0x23, 0x74, 0x98, 0xdd, 0xbc, 0x10, 0x19, 0x62, 0x37, 0xaf,
4002
+	0x0a, 0x47, 0xdc, 0xf3, 0x31, 0x96, 0xe1, 0x97, 0xd3, 0x62, 0x37, 0x2f, 0x86, 0x47, 0xd8, 0xcd,
4003
+	0xc7, 0x05, 0x07, 0x5f, 0xfc, 0x3f, 0x9f, 0xe2, 0x6e, 0x5e, 0xed, 0xdb, 0xe8, 0xaf, 0xfd, 0x79,
4004
+	0x98, 0xdd, 0x77, 0x9d, 0x7e, 0x4f, 0xb6, 0x35, 0xf1, 0x17, 0x59, 0x81, 0x72, 0xc7, 0xb5, 0x58,
4005
+	0x12, 0xe0, 0xdd, 0x36, 0xf9, 0x73, 0x02, 0xfb, 0xff, 0x60, 0x0e, 0xe1, 0xfe, 0x5f, 0x84, 0x4e,
4006
+	0xbb, 0xff, 0xc7, 0x28, 0x4b, 0xa8, 0xf1, 0x50, 0x6e, 0xb4, 0x47, 0x4e, 0x76, 0xf5, 0xb5, 0xad,
4007
+	0x60, 0xfb, 0x1d, 0x4f, 0xc5, 0xcd, 0xbf, 0xaf, 0x43, 0xf9, 0x96, 0xb8, 0x69, 0x4b, 0x2c, 0x28,
4008
+	0xe3, 0x45, 0x51, 0x62, 0xa8, 0x7c, 0x8d, 0x5f, 0x3e, 0xad, 0x5f, 0xd4, 0x62, 0x70, 0x97, 0x72,
4009
+	0xee, 0x6f, 0x7f, 0xf8, 0xcf, 0xc7, 0xc5, 0x45, 0x98, 0xe7, 0xa0, 0xaf, 0xe0, 0xe9, 0x2d, 0x71,
4010
+	0xa0, 0x1a, 0xdc, 0xe5, 0x23, 0xcf, 0xe4, 0xb9, 0x48, 0x59, 0xbf, 0x94, 0x81, 0xd2, 0x1b, 0x74,
4011
+	0x01, 0xc2, 0xab, 0x74, 0xe4, 0x52, 0xfa, 0xc5, 0x89, 0xe8, 0x0c, 0x2f, 0x67, 0xc1, 0x32, 0x6d,
4012
+	0x86, 0x57, 0xe5, 0xd4, 0x36, 0x07, 0xae, 0xe6, 0xa9, 0x6d, 0x2a, 0x6e, 0xdc, 0xa5, 0xd8, 0x14,
4013
+	0x31, 0x7c, 0xd0, 0xf2, 0x0e, 0x52, 0x63, 0x18, 0xb9, 0x2a, 0x97, 0x1a, 0xc3, 0xd8, 0xa5, 0x38,
4014
+	0x7d, 0x0c, 0x45, 0x8f, 0xf9, 0x99, 0x3c, 0x17, 0xcf, 0xd2, 0x63, 0x18, 0xbb, 0x31, 0x95, 0xb9,
4015
+	0x9e, 0x7c, 0x7a, 0x9a, 0xf5, 0x8c, 0xce, 0xf0, 0x72, 0x16, 0x2c, 0xd3, 0x66, 0x78, 0x07, 0x49,
4016
+	0x6d, 0x73, 0xe0, 0x3e, 0x94, 0xda, 0xe6, 0xe0, 0x55, 0xa6, 0x34, 0x9b, 0x1f, 0xc0, 0x5c, 0xf4,
4017
+	0xfe, 0x04, 0xb9, 0x92, 0xf3, 0x42, 0x48, 0x7d, 0x3d, 0x1b, 0xa8, 0xb7, 0xfc, 0x7d, 0x98, 0x8f,
4018
+	0xdd, 0x16, 0x23, 0x4a, 0x8d, 0xaa, 0xdb, 0x69, 0xf5, 0xab, 0x39, 0x90, 0x99, 0xc6, 0x63, 0x97,
4019
+	0x8d, 0xd4, 0xc6, 0x55, 0xd7, 0x9b, 0xd4, 0xc6, 0x95, 0x37, 0x97, 0x34, 0xc6, 0x63, 0x77, 0x8a,
4020
+	0xd4, 0xc6, 0x55, 0x97, 0x97, 0xd4, 0xc6, 0xd5, 0x17, 0x94, 0x52, 0x8c, 0xff, 0xac, 0x10, 0xbb,
4021
+	0xb7, 0x24, 0xaf, 0x98, 0x90, 0x46, 0xee, 0xbb, 0x28, 0xc2, 0x93, 0x8d, 0x21, 0xef, 0xae, 0xe8,
4022
+	0x93, 0x1e, 0xdb, 0xc9, 0xa9, 0x49, 0x1f, 0xbf, 0xb2, 0x90, 0x9a, 0xf4, 0xc9, 0xfb, 0x07, 0xfa,
4023
+	0xa4, 0x97, 0xbd, 0xef, 0xf4, 0xa4, 0x4f, 0x34, 0xec, 0xd3, 0x93, 0x3e, 0xd9, 0x46, 0xcf, 0x4c,
4024
+	0x7a, 0x39, 0x61, 0x4d, 0xd2, 0x27, 0xe6, 0x7c, 0x35, 0x07, 0x32, 0x67, 0xde, 0x69, 0x8d, 0xab,
4025
+	0xee, 0x88, 0xe8, 0xf2, 0x2e, 0xa7, 0x71, 0x11, 0x67, 0x6c, 0xfe, 0xa5, 0xc6, 0x39, 0xde, 0x56,
4026
+	0x4d, 0x8d, 0x73, 0xa2, 0xf3, 0x98, 0x11, 0x67, 0xd9, 0x97, 0x4e, 0x8f, 0x73, 0xa2, 0x99, 0x9e,
4027
+	0x1e, 0xe7, 0x64, 0x8b, 0x3b, 0x93, 0x5f, 0xe4, 0x84, 0x35, 0xfc, 0x92, 0x98, 0xf3, 0xd5, 0x1c,
4028
+	0xc8, 0xcc, 0x62, 0x19, 0x74, 0x44, 0xd5, 0xc5, 0x32, 0xd9, 0x6f, 0xad, 0x5f, 0xca, 0x40, 0x65,
4029
+	0xae, 0x73, 0xb4, 0xfd, 0xa8, 0x5e, 0x67, 0x45, 0x6b, 0xb5, 0xbe, 0x9e, 0x0d, 0xd4, 0x5b, 0xee,
4030
+	0x43, 0x2d, 0xd2, 0x44, 0x23, 0x97, 0xf3, 0xf5, 0xfd, 0xea, 0x57, 0x32, 0x71, 0x99, 0x13, 0x8e,
4031
+	0xf6, 0xc8, 0xd4, 0x13, 0x56, 0x34, 0xe4, 0xea, 0xeb, 0xd9, 0xc0, 0x4c, 0xcb, 0xd1, 0x7e, 0x98,
4032
+	0xda, 0xb2, 0xa2, 0xe7, 0x56, 0x5f, 0xcf, 0x06, 0xe6, 0xc9, 0x2a, 0x71, 0xa2, 0x9e, 0x9a, 0x55,
4033
+	0xb1, 0x23, 0xfb, 0xd4, 0xac, 0x4a, 0x1c, 0xcb, 0x67, 0x65, 0x15, 0xda, 0xd4, 0x64, 0x55, 0xdc,
4034
+	0xec, 0x7a, 0x36, 0x30, 0x57, 0x56, 0x61, 0x97, 0x25, 0x3d, 0xab, 0xe2, 0x8d, 0xa1, 0xf4, 0xac,
4035
+	0x4a, 0xb4, 0x6b, 0x32, 0xb3, 0x4a, 0x37, 0x61, 0x45, 0xc7, 0x46, 0x97, 0x55, 0xb9, 0x97, 0x3a,
4036
+	0xda, 0x30, 0xd1, 0x65, 0x55, 0x0e, 0xcb, 0xca, 0xde, 0x4b, 0xba, 0xe5, 0x68, 0x1f, 0x40, 0x6d,
4037
+	0x59, 0xd1, 0x74, 0x50, 0x5b, 0x56, 0xb5, 0x14, 0xd2, 0x2c, 0xff, 0xb8, 0x00, 0x8b, 0x89, 0x76,
4038
+	0x0c, 0xb9, 0x96, 0xbe, 0x90, 0x03, 0x0e, 0x7c, 0x39, 0x17, 0x36, 0xdb, 0x87, 0x44, 0xb3, 0x45,
4039
+	0xed, 0x83, 0xba, 0xbf, 0xa3, 0xf6, 0x21, 0xad, 0x7b, 0x93, 0x9e, 0xec, 0x91, 0xa3, 0x63, 0x92,
4040
+	0x56, 0x72, 0x13, 0x47, 0xd4, 0xf5, 0x2b, 0x99, 0x38, 0xbd, 0xd9, 0x1f, 0xc2, 0x42, 0xfc, 0x30,
4041
+	0x9d, 0x68, 0x0a, 0x5f, 0xd2, 0xf8, 0xb5, 0x3c, 0xd0, 0xcc, 0x0a, 0x1d, 0x3b, 0x5e, 0x25, 0xeb,
4042
+	0x79, 0x4f, 0x8a, 0xd5, 0x15, 0x5a, 0x79, 0x56, 0xab, 0x99, 0x7c, 0xbc, 0x0f, 0x44, 0x34, 0xbb,
4043
+	0xbb, 0x5c, 0x93, 0x57, 0xb7, 0x95, 0x34, 0xf6, 0xe3, 0x9d, 0x1e, 0xa2, 0xd9, 0xe0, 0xe5, 0xb2,
4044
+	0x9f, 0xd2, 0x38, 0xca, 0x62, 0x3a, 0x71, 0x42, 0xa4, 0x63, 0xba, 0xd8, 0xd9, 0x94, 0x8e, 0xe9,
4045
+	0xe2, 0x87, 0x4d, 0xfa, 0x2a, 0x86, 0x66, 0xd3, 0xaa, 0x58, 0xdc, 0xe6, 0xa5, 0x0c, 0x54, 0xce,
4046
+	0x2a, 0xa6, 0x9b, 0xaa, 0xe2, 0xcc, 0x59, 0x57, 0xc5, 0xf2, 0x59, 0xc6, 0x2a, 0x86, 0x67, 0x85,
4047
+	0xe9, 0x55, 0x2c, 0x7e, 0x20, 0x9a, 0x5e, 0xc5, 0x12, 0x87, 0x8e, 0x99, 0xb5, 0x44, 0x37, 0x61,
4048
+	0xc5, 0xb9, 0xa3, 0xae, 0x96, 0xe4, 0x9a, 0xf0, 0xd6, 0x33, 0x9f, 0x7c, 0xbe, 0x3a, 0xf5, 0xd9,
4049
+	0xe7, 0xab, 0x53, 0x3f, 0x3a, 0x59, 0x2d, 0x7c, 0x72, 0xb2, 0x5a, 0xf8, 0xf4, 0x64, 0xb5, 0xf0,
4050
+	0xcf, 0x93, 0xd5, 0xc2, 0xcf, 0xbf, 0x58, 0x9d, 0xfa, 0xf4, 0x8b, 0xd5, 0xa9, 0xcf, 0xbe, 0x58,
4051
+	0x9d, 0xda, 0x9b, 0xe5, 0xcd, 0xbd, 0xe7, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0x79, 0x77, 0x4d,
4052
+	0x1d, 0x14, 0x40, 0x00, 0x00,
4051 4053
 }
4052 4054
 
4053 4055
 type authenticatedWrapperControlServer struct {
... ...
@@ -5093,6 +5099,10 @@ func (m *GetNetworkRequest) CopyFrom(src interface{}) {
5093 5093
 
5094 5094
 	o := src.(*GetNetworkRequest)
5095 5095
 	*m = *o
5096
+	if o.Appdata != nil {
5097
+		m.Appdata = &types.Any{}
5098
+		github_com_moby_swarmkit_v2_api_deepcopy.Copy(m.Appdata, o.Appdata)
5099
+	}
5096 5100
 }
5097 5101
 
5098 5102
 func (m *GetNetworkResponse) Copy() *GetNetworkResponse {
... ...
@@ -5156,6 +5166,10 @@ func (m *ListNetworksRequest) CopyFrom(src interface{}) {
5156 5156
 		m.Filters = &ListNetworksRequest_Filters{}
5157 5157
 		github_com_moby_swarmkit_v2_api_deepcopy.Copy(m.Filters, o.Filters)
5158 5158
 	}
5159
+	if o.Appdata != nil {
5160
+		m.Appdata = &types.Any{}
5161
+		github_com_moby_swarmkit_v2_api_deepcopy.Copy(m.Appdata, o.Appdata)
5162
+	}
5159 5163
 }
5160 5164
 
5161 5165
 func (m *ListNetworksRequest_Filters) Copy() *ListNetworksRequest_Filters {
... ...
@@ -9505,6 +9519,18 @@ func (m *GetNetworkRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
9505 9505
 	_ = i
9506 9506
 	var l int
9507 9507
 	_ = l
9508
+	if m.Appdata != nil {
9509
+		{
9510
+			size, err := m.Appdata.MarshalToSizedBuffer(dAtA[:i])
9511
+			if err != nil {
9512
+				return 0, err
9513
+			}
9514
+			i -= size
9515
+			i = encodeVarintControl(dAtA, i, uint64(size))
9516
+		}
9517
+		i--
9518
+		dAtA[i] = 0x1a
9519
+	}
9508 9520
 	if len(m.NetworkID) > 0 {
9509 9521
 		i -= len(m.NetworkID)
9510 9522
 		copy(dAtA[i:], m.NetworkID)
... ...
@@ -9637,6 +9663,18 @@ func (m *ListNetworksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
9637 9637
 	_ = i
9638 9638
 	var l int
9639 9639
 	_ = l
9640
+	if m.Appdata != nil {
9641
+		{
9642
+			size, err := m.Appdata.MarshalToSizedBuffer(dAtA[:i])
9643
+			if err != nil {
9644
+				return 0, err
9645
+			}
9646
+			i -= size
9647
+			i = encodeVarintControl(dAtA, i, uint64(size))
9648
+		}
9649
+		i--
9650
+		dAtA[i] = 0x12
9651
+	}
9640 9652
 	if m.Filters != nil {
9641 9653
 		{
9642 9654
 			size, err := m.Filters.MarshalToSizedBuffer(dAtA[:i])
... ...
@@ -14216,6 +14254,10 @@ func (m *GetNetworkRequest) Size() (n int) {
14216 14216
 	if l > 0 {
14217 14217
 		n += 1 + l + sovControl(uint64(l))
14218 14218
 	}
14219
+	if m.Appdata != nil {
14220
+		l = m.Appdata.Size()
14221
+		n += 1 + l + sovControl(uint64(l))
14222
+	}
14219 14223
 	return n
14220 14224
 }
14221 14225
 
... ...
@@ -14268,6 +14310,10 @@ func (m *ListNetworksRequest) Size() (n int) {
14268 14268
 		l = m.Filters.Size()
14269 14269
 		n += 1 + l + sovControl(uint64(l))
14270 14270
 	}
14271
+	if m.Appdata != nil {
14272
+		l = m.Appdata.Size()
14273
+		n += 1 + l + sovControl(uint64(l))
14274
+	}
14271 14275
 	return n
14272 14276
 }
14273 14277
 
... ...
@@ -15675,6 +15721,7 @@ func (this *GetNetworkRequest) String() string {
15675 15675
 	s := strings.Join([]string{`&GetNetworkRequest{`,
15676 15676
 		`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
15677 15677
 		`NetworkID:` + fmt.Sprintf("%v", this.NetworkID) + `,`,
15678
+		`Appdata:` + strings.Replace(fmt.Sprintf("%v", this.Appdata), "Any", "types.Any", 1) + `,`,
15678 15679
 		`}`,
15679 15680
 	}, "")
15680 15681
 	return s
... ...
@@ -15715,6 +15762,7 @@ func (this *ListNetworksRequest) String() string {
15715 15715
 	}
15716 15716
 	s := strings.Join([]string{`&ListNetworksRequest{`,
15717 15717
 		`Filters:` + strings.Replace(fmt.Sprintf("%v", this.Filters), "ListNetworksRequest_Filters", "ListNetworksRequest_Filters", 1) + `,`,
15718
+		`Appdata:` + strings.Replace(fmt.Sprintf("%v", this.Appdata), "Any", "types.Any", 1) + `,`,
15718 15719
 		`}`,
15719 15720
 	}, "")
15720 15721
 	return s
... ...
@@ -20443,6 +20491,42 @@ func (m *GetNetworkRequest) Unmarshal(dAtA []byte) error {
20443 20443
 			}
20444 20444
 			m.NetworkID = string(dAtA[iNdEx:postIndex])
20445 20445
 			iNdEx = postIndex
20446
+		case 3:
20447
+			if wireType != 2 {
20448
+				return fmt.Errorf("proto: wrong wireType = %d for field Appdata", wireType)
20449
+			}
20450
+			var msglen int
20451
+			for shift := uint(0); ; shift += 7 {
20452
+				if shift >= 64 {
20453
+					return ErrIntOverflowControl
20454
+				}
20455
+				if iNdEx >= l {
20456
+					return io.ErrUnexpectedEOF
20457
+				}
20458
+				b := dAtA[iNdEx]
20459
+				iNdEx++
20460
+				msglen |= int(b&0x7F) << shift
20461
+				if b < 0x80 {
20462
+					break
20463
+				}
20464
+			}
20465
+			if msglen < 0 {
20466
+				return ErrInvalidLengthControl
20467
+			}
20468
+			postIndex := iNdEx + msglen
20469
+			if postIndex < 0 {
20470
+				return ErrInvalidLengthControl
20471
+			}
20472
+			if postIndex > l {
20473
+				return io.ErrUnexpectedEOF
20474
+			}
20475
+			if m.Appdata == nil {
20476
+				m.Appdata = &types.Any{}
20477
+			}
20478
+			if err := m.Appdata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
20479
+				return err
20480
+			}
20481
+			iNdEx = postIndex
20446 20482
 		default:
20447 20483
 			iNdEx = preIndex
20448 20484
 			skippy, err := skipControl(dAtA[iNdEx:])
... ...
@@ -20779,6 +20863,42 @@ func (m *ListNetworksRequest) Unmarshal(dAtA []byte) error {
20779 20779
 				return err
20780 20780
 			}
20781 20781
 			iNdEx = postIndex
20782
+		case 2:
20783
+			if wireType != 2 {
20784
+				return fmt.Errorf("proto: wrong wireType = %d for field Appdata", wireType)
20785
+			}
20786
+			var msglen int
20787
+			for shift := uint(0); ; shift += 7 {
20788
+				if shift >= 64 {
20789
+					return ErrIntOverflowControl
20790
+				}
20791
+				if iNdEx >= l {
20792
+					return io.ErrUnexpectedEOF
20793
+				}
20794
+				b := dAtA[iNdEx]
20795
+				iNdEx++
20796
+				msglen |= int(b&0x7F) << shift
20797
+				if b < 0x80 {
20798
+					break
20799
+				}
20800
+			}
20801
+			if msglen < 0 {
20802
+				return ErrInvalidLengthControl
20803
+			}
20804
+			postIndex := iNdEx + msglen
20805
+			if postIndex < 0 {
20806
+				return ErrInvalidLengthControl
20807
+			}
20808
+			if postIndex > l {
20809
+				return io.ErrUnexpectedEOF
20810
+			}
20811
+			if m.Appdata == nil {
20812
+				m.Appdata = &types.Any{}
20813
+			}
20814
+			if err := m.Appdata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
20815
+				return err
20816
+			}
20817
+			iNdEx = postIndex
20782 20818
 		default:
20783 20819
 			iNdEx = preIndex
20784 20820
 			skippy, err := skipControl(dAtA[iNdEx:])
... ...
@@ -484,6 +484,8 @@ message CreateNetworkResponse {
484 484
 message GetNetworkRequest {
485 485
 	string name = 1;
486 486
 	string network_id = 2;
487
+	// Application-specific message for the NetworkAllocator's OnGetNetwork callback.
488
+	google.protobuf.Any appdata = 3;
487 489
 }
488 490
 
489 491
 message GetNetworkResponse {
... ...
@@ -507,6 +509,8 @@ message ListNetworksRequest {
507 507
 	}
508 508
 
509 509
 	Filters filters = 1;
510
+	// Application-specific message for the NetworkAllocator's OnGetNetwork callback.
511
+	google.protobuf.Any appdata = 2;
510 512
 }
511 513
 
512 514
 message ListNetworksResponse {
... ...
@@ -473,6 +473,10 @@ type Network struct {
473 473
 	// the services that still use this service, and proceed to delete
474 474
 	// this network when all of these services are gone
475 475
 	PendingDelete bool `protobuf:"varint,6,opt,name=pending_delete,json=pendingDelete,proto3" json:"pending_delete,omitempty"`
476
+	// Extra encodes application-specific information about the live state
477
+	// of the network. The syntax and semantics of the value are dictated by
478
+	// the network allocator implementation.
479
+	Extra *types.Any `protobuf:"bytes,7,opt,name=extra,proto3" json:"extra,omitempty"`
476 480
 }
477 481
 
478 482
 func (m *Network) Reset()      { *m = Network{} }
... ...
@@ -835,119 +839,120 @@ func init() {
835 835
 }
836 836
 
837 837
 var fileDescriptor_6218a23329ef342d = []byte{
838
-	// 1786 bytes of a gzipped FileDescriptorProto
839
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcb, 0x73, 0x1c, 0x47,
840
-	0x19, 0xd7, 0xac, 0xc6, 0xfb, 0xf8, 0xf6, 0x81, 0xd3, 0x11, 0x62, 0x2c, 0xc4, 0x4a, 0x6c, 0x12,
841
-	0x70, 0xa5, 0x5c, 0xab, 0x60, 0x02, 0xc8, 0x22, 0x89, 0xbd, 0x2b, 0x09, 0x67, 0x49, 0x6c, 0xab,
842
-	0x5a, 0x89, 0x93, 0xdb, 0x30, 0x3b, 0xd3, 0x5a, 0x8f, 0x77, 0x76, 0x7a, 0x6a, 0xba, 0x67, 0xc3,
843
-	0x72, 0xe2, 0xec, 0x2a, 0xaa, 0xb8, 0xf9, 0xc6, 0x81, 0xe2, 0x9f, 0xe0, 0xc2, 0x81, 0x03, 0x65,
844
-	0x6e, 0x39, 0x51, 0x29, 0x0e, 0x2a, 0xbc, 0xfe, 0x2b, 0xb8, 0x51, 0xfd, 0x98, 0xdd, 0x91, 0x77,
845
-	0xf4, 0x30, 0xb8, 0x54, 0x9c, 0xb6, 0x1f, 0xbf, 0xdf, 0xd7, 0xdf, 0xf7, 0x75, 0x7f, 0x8f, 0x59,
846
-	0xb8, 0x31, 0xf0, 0xf9, 0xa3, 0xa4, 0xdf, 0x76, 0xe9, 0x68, 0xcb, 0xa3, 0xee, 0x90, 0xc4, 0x5b,
847
-	0xec, 0x2b, 0x27, 0x1e, 0x0d, 0x7d, 0xbe, 0xe5, 0x44, 0xfe, 0x16, 0xed, 0x3f, 0x26, 0x2e, 0x67,
848
-	0xed, 0x28, 0xa6, 0x9c, 0x22, 0xa4, 0x20, 0xed, 0x14, 0xd2, 0x1e, 0xff, 0x68, 0xed, 0xdd, 0x73,
849
-	0x24, 0xf0, 0x49, 0x44, 0x34, 0xff, 0x5c, 0x2c, 0x8b, 0x88, 0x9b, 0x62, 0x37, 0x06, 0x94, 0x0e,
850
-	0x02, 0xb2, 0x25, 0x67, 0xfd, 0xe4, 0x68, 0x8b, 0xfb, 0x23, 0xc2, 0xb8, 0x33, 0x8a, 0x34, 0x60,
851
-	0x65, 0x40, 0x07, 0x54, 0x0e, 0xb7, 0xc4, 0x48, 0xaf, 0x5e, 0x7b, 0x99, 0xe6, 0x84, 0x13, 0xbd,
852
-	0xf5, 0xb3, 0x33, 0x4e, 0x9f, 0xc1, 0xa3, 0x20, 0x19, 0xf8, 0xa1, 0xfe, 0x51, 0xc4, 0xd6, 0x9f,
853
-	0x0d, 0x30, 0xef, 0x11, 0xee, 0xa0, 0x9f, 0x43, 0x69, 0x4c, 0x62, 0xe6, 0xd3, 0xd0, 0x32, 0x36,
854
-	0x8d, 0xeb, 0xd5, 0x9b, 0xdf, 0x6d, 0x2f, 0x7a, 0xa4, 0xfd, 0x50, 0x41, 0xba, 0xe6, 0xb3, 0xe3,
855
-	0x8d, 0x25, 0x9c, 0x32, 0xd0, 0x2d, 0x00, 0x37, 0x26, 0x0e, 0x27, 0x9e, 0xed, 0x70, 0xab, 0x20,
856
-	0xf9, 0x6b, 0x6d, 0xa5, 0x6e, 0x3b, 0x3d, 0xbf, 0xfd, 0x59, 0x6a, 0x25, 0xae, 0x68, 0x74, 0x87,
857
-	0x0b, 0x6a, 0x12, 0x79, 0x29, 0x75, 0xf9, 0x7c, 0xaa, 0x46, 0x77, 0x78, 0xeb, 0x4f, 0x57, 0xc0,
858
-	0xbc, 0x4f, 0x3d, 0x82, 0x56, 0xa1, 0xe0, 0x7b, 0x52, 0xed, 0x4a, 0xb7, 0x38, 0x3d, 0xde, 0x28,
859
-	0xf4, 0xf6, 0x70, 0xc1, 0xf7, 0xd0, 0x4d, 0x30, 0x47, 0x84, 0x3b, 0x5a, 0x21, 0x2b, 0xcf, 0x20,
860
-	0x61, 0xbb, 0xb6, 0x46, 0x62, 0xd1, 0x4f, 0xc1, 0x14, 0x57, 0xa5, 0x35, 0x59, 0xcf, 0xe3, 0x88,
861
-	0x33, 0x0f, 0x23, 0xe2, 0xa6, 0x3c, 0x81, 0x47, 0xfb, 0x50, 0xf5, 0x08, 0x73, 0x63, 0x3f, 0xe2,
862
-	0xc2, 0x87, 0xa6, 0xa4, 0xbf, 0x75, 0x1a, 0x7d, 0x6f, 0x0e, 0xc5, 0x59, 0x1e, 0xfa, 0x00, 0x8a,
863
-	0x8c, 0x3b, 0x3c, 0x61, 0xd6, 0x15, 0x29, 0xa1, 0x79, 0xaa, 0x02, 0x12, 0xa5, 0x55, 0xd0, 0x1c,
864
-	0xf4, 0x31, 0x34, 0x46, 0x4e, 0xe8, 0x0c, 0x48, 0x6c, 0x6b, 0x29, 0x45, 0x29, 0xe5, 0xfb, 0xb9,
865
-	0xa6, 0x2b, 0xa4, 0x12, 0x84, 0xeb, 0xa3, 0xec, 0x14, 0xf5, 0x00, 0x1c, 0xce, 0x1d, 0xf7, 0xd1,
866
-	0x88, 0x84, 0xdc, 0x2a, 0x49, 0x29, 0xef, 0xe4, 0xea, 0x42, 0xf8, 0x57, 0x34, 0x1e, 0x76, 0x66,
867
-	0xe0, 0x6e, 0xc1, 0x32, 0x70, 0x86, 0x8c, 0xee, 0x42, 0xd5, 0x25, 0x31, 0xf7, 0x8f, 0x7c, 0xd7,
868
-	0xe1, 0xc4, 0x2a, 0x4b, 0x59, 0x1b, 0x79, 0xb2, 0x76, 0xe7, 0x30, 0x6d, 0x58, 0x96, 0x89, 0xde,
869
-	0x03, 0x33, 0xa6, 0x01, 0xb1, 0x2a, 0x9b, 0xc6, 0xf5, 0xc6, 0xe9, 0x57, 0x83, 0x69, 0x40, 0xb0,
870
-	0x44, 0x8a, 0xa3, 0xe7, 0x8a, 0x30, 0x0b, 0x36, 0x97, 0x2f, 0x6c, 0x06, 0xce, 0x32, 0x51, 0x0b,
871
-	0x6a, 0x0f, 0xbf, 0xfc, 0xb4, 0x73, 0xff, 0xf3, 0xbd, 0x83, 0x03, 0x1a, 0x73, 0xab, 0xba, 0x69,
872
-	0x5c, 0xaf, 0xe3, 0x13, 0x6b, 0x3b, 0xab, 0x4f, 0x9e, 0xb6, 0x10, 0x5c, 0x2d, 0x1b, 0x57, 0x0d,
873
-	0xf9, 0x16, 0x8d, 0xf7, 0x8c, 0x2f, 0x8d, 0x5f, 0x19, 0xad, 0xe7, 0x26, 0x94, 0x0e, 0x49, 0x3c,
874
-	0xf6, 0xdd, 0xd7, 0xfb, 0x52, 0x6f, 0x9d, 0x78, 0xa9, 0xb9, 0x0e, 0xd5, 0xc7, 0x2e, 0x3c, 0xd6,
875
-	0x8f, 0xa0, 0x26, 0x7e, 0xed, 0x34, 0xe2, 0xe1, 0xdc, 0x88, 0xc7, 0x55, 0x41, 0xd0, 0x13, 0xb4,
876
-	0x07, 0xf5, 0x28, 0x26, 0x63, 0x9f, 0x26, 0xcc, 0x96, 0x3a, 0x14, 0x2f, 0xa4, 0x03, 0xae, 0xa5,
877
-	0x2c, 0x31, 0x43, 0x0f, 0xe0, 0xdb, 0x27, 0xa4, 0xcc, 0xd4, 0xa9, 0x9e, 0xaf, 0xce, 0x9b, 0x59,
878
-	0x49, 0xa9, 0x5a, 0xdb, 0x50, 0x26, 0xa1, 0x17, 0x51, 0x3f, 0xe4, 0x3a, 0x00, 0x73, 0x1f, 0xc9,
879
-	0xbe, 0xc6, 0xe0, 0x19, 0x1a, 0xed, 0x43, 0x5d, 0xe5, 0x15, 0xfb, 0x44, 0xf4, 0x6d, 0xe6, 0xd1,
880
-	0x3f, 0x97, 0x40, 0x1d, 0x36, 0xb5, 0x24, 0x33, 0x43, 0x1f, 0x00, 0x3c, 0xa6, 0xfd, 0x54, 0x46,
881
-	0x4d, 0xca, 0xf8, 0x5e, 0x9e, 0x8c, 0x5f, 0xd2, 0xbe, 0x16, 0x50, 0x79, 0x9c, 0x0e, 0xd1, 0x3b,
882
-	0xd0, 0x88, 0x48, 0xe8, 0xf9, 0xe1, 0xc0, 0xf6, 0x48, 0x40, 0x38, 0x91, 0x71, 0x57, 0xc6, 0x75,
883
-	0xbd, 0xba, 0x27, 0x17, 0x77, 0xd0, 0x93, 0xa7, 0xad, 0x06, 0xd4, 0xb2, 0xef, 0xac, 0xf5, 0x87,
884
-	0x02, 0x94, 0x53, 0xb3, 0xd0, 0xfb, 0xfa, 0x61, 0x18, 0xa7, 0xdb, 0x90, 0x62, 0xe5, 0xad, 0xa8,
885
-	0x37, 0xf1, 0x3e, 0x5c, 0x89, 0x68, 0xcc, 0x99, 0x55, 0x90, 0x51, 0x92, 0x9b, 0x78, 0xc4, 0x3b,
886
-	0xdf, 0xa5, 0xe1, 0x91, 0x3f, 0xc0, 0x0a, 0x8c, 0xbe, 0x80, 0xea, 0xd8, 0x8f, 0x79, 0xe2, 0x04,
887
-	0xb6, 0x1f, 0x31, 0x6b, 0x59, 0x72, 0x7f, 0x70, 0xd6, 0x91, 0xed, 0x87, 0x0a, 0xdf, 0x3b, 0xe8,
888
-	0x36, 0xa6, 0xc7, 0x1b, 0x30, 0x9b, 0x32, 0x0c, 0x5a, 0x54, 0x2f, 0x62, 0x6b, 0xf7, 0xa0, 0x32,
889
-	0xdb, 0x41, 0x37, 0x00, 0x42, 0x15, 0xa0, 0xf6, 0x2c, 0x7c, 0xea, 0xd3, 0xe3, 0x8d, 0x8a, 0x0e,
890
-	0xdb, 0xde, 0x1e, 0xae, 0x68, 0x40, 0xcf, 0x43, 0x08, 0x4c, 0xc7, 0xf3, 0x62, 0x19, 0x4c, 0x15,
891
-	0x2c, 0xc7, 0xad, 0xdf, 0x95, 0xc1, 0xfc, 0xcc, 0x61, 0xc3, 0xcb, 0xae, 0x15, 0xe2, 0xcc, 0x73,
892
-	0xc3, 0xaf, 0xf1, 0x8a, 0xe1, 0x77, 0x03, 0x80, 0xa9, 0xa8, 0x12, 0xee, 0x30, 0xe7, 0xee, 0xd0,
893
-	0xb1, 0x26, 0xdc, 0xa1, 0x01, 0xca, 0x1d, 0x2c, 0xa0, 0x5c, 0x3e, 0x69, 0x13, 0xcb, 0x31, 0x7a,
894
-	0x0b, 0x4a, 0x21, 0xf5, 0x24, 0xbd, 0x28, 0xe9, 0x30, 0x3d, 0xde, 0x28, 0x8a, 0xec, 0xd9, 0xdb,
895
-	0xc3, 0x45, 0xb1, 0xd5, 0xf3, 0x64, 0xf6, 0x0c, 0x43, 0xca, 0x1d, 0x51, 0x99, 0x98, 0x2e, 0x02,
896
-	0xb9, 0x31, 0xde, 0x99, 0xc3, 0xd2, 0xc4, 0x9d, 0x61, 0xa2, 0x87, 0xf0, 0x66, 0xaa, 0x6f, 0x56,
897
-	0x60, 0xf9, 0x55, 0x04, 0x22, 0x2d, 0x21, 0xb3, 0x93, 0x29, 0x96, 0x95, 0xd3, 0x8b, 0xa5, 0xbc,
898
-	0x81, 0xbc, 0x62, 0xd9, 0x85, 0xba, 0x47, 0x98, 0x1f, 0x13, 0x4f, 0x06, 0x2c, 0x91, 0x59, 0xb0,
899
-	0x91, 0x1f, 0xaf, 0xa9, 0x10, 0x82, 0x6b, 0x9a, 0x23, 0x67, 0xa8, 0x03, 0x65, 0xfd, 0xee, 0x98,
900
-	0x55, 0x7d, 0x95, 0xea, 0x32, 0xa3, 0x9d, 0x48, 0x5a, 0xb5, 0x57, 0x4a, 0x5a, 0xb7, 0x00, 0x02,
901
-	0x3a, 0xb0, 0xbd, 0xd8, 0x1f, 0x93, 0xd8, 0xaa, 0xeb, 0xd6, 0x29, 0x87, 0xbb, 0x27, 0x11, 0xb8,
902
-	0x12, 0xd0, 0x81, 0x1a, 0x22, 0x07, 0xd6, 0x1c, 0xc6, 0xfc, 0x41, 0x48, 0x3c, 0x7b, 0x40, 0x42,
903
-	0x12, 0xfb, 0xae, 0x1d, 0x13, 0x46, 0x93, 0xd8, 0x25, 0xcc, 0xfa, 0x96, 0xb4, 0x24, 0xb7, 0x79,
904
-	0xb9, 0xab, 0xc0, 0x58, 0x63, 0xb1, 0x95, 0x8a, 0x79, 0x69, 0x83, 0xa1, 0x3b, 0x50, 0x17, 0xb9,
905
-	0xd0, 0xe7, 0x24, 0x96, 0xd7, 0x65, 0x5d, 0x3d, 0xff, 0x95, 0xd7, 0x1e, 0xd3, 0x7e, 0x2f, 0x25,
906
-	0xa0, 0x8f, 0xa0, 0x34, 0xa6, 0x41, 0x32, 0x22, 0xcc, 0x7a, 0x43, 0x6a, 0xf4, 0x76, 0x2e, 0x57,
907
-	0x42, 0x32, 0xae, 0x4d, 0x49, 0x3b, 0x6b, 0x4f, 0x9e, 0xb6, 0x56, 0x61, 0x25, 0x9b, 0x28, 0xb7,
908
-	0x8d, 0x3b, 0xc6, 0xc7, 0xc6, 0x81, 0xd1, 0xfa, 0x6b, 0x01, 0xde, 0x58, 0xb8, 0x15, 0xf4, 0x13,
909
-	0x28, 0xe9, 0x7b, 0x39, 0xab, 0x09, 0xd6, 0x3c, 0x9c, 0x62, 0xd1, 0x3a, 0x54, 0x44, 0x92, 0x21,
910
-	0x8c, 0x11, 0x95, 0x3e, 0x2b, 0x78, 0xbe, 0x80, 0x2c, 0x28, 0x39, 0x81, 0xef, 0x88, 0xbd, 0x65,
911
-	0xb9, 0x97, 0x4e, 0x51, 0x02, 0xab, 0xea, 0xf2, 0xec, 0x79, 0xaf, 0x61, 0xd3, 0x88, 0x33, 0xcb,
912
-	0x94, 0xf6, 0xde, 0xbe, 0xd0, 0x5b, 0xd2, 0xd7, 0x3b, 0x5f, 0x78, 0x10, 0x71, 0xb6, 0x1f, 0xf2,
913
-	0x78, 0x82, 0x57, 0xbc, 0x9c, 0xad, 0xb5, 0xbb, 0x70, 0xed, 0x54, 0x0a, 0xba, 0x0a, 0xcb, 0x43,
914
-	0x32, 0x51, 0x09, 0x12, 0x8b, 0x21, 0x5a, 0x81, 0x2b, 0x63, 0x27, 0x48, 0x88, 0xce, 0xa7, 0x6a,
915
-	0xb2, 0x53, 0xd8, 0x36, 0x5a, 0x7f, 0x2f, 0x40, 0x49, 0xab, 0x73, 0xd9, 0x9d, 0x8d, 0x3e, 0x76,
916
-	0x21, 0xb5, 0x7e, 0x08, 0x35, 0xed, 0x52, 0x15, 0xd3, 0xe6, 0xb9, 0x51, 0x51, 0x55, 0x78, 0x15,
917
-	0xcf, 0x1f, 0x82, 0xe9, 0x47, 0xce, 0x48, 0x97, 0xff, 0xdc, 0x93, 0x7b, 0x07, 0x9d, 0x7b, 0x0f,
918
-	0x22, 0x95, 0x9a, 0xca, 0xd3, 0xe3, 0x0d, 0x53, 0x2c, 0x60, 0x49, 0xcb, 0xa9, 0xe0, 0xc5, 0x8b,
919
-	0x56, 0xf0, 0xbf, 0x15, 0xa1, 0xb4, 0x1b, 0x24, 0x8c, 0x93, 0xf8, 0xb2, 0x7d, 0xa9, 0x8f, 0x5d,
920
-	0xf0, 0xe5, 0x2e, 0x94, 0x62, 0x4a, 0xb9, 0xed, 0x3a, 0x67, 0xb9, 0x11, 0x53, 0xca, 0x77, 0x3b,
921
-	0xdd, 0x86, 0x20, 0x8a, 0x22, 0xa2, 0xe6, 0xb8, 0x28, 0xa8, 0xbb, 0x0e, 0xfa, 0x02, 0x56, 0xd3,
922
-	0xd2, 0xdd, 0xa7, 0x94, 0x33, 0x1e, 0x3b, 0x91, 0x3d, 0x24, 0x13, 0xd1, 0x62, 0x2d, 0x9f, 0xf6,
923
-	0x69, 0xb2, 0x1f, 0xba, 0xf1, 0x44, 0xfa, 0xf8, 0x13, 0x32, 0xc1, 0x2b, 0x5a, 0x40, 0x37, 0xe5,
924
-	0x7f, 0x42, 0x26, 0x0c, 0xdd, 0x86, 0x75, 0x32, 0x83, 0x09, 0x89, 0x76, 0xe0, 0x8c, 0x44, 0x53,
925
-	0x62, 0xbb, 0x01, 0x75, 0x87, 0xd2, 0xf3, 0x26, 0xbe, 0x46, 0xb2, 0xa2, 0x3e, 0x55, 0x88, 0x5d,
926
-	0x01, 0x40, 0x0c, 0xac, 0x7e, 0xe0, 0xb8, 0xc3, 0xc0, 0x67, 0xe2, 0xeb, 0x33, 0xf3, 0xa5, 0x21,
927
-	0x4a, 0x93, 0xd0, 0x6d, 0xfb, 0x0c, 0x6f, 0xb5, 0xbb, 0x73, 0x6e, 0xe6, 0xbb, 0x45, 0x07, 0xde,
928
-	0x77, 0xfa, 0xf9, 0xbb, 0xa8, 0x0b, 0xd5, 0x24, 0x14, 0xc7, 0x2b, 0x1f, 0x54, 0x2e, 0xea, 0x03,
929
-	0x50, 0x2c, 0x69, 0xf9, 0x3a, 0x98, 0x47, 0xa2, 0xd9, 0x12, 0xf5, 0xaa, 0xac, 0xde, 0xe0, 0x2f,
930
-	0x7a, 0x07, 0x87, 0x58, 0xae, 0xa2, 0x36, 0x20, 0x8f, 0x1c, 0x39, 0x49, 0xc0, 0x3b, 0x2a, 0x05,
931
-	0x1d, 0x50, 0x1a, 0xc8, 0xe2, 0x54, 0xc1, 0x39, 0x3b, 0xa8, 0x09, 0xc0, 0x92, 0x7e, 0x48, 0xf8,
932
-	0xa1, 0xff, 0x1b, 0x22, 0x2b, 0x50, 0x1d, 0x67, 0x56, 0x16, 0x3e, 0x7d, 0xea, 0x8b, 0x9f, 0x3e,
933
-	0x6b, 0x63, 0x58, 0x3f, 0xcb, 0x1d, 0x39, 0x49, 0xe5, 0x4e, 0x36, 0xa9, 0x54, 0x6f, 0xbe, 0x9b,
934
-	0xe7, 0x81, 0x7c, 0x91, 0x99, 0x04, 0x94, 0x1b, 0x48, 0x7f, 0x31, 0xa0, 0x78, 0x48, 0xdc, 0x98,
935
-	0xf0, 0xd7, 0x1a, 0x47, 0xdb, 0x27, 0xe2, 0xa8, 0x99, 0xff, 0xa5, 0x23, 0x4e, 0x5d, 0x08, 0xa3,
936
-	0x35, 0x28, 0xfb, 0x21, 0x27, 0x71, 0xe8, 0x04, 0x32, 0x8e, 0xca, 0x78, 0x36, 0xcf, 0x35, 0xe0,
937
-	0x8f, 0x06, 0x14, 0x55, 0x93, 0x7d, 0xd9, 0x06, 0xa8, 0x53, 0x5f, 0x36, 0x20, 0x57, 0xc9, 0x7f,
938
-	0x1b, 0x50, 0x4e, 0x6b, 0xfd, 0x6b, 0x55, 0xf3, 0xa5, 0xa6, 0x73, 0xf9, 0xbf, 0x6e, 0x3a, 0x11,
939
-	0x98, 0x43, 0x3f, 0xd4, 0xed, 0x31, 0x96, 0x63, 0xd4, 0x86, 0x52, 0xe4, 0x4c, 0x02, 0xea, 0x78,
940
-	0x3a, 0xc3, 0xaf, 0x2c, 0xfc, 0xd3, 0xd4, 0x09, 0x27, 0x38, 0x05, 0xed, 0xac, 0x3c, 0x79, 0xda,
941
-	0xba, 0x0a, 0x8d, 0xac, 0xe5, 0x8f, 0x8c, 0xd6, 0x3f, 0x0c, 0xa8, 0xec, 0xff, 0x9a, 0x93, 0x50,
942
-	0x36, 0xe3, 0xff, 0x97, 0xc6, 0x6f, 0x2e, 0xfe, 0x1b, 0x55, 0x39, 0xf1, 0x47, 0x53, 0xee, 0xa5,
943
-	0xfe, 0xb3, 0x00, 0x45, 0xd5, 0x4e, 0x5d, 0xf6, 0xcb, 0x53, 0xa7, 0x2e, 0x84, 0xce, 0x7d, 0x68,
944
-	0x44, 0x49, 0x3f, 0xf0, 0xd9, 0xa3, 0xf4, 0x9b, 0x5a, 0x35, 0x46, 0x3f, 0x3c, 0x5d, 0xc6, 0x81,
945
-	0xc2, 0xa7, 0xff, 0x6a, 0x45, 0xd9, 0x29, 0xba, 0x0d, 0x55, 0xd5, 0x1c, 0xda, 0x7e, 0x78, 0x44,
946
-	0xcf, 0xfa, 0x8b, 0x4d, 0x09, 0xeb, 0x85, 0x47, 0x14, 0xc3, 0x78, 0x36, 0xfe, 0x1f, 0x0a, 0x7c,
947
-	0xf7, 0xed, 0x67, 0xcf, 0x9b, 0x4b, 0xdf, 0x3c, 0x6f, 0x2e, 0xfd, 0x76, 0xda, 0x34, 0x9e, 0x4d,
948
-	0x9b, 0xc6, 0xd7, 0xd3, 0xa6, 0xf1, 0xaf, 0x69, 0xd3, 0xf8, 0xfd, 0x8b, 0xe6, 0xd2, 0xd7, 0x2f,
949
-	0x9a, 0x4b, 0xdf, 0xbc, 0x68, 0x2e, 0xf5, 0x8b, 0xf2, 0x21, 0xfe, 0xf8, 0x3f, 0x01, 0x00, 0x00,
950
-	0xff, 0xff, 0xb2, 0x67, 0x0d, 0x00, 0xbd, 0x16, 0x00, 0x00,
838
+	// 1805 bytes of a gzipped FileDescriptorProto
839
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0xcd, 0x6f, 0x1b, 0xc7,
840
+	0x15, 0xd7, 0x52, 0x2b, 0x7e, 0x3c, 0x7e, 0x54, 0x99, 0xa8, 0xea, 0x5a, 0x55, 0x29, 0x95, 0x49,
841
+	0x5a, 0xc3, 0x30, 0xa8, 0xd4, 0x4d, 0x5b, 0x59, 0x4d, 0x62, 0x93, 0x92, 0xea, 0xb0, 0x89, 0x6d,
842
+	0x61, 0x94, 0x38, 0xb9, 0x6d, 0x97, 0xbb, 0x23, 0x7a, 0xcd, 0xe5, 0xce, 0x62, 0x67, 0xc8, 0x84,
843
+	0x3d, 0xf5, 0x6c, 0xa0, 0x40, 0x6f, 0xbe, 0xf5, 0x50, 0xf4, 0x9f, 0xe8, 0xa5, 0x87, 0x1e, 0x0a,
844
+	0x1f, 0x73, 0x2a, 0x8c, 0x1e, 0x84, 0x9a, 0xfe, 0x1b, 0x7a, 0xe8, 0xad, 0x98, 0x8f, 0x25, 0x57,
845
+	0xe6, 0xea, 0xab, 0x30, 0x84, 0x9e, 0xb8, 0x33, 0xf3, 0xfb, 0xbd, 0x79, 0xef, 0xcd, 0xbc, 0x8f,
846
+	0x21, 0xdc, 0xec, 0xf9, 0xfc, 0xf1, 0xb0, 0xdb, 0x74, 0xe9, 0x60, 0xcb, 0xa3, 0x6e, 0x9f, 0xc4,
847
+	0x5b, 0xec, 0x6b, 0x27, 0x1e, 0xf4, 0x7d, 0xbe, 0xe5, 0x44, 0xfe, 0x16, 0xed, 0x3e, 0x21, 0x2e,
848
+	0x67, 0xcd, 0x28, 0xa6, 0x9c, 0x22, 0xa4, 0x20, 0xcd, 0x04, 0xd2, 0x1c, 0xfd, 0x64, 0xed, 0xc6,
849
+	0x39, 0x12, 0xf8, 0x38, 0x22, 0x9a, 0x7f, 0x2e, 0x96, 0x45, 0xc4, 0x4d, 0xb0, 0x1b, 0x3d, 0x4a,
850
+	0x7b, 0x01, 0xd9, 0x92, 0xa3, 0xee, 0xf0, 0x68, 0x8b, 0xfb, 0x03, 0xc2, 0xb8, 0x33, 0x88, 0x34,
851
+	0x60, 0xa5, 0x47, 0x7b, 0x54, 0x7e, 0x6e, 0x89, 0x2f, 0x3d, 0x7b, 0xed, 0x75, 0x9a, 0x13, 0x8e,
852
+	0xf5, 0xd2, 0x2f, 0xce, 0xd8, 0x7d, 0x0a, 0x8f, 0x82, 0x61, 0xcf, 0x0f, 0xf5, 0x8f, 0x22, 0x36,
853
+	0xfe, 0x62, 0x80, 0x79, 0x9f, 0x70, 0x07, 0xfd, 0x12, 0x0a, 0x23, 0x12, 0x33, 0x9f, 0x86, 0x96,
854
+	0xb1, 0x69, 0x5c, 0x2f, 0xdf, 0xfa, 0x7e, 0x73, 0xde, 0x23, 0xcd, 0x47, 0x0a, 0xd2, 0x36, 0x9f,
855
+	0x1f, 0x6f, 0x2c, 0xe0, 0x84, 0x81, 0x6e, 0x03, 0xb8, 0x31, 0x71, 0x38, 0xf1, 0x6c, 0x87, 0x5b,
856
+	0x39, 0xc9, 0x5f, 0x6b, 0x2a, 0x75, 0x9b, 0xc9, 0xfe, 0xcd, 0xcf, 0x13, 0x2b, 0x71, 0x49, 0xa3,
857
+	0x5b, 0x5c, 0x50, 0x87, 0x91, 0x97, 0x50, 0x17, 0xcf, 0xa7, 0x6a, 0x74, 0x8b, 0x37, 0xfe, 0xbc,
858
+	0x04, 0xe6, 0x03, 0xea, 0x11, 0xb4, 0x0a, 0x39, 0xdf, 0x93, 0x6a, 0x97, 0xda, 0xf9, 0xc9, 0xf1,
859
+	0x46, 0xae, 0xb3, 0x87, 0x73, 0xbe, 0x87, 0x6e, 0x81, 0x39, 0x20, 0xdc, 0xd1, 0x0a, 0x59, 0x59,
860
+	0x06, 0x09, 0xdb, 0xb5, 0x35, 0x12, 0x8b, 0x7e, 0x0e, 0xa6, 0x38, 0x2a, 0xad, 0xc9, 0x7a, 0x16,
861
+	0x47, 0xec, 0x79, 0x18, 0x11, 0x37, 0xe1, 0x09, 0x3c, 0xda, 0x87, 0xb2, 0x47, 0x98, 0x1b, 0xfb,
862
+	0x11, 0x17, 0x3e, 0x34, 0x25, 0xfd, 0x9d, 0xd3, 0xe8, 0x7b, 0x33, 0x28, 0x4e, 0xf3, 0xd0, 0x87,
863
+	0x90, 0x67, 0xdc, 0xe1, 0x43, 0x66, 0x2d, 0x49, 0x09, 0xf5, 0x53, 0x15, 0x90, 0x28, 0xad, 0x82,
864
+	0xe6, 0xa0, 0x4f, 0xa0, 0x36, 0x70, 0x42, 0xa7, 0x47, 0x62, 0x5b, 0x4b, 0xc9, 0x4b, 0x29, 0x3f,
865
+	0xcc, 0x34, 0x5d, 0x21, 0x95, 0x20, 0x5c, 0x1d, 0xa4, 0x87, 0xa8, 0x03, 0xe0, 0x70, 0xee, 0xb8,
866
+	0x8f, 0x07, 0x24, 0xe4, 0x56, 0x41, 0x4a, 0x79, 0x2f, 0x53, 0x17, 0xc2, 0xbf, 0xa6, 0x71, 0xbf,
867
+	0x35, 0x05, 0xb7, 0x73, 0x96, 0x81, 0x53, 0x64, 0x74, 0x0f, 0xca, 0x2e, 0x89, 0xb9, 0x7f, 0xe4,
868
+	0xbb, 0x0e, 0x27, 0x56, 0x51, 0xca, 0xda, 0xc8, 0x92, 0xb5, 0x3b, 0x83, 0x69, 0xc3, 0xd2, 0x4c,
869
+	0xf4, 0x3e, 0x98, 0x31, 0x0d, 0x88, 0x55, 0xda, 0x34, 0xae, 0xd7, 0x4e, 0x3f, 0x1a, 0x4c, 0x03,
870
+	0x82, 0x25, 0x52, 0x6c, 0x3d, 0x53, 0x84, 0x59, 0xb0, 0xb9, 0x78, 0x61, 0x33, 0x70, 0x9a, 0x89,
871
+	0x1a, 0x50, 0x79, 0xf4, 0xd5, 0x67, 0xad, 0x07, 0x5f, 0xec, 0x1d, 0x1c, 0xd0, 0x98, 0x5b, 0xe5,
872
+	0x4d, 0xe3, 0x7a, 0x15, 0x9f, 0x98, 0xdb, 0x59, 0x7d, 0xfa, 0xac, 0x81, 0x60, 0xb9, 0x68, 0x2c,
873
+	0x1b, 0xf2, 0x2e, 0x1a, 0xef, 0x1b, 0x5f, 0x19, 0xbf, 0x31, 0x1a, 0x2f, 0x4d, 0x28, 0x1c, 0x92,
874
+	0x78, 0xe4, 0xbb, 0x6f, 0xf6, 0xa6, 0xde, 0x3e, 0x71, 0x53, 0x33, 0x1d, 0xaa, 0xb7, 0x9d, 0xbb,
875
+	0xac, 0x1f, 0x43, 0x45, 0xfc, 0xda, 0x49, 0xc4, 0xc3, 0xb9, 0x11, 0x8f, 0xcb, 0x82, 0xa0, 0x07,
876
+	0x68, 0x0f, 0xaa, 0x51, 0x4c, 0x46, 0x3e, 0x1d, 0x32, 0x5b, 0xea, 0x90, 0xbf, 0x90, 0x0e, 0xb8,
877
+	0x92, 0xb0, 0xc4, 0x08, 0x3d, 0x84, 0xef, 0x9e, 0x90, 0x32, 0x55, 0xa7, 0x7c, 0xbe, 0x3a, 0x6f,
878
+	0xa7, 0x25, 0x25, 0x6a, 0x6d, 0x43, 0x91, 0x84, 0x5e, 0x44, 0xfd, 0x90, 0xeb, 0x00, 0xcc, 0xbc,
879
+	0x24, 0xfb, 0x1a, 0x83, 0xa7, 0x68, 0xb4, 0x0f, 0x55, 0x95, 0x57, 0xec, 0x13, 0xd1, 0xb7, 0x99,
880
+	0x45, 0xff, 0x42, 0x02, 0x75, 0xd8, 0x54, 0x86, 0xa9, 0x11, 0xfa, 0x10, 0xe0, 0x09, 0xed, 0x26,
881
+	0x32, 0x2a, 0x52, 0xc6, 0x0f, 0xb2, 0x64, 0xfc, 0x9a, 0x76, 0xb5, 0x80, 0xd2, 0x93, 0xe4, 0x13,
882
+	0xbd, 0x07, 0xb5, 0x88, 0x84, 0x9e, 0x1f, 0xf6, 0x6c, 0x8f, 0x04, 0x84, 0x13, 0x19, 0x77, 0x45,
883
+	0x5c, 0xd5, 0xb3, 0x7b, 0x72, 0x72, 0x07, 0x3d, 0x7d, 0xd6, 0xa8, 0x41, 0x25, 0x7d, 0xcf, 0x1a,
884
+	0x7f, 0xcc, 0x41, 0x31, 0x31, 0x0b, 0x7d, 0xa0, 0x2f, 0x86, 0x71, 0xba, 0x0d, 0x09, 0x56, 0x9e,
885
+	0x8a, 0xba, 0x13, 0x1f, 0xc0, 0x52, 0x44, 0x63, 0xce, 0xac, 0x9c, 0x8c, 0x92, 0xcc, 0xc4, 0x23,
886
+	0xee, 0xf9, 0x2e, 0x0d, 0x8f, 0xfc, 0x1e, 0x56, 0x60, 0xf4, 0x25, 0x94, 0x47, 0x7e, 0xcc, 0x87,
887
+	0x4e, 0x60, 0xfb, 0x11, 0xb3, 0x16, 0x25, 0xf7, 0x47, 0x67, 0x6d, 0xd9, 0x7c, 0xa4, 0xf0, 0x9d,
888
+	0x83, 0x76, 0x6d, 0x72, 0xbc, 0x01, 0xd3, 0x21, 0xc3, 0xa0, 0x45, 0x75, 0x22, 0xb6, 0x76, 0x1f,
889
+	0x4a, 0xd3, 0x15, 0x74, 0x13, 0x20, 0x54, 0x01, 0x6a, 0x4f, 0xc3, 0xa7, 0x3a, 0x39, 0xde, 0x28,
890
+	0xe9, 0xb0, 0xed, 0xec, 0xe1, 0x92, 0x06, 0x74, 0x3c, 0x84, 0xc0, 0x74, 0x3c, 0x2f, 0x96, 0xc1,
891
+	0x54, 0xc2, 0xf2, 0xbb, 0xf1, 0xfb, 0x22, 0x98, 0x9f, 0x3b, 0xac, 0x7f, 0xd5, 0xb5, 0x42, 0xec,
892
+	0x79, 0x6e, 0xf8, 0xd5, 0x2e, 0x19, 0x7e, 0x37, 0x01, 0x98, 0x8a, 0x2a, 0xe1, 0x0e, 0x73, 0xe6,
893
+	0x0e, 0x1d, 0x6b, 0xc2, 0x1d, 0x1a, 0xa0, 0xdc, 0xc1, 0x02, 0xca, 0xe5, 0x95, 0x36, 0xb1, 0xfc,
894
+	0x46, 0xef, 0x40, 0x21, 0xa4, 0x9e, 0xa4, 0xe7, 0x25, 0x1d, 0x26, 0xc7, 0x1b, 0x79, 0x91, 0x3d,
895
+	0x3b, 0x7b, 0x38, 0x2f, 0x96, 0x3a, 0x9e, 0xcc, 0x9e, 0x61, 0x48, 0xb9, 0x23, 0x2a, 0x13, 0xd3,
896
+	0x45, 0x20, 0x33, 0xc6, 0x5b, 0x33, 0x58, 0x92, 0xb8, 0x53, 0x4c, 0xf4, 0x08, 0xde, 0x4e, 0xf4,
897
+	0x4d, 0x0b, 0x2c, 0x5e, 0x46, 0x20, 0xd2, 0x12, 0x52, 0x2b, 0xa9, 0x62, 0x59, 0x3a, 0xbd, 0x58,
898
+	0xca, 0x13, 0xc8, 0x2a, 0x96, 0x6d, 0xa8, 0x7a, 0x84, 0xf9, 0x31, 0xf1, 0x64, 0xc0, 0x12, 0x99,
899
+	0x05, 0x6b, 0xd9, 0xf1, 0x9a, 0x08, 0x21, 0xb8, 0xa2, 0x39, 0x72, 0x84, 0x5a, 0x50, 0xd4, 0xf7,
900
+	0x8e, 0x59, 0xe5, 0xcb, 0x54, 0x97, 0x29, 0xed, 0x44, 0xd2, 0xaa, 0x5c, 0x2a, 0x69, 0xdd, 0x06,
901
+	0x08, 0x68, 0xcf, 0xf6, 0x62, 0x7f, 0x44, 0x62, 0xab, 0xaa, 0x5b, 0xa7, 0x0c, 0xee, 0x9e, 0x44,
902
+	0xe0, 0x52, 0x40, 0x7b, 0xea, 0x13, 0x39, 0xb0, 0xe6, 0x30, 0xe6, 0xf7, 0x42, 0xe2, 0xd9, 0x3d,
903
+	0x12, 0x92, 0xd8, 0x77, 0xed, 0x98, 0x30, 0x3a, 0x8c, 0x5d, 0xc2, 0xac, 0xef, 0x48, 0x4b, 0x32,
904
+	0x9b, 0x97, 0x7b, 0x0a, 0x8c, 0x35, 0x16, 0x5b, 0x89, 0x98, 0xd7, 0x16, 0x18, 0xba, 0x0b, 0x55,
905
+	0x91, 0x0b, 0x7d, 0x4e, 0x62, 0x79, 0x5c, 0xd6, 0xf2, 0xf9, 0xb7, 0xbc, 0xf2, 0x84, 0x76, 0x3b,
906
+	0x09, 0x01, 0x7d, 0x0c, 0x85, 0x11, 0x0d, 0x86, 0x03, 0xc2, 0xac, 0xb7, 0xa4, 0x46, 0xef, 0x66,
907
+	0x72, 0x25, 0x24, 0xe5, 0xda, 0x84, 0xb4, 0xb3, 0xf6, 0xf4, 0x59, 0x63, 0x15, 0x56, 0xd2, 0x89,
908
+	0x72, 0xdb, 0xb8, 0x6b, 0x7c, 0x62, 0x1c, 0x18, 0x8d, 0xbf, 0xe5, 0xe0, 0xad, 0xb9, 0x53, 0x41,
909
+	0x3f, 0x83, 0x82, 0x3e, 0x97, 0xb3, 0x9a, 0x60, 0xcd, 0xc3, 0x09, 0x16, 0xad, 0x43, 0x49, 0x24,
910
+	0x19, 0xc2, 0x18, 0x51, 0xe9, 0xb3, 0x84, 0x67, 0x13, 0xc8, 0x82, 0x82, 0x13, 0xf8, 0x8e, 0x58,
911
+	0x5b, 0x94, 0x6b, 0xc9, 0x10, 0x0d, 0x61, 0x55, 0x1d, 0x9e, 0x3d, 0xeb, 0x35, 0x6c, 0x1a, 0x71,
912
+	0x66, 0x99, 0xd2, 0xde, 0x3b, 0x17, 0xba, 0x4b, 0xfa, 0x78, 0x67, 0x13, 0x0f, 0x23, 0xce, 0xf6,
913
+	0x43, 0x1e, 0x8f, 0xf1, 0x8a, 0x97, 0xb1, 0xb4, 0x76, 0x0f, 0xae, 0x9d, 0x4a, 0x41, 0xcb, 0xb0,
914
+	0xd8, 0x27, 0x63, 0x95, 0x20, 0xb1, 0xf8, 0x44, 0x2b, 0xb0, 0x34, 0x72, 0x82, 0x21, 0xd1, 0xf9,
915
+	0x54, 0x0d, 0x76, 0x72, 0xdb, 0x46, 0xe3, 0xdf, 0x39, 0x28, 0x68, 0x75, 0xae, 0xba, 0xb3, 0xd1,
916
+	0xdb, 0xce, 0xa5, 0xd6, 0x8f, 0xa0, 0xa2, 0x5d, 0xaa, 0x62, 0xda, 0x3c, 0x37, 0x2a, 0xca, 0x0a,
917
+	0xaf, 0xe2, 0xf9, 0x23, 0x30, 0xfd, 0xc8, 0x19, 0xe8, 0xf2, 0x9f, 0xb9, 0x73, 0xe7, 0xa0, 0x75,
918
+	0xff, 0x61, 0xa4, 0x52, 0x53, 0x71, 0x72, 0xbc, 0x61, 0x8a, 0x09, 0x2c, 0x69, 0x19, 0x15, 0x3c,
919
+	0x9f, 0x51, 0xc1, 0xd1, 0x0d, 0x58, 0x22, 0xdf, 0xf0, 0xd8, 0xd1, 0x29, 0x75, 0x65, 0xee, 0xb9,
920
+	0xd3, 0x0a, 0xc7, 0x58, 0x41, 0x32, 0xab, 0xfd, 0xdf, 0xf3, 0x50, 0xd8, 0x0d, 0x86, 0x8c, 0x93,
921
+	0xf8, 0xaa, 0xfd, 0xae, 0xb7, 0x9d, 0xf3, 0xfb, 0x2e, 0x14, 0x62, 0x4a, 0xb9, 0xed, 0x3a, 0x67,
922
+	0xb9, 0x1c, 0x53, 0xca, 0x77, 0x5b, 0xed, 0x9a, 0x20, 0x8a, 0x82, 0xa3, 0xc6, 0x38, 0x2f, 0xa8,
923
+	0xbb, 0x0e, 0xfa, 0x12, 0x56, 0x93, 0x32, 0xdf, 0xa5, 0x94, 0x33, 0x1e, 0x3b, 0x91, 0xdd, 0x27,
924
+	0x63, 0xd1, 0x8e, 0x2d, 0x9e, 0xf6, 0x8c, 0xd9, 0x0f, 0xdd, 0x78, 0x2c, 0xcf, 0xe3, 0x53, 0x32,
925
+	0xc6, 0x2b, 0x5a, 0x40, 0x3b, 0xe1, 0x7f, 0x4a, 0xc6, 0x0c, 0xdd, 0x81, 0x75, 0x32, 0x85, 0x09,
926
+	0x89, 0x76, 0xe0, 0x0c, 0x44, 0x03, 0x63, 0xbb, 0x01, 0x75, 0xfb, 0xf2, 0x94, 0x4c, 0x7c, 0x8d,
927
+	0xa4, 0x45, 0x7d, 0xa6, 0x10, 0xbb, 0x02, 0x80, 0x18, 0x58, 0xdd, 0xc0, 0x71, 0xfb, 0x81, 0xcf,
928
+	0xc4, 0x4b, 0x35, 0xf5, 0x2a, 0x11, 0x65, 0x4c, 0xe8, 0xb6, 0x7d, 0x86, 0xb7, 0x9a, 0xed, 0x19,
929
+	0x37, 0xf5, 0xc6, 0xd1, 0x41, 0xfa, 0xbd, 0x6e, 0xf6, 0x2a, 0x6a, 0x43, 0x79, 0x18, 0x8a, 0xed,
930
+	0x95, 0x0f, 0x4a, 0x17, 0xf5, 0x01, 0x28, 0x96, 0xb4, 0x7c, 0x1d, 0xcc, 0x23, 0xd1, 0x98, 0x89,
931
+	0xda, 0x56, 0x54, 0xf7, 0xf5, 0x57, 0x9d, 0x83, 0x43, 0x2c, 0x67, 0x51, 0x13, 0x90, 0x47, 0x8e,
932
+	0x9c, 0x61, 0xc0, 0x5b, 0x2a, 0x5d, 0x1d, 0x50, 0x1a, 0xc8, 0x42, 0x56, 0xc2, 0x19, 0x2b, 0xa8,
933
+	0x0e, 0xc0, 0x86, 0xdd, 0x90, 0xf0, 0x43, 0xff, 0xb7, 0x44, 0x56, 0xab, 0x2a, 0x4e, 0xcd, 0xcc,
934
+	0x3d, 0x93, 0xaa, 0xf3, 0xcf, 0xa4, 0xb5, 0x11, 0xac, 0x9f, 0xe5, 0x8e, 0x8c, 0x04, 0x74, 0x37,
935
+	0x9d, 0x80, 0xca, 0xb7, 0x6e, 0x64, 0x79, 0x20, 0x5b, 0x64, 0x2a, 0x59, 0x65, 0x06, 0xd2, 0x5f,
936
+	0x0d, 0xc8, 0x1f, 0x12, 0x37, 0x26, 0xfc, 0x8d, 0xc6, 0xd1, 0xf6, 0x89, 0x38, 0xaa, 0x67, 0xbf,
937
+	0x8a, 0xc4, 0xae, 0x73, 0x61, 0xb4, 0x06, 0x45, 0x3f, 0xe4, 0x24, 0x0e, 0x9d, 0x40, 0xc6, 0x51,
938
+	0x11, 0x4f, 0xc7, 0x99, 0x06, 0xfc, 0xc9, 0x80, 0xbc, 0x6a, 0xc8, 0xaf, 0xda, 0x00, 0xb5, 0xeb,
939
+	0xeb, 0x06, 0x64, 0x2a, 0xf9, 0x1f, 0x03, 0x8a, 0x49, 0x5f, 0xf0, 0x46, 0xd5, 0x7c, 0xad, 0x41,
940
+	0x5d, 0xfc, 0x9f, 0x1b, 0x54, 0x04, 0x66, 0xdf, 0x0f, 0x75, 0x2b, 0x8d, 0xe5, 0x37, 0x6a, 0x42,
941
+	0x21, 0x72, 0xc6, 0x01, 0x75, 0x3c, 0x5d, 0x0d, 0xb2, 0xd3, 0x74, 0x02, 0xda, 0x59, 0x79, 0xfa,
942
+	0xac, 0xb1, 0x0c, 0xb5, 0xb4, 0xe5, 0x8f, 0x8d, 0xc6, 0x3f, 0x0c, 0x28, 0xed, 0x7f, 0xc3, 0x49,
943
+	0x28, 0x1b, 0xf7, 0xff, 0x4b, 0xe3, 0x37, 0xe7, 0xff, 0xb9, 0x2a, 0x9d, 0xf8, 0x53, 0x2a, 0xf3,
944
+	0x50, 0xff, 0x99, 0x83, 0xbc, 0x6a, 0xbd, 0xae, 0xfa, 0xe6, 0xa9, 0x5d, 0xe7, 0x42, 0xe7, 0x01,
945
+	0xd4, 0xa2, 0x61, 0x37, 0xf0, 0xd9, 0xe3, 0xe4, 0xfd, 0xad, 0x9a, 0xa8, 0x1f, 0x9f, 0x2e, 0xe3,
946
+	0x40, 0xe1, 0x93, 0x7f, 0xc0, 0xa2, 0xf4, 0x10, 0xdd, 0x81, 0xb2, 0x6a, 0x24, 0x6d, 0x3f, 0x3c,
947
+	0xa2, 0x67, 0xfd, 0x1d, 0xa7, 0x84, 0x75, 0xc2, 0x23, 0x8a, 0x61, 0x34, 0xfd, 0xbe, 0x60, 0x33,
948
+	0x90, 0xe5, 0xdc, 0xf6, 0xbb, 0xcf, 0x5f, 0xd6, 0x17, 0x5e, 0xbc, 0xac, 0x2f, 0xfc, 0x6e, 0x52,
949
+	0x37, 0x9e, 0x4f, 0xea, 0xc6, 0xb7, 0x93, 0xba, 0xf1, 0xaf, 0x49, 0xdd, 0xf8, 0xc3, 0xab, 0xfa,
950
+	0xc2, 0xb7, 0xaf, 0xea, 0x0b, 0x2f, 0x5e, 0xd5, 0x17, 0xba, 0x79, 0x79, 0x11, 0x7f, 0xfa, 0xdf,
951
+	0x00, 0x00, 0x00, 0xff, 0xff, 0xc8, 0xcf, 0x42, 0x61, 0xe9, 0x16, 0x00, 0x00,
951 952
 }
952 953
 
953 954
 func (m *Meta) Copy() *Meta {
... ...
@@ -1223,6 +1228,10 @@ func (m *Network) CopyFrom(src interface{}) {
1223 1223
 		m.IPAM = &IPAMOptions{}
1224 1224
 		github_com_moby_swarmkit_v2_api_deepcopy.Copy(m.IPAM, o.IPAM)
1225 1225
 	}
1226
+	if o.Extra != nil {
1227
+		m.Extra = &types.Any{}
1228
+		github_com_moby_swarmkit_v2_api_deepcopy.Copy(m.Extra, o.Extra)
1229
+	}
1226 1230
 }
1227 1231
 
1228 1232
 func (m *Cluster) Copy() *Cluster {
... ...
@@ -2082,6 +2091,18 @@ func (m *Network) MarshalToSizedBuffer(dAtA []byte) (int, error) {
2082 2082
 	_ = i
2083 2083
 	var l int
2084 2084
 	_ = l
2085
+	if m.Extra != nil {
2086
+		{
2087
+			size, err := m.Extra.MarshalToSizedBuffer(dAtA[:i])
2088
+			if err != nil {
2089
+				return 0, err
2090
+			}
2091
+			i -= size
2092
+			i = encodeVarintObjects(dAtA, i, uint64(size))
2093
+		}
2094
+		i--
2095
+		dAtA[i] = 0x3a
2096
+	}
2085 2097
 	if m.PendingDelete {
2086 2098
 		i--
2087 2099
 		if m.PendingDelete {
... ...
@@ -2906,6 +2927,10 @@ func (m *Network) Size() (n int) {
2906 2906
 	if m.PendingDelete {
2907 2907
 		n += 2
2908 2908
 	}
2909
+	if m.Extra != nil {
2910
+		l = m.Extra.Size()
2911
+		n += 1 + l + sovObjects(uint64(l))
2912
+	}
2909 2913
 	return n
2910 2914
 }
2911 2915
 
... ...
@@ -6171,6 +6196,7 @@ func (this *Network) String() string {
6171 6171
 		`DriverState:` + strings.Replace(fmt.Sprintf("%v", this.DriverState), "Driver", "Driver", 1) + `,`,
6172 6172
 		`IPAM:` + strings.Replace(fmt.Sprintf("%v", this.IPAM), "IPAMOptions", "IPAMOptions", 1) + `,`,
6173 6173
 		`PendingDelete:` + fmt.Sprintf("%v", this.PendingDelete) + `,`,
6174
+		`Extra:` + strings.Replace(fmt.Sprintf("%v", this.Extra), "Any", "types.Any", 1) + `,`,
6174 6175
 		`}`,
6175 6176
 	}, "")
6176 6177
 	return s
... ...
@@ -8588,6 +8614,42 @@ func (m *Network) Unmarshal(dAtA []byte) error {
8588 8588
 				}
8589 8589
 			}
8590 8590
 			m.PendingDelete = bool(v != 0)
8591
+		case 7:
8592
+			if wireType != 2 {
8593
+				return fmt.Errorf("proto: wrong wireType = %d for field Extra", wireType)
8594
+			}
8595
+			var msglen int
8596
+			for shift := uint(0); ; shift += 7 {
8597
+				if shift >= 64 {
8598
+					return ErrIntOverflowObjects
8599
+				}
8600
+				if iNdEx >= l {
8601
+					return io.ErrUnexpectedEOF
8602
+				}
8603
+				b := dAtA[iNdEx]
8604
+				iNdEx++
8605
+				msglen |= int(b&0x7F) << shift
8606
+				if b < 0x80 {
8607
+					break
8608
+				}
8609
+			}
8610
+			if msglen < 0 {
8611
+				return ErrInvalidLengthObjects
8612
+			}
8613
+			postIndex := iNdEx + msglen
8614
+			if postIndex < 0 {
8615
+				return ErrInvalidLengthObjects
8616
+			}
8617
+			if postIndex > l {
8618
+				return io.ErrUnexpectedEOF
8619
+			}
8620
+			if m.Extra == nil {
8621
+				m.Extra = &types.Any{}
8622
+			}
8623
+			if err := m.Extra.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
8624
+				return err
8625
+			}
8626
+			iNdEx = postIndex
8591 8627
 		default:
8592 8628
 			iNdEx = preIndex
8593 8629
 			skippy, err := skipObjects(dAtA[iNdEx:])
... ...
@@ -332,6 +332,11 @@ message Network {
332 332
 	// the services that still use this service, and proceed to delete
333 333
 	// this network when all of these services are gone
334 334
 	bool pending_delete = 6;
335
+
336
+	// Extra encodes application-specific information about the live state
337
+	// of the network. The syntax and semantics of the value are dictated by
338
+	// the network allocator implementation.
339
+	google.protobuf.Any extra = 7;
335 340
 }
336 341
 
337 342
 // Cluster provides global cluster settings.
... ...
@@ -1524,6 +1524,10 @@ func (a *Allocator) procTasksNetwork(ctx context.Context, onRetry bool) {
1524 1524
 	}
1525 1525
 }
1526 1526
 
1527
+func (a *Allocator) NetworkAllocator() networkallocator.NetworkAllocator {
1528
+	return a.nwkAllocator
1529
+}
1530
+
1527 1531
 // updateTaskStatus sets TaskStatus and updates timestamp.
1528 1532
 func updateTaskStatus(t *api.Task, newStatus api.TaskState, message string) {
1529 1533
 	t.Status = api.TaskStatus{
... ...
@@ -1,6 +1,8 @@
1 1
 package networkallocator
2 2
 
3 3
 import (
4
+	"context"
5
+
4 6
 	"github.com/moby/swarmkit/v2/api"
5 7
 )
6 8
 
... ...
@@ -87,6 +89,27 @@ type NetworkAllocator interface {
87 87
 	IsAttachmentAllocated(node *api.Node, networkAttachment *api.NetworkAttachment) bool
88 88
 }
89 89
 
90
+// OnGetNetworker is an optional interface that [NetworkAllocator] may implement
91
+// to customize the Control API response for GetNetwork and ListNetworks requests.
92
+type OnGetNetworker interface {
93
+	// OnGetNetwork is called with a copy of the network object that will be
94
+	// returned in a GetNetwork or ListNetworks Control API response. Any
95
+	// modifications to the network object will be reflected in the
96
+	// response. The modified network object will not be persisted to the
97
+	// store. Errors returned will be bubbled up to the Control API client.
98
+	//
99
+	// The appdataTypeURL and appdata parameters are set to the TypeUrl and
100
+	// value, respectively, of the appdata field in the ListNetworks or
101
+	// GetNetwork Control API request.
102
+	//
103
+	// The network may not have been allocated at the time of the call.
104
+	// Calling OnGetNetwork with an unallocated network should not be an
105
+	// error.
106
+	//
107
+	// This method may be called concurrently from multiple goroutines.
108
+	OnGetNetwork(ctx context.Context, network *api.Network, appdataTypeURL string, appdata []byte) error
109
+}
110
+
90 111
 // Config is used to store network related cluster config in the Manager.
91 112
 type Config struct {
92 113
 	// DefaultAddrPool specifies default subnet pool for global scope networks
93 114
new file mode 100644
... ...
@@ -0,0 +1,35 @@
0
+package manager
1
+
2
+import (
3
+	"context"
4
+
5
+	"github.com/moby/swarmkit/v2/api"
6
+	"github.com/moby/swarmkit/v2/manager/allocator/networkallocator"
7
+)
8
+
9
+func (m *Manager) networkAllocator() networkallocator.NetworkAllocator {
10
+	m.mu.Lock()
11
+	defer m.mu.Unlock()
12
+	if m.allocator == nil {
13
+		return nil
14
+	}
15
+	return m.allocator.NetworkAllocator()
16
+}
17
+
18
+func (m *Manager) OnGetNetwork(ctx context.Context, n *api.Network, appdataTypeURL string, appdata []byte) error {
19
+	if nwh, ok := m.networkAllocator().(networkallocator.OnGetNetworker); ok {
20
+		return nwh.OnGetNetwork(ctx, n, appdataTypeURL, appdata)
21
+	}
22
+	return nil
23
+}
24
+
25
+func (m *Manager) OnListNetworks(ctx context.Context, networks []*api.Network, appdataTypeURL string, appdata []byte) error {
26
+	if nwh, ok := m.networkAllocator().(networkallocator.OnGetNetworker); ok {
27
+		for _, n := range networks {
28
+			if err := nwh.OnGetNetwork(ctx, n, appdataTypeURL, appdata); err != nil {
29
+				return err
30
+			}
31
+		}
32
+	}
33
+	return nil
34
+}
0 35
new file mode 100644
... ...
@@ -0,0 +1,32 @@
0
+package controlapi
1
+
2
+import (
3
+	"context"
4
+
5
+	"github.com/moby/swarmkit/v2/api"
6
+)
7
+
8
+// NetworkViewResponseMutator provides callbacks which may modify the response
9
+// objects for GetNetwork and ListNetworks Control API requests before they are
10
+// sent to the client.
11
+type NetworkViewResponseMutator interface {
12
+	OnGetNetwork(context.Context, *api.Network, string, []byte) error
13
+	OnListNetworks(context.Context, []*api.Network, string, []byte) error
14
+}
15
+
16
+type NoopViewResponseMutator struct{}
17
+
18
+func (NoopViewResponseMutator) OnGetNetwork(ctx context.Context, n *api.Network, appdataTypeURL string, appdata []byte) error {
19
+	return nil
20
+}
21
+
22
+func (NoopViewResponseMutator) OnListNetworks(ctx context.Context, networks []*api.Network, appdataTypeURL string, appdata []byte) error {
23
+	return nil
24
+}
25
+
26
+func (s *Server) networkhooks() NetworkViewResponseMutator {
27
+	if s.NetworkHooks != nil {
28
+		return s.NetworkHooks
29
+	}
30
+	return NoopViewResponseMutator{}
31
+}
... ...
@@ -148,6 +148,9 @@ func (s *Server) GetNetwork(ctx context.Context, request *api.GetNetworkRequest)
148 148
 	if n == nil {
149 149
 		return nil, status.Errorf(codes.NotFound, "network %s not found", request.NetworkID)
150 150
 	}
151
+	if err := s.networkhooks().OnGetNetwork(ctx, n, request.Appdata.GetTypeUrl(), request.Appdata.GetValue()); err != nil {
152
+		return nil, err
153
+	}
151 154
 	return &api.GetNetworkResponse{
152 155
 		Network: n,
153 156
 	}, nil
... ...
@@ -292,6 +295,10 @@ func (s *Server) ListNetworks(ctx context.Context, request *api.ListNetworksRequ
292 292
 		)
293 293
 	}
294 294
 
295
+	if err := s.networkhooks().OnListNetworks(ctx, networks, request.Appdata.GetTypeUrl(), request.Appdata.GetValue()); err != nil {
296
+		return nil, err
297
+	}
298
+
295 299
 	return &api.ListNetworksResponse{
296 300
 		Networks: networks,
297 301
 	}, nil
... ...
@@ -21,6 +21,10 @@ type Server struct {
21 21
 	securityConfig *ca.SecurityConfig
22 22
 	netvalidator   networkallocator.DriverValidator
23 23
 	dr             *drivers.DriverProvider
24
+
25
+	// NetworkHooks intercept and mutate API server responses for GetNetwork
26
+	// and ListNetworks API requests when set.
27
+	NetworkHooks NetworkViewResponseMutator
24 28
 }
25 29
 
26 30
 // NewServer creates a Cluster API server.
... ...
@@ -473,6 +473,7 @@ func (m *Manager) Run(parent context.Context) error {
473 473
 	}
474 474
 
475 475
 	baseControlAPI := controlapi.NewServer(m.raftNode.MemoryStore(), m.raftNode, m.config.SecurityConfig, m.config.networkProvider(), drivers.New(m.config.PluginGetter))
476
+	baseControlAPI.NetworkHooks = m
476 477
 	baseResourceAPI := resourceapi.New(m.raftNode.MemoryStore())
477 478
 	healthServer := health.NewHealthServer()
478 479
 	localHealthServer := health.NewHealthServer()
... ...
@@ -983,7 +983,7 @@ github.com/moby/profiles/seccomp
983 983
 # github.com/moby/pubsub v1.0.0
984 984
 ## explicit; go 1.19
985 985
 github.com/moby/pubsub
986
-# github.com/moby/swarmkit/v2 v2.0.0
986
+# github.com/moby/swarmkit/v2 v2.1.0
987 987
 ## explicit; go 1.18
988 988
 github.com/moby/swarmkit/v2/agent
989 989
 github.com/moby/swarmkit/v2/agent/configs