1
The following changes since commit 6632f6ff96f0537fc34cdc00c760656fc62e23c5:
1
The following changes since commit 03a3a62fbd0aa5227e978eef3c67d3978aec9e5f:
2
2
3
Merge remote-tracking branch 'remotes/famz/tags/block-and-testing-pull-request' into staging (2017-07-17 11:46:36 +0100)
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-09-07 10:29:06 -0400)
4
4
5
are available in the git repository at:
5
are available in the git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to 189ae6bb5ce1f5a322f8691d00fe942ba43dd601:
9
for you to fetch changes up to 049cfda145e96b2605cdf9739f1bcf9ebf3a83e1:
10
10
11
virtio-net: fix offload ctrl endian (2017-07-17 20:13:56 +0800)
11
ebpf: Updated eBPF program and skeleton. (2023-09-08 14:33:46 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
- fix virtio-net ctrl offload endian
15
----------------------------------------------------------------
16
- vnet header support for variou COLO netfilters and compare thread
16
Andrew Melnychenko (7):
17
tap: Add USO support to tap device.
18
virtio-net: Add USO flags to vhost support.
19
ebpf: Added eBPF map update through mmap.
20
ebpf: Added eBPF initialization by fds.
21
virtio-net: Added property to load eBPF RSS with fds.
22
qmp: Added new command to retrieve eBPF blob.
23
ebpf: Updated eBPF program and skeleton.
17
24
18
----------------------------------------------------------------
25
Ilya Maximets (1):
19
Jason Wang (1):
26
net: add initial support for AF_XDP network backend
20
virtio-net: fix offload ctrl endian
21
27
22
Michal Privoznik (1):
28
Tomasz Dzieciol (7):
23
virtion-net: Prefer is_power_of_2()
29
igb: remove TCP ACK detection
30
igb: rename E1000E_RingInfo_st
31
igb: RX descriptors guest writting refactoring
32
igb: RX payload guest writting refactoring
33
igb: add IPv6 extended headers traffic detection
34
igb: packet-split descriptors support
35
e1000e: rename e1000e_ba_state and e1000e_write_hdr_to_rx_buffers
24
36
25
Zhang Chen (12):
37
Yuri Benditovich (2):
26
net: Add vnet_hdr_len arguments in NetClientState
38
tap: Add check for USO features
27
net/net.c: Add vnet_hdr support in SocketReadState
39
virtio-net: Add support for USO features
28
net/filter-mirror.c: Introduce parameter for filter_send()
29
net/filter-mirror.c: Make filter mirror support vnet support.
30
net/filter-mirror.c: Add new option to enable vnet support for filter-redirector
31
net/colo.c: Make vnet_hdr_len as packet property
32
net/colo-compare.c: Introduce parameter for compare_chr_send()
33
net/colo-compare.c: Make colo-compare support vnet_hdr_len
34
net/colo.c: Add vnet packet parse feature in colo-proxy
35
net/colo-compare.c: Add vnet packet's tcp/udp/icmp compare
36
net/filter-rewriter.c: Make filter-rewriter support vnet_hdr_len
37
docs/colo-proxy.txt: Update colo-proxy usage of net driver with vnet_header
38
40
39
docs/colo-proxy.txt | 26 ++++++++++++++++
41
MAINTAINERS | 4 +
40
hw/net/virtio-net.c | 4 ++-
42
ebpf/ebpf.c | 70 ++
41
include/net/net.h | 10 ++++--
43
ebpf/ebpf.h | 31 +
42
net/colo-compare.c | 84 ++++++++++++++++++++++++++++++++++++++++++---------
44
ebpf/ebpf_rss-stub.c | 6 +
43
net/colo.c | 9 +++---
45
ebpf/ebpf_rss.c | 150 ++-
44
net/colo.h | 4 ++-
46
ebpf/ebpf_rss.h | 10 +
45
net/filter-mirror.c | 75 +++++++++++++++++++++++++++++++++++++++++----
47
ebpf/meson.build | 2 +-
46
net/filter-rewriter.c | 37 ++++++++++++++++++++++-
48
ebpf/rss.bpf.skeleton.h | 1460 ++++++++++++-----------
47
net/net.c | 37 ++++++++++++++++++++---
49
hmp-commands.hx | 3 +
48
net/socket.c | 8 ++---
50
hw/core/machine.c | 4 +
49
qemu-options.hx | 19 ++++++------
51
hw/net/e1000e_core.c | 80 +-
50
11 files changed, 265 insertions(+), 48 deletions(-)
52
hw/net/igb_core.c | 732 ++++++++----
51
53
hw/net/igb_regs.h | 20 +-
52
54
hw/net/trace-events | 6 +-
55
hw/net/vhost_net.c | 3 +
56
hw/net/virtio-net.c | 90 +-
57
hw/net/vmxnet3.c | 2 +
58
include/hw/virtio/virtio-net.h | 1 +
59
include/net/net.h | 7 +-
60
meson.build | 19 +-
61
meson_options.txt | 2 +
62
net/af-xdp.c | 526 ++++++++
63
net/clients.h | 5 +
64
net/meson.build | 3 +
65
net/net.c | 19 +-
66
net/tap-bsd.c | 7 +-
67
net/tap-linux.c | 27 +-
68
net/tap-linux.h | 2 +
69
net/tap-solaris.c | 7 +-
70
net/tap-stub.c | 7 +-
71
net/tap-win32.c | 2 +-
72
net/tap.c | 18 +-
73
net/tap_int.h | 4 +-
74
net/vhost-vdpa.c | 3 +
75
qapi/ebpf.json | 66 +
76
qapi/meson.build | 1 +
77
qapi/net.json | 58 +
78
qapi/qapi-schema.json | 1 +
79
qemu-options.hx | 70 +-
80
scripts/ci/org.centos/stream/8/x86_64/configure | 1 +
81
scripts/meson-buildoptions.sh | 3 +
82
tests/docker/dockerfiles/debian-amd64.docker | 1 +
83
tests/qtest/libqos/igb.c | 5 +
84
tools/ebpf/rss.bpf.c | 5 +-
85
44 files changed, 2518 insertions(+), 1025 deletions(-)
86
create mode 100644 ebpf/ebpf.c
87
create mode 100644 ebpf/ebpf.h
88
create mode 100644 net/af-xdp.c
89
create mode 100644 qapi/ebpf.json
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
Add vnet_hdr_len arguments in NetClientState
3
Passing additional parameters (USOv4 and USOv6 offloads) when
4
that make other module get real vnet_hdr_len easily.
4
setting TAP offloads
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
include/net/net.h | 1 +
10
hw/net/e1000e_core.c | 2 +-
10
net/net.c | 1 +
11
hw/net/igb_core.c | 2 +-
11
2 files changed, 2 insertions(+)
12
hw/net/virtio-net.c | 4 +++-
13
hw/net/vmxnet3.c | 2 ++
14
include/net/net.h | 4 ++--
15
net/net.c | 4 ++--
16
net/tap-bsd.c | 2 +-
17
net/tap-linux.c | 15 ++++++++++++---
18
net/tap-linux.h | 2 ++
19
net/tap-solaris.c | 2 +-
20
net/tap-stub.c | 2 +-
21
net/tap-win32.c | 2 +-
22
net/tap.c | 6 +++---
23
net/tap_int.h | 3 ++-
24
14 files changed, 34 insertions(+), 18 deletions(-)
12
25
26
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/net/e1000e_core.c
29
+++ b/hw/net/e1000e_core.c
30
@@ -XXX,XX +XXX,XX @@ e1000e_update_rx_offloads(E1000ECore *core)
31
32
if (core->has_vnet) {
33
qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
34
- cso_state, 0, 0, 0, 0);
35
+ cso_state, 0, 0, 0, 0, 0, 0);
36
}
37
}
38
39
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/net/igb_core.c
42
+++ b/hw/net/igb_core.c
43
@@ -XXX,XX +XXX,XX @@ igb_update_rx_offloads(IGBCore *core)
44
45
if (core->has_vnet) {
46
qemu_set_offload(qemu_get_queue(core->owner_nic)->peer,
47
- cso_state, 0, 0, 0, 0);
48
+ cso_state, 0, 0, 0, 0, 0, 0);
49
}
50
}
51
52
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/net/virtio-net.c
55
+++ b/hw/net/virtio-net.c
56
@@ -XXX,XX +XXX,XX @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
57
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
58
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
59
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
60
- !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
61
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)),
62
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO4)),
63
+ !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6)));
64
}
65
66
static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
67
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/net/vmxnet3.c
70
+++ b/hw/net/vmxnet3.c
71
@@ -XXX,XX +XXX,XX @@ static void vmxnet3_update_features(VMXNET3State *s)
72
s->lro_supported,
73
s->lro_supported,
74
0,
75
+ 0,
76
+ 0,
77
0);
78
}
79
}
13
diff --git a/include/net/net.h b/include/net/net.h
80
diff --git a/include/net/net.h b/include/net/net.h
14
index XXXXXXX..XXXXXXX 100644
81
index XXXXXXX..XXXXXXX 100644
15
--- a/include/net/net.h
82
--- a/include/net/net.h
16
+++ b/include/net/net.h
83
+++ b/include/net/net.h
17
@@ -XXX,XX +XXX,XX @@ struct NetClientState {
84
@@ -XXX,XX +XXX,XX @@ typedef bool (HasVnetHdr)(NetClientState *);
18
unsigned int queue_index;
85
typedef bool (HasVnetHdrLen)(NetClientState *, int);
19
unsigned rxfilter_notify_enabled:1;
86
typedef bool (GetUsingVnetHdr)(NetClientState *);
20
int vring_enable;
87
typedef void (UsingVnetHdr)(NetClientState *, bool);
21
+ int vnet_hdr_len;
88
-typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
22
QTAILQ_HEAD(NetFilterHead, NetFilterState) filters;
89
+typedef void (SetOffload)(NetClientState *, int, int, int, int, int, int, int);
23
};
90
typedef int (GetVnetHdrLen)(NetClientState *);
24
91
typedef void (SetVnetHdrLen)(NetClientState *, int);
92
typedef int (SetVnetLE)(NetClientState *, bool);
93
@@ -XXX,XX +XXX,XX @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
94
bool qemu_get_using_vnet_hdr(NetClientState *nc);
95
void qemu_using_vnet_hdr(NetClientState *nc, bool enable);
96
void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
97
- int ecn, int ufo);
98
+ int ecn, int ufo, int uso4, int uso6);
99
int qemu_get_vnet_hdr_len(NetClientState *nc);
100
void qemu_set_vnet_hdr_len(NetClientState *nc, int len);
101
int qemu_set_vnet_le(NetClientState *nc, bool is_le);
25
diff --git a/net/net.c b/net/net.c
102
diff --git a/net/net.c b/net/net.c
26
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
27
--- a/net/net.c
104
--- a/net/net.c
28
+++ b/net/net.c
105
+++ b/net/net.c
29
@@ -XXX,XX +XXX,XX @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len)
106
@@ -XXX,XX +XXX,XX @@ void qemu_using_vnet_hdr(NetClientState *nc, bool enable)
107
}
108
109
void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6,
110
- int ecn, int ufo)
111
+ int ecn, int ufo, int uso4, int uso6)
112
{
113
if (!nc || !nc->info->set_offload) {
30
return;
114
return;
31
}
115
}
32
116
33
+ nc->vnet_hdr_len = len;
117
- nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo);
34
nc->info->set_vnet_hdr_len(nc, len);
118
+ nc->info->set_offload(nc, csum, tso4, tso6, ecn, ufo, uso4, uso6);
35
}
119
}
36
120
121
int qemu_get_vnet_hdr_len(NetClientState *nc)
122
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/net/tap-bsd.c
125
+++ b/net/tap-bsd.c
126
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
127
}
128
129
void tap_fd_set_offload(int fd, int csum, int tso4,
130
- int tso6, int ecn, int ufo)
131
+ int tso6, int ecn, int ufo, int uso4, int uso6)
132
{
133
}
134
135
diff --git a/net/tap-linux.c b/net/tap-linux.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/net/tap-linux.c
138
+++ b/net/tap-linux.c
139
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
140
}
141
142
void tap_fd_set_offload(int fd, int csum, int tso4,
143
- int tso6, int ecn, int ufo)
144
+ int tso6, int ecn, int ufo, int uso4, int uso6)
145
{
146
unsigned int offload = 0;
147
148
@@ -XXX,XX +XXX,XX @@ void tap_fd_set_offload(int fd, int csum, int tso4,
149
offload |= TUN_F_TSO_ECN;
150
if (ufo)
151
offload |= TUN_F_UFO;
152
+ if (uso4) {
153
+ offload |= TUN_F_USO4;
154
+ }
155
+ if (uso6) {
156
+ offload |= TUN_F_USO6;
157
+ }
158
}
159
160
if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
161
- offload &= ~TUN_F_UFO;
162
+ offload &= ~(TUN_F_USO4 | TUN_F_USO6);
163
if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
164
- fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
165
+ offload &= ~TUN_F_UFO;
166
+ if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) {
167
+ fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
168
strerror(errno));
169
+ }
170
}
171
}
172
}
173
diff --git a/net/tap-linux.h b/net/tap-linux.h
174
index XXXXXXX..XXXXXXX 100644
175
--- a/net/tap-linux.h
176
+++ b/net/tap-linux.h
177
@@ -XXX,XX +XXX,XX @@
178
#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
179
#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
180
#define TUN_F_UFO 0x10 /* I can handle UFO packets */
181
+#define TUN_F_USO4 0x20 /* I can handle USO for IPv4 packets */
182
+#define TUN_F_USO6 0x40 /* I can handle USO for IPv6 packets */
183
184
#endif /* QEMU_TAP_LINUX_H */
185
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
186
index XXXXXXX..XXXXXXX 100644
187
--- a/net/tap-solaris.c
188
+++ b/net/tap-solaris.c
189
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
190
}
191
192
void tap_fd_set_offload(int fd, int csum, int tso4,
193
- int tso6, int ecn, int ufo)
194
+ int tso6, int ecn, int ufo, int uso4, int uso6)
195
{
196
}
197
198
diff --git a/net/tap-stub.c b/net/tap-stub.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/net/tap-stub.c
201
+++ b/net/tap-stub.c
202
@@ -XXX,XX +XXX,XX @@ int tap_fd_set_vnet_be(int fd, int is_be)
203
}
204
205
void tap_fd_set_offload(int fd, int csum, int tso4,
206
- int tso6, int ecn, int ufo)
207
+ int tso6, int ecn, int ufo, int uso4, int uso6)
208
{
209
}
210
211
diff --git a/net/tap-win32.c b/net/tap-win32.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/net/tap-win32.c
214
+++ b/net/tap-win32.c
215
@@ -XXX,XX +XXX,XX @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
216
}
217
218
static void tap_set_offload(NetClientState *nc, int csum, int tso4,
219
- int tso6, int ecn, int ufo)
220
+ int tso6, int ecn, int ufo, int uso4, int uso6)
221
{
222
}
223
224
diff --git a/net/tap.c b/net/tap.c
225
index XXXXXXX..XXXXXXX 100644
226
--- a/net/tap.c
227
+++ b/net/tap.c
228
@@ -XXX,XX +XXX,XX @@ static int tap_set_vnet_be(NetClientState *nc, bool is_be)
229
}
230
231
static void tap_set_offload(NetClientState *nc, int csum, int tso4,
232
- int tso6, int ecn, int ufo)
233
+ int tso6, int ecn, int ufo, int uso4, int uso6)
234
{
235
TAPState *s = DO_UPCAST(TAPState, nc, nc);
236
if (s->fd < 0) {
237
return;
238
}
239
240
- tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
241
+ tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo, uso4, uso6);
242
}
243
244
static void tap_exit_notify(Notifier *notifier, void *data)
245
@@ -XXX,XX +XXX,XX @@ static TAPState *net_tap_fd_init(NetClientState *peer,
246
s->using_vnet_hdr = false;
247
s->has_ufo = tap_probe_has_ufo(s->fd);
248
s->enabled = true;
249
- tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
250
+ tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
251
/*
252
* Make sure host header length is set correctly in tap:
253
* it might have been modified by another instance of qemu.
254
diff --git a/net/tap_int.h b/net/tap_int.h
255
index XXXXXXX..XXXXXXX 100644
256
--- a/net/tap_int.h
257
+++ b/net/tap_int.h
258
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
259
int tap_probe_vnet_hdr(int fd, Error **errp);
260
int tap_probe_vnet_hdr_len(int fd, int len);
261
int tap_probe_has_ufo(int fd);
262
-void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo);
263
+void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
264
+ int uso4, int uso6);
265
void tap_fd_set_vnet_hdr_len(int fd, int len);
266
int tap_fd_set_vnet_le(int fd, int vnet_is_le);
267
int tap_fd_set_vnet_be(int fd, int vnet_is_be);
37
--
268
--
38
2.7.4
269
2.7.4
39
40
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
2
2
3
We add a flag to decide whether net_fill_rstate() need read
3
Tap indicates support for USO features according to
4
the vnet_hdr_len or not.
4
capabilities of current kernel module.
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
7
Suggested-by: Jason Wang <jasowang@redhat.com>
7
Signed-off-by: Andrew Melnychecnko <andrew@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
9
---
10
include/net/net.h | 9 +++++++--
10
include/net/net.h | 3 +++
11
net/colo-compare.c | 4 ++--
11
net/net.c | 9 +++++++++
12
net/filter-mirror.c | 2 +-
12
net/tap-bsd.c | 5 +++++
13
net/net.c | 36 ++++++++++++++++++++++++++++++++----
13
net/tap-linux.c | 12 ++++++++++++
14
net/socket.c | 8 ++++----
14
net/tap-solaris.c | 5 +++++
15
5 files changed, 46 insertions(+), 13 deletions(-)
15
net/tap-stub.c | 5 +++++
16
net/tap.c | 12 ++++++++++++
17
net/tap_int.h | 1 +
18
8 files changed, 52 insertions(+)
16
19
17
diff --git a/include/net/net.h b/include/net/net.h
20
diff --git a/include/net/net.h b/include/net/net.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/include/net/net.h
22
--- a/include/net/net.h
20
+++ b/include/net/net.h
23
+++ b/include/net/net.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct NICState {
24
@@ -XXX,XX +XXX,XX @@ typedef void (LinkStatusChanged)(NetClientState *);
22
} NICState;
25
typedef void (NetClientDestructor)(NetClientState *);
23
26
typedef RxFilterInfo *(QueryRxFilter)(NetClientState *);
24
struct SocketReadState {
27
typedef bool (HasUfo)(NetClientState *);
25
- int state; /* 0 = getting length, 1 = getting data */
28
+typedef bool (HasUso)(NetClientState *);
26
+ /* 0 = getting length, 1 = getting vnet header length, 2 = getting data */
29
typedef bool (HasVnetHdr)(NetClientState *);
27
+ int state;
30
typedef bool (HasVnetHdrLen)(NetClientState *, int);
28
+ /* This flag decide whether to read the vnet_hdr_len field */
31
typedef bool (GetUsingVnetHdr)(NetClientState *);
29
+ bool vnet_hdr;
32
@@ -XXX,XX +XXX,XX @@ typedef struct NetClientInfo {
30
uint32_t index;
33
QueryRxFilter *query_rx_filter;
31
uint32_t packet_len;
34
NetPoll *poll;
32
+ uint32_t vnet_hdr_len;
35
HasUfo *has_ufo;
33
uint8_t buf[NET_BUFSIZE];
36
+ HasUso *has_uso;
34
SocketReadStateFinalize *finalize;
37
HasVnetHdr *has_vnet_hdr;
35
};
38
HasVnetHdrLen *has_vnet_hdr_len;
36
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
39
GetUsingVnetHdr *get_using_vnet_hdr;
37
void print_net_client(Monitor *mon, NetClientState *nc);
40
@@ -XXX,XX +XXX,XX @@ void qemu_set_info_str(NetClientState *nc,
38
void hmp_info_network(Monitor *mon, const QDict *qdict);
41
const char *fmt, ...) G_GNUC_PRINTF(2, 3);
39
void net_socket_rs_init(SocketReadState *rs,
42
void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6]);
40
- SocketReadStateFinalize *finalize);
43
bool qemu_has_ufo(NetClientState *nc);
41
+ SocketReadStateFinalize *finalize,
44
+bool qemu_has_uso(NetClientState *nc);
42
+ bool vnet_hdr);
45
bool qemu_has_vnet_hdr(NetClientState *nc);
43
46
bool qemu_has_vnet_hdr_len(NetClientState *nc, int len);
44
/* NIC info */
47
bool qemu_get_using_vnet_hdr(NetClientState *nc);
45
46
diff --git a/net/colo-compare.c b/net/colo-compare.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/net/colo-compare.c
49
+++ b/net/colo-compare.c
50
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
51
return;
52
}
53
54
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize);
55
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize);
56
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
57
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
58
59
g_queue_init(&s->conn_list);
60
61
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/net/filter-mirror.c
64
+++ b/net/filter-mirror.c
65
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
66
}
67
}
68
69
- net_socket_rs_init(&s->rs, redirector_rs_finalize);
70
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
71
72
if (s->indev) {
73
chr = qemu_chr_find(s->indev);
74
diff --git a/net/net.c b/net/net.c
48
diff --git a/net/net.c b/net/net.c
75
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
76
--- a/net/net.c
50
--- a/net/net.c
77
+++ b/net/net.c
51
+++ b/net/net.c
78
@@ -XXX,XX +XXX,XX @@ QemuOptsList qemu_net_opts = {
52
@@ -XXX,XX +XXX,XX @@ bool qemu_has_ufo(NetClientState *nc)
79
};
53
return nc->info->has_ufo(nc);
80
54
}
81
void net_socket_rs_init(SocketReadState *rs,
55
82
- SocketReadStateFinalize *finalize)
56
+bool qemu_has_uso(NetClientState *nc)
83
+ SocketReadStateFinalize *finalize,
57
+{
84
+ bool vnet_hdr)
58
+ if (!nc || !nc->info->has_uso) {
59
+ return false;
60
+ }
61
+
62
+ return nc->info->has_uso(nc);
63
+}
64
+
65
bool qemu_has_vnet_hdr(NetClientState *nc)
85
{
66
{
86
rs->state = 0;
67
if (!nc || !nc->info->has_vnet_hdr) {
87
+ rs->vnet_hdr = vnet_hdr;
68
diff --git a/net/tap-bsd.c b/net/tap-bsd.c
88
rs->index = 0;
69
index XXXXXXX..XXXXXXX 100644
89
rs->packet_len = 0;
70
--- a/net/tap-bsd.c
90
+ rs->vnet_hdr_len = 0;
71
+++ b/net/tap-bsd.c
91
memset(rs->buf, 0, sizeof(rs->buf));
72
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
92
rs->finalize = finalize;
73
return 0;
93
}
74
}
94
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
75
95
unsigned int l;
76
+int tap_probe_has_uso(int fd)
96
77
+{
97
while (size > 0) {
78
+ return 0;
98
- /* reassemble a packet from the network */
79
+}
99
- switch (rs->state) { /* 0 = getting length, 1 = getting data */
80
+
100
+ /* Reassemble a packet from the network.
81
int tap_probe_vnet_hdr_len(int fd, int len)
101
+ * 0 = getting length.
82
{
102
+ * 1 = getting vnet header length.
83
return 0;
103
+ * 2 = getting data.
84
diff --git a/net/tap-linux.c b/net/tap-linux.c
104
+ */
105
+ switch (rs->state) {
106
case 0:
107
l = 4 - rs->index;
108
if (l > size) {
109
@@ -XXX,XX +XXX,XX @@ int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
110
/* got length */
111
rs->packet_len = ntohl(*(uint32_t *)rs->buf);
112
rs->index = 0;
113
- rs->state = 1;
114
+ if (rs->vnet_hdr) {
115
+ rs->state = 1;
116
+ } else {
117
+ rs->state = 2;
118
+ rs->vnet_hdr_len = 0;
119
+ }
120
}
121
break;
122
case 1:
123
+ l = 4 - rs->index;
124
+ if (l > size) {
125
+ l = size;
126
+ }
127
+ memcpy(rs->buf + rs->index, buf, l);
128
+ buf += l;
129
+ size -= l;
130
+ rs->index += l;
131
+ if (rs->index == 4) {
132
+ /* got vnet header length */
133
+ rs->vnet_hdr_len = ntohl(*(uint32_t *)rs->buf);
134
+ rs->index = 0;
135
+ rs->state = 2;
136
+ }
137
+ break;
138
+ case 2:
139
l = rs->packet_len - rs->index;
140
if (l > size) {
141
l = size;
142
diff --git a/net/socket.c b/net/socket.c
143
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
144
--- a/net/socket.c
86
--- a/net/tap-linux.c
145
+++ b/net/socket.c
87
+++ b/net/tap-linux.c
146
@@ -XXX,XX +XXX,XX @@ static void net_socket_send(void *opaque)
88
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
147
closesocket(s->fd);
89
return 1;
148
90
}
149
s->fd = -1;
91
150
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
92
+int tap_probe_has_uso(int fd)
151
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
93
+{
152
s->nc.link_down = true;
94
+ unsigned offload;
153
memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
95
+
154
96
+ offload = TUN_F_CSUM | TUN_F_USO4 | TUN_F_USO6;
155
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
97
+
156
s->fd = fd;
98
+ if (ioctl(fd, TUNSETOFFLOAD, offload) < 0) {
157
s->listen_fd = -1;
99
+ return 0;
158
s->send_fn = net_socket_send_dgram;
100
+ }
159
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
101
+ return 1;
160
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
102
+}
161
net_socket_read_poll(s, true);
103
+
162
104
/* Verify that we can assign given length */
163
/* mcast: save bound address as dst */
105
int tap_probe_vnet_hdr_len(int fd, int len)
164
@@ -XXX,XX +XXX,XX @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
106
{
165
107
diff --git a/net/tap-solaris.c b/net/tap-solaris.c
166
s->fd = fd;
108
index XXXXXXX..XXXXXXX 100644
167
s->listen_fd = -1;
109
--- a/net/tap-solaris.c
168
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
110
+++ b/net/tap-solaris.c
169
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
111
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
170
171
/* Disable Nagle algorithm on TCP sockets to reduce latency */
172
socket_set_nodelay(fd);
173
@@ -XXX,XX +XXX,XX @@ static int net_socket_listen_init(NetClientState *peer,
174
s->fd = -1;
175
s->listen_fd = fd;
176
s->nc.link_down = true;
177
- net_socket_rs_init(&s->rs, net_socket_rs_finalize);
178
+ net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);
179
180
qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
181
return 0;
112
return 0;
113
}
114
115
+int tap_probe_has_uso(int fd)
116
+{
117
+ return 0;
118
+}
119
+
120
int tap_probe_vnet_hdr_len(int fd, int len)
121
{
122
return 0;
123
diff --git a/net/tap-stub.c b/net/tap-stub.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/net/tap-stub.c
126
+++ b/net/tap-stub.c
127
@@ -XXX,XX +XXX,XX @@ int tap_probe_has_ufo(int fd)
128
return 0;
129
}
130
131
+int tap_probe_has_uso(int fd)
132
+{
133
+ return 0;
134
+}
135
+
136
int tap_probe_vnet_hdr_len(int fd, int len)
137
{
138
return 0;
139
diff --git a/net/tap.c b/net/tap.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/net/tap.c
142
+++ b/net/tap.c
143
@@ -XXX,XX +XXX,XX @@ typedef struct TAPState {
144
bool write_poll;
145
bool using_vnet_hdr;
146
bool has_ufo;
147
+ bool has_uso;
148
bool enabled;
149
VHostNetState *vhost_net;
150
unsigned host_vnet_hdr_len;
151
@@ -XXX,XX +XXX,XX @@ static bool tap_has_ufo(NetClientState *nc)
152
return s->has_ufo;
153
}
154
155
+static bool tap_has_uso(NetClientState *nc)
156
+{
157
+ TAPState *s = DO_UPCAST(TAPState, nc, nc);
158
+
159
+ assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
160
+
161
+ return s->has_uso;
162
+}
163
+
164
static bool tap_has_vnet_hdr(NetClientState *nc)
165
{
166
TAPState *s = DO_UPCAST(TAPState, nc, nc);
167
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_tap_info = {
168
.poll = tap_poll,
169
.cleanup = tap_cleanup,
170
.has_ufo = tap_has_ufo,
171
+ .has_uso = tap_has_uso,
172
.has_vnet_hdr = tap_has_vnet_hdr,
173
.has_vnet_hdr_len = tap_has_vnet_hdr_len,
174
.get_using_vnet_hdr = tap_get_using_vnet_hdr,
175
@@ -XXX,XX +XXX,XX @@ static TAPState *net_tap_fd_init(NetClientState *peer,
176
s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
177
s->using_vnet_hdr = false;
178
s->has_ufo = tap_probe_has_ufo(s->fd);
179
+ s->has_uso = tap_probe_has_uso(s->fd);
180
s->enabled = true;
181
tap_set_offload(&s->nc, 0, 0, 0, 0, 0, 0, 0);
182
/*
183
diff --git a/net/tap_int.h b/net/tap_int.h
184
index XXXXXXX..XXXXXXX 100644
185
--- a/net/tap_int.h
186
+++ b/net/tap_int.h
187
@@ -XXX,XX +XXX,XX @@ void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp);
188
int tap_probe_vnet_hdr(int fd, Error **errp);
189
int tap_probe_vnet_hdr_len(int fd, int len);
190
int tap_probe_has_ufo(int fd);
191
+int tap_probe_has_uso(int fd);
192
void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo,
193
int uso4, int uso6);
194
void tap_fd_set_vnet_hdr_len(int fd, int len);
182
--
195
--
183
2.7.4
196
2.7.4
184
185
diff view generated by jsdifflib
New patch
1
From: Andrew Melnychenko <andrew@daynix.com>
1
2
3
New features are subject to check with vhost-user and vdpa.
4
5
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
6
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
hw/net/vhost_net.c | 3 +++
10
net/vhost-vdpa.c | 3 +++
11
2 files changed, 6 insertions(+)
12
13
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/vhost_net.c
16
+++ b/hw/net/vhost_net.c
17
@@ -XXX,XX +XXX,XX @@ static const int user_feature_bits[] = {
18
VIRTIO_F_RING_RESET,
19
VIRTIO_NET_F_RSS,
20
VIRTIO_NET_F_HASH_REPORT,
21
+ VIRTIO_NET_F_GUEST_USO4,
22
+ VIRTIO_NET_F_GUEST_USO6,
23
+ VIRTIO_NET_F_HOST_USO,
24
25
/* This bit implies RARP isn't sent by QEMU out of band */
26
VIRTIO_NET_F_GUEST_ANNOUNCE,
27
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/net/vhost-vdpa.c
30
+++ b/net/vhost-vdpa.c
31
@@ -XXX,XX +XXX,XX @@ const int vdpa_feature_bits[] = {
32
VIRTIO_NET_F_GUEST_TSO4,
33
VIRTIO_NET_F_GUEST_TSO6,
34
VIRTIO_NET_F_GUEST_UFO,
35
+ VIRTIO_NET_F_GUEST_USO4,
36
+ VIRTIO_NET_F_GUEST_USO6,
37
VIRTIO_NET_F_HASH_REPORT,
38
VIRTIO_NET_F_HOST_ECN,
39
VIRTIO_NET_F_HOST_TSO4,
40
VIRTIO_NET_F_HOST_TSO6,
41
VIRTIO_NET_F_HOST_UFO,
42
+ VIRTIO_NET_F_HOST_USO,
43
VIRTIO_NET_F_MQ,
44
VIRTIO_NET_F_MRG_RXBUF,
45
VIRTIO_NET_F_MTU,
46
--
47
2.7.4
diff view generated by jsdifflib
1
Spec said offloads should be le64, so use virtio_ldq_p() to guarantee
1
From: Yuri Benditovich <yuri.benditovich@daynix.com>
2
valid endian.
3
2
4
Fixes: 644c98587d4c ("virtio-net: dynamic network offloads configuration")
3
USO features of virtio-net device depend on kernel ability
5
Cc: qemu-stable@nongnu.org
4
to support them, for backward compatibility by default the
6
Cc: Dmitry Fleytman <dfleytma@redhat.com>
5
features are disabled on 8.0 and earlier.
6
7
Signed-off-by: Yuri Benditovich <yuri.benditovich@daynix.com>
8
Signed-off-by: Andrew Melnychecnko <andrew@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
hw/net/virtio-net.c | 2 ++
11
hw/core/machine.c | 4 ++++
10
1 file changed, 2 insertions(+)
12
hw/net/virtio-net.c | 31 +++++++++++++++++++++++++++++--
13
2 files changed, 33 insertions(+), 2 deletions(-)
11
14
15
diff --git a/hw/core/machine.c b/hw/core/machine.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/core/machine.c
18
+++ b/hw/core/machine.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "exec/confidential-guest-support.h"
21
#include "hw/virtio/virtio.h"
22
#include "hw/virtio/virtio-pci.h"
23
+#include "hw/virtio/virtio-net.h"
24
25
GlobalProperty hw_compat_8_1[] = {};
26
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
27
@@ -XXX,XX +XXX,XX @@ const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
28
GlobalProperty hw_compat_8_0[] = {
29
{ "migration", "multifd-flush-after-each-section", "on"},
30
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
31
+ { TYPE_VIRTIO_NET, "host_uso", "off"},
32
+ { TYPE_VIRTIO_NET, "guest_uso4", "off"},
33
+ { TYPE_VIRTIO_NET, "guest_uso6", "off"},
34
};
35
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
36
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
37
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
13
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
39
--- a/hw/net/virtio-net.c
15
+++ b/hw/net/virtio-net.c
40
+++ b/hw/net/virtio-net.c
16
@@ -XXX,XX +XXX,XX @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
41
@@ -XXX,XX +XXX,XX @@ static int peer_has_ufo(VirtIONet *n)
17
if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
42
return n->has_ufo;
18
uint64_t supported_offloads;
43
}
19
44
20
+ offloads = virtio_ldq_p(vdev, &offloads);
45
+static int peer_has_uso(VirtIONet *n)
46
+{
47
+ if (!peer_has_vnet_hdr(n)) {
48
+ return 0;
49
+ }
21
+
50
+
22
if (!n->has_vnet_hdr) {
51
+ return qemu_has_uso(qemu_get_queue(n->nic)->peer);
23
return VIRTIO_NET_ERR;
52
+}
24
}
53
+
54
static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs,
55
int version_1, int hash_report)
56
{
57
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
58
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_TSO6);
59
virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_ECN);
60
61
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
62
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
63
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
64
+
65
virtio_clear_feature(&features, VIRTIO_NET_F_HASH_REPORT);
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features,
69
virtio_clear_feature(&features, VIRTIO_NET_F_HOST_UFO);
70
}
71
72
+ if (!peer_has_uso(n)) {
73
+ virtio_clear_feature(&features, VIRTIO_NET_F_HOST_USO);
74
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO4);
75
+ virtio_clear_feature(&features, VIRTIO_NET_F_GUEST_USO6);
76
+ }
77
+
78
if (!get_vhost_net(nc->peer)) {
79
return features;
80
}
81
@@ -XXX,XX +XXX,XX @@ static void virtio_net_apply_guest_offloads(VirtIONet *n)
82
!!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_USO6)));
83
}
84
85
-static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
86
+static uint64_t virtio_net_guest_offloads_by_features(uint64_t features)
87
{
88
static const uint64_t guest_offloads_mask =
89
(1ULL << VIRTIO_NET_F_GUEST_CSUM) |
90
(1ULL << VIRTIO_NET_F_GUEST_TSO4) |
91
(1ULL << VIRTIO_NET_F_GUEST_TSO6) |
92
(1ULL << VIRTIO_NET_F_GUEST_ECN) |
93
- (1ULL << VIRTIO_NET_F_GUEST_UFO);
94
+ (1ULL << VIRTIO_NET_F_GUEST_UFO) |
95
+ (1ULL << VIRTIO_NET_F_GUEST_USO4) |
96
+ (1ULL << VIRTIO_NET_F_GUEST_USO6);
97
98
return guest_offloads_mask & features;
99
}
100
@@ -XXX,XX +XXX,XX @@ static Property virtio_net_properties[] = {
101
DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
102
DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
103
DEFINE_PROP_BOOL("failover", VirtIONet, failover, false),
104
+ DEFINE_PROP_BIT64("guest_uso4", VirtIONet, host_features,
105
+ VIRTIO_NET_F_GUEST_USO4, true),
106
+ DEFINE_PROP_BIT64("guest_uso6", VirtIONet, host_features,
107
+ VIRTIO_NET_F_GUEST_USO6, true),
108
+ DEFINE_PROP_BIT64("host_uso", VirtIONet, host_features,
109
+ VIRTIO_NET_F_HOST_USO, true),
110
DEFINE_PROP_END_OF_LIST(),
111
};
112
25
--
113
--
26
2.7.4
114
2.7.4
27
28
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
COLO-Proxy just focus on packet payload, so we skip vnet header.
3
TCP ACK detection is no longer present in igb.
4
4
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
9
---
8
net/colo-compare.c | 8 ++++++--
10
hw/net/igb_core.c | 5 -----
9
1 file changed, 6 insertions(+), 2 deletions(-)
11
1 file changed, 5 deletions(-)
10
12
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
15
--- a/hw/net/igb_core.c
14
+++ b/net/colo-compare.c
16
+++ b/hw/net/igb_core.c
15
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_common(Packet *ppkt, Packet *spkt, int offset)
17
@@ -XXX,XX +XXX,XX @@ igb_build_rx_metadata(IGBCore *core,
16
sec_ip_src, sec_ip_dst);
18
trace_e1000e_rx_metadata_ip_id(*ip_id);
17
}
19
}
18
20
19
+ offset = ppkt->vnet_hdr_len + offset;
21
- if (l4hdr_proto == ETH_L4_HDR_PROTO_TCP && net_rx_pkt_is_tcp_ack(pkt)) {
20
+
22
- *status_flags |= E1000_RXD_STAT_ACK;
21
if (ppkt->size == spkt->size) {
23
- trace_e1000e_rx_metadata_ack();
22
- return memcmp(ppkt->data + offset, spkt->data + offset,
24
- }
23
+ return memcmp(ppkt->data + offset,
25
-
24
+ spkt->data + offset,
26
if (pkt_info) {
25
spkt->size - offset);
27
*pkt_info = rss_info->enabled ? rss_info->type : 0;
26
} else {
28
27
trace_colo_compare_main("Net packet size are not the same");
28
@@ -XXX,XX +XXX,XX @@ static int colo_packet_compare_tcp(Packet *spkt, Packet *ppkt)
29
*/
30
if (ptcp->th_off > 5) {
31
ptrdiff_t tcp_offset;
32
+
33
tcp_offset = ppkt->transport_header - (uint8_t *)ppkt->data
34
- + (ptcp->th_off * 4);
35
+ + (ptcp->th_off * 4) - ppkt->vnet_hdr_len;
36
res = colo_packet_compare_common(ppkt, spkt, tcp_offset);
37
} else if (ptcp->th_sum == stcp->th_sum) {
38
res = colo_packet_compare_common(ppkt, spkt, ETH_HLEN);
39
--
29
--
40
2.7.4
30
2.7.4
41
42
diff view generated by jsdifflib
New patch
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
1
2
3
Rename E1000E_RingInfo_st and E1000E_RingInfo according to qemu typdefs guide.
4
5
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
hw/net/e1000e_core.c | 34 +++++++++++++++++-----------------
11
hw/net/igb_core.c | 42 +++++++++++++++++++++---------------------
12
2 files changed, 38 insertions(+), 38 deletions(-)
13
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/e1000e_core.c
17
+++ b/hw/net/e1000e_core.c
18
@@ -XXX,XX +XXX,XX @@ e1000e_txdesc_writeback(E1000ECore *core, dma_addr_t base,
19
return e1000e_tx_wb_interrupt_cause(core, queue_idx);
20
}
21
22
-typedef struct E1000E_RingInfo_st {
23
+typedef struct E1000ERingInfo {
24
int dbah;
25
int dbal;
26
int dlen;
27
int dh;
28
int dt;
29
int idx;
30
-} E1000E_RingInfo;
31
+} E1000ERingInfo;
32
33
static inline bool
34
-e1000e_ring_empty(E1000ECore *core, const E1000E_RingInfo *r)
35
+e1000e_ring_empty(E1000ECore *core, const E1000ERingInfo *r)
36
{
37
return core->mac[r->dh] == core->mac[r->dt] ||
38
core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN;
39
}
40
41
static inline uint64_t
42
-e1000e_ring_base(E1000ECore *core, const E1000E_RingInfo *r)
43
+e1000e_ring_base(E1000ECore *core, const E1000ERingInfo *r)
44
{
45
uint64_t bah = core->mac[r->dbah];
46
uint64_t bal = core->mac[r->dbal];
47
@@ -XXX,XX +XXX,XX @@ e1000e_ring_base(E1000ECore *core, const E1000E_RingInfo *r)
48
}
49
50
static inline uint64_t
51
-e1000e_ring_head_descr(E1000ECore *core, const E1000E_RingInfo *r)
52
+e1000e_ring_head_descr(E1000ECore *core, const E1000ERingInfo *r)
53
{
54
return e1000e_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh];
55
}
56
57
static inline void
58
-e1000e_ring_advance(E1000ECore *core, const E1000E_RingInfo *r, uint32_t count)
59
+e1000e_ring_advance(E1000ECore *core, const E1000ERingInfo *r, uint32_t count)
60
{
61
core->mac[r->dh] += count;
62
63
@@ -XXX,XX +XXX,XX @@ e1000e_ring_advance(E1000ECore *core, const E1000E_RingInfo *r, uint32_t count)
64
}
65
66
static inline uint32_t
67
-e1000e_ring_free_descr_num(E1000ECore *core, const E1000E_RingInfo *r)
68
+e1000e_ring_free_descr_num(E1000ECore *core, const E1000ERingInfo *r)
69
{
70
trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen],
71
core->mac[r->dh], core->mac[r->dt]);
72
@@ -XXX,XX +XXX,XX @@ e1000e_ring_free_descr_num(E1000ECore *core, const E1000E_RingInfo *r)
73
}
74
75
static inline bool
76
-e1000e_ring_enabled(E1000ECore *core, const E1000E_RingInfo *r)
77
+e1000e_ring_enabled(E1000ECore *core, const E1000ERingInfo *r)
78
{
79
return core->mac[r->dlen] > 0;
80
}
81
82
static inline uint32_t
83
-e1000e_ring_len(E1000ECore *core, const E1000E_RingInfo *r)
84
+e1000e_ring_len(E1000ECore *core, const E1000ERingInfo *r)
85
{
86
return core->mac[r->dlen];
87
}
88
89
typedef struct E1000E_TxRing_st {
90
- const E1000E_RingInfo *i;
91
+ const E1000ERingInfo *i;
92
struct e1000e_tx *tx;
93
} E1000E_TxRing;
94
95
@@ -XXX,XX +XXX,XX @@ e1000e_mq_queue_idx(int base_reg_idx, int reg_idx)
96
static inline void
97
e1000e_tx_ring_init(E1000ECore *core, E1000E_TxRing *txr, int idx)
98
{
99
- static const E1000E_RingInfo i[E1000E_NUM_QUEUES] = {
100
+ static const E1000ERingInfo i[E1000E_NUM_QUEUES] = {
101
{ TDBAH, TDBAL, TDLEN, TDH, TDT, 0 },
102
{ TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 }
103
};
104
@@ -XXX,XX +XXX,XX @@ e1000e_tx_ring_init(E1000ECore *core, E1000E_TxRing *txr, int idx)
105
}
106
107
typedef struct E1000E_RxRing_st {
108
- const E1000E_RingInfo *i;
109
+ const E1000ERingInfo *i;
110
} E1000E_RxRing;
111
112
static inline void
113
e1000e_rx_ring_init(E1000ECore *core, E1000E_RxRing *rxr, int idx)
114
{
115
- static const E1000E_RingInfo i[E1000E_NUM_QUEUES] = {
116
+ static const E1000ERingInfo i[E1000E_NUM_QUEUES] = {
117
{ RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 },
118
{ RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 }
119
};
120
@@ -XXX,XX +XXX,XX @@ e1000e_start_xmit(E1000ECore *core, const E1000E_TxRing *txr)
121
dma_addr_t base;
122
struct e1000_tx_desc desc;
123
bool ide = false;
124
- const E1000E_RingInfo *txi = txr->i;
125
+ const E1000ERingInfo *txi = txr->i;
126
uint32_t cause = E1000_ICS_TXQE;
127
128
if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
129
@@ -XXX,XX +XXX,XX @@ e1000e_start_xmit(E1000ECore *core, const E1000E_TxRing *txr)
130
}
131
132
static bool
133
-e1000e_has_rxbufs(E1000ECore *core, const E1000E_RingInfo *r,
134
+e1000e_has_rxbufs(E1000ECore *core, const E1000ERingInfo *r,
135
size_t total_size)
136
{
137
uint32_t bufs = e1000e_ring_free_descr_num(core, r);
138
@@ -XXX,XX +XXX,XX @@ e1000e_update_rx_stats(E1000ECore *core, size_t pkt_size, size_t pkt_fcs_size)
139
}
140
141
static inline bool
142
-e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000E_RingInfo *rxi)
143
+e1000e_rx_descr_threshold_hit(E1000ECore *core, const E1000ERingInfo *rxi)
144
{
145
return e1000e_ring_free_descr_num(core, rxi) ==
146
e1000e_ring_len(core, rxi) >> core->rxbuf_min_shift;
147
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
148
struct iovec *iov = net_rx_pkt_get_iovec(pkt);
149
size_t size = net_rx_pkt_get_total_len(pkt);
150
size_t total_size = size + e1000x_fcs_len(core->mac);
151
- const E1000E_RingInfo *rxi;
152
+ const E1000ERingInfo *rxi;
153
size_t ps_hdr_len = 0;
154
bool do_ps = e1000e_do_ps(core, pkt, &ps_hdr_len);
155
bool is_first = true;
156
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/hw/net/igb_core.c
159
+++ b/hw/net/igb_core.c
160
@@ -XXX,XX +XXX,XX @@ static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx)
161
return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
162
}
163
164
-typedef struct E1000E_RingInfo_st {
165
+typedef struct E1000ERingInfo {
166
int dbah;
167
int dbal;
168
int dlen;
169
int dh;
170
int dt;
171
int idx;
172
-} E1000E_RingInfo;
173
+} E1000ERingInfo;
174
175
static inline bool
176
-igb_ring_empty(IGBCore *core, const E1000E_RingInfo *r)
177
+igb_ring_empty(IGBCore *core, const E1000ERingInfo *r)
178
{
179
return core->mac[r->dh] == core->mac[r->dt] ||
180
core->mac[r->dt] >= core->mac[r->dlen] / E1000_RING_DESC_LEN;
181
}
182
183
static inline uint64_t
184
-igb_ring_base(IGBCore *core, const E1000E_RingInfo *r)
185
+igb_ring_base(IGBCore *core, const E1000ERingInfo *r)
186
{
187
uint64_t bah = core->mac[r->dbah];
188
uint64_t bal = core->mac[r->dbal];
189
@@ -XXX,XX +XXX,XX @@ igb_ring_base(IGBCore *core, const E1000E_RingInfo *r)
190
}
191
192
static inline uint64_t
193
-igb_ring_head_descr(IGBCore *core, const E1000E_RingInfo *r)
194
+igb_ring_head_descr(IGBCore *core, const E1000ERingInfo *r)
195
{
196
return igb_ring_base(core, r) + E1000_RING_DESC_LEN * core->mac[r->dh];
197
}
198
199
static inline void
200
-igb_ring_advance(IGBCore *core, const E1000E_RingInfo *r, uint32_t count)
201
+igb_ring_advance(IGBCore *core, const E1000ERingInfo *r, uint32_t count)
202
{
203
core->mac[r->dh] += count;
204
205
@@ -XXX,XX +XXX,XX @@ igb_ring_advance(IGBCore *core, const E1000E_RingInfo *r, uint32_t count)
206
}
207
208
static inline uint32_t
209
-igb_ring_free_descr_num(IGBCore *core, const E1000E_RingInfo *r)
210
+igb_ring_free_descr_num(IGBCore *core, const E1000ERingInfo *r)
211
{
212
trace_e1000e_ring_free_space(r->idx, core->mac[r->dlen],
213
core->mac[r->dh], core->mac[r->dt]);
214
@@ -XXX,XX +XXX,XX @@ igb_ring_free_descr_num(IGBCore *core, const E1000E_RingInfo *r)
215
}
216
217
static inline bool
218
-igb_ring_enabled(IGBCore *core, const E1000E_RingInfo *r)
219
+igb_ring_enabled(IGBCore *core, const E1000ERingInfo *r)
220
{
221
return core->mac[r->dlen] > 0;
222
}
223
224
typedef struct IGB_TxRing_st {
225
- const E1000E_RingInfo *i;
226
+ const E1000ERingInfo *i;
227
struct igb_tx *tx;
228
} IGB_TxRing;
229
230
@@ -XXX,XX +XXX,XX @@ igb_mq_queue_idx(int base_reg_idx, int reg_idx)
231
static inline void
232
igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx)
233
{
234
- static const E1000E_RingInfo i[IGB_NUM_QUEUES] = {
235
+ static const E1000ERingInfo i[IGB_NUM_QUEUES] = {
236
{ TDBAH0, TDBAL0, TDLEN0, TDH0, TDT0, 0 },
237
{ TDBAH1, TDBAL1, TDLEN1, TDH1, TDT1, 1 },
238
{ TDBAH2, TDBAL2, TDLEN2, TDH2, TDT2, 2 },
239
@@ -XXX,XX +XXX,XX @@ igb_tx_ring_init(IGBCore *core, IGB_TxRing *txr, int idx)
240
}
241
242
typedef struct E1000E_RxRing_st {
243
- const E1000E_RingInfo *i;
244
+ const E1000ERingInfo *i;
245
} E1000E_RxRing;
246
247
static inline void
248
igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, int idx)
249
{
250
- static const E1000E_RingInfo i[IGB_NUM_QUEUES] = {
251
+ static const E1000ERingInfo i[IGB_NUM_QUEUES] = {
252
{ RDBAH0, RDBAL0, RDLEN0, RDH0, RDT0, 0 },
253
{ RDBAH1, RDBAL1, RDLEN1, RDH1, RDT1, 1 },
254
{ RDBAH2, RDBAL2, RDLEN2, RDH2, RDT2, 2 },
255
@@ -XXX,XX +XXX,XX @@ igb_rx_ring_init(IGBCore *core, E1000E_RxRing *rxr, int idx)
256
static uint32_t
257
igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
258
union e1000_adv_tx_desc *tx_desc,
259
- const E1000E_RingInfo *txi)
260
+ const E1000ERingInfo *txi)
261
{
262
PCIDevice *d;
263
uint32_t cmd_type_len = le32_to_cpu(tx_desc->read.cmd_type_len);
264
@@ -XXX,XX +XXX,XX @@ igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
265
}
266
267
static inline bool
268
-igb_tx_enabled(IGBCore *core, const E1000E_RingInfo *txi)
269
+igb_tx_enabled(IGBCore *core, const E1000ERingInfo *txi)
270
{
271
bool vmdq = core->mac[MRQC] & 1;
272
uint16_t qn = txi->idx;
273
@@ -XXX,XX +XXX,XX @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
274
PCIDevice *d;
275
dma_addr_t base;
276
union e1000_adv_tx_desc desc;
277
- const E1000E_RingInfo *txi = txr->i;
278
+ const E1000ERingInfo *txi = txr->i;
279
uint32_t eic = 0;
280
281
if (!igb_tx_enabled(core, txi)) {
282
@@ -XXX,XX +XXX,XX @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
283
}
284
285
static uint32_t
286
-igb_rxbufsize(IGBCore *core, const E1000E_RingInfo *r)
287
+igb_rxbufsize(IGBCore *core, const E1000ERingInfo *r)
288
{
289
uint32_t srrctl = core->mac[E1000_SRRCTL(r->idx) >> 2];
290
uint32_t bsizepkt = srrctl & E1000_SRRCTL_BSIZEPKT_MASK;
291
@@ -XXX,XX +XXX,XX @@ igb_rxbufsize(IGBCore *core, const E1000E_RingInfo *r)
292
}
293
294
static bool
295
-igb_has_rxbufs(IGBCore *core, const E1000E_RingInfo *r, size_t total_size)
296
+igb_has_rxbufs(IGBCore *core, const E1000ERingInfo *r, size_t total_size)
297
{
298
uint32_t bufs = igb_ring_free_descr_num(core, r);
299
uint32_t bufsize = igb_rxbufsize(core, r);
300
@@ -XXX,XX +XXX,XX @@ igb_write_to_rx_buffers(IGBCore *core,
301
}
302
303
static void
304
-igb_update_rx_stats(IGBCore *core, const E1000E_RingInfo *rxi,
305
+igb_update_rx_stats(IGBCore *core, const E1000ERingInfo *rxi,
306
size_t pkt_size, size_t pkt_fcs_size)
307
{
308
eth_pkt_types_e pkt_type = net_rx_pkt_get_packet_type(core->rx_pkt);
309
@@ -XXX,XX +XXX,XX @@ igb_update_rx_stats(IGBCore *core, const E1000E_RingInfo *rxi,
310
}
311
312
static inline bool
313
-igb_rx_descr_threshold_hit(IGBCore *core, const E1000E_RingInfo *rxi)
314
+igb_rx_descr_threshold_hit(IGBCore *core, const E1000ERingInfo *rxi)
315
{
316
return igb_ring_free_descr_num(core, rxi) ==
317
((core->mac[E1000_SRRCTL(rxi->idx) >> 2] >> 20) & 31) * 16;
318
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
319
struct iovec *iov = net_rx_pkt_get_iovec(pkt);
320
size_t size = net_rx_pkt_get_total_len(pkt);
321
size_t total_size = size + e1000x_fcs_len(core->mac);
322
- const E1000E_RingInfo *rxi = rxr->i;
323
+ const E1000ERingInfo *rxi = rxr->i;
324
size_t bufsize = igb_rxbufsize(core, rxi);
325
326
d = pcie_sriov_get_vf_at_index(core->owner, rxi->idx % 8);
327
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
328
}
329
330
static bool
331
-igb_rx_strip_vlan(IGBCore *core, const E1000E_RingInfo *rxi)
332
+igb_rx_strip_vlan(IGBCore *core, const E1000ERingInfo *rxi)
333
{
334
if (core->mac[MRQC] & 1) {
335
uint16_t pool = rxi->idx % IGB_NUM_VM_POOLS;
336
--
337
2.7.4
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
We add the vnet_hdr_support option for filter-rewriter, default is disabled.
3
Refactoring is done in preparation for support of multiple advanced
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
descriptors RX modes, especially packet-split modes.
5
You can use it for example:
6
-object filter-rewriter,id=rew0,netdev=hn0,queue=all,vnet_hdr_support
7
5
8
We get the vnet_hdr_len from NetClientState that make us
6
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
9
parse net packet correctly.
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
10
8
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
11
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
10
---
14
net/filter-rewriter.c | 37 ++++++++++++++++++++++++++++++++++++-
11
hw/net/igb_core.c | 170 +++++++++++++++++++++++++++-------------------------
15
qemu-options.hx | 4 ++--
12
hw/net/igb_regs.h | 10 ++--
16
2 files changed, 38 insertions(+), 3 deletions(-)
13
hw/net/trace-events | 4 +-
14
3 files changed, 96 insertions(+), 88 deletions(-)
17
15
18
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
16
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/net/filter-rewriter.c
18
--- a/hw/net/igb_core.c
21
+++ b/net/filter-rewriter.c
19
+++ b/hw/net/igb_core.c
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ igb_verify_csum_in_sw(IGBCore *core,
23
#include "qemu-common.h"
24
#include "qapi/error.h"
25
#include "qapi/qmp/qerror.h"
26
+#include "qemu/error-report.h"
27
#include "qapi-visit.h"
28
#include "qom/object.h"
29
#include "qemu/main-loop.h"
30
@@ -XXX,XX +XXX,XX @@ typedef struct RewriterState {
31
NetQueue *incoming_queue;
32
/* hashtable to save connection */
33
GHashTable *connection_track_table;
34
+ bool vnet_hdr;
35
} RewriterState;
36
37
static void filter_rewriter_flush(NetFilterState *nf)
38
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
39
ConnectionKey key;
40
Packet *pkt;
41
ssize_t size = iov_size(iov, iovcnt);
42
+ ssize_t vnet_hdr_len = 0;
43
char *buf = g_malloc0(size);
44
45
iov_to_buf(iov, iovcnt, 0, buf, size);
46
- pkt = packet_new(buf, size, 0);
47
+
48
+ if (s->vnet_hdr) {
49
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
50
+ }
51
+
52
+ pkt = packet_new(buf, size, vnet_hdr_len);
53
g_free(buf);
54
55
/*
56
@@ -XXX,XX +XXX,XX @@ static void colo_rewriter_setup(NetFilterState *nf, Error **errp)
57
s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
58
}
21
}
59
22
60
+static bool filter_rewriter_get_vnet_hdr(Object *obj, Error **errp)
23
static void
24
-igb_build_rx_metadata(IGBCore *core,
25
- struct NetRxPkt *pkt,
26
- bool is_eop,
27
- const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
28
- uint16_t *pkt_info, uint16_t *hdr_info,
29
- uint32_t *rss,
30
- uint32_t *status_flags,
31
- uint16_t *ip_id,
32
- uint16_t *vlan_tag)
33
+igb_build_rx_metadata_common(IGBCore *core,
34
+ struct NetRxPkt *pkt,
35
+ bool is_eop,
36
+ uint32_t *status_flags,
37
+ uint16_t *vlan_tag)
38
{
39
struct virtio_net_hdr *vhdr;
40
bool hasip4, hasip6, csum_valid;
41
@@ -XXX,XX +XXX,XX @@ igb_build_rx_metadata(IGBCore *core,
42
*status_flags = E1000_RXD_STAT_DD;
43
44
/* No additional metadata needed for non-EOP descriptors */
45
- /* TODO: EOP apply only to status so don't skip whole function. */
46
if (!is_eop) {
47
goto func_exit;
48
}
49
@@ -XXX,XX +XXX,XX @@ igb_build_rx_metadata(IGBCore *core,
50
trace_e1000e_rx_metadata_vlan(*vlan_tag);
51
}
52
53
- /* Packet parsing results */
54
- if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
55
- if (rss_info->enabled) {
56
- *rss = cpu_to_le32(rss_info->hash);
57
- trace_igb_rx_metadata_rss(*rss);
58
- }
59
- } else if (hasip4) {
60
- *status_flags |= E1000_RXD_STAT_IPIDV;
61
- *ip_id = cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
62
- trace_e1000e_rx_metadata_ip_id(*ip_id);
63
- }
64
-
65
- if (pkt_info) {
66
- *pkt_info = rss_info->enabled ? rss_info->type : 0;
67
-
68
- if (etqf < 8) {
69
- *pkt_info |= (BIT(11) | etqf) << 4;
70
- } else {
71
- if (hasip4) {
72
- *pkt_info |= E1000_ADVRXD_PKT_IP4;
73
- }
74
-
75
- if (hasip6) {
76
- *pkt_info |= E1000_ADVRXD_PKT_IP6;
77
- }
78
-
79
- switch (l4hdr_proto) {
80
- case ETH_L4_HDR_PROTO_TCP:
81
- *pkt_info |= E1000_ADVRXD_PKT_TCP;
82
- break;
83
-
84
- case ETH_L4_HDR_PROTO_UDP:
85
- *pkt_info |= E1000_ADVRXD_PKT_UDP;
86
- break;
87
-
88
- case ETH_L4_HDR_PROTO_SCTP:
89
- *pkt_info |= E1000_ADVRXD_PKT_SCTP;
90
- break;
91
-
92
- default:
93
- break;
94
- }
95
- }
96
- }
97
-
98
- if (hdr_info) {
99
- *hdr_info = 0;
100
- }
101
-
102
- if (ts) {
103
- *status_flags |= BIT(16);
104
- }
105
-
106
/* RX CSO information */
107
if (hasip6 && (core->mac[RFCTL] & E1000_RFCTL_IPV6_XSUM_DIS)) {
108
trace_e1000e_rx_metadata_ipv6_sum_disabled();
109
@@ -XXX,XX +XXX,XX @@ func_exit:
110
static inline void
111
igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
112
struct NetRxPkt *pkt,
113
- const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
114
+ const E1000E_RSSInfo *rss_info,
115
uint16_t length)
116
{
117
- uint32_t status_flags, rss;
118
- uint16_t ip_id;
119
+ uint32_t status_flags;
120
121
assert(!rss_info->enabled);
122
+
123
+ memset(desc, 0, sizeof(*desc));
124
desc->length = cpu_to_le16(length);
125
- desc->csum = 0;
126
+ igb_build_rx_metadata_common(core, pkt, pkt != NULL,
127
+ &status_flags,
128
+ &desc->special);
129
130
- igb_build_rx_metadata(core, pkt, pkt != NULL,
131
- rss_info, etqf, ts,
132
- NULL, NULL, &rss,
133
- &status_flags, &ip_id,
134
- &desc->special);
135
desc->errors = (uint8_t) (le32_to_cpu(status_flags) >> 24);
136
desc->status = (uint8_t) le32_to_cpu(status_flags);
137
}
138
139
+static uint16_t
140
+igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
61
+{
141
+{
62
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
142
+ uint16_t pkt_type;
63
+
143
+ bool hasip4, hasip6;
64
+ return s->vnet_hdr;
144
+ EthL4HdrProto l4hdr_proto;
145
+
146
+ if (etqf < 8) {
147
+ pkt_type = BIT(11) | etqf;
148
+ return pkt_type;
149
+ }
150
+
151
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
152
+
153
+ if (hasip6 && !(core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
154
+ pkt_type = E1000_ADVRXD_PKT_IP6;
155
+ } else if (hasip4) {
156
+ pkt_type = E1000_ADVRXD_PKT_IP4;
157
+ } else {
158
+ pkt_type = 0;
159
+ }
160
+
161
+ switch (l4hdr_proto) {
162
+ case ETH_L4_HDR_PROTO_TCP:
163
+ pkt_type |= E1000_ADVRXD_PKT_TCP;
164
+ break;
165
+ case ETH_L4_HDR_PROTO_UDP:
166
+ pkt_type |= E1000_ADVRXD_PKT_UDP;
167
+ break;
168
+ case ETH_L4_HDR_PROTO_SCTP:
169
+ pkt_type |= E1000_ADVRXD_PKT_SCTP;
170
+ break;
171
+ default:
172
+ break;
173
+ }
174
+
175
+ return pkt_type;
65
+}
176
+}
66
+
177
+
67
+static void filter_rewriter_set_vnet_hdr(Object *obj,
178
static inline void
68
+ bool value,
179
igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
69
+ Error **errp)
180
struct NetRxPkt *pkt,
70
+{
181
const E1000E_RSSInfo *rss_info, uint16_t etqf, bool ts,
71
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
182
uint16_t length)
72
+
183
{
73
+ s->vnet_hdr = value;
184
+ bool hasip4, hasip6;
74
+}
185
+ EthL4HdrProto l4hdr_proto;
75
+
186
+ uint16_t rss_type = 0, pkt_type;
76
+static void filter_rewriter_init(Object *obj)
187
+ bool eop = (pkt != NULL);
77
+{
188
+ uint32_t adv_desc_status_error = 0;
78
+ RewriterState *s = FILTER_COLO_REWRITER(obj);
189
memset(&desc->wb, 0, sizeof(desc->wb));
79
+
190
80
+ s->vnet_hdr = false;
191
desc->wb.upper.length = cpu_to_le16(length);
81
+ object_property_add_bool(obj, "vnet_hdr_support",
192
+ igb_build_rx_metadata_common(core, pkt, eop,
82
+ filter_rewriter_get_vnet_hdr,
193
+ &desc->wb.upper.status_error,
83
+ filter_rewriter_set_vnet_hdr, NULL);
194
+ &desc->wb.upper.vlan);
84
+}
195
+
85
+
196
+ if (!eop) {
86
static void colo_rewriter_class_init(ObjectClass *oc, void *data)
197
+ return;
87
{
198
+ }
88
NetFilterClass *nfc = NETFILTER_CLASS(oc);
199
+
89
@@ -XXX,XX +XXX,XX @@ static const TypeInfo colo_rewriter_info = {
200
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
90
.name = TYPE_FILTER_REWRITER,
201
+
91
.parent = TYPE_NETFILTER,
202
+ if ((core->mac[RXCSUM] & E1000_RXCSUM_PCSD) != 0) {
92
.class_init = colo_rewriter_class_init,
203
+ if (rss_info->enabled) {
93
+ .instance_init = filter_rewriter_init,
204
+ desc->wb.lower.hi_dword.rss = cpu_to_le32(rss_info->hash);
94
.instance_size = sizeof(RewriterState),
205
+ rss_type = rss_info->type;
95
};
206
+ trace_igb_rx_metadata_rss(desc->wb.lower.hi_dword.rss, rss_type);
96
207
+ }
97
diff --git a/qemu-options.hx b/qemu-options.hx
208
+ } else if (hasip4) {
209
+ adv_desc_status_error |= E1000_RXD_STAT_IPIDV;
210
+ desc->wb.lower.hi_dword.csum_ip.ip_id =
211
+ cpu_to_le16(net_rx_pkt_get_ip_id(pkt));
212
+ trace_e1000e_rx_metadata_ip_id(
213
+ desc->wb.lower.hi_dword.csum_ip.ip_id);
214
+ }
215
+
216
+ if (ts) {
217
+ adv_desc_status_error |= BIT(16);
218
+ }
219
220
- igb_build_rx_metadata(core, pkt, pkt != NULL,
221
- rss_info, etqf, ts,
222
- &desc->wb.lower.lo_dword.pkt_info,
223
- &desc->wb.lower.lo_dword.hdr_info,
224
- &desc->wb.lower.hi_dword.rss,
225
- &desc->wb.upper.status_error,
226
- &desc->wb.lower.hi_dword.csum_ip.ip_id,
227
- &desc->wb.upper.vlan);
228
+ pkt_type = igb_rx_desc_get_packet_type(core, pkt, etqf);
229
+ trace_e1000e_rx_metadata_pkt_type(pkt_type);
230
+ desc->wb.lower.lo_dword.pkt_info = cpu_to_le16(rss_type | (pkt_type << 4));
231
+ desc->wb.upper.status_error |= cpu_to_le32(adv_desc_status_error);
232
}
233
234
static inline void
235
@@ -XXX,XX +XXX,XX @@ igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
236
uint16_t etqf, bool ts, uint16_t length)
237
{
238
if (igb_rx_use_legacy_descriptor(core)) {
239
- igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
240
- etqf, ts, length);
241
+ igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
242
} else {
243
igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info,
244
etqf, ts, length);
245
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
98
index XXXXXXX..XXXXXXX 100644
246
index XXXXXXX..XXXXXXX 100644
99
--- a/qemu-options.hx
247
--- a/hw/net/igb_regs.h
100
+++ b/qemu-options.hx
248
+++ b/hw/net/igb_regs.h
101
@@ -XXX,XX +XXX,XX @@ Create a filter-redirector we need to differ outdev id from indev id, id can not
249
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
102
be the same. we can just use indev or outdev, but at least one of indev or outdev
250
103
need to be specified.
251
#define E1000_STATUS_NUM_VFS_SHIFT 14
104
252
105
-@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid}[,queue=@var{all|rx|tx}]
253
-#define E1000_ADVRXD_PKT_IP4 BIT(4)
106
+@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support]
254
-#define E1000_ADVRXD_PKT_IP6 BIT(6)
107
255
-#define E1000_ADVRXD_PKT_TCP BIT(8)
108
Filter-rewriter is a part of COLO project.It will rewrite tcp packet to
256
-#define E1000_ADVRXD_PKT_UDP BIT(9)
109
secondary from primary to keep secondary tcp connection,and rewrite
257
-#define E1000_ADVRXD_PKT_SCTP BIT(10)
110
tcp packet to primary from secondary make tcp packet can be handled by
258
+#define E1000_ADVRXD_PKT_IP4 BIT(0)
111
-client.
259
+#define E1000_ADVRXD_PKT_IP6 BIT(2)
112
+client.if it has the vnet_hdr_support flag, we can parse packet with vnet header.
260
+#define E1000_ADVRXD_PKT_TCP BIT(4)
113
261
+#define E1000_ADVRXD_PKT_UDP BIT(5)
114
usage:
262
+#define E1000_ADVRXD_PKT_SCTP BIT(6)
115
colo secondary:
263
264
static inline uint8_t igb_ivar_entry_rx(uint8_t i)
265
{
266
diff --git a/hw/net/trace-events b/hw/net/trace-events
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/trace-events
269
+++ b/hw/net/trace-events
270
@@ -XXX,XX +XXX,XX @@ igb_link_set_ext_params(bool asd_check, bool speed_select_bypass, bool pfrstd) "
271
igb_rx_desc_buff_size(uint32_t b) "buffer size: %u"
272
igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source, uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
273
274
-igb_rx_metadata_rss(uint32_t rss) "RSS data: 0x%X"
275
+igb_rx_metadata_rss(uint32_t rss, uint16_t rss_pkt_type) "RSS data: rss: 0x%X, rss_pkt_type: 0x%X"
276
277
igb_irq_icr_clear_gpie_nsicr(void) "Clearing ICR on read due to GPIE.NSICR enabled"
278
igb_irq_set_iam(uint32_t icr) "Update IAM: 0x%x"
279
@@ -XXX,XX +XXX,XX @@ igb_irq_eitr_set(uint32_t eitr_num, uint32_t val) "EITR[%u] = 0x%x"
280
igb_set_pfmailbox(uint32_t vf_num, uint32_t val) "PFMailbox[%d]: 0x%x"
281
igb_set_vfmailbox(uint32_t vf_num, uint32_t val) "VFMailbox[%d]: 0x%x"
282
283
+igb_wrn_rx_desc_modes_not_supp(int desc_type) "Not supported descriptor type: %d"
284
+
285
# igbvf.c
286
igbvf_wrn_io_addr_unknown(uint64_t addr) "IO unknown register 0x%"PRIx64
287
116
--
288
--
117
2.7.4
289
2.7.4
118
119
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
This patch change the filter_send() parameter from CharBackend to MirrorState,
3
Refactoring is done in preparation for support of multiple advanced
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
descriptors RX modes, especially packet-split modes.
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
net/filter-mirror.c | 10 +++++-----
11
hw/net/e1000e_core.c | 18 ++--
10
1 file changed, 5 insertions(+), 5 deletions(-)
12
hw/net/igb_core.c | 213 ++++++++++++++++++++++++++++++-----------------
13
tests/qtest/libqos/igb.c | 5 ++
14
3 files changed, 150 insertions(+), 86 deletions(-)
11
15
12
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
16
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/net/filter-mirror.c
18
--- a/hw/net/e1000e_core.c
15
+++ b/net/filter-mirror.c
19
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
20
@@ -XXX,XX +XXX,XX @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
17
SocketReadState rs;
21
}
18
} MirrorState;
22
19
23
static void
20
-static int filter_send(CharBackend *chr_out,
24
-e1000e_write_to_rx_buffers(E1000ECore *core,
21
+static int filter_send(MirrorState *s,
25
- hwaddr ba[MAX_PS_BUFFERS],
22
const struct iovec *iov,
26
- e1000e_ba_state *bastate,
23
int iovcnt)
27
- const char *data,
28
- dma_addr_t data_len)
29
+e1000e_write_payload_frag_to_rx_buffers(E1000ECore *core,
30
+ hwaddr ba[MAX_PS_BUFFERS],
31
+ e1000e_ba_state *bastate,
32
+ const char *data,
33
+ dma_addr_t data_len)
24
{
34
{
25
@@ -XXX,XX +XXX,XX @@ static int filter_send(CharBackend *chr_out,
35
while (data_len > 0) {
36
uint32_t cur_buf_len = core->rxbuf_sizes[bastate->cur_idx];
37
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
38
while (copy_size) {
39
iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
40
41
- e1000e_write_to_rx_buffers(core, ba, &bastate,
42
- iov->iov_base + iov_ofs, iov_copy);
43
+ e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
44
+ iov->iov_base +
45
+ iov_ofs,
46
+ iov_copy);
47
48
copy_size -= iov_copy;
49
iov_ofs += iov_copy;
50
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
51
52
if (desc_offset + desc_size >= total_size) {
53
/* Simulate FCS checksum presence in the last descriptor */
54
- e1000e_write_to_rx_buffers(core, ba, &bastate,
55
+ e1000e_write_payload_frag_to_rx_buffers(core, ba, &bastate,
56
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
57
}
58
}
59
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/net/igb_core.c
62
+++ b/hw/net/igb_core.c
63
@@ -XXX,XX +XXX,XX @@ igb_has_rxbufs(IGBCore *core, const E1000ERingInfo *r, size_t total_size)
64
bufsize;
65
}
66
67
+static uint32_t
68
+igb_rxhdrbufsize(IGBCore *core, const E1000ERingInfo *r)
69
+{
70
+ uint32_t srrctl = core->mac[E1000_SRRCTL(r->idx) >> 2];
71
+ return (srrctl & E1000_SRRCTL_BSIZEHDRSIZE_MASK) >>
72
+ E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
73
+}
74
+
75
void
76
igb_start_recv(IGBCore *core)
77
{
78
@@ -XXX,XX +XXX,XX @@ igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
79
*buff_addr = le64_to_cpu(desc->read.pkt_addr);
80
}
81
82
+typedef struct IGBPacketRxDMAState {
83
+ size_t size;
84
+ size_t total_size;
85
+ size_t ps_hdr_len;
86
+ size_t desc_size;
87
+ size_t desc_offset;
88
+ uint32_t rx_desc_packet_buf_size;
89
+ uint32_t rx_desc_header_buf_size;
90
+ struct iovec *iov;
91
+ size_t iov_ofs;
92
+ bool is_first;
93
+ uint16_t written;
94
+ hwaddr ba;
95
+} IGBPacketRxDMAState;
96
+
97
static inline void
98
igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
99
hwaddr *buff_addr)
100
@@ -XXX,XX +XXX,XX @@ igb_pci_dma_write_rx_desc(IGBCore *core, PCIDevice *dev, dma_addr_t addr,
101
}
102
103
static void
104
-igb_write_to_rx_buffers(IGBCore *core,
105
- PCIDevice *d,
106
- hwaddr ba,
107
- uint16_t *written,
108
- const char *data,
109
- dma_addr_t data_len)
110
-{
111
- trace_igb_rx_desc_buff_write(ba, *written, data, data_len);
112
- pci_dma_write(d, ba + *written, data, data_len);
113
- *written += data_len;
114
-}
115
-
116
-static void
117
igb_update_rx_stats(IGBCore *core, const E1000ERingInfo *rxi,
118
size_t pkt_size, size_t pkt_fcs_size)
119
{
120
@@ -XXX,XX +XXX,XX @@ igb_rx_descr_threshold_hit(IGBCore *core, const E1000ERingInfo *rxi)
121
}
122
123
static void
124
+igb_truncate_to_descriptor_size(IGBPacketRxDMAState *pdma_st, size_t *size)
125
+{
126
+ if (*size > pdma_st->rx_desc_packet_buf_size) {
127
+ *size = pdma_st->rx_desc_packet_buf_size;
128
+ }
129
+}
130
+
131
+static void
132
+igb_write_payload_frag_to_rx_buffers(IGBCore *core,
133
+ PCIDevice *d,
134
+ hwaddr ba,
135
+ uint16_t *written,
136
+ uint32_t cur_buf_len,
137
+ const char *data,
138
+ dma_addr_t data_len)
139
+{
140
+ trace_igb_rx_desc_buff_write(ba, *written, data, data_len);
141
+ pci_dma_write(d, ba + *written, data, data_len);
142
+ *written += data_len;
143
+}
144
+
145
+static void
146
+igb_write_payload_to_rx_buffers(IGBCore *core,
147
+ struct NetRxPkt *pkt,
148
+ PCIDevice *d,
149
+ IGBPacketRxDMAState *pdma_st,
150
+ size_t *copy_size)
151
+{
152
+ static const uint32_t fcs_pad;
153
+ size_t iov_copy;
154
+
155
+ /* Copy packet payload */
156
+ while (*copy_size) {
157
+ iov_copy = MIN(*copy_size, pdma_st->iov->iov_len - pdma_st->iov_ofs);
158
+ igb_write_payload_frag_to_rx_buffers(core, d,
159
+ pdma_st->ba,
160
+ &pdma_st->written,
161
+ pdma_st->rx_desc_packet_buf_size,
162
+ pdma_st->iov->iov_base +
163
+ pdma_st->iov_ofs,
164
+ iov_copy);
165
+
166
+ *copy_size -= iov_copy;
167
+ pdma_st->iov_ofs += iov_copy;
168
+ if (pdma_st->iov_ofs == pdma_st->iov->iov_len) {
169
+ pdma_st->iov++;
170
+ pdma_st->iov_ofs = 0;
171
+ }
172
+ }
173
+
174
+ if (pdma_st->desc_offset + pdma_st->desc_size >= pdma_st->total_size) {
175
+ /* Simulate FCS checksum presence in the last descriptor */
176
+ igb_write_payload_frag_to_rx_buffers(core, d,
177
+ pdma_st->ba,
178
+ &pdma_st->written,
179
+ pdma_st->rx_desc_packet_buf_size,
180
+ (const char *) &fcs_pad,
181
+ e1000x_fcs_len(core->mac));
182
+ }
183
+}
184
+
185
+static void
186
+igb_write_to_rx_buffers(IGBCore *core,
187
+ struct NetRxPkt *pkt,
188
+ PCIDevice *d,
189
+ IGBPacketRxDMAState *pdma_st)
190
+{
191
+ size_t copy_size;
192
+
193
+ if (!pdma_st->ba) {
194
+ /* as per intel docs; skip descriptors with null buf addr */
195
+ trace_e1000e_rx_null_descriptor();
196
+ return;
197
+ }
198
+
199
+ if (pdma_st->desc_offset >= pdma_st->size) {
200
+ return;
201
+ }
202
+
203
+ pdma_st->desc_size = pdma_st->total_size - pdma_st->desc_offset;
204
+ igb_truncate_to_descriptor_size(pdma_st, &pdma_st->desc_size);
205
+ copy_size = pdma_st->size - pdma_st->desc_offset;
206
+ igb_truncate_to_descriptor_size(pdma_st, &copy_size);
207
+ igb_write_payload_to_rx_buffers(core, pkt, d, pdma_st, &copy_size);
208
+}
209
+
210
+static void
211
igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
212
const E1000E_RxRing *rxr,
213
const E1000E_RSSInfo *rss_info,
214
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
215
PCIDevice *d;
216
dma_addr_t base;
217
union e1000_rx_desc_union desc;
218
- size_t desc_size;
219
- size_t desc_offset = 0;
220
- size_t iov_ofs = 0;
221
-
222
- struct iovec *iov = net_rx_pkt_get_iovec(pkt);
223
- size_t size = net_rx_pkt_get_total_len(pkt);
224
- size_t total_size = size + e1000x_fcs_len(core->mac);
225
- const E1000ERingInfo *rxi = rxr->i;
226
- size_t bufsize = igb_rxbufsize(core, rxi);
227
-
228
+ const E1000ERingInfo *rxi;
229
+ size_t rx_desc_len;
230
+
231
+ IGBPacketRxDMAState pdma_st = {0};
232
+ pdma_st.is_first = true;
233
+ pdma_st.size = net_rx_pkt_get_total_len(pkt);
234
+ pdma_st.total_size = pdma_st.size + e1000x_fcs_len(core->mac);
235
+
236
+ rxi = rxr->i;
237
+ rx_desc_len = core->rx_desc_len;
238
+ pdma_st.rx_desc_packet_buf_size = igb_rxbufsize(core, rxi);
239
+ pdma_st.rx_desc_header_buf_size = igb_rxhdrbufsize(core, rxi);
240
+ pdma_st.iov = net_rx_pkt_get_iovec(pkt);
241
d = pcie_sriov_get_vf_at_index(core->owner, rxi->idx % 8);
242
if (!d) {
243
d = core->owner;
26
}
244
}
27
245
28
len = htonl(size);
246
do {
29
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len));
247
- hwaddr ba;
30
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
248
- uint16_t written = 0;
31
if (ret != sizeof(len)) {
249
+ pdma_st.written = 0;
32
goto err;
250
bool is_last = false;
33
}
251
34
252
- desc_size = total_size - desc_offset;
35
buf = g_malloc(size);
253
-
36
iov_to_buf(iov, iovcnt, 0, buf, size);
254
- if (desc_size > bufsize) {
37
- ret = qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size);
255
- desc_size = bufsize;
38
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
256
- }
39
g_free(buf);
257
-
40
if (ret != size) {
258
if (igb_ring_empty(core, rxi)) {
41
goto err;
259
return;
42
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_mirror_receive_iov(NetFilterState *nf,
43
MirrorState *s = FILTER_MIRROR(nf);
44
int ret;
45
46
- ret = filter_send(&s->chr_out, iov, iovcnt);
47
+ ret = filter_send(s, iov, iovcnt);
48
if (ret) {
49
error_report("filter mirror send failed(%s)", strerror(-ret));
50
}
51
@@ -XXX,XX +XXX,XX @@ static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
52
int ret;
53
54
if (qemu_chr_fe_backend_connected(&s->chr_out)) {
55
- ret = filter_send(&s->chr_out, iov, iovcnt);
56
+ ret = filter_send(s, iov, iovcnt);
57
if (ret) {
58
error_report("filter redirector send failed(%s)", strerror(-ret));
59
}
260
}
261
262
base = igb_ring_head_descr(core, rxi);
263
+ pci_dma_read(d, base, &desc, rx_desc_len);
264
+ trace_e1000e_rx_descr(rxi->idx, base, rx_desc_len);
265
266
- pci_dma_read(d, base, &desc, core->rx_desc_len);
267
-
268
- trace_e1000e_rx_descr(rxi->idx, base, core->rx_desc_len);
269
-
270
- igb_read_rx_descr(core, &desc, &ba);
271
-
272
- if (ba) {
273
- if (desc_offset < size) {
274
- static const uint32_t fcs_pad;
275
- size_t iov_copy;
276
- size_t copy_size = size - desc_offset;
277
- if (copy_size > bufsize) {
278
- copy_size = bufsize;
279
- }
280
-
281
- /* Copy packet payload */
282
- while (copy_size) {
283
- iov_copy = MIN(copy_size, iov->iov_len - iov_ofs);
284
-
285
- igb_write_to_rx_buffers(core, d, ba, &written,
286
- iov->iov_base + iov_ofs, iov_copy);
287
+ igb_read_rx_descr(core, &desc, &pdma_st.ba);
288
289
- copy_size -= iov_copy;
290
- iov_ofs += iov_copy;
291
- if (iov_ofs == iov->iov_len) {
292
- iov++;
293
- iov_ofs = 0;
294
- }
295
- }
296
-
297
- if (desc_offset + desc_size >= total_size) {
298
- /* Simulate FCS checksum presence in the last descriptor */
299
- igb_write_to_rx_buffers(core, d, ba, &written,
300
- (const char *) &fcs_pad, e1000x_fcs_len(core->mac));
301
- }
302
- }
303
- } else { /* as per intel docs; skip descriptors with null buf addr */
304
- trace_e1000e_rx_null_descriptor();
305
- }
306
- desc_offset += desc_size;
307
- if (desc_offset >= total_size) {
308
+ igb_write_to_rx_buffers(core, pkt, d, &pdma_st);
309
+ pdma_st.desc_offset += pdma_st.desc_size;
310
+ if (pdma_st.desc_offset >= pdma_st.total_size) {
311
is_last = true;
312
}
313
314
igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
315
- rss_info, etqf, ts, written);
316
- igb_pci_dma_write_rx_desc(core, d, base, &desc, core->rx_desc_len);
317
-
318
- igb_ring_advance(core, rxi, core->rx_desc_len / E1000_MIN_RX_DESC_LEN);
319
-
320
- } while (desc_offset < total_size);
321
+ rss_info, etqf, ts, pdma_st.written);
322
+ igb_pci_dma_write_rx_desc(core, d, base, &desc, rx_desc_len);
323
+ igb_ring_advance(core, rxi, rx_desc_len / E1000_MIN_RX_DESC_LEN);
324
+ } while (pdma_st.desc_offset < pdma_st.total_size);
325
326
- igb_update_rx_stats(core, rxi, size, total_size);
327
+ igb_update_rx_stats(core, rxi, pdma_st.size, pdma_st.total_size);
328
}
329
330
static bool
331
diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c
332
index XXXXXXX..XXXXXXX 100644
333
--- a/tests/qtest/libqos/igb.c
334
+++ b/tests/qtest/libqos/igb.c
335
@@ -XXX,XX +XXX,XX @@ static void igb_pci_start_hw(QOSGraphObject *obj)
336
E1000_RAH_AV | E1000_RAH_POOL_1 |
337
le16_to_cpu(*(uint16_t *)(address + 4)));
338
339
+ /* Set supported receive descriptor mode */
340
+ e1000e_macreg_write(&d->e1000e,
341
+ E1000_SRRCTL(0),
342
+ E1000_SRRCTL_DESCTYPE_ADV_ONEBUF);
343
+
344
/* Enable receive */
345
e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN);
346
e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN);
60
--
347
--
61
2.7.4
348
2.7.4
62
63
diff view generated by jsdifflib
New patch
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
1
2
3
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
4
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
5
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
hw/net/igb_core.c | 4 +++-
9
hw/net/igb_regs.h | 1 +
10
2 files changed, 4 insertions(+), 1 deletion(-)
11
12
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/igb_core.c
15
+++ b/hw/net/igb_core.c
16
@@ -XXX,XX +XXX,XX @@ igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
17
net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
18
19
if (hasip6 && !(core->mac[RFCTL] & E1000_RFCTL_IPV6_DIS)) {
20
- pkt_type = E1000_ADVRXD_PKT_IP6;
21
+ eth_ip6_hdr_info *ip6hdr_info = net_rx_pkt_get_ip6_info(pkt);
22
+ pkt_type = ip6hdr_info->has_ext_hdrs ? E1000_ADVRXD_PKT_IP6E :
23
+ E1000_ADVRXD_PKT_IP6;
24
} else if (hasip4) {
25
pkt_type = E1000_ADVRXD_PKT_IP4;
26
} else {
27
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/igb_regs.h
30
+++ b/hw/net/igb_regs.h
31
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
32
33
#define E1000_ADVRXD_PKT_IP4 BIT(0)
34
#define E1000_ADVRXD_PKT_IP6 BIT(2)
35
+#define E1000_ADVRXD_PKT_IP6E BIT(3)
36
#define E1000_ADVRXD_PKT_TCP BIT(4)
37
#define E1000_ADVRXD_PKT_UDP BIT(5)
38
#define E1000_ADVRXD_PKT_SCTP BIT(6)
39
--
40
2.7.4
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
3
Packet-split descriptors are used by Linux VF driver for MTU values from 2048
4
5
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
6
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
9
---
6
docs/colo-proxy.txt | 26 ++++++++++++++++++++++++++
10
hw/net/igb_core.c | 348 +++++++++++++++++++++++++++++++++++++++++++++-------
7
1 file changed, 26 insertions(+)
11
hw/net/igb_regs.h | 9 ++
12
hw/net/trace-events | 2 +-
13
3 files changed, 316 insertions(+), 43 deletions(-)
8
14
9
diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
15
diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c
10
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
11
--- a/docs/colo-proxy.txt
17
--- a/hw/net/igb_core.c
12
+++ b/docs/colo-proxy.txt
18
+++ b/hw/net/igb_core.c
13
@@ -XXX,XX +XXX,XX @@ Secondary(ip:3.3.3.8):
19
@@ -XXX,XX +XXX,XX @@ igb_rx_use_legacy_descriptor(IGBCore *core)
14
-chardev socket,id=red1,host=3.3.3.3,port=9004
20
return false;
15
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
21
}
16
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
22
17
+-object filter-rewriter,id=f3,netdev=hn0,queue=all
23
+typedef struct E1000ERingInfo {
18
+
24
+ int dbah;
19
+If you want to use virtio-net-pci or other driver with vnet_header:
25
+ int dbal;
20
+
26
+ int dlen;
21
+Primary(ip:3.3.3.3):
27
+ int dh;
22
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
28
+ int dt;
23
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
29
+ int idx;
24
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
30
+} E1000ERingInfo;
25
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
31
+
26
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
32
+static uint32_t
27
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
33
+igb_rx_queue_desctyp_get(IGBCore *core, const E1000ERingInfo *r)
28
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
34
+{
29
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
35
+ return core->mac[E1000_SRRCTL(r->idx) >> 2] & E1000_SRRCTL_DESCTYPE_MASK;
30
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
36
+}
31
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out,vnet_hdr_support
37
+
32
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0,vnet_hdr_support
38
+static bool
33
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
39
+igb_rx_use_ps_descriptor(IGBCore *core, const E1000ERingInfo *r)
34
+
40
+{
35
+Secondary(ip:3.3.3.8):
41
+ uint32_t desctyp = igb_rx_queue_desctyp_get(core, r);
36
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
42
+ return desctyp == E1000_SRRCTL_DESCTYPE_HDR_SPLIT ||
37
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
43
+ desctyp == E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
38
+-chardev socket,id=red0,host=3.3.3.3,port=9003
44
+}
39
+-chardev socket,id=red1,host=3.3.3.3,port=9004
45
+
40
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0,vnet_hdr_support
46
static inline bool
41
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1,vnet_hdr_support
47
igb_rss_enabled(IGBCore *core)
42
+-object filter-rewriter,id=f3,netdev=hn0,queue=all,vnet_hdr_support
48
{
43
49
@@ -XXX,XX +XXX,XX @@ static uint32_t igb_rx_wb_eic(IGBCore *core, int queue_idx)
44
Note:
50
return (ent & E1000_IVAR_VALID) ? BIT(ent & 0x1f) : 0;
45
a.COLO-proxy must work with COLO-frame and Block-replication.
51
}
52
53
-typedef struct E1000ERingInfo {
54
- int dbah;
55
- int dbal;
56
- int dlen;
57
- int dh;
58
- int dt;
59
- int idx;
60
-} E1000ERingInfo;
61
-
62
static inline bool
63
igb_ring_empty(IGBCore *core, const E1000ERingInfo *r)
64
{
65
@@ -XXX,XX +XXX,XX @@ igb_read_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
66
}
67
68
static inline void
69
-igb_read_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
70
- hwaddr *buff_addr)
71
+igb_read_adv_rx_single_buf_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
72
+ hwaddr *buff_addr)
73
{
74
*buff_addr = le64_to_cpu(desc->read.pkt_addr);
75
}
76
77
+static inline void
78
+igb_read_adv_rx_split_buf_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
79
+ hwaddr *buff_addr)
80
+{
81
+ buff_addr[0] = le64_to_cpu(desc->read.hdr_addr);
82
+ buff_addr[1] = le64_to_cpu(desc->read.pkt_addr);
83
+}
84
+
85
+typedef struct IGBBAState {
86
+ uint16_t written[IGB_MAX_PS_BUFFERS];
87
+ uint8_t cur_idx;
88
+} IGBBAState;
89
+
90
+typedef struct IGBSplitDescriptorData {
91
+ bool sph;
92
+ bool hbo;
93
+ size_t hdr_len;
94
+} IGBSplitDescriptorData;
95
+
96
typedef struct IGBPacketRxDMAState {
97
size_t size;
98
size_t total_size;
99
@@ -XXX,XX +XXX,XX @@ typedef struct IGBPacketRxDMAState {
100
uint32_t rx_desc_header_buf_size;
101
struct iovec *iov;
102
size_t iov_ofs;
103
+ bool do_ps;
104
bool is_first;
105
- uint16_t written;
106
- hwaddr ba;
107
+ IGBBAState bastate;
108
+ hwaddr ba[IGB_MAX_PS_BUFFERS];
109
+ IGBSplitDescriptorData ps_desc_data;
110
} IGBPacketRxDMAState;
111
112
static inline void
113
-igb_read_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
114
- hwaddr *buff_addr)
115
+igb_read_rx_descr(IGBCore *core,
116
+ union e1000_rx_desc_union *desc,
117
+ IGBPacketRxDMAState *pdma_st,
118
+ const E1000ERingInfo *r)
119
{
120
+ uint32_t desc_type;
121
+
122
if (igb_rx_use_legacy_descriptor(core)) {
123
- igb_read_lgcy_rx_descr(core, &desc->legacy, buff_addr);
124
- } else {
125
- igb_read_adv_rx_descr(core, &desc->adv, buff_addr);
126
+ igb_read_lgcy_rx_descr(core, &desc->legacy, &pdma_st->ba[1]);
127
+ pdma_st->ba[0] = 0;
128
+ return;
129
+ }
130
+
131
+ /* advanced header split descriptor */
132
+ if (igb_rx_use_ps_descriptor(core, r)) {
133
+ igb_read_adv_rx_split_buf_descr(core, &desc->adv, &pdma_st->ba[0]);
134
+ return;
135
+ }
136
+
137
+ /* descriptor replication modes not supported */
138
+ desc_type = igb_rx_queue_desctyp_get(core, r);
139
+ if (desc_type != E1000_SRRCTL_DESCTYPE_ADV_ONEBUF) {
140
+ trace_igb_wrn_rx_desc_modes_not_supp(desc_type);
141
}
142
+
143
+ /* advanced single buffer descriptor */
144
+ igb_read_adv_rx_single_buf_descr(core, &desc->adv, &pdma_st->ba[1]);
145
+ pdma_st->ba[0] = 0;
146
}
147
148
static void
149
@@ -XXX,XX +XXX,XX @@ igb_write_lgcy_rx_descr(IGBCore *core, struct e1000_rx_desc *desc,
150
desc->status = (uint8_t) le32_to_cpu(status_flags);
151
}
152
153
+static bool
154
+igb_rx_ps_descriptor_split_always(IGBCore *core, const E1000ERingInfo *r)
155
+{
156
+ uint32_t desctyp = igb_rx_queue_desctyp_get(core, r);
157
+ return desctyp == E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
158
+}
159
+
160
static uint16_t
161
igb_rx_desc_get_packet_type(IGBCore *core, struct NetRxPkt *pkt, uint16_t etqf)
162
{
163
@@ -XXX,XX +XXX,XX @@ igb_write_adv_rx_descr(IGBCore *core, union e1000_adv_rx_desc *desc,
164
}
165
166
static inline void
167
-igb_write_rx_descr(IGBCore *core, union e1000_rx_desc_union *desc,
168
- struct NetRxPkt *pkt, const E1000E_RSSInfo *rss_info,
169
- uint16_t etqf, bool ts, uint16_t length)
170
+igb_write_adv_ps_rx_descr(IGBCore *core,
171
+ union e1000_adv_rx_desc *desc,
172
+ struct NetRxPkt *pkt,
173
+ const E1000E_RSSInfo *rss_info,
174
+ const E1000ERingInfo *r,
175
+ uint16_t etqf,
176
+ bool ts,
177
+ IGBPacketRxDMAState *pdma_st)
178
+{
179
+ size_t pkt_len;
180
+ uint16_t hdr_info = 0;
181
+
182
+ if (pdma_st->do_ps) {
183
+ pkt_len = pdma_st->bastate.written[1];
184
+ } else {
185
+ pkt_len = pdma_st->bastate.written[0] + pdma_st->bastate.written[1];
186
+ }
187
+
188
+ igb_write_adv_rx_descr(core, desc, pkt, rss_info, etqf, ts, pkt_len);
189
+
190
+ hdr_info = (pdma_st->ps_desc_data.hdr_len << E1000_ADVRXD_HDR_LEN_OFFSET) &
191
+ E1000_ADVRXD_ADV_HDR_LEN_MASK;
192
+ hdr_info |= pdma_st->ps_desc_data.sph ? E1000_ADVRXD_HDR_SPH : 0;
193
+ desc->wb.lower.lo_dword.hdr_info = cpu_to_le16(hdr_info);
194
+
195
+ desc->wb.upper.status_error |= cpu_to_le32(
196
+ pdma_st->ps_desc_data.hbo ? E1000_ADVRXD_ST_ERR_HBO_OFFSET : 0);
197
+}
198
+
199
+static inline void
200
+igb_write_rx_descr(IGBCore *core,
201
+ union e1000_rx_desc_union *desc,
202
+ struct NetRxPkt *pkt,
203
+ const E1000E_RSSInfo *rss_info,
204
+ uint16_t etqf,
205
+ bool ts,
206
+ IGBPacketRxDMAState *pdma_st,
207
+ const E1000ERingInfo *r)
208
{
209
if (igb_rx_use_legacy_descriptor(core)) {
210
- igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info, length);
211
+ igb_write_lgcy_rx_descr(core, &desc->legacy, pkt, rss_info,
212
+ pdma_st->bastate.written[1]);
213
+ } else if (igb_rx_use_ps_descriptor(core, r)) {
214
+ igb_write_adv_ps_rx_descr(core, &desc->adv, pkt, rss_info, r, etqf, ts,
215
+ pdma_st);
216
} else {
217
igb_write_adv_rx_descr(core, &desc->adv, pkt, rss_info,
218
- etqf, ts, length);
219
+ etqf, ts, pdma_st->bastate.written[1]);
220
}
221
}
222
223
@@ -XXX,XX +XXX,XX @@ igb_rx_descr_threshold_hit(IGBCore *core, const E1000ERingInfo *rxi)
224
((core->mac[E1000_SRRCTL(rxi->idx) >> 2] >> 20) & 31) * 16;
225
}
226
227
+static bool
228
+igb_do_ps(IGBCore *core,
229
+ const E1000ERingInfo *r,
230
+ struct NetRxPkt *pkt,
231
+ IGBPacketRxDMAState *pdma_st)
232
+{
233
+ bool hasip4, hasip6;
234
+ EthL4HdrProto l4hdr_proto;
235
+ bool fragment;
236
+ bool split_always;
237
+ size_t bheader_size;
238
+ size_t total_pkt_len;
239
+
240
+ if (!igb_rx_use_ps_descriptor(core, r)) {
241
+ return false;
242
+ }
243
+
244
+ total_pkt_len = net_rx_pkt_get_total_len(pkt);
245
+ bheader_size = igb_rxhdrbufsize(core, r);
246
+ split_always = igb_rx_ps_descriptor_split_always(core, r);
247
+ if (split_always && total_pkt_len <= bheader_size) {
248
+ pdma_st->ps_hdr_len = total_pkt_len;
249
+ pdma_st->ps_desc_data.hdr_len = total_pkt_len;
250
+ return true;
251
+ }
252
+
253
+ net_rx_pkt_get_protocols(pkt, &hasip4, &hasip6, &l4hdr_proto);
254
+
255
+ if (hasip4) {
256
+ fragment = net_rx_pkt_get_ip4_info(pkt)->fragment;
257
+ } else if (hasip6) {
258
+ fragment = net_rx_pkt_get_ip6_info(pkt)->fragment;
259
+ } else {
260
+ pdma_st->ps_desc_data.hdr_len = bheader_size;
261
+ goto header_not_handled;
262
+ }
263
+
264
+ if (fragment && (core->mac[RFCTL] & E1000_RFCTL_IPFRSP_DIS)) {
265
+ pdma_st->ps_desc_data.hdr_len = bheader_size;
266
+ goto header_not_handled;
267
+ }
268
+
269
+ /* no header splitting for SCTP */
270
+ if (!fragment && (l4hdr_proto == ETH_L4_HDR_PROTO_UDP ||
271
+ l4hdr_proto == ETH_L4_HDR_PROTO_TCP)) {
272
+ pdma_st->ps_hdr_len = net_rx_pkt_get_l5_hdr_offset(pkt);
273
+ } else {
274
+ pdma_st->ps_hdr_len = net_rx_pkt_get_l4_hdr_offset(pkt);
275
+ }
276
+
277
+ pdma_st->ps_desc_data.sph = true;
278
+ pdma_st->ps_desc_data.hdr_len = pdma_st->ps_hdr_len;
279
+
280
+ if (pdma_st->ps_hdr_len > bheader_size) {
281
+ pdma_st->ps_desc_data.hbo = true;
282
+ goto header_not_handled;
283
+ }
284
+
285
+ return true;
286
+
287
+header_not_handled:
288
+ if (split_always) {
289
+ pdma_st->ps_hdr_len = bheader_size;
290
+ return true;
291
+ }
292
+
293
+ return false;
294
+}
295
+
296
static void
297
igb_truncate_to_descriptor_size(IGBPacketRxDMAState *pdma_st, size_t *size)
298
{
299
- if (*size > pdma_st->rx_desc_packet_buf_size) {
300
- *size = pdma_st->rx_desc_packet_buf_size;
301
+ if (pdma_st->do_ps && pdma_st->is_first) {
302
+ if (*size > pdma_st->rx_desc_packet_buf_size + pdma_st->ps_hdr_len) {
303
+ *size = pdma_st->rx_desc_packet_buf_size + pdma_st->ps_hdr_len;
304
+ }
305
+ } else {
306
+ if (*size > pdma_st->rx_desc_packet_buf_size) {
307
+ *size = pdma_st->rx_desc_packet_buf_size;
308
+ }
309
+ }
310
+}
311
+
312
+static inline void
313
+igb_write_hdr_frag_to_rx_buffers(IGBCore *core,
314
+ PCIDevice *d,
315
+ IGBPacketRxDMAState *pdma_st,
316
+ const char *data,
317
+ dma_addr_t data_len)
318
+{
319
+ assert(data_len <= pdma_st->rx_desc_header_buf_size -
320
+ pdma_st->bastate.written[0]);
321
+ pci_dma_write(d,
322
+ pdma_st->ba[0] + pdma_st->bastate.written[0],
323
+ data, data_len);
324
+ pdma_st->bastate.written[0] += data_len;
325
+ pdma_st->bastate.cur_idx = 1;
326
+}
327
+
328
+static void
329
+igb_write_header_to_rx_buffers(IGBCore *core,
330
+ struct NetRxPkt *pkt,
331
+ PCIDevice *d,
332
+ IGBPacketRxDMAState *pdma_st,
333
+ size_t *copy_size)
334
+{
335
+ size_t iov_copy;
336
+ size_t ps_hdr_copied = 0;
337
+
338
+ if (!pdma_st->is_first) {
339
+ /* Leave buffer 0 of each descriptor except first */
340
+ /* empty */
341
+ pdma_st->bastate.cur_idx = 1;
342
+ return;
343
}
344
+
345
+ do {
346
+ iov_copy = MIN(pdma_st->ps_hdr_len - ps_hdr_copied,
347
+ pdma_st->iov->iov_len - pdma_st->iov_ofs);
348
+
349
+ igb_write_hdr_frag_to_rx_buffers(core, d, pdma_st,
350
+ pdma_st->iov->iov_base,
351
+ iov_copy);
352
+
353
+ *copy_size -= iov_copy;
354
+ ps_hdr_copied += iov_copy;
355
+
356
+ pdma_st->iov_ofs += iov_copy;
357
+ if (pdma_st->iov_ofs == pdma_st->iov->iov_len) {
358
+ pdma_st->iov++;
359
+ pdma_st->iov_ofs = 0;
360
+ }
361
+ } while (ps_hdr_copied < pdma_st->ps_hdr_len);
362
+
363
+ pdma_st->is_first = false;
364
}
365
366
static void
367
igb_write_payload_frag_to_rx_buffers(IGBCore *core,
368
PCIDevice *d,
369
- hwaddr ba,
370
- uint16_t *written,
371
- uint32_t cur_buf_len,
372
+ IGBPacketRxDMAState *pdma_st,
373
const char *data,
374
dma_addr_t data_len)
375
{
376
- trace_igb_rx_desc_buff_write(ba, *written, data, data_len);
377
- pci_dma_write(d, ba + *written, data, data_len);
378
- *written += data_len;
379
+ while (data_len > 0) {
380
+ assert(pdma_st->bastate.cur_idx < IGB_MAX_PS_BUFFERS);
381
+
382
+ uint32_t cur_buf_bytes_left =
383
+ pdma_st->rx_desc_packet_buf_size -
384
+ pdma_st->bastate.written[pdma_st->bastate.cur_idx];
385
+ uint32_t bytes_to_write = MIN(data_len, cur_buf_bytes_left);
386
+
387
+ trace_igb_rx_desc_buff_write(
388
+ pdma_st->bastate.cur_idx,
389
+ pdma_st->ba[pdma_st->bastate.cur_idx],
390
+ pdma_st->bastate.written[pdma_st->bastate.cur_idx],
391
+ data,
392
+ bytes_to_write);
393
+
394
+ pci_dma_write(d,
395
+ pdma_st->ba[pdma_st->bastate.cur_idx] +
396
+ pdma_st->bastate.written[pdma_st->bastate.cur_idx],
397
+ data, bytes_to_write);
398
+
399
+ pdma_st->bastate.written[pdma_st->bastate.cur_idx] += bytes_to_write;
400
+ data += bytes_to_write;
401
+ data_len -= bytes_to_write;
402
+
403
+ if (pdma_st->bastate.written[pdma_st->bastate.cur_idx] ==
404
+ pdma_st->rx_desc_packet_buf_size) {
405
+ pdma_st->bastate.cur_idx++;
406
+ }
407
+ }
408
}
409
410
static void
411
@@ -XXX,XX +XXX,XX @@ igb_write_payload_to_rx_buffers(IGBCore *core,
412
while (*copy_size) {
413
iov_copy = MIN(*copy_size, pdma_st->iov->iov_len - pdma_st->iov_ofs);
414
igb_write_payload_frag_to_rx_buffers(core, d,
415
- pdma_st->ba,
416
- &pdma_st->written,
417
- pdma_st->rx_desc_packet_buf_size,
418
+ pdma_st,
419
pdma_st->iov->iov_base +
420
pdma_st->iov_ofs,
421
iov_copy);
422
@@ -XXX,XX +XXX,XX @@ igb_write_payload_to_rx_buffers(IGBCore *core,
423
if (pdma_st->desc_offset + pdma_st->desc_size >= pdma_st->total_size) {
424
/* Simulate FCS checksum presence in the last descriptor */
425
igb_write_payload_frag_to_rx_buffers(core, d,
426
- pdma_st->ba,
427
- &pdma_st->written,
428
- pdma_st->rx_desc_packet_buf_size,
429
+ pdma_st,
430
(const char *) &fcs_pad,
431
e1000x_fcs_len(core->mac));
432
}
433
@@ -XXX,XX +XXX,XX @@ igb_write_to_rx_buffers(IGBCore *core,
434
{
435
size_t copy_size;
436
437
- if (!pdma_st->ba) {
438
+ if (!(pdma_st->ba)[1] || (pdma_st->do_ps && !(pdma_st->ba[0]))) {
439
/* as per intel docs; skip descriptors with null buf addr */
440
trace_e1000e_rx_null_descriptor();
441
return;
442
@@ -XXX,XX +XXX,XX @@ igb_write_to_rx_buffers(IGBCore *core,
443
igb_truncate_to_descriptor_size(pdma_st, &pdma_st->desc_size);
444
copy_size = pdma_st->size - pdma_st->desc_offset;
445
igb_truncate_to_descriptor_size(pdma_st, &copy_size);
446
+
447
+ /* For PS mode copy the packet header first */
448
+ if (pdma_st->do_ps) {
449
+ igb_write_header_to_rx_buffers(core, pkt, d, pdma_st, &copy_size);
450
+ } else {
451
+ pdma_st->bastate.cur_idx = 1;
452
+ }
453
+
454
igb_write_payload_to_rx_buffers(core, pkt, d, pdma_st, &copy_size);
455
}
456
457
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
458
d = core->owner;
459
}
460
461
+ pdma_st.do_ps = igb_do_ps(core, rxi, pkt, &pdma_st);
462
+
463
do {
464
- pdma_st.written = 0;
465
+ memset(&pdma_st.bastate, 0, sizeof(IGBBAState));
466
bool is_last = false;
467
468
if (igb_ring_empty(core, rxi)) {
469
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
470
pci_dma_read(d, base, &desc, rx_desc_len);
471
trace_e1000e_rx_descr(rxi->idx, base, rx_desc_len);
472
473
- igb_read_rx_descr(core, &desc, &pdma_st.ba);
474
+ igb_read_rx_descr(core, &desc, &pdma_st, rxi);
475
476
igb_write_to_rx_buffers(core, pkt, d, &pdma_st);
477
pdma_st.desc_offset += pdma_st.desc_size;
478
@@ -XXX,XX +XXX,XX @@ igb_write_packet_to_guest(IGBCore *core, struct NetRxPkt *pkt,
479
is_last = true;
480
}
481
482
- igb_write_rx_descr(core, &desc, is_last ? core->rx_pkt : NULL,
483
- rss_info, etqf, ts, pdma_st.written);
484
+ igb_write_rx_descr(core, &desc,
485
+ is_last ? pkt : NULL,
486
+ rss_info,
487
+ etqf, ts,
488
+ &pdma_st,
489
+ rxi);
490
igb_pci_dma_write_rx_desc(core, d, base, &desc, rx_desc_len);
491
igb_ring_advance(core, rxi, rx_desc_len / E1000_MIN_RX_DESC_LEN);
492
} while (pdma_st.desc_offset < pdma_st.total_size);
493
diff --git a/hw/net/igb_regs.h b/hw/net/igb_regs.h
494
index XXXXXXX..XXXXXXX 100644
495
--- a/hw/net/igb_regs.h
496
+++ b/hw/net/igb_regs.h
497
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
498
#define E1000_SRRCTL_BSIZEHDRSIZE_MASK 0x00000F00
499
#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
500
#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
501
+#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000
502
#define E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
503
#define E1000_SRRCTL_DESCTYPE_MASK 0x0E000000
504
#define E1000_SRRCTL_DROP_EN 0x80000000
505
@@ -XXX,XX +XXX,XX @@ union e1000_adv_rx_desc {
506
#define E1000_ADVRXD_PKT_UDP BIT(5)
507
#define E1000_ADVRXD_PKT_SCTP BIT(6)
508
509
+#define IGB_MAX_PS_BUFFERS 2
510
+
511
+#define E1000_ADVRXD_HDR_LEN_OFFSET (21 - 16)
512
+#define E1000_ADVRXD_ADV_HDR_LEN_MASK ((BIT(10) - 1) << \
513
+ E1000_ADVRXD_HDR_LEN_OFFSET)
514
+#define E1000_ADVRXD_HDR_SPH BIT(15)
515
+#define E1000_ADVRXD_ST_ERR_HBO_OFFSET BIT(3 + 20)
516
+
517
static inline uint8_t igb_ivar_entry_rx(uint8_t i)
518
{
519
return i < 8 ? i * 4 : (i - 8) * 4 + 2;
520
diff --git a/hw/net/trace-events b/hw/net/trace-events
521
index XXXXXXX..XXXXXXX 100644
522
--- a/hw/net/trace-events
523
+++ b/hw/net/trace-events
524
@@ -XXX,XX +XXX,XX @@ igb_core_mdic_write_unhandled(uint32_t addr) "MDIC WRITE: PHY[%u] UNHANDLED"
525
igb_link_set_ext_params(bool asd_check, bool speed_select_bypass, bool pfrstd) "Set extended link params: ASD check: %d, Speed select bypass: %d, PF reset done: %d"
526
527
igb_rx_desc_buff_size(uint32_t b) "buffer size: %u"
528
-igb_rx_desc_buff_write(uint64_t addr, uint16_t offset, const void* source, uint32_t len) "addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
529
+igb_rx_desc_buff_write(uint8_t idx, uint64_t addr, uint16_t offset, const void* source, uint32_t len) "buffer %u, addr: 0x%"PRIx64", offset: %u, from: %p, length: %u"
530
531
igb_rx_metadata_rss(uint32_t rss, uint16_t rss_pkt_type) "RSS data: rss: 0x%X, rss_pkt_type: 0x%X"
532
46
--
533
--
47
2.7.4
534
2.7.4
48
49
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
2
2
3
This patch change the compare_chr_send() parameter from CharBackend to CompareState,
3
Rename e1000e_ba_state according and e1000e_write_hdr_to_rx_buffers for
4
we can get more information like vnet_hdr(We use it to support packet with vnet_header).
4
consistency with IGB.
5
5
6
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
6
Signed-off-by: Tomasz Dzieciol <t.dzieciol@partner.samsung.com>
7
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
8
Tested-by: Akihiko Odaki <akihiko.odaki@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
10
---
9
net/colo-compare.c | 14 +++++++-------
11
hw/net/e1000e_core.c | 28 +++++++++++++++-------------
10
1 file changed, 7 insertions(+), 7 deletions(-)
12
1 file changed, 15 insertions(+), 13 deletions(-)
11
13
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
14
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
16
--- a/hw/net/e1000e_core.c
15
+++ b/net/colo-compare.c
17
+++ b/hw/net/e1000e_core.c
16
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@ e1000e_pci_dma_write_rx_desc(E1000ECore *core, dma_addr_t addr,
17
SECONDARY_IN,
18
};
19
20
-static int compare_chr_send(CharBackend *out,
21
+static int compare_chr_send(CompareState *s,
22
const uint8_t *buf,
23
uint32_t size);
24
25
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
26
}
27
28
if (result) {
29
- ret = compare_chr_send(&s->chr_out, pkt->data, pkt->size);
30
+ ret = compare_chr_send(s, pkt->data, pkt->size);
31
if (ret < 0) {
32
error_report("colo_send_primary_packet failed");
33
}
34
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
35
}
19
}
36
}
20
}
37
21
38
-static int compare_chr_send(CharBackend *out,
22
-typedef struct e1000e_ba_state_st {
39
+static int compare_chr_send(CompareState *s,
23
+typedef struct E1000EBAState {
40
const uint8_t *buf,
24
uint16_t written[MAX_PS_BUFFERS];
41
uint32_t size)
25
uint8_t cur_idx;
26
-} e1000e_ba_state;
27
+} E1000EBAState;
28
29
static inline void
30
-e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
31
- hwaddr ba[MAX_PS_BUFFERS],
32
- e1000e_ba_state *bastate,
33
- const char *data,
34
- dma_addr_t data_len)
35
+e1000e_write_hdr_frag_to_rx_buffers(E1000ECore *core,
36
+ hwaddr ba[MAX_PS_BUFFERS],
37
+ E1000EBAState *bastate,
38
+ const char *data,
39
+ dma_addr_t data_len)
42
{
40
{
43
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CharBackend *out,
41
assert(data_len <= core->rxbuf_sizes[0] - bastate->written[0]);
44
return 0;
42
45
}
43
@@ -XXX,XX +XXX,XX @@ e1000e_write_hdr_to_rx_buffers(E1000ECore *core,
46
44
static void
47
- ret = qemu_chr_fe_write_all(out, (uint8_t *)&len, sizeof(len));
45
e1000e_write_payload_frag_to_rx_buffers(E1000ECore *core,
48
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
46
hwaddr ba[MAX_PS_BUFFERS],
49
if (ret != sizeof(len)) {
47
- e1000e_ba_state *bastate,
50
goto err;
48
+ E1000EBAState *bastate,
51
}
49
const char *data,
52
50
dma_addr_t data_len)
53
- ret = qemu_chr_fe_write_all(out, (uint8_t *)buf, size);
51
{
54
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
52
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
55
if (ret != size) {
53
56
goto err;
54
do {
57
}
55
hwaddr ba[MAX_PS_BUFFERS];
58
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
56
- e1000e_ba_state bastate = { { 0 } };
59
57
+ E1000EBAState bastate = { { 0 } };
60
if (packet_enqueue(s, PRIMARY_IN)) {
58
bool is_last = false;
61
trace_colo_compare_main("primary: unsupported packet in");
59
62
- compare_chr_send(&s->chr_out, pri_rs->buf, pri_rs->packet_len);
60
desc_size = total_size - desc_offset;
63
+ compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
61
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
64
} else {
62
iov_copy = MIN(ps_hdr_len - ps_hdr_copied,
65
/* compare connection */
63
iov->iov_len - iov_ofs);
66
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
64
67
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
65
- e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
68
66
- iov->iov_base, iov_copy);
69
while (!g_queue_is_empty(&conn->primary_list)) {
67
+ e1000e_write_hdr_frag_to_rx_buffers(core, ba,
70
pkt = g_queue_pop_head(&conn->primary_list);
68
+ &bastate,
71
- compare_chr_send(&s->chr_out, pkt->data, pkt->size);
69
+ iov->iov_base,
72
+ compare_chr_send(s, pkt->data, pkt->size);
70
+ iov_copy);
73
packet_destroy(pkt, NULL);
71
74
}
72
copy_size -= iov_copy;
75
while (!g_queue_is_empty(&conn->secondary_list)) {
73
ps_hdr_copied += iov_copy;
74
@@ -XXX,XX +XXX,XX @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
75
} else {
76
/* Leave buffer 0 of each descriptor except first */
77
/* empty as per spec 7.1.5.1 */
78
- e1000e_write_hdr_to_rx_buffers(core, ba, &bastate,
79
- NULL, 0);
80
+ e1000e_write_hdr_frag_to_rx_buffers(core, ba, &bastate,
81
+ NULL, 0);
82
}
83
}
84
76
--
85
--
77
2.7.4
86
2.7.4
78
79
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Ilya Maximets <i.maximets@ovn.org>
2
2
3
We add the vnet_hdr_support option for filter-mirror, default is disabled.
3
AF_XDP is a network socket family that allows communication directly
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
with the network device driver in the kernel, bypassing most or all
5
You can use it for example:
5
of the kernel networking stack. In the essence, the technology is
6
-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0,vnet_hdr_support
6
pretty similar to netmap. But, unlike netmap, AF_XDP is Linux-native
7
7
and works with any network interfaces without driver modifications.
8
If it has vnet_hdr_support flag, we will change the sending packet format from
8
Unlike vhost-based backends (kernel, user, vdpa), AF_XDP doesn't
9
struct {int size; const uint8_t buf[];} to {int size; int vnet_hdr_len; const uint8_t buf[];}.
9
require access to character devices or unix sockets. Only access to
10
make other module(like colo-compare) know how to parse net packet correctly.
10
the network interface itself is necessary.
11
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
12
This patch implements a network backend that communicates with the
13
kernel by creating an AF_XDP socket. A chunk of userspace memory
14
is shared between QEMU and the host kernel. 4 ring buffers (Tx, Rx,
15
Fill and Completion) are placed in that memory along with a pool of
16
memory buffers for the packet data. Data transmission is done by
17
allocating one of the buffers, copying packet data into it and
18
placing the pointer into Tx ring. After transmission, device will
19
return the buffer via Completion ring. On Rx, device will take
20
a buffer form a pre-populated Fill ring, write the packet data into
21
it and place the buffer into Rx ring.
22
23
AF_XDP network backend takes on the communication with the host
24
kernel and the network interface and forwards packets to/from the
25
peer device in QEMU.
26
27
Usage example:
28
29
-device virtio-net-pci,netdev=guest1,mac=00:16:35:AF:AA:5C
30
-netdev af-xdp,ifname=ens6f1np1,id=guest1,mode=native,queues=1
31
32
XDP program bridges the socket with a network interface. It can be
33
attached to the interface in 2 different modes:
34
35
1. skb - this mode should work for any interface and doesn't require
36
driver support. With a caveat of lower performance.
37
38
2. native - this does require support from the driver and allows to
39
bypass skb allocation in the kernel and potentially use
40
zero-copy while getting packets in/out userspace.
41
42
By default, QEMU will try to use native mode and fall back to skb.
43
Mode can be forced via 'mode' option. To force 'copy' even in native
44
mode, use 'force-copy=on' option. This might be useful if there is
45
some issue with the driver.
46
47
Option 'queues=N' allows to specify how many device queues should
48
be open. Note that all the queues that are not open are still
49
functional and can receive traffic, but it will not be delivered to
50
QEMU. So, the number of device queues should generally match the
51
QEMU configuration, unless the device is shared with something
52
else and the traffic re-direction to appropriate queues is correctly
53
configured on a device level (e.g. with ethtool -N).
54
'start-queue=M' option can be used to specify from which queue id
55
QEMU should start configuring 'N' queues. It might also be necessary
56
to use this option with certain NICs, e.g. MLX5 NICs. See the docs
57
for examples.
58
59
In a general case QEMU will need CAP_NET_ADMIN and CAP_SYS_ADMIN
60
or CAP_BPF capabilities in order to load default XSK/XDP programs to
61
the network interface and configure BPF maps. It is possible, however,
62
to run with no capabilities. For that to work, an external process
63
with enough capabilities will need to pre-load default XSK program,
64
create AF_XDP sockets and pass their file descriptors to QEMU process
65
on startup via 'sock-fds' option. Network backend will need to be
66
configured with 'inhibit=on' to avoid loading of the program.
67
QEMU will need 32 MB of locked memory (RLIMIT_MEMLOCK) per queue
68
or CAP_IPC_LOCK.
69
70
There are few performance challenges with the current network backends.
71
72
First is that they do not support IO threads. This means that data
73
path is handled by the main thread in QEMU and may slow down other
74
work or may be slowed down by some other work. This also means that
75
taking advantage of multi-queue is generally not possible today.
76
77
Another thing is that data path is going through the device emulation
78
code, which is not really optimized for performance. The fastest
79
"frontend" device is virtio-net. But it's not optimized for heavy
80
traffic either, because it expects such use-cases to be handled via
81
some implementation of vhost (user, kernel, vdpa). In practice, we
82
have virtio notifications and rcu lock/unlock on a per-packet basis
83
and not very efficient accesses to the guest memory. Communication
84
channels between backend and frontend devices do not allow passing
85
more than one packet at a time as well.
86
87
Some of these challenges can be avoided in the future by adding better
88
batching into device emulation or by implementing vhost-af-xdp variant.
89
90
There are also a few kernel limitations. AF_XDP sockets do not
91
support any kinds of checksum or segmentation offloading. Buffers
92
are limited to a page size (4K), i.e. MTU is limited. Multi-buffer
93
support implementation for AF_XDP is in progress, but not ready yet.
94
Also, transmission in all non-zero-copy modes is synchronous, i.e.
95
done in a syscall. That doesn't allow high packet rates on virtual
96
interfaces.
97
98
However, keeping in mind all of these challenges, current implementation
99
of the AF_XDP backend shows a decent performance while running on top
100
of a physical NIC with zero-copy support.
101
102
Test setup:
103
104
2 VMs running on 2 physical hosts connected via ConnectX6-Dx card.
105
Network backend is configured to open the NIC directly in native mode.
106
The driver supports zero-copy. NIC is configured to use 1 queue.
107
108
Inside a VM - iperf3 for basic TCP performance testing and dpdk-testpmd
109
for PPS testing.
110
111
iperf3 result:
112
TCP stream : 19.1 Gbps
113
114
dpdk-testpmd (single queue, single CPU core, 64 B packets) results:
115
Tx only : 3.4 Mpps
116
Rx only : 2.0 Mpps
117
L2 FWD Loopback : 1.5 Mpps
118
119
In skb mode the same setup shows much lower performance, similar to
120
the setup where pair of physical NICs is replaced with veth pair:
121
122
iperf3 result:
123
TCP stream : 9 Gbps
124
125
dpdk-testpmd (single queue, single CPU core, 64 B packets) results:
126
Tx only : 1.2 Mpps
127
Rx only : 1.0 Mpps
128
L2 FWD Loopback : 0.7 Mpps
129
130
Results in skb mode or over the veth are close to results of a tap
131
backend with vhost=on and disabled segmentation offloading bridged
132
with a NIC.
133
134
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
135
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
136
---
15
net/filter-mirror.c | 42 +++++++++++++++++++++++++++++++++++++++++-
137
MAINTAINERS | 4 +
16
qemu-options.hx | 5 ++---
138
hmp-commands.hx | 3 +
17
2 files changed, 43 insertions(+), 4 deletions(-)
139
meson.build | 9 +
18
140
meson_options.txt | 2 +
19
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
141
net/af-xdp.c | 526 ++++++++++++++++++++++++
142
net/clients.h | 5 +
143
net/meson.build | 3 +
144
net/net.c | 6 +
145
qapi/net.json | 58 +++
146
qemu-options.hx | 70 +++-
147
scripts/ci/org.centos/stream/8/x86_64/configure | 1 +
148
scripts/meson-buildoptions.sh | 3 +
149
tests/docker/dockerfiles/debian-amd64.docker | 1 +
150
13 files changed, 690 insertions(+), 1 deletion(-)
151
create mode 100644 net/af-xdp.c
152
153
diff --git a/MAINTAINERS b/MAINTAINERS
20
index XXXXXXX..XXXXXXX 100644
154
index XXXXXXX..XXXXXXX 100644
21
--- a/net/filter-mirror.c
155
--- a/MAINTAINERS
22
+++ b/net/filter-mirror.c
156
+++ b/MAINTAINERS
23
@@ -XXX,XX +XXX,XX @@ typedef struct MirrorState {
157
@@ -XXX,XX +XXX,XX @@ W: http://info.iet.unipi.it/~luigi/netmap/
24
CharBackend chr_in;
158
S: Maintained
25
CharBackend chr_out;
159
F: net/netmap.c
26
SocketReadState rs;
160
27
+ bool vnet_hdr;
161
+AF_XDP network backend
28
} MirrorState;
162
+R: Ilya Maximets <i.maximets@ovn.org>
29
163
+F: net/af-xdp.c
30
static int filter_send(MirrorState *s,
164
+
31
const struct iovec *iov,
165
Host Memory Backends
32
int iovcnt)
166
M: David Hildenbrand <david@redhat.com>
33
{
167
M: Igor Mammedov <imammedo@redhat.com>
34
+ NetFilterState *nf = NETFILTER(s);
168
diff --git a/hmp-commands.hx b/hmp-commands.hx
35
int ret = 0;
169
index XXXXXXX..XXXXXXX 100644
36
ssize_t size = 0;
170
--- a/hmp-commands.hx
37
uint32_t len = 0;
171
+++ b/hmp-commands.hx
38
@@ -XXX,XX +XXX,XX @@ static int filter_send(MirrorState *s,
172
@@ -XXX,XX +XXX,XX @@ ERST
39
goto err;
173
.name = "netdev_add",
40
}
174
.args_type = "netdev:O",
41
175
.params = "[user|tap|socket|stream|dgram|vde|bridge|hubport|netmap|vhost-user"
42
+ if (s->vnet_hdr) {
176
+#ifdef CONFIG_AF_XDP
177
+ "|af-xdp"
178
+#endif
179
#ifdef CONFIG_VMNET
180
"|vmnet-host|vmnet-shared|vmnet-bridged"
181
#endif
182
diff --git a/meson.build b/meson.build
183
index XXXXXXX..XXXXXXX 100644
184
--- a/meson.build
185
+++ b/meson.build
186
@@ -XXX,XX +XXX,XX @@ if libbpf.found() and not cc.links('''
187
endif
188
endif
189
190
+# libxdp
191
+libxdp = not_found
192
+if not get_option('af_xdp').auto() or have_system
193
+ libxdp = dependency('libxdp', required: get_option('af_xdp'),
194
+ version: '>=1.4.0', method: 'pkg-config')
195
+endif
196
+
197
# libdw
198
libdw = not_found
199
if not get_option('libdw').auto() or \
200
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_HEXAGON_IDEF_PARSER', get_option('hexagon_idef_pars
201
config_host_data.set('CONFIG_LIBATTR', have_old_libattr)
202
config_host_data.set('CONFIG_LIBCAP_NG', libcap_ng.found())
203
config_host_data.set('CONFIG_EBPF', libbpf.found())
204
+config_host_data.set('CONFIG_AF_XDP', libxdp.found())
205
config_host_data.set('CONFIG_LIBDAXCTL', libdaxctl.found())
206
config_host_data.set('CONFIG_LIBISCSI', libiscsi.found())
207
config_host_data.set('CONFIG_LIBNFS', libnfs.found())
208
@@ -XXX,XX +XXX,XX @@ summary_info = {}
209
if targetos == 'darwin'
210
summary_info += {'vmnet.framework support': vmnet}
211
endif
212
+summary_info += {'AF_XDP support': libxdp}
213
summary_info += {'slirp support': slirp}
214
summary_info += {'vde support': vde}
215
summary_info += {'netmap support': have_netmap}
216
diff --git a/meson_options.txt b/meson_options.txt
217
index XXXXXXX..XXXXXXX 100644
218
--- a/meson_options.txt
219
+++ b/meson_options.txt
220
@@ -XXX,XX +XXX,XX @@ option('avx512bw', type: 'feature', value: 'auto',
221
option('keyring', type: 'feature', value: 'auto',
222
description: 'Linux keyring support')
223
224
+option('af_xdp', type : 'feature', value : 'auto',
225
+ description: 'AF_XDP network backend support')
226
option('attr', type : 'feature', value : 'auto',
227
description: 'attr/xattr support')
228
option('auth_pam', type : 'feature', value : 'auto',
229
diff --git a/net/af-xdp.c b/net/af-xdp.c
230
new file mode 100644
231
index XXXXXXX..XXXXXXX
232
--- /dev/null
233
+++ b/net/af-xdp.c
234
@@ -XXX,XX +XXX,XX @@
235
+/*
236
+ * AF_XDP network backend.
237
+ *
238
+ * Copyright (c) 2023 Red Hat, Inc.
239
+ *
240
+ * Authors:
241
+ * Ilya Maximets <i.maximets@ovn.org>
242
+ *
243
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
244
+ * See the COPYING file in the top-level directory.
245
+ */
246
+
247
+
248
+#include "qemu/osdep.h"
249
+#include <bpf/bpf.h>
250
+#include <inttypes.h>
251
+#include <linux/if_link.h>
252
+#include <linux/if_xdp.h>
253
+#include <net/if.h>
254
+#include <xdp/xsk.h>
255
+
256
+#include "clients.h"
257
+#include "monitor/monitor.h"
258
+#include "net/net.h"
259
+#include "qapi/error.h"
260
+#include "qemu/cutils.h"
261
+#include "qemu/error-report.h"
262
+#include "qemu/iov.h"
263
+#include "qemu/main-loop.h"
264
+#include "qemu/memalign.h"
265
+
266
+
267
+typedef struct AFXDPState {
268
+ NetClientState nc;
269
+
270
+ struct xsk_socket *xsk;
271
+ struct xsk_ring_cons rx;
272
+ struct xsk_ring_prod tx;
273
+ struct xsk_ring_cons cq;
274
+ struct xsk_ring_prod fq;
275
+
276
+ char ifname[IFNAMSIZ];
277
+ int ifindex;
278
+ bool read_poll;
279
+ bool write_poll;
280
+ uint32_t outstanding_tx;
281
+
282
+ uint64_t *pool;
283
+ uint32_t n_pool;
284
+ char *buffer;
285
+ struct xsk_umem *umem;
286
+
287
+ uint32_t n_queues;
288
+ uint32_t xdp_flags;
289
+ bool inhibit;
290
+} AFXDPState;
291
+
292
+#define AF_XDP_BATCH_SIZE 64
293
+
294
+static void af_xdp_send(void *opaque);
295
+static void af_xdp_writable(void *opaque);
296
+
297
+/* Set the event-loop handlers for the af-xdp backend. */
298
+static void af_xdp_update_fd_handler(AFXDPState *s)
299
+{
300
+ qemu_set_fd_handler(xsk_socket__fd(s->xsk),
301
+ s->read_poll ? af_xdp_send : NULL,
302
+ s->write_poll ? af_xdp_writable : NULL,
303
+ s);
304
+}
305
+
306
+/* Update the read handler. */
307
+static void af_xdp_read_poll(AFXDPState *s, bool enable)
308
+{
309
+ if (s->read_poll != enable) {
310
+ s->read_poll = enable;
311
+ af_xdp_update_fd_handler(s);
312
+ }
313
+}
314
+
315
+/* Update the write handler. */
316
+static void af_xdp_write_poll(AFXDPState *s, bool enable)
317
+{
318
+ if (s->write_poll != enable) {
319
+ s->write_poll = enable;
320
+ af_xdp_update_fd_handler(s);
321
+ }
322
+}
323
+
324
+static void af_xdp_poll(NetClientState *nc, bool enable)
325
+{
326
+ AFXDPState *s = DO_UPCAST(AFXDPState, nc, nc);
327
+
328
+ if (s->read_poll != enable || s->write_poll != enable) {
329
+ s->write_poll = enable;
330
+ s->read_poll = enable;
331
+ af_xdp_update_fd_handler(s);
332
+ }
333
+}
334
+
335
+static void af_xdp_complete_tx(AFXDPState *s)
336
+{
337
+ uint32_t idx = 0;
338
+ uint32_t done, i;
339
+ uint64_t *addr;
340
+
341
+ done = xsk_ring_cons__peek(&s->cq, XSK_RING_CONS__DEFAULT_NUM_DESCS, &idx);
342
+
343
+ for (i = 0; i < done; i++) {
344
+ addr = (void *) xsk_ring_cons__comp_addr(&s->cq, idx++);
345
+ s->pool[s->n_pool++] = *addr;
346
+ s->outstanding_tx--;
347
+ }
348
+
349
+ if (done) {
350
+ xsk_ring_cons__release(&s->cq, done);
351
+ }
352
+}
353
+
354
+/*
355
+ * The fd_write() callback, invoked if the fd is marked as writable
356
+ * after a poll.
357
+ */
358
+static void af_xdp_writable(void *opaque)
359
+{
360
+ AFXDPState *s = opaque;
361
+
362
+ /* Try to recover buffers that are already sent. */
363
+ af_xdp_complete_tx(s);
364
+
365
+ /*
366
+ * Unregister the handler, unless we still have packets to transmit
367
+ * and kernel needs a wake up.
368
+ */
369
+ if (!s->outstanding_tx || !xsk_ring_prod__needs_wakeup(&s->tx)) {
370
+ af_xdp_write_poll(s, false);
371
+ }
372
+
373
+ /* Flush any buffered packets. */
374
+ qemu_flush_queued_packets(&s->nc);
375
+}
376
+
377
+static ssize_t af_xdp_receive(NetClientState *nc,
378
+ const uint8_t *buf, size_t size)
379
+{
380
+ AFXDPState *s = DO_UPCAST(AFXDPState, nc, nc);
381
+ struct xdp_desc *desc;
382
+ uint32_t idx;
383
+ void *data;
384
+
385
+ /* Try to recover buffers that are already sent. */
386
+ af_xdp_complete_tx(s);
387
+
388
+ if (size > XSK_UMEM__DEFAULT_FRAME_SIZE) {
389
+ /* We can't transmit packet this size... */
390
+ return size;
391
+ }
392
+
393
+ if (!s->n_pool || !xsk_ring_prod__reserve(&s->tx, 1, &idx)) {
43
+ /*
394
+ /*
44
+ * If vnet_hdr = on, we send vnet header len to make other
395
+ * Out of buffers or space in tx ring. Poll until we can write.
45
+ * module(like colo-compare) know how to parse net
396
+ * This will also kick the Tx, if it was waiting on CQ.
46
+ * packet correctly.
47
+ */
397
+ */
48
+ ssize_t vnet_hdr_len;
398
+ af_xdp_write_poll(s, true);
49
+
399
+ return 0;
50
+ vnet_hdr_len = nf->netdev->vnet_hdr_len;
400
+ }
51
+
401
+
52
+ len = htonl(vnet_hdr_len);
402
+ desc = xsk_ring_prod__tx_desc(&s->tx, idx);
53
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
403
+ desc->addr = s->pool[--s->n_pool];
54
+ if (ret != sizeof(len)) {
404
+ desc->len = size;
405
+
406
+ data = xsk_umem__get_data(s->buffer, desc->addr);
407
+ memcpy(data, buf, size);
408
+
409
+ xsk_ring_prod__submit(&s->tx, 1);
410
+ s->outstanding_tx++;
411
+
412
+ if (xsk_ring_prod__needs_wakeup(&s->tx)) {
413
+ af_xdp_write_poll(s, true);
414
+ }
415
+
416
+ return size;
417
+}
418
+
419
+/*
420
+ * Complete a previous send (backend --> guest) and enable the
421
+ * fd_read callback.
422
+ */
423
+static void af_xdp_send_completed(NetClientState *nc, ssize_t len)
424
+{
425
+ AFXDPState *s = DO_UPCAST(AFXDPState, nc, nc);
426
+
427
+ af_xdp_read_poll(s, true);
428
+}
429
+
430
+static void af_xdp_fq_refill(AFXDPState *s, uint32_t n)
431
+{
432
+ uint32_t i, idx = 0;
433
+
434
+ /* Leave one packet for Tx, just in case. */
435
+ if (s->n_pool < n + 1) {
436
+ n = s->n_pool;
437
+ }
438
+
439
+ if (!n || !xsk_ring_prod__reserve(&s->fq, n, &idx)) {
440
+ return;
441
+ }
442
+
443
+ for (i = 0; i < n; i++) {
444
+ *xsk_ring_prod__fill_addr(&s->fq, idx++) = s->pool[--s->n_pool];
445
+ }
446
+ xsk_ring_prod__submit(&s->fq, n);
447
+
448
+ if (xsk_ring_prod__needs_wakeup(&s->fq)) {
449
+ /* Receive was blocked by not having enough buffers. Wake it up. */
450
+ af_xdp_read_poll(s, true);
451
+ }
452
+}
453
+
454
+static void af_xdp_send(void *opaque)
455
+{
456
+ uint32_t i, n_rx, idx = 0;
457
+ AFXDPState *s = opaque;
458
+
459
+ n_rx = xsk_ring_cons__peek(&s->rx, AF_XDP_BATCH_SIZE, &idx);
460
+ if (!n_rx) {
461
+ return;
462
+ }
463
+
464
+ for (i = 0; i < n_rx; i++) {
465
+ const struct xdp_desc *desc;
466
+ struct iovec iov;
467
+
468
+ desc = xsk_ring_cons__rx_desc(&s->rx, idx++);
469
+
470
+ iov.iov_base = xsk_umem__get_data(s->buffer, desc->addr);
471
+ iov.iov_len = desc->len;
472
+
473
+ s->pool[s->n_pool++] = desc->addr;
474
+
475
+ if (!qemu_sendv_packet_async(&s->nc, &iov, 1,
476
+ af_xdp_send_completed)) {
477
+ /*
478
+ * The peer does not receive anymore. Packet is queued, stop
479
+ * reading from the backend until af_xdp_send_completed().
480
+ */
481
+ af_xdp_read_poll(s, false);
482
+
483
+ /* Return unused descriptors to not break the ring cache. */
484
+ xsk_ring_cons__cancel(&s->rx, n_rx - i - 1);
485
+ n_rx = i + 1;
486
+ break;
487
+ }
488
+ }
489
+
490
+ /* Release actually sent descriptors and try to re-fill. */
491
+ xsk_ring_cons__release(&s->rx, n_rx);
492
+ af_xdp_fq_refill(s, AF_XDP_BATCH_SIZE);
493
+}
494
+
495
+/* Flush and close. */
496
+static void af_xdp_cleanup(NetClientState *nc)
497
+{
498
+ AFXDPState *s = DO_UPCAST(AFXDPState, nc, nc);
499
+
500
+ qemu_purge_queued_packets(nc);
501
+
502
+ af_xdp_poll(nc, false);
503
+
504
+ xsk_socket__delete(s->xsk);
505
+ s->xsk = NULL;
506
+ g_free(s->pool);
507
+ s->pool = NULL;
508
+ xsk_umem__delete(s->umem);
509
+ s->umem = NULL;
510
+ qemu_vfree(s->buffer);
511
+ s->buffer = NULL;
512
+
513
+ /* Remove the program if it's the last open queue. */
514
+ if (!s->inhibit && nc->queue_index == s->n_queues - 1 && s->xdp_flags
515
+ && bpf_xdp_detach(s->ifindex, s->xdp_flags, NULL) != 0) {
516
+ fprintf(stderr,
517
+ "af-xdp: unable to remove XDP program from '%s', ifindex: %d\n",
518
+ s->ifname, s->ifindex);
519
+ }
520
+}
521
+
522
+static int af_xdp_umem_create(AFXDPState *s, int sock_fd, Error **errp)
523
+{
524
+ struct xsk_umem_config config = {
525
+ .fill_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
526
+ .comp_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
527
+ .frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE,
528
+ .frame_headroom = 0,
529
+ };
530
+ uint64_t n_descs;
531
+ uint64_t size;
532
+ int64_t i;
533
+ int ret;
534
+
535
+ /* Number of descriptors if all 4 queues (rx, tx, cq, fq) are full. */
536
+ n_descs = (XSK_RING_PROD__DEFAULT_NUM_DESCS
537
+ + XSK_RING_CONS__DEFAULT_NUM_DESCS) * 2;
538
+ size = n_descs * XSK_UMEM__DEFAULT_FRAME_SIZE;
539
+
540
+ s->buffer = qemu_memalign(qemu_real_host_page_size(), size);
541
+ memset(s->buffer, 0, size);
542
+
543
+ if (sock_fd < 0) {
544
+ ret = xsk_umem__create(&s->umem, s->buffer, size,
545
+ &s->fq, &s->cq, &config);
546
+ } else {
547
+ ret = xsk_umem__create_with_fd(&s->umem, sock_fd, s->buffer, size,
548
+ &s->fq, &s->cq, &config);
549
+ }
550
+
551
+ if (ret) {
552
+ qemu_vfree(s->buffer);
553
+ error_setg_errno(errp, errno,
554
+ "failed to create umem for %s queue_index: %d",
555
+ s->ifname, s->nc.queue_index);
556
+ return -1;
557
+ }
558
+
559
+ s->pool = g_new(uint64_t, n_descs);
560
+ /* Fill the pool in the opposite order, because it's a LIFO queue. */
561
+ for (i = n_descs; i >= 0; i--) {
562
+ s->pool[i] = i * XSK_UMEM__DEFAULT_FRAME_SIZE;
563
+ }
564
+ s->n_pool = n_descs;
565
+
566
+ af_xdp_fq_refill(s, XSK_RING_PROD__DEFAULT_NUM_DESCS);
567
+
568
+ return 0;
569
+}
570
+
571
+static int af_xdp_socket_create(AFXDPState *s,
572
+ const NetdevAFXDPOptions *opts, Error **errp)
573
+{
574
+ struct xsk_socket_config cfg = {
575
+ .rx_size = XSK_RING_CONS__DEFAULT_NUM_DESCS,
576
+ .tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS,
577
+ .libxdp_flags = 0,
578
+ .bind_flags = XDP_USE_NEED_WAKEUP,
579
+ .xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST,
580
+ };
581
+ int queue_id, error = 0;
582
+
583
+ s->inhibit = opts->has_inhibit && opts->inhibit;
584
+ if (s->inhibit) {
585
+ cfg.libxdp_flags |= XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD;
586
+ }
587
+
588
+ if (opts->has_force_copy && opts->force_copy) {
589
+ cfg.bind_flags |= XDP_COPY;
590
+ }
591
+
592
+ queue_id = s->nc.queue_index;
593
+ if (opts->has_start_queue && opts->start_queue > 0) {
594
+ queue_id += opts->start_queue;
595
+ }
596
+
597
+ if (opts->has_mode) {
598
+ /* Specific mode requested. */
599
+ cfg.xdp_flags |= (opts->mode == AFXDP_MODE_NATIVE)
600
+ ? XDP_FLAGS_DRV_MODE : XDP_FLAGS_SKB_MODE;
601
+ if (xsk_socket__create(&s->xsk, s->ifname, queue_id,
602
+ s->umem, &s->rx, &s->tx, &cfg)) {
603
+ error = errno;
604
+ }
605
+ } else {
606
+ /* No mode requested, try native first. */
607
+ cfg.xdp_flags |= XDP_FLAGS_DRV_MODE;
608
+
609
+ if (xsk_socket__create(&s->xsk, s->ifname, queue_id,
610
+ s->umem, &s->rx, &s->tx, &cfg)) {
611
+ /* Can't use native mode, try skb. */
612
+ cfg.xdp_flags &= ~XDP_FLAGS_DRV_MODE;
613
+ cfg.xdp_flags |= XDP_FLAGS_SKB_MODE;
614
+
615
+ if (xsk_socket__create(&s->xsk, s->ifname, queue_id,
616
+ s->umem, &s->rx, &s->tx, &cfg)) {
617
+ error = errno;
618
+ }
619
+ }
620
+ }
621
+
622
+ if (error) {
623
+ error_setg_errno(errp, error,
624
+ "failed to create AF_XDP socket for %s queue_id: %d",
625
+ s->ifname, queue_id);
626
+ return -1;
627
+ }
628
+
629
+ s->xdp_flags = cfg.xdp_flags;
630
+
631
+ return 0;
632
+}
633
+
634
+/* NetClientInfo methods. */
635
+static NetClientInfo net_af_xdp_info = {
636
+ .type = NET_CLIENT_DRIVER_AF_XDP,
637
+ .size = sizeof(AFXDPState),
638
+ .receive = af_xdp_receive,
639
+ .poll = af_xdp_poll,
640
+ .cleanup = af_xdp_cleanup,
641
+};
642
+
643
+static int *parse_socket_fds(const char *sock_fds_str,
644
+ int64_t n_expected, Error **errp)
645
+{
646
+ gchar **substrings = g_strsplit(sock_fds_str, ":", -1);
647
+ int64_t i, n_sock_fds = g_strv_length(substrings);
648
+ int *sock_fds = NULL;
649
+
650
+ if (n_sock_fds != n_expected) {
651
+ error_setg(errp, "expected %"PRIi64" socket fds, got %"PRIi64,
652
+ n_expected, n_sock_fds);
653
+ goto exit;
654
+ }
655
+
656
+ sock_fds = g_new(int, n_sock_fds);
657
+
658
+ for (i = 0; i < n_sock_fds; i++) {
659
+ sock_fds[i] = monitor_fd_param(monitor_cur(), substrings[i], errp);
660
+ if (sock_fds[i] < 0) {
661
+ g_free(sock_fds);
662
+ sock_fds = NULL;
663
+ goto exit;
664
+ }
665
+ }
666
+
667
+exit:
668
+ g_strfreev(substrings);
669
+ return sock_fds;
670
+}
671
+
672
+/*
673
+ * The exported init function.
674
+ *
675
+ * ... -netdev af-xdp,ifname="..."
676
+ */
677
+int net_init_af_xdp(const Netdev *netdev,
678
+ const char *name, NetClientState *peer, Error **errp)
679
+{
680
+ const NetdevAFXDPOptions *opts = &netdev->u.af_xdp;
681
+ NetClientState *nc, *nc0 = NULL;
682
+ unsigned int ifindex;
683
+ uint32_t prog_id = 0;
684
+ int *sock_fds = NULL;
685
+ int64_t i, queues;
686
+ Error *err = NULL;
687
+ AFXDPState *s;
688
+
689
+ ifindex = if_nametoindex(opts->ifname);
690
+ if (!ifindex) {
691
+ error_setg_errno(errp, errno, "failed to get ifindex for '%s'",
692
+ opts->ifname);
693
+ return -1;
694
+ }
695
+
696
+ queues = opts->has_queues ? opts->queues : 1;
697
+ if (queues < 1) {
698
+ error_setg(errp, "invalid number of queues (%" PRIi64 ") for '%s'",
699
+ queues, opts->ifname);
700
+ return -1;
701
+ }
702
+
703
+ if ((opts->has_inhibit && opts->inhibit) != !!opts->sock_fds) {
704
+ error_setg(errp, "'inhibit=on' requires 'sock-fds' and vice versa");
705
+ return -1;
706
+ }
707
+
708
+ if (opts->sock_fds) {
709
+ sock_fds = parse_socket_fds(opts->sock_fds, queues, errp);
710
+ if (!sock_fds) {
711
+ return -1;
712
+ }
713
+ }
714
+
715
+ for (i = 0; i < queues; i++) {
716
+ nc = qemu_new_net_client(&net_af_xdp_info, peer, "af-xdp", name);
717
+ qemu_set_info_str(nc, "af-xdp%"PRIi64" to %s", i, opts->ifname);
718
+ nc->queue_index = i;
719
+
720
+ if (!nc0) {
721
+ nc0 = nc;
722
+ }
723
+
724
+ s = DO_UPCAST(AFXDPState, nc, nc);
725
+
726
+ pstrcpy(s->ifname, sizeof(s->ifname), opts->ifname);
727
+ s->ifindex = ifindex;
728
+ s->n_queues = queues;
729
+
730
+ if (af_xdp_umem_create(s, sock_fds ? sock_fds[i] : -1, errp)
731
+ || af_xdp_socket_create(s, opts, errp)) {
732
+ /* Make sure the XDP program will be removed. */
733
+ s->n_queues = i;
734
+ error_propagate(errp, err);
55
+ goto err;
735
+ goto err;
56
+ }
736
+ }
57
+ }
737
+ }
58
+
738
+
59
buf = g_malloc(size);
739
+ if (nc0) {
60
iov_to_buf(iov, iovcnt, 0, buf, size);
740
+ s = DO_UPCAST(AFXDPState, nc, nc0);
61
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
741
+ if (bpf_xdp_query_id(s->ifindex, s->xdp_flags, &prog_id) || !prog_id) {
62
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
742
+ error_setg_errno(errp, errno,
63
}
743
+ "no XDP program loaded on '%s', ifindex: %d",
64
}
744
+ s->ifname, s->ifindex);
65
745
+ goto err;
66
- net_socket_rs_init(&s->rs, redirector_rs_finalize, false);
746
+ }
67
+ net_socket_rs_init(&s->rs, redirector_rs_finalize, s->vnet_hdr);
747
+ }
68
748
+
69
if (s->indev) {
749
+ af_xdp_read_poll(s, true); /* Initially only poll for reads. */
70
chr = qemu_chr_find(s->indev);
750
+
71
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_set_outdev(Object *obj,
751
+ return 0;
72
}
752
+
73
}
753
+err:
74
754
+ g_free(sock_fds);
75
+static bool filter_mirror_get_vnet_hdr(Object *obj, Error **errp)
755
+ if (nc0) {
76
+{
756
+ qemu_del_net_client(nc0);
77
+ MirrorState *s = FILTER_MIRROR(obj);
757
+ }
78
+
758
+
79
+ return s->vnet_hdr;
759
+ return -1;
80
+}
760
+}
81
+
761
diff --git a/net/clients.h b/net/clients.h
82
+static void filter_mirror_set_vnet_hdr(Object *obj, bool value, Error **errp)
762
index XXXXXXX..XXXXXXX 100644
83
+{
763
--- a/net/clients.h
84
+ MirrorState *s = FILTER_MIRROR(obj);
764
+++ b/net/clients.h
85
+
765
@@ -XXX,XX +XXX,XX @@ int net_init_netmap(const Netdev *netdev, const char *name,
86
+ s->vnet_hdr = value;
766
NetClientState *peer, Error **errp);
87
+}
767
#endif
88
+
768
89
static char *filter_redirector_get_outdev(Object *obj, Error **errp)
769
+#ifdef CONFIG_AF_XDP
90
{
770
+int net_init_af_xdp(const Netdev *netdev, const char *name,
91
MirrorState *s = FILTER_REDIRECTOR(obj);
771
+ NetClientState *peer, Error **errp);
92
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
772
+#endif
93
773
+
94
static void filter_mirror_init(Object *obj)
774
int net_init_vhost_user(const Netdev *netdev, const char *name,
95
{
775
NetClientState *peer, Error **errp);
96
+ MirrorState *s = FILTER_MIRROR(obj);
776
97
+
777
diff --git a/net/meson.build b/net/meson.build
98
object_property_add_str(obj, "outdev", filter_mirror_get_outdev,
778
index XXXXXXX..XXXXXXX 100644
99
filter_mirror_set_outdev, NULL);
779
--- a/net/meson.build
100
+
780
+++ b/net/meson.build
101
+ s->vnet_hdr = false;
781
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: vde, if_true: files('vde.c'))
102
+ object_property_add_bool(obj, "vnet_hdr_support",
782
if have_netmap
103
+ filter_mirror_get_vnet_hdr,
783
system_ss.add(files('netmap.c'))
104
+ filter_mirror_set_vnet_hdr, NULL);
784
endif
105
}
785
+
106
786
+system_ss.add(when: libxdp, if_true: files('af-xdp.c'))
107
static void filter_redirector_init(Object *obj)
787
+
788
if have_vhost_net_user
789
system_ss.add(when: 'CONFIG_VIRTIO_NET', if_true: files('vhost-user.c'), if_false: files('vhost-user-stub.c'))
790
system_ss.add(when: 'CONFIG_ALL', if_true: files('vhost-user-stub.c'))
791
diff --git a/net/net.c b/net/net.c
792
index XXXXXXX..XXXXXXX 100644
793
--- a/net/net.c
794
+++ b/net/net.c
795
@@ -XXX,XX +XXX,XX @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])(
796
#ifdef CONFIG_NETMAP
797
[NET_CLIENT_DRIVER_NETMAP] = net_init_netmap,
798
#endif
799
+#ifdef CONFIG_AF_XDP
800
+ [NET_CLIENT_DRIVER_AF_XDP] = net_init_af_xdp,
801
+#endif
802
#ifdef CONFIG_NET_BRIDGE
803
[NET_CLIENT_DRIVER_BRIDGE] = net_init_bridge,
804
#endif
805
@@ -XXX,XX +XXX,XX @@ void show_netdevs(void)
806
#ifdef CONFIG_NETMAP
807
"netmap",
808
#endif
809
+#ifdef CONFIG_AF_XDP
810
+ "af-xdp",
811
+#endif
812
#ifdef CONFIG_POSIX
813
"vhost-user",
814
#endif
815
diff --git a/qapi/net.json b/qapi/net.json
816
index XXXXXXX..XXXXXXX 100644
817
--- a/qapi/net.json
818
+++ b/qapi/net.json
819
@@ -XXX,XX +XXX,XX @@
820
'*devname': 'str' } }
821
822
##
823
+# @AFXDPMode:
824
+#
825
+# Attach mode for a default XDP program
826
+#
827
+# @skb: generic mode, no driver support necessary
828
+#
829
+# @native: DRV mode, program is attached to a driver, packets are passed to
830
+# the socket without allocation of skb.
831
+#
832
+# Since: 8.2
833
+##
834
+{ 'enum': 'AFXDPMode',
835
+ 'data': [ 'native', 'skb' ],
836
+ 'if': 'CONFIG_AF_XDP' }
837
+
838
+##
839
+# @NetdevAFXDPOptions:
840
+#
841
+# AF_XDP network backend
842
+#
843
+# @ifname: The name of an existing network interface.
844
+#
845
+# @mode: Attach mode for a default XDP program. If not specified, then
846
+# 'native' will be tried first, then 'skb'.
847
+#
848
+# @force-copy: Force XDP copy mode even if device supports zero-copy.
849
+# (default: false)
850
+#
851
+# @queues: number of queues to be used for multiqueue interfaces (default: 1).
852
+#
853
+# @start-queue: Use @queues starting from this queue number (default: 0).
854
+#
855
+# @inhibit: Don't load a default XDP program, use one already loaded to
856
+# the interface (default: false). Requires @sock-fds.
857
+#
858
+# @sock-fds: A colon (:) separated list of file descriptors for already open
859
+# but not bound AF_XDP sockets in the queue order. One fd per queue.
860
+# These descriptors should already be added into XDP socket map for
861
+# corresponding queues. Requires @inhibit.
862
+#
863
+# Since: 8.2
864
+##
865
+{ 'struct': 'NetdevAFXDPOptions',
866
+ 'data': {
867
+ 'ifname': 'str',
868
+ '*mode': 'AFXDPMode',
869
+ '*force-copy': 'bool',
870
+ '*queues': 'int',
871
+ '*start-queue': 'int',
872
+ '*inhibit': 'bool',
873
+ '*sock-fds': 'str' },
874
+ 'if': 'CONFIG_AF_XDP' }
875
+
876
+##
877
# @NetdevVhostUserOptions:
878
#
879
# Vhost-user network backend
880
@@ -XXX,XX +XXX,XX @@
881
# @vmnet-bridged: since 7.1
882
# @stream: since 7.2
883
# @dgram: since 7.2
884
+# @af-xdp: since 8.2
885
#
886
# Since: 2.7
887
##
888
@@ -XXX,XX +XXX,XX @@
889
'data': [ 'none', 'nic', 'user', 'tap', 'l2tpv3', 'socket', 'stream',
890
'dgram', 'vde', 'bridge', 'hubport', 'netmap', 'vhost-user',
891
'vhost-vdpa',
892
+ { 'name': 'af-xdp', 'if': 'CONFIG_AF_XDP' },
893
{ 'name': 'vmnet-host', 'if': 'CONFIG_VMNET' },
894
{ 'name': 'vmnet-shared', 'if': 'CONFIG_VMNET' },
895
{ 'name': 'vmnet-bridged', 'if': 'CONFIG_VMNET' }] }
896
@@ -XXX,XX +XXX,XX @@
897
'bridge': 'NetdevBridgeOptions',
898
'hubport': 'NetdevHubPortOptions',
899
'netmap': 'NetdevNetmapOptions',
900
+ 'af-xdp': { 'type': 'NetdevAFXDPOptions',
901
+ 'if': 'CONFIG_AF_XDP' },
902
'vhost-user': 'NetdevVhostUserOptions',
903
'vhost-vdpa': 'NetdevVhostVDPAOptions',
904
'vmnet-host': { 'type': 'NetdevVmnetHostOptions',
108
diff --git a/qemu-options.hx b/qemu-options.hx
905
diff --git a/qemu-options.hx b/qemu-options.hx
109
index XXXXXXX..XXXXXXX 100644
906
index XXXXXXX..XXXXXXX 100644
110
--- a/qemu-options.hx
907
--- a/qemu-options.hx
111
+++ b/qemu-options.hx
908
+++ b/qemu-options.hx
112
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
909
@@ -XXX,XX +XXX,XX @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
113
@option{tx}: the filter is attached to the transmit queue of the netdev,
910
" VALE port (created on the fly) called 'name' ('nmname' is name of the \n"
114
where it will receive packets sent by the netdev.
911
" netmap device, defaults to '/dev/netmap')\n"
115
912
#endif
116
-@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
913
+#ifdef CONFIG_AF_XDP
117
+@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
914
+ "-netdev af-xdp,id=str,ifname=name[,mode=native|skb][,force-copy=on|off]\n"
118
915
+ " [,queues=n][,start-queue=m][,inhibit=on|off][,sock-fds=x:y:...:z]\n"
119
-filter-mirror on netdev @var{netdevid},mirror net packet to chardev
916
+ " attach to the existing network interface 'name' with AF_XDP socket\n"
120
-@var{chardevid}
917
+ " use 'mode=MODE' to specify an XDP program attach mode\n"
121
+filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
918
+ " use 'force-copy=on|off' to force XDP copy mode even if device supports zero-copy (default: off)\n"
122
919
+ " use 'inhibit=on|off' to inhibit loading of a default XDP program (default: off)\n"
123
@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
920
+ " with inhibit=on,\n"
124
outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
921
+ " use 'sock-fds' to provide file descriptors for already open AF_XDP sockets\n"
922
+ " added to a socket map in XDP program. One socket per queue.\n"
923
+ " use 'queues=n' to specify how many queues of a multiqueue interface should be used\n"
924
+ " use 'start-queue=m' to specify the first queue that should be used\n"
925
+#endif
926
#ifdef CONFIG_POSIX
927
"-netdev vhost-user,id=str,chardev=dev[,vhostforce=on|off]\n"
928
" configure a vhost-user network, backed by a chardev 'dev'\n"
929
@@ -XXX,XX +XXX,XX @@ DEF("nic", HAS_ARG, QEMU_OPTION_nic,
930
#ifdef CONFIG_NETMAP
931
"netmap|"
932
#endif
933
+#ifdef CONFIG_AF_XDP
934
+ "af-xdp|"
935
+#endif
936
#ifdef CONFIG_POSIX
937
"vhost-user|"
938
#endif
939
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
940
#ifdef CONFIG_NETMAP
941
"netmap|"
942
#endif
943
+#ifdef CONFIG_AF_XDP
944
+ "af-xdp|"
945
+#endif
946
#ifdef CONFIG_VMNET
947
"vmnet-host|vmnet-shared|vmnet-bridged|"
948
#endif
949
@@ -XXX,XX +XXX,XX @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
950
" old way to initialize a host network interface\n"
951
" (use the -netdev option if possible instead)\n", QEMU_ARCH_ALL)
952
SRST
953
-``-nic [tap|bridge|user|l2tpv3|vde|netmap|vhost-user|socket][,...][,mac=macaddr][,model=mn]``
954
+``-nic [tap|bridge|user|l2tpv3|vde|netmap|af-xdp|vhost-user|socket][,...][,mac=macaddr][,model=mn]``
955
This option is a shortcut for configuring both the on-board
956
(default) guest NIC hardware and the host network backend in one go.
957
The host backend options are the same as with the corresponding
958
@@ -XXX,XX +XXX,XX @@ SRST
959
# launch QEMU instance
960
|qemu_system| linux.img -nic vde,sock=/tmp/myswitch
961
962
+``-netdev af-xdp,id=str,ifname=name[,mode=native|skb][,force-copy=on|off][,queues=n][,start-queue=m][,inhibit=on|off][,sock-fds=x:y:...:z]``
963
+ Configure AF_XDP backend to connect to a network interface 'name'
964
+ using AF_XDP socket. A specific program attach mode for a default
965
+ XDP program can be forced with 'mode', defaults to best-effort,
966
+ where the likely most performant mode will be in use. Number of queues
967
+ 'n' should generally match the number or queues in the interface,
968
+ defaults to 1. Traffic arriving on non-configured device queues will
969
+ not be delivered to the network backend.
970
+
971
+ .. parsed-literal::
972
+
973
+ # set number of queues to 4
974
+ ethtool -L eth0 combined 4
975
+ # launch QEMU instance
976
+ |qemu_system| linux.img -device virtio-net-pci,netdev=n1 \\
977
+ -netdev af-xdp,id=n1,ifname=eth0,queues=4
978
+
979
+ 'start-queue' option can be specified if a particular range of queues
980
+ [m, m + n] should be in use. For example, this is may be necessary in
981
+ order to use certain NICs in native mode. Kernel allows the driver to
982
+ create a separate set of XDP queues on top of regular ones, and only
983
+ these queues can be used for AF_XDP sockets. NICs that work this way
984
+ may also require an additional traffic redirection with ethtool to these
985
+ special queues.
986
+
987
+ .. parsed-literal::
988
+
989
+ # set number of queues to 1
990
+ ethtool -L eth0 combined 1
991
+ # redirect all the traffic to the second queue (id: 1)
992
+ # note: drivers may require non-empty key/mask pair.
993
+ ethtool -N eth0 flow-type ether \\
994
+ dst 00:00:00:00:00:00 m FF:FF:FF:FF:FF:FE action 1
995
+ ethtool -N eth0 flow-type ether \\
996
+ dst 00:00:00:00:00:01 m FF:FF:FF:FF:FF:FE action 1
997
+ # launch QEMU instance
998
+ |qemu_system| linux.img -device virtio-net-pci,netdev=n1 \\
999
+ -netdev af-xdp,id=n1,ifname=eth0,queues=1,start-queue=1
1000
+
1001
+ XDP program can also be loaded externally. In this case 'inhibit' option
1002
+ should be set to 'on' and 'sock-fds' provided with file descriptors for
1003
+ already open but not bound XDP sockets already added to a socket map for
1004
+ corresponding queues. One socket per queue.
1005
+
1006
+ .. parsed-literal::
1007
+
1008
+ |qemu_system| linux.img -device virtio-net-pci,netdev=n1 \\
1009
+ -netdev af-xdp,id=n1,ifname=eth0,queues=3,inhibit=on,sock-fds=15:16:17
1010
+
1011
``-netdev vhost-user,chardev=id[,vhostforce=on|off][,queues=n]``
1012
Establish a vhost-user netdev, backed by a chardev id. The chardev
1013
should be a unix domain socket backed one. The vhost-user uses a
1014
diff --git a/scripts/ci/org.centos/stream/8/x86_64/configure b/scripts/ci/org.centos/stream/8/x86_64/configure
1015
index XXXXXXX..XXXXXXX 100755
1016
--- a/scripts/ci/org.centos/stream/8/x86_64/configure
1017
+++ b/scripts/ci/org.centos/stream/8/x86_64/configure
1018
@@ -XXX,XX +XXX,XX @@
1019
--block-drv-ro-whitelist="vmdk,vhdx,vpc,https,ssh" \
1020
--with-coroutine=ucontext \
1021
--tls-priority=@QEMU,SYSTEM \
1022
+--disable-af-xdp \
1023
--disable-attr \
1024
--disable-auth-pam \
1025
--disable-avx2 \
1026
diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh
1027
index XXXXXXX..XXXXXXX 100644
1028
--- a/scripts/meson-buildoptions.sh
1029
+++ b/scripts/meson-buildoptions.sh
1030
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
1031
printf "%s\n" 'disabled with --disable-FEATURE, default is enabled if available'
1032
printf "%s\n" '(unless built with --without-default-features):'
1033
printf "%s\n" ''
1034
+ printf "%s\n" ' af-xdp AF_XDP network backend support'
1035
printf "%s\n" ' alsa ALSA sound support'
1036
printf "%s\n" ' attr attr/xattr support'
1037
printf "%s\n" ' auth-pam PAM access control'
1038
@@ -XXX,XX +XXX,XX @@ meson_options_help() {
1039
}
1040
_meson_option_parse() {
1041
case $1 in
1042
+ --enable-af-xdp) printf "%s" -Daf_xdp=enabled ;;
1043
+ --disable-af-xdp) printf "%s" -Daf_xdp=disabled ;;
1044
--enable-alsa) printf "%s" -Dalsa=enabled ;;
1045
--disable-alsa) printf "%s" -Dalsa=disabled ;;
1046
--enable-attr) printf "%s" -Dattr=enabled ;;
1047
diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker
1048
index XXXXXXX..XXXXXXX 100644
1049
--- a/tests/docker/dockerfiles/debian-amd64.docker
1050
+++ b/tests/docker/dockerfiles/debian-amd64.docker
1051
@@ -XXX,XX +XXX,XX @@ RUN export DEBIAN_FRONTEND=noninteractive && \
1052
libvirglrenderer-dev \
1053
libvte-2.91-dev \
1054
libxen-dev \
1055
+ libxdp-dev \
1056
libzstd-dev \
1057
llvm \
1058
locales \
125
--
1059
--
126
2.7.4
1060
2.7.4
127
128
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
We add the vnet_hdr_support option for colo-compare, default is disabled.
3
Changed eBPF map updates through mmaped array.
4
If you use virtio-net-pci or other driver needs vnet_hdr, please enable it.
4
Mmaped arrays provide direct access to map data.
5
You can use it for example:
5
It should omit using bpf_map_update_elem() call,
6
-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,vnet_hdr_support
6
which may require capabilities that are not present.
7
7
8
COLO-compare can get vnet header length from filter,
8
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
9
Add vnet_hdr_len to struct packet and output packet with
10
the vnet_hdr_len.
11
12
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
10
---
15
net/colo-compare.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------
11
ebpf/ebpf_rss.c | 117 +++++++++++++++++++++++++++++++++++++++++++++-----------
16
qemu-options.hx | 4 ++--
12
ebpf/ebpf_rss.h | 5 +++
17
2 files changed, 55 insertions(+), 9 deletions(-)
13
2 files changed, 99 insertions(+), 23 deletions(-)
18
14
19
diff --git a/net/colo-compare.c b/net/colo-compare.c
15
diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/net/colo-compare.c
17
--- a/ebpf/ebpf_rss.c
22
+++ b/net/colo-compare.c
18
+++ b/ebpf/ebpf_rss.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
19
@@ -XXX,XX +XXX,XX @@ void ebpf_rss_init(struct EBPFRSSContext *ctx)
24
CharBackend chr_out;
20
{
25
SocketReadState pri_rs;
21
if (ctx != NULL) {
26
SocketReadState sec_rs;
22
ctx->obj = NULL;
27
+ bool vnet_hdr;
23
+ ctx->program_fd = -1;
28
24
+ ctx->map_configuration = -1;
29
/* connection list: the connections belonged to this NIC could be found
25
+ ctx->map_toeplitz_key = -1;
30
* in this list.
26
+ ctx->map_indirections_table = -1;
31
@@ -XXX,XX +XXX,XX @@ enum {
27
+
32
28
+ ctx->mmap_configuration = NULL;
33
static int compare_chr_send(CompareState *s,
29
+ ctx->mmap_toeplitz_key = NULL;
34
const uint8_t *buf,
30
+ ctx->mmap_indirections_table = NULL;
35
- uint32_t size);
31
}
36
+ uint32_t size,
32
}
37
+ uint32_t vnet_hdr_len);
33
38
34
bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx)
39
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
35
{
40
{
36
- return ctx != NULL && ctx->obj != NULL;
41
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
37
+ return ctx != NULL && (ctx->obj != NULL || ctx->program_fd != -1);
42
}
38
+}
43
39
+
44
if (result) {
40
+static bool ebpf_rss_mmap(struct EBPFRSSContext *ctx)
45
- ret = compare_chr_send(s, pkt->data, pkt->size);
46
+ ret = compare_chr_send(s,
47
+ pkt->data,
48
+ pkt->size,
49
+ pkt->vnet_hdr_len);
50
if (ret < 0) {
51
error_report("colo_send_primary_packet failed");
52
}
53
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
54
55
static int compare_chr_send(CompareState *s,
56
const uint8_t *buf,
57
- uint32_t size)
58
+ uint32_t size,
59
+ uint32_t vnet_hdr_len)
60
{
61
int ret = 0;
62
uint32_t len = htonl(size);
63
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
64
goto err;
65
}
66
67
+ if (s->vnet_hdr) {
68
+ /*
69
+ * We send vnet header len make other module(like filter-redirector)
70
+ * know how to parse net packet correctly.
71
+ */
72
+ len = htonl(vnet_hdr_len);
73
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
74
+ if (ret != sizeof(len)) {
75
+ goto err;
76
+ }
77
+ }
78
+
79
ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
80
if (ret != size) {
81
goto err;
82
@@ -XXX,XX +XXX,XX @@ static void compare_set_outdev(Object *obj, const char *value, Error **errp)
83
s->outdev = g_strdup(value);
84
}
85
86
+static bool compare_get_vnet_hdr(Object *obj, Error **errp)
87
+{
41
+{
88
+ CompareState *s = COLO_COMPARE(obj);
42
+ if (!ebpf_rss_is_loaded(ctx)) {
89
+
43
+ return false;
90
+ return s->vnet_hdr;
44
+ }
45
+
46
+ ctx->mmap_configuration = mmap(NULL, qemu_real_host_page_size(),
47
+ PROT_READ | PROT_WRITE, MAP_SHARED,
48
+ ctx->map_configuration, 0);
49
+ if (ctx->mmap_configuration == MAP_FAILED) {
50
+ trace_ebpf_error("eBPF RSS", "can not mmap eBPF configuration array");
51
+ return false;
52
+ }
53
+ ctx->mmap_toeplitz_key = mmap(NULL, qemu_real_host_page_size(),
54
+ PROT_READ | PROT_WRITE, MAP_SHARED,
55
+ ctx->map_toeplitz_key, 0);
56
+ if (ctx->mmap_toeplitz_key == MAP_FAILED) {
57
+ trace_ebpf_error("eBPF RSS", "can not mmap eBPF toeplitz key");
58
+ goto toeplitz_fail;
59
+ }
60
+ ctx->mmap_indirections_table = mmap(NULL, qemu_real_host_page_size(),
61
+ PROT_READ | PROT_WRITE, MAP_SHARED,
62
+ ctx->map_indirections_table, 0);
63
+ if (ctx->mmap_indirections_table == MAP_FAILED) {
64
+ trace_ebpf_error("eBPF RSS", "can not mmap eBPF indirection table");
65
+ goto indirection_fail;
66
+ }
67
+
68
+ return true;
69
+
70
+indirection_fail:
71
+ munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
72
+toeplitz_fail:
73
+ munmap(ctx->mmap_configuration, qemu_real_host_page_size());
74
+
75
+ ctx->mmap_configuration = NULL;
76
+ ctx->mmap_toeplitz_key = NULL;
77
+ ctx->mmap_indirections_table = NULL;
78
+ return false;
91
+}
79
+}
92
+
80
+
93
+static void compare_set_vnet_hdr(Object *obj,
81
+static void ebpf_rss_munmap(struct EBPFRSSContext *ctx)
94
+ bool value,
95
+ Error **errp)
96
+{
82
+{
97
+ CompareState *s = COLO_COMPARE(obj);
83
+ if (!ebpf_rss_is_loaded(ctx)) {
98
+
84
+ return;
99
+ s->vnet_hdr = value;
85
+ }
100
+}
86
+
101
+
87
+ munmap(ctx->mmap_indirections_table, qemu_real_host_page_size());
102
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
88
+ munmap(ctx->mmap_toeplitz_key, qemu_real_host_page_size());
103
{
89
+ munmap(ctx->mmap_configuration, qemu_real_host_page_size());
104
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
90
+
105
91
+ ctx->mmap_configuration = NULL;
106
if (packet_enqueue(s, PRIMARY_IN)) {
92
+ ctx->mmap_toeplitz_key = NULL;
107
trace_colo_compare_main("primary: unsupported packet in");
93
+ ctx->mmap_indirections_table = NULL;
108
- compare_chr_send(s, pri_rs->buf, pri_rs->packet_len);
94
}
109
+ compare_chr_send(s,
95
110
+ pri_rs->buf,
96
bool ebpf_rss_load(struct EBPFRSSContext *ctx)
111
+ pri_rs->packet_len,
97
{
112
+ pri_rs->vnet_hdr_len);
98
struct rss_bpf *rss_bpf_ctx;
113
} else {
99
114
/* compare connection */
100
- if (ctx == NULL) {
115
g_queue_foreach(&s->conn_list, colo_compare_connection, s);
101
+ if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
116
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
102
return false;
103
}
104
105
@@ -XXX,XX +XXX,XX @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
106
ctx->map_toeplitz_key = bpf_map__fd(
107
rss_bpf_ctx->maps.tap_rss_map_toeplitz_key);
108
109
+ if (!ebpf_rss_mmap(ctx)) {
110
+ goto error;
111
+ }
112
+
113
return true;
114
error:
115
rss_bpf__destroy(rss_bpf_ctx);
116
ctx->obj = NULL;
117
+ ctx->program_fd = -1;
118
+ ctx->map_configuration = -1;
119
+ ctx->map_toeplitz_key = -1;
120
+ ctx->map_indirections_table = -1;
121
122
return false;
123
}
124
@@ -XXX,XX +XXX,XX @@ error:
125
static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
126
struct EBPFRSSConfig *config)
127
{
128
- uint32_t map_key = 0;
129
-
130
if (!ebpf_rss_is_loaded(ctx)) {
131
return false;
132
}
133
- if (bpf_map_update_elem(ctx->map_configuration,
134
- &map_key, config, 0) < 0) {
135
- return false;
136
- }
137
+
138
+ memcpy(ctx->mmap_configuration, config, sizeof(*config));
139
return true;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool ebpf_rss_set_indirections_table(struct EBPFRSSContext *ctx,
143
uint16_t *indirections_table,
144
size_t len)
145
{
146
- uint32_t i = 0;
147
-
148
if (!ebpf_rss_is_loaded(ctx) || indirections_table == NULL ||
149
len > VIRTIO_NET_RSS_MAX_TABLE_LEN) {
150
return false;
151
}
152
153
- for (; i < len; ++i) {
154
- if (bpf_map_update_elem(ctx->map_indirections_table, &i,
155
- indirections_table + i, 0) < 0) {
156
- return false;
157
- }
158
- }
159
+ memcpy(ctx->mmap_indirections_table, indirections_table,
160
+ sizeof(*indirections_table) * len);
161
return true;
162
}
163
164
static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
165
uint8_t *toeplitz_key)
166
{
167
- uint32_t map_key = 0;
168
-
169
/* prepare toeplitz key */
170
uint8_t toe[VIRTIO_NET_RSS_MAX_KEY_SIZE] = {};
171
172
@@ -XXX,XX +XXX,XX @@ static bool ebpf_rss_set_toepliz_key(struct EBPFRSSContext *ctx,
173
memcpy(toe, toeplitz_key, VIRTIO_NET_RSS_MAX_KEY_SIZE);
174
*(uint32_t *)toe = ntohl(*(uint32_t *)toe);
175
176
- if (bpf_map_update_elem(ctx->map_toeplitz_key, &map_key, toe,
177
- 0) < 0) {
178
- return false;
179
- }
180
+ memcpy(ctx->mmap_toeplitz_key, toe, VIRTIO_NET_RSS_MAX_KEY_SIZE);
181
return true;
182
}
183
184
@@ -XXX,XX +XXX,XX @@ void ebpf_rss_unload(struct EBPFRSSContext *ctx)
117
return;
185
return;
118
}
186
}
119
187
120
- net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, false);
188
- rss_bpf__destroy(ctx->obj);
121
- net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, false);
189
+ ebpf_rss_munmap(ctx);
122
+ net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
190
+
123
+ net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
191
+ if (ctx->obj) {
124
192
+ rss_bpf__destroy(ctx->obj);
125
g_queue_init(&s->conn_list);
193
+ } else {
126
194
+ close(ctx->program_fd);
127
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
195
+ close(ctx->map_configuration);
128
196
+ close(ctx->map_toeplitz_key);
129
while (!g_queue_is_empty(&conn->primary_list)) {
197
+ close(ctx->map_indirections_table);
130
pkt = g_queue_pop_head(&conn->primary_list);
198
+ }
131
- compare_chr_send(s, pkt->data, pkt->size);
199
+
132
+ compare_chr_send(s,
200
ctx->obj = NULL;
133
+ pkt->data,
201
+ ctx->program_fd = -1;
134
+ pkt->size,
202
+ ctx->map_configuration = -1;
135
+ pkt->vnet_hdr_len);
203
+ ctx->map_toeplitz_key = -1;
136
packet_destroy(pkt, NULL);
204
+ ctx->map_indirections_table = -1;
137
}
205
}
138
while (!g_queue_is_empty(&conn->secondary_list)) {
206
diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
139
@@ -XXX,XX +XXX,XX @@ static void colo_compare_class_init(ObjectClass *oc, void *data)
140
141
static void colo_compare_init(Object *obj)
142
{
143
+ CompareState *s = COLO_COMPARE(obj);
144
+
145
object_property_add_str(obj, "primary_in",
146
compare_get_pri_indev, compare_set_pri_indev,
147
NULL);
148
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
149
object_property_add_str(obj, "outdev",
150
compare_get_outdev, compare_set_outdev,
151
NULL);
152
+
153
+ s->vnet_hdr = false;
154
+ object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
155
+ compare_set_vnet_hdr, NULL);
156
}
157
158
static void colo_compare_finalize(Object *obj)
159
diff --git a/qemu-options.hx b/qemu-options.hx
160
index XXXXXXX..XXXXXXX 100644
207
index XXXXXXX..XXXXXXX 100644
161
--- a/qemu-options.hx
208
--- a/ebpf/ebpf_rss.h
162
+++ b/qemu-options.hx
209
+++ b/ebpf/ebpf_rss.h
163
@@ -XXX,XX +XXX,XX @@ Dump the network traffic on netdev @var{dev} to the file specified by
210
@@ -XXX,XX +XXX,XX @@ struct EBPFRSSContext {
164
The file format is libpcap, so it can be analyzed with tools such as tcpdump
211
int map_configuration;
165
or Wireshark.
212
int map_toeplitz_key;
166
213
int map_indirections_table;
167
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},
214
+
168
-outdev=@var{chardevid}
215
+ /* mapped eBPF maps for direct access to omit bpf_map_update_elem() */
169
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid}[,vnet_hdr_support]
216
+ void *mmap_configuration;
170
217
+ void *mmap_toeplitz_key;
171
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
218
+ void *mmap_indirections_table;
172
secondary packet. If the packets are same, we will output primary
219
};
173
packet to outdev@var{chardevid}, else we will notify colo-frame
220
174
do checkpoint and send primary packet to outdev@var{chardevid}.
221
struct EBPFRSSConfig {
175
+if it has the vnet_hdr_support flag, colo compare will send/recv packet with vnet_hdr_len.
176
177
we must use it with the help of filter-mirror and filter-redirector.
178
179
--
222
--
180
2.7.4
223
2.7.4
181
182
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
We add the vnet_hdr_support option for filter-redirector, default is disabled.
3
It allows using file descriptors of eBPF provided
4
If you use virtio-net-pci net driver or other driver needs vnet_hdr, please enable it.
4
outside of QEMU.
5
Because colo-compare or other modules needs the vnet_hdr_len to parse
5
QEMU may be run without capabilities for eBPF and run
6
packet, we add this new option send the len to others.
6
RSS program provided by management tool(g.e. libvirt).
7
You can use it for example:
8
-object filter-redirector,id=r0,netdev=hn0,queue=tx,outdev=red0,vnet_hdr_support
9
7
10
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
8
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
12
---
10
---
13
net/filter-mirror.c | 23 +++++++++++++++++++++++
11
ebpf/ebpf_rss-stub.c | 6 ++++++
14
qemu-options.hx | 6 +++---
12
ebpf/ebpf_rss.c | 27 +++++++++++++++++++++++++++
15
2 files changed, 26 insertions(+), 3 deletions(-)
13
ebpf/ebpf_rss.h | 5 +++++
14
3 files changed, 38 insertions(+)
16
15
17
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
16
diff --git a/ebpf/ebpf_rss-stub.c b/ebpf/ebpf_rss-stub.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/net/filter-mirror.c
18
--- a/ebpf/ebpf_rss-stub.c
20
+++ b/net/filter-mirror.c
19
+++ b/ebpf/ebpf_rss-stub.c
21
@@ -XXX,XX +XXX,XX @@ static void filter_redirector_set_outdev(Object *obj,
20
@@ -XXX,XX +XXX,XX @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
22
s->outdev = g_strdup(value);
21
return false;
23
}
22
}
24
23
25
+static bool filter_redirector_get_vnet_hdr(Object *obj, Error **errp)
24
+bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
25
+ int config_fd, int toeplitz_fd, int table_fd)
26
+{
26
+{
27
+ MirrorState *s = FILTER_REDIRECTOR(obj);
27
+ return false;
28
+
29
+ return s->vnet_hdr;
30
+}
28
+}
31
+
29
+
32
+static void filter_redirector_set_vnet_hdr(Object *obj,
30
bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
33
+ bool value,
31
uint16_t *indirections_table, uint8_t *toeplitz_key)
34
+ Error **errp)
32
{
33
diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/ebpf/ebpf_rss.c
36
+++ b/ebpf/ebpf_rss.c
37
@@ -XXX,XX +XXX,XX @@ error:
38
return false;
39
}
40
41
+bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
42
+ int config_fd, int toeplitz_fd, int table_fd)
35
+{
43
+{
36
+ MirrorState *s = FILTER_REDIRECTOR(obj);
44
+ if (ctx == NULL || ebpf_rss_is_loaded(ctx)) {
45
+ return false;
46
+ }
37
+
47
+
38
+ s->vnet_hdr = value;
48
+ if (program_fd < 0 || config_fd < 0 || toeplitz_fd < 0 || table_fd < 0) {
49
+ return false;
50
+ }
51
+
52
+ ctx->program_fd = program_fd;
53
+ ctx->map_configuration = config_fd;
54
+ ctx->map_toeplitz_key = toeplitz_fd;
55
+ ctx->map_indirections_table = table_fd;
56
+
57
+ if (!ebpf_rss_mmap(ctx)) {
58
+ ctx->program_fd = -1;
59
+ ctx->map_configuration = -1;
60
+ ctx->map_toeplitz_key = -1;
61
+ ctx->map_indirections_table = -1;
62
+ return false;
63
+ }
64
+
65
+ return true;
39
+}
66
+}
40
+
67
+
41
static void filter_mirror_init(Object *obj)
68
static bool ebpf_rss_set_config(struct EBPFRSSContext *ctx,
69
struct EBPFRSSConfig *config)
42
{
70
{
43
MirrorState *s = FILTER_MIRROR(obj);
71
diff --git a/ebpf/ebpf_rss.h b/ebpf/ebpf_rss.h
44
@@ -XXX,XX +XXX,XX @@ static void filter_mirror_init(Object *obj)
72
index XXXXXXX..XXXXXXX 100644
45
73
--- a/ebpf/ebpf_rss.h
46
static void filter_redirector_init(Object *obj)
74
+++ b/ebpf/ebpf_rss.h
47
{
75
@@ -XXX,XX +XXX,XX @@
48
+ MirrorState *s = FILTER_REDIRECTOR(obj);
76
#ifndef QEMU_EBPF_RSS_H
77
#define QEMU_EBPF_RSS_H
78
79
+#define EBPF_RSS_MAX_FDS 4
49
+
80
+
50
object_property_add_str(obj, "indev", filter_redirector_get_indev,
81
struct EBPFRSSContext {
51
filter_redirector_set_indev, NULL);
82
void *obj;
52
object_property_add_str(obj, "outdev", filter_redirector_get_outdev,
83
int program_fd;
53
filter_redirector_set_outdev, NULL);
84
@@ -XXX,XX +XXX,XX @@ bool ebpf_rss_is_loaded(struct EBPFRSSContext *ctx);
85
86
bool ebpf_rss_load(struct EBPFRSSContext *ctx);
87
88
+bool ebpf_rss_load_fds(struct EBPFRSSContext *ctx, int program_fd,
89
+ int config_fd, int toeplitz_fd, int table_fd);
54
+
90
+
55
+ s->vnet_hdr = false;
91
bool ebpf_rss_set_all(struct EBPFRSSContext *ctx, struct EBPFRSSConfig *config,
56
+ object_property_add_bool(obj, "vnet_hdr_support",
92
uint16_t *indirections_table, uint8_t *toeplitz_key);
57
+ filter_redirector_get_vnet_hdr,
93
58
+ filter_redirector_set_vnet_hdr, NULL);
59
}
60
61
static void filter_mirror_fini(Object *obj)
62
diff --git a/qemu-options.hx b/qemu-options.hx
63
index XXXXXXX..XXXXXXX 100644
64
--- a/qemu-options.hx
65
+++ b/qemu-options.hx
66
@@ -XXX,XX +XXX,XX @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter.
67
68
filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len.
69
70
-@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},
71
-outdev=@var{chardevid}[,queue=@var{all|rx|tx}]
72
+@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support]
73
74
filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev
75
-@var{chardevid},and redirect indev's packet to filter.
76
+@var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag,
77
+filter-redirector will redirect packet with vnet_hdr_len.
78
Create a filter-redirector we need to differ outdev id from indev id, id can not
79
be the same. we can just use indev or outdev, but at least one of indev or outdev
80
need to be specified.
81
--
94
--
82
2.7.4
95
2.7.4
83
84
diff view generated by jsdifflib
1
From: Michal Privoznik <mprivozn@redhat.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
We have a function that checks if given number is power of two.
3
eBPF RSS program and maps may now be passed during initialization.
4
We should prefer it instead of expanding the check on our own.
4
Initially was implemented for libvirt to launch qemu without permissions,
5
and initialized eBPF program through the helper.
5
6
6
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
7
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
---
9
hw/net/virtio-net.c | 2 +-
10
hw/net/virtio-net.c | 55 +++++++++++++++++++++++++++++++++++++-----
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
include/hw/virtio/virtio-net.h | 1 +
12
2 files changed, 50 insertions(+), 6 deletions(-)
11
13
12
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
14
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/net/virtio-net.c
16
--- a/hw/net/virtio-net.c
15
+++ b/hw/net/virtio-net.c
17
+++ b/hw/net/virtio-net.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "sysemu/sysemu.h"
20
#include "trace.h"
21
#include "monitor/qdev.h"
22
+#include "monitor/monitor.h"
23
#include "hw/pci/pci_device.h"
24
#include "net_rx_pkt.h"
25
#include "hw/virtio/vhost.h"
26
@@ -XXX,XX +XXX,XX @@ static void virtio_net_detach_epbf_rss(VirtIONet *n)
27
virtio_net_attach_ebpf_to_backend(n->nic, -1);
28
}
29
30
-static bool virtio_net_load_ebpf(VirtIONet *n)
31
+static bool virtio_net_load_ebpf_fds(VirtIONet *n, Error **errp)
32
{
33
- if (!virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
34
- /* backend does't support steering ebpf */
35
- return false;
36
+ int fds[EBPF_RSS_MAX_FDS] = { [0 ... EBPF_RSS_MAX_FDS - 1] = -1};
37
+ int nfds = 0;
38
+ int ret = true;
39
+ int i = 0;
40
+ g_auto(GStrv) fds_strs = g_strsplit(n->ebpf_rss_fds, ":", 0);
41
+
42
+ ERRP_GUARD();
43
+
44
+ if (g_strv_length(fds_strs) != EBPF_RSS_MAX_FDS) {
45
+ error_setg(errp,
46
+ "Expected %d file descriptors but got %d",
47
+ EBPF_RSS_MAX_FDS, g_strv_length(fds_strs));
48
+ return false;
49
+ }
50
+
51
+ for (i = 0; i < nfds; i++) {
52
+ fds[i] = monitor_fd_param(monitor_cur(), fds_strs[i], errp);
53
+ if (*errp) {
54
+ ret = false;
55
+ goto exit;
56
+ }
57
+ }
58
+
59
+ ret = ebpf_rss_load_fds(&n->ebpf_rss, fds[0], fds[1], fds[2], fds[3]);
60
+
61
+exit:
62
+ if (!ret || *errp) {
63
+ for (i = 0; i < nfds && fds[i] != -1; i++) {
64
+ close(fds[i]);
65
+ }
66
}
67
68
- return ebpf_rss_load(&n->ebpf_rss);
69
+ return ret;
70
+}
71
+
72
+static bool virtio_net_load_ebpf(VirtIONet *n, Error **errp)
73
+{
74
+ bool ret = false;
75
+
76
+ if (virtio_net_attach_ebpf_to_backend(n->nic, -1)) {
77
+ if (!(n->ebpf_rss_fds
78
+ && virtio_net_load_ebpf_fds(n, errp))) {
79
+ ret = ebpf_rss_load(&n->ebpf_rss);
80
+ }
81
+ }
82
+
83
+ return ret;
84
}
85
86
static void virtio_net_unload_ebpf(VirtIONet *n)
16
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
87
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
17
*/
88
net_rx_pkt_init(&n->rx_pkt);
18
if (n->net_conf.rx_queue_size < VIRTIO_NET_RX_QUEUE_MIN_SIZE ||
89
19
n->net_conf.rx_queue_size > VIRTQUEUE_MAX_SIZE ||
90
if (virtio_has_feature(n->host_features, VIRTIO_NET_F_RSS)) {
20
- (n->net_conf.rx_queue_size & (n->net_conf.rx_queue_size - 1))) {
91
- virtio_net_load_ebpf(n);
21
+ !is_power_of_2(n->net_conf.rx_queue_size)) {
92
+ virtio_net_load_ebpf(n, errp);
22
error_setg(errp, "Invalid rx_queue_size (= %" PRIu16 "), "
93
}
23
"must be a power of 2 between %d and %d.",
94
}
24
n->net_conf.rx_queue_size, VIRTIO_NET_RX_QUEUE_MIN_SIZE,
95
96
@@ -XXX,XX +XXX,XX @@ static Property virtio_net_properties[] = {
97
VIRTIO_NET_F_RSS, false),
98
DEFINE_PROP_BIT64("hash", VirtIONet, host_features,
99
VIRTIO_NET_F_HASH_REPORT, false),
100
+ DEFINE_PROP_STRING("ebpf_rss_fds", VirtIONet, ebpf_rss_fds),
101
DEFINE_PROP_BIT64("guest_rsc_ext", VirtIONet, host_features,
102
VIRTIO_NET_F_RSC_EXT, false),
103
DEFINE_PROP_UINT32("rsc_interval", VirtIONet, rsc_timeout,
104
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
105
index XXXXXXX..XXXXXXX 100644
106
--- a/include/hw/virtio/virtio-net.h
107
+++ b/include/hw/virtio/virtio-net.h
108
@@ -XXX,XX +XXX,XX @@ struct VirtIONet {
109
VirtioNetRssData rss_data;
110
struct NetRxPkt *rx_pkt;
111
struct EBPFRSSContext ebpf_rss;
112
+ char *ebpf_rss_fds;
113
};
114
115
size_t virtio_net_handle_ctrl_iov(VirtIODevice *vdev,
25
--
116
--
26
2.7.4
117
2.7.4
27
28
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
Make colo-compare and filter-rewriter can parse vnet packet.
3
Now, the binary objects may be retrieved by id.
4
4
It would require for future qmp commands that may require specific
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
5
eBPF blob.
6
7
Added command "request-ebpf". This command returns
8
eBPF program encoded base64. The program taken from the
9
skeleton and essentially is an ELF object that can be
10
loaded in the future with libbpf.
11
12
The reason to use the command to provide the eBPF object
13
instead of a separate artifact was to avoid issues related
14
to finding the eBPF itself. eBPF object is an ELF binary
15
that contains the eBPF program and eBPF map description(BTF).
16
Overall, eBPF object should contain the program and enough
17
metadata to create/load eBPF with libbpf. As the eBPF
18
maps/program should correspond to QEMU, the eBPF can't
19
be used from different QEMU build.
20
21
The first solution was a helper that comes with QEMU
22
and loads appropriate eBPF objects. And the issue is
23
to find a proper helper if the system has several
24
different QEMUs installed and/or built from the source,
25
which helpers may not be compatible.
26
27
Another issue is QEMU updating while there is a running
28
QEMU instance. With an updated helper, it may not be
29
possible to hotplug virtio-net device to the already
30
running QEMU. Overall, requesting the eBPF object from
31
QEMU itself solves possible failures with acceptable effort.
32
33
Links:
34
[PATCH 3/5] qmp: Added the helper stamp check.
35
https://lore.kernel.org/all/20230219162100.174318-4-andrew@daynix.com/
36
37
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
38
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
39
---
8
net/colo.c | 6 +++---
40
ebpf/ebpf.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 3 insertions(+), 3 deletions(-)
41
ebpf/ebpf.h | 31 +++++++++++++++++++++++
10
42
ebpf/ebpf_rss.c | 6 +++++
11
diff --git a/net/colo.c b/net/colo.c
43
ebpf/meson.build | 2 +-
12
index XXXXXXX..XXXXXXX 100644
44
qapi/ebpf.json | 66 ++++++++++++++++++++++++++++++++++++++++++++++++
13
--- a/net/colo.c
45
qapi/meson.build | 1 +
14
+++ b/net/colo.c
46
qapi/qapi-schema.json | 1 +
15
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
47
7 files changed, 176 insertions(+), 1 deletion(-)
16
{
48
create mode 100644 ebpf/ebpf.c
17
int network_length;
49
create mode 100644 ebpf/ebpf.h
18
static const uint8_t vlan[] = {0x81, 0x00};
50
create mode 100644 qapi/ebpf.json
19
- uint8_t *data = pkt->data;
51
20
+ uint8_t *data = pkt->data + pkt->vnet_hdr_len;
52
diff --git a/ebpf/ebpf.c b/ebpf/ebpf.c
21
uint16_t l3_proto;
53
new file mode 100644
22
ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
54
index XXXXXXX..XXXXXXX
23
55
--- /dev/null
24
- if (pkt->size < ETH_HLEN) {
56
+++ b/ebpf/ebpf.c
25
+ if (pkt->size < ETH_HLEN + pkt->vnet_hdr_len) {
57
@@ -XXX,XX +XXX,XX @@
26
trace_colo_proxy_main("pkt->size < ETH_HLEN");
58
+/*
27
return 1;
59
+ * QEMU eBPF binary declaration routine.
28
}
60
+ *
29
@@ -XXX,XX +XXX,XX @@ int parse_packet_early(Packet *pkt)
61
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
30
}
62
+ *
31
63
+ * Authors:
32
network_length = pkt->ip->ip_hl * 4;
64
+ * Andrew Melnychenko <andrew@daynix.com>
33
- if (pkt->size < l2hdr_len + network_length) {
65
+ *
34
+ if (pkt->size < l2hdr_len + network_length + pkt->vnet_hdr_len) {
66
+ * This work is licensed under the terms of the GNU GPL, version 2 or
35
trace_colo_proxy_main("pkt->size < network_header + network_length");
67
+ * later. See the COPYING file in the top-level directory.
36
return 1;
68
+ */
37
}
69
+
70
+#include "qemu/osdep.h"
71
+#include "qemu/queue.h"
72
+#include "qapi/error.h"
73
+#include "qapi/qapi-commands-ebpf.h"
74
+#include "ebpf/ebpf.h"
75
+
76
+struct ElfBinaryDataEntry {
77
+ int id;
78
+ const void *data;
79
+ size_t datalen;
80
+
81
+ QSLIST_ENTRY(ElfBinaryDataEntry) node;
82
+};
83
+
84
+static QSLIST_HEAD(, ElfBinaryDataEntry) ebpf_elf_obj_list =
85
+ QSLIST_HEAD_INITIALIZER();
86
+
87
+void ebpf_register_binary_data(int id, const void *data, size_t datalen)
88
+{
89
+ struct ElfBinaryDataEntry *dataentry = NULL;
90
+
91
+ dataentry = g_new0(struct ElfBinaryDataEntry, 1);
92
+ dataentry->data = data;
93
+ dataentry->datalen = datalen;
94
+ dataentry->id = id;
95
+
96
+ QSLIST_INSERT_HEAD(&ebpf_elf_obj_list, dataentry, node);
97
+}
98
+
99
+const void *ebpf_find_binary_by_id(int id, size_t *sz, Error **errp)
100
+{
101
+ struct ElfBinaryDataEntry *it = NULL;
102
+ QSLIST_FOREACH(it, &ebpf_elf_obj_list, node) {
103
+ if (id == it->id) {
104
+ *sz = it->datalen;
105
+ return it->data;
106
+ }
107
+ }
108
+
109
+ error_setg(errp, "can't find eBPF object with id: %d", id);
110
+
111
+ return NULL;
112
+}
113
+
114
+EbpfObject *qmp_request_ebpf(EbpfProgramID id, Error **errp)
115
+{
116
+ EbpfObject *ret = NULL;
117
+ size_t size = 0;
118
+ const void *data = ebpf_find_binary_by_id(id, &size, errp);
119
+ if (!data) {
120
+ return NULL;
121
+ }
122
+
123
+ ret = g_new0(EbpfObject, 1);
124
+ ret->object = g_base64_encode(data, size);
125
+
126
+ return ret;
127
+}
128
diff --git a/ebpf/ebpf.h b/ebpf/ebpf.h
129
new file mode 100644
130
index XXXXXXX..XXXXXXX
131
--- /dev/null
132
+++ b/ebpf/ebpf.h
133
@@ -XXX,XX +XXX,XX @@
134
+/*
135
+ * QEMU eBPF binary declaration routine.
136
+ *
137
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
138
+ *
139
+ * Authors:
140
+ * Andrew Melnychenko <andrew@daynix.com>
141
+ *
142
+ * This work is licensed under the terms of the GNU GPL, version 2 or
143
+ * later. See the COPYING file in the top-level directory.
144
+ */
145
+
146
+#ifndef EBPF_H
147
+#define EBPF_H
148
+
149
+struct Error;
150
+
151
+void ebpf_register_binary_data(int id, const void *data,
152
+ size_t datalen);
153
+const void *ebpf_find_binary_by_id(int id, size_t *sz,
154
+ struct Error **errp);
155
+
156
+#define ebpf_binary_init(id, fn) \
157
+static void __attribute__((constructor)) ebpf_binary_init_ ## fn(void) \
158
+{ \
159
+ size_t datalen = 0; \
160
+ const void *data = fn(&datalen); \
161
+ ebpf_register_binary_data(id, data, datalen); \
162
+}
163
+
164
+#endif /* EBPF_H */
165
diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/ebpf/ebpf_rss.c
168
+++ b/ebpf/ebpf_rss.c
169
@@ -XXX,XX +XXX,XX @@
170
171
#include "qemu/osdep.h"
172
#include "qemu/error-report.h"
173
+#include "qapi/qapi-types-misc.h"
174
+#include "qapi/qapi-commands-ebpf.h"
175
176
#include <bpf/libbpf.h>
177
#include <bpf/bpf.h>
178
@@ -XXX,XX +XXX,XX @@
179
180
#include "ebpf/ebpf_rss.h"
181
#include "ebpf/rss.bpf.skeleton.h"
182
+#include "ebpf/ebpf.h"
183
+
184
#include "trace.h"
185
186
void ebpf_rss_init(struct EBPFRSSContext *ctx)
187
@@ -XXX,XX +XXX,XX @@ void ebpf_rss_unload(struct EBPFRSSContext *ctx)
188
ctx->map_toeplitz_key = -1;
189
ctx->map_indirections_table = -1;
190
}
191
+
192
+ebpf_binary_init(EBPF_PROGRAMID_RSS, rss_bpf__elf_bytes)
193
diff --git a/ebpf/meson.build b/ebpf/meson.build
194
index XXXXXXX..XXXXXXX 100644
195
--- a/ebpf/meson.build
196
+++ b/ebpf/meson.build
197
@@ -1 +1 @@
198
-system_ss.add(when: libbpf, if_true: files('ebpf_rss.c'), if_false: files('ebpf_rss-stub.c'))
199
+common_ss.add(when: libbpf, if_true: files('ebpf.c', 'ebpf_rss.c'), if_false: files('ebpf_rss-stub.c'))
200
diff --git a/qapi/ebpf.json b/qapi/ebpf.json
201
new file mode 100644
202
index XXXXXXX..XXXXXXX
203
--- /dev/null
204
+++ b/qapi/ebpf.json
205
@@ -XXX,XX +XXX,XX @@
206
+# -*- Mode: Python -*-
207
+# vim: filetype=python
208
+#
209
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
210
+# See the COPYING file in the top-level directory.
211
+
212
+##
213
+# = eBPF Objects
214
+#
215
+# eBPF object is an ELF binary that contains the eBPF
216
+# program and eBPF map description(BTF). Overall, eBPF
217
+# object should contain the program and enough metadata
218
+# to create/load eBPF with libbpf. As the eBPF maps/program
219
+# should correspond to QEMU, the eBPF can't be used from
220
+# different QEMU build.
221
+#
222
+# Currently, there is a possible eBPF for receive-side scaling (RSS).
223
+#
224
+##
225
+
226
+##
227
+# @EbpfObject:
228
+#
229
+# An eBPF ELF object.
230
+#
231
+# @object: the eBPF object encoded in base64
232
+#
233
+# Since: 8.2
234
+##
235
+{ 'struct': 'EbpfObject',
236
+ 'data': {'object': 'str'},
237
+ 'if': 'CONFIG_EBPF' }
238
+
239
+##
240
+# @EbpfProgramID:
241
+#
242
+# The eBPF programs that can be gotten with request-ebpf.
243
+#
244
+# @rss: Receive side scaling, technology that allows steering traffic
245
+# between queues by calculation hash. Users may set up
246
+# indirection table and hash/packet types configurations. Used
247
+# with virtio-net.
248
+#
249
+# Since: 8.2
250
+##
251
+{ 'enum': 'EbpfProgramID',
252
+ 'if': 'CONFIG_EBPF',
253
+ 'data': [ { 'name': 'rss' } ] }
254
+
255
+##
256
+# @request-ebpf:
257
+#
258
+# Retrieve an eBPF object that can be loaded with libbpf. Management
259
+# applications (g.e. libvirt) may load it and pass file descriptors to
260
+# QEMU, so they can run running QEMU without BPF capabilities.
261
+#
262
+# @id: The ID of the program to return.
263
+#
264
+# Returns: eBPF object encoded in base64.
265
+#
266
+# Since: 8.2
267
+##
268
+{ 'command': 'request-ebpf',
269
+ 'data': { 'id': 'EbpfProgramID' },
270
+ 'returns': 'EbpfObject',
271
+ 'if': 'CONFIG_EBPF' }
272
diff --git a/qapi/meson.build b/qapi/meson.build
273
index XXXXXXX..XXXXXXX 100644
274
--- a/qapi/meson.build
275
+++ b/qapi/meson.build
276
@@ -XXX,XX +XXX,XX @@ qapi_all_modules = [
277
'crypto',
278
'cxl',
279
'dump',
280
+ 'ebpf',
281
'error',
282
'introspect',
283
'job',
284
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
285
index XXXXXXX..XXXXXXX 100644
286
--- a/qapi/qapi-schema.json
287
+++ b/qapi/qapi-schema.json
288
@@ -XXX,XX +XXX,XX @@
289
{ 'include': 'char.json' }
290
{ 'include': 'dump.json' }
291
{ 'include': 'net.json' }
292
+{ 'include': 'ebpf.json' }
293
{ 'include': 'rdma.json' }
294
{ 'include': 'rocker.json' }
295
{ 'include': 'tpm.json' }
38
--
296
--
39
2.7.4
297
2.7.4
40
41
diff view generated by jsdifflib
1
From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
1
From: Andrew Melnychenko <andrew@daynix.com>
2
2
3
We can use this property flush and send packet with vnet_hdr_len.
3
Updated section name, so libbpf should init/gues proper
4
program type without specifications during open/load.
5
Also, added map_flags with explicitly declared BPF_F_MMAPABLE.
6
Added check for BPF_F_MMAPABLE flag to meson script and
7
requirements to libbpf version.
4
8
5
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
9
Signed-off-by: Andrew Melnychenko <andrew@daynix.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
11
---
8
net/colo-compare.c | 8 ++++++--
12
ebpf/rss.bpf.skeleton.h | 1460 ++++++++++++++++++++++++-----------------------
9
net/colo.c | 3 ++-
13
meson.build | 10 +-
10
net/colo.h | 4 +++-
14
tools/ebpf/rss.bpf.c | 5 +-
11
net/filter-rewriter.c | 2 +-
15
3 files changed, 748 insertions(+), 727 deletions(-)
12
4 files changed, 12 insertions(+), 5 deletions(-)
13
16
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
17
diff --git a/ebpf/rss.bpf.skeleton.h b/ebpf/rss.bpf.skeleton.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
19
--- a/ebpf/rss.bpf.skeleton.h
17
+++ b/net/colo-compare.c
20
+++ b/ebpf/rss.bpf.skeleton.h
18
@@ -XXX,XX +XXX,XX @@ static int packet_enqueue(CompareState *s, int mode)
21
@@ -XXX,XX +XXX,XX @@ err:
19
Connection *conn;
22
20
23
static inline const void *rss_bpf__elf_bytes(size_t *sz)
21
if (mode == PRIMARY_IN) {
24
{
22
- pkt = packet_new(s->pri_rs.buf, s->pri_rs.packet_len);
25
-    *sz = 20440;
23
+ pkt = packet_new(s->pri_rs.buf,
26
+    *sz = 20824;
24
+ s->pri_rs.packet_len,
27
    return (const void *)"\
25
+ s->pri_rs.vnet_hdr_len);
28
\x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\
26
} else {
29
-\0\0\0\0\0\0\0\0\0\0\0\x98\x4c\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\
27
- pkt = packet_new(s->sec_rs.buf, s->sec_rs.packet_len);
30
-\x01\0\xbf\x19\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x54\xff\0\0\0\0\xbf\xa7\
28
+ pkt = packet_new(s->sec_rs.buf,
31
-\0\0\0\0\0\0\x07\x07\0\0\x54\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
29
+ s->sec_rs.packet_len,
32
+\0\0\0\0\0\0\0\0\0\0\0\x18\x4e\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0d\0\
30
+ s->sec_rs.vnet_hdr_len);
33
+\x01\0\xbf\x19\0\0\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\x4c\xff\0\0\0\0\xbf\xa7\
31
}
34
+\0\0\0\0\0\0\x07\x07\0\0\x4c\xff\xff\xff\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
32
35
\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x06\0\0\0\0\0\0\x18\x01\0\0\0\0\0\
33
if (parse_packet_early(pkt)) {
36
\0\0\0\0\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\xbf\x08\0\0\0\0\0\0\
34
diff --git a/net/colo.c b/net/colo.c
37
-\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x67\x02\0\0\0\0\xbf\x87\0\0\
38
-\0\0\0\0\x15\x07\x65\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
39
-\0\x5e\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc8\xff\0\0\0\0\x7b\x1a\xc0\xff\
40
-\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\
41
-\0\x63\x1a\xa0\xff\0\0\0\0\x7b\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\
42
-\x1a\x88\xff\0\0\0\0\x7b\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\
43
-\x70\xff\0\0\0\0\x7b\x1a\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\
44
-\xff\0\0\0\0\x15\x09\x4d\x02\0\0\0\0\x6b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
45
-\0\x07\x03\0\0\xd0\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\
46
+\x18\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\x15\x06\x64\x02\0\0\0\0\xbf\x87\0\0\
47
+\0\0\0\0\x15\x07\x62\x02\0\0\0\0\x71\x61\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\
48
+\0\x5b\x02\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xc0\xff\0\0\0\0\x7b\x1a\xb8\xff\
49
+\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\0\x7b\x1a\xa0\xff\0\0\0\
50
+\0\x63\x1a\x98\xff\0\0\0\0\x7b\x1a\x90\xff\0\0\0\0\x7b\x1a\x88\xff\0\0\0\0\x7b\
51
+\x1a\x80\xff\0\0\0\0\x7b\x1a\x78\xff\0\0\0\0\x7b\x1a\x70\xff\0\0\0\0\x7b\x1a\
52
+\x68\xff\0\0\0\0\x7b\x1a\x60\xff\0\0\0\0\x7b\x1a\x58\xff\0\0\0\0\x7b\x1a\x50\
53
+\xff\0\0\0\0\x15\x09\x4a\x02\0\0\0\0\x6b\x1a\xc8\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\
54
+\0\x07\x03\0\0\xc8\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\
55
\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\
56
-\x77\0\0\0\x20\0\0\0\x55\0\x42\x02\0\0\0\0\xb7\x02\0\0\x10\0\0\0\x69\xa1\xd0\
57
+\x77\0\0\0\x20\0\0\0\x55\0\x3f\x02\0\0\0\0\xb7\x02\0\0\x10\0\0\0\x69\xa1\xc8\
58
\xff\0\0\0\0\xbf\x13\0\0\0\0\0\0\xdc\x03\0\0\x10\0\0\0\x15\x03\x02\0\0\x81\0\0\
59
\x55\x03\x0b\0\xa8\x88\0\0\xb7\x02\0\0\x14\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\
60
-\0\xd0\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\
61
-\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x32\x02\0\
62
-\0\0\0\x69\xa1\xd0\xff\0\0\0\0\x15\x01\x30\x02\0\0\0\0\x7b\x7a\x38\xff\0\0\0\0\
63
-\x7b\x9a\x40\xff\0\0\0\0\x15\x01\x55\0\x86\xdd\0\0\x55\x01\x39\0\x08\0\0\0\xb7\
64
-\x07\0\0\x01\0\0\0\x73\x7a\x58\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xe0\xff\
65
-\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\
66
-\x07\x03\0\0\xd0\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\xb7\x02\0\0\0\0\0\0\xb7\
67
+\0\xc8\xff\xff\xff\xbf\x91\0\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\0\0\0\
68
+\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x2f\x02\0\
69
+\0\0\0\x69\xa1\xc8\xff\0\0\0\0\x15\x01\x2d\x02\0\0\0\0\x7b\x7a\x30\xff\0\0\0\0\
70
+\x7b\x9a\x38\xff\0\0\0\0\x15\x01\x55\0\x86\xdd\0\0\x55\x01\x39\0\x08\0\0\0\xb7\
71
+\x07\0\0\x01\0\0\0\x73\x7a\x50\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xd8\xff\
72
+\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\x7b\x1a\xc8\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\
73
+\x07\x03\0\0\xc8\xff\xff\xff\x79\xa1\x38\xff\0\0\0\0\xb7\x02\0\0\0\0\0\0\xb7\
74
\x04\0\0\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\
75
-\0\x77\0\0\0\x20\0\0\0\x55\0\x1c\x02\0\0\0\0\x69\xa1\xd6\xff\0\0\0\0\x55\x01\
76
-\x01\0\0\0\0\0\xb7\x07\0\0\0\0\0\0\x61\xa1\xdc\xff\0\0\0\0\x63\x1a\x64\xff\0\0\
77
-\0\0\x61\xa1\xe0\xff\0\0\0\0\x63\x1a\x68\xff\0\0\0\0\x71\xa9\xd9\xff\0\0\0\0\
78
-\x73\x7a\x5e\xff\0\0\0\0\x71\xa1\xd0\xff\0\0\0\0\x67\x01\0\0\x02\0\0\0\x57\x01\
79
-\0\0\x3c\0\0\0\x7b\x1a\x48\xff\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\xff\0\0\
80
+\0\x77\0\0\0\x20\0\0\0\x55\0\x19\x02\0\0\0\0\x69\xa1\xce\xff\0\0\0\0\x55\x01\
81
+\x01\0\0\0\0\0\xb7\x07\0\0\0\0\0\0\x61\xa1\xd4\xff\0\0\0\0\x63\x1a\x5c\xff\0\0\
82
+\0\0\x61\xa1\xd8\xff\0\0\0\0\x63\x1a\x60\xff\0\0\0\0\x71\xa9\xd1\xff\0\0\0\0\
83
+\x73\x7a\x56\xff\0\0\0\0\x71\xa1\xc8\xff\0\0\0\0\x67\x01\0\0\x02\0\0\0\x57\x01\
84
+\0\0\x3c\0\0\0\x7b\x1a\x40\xff\0\0\0\0\xbf\x91\0\0\0\0\0\0\x57\x01\0\0\xff\0\0\
85
\0\x15\x01\x19\0\0\0\0\0\x57\x07\0\0\xff\0\0\0\x55\x07\x17\0\0\0\0\0\x57\x09\0\
86
\0\xff\0\0\0\x15\x09\x5a\x01\x11\0\0\0\x55\x09\x14\0\x06\0\0\0\xb7\x01\0\0\x01\
87
-\0\0\0\x73\x1a\x5b\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xe0\xff\0\0\0\0\x7b\
88
-\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\
89
-\xd0\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\
90
+\0\0\0\x73\x1a\x53\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xd8\xff\0\0\0\0\x7b\
91
+\x1a\xd0\xff\0\0\0\0\x7b\x1a\xc8\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\
92
+\xc8\xff\xff\xff\x79\xa1\x38\xff\0\0\0\0\x79\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\
93
\x14\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\
94
-\0\0\x20\0\0\0\x55\0\xf7\x01\0\0\0\0\x69\xa1\xd0\xff\0\0\0\0\x6b\x1a\x60\xff\0\
95
-\0\0\0\x69\xa1\xd2\xff\0\0\0\0\x6b\x1a\x62\xff\0\0\0\0\x71\xa1\x58\xff\0\0\0\0\
96
+\0\0\x20\0\0\0\x55\0\xf4\x01\0\0\0\0\x69\xa1\xc8\xff\0\0\0\0\x6b\x1a\x58\xff\0\
97
+\0\0\0\x69\xa1\xca\xff\0\0\0\0\x6b\x1a\x5a\xff\0\0\0\0\x71\xa1\x50\xff\0\0\0\0\
98
\x15\x01\xdb\0\0\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\x02\
99
\0\0\0\0\0\x4f\x12\0\0\0\0\0\0\x71\x63\x04\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\x67\
100
\x01\0\0\x08\0\0\0\x4f\x31\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\0\0\
101
-\0\x71\xa2\x5b\xff\0\0\0\0\x79\xa0\x38\xff\0\0\0\0\x15\x02\x0c\x01\0\0\0\0\xbf\
102
-\x12\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\x02\x09\x01\0\0\0\0\x61\xa1\x64\xff\
103
-\0\0\0\0\x63\x1a\xa8\xff\0\0\0\0\x61\xa1\x68\xff\0\0\0\0\x63\x1a\xac\xff\0\0\0\
104
-\0\x69\xa1\x60\xff\0\0\0\0\x6b\x1a\xb0\xff\0\0\0\0\x69\xa1\x62\xff\0\0\0\0\x6b\
105
-\x1a\xb2\xff\0\0\0\0\x05\0\x6b\x01\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x59\
106
-\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\xf0\xff\0\0\0\0\x7b\x1a\xe8\xff\0\0\0\
107
-\0\x7b\x1a\xe0\xff\0\0\0\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\xbf\
108
-\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x48\
109
+\0\x71\xa2\x53\xff\0\0\0\0\x79\xa0\x30\xff\0\0\0\0\x15\x02\x0c\x01\0\0\0\0\xbf\
110
+\x12\0\0\0\0\0\0\x57\x02\0\0\x02\0\0\0\x15\x02\x09\x01\0\0\0\0\x61\xa1\x5c\xff\
111
+\0\0\0\0\x63\x1a\xa0\xff\0\0\0\0\x61\xa1\x60\xff\0\0\0\0\x63\x1a\xa4\xff\0\0\0\
112
+\0\x69\xa1\x58\xff\0\0\0\0\x6b\x1a\xa8\xff\0\0\0\0\x69\xa1\x5a\xff\0\0\0\0\x6b\
113
+\x1a\xaa\xff\0\0\0\0\x05\0\x6b\x01\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x51\
114
+\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\x1a\xe8\xff\0\0\0\0\x7b\x1a\xe0\xff\0\0\0\
115
+\0\x7b\x1a\xd8\xff\0\0\0\0\x7b\x1a\xd0\xff\0\0\0\0\x7b\x1a\xc8\xff\0\0\0\0\xbf\
116
+\xa3\0\0\0\0\0\0\x07\x03\0\0\xc8\xff\xff\xff\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x40\
117
\xff\0\0\0\0\xbf\x91\0\0\0\0\0\0\xb7\x02\0\0\0\0\0\0\xb7\x04\0\0\x28\0\0\0\xb7\
118
\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\
119
-\x55\0\xfe\0\0\0\0\0\x79\xa1\xe0\xff\0\0\0\0\x63\x1a\x6c\xff\0\0\0\0\x77\x01\0\
120
-\0\x20\0\0\0\x63\x1a\x70\xff\0\0\0\0\x79\xa1\xd8\xff\0\0\0\0\x63\x1a\x64\xff\0\
121
-\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x68\xff\0\0\0\0\x79\xa1\xe8\xff\0\0\0\0\
122
-\x63\x1a\x74\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x78\xff\0\0\0\0\x79\xa1\
123
-\xf0\xff\0\0\0\0\x63\x1a\x7c\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x80\xff\
124
-\0\0\0\0\x71\xa9\xd6\xff\0\0\0\0\x25\x09\x13\x01\x3c\0\0\0\xb7\x01\0\0\x01\0\0\
125
+\x55\0\xfe\0\0\0\0\0\x79\xa1\xd8\xff\0\0\0\0\x63\x1a\x64\xff\0\0\0\0\x77\x01\0\
126
+\0\x20\0\0\0\x63\x1a\x68\xff\0\0\0\0\x79\xa1\xd0\xff\0\0\0\0\x63\x1a\x5c\xff\0\
127
+\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x60\xff\0\0\0\0\x79\xa1\xe0\xff\0\0\0\0\
128
+\x63\x1a\x6c\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x70\xff\0\0\0\0\x79\xa1\
129
+\xe8\xff\0\0\0\0\x63\x1a\x74\xff\0\0\0\0\x77\x01\0\0\x20\0\0\0\x63\x1a\x78\xff\
130
+\0\0\0\0\x71\xa9\xce\xff\0\0\0\0\x25\x09\x13\x01\x3c\0\0\0\xb7\x01\0\0\x01\0\0\
131
\0\x6f\x91\0\0\0\0\0\0\x18\x02\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x5f\x21\0\0\0\
132
\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\x0c\x01\0\0\0\0\xb7\x01\0\0\0\0\0\0\x6b\x1a\
133
-\xfe\xff\0\0\0\0\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x48\xff\0\0\0\0\xbf\xa1\0\0\0\0\
134
-\0\0\x07\x01\0\0\x94\xff\xff\xff\x7b\x1a\x20\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\
135
-\x07\x01\0\0\x84\xff\xff\xff\x7b\x1a\x18\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\
136
-\0\0\0\x18\0\x1c\xb7\x02\0\0\0\0\0\0\x7b\x8a\x28\xff\0\0\0\0\x7b\x2a\x30\xff\0\
137
-\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xfe\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\
138
-\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\
139
-\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\0\x01\0\0\0\0\0\x05\0\
140
-\x91\x01\0\0\0\0\xbf\x91\0\0\0\0\0\0\x15\x01\x26\0\x3c\0\0\0\x15\x01\x5f\0\x2c\
141
-\0\0\0\x55\x01\x60\0\x2b\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xf8\xff\0\0\0\0\xbf\
142
-\xa3\0\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\x79\xa7\x40\xff\0\0\0\0\xbf\x71\0\
143
-\0\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x04\0\0\0\xb7\x05\0\0\x01\0\0\0\
144
-\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\
145
-\0\0\0\x55\x01\x06\x01\0\0\0\0\x71\xa1\xfa\xff\0\0\0\0\x55\x01\x11\0\x02\0\0\0\
146
-\x71\xa1\xf9\xff\0\0\0\0\x55\x01\x0f\0\x02\0\0\0\x71\xa1\xfb\xff\0\0\0\0\x55\
147
-\x01\x0d\0\x01\0\0\0\x79\xa2\x48\xff\0\0\0\0\x07\x02\0\0\x08\0\0\0\xbf\x71\0\0\
148
-\0\0\0\0\x79\xa3\x20\xff\0\0\0\0\xb7\x04\0\0\x10\0\0\0\xb7\x05\0\0\x01\0\0\0\
149
-\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\
150
-\0\0\0\x55\x01\xf5\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5d\xff\0\0\0\0\x18\
151
-\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x3c\0\0\0\0\0\xb7\x08\0\0\x02\0\0\
152
-\0\xb7\x07\0\0\0\0\0\0\x6b\x7a\xf8\xff\0\0\0\0\x05\0\x13\0\0\0\0\0\x0f\x81\0\0\
153
-\0\0\0\0\xbf\x12\0\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\x71\xa3\xff\xff\0\0\0\0\x67\
154
-\x03\0\0\x03\0\0\0\x3d\x32\x09\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\x01\0\
155
-\0\0\x67\x07\0\0\x20\0\0\0\xbf\x73\0\0\0\0\0\0\x77\x03\0\0\x20\0\0\0\xbf\x27\0\
156
-\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xb7\x01\0\0\x1d\0\0\0\x2d\x31\x04\0\0\0\0\0\x79\
157
-\xa8\x28\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x25\0\0\0\
158
-\0\0\xbf\x89\0\0\0\0\0\0\x79\xa1\x48\xff\0\0\0\0\x0f\x19\0\0\0\0\0\0\xbf\xa3\0\
159
-\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\x79\xa1\x40\xff\0\0\0\0\xbf\x92\0\0\0\0\
160
-\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\
161
-\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x79\0\0\0\0\0\
162
-\x71\xa2\xf8\xff\0\0\0\0\x55\x02\x0e\0\xc9\0\0\0\x07\x09\0\0\x02\0\0\0\x79\xa1\
163
-\x40\xff\0\0\0\0\xbf\x92\0\0\0\0\0\0\x79\xa3\x18\xff\0\0\0\0\xb7\x04\0\0\x10\0\
164
-\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\
165
-\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x6c\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\
166
-\x73\x1a\x5c\xff\0\0\0\0\x05\0\xde\xff\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x15\x02\
167
-\xcd\xff\0\0\0\0\x71\xa1\xf9\xff\0\0\0\0\x07\x01\0\0\x02\0\0\0\x05\0\xca\xff\0\
168
-\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5e\xff\0\0\0\0\x71\xa1\xff\xff\0\0\0\0\
169
-\x67\x01\0\0\x03\0\0\0\x79\xa2\x48\xff\0\0\0\0\x0f\x12\0\0\0\0\0\0\x07\x02\0\0\
170
-\x08\0\0\0\x7b\x2a\x48\xff\0\0\0\0\x71\xa9\xfe\xff\0\0\0\0\x79\xa2\x30\xff\0\0\
171
-\0\0\x25\x09\x0c\0\x3c\0\0\0\xb7\x01\0\0\x01\0\0\0\x6f\x91\0\0\0\0\0\0\x5f\x71\
172
-\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\x07\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\
173
-\xbf\x21\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x7d\
174
-\xff\x0b\0\0\0\x71\xa7\x5e\xff\0\0\0\0\x05\0\x09\xff\0\0\0\0\x15\x09\xf8\xff\
175
-\x87\0\0\0\x05\0\xfc\xff\0\0\0\0\x71\xa1\x59\xff\0\0\0\0\x79\xa0\x38\xff\0\0\0\
176
-\0\x15\x01\x13\x01\0\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\
177
+\xf8\xff\0\0\0\0\xb7\x01\0\0\x28\0\0\0\x7b\x1a\x40\xff\0\0\0\0\xbf\xa1\0\0\0\0\
178
+\0\0\x07\x01\0\0\x8c\xff\xff\xff\x7b\x1a\x18\xff\0\0\0\0\xbf\xa1\0\0\0\0\0\0\
179
+\x07\x01\0\0\x7c\xff\xff\xff\x7b\x1a\x10\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\
180
+\0\0\0\x18\0\x1c\xb7\x02\0\0\0\0\0\0\x7b\x8a\x20\xff\0\0\0\0\x7b\x2a\x28\xff\0\
181
+\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xf8\xff\xff\xff\x79\xa1\x38\xff\0\0\0\0\
182
+\x79\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\
183
+\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\
184
+\x01\xc8\0\0\0\0\0\xbf\x91\0\0\0\0\0\0\x15\x01\x26\0\x3c\0\0\0\x15\x01\x5f\0\
185
+\x2c\0\0\0\x55\x01\x60\0\x2b\0\0\0\xb7\x01\0\0\0\0\0\0\x63\x1a\xf0\xff\0\0\0\0\
186
+\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xf0\xff\xff\xff\x79\xa7\x38\xff\0\0\0\0\xbf\
187
+\x71\0\0\0\0\0\0\x79\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\x04\0\0\0\xb7\x05\0\0\x01\
188
+\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\
189
+\0\x20\0\0\0\x55\x01\x06\x01\0\0\0\0\x71\xa1\xf2\xff\0\0\0\0\x55\x01\x11\0\x02\
190
+\0\0\0\x71\xa1\xf1\xff\0\0\0\0\x55\x01\x0f\0\x02\0\0\0\x71\xa1\xf3\xff\0\0\0\0\
191
+\x55\x01\x0d\0\x01\0\0\0\x79\xa2\x40\xff\0\0\0\0\x07\x02\0\0\x08\0\0\0\xbf\x71\
192
+\0\0\0\0\0\0\x79\xa3\x18\xff\0\0\0\0\xb7\x04\0\0\x10\0\0\0\xb7\x05\0\0\x01\0\0\
193
+\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\
194
+\x20\0\0\0\x55\x01\xf5\0\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x55\xff\0\0\0\0\
195
+\x18\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x3c\0\0\0\0\0\xb7\x08\0\0\x02\
196
+\0\0\0\xb7\x07\0\0\0\0\0\0\x6b\x7a\xf0\xff\0\0\0\0\x05\0\x13\0\0\0\0\0\x0f\x81\
197
+\0\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\x71\xa3\xf9\xff\0\0\0\0\
198
+\x67\x03\0\0\x03\0\0\0\x3d\x32\x09\0\0\0\0\0\xbf\x72\0\0\0\0\0\0\x07\x02\0\0\
199
+\x01\0\0\0\x67\x07\0\0\x20\0\0\0\xbf\x73\0\0\0\0\0\0\x77\x03\0\0\x20\0\0\0\xbf\
200
+\x27\0\0\0\0\0\0\xbf\x18\0\0\0\0\0\0\xb7\x01\0\0\x1d\0\0\0\x2d\x31\x04\0\0\0\0\
201
+\0\x79\xa8\x20\xff\0\0\0\0\x18\x07\0\0\x01\0\0\0\0\0\0\0\0\x18\0\x1c\x05\0\x25\
202
+\0\0\0\0\0\xbf\x89\0\0\0\0\0\0\x79\xa1\x40\xff\0\0\0\0\x0f\x19\0\0\0\0\0\0\xbf\
203
+\xa3\0\0\0\0\0\0\x07\x03\0\0\xf0\xff\xff\xff\x79\xa1\x38\xff\0\0\0\0\xbf\x92\0\
204
+\0\0\0\0\0\xb7\x04\0\0\x02\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\
205
+\x01\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x79\0\0\0\
206
+\0\0\x71\xa2\xf0\xff\0\0\0\0\x55\x02\x0e\0\xc9\0\0\0\x07\x09\0\0\x02\0\0\0\x79\
207
+\xa1\x38\xff\0\0\0\0\xbf\x92\0\0\0\0\0\0\x79\xa3\x10\xff\0\0\0\0\xb7\x04\0\0\
208
+\x10\0\0\0\xb7\x05\0\0\x01\0\0\0\x85\0\0\0\x44\0\0\0\xbf\x01\0\0\0\0\0\0\x67\
209
+\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x6c\0\0\0\0\0\xb7\x01\0\0\x01\
210
+\0\0\0\x73\x1a\x54\xff\0\0\0\0\x05\0\xde\xff\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x15\
211
+\x02\xcd\xff\0\0\0\0\x71\xa1\xf1\xff\0\0\0\0\x07\x01\0\0\x02\0\0\0\x05\0\xca\
212
+\xff\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x56\xff\0\0\0\0\x71\xa1\xf9\xff\0\0\
213
+\0\0\x67\x01\0\0\x03\0\0\0\x79\xa2\x40\xff\0\0\0\0\x0f\x12\0\0\0\0\0\0\x07\x02\
214
+\0\0\x08\0\0\0\x7b\x2a\x40\xff\0\0\0\0\x71\xa9\xf8\xff\0\0\0\0\x79\xa2\x28\xff\
215
+\0\0\0\0\x25\x09\x0c\0\x3c\0\0\0\xb7\x01\0\0\x01\0\0\0\x6f\x91\0\0\0\0\0\0\x5f\
216
+\x71\0\0\0\0\0\0\x55\x01\x01\0\0\0\0\0\x05\0\x07\0\0\0\0\0\x07\x02\0\0\x01\0\0\
217
+\0\xbf\x21\0\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x55\x01\x7d\
218
+\xff\x0b\0\0\0\x71\xa7\x56\xff\0\0\0\0\x05\0\x09\xff\0\0\0\0\x15\x09\xf8\xff\
219
+\x87\0\0\0\x05\0\xfc\xff\0\0\0\0\x71\xa1\x51\xff\0\0\0\0\x79\xa0\x30\xff\0\0\0\
220
+\0\x15\x01\x10\x01\0\0\0\0\x71\x62\x03\0\0\0\0\0\x67\x02\0\0\x08\0\0\0\x71\x61\
221
\x02\0\0\0\0\0\x4f\x12\0\0\0\0\0\0\x71\x63\x04\0\0\0\0\0\x71\x61\x05\0\0\0\0\0\
222
\x67\x01\0\0\x08\0\0\0\x4f\x31\0\0\0\0\0\0\x67\x01\0\0\x10\0\0\0\x4f\x21\0\0\0\
223
-\0\0\0\x71\xa2\x5b\xff\0\0\0\0\x15\x02\x42\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\
224
+\0\0\0\x71\xa2\x53\xff\0\0\0\0\x15\x02\x42\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\
225
\x02\0\0\x10\0\0\0\x15\x02\x3f\0\0\0\0\0\x57\x01\0\0\x80\0\0\0\xb7\x02\0\0\x10\
226
\0\0\0\xb7\x03\0\0\x10\0\0\0\x15\x01\x01\0\0\0\0\0\xb7\x03\0\0\x30\0\0\0\x71\
227
-\xa4\x5d\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\xbf\xa3\0\0\0\0\
228
-\0\0\x07\x03\0\0\x64\xff\xff\xff\xbf\x34\0\0\0\0\0\0\x15\x01\x02\0\0\0\0\0\xbf\
229
-\xa4\0\0\0\0\0\0\x07\x04\0\0\x84\xff\xff\xff\x71\xa5\x5c\xff\0\0\0\0\xbf\x31\0\
230
+\xa4\x55\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\0\0\0\0\0\xbf\xa3\0\0\0\0\
231
+\0\0\x07\x03\0\0\x5c\xff\xff\xff\xbf\x34\0\0\0\0\0\0\x15\x01\x02\0\0\0\0\0\xbf\
232
+\xa4\0\0\0\0\0\0\x07\x04\0\0\x7c\xff\xff\xff\x71\xa5\x54\xff\0\0\0\0\xbf\x31\0\
233
\0\0\0\0\0\x15\x05\x01\0\0\0\0\0\xbf\x41\0\0\0\0\0\0\x61\x14\x04\0\0\0\0\0\x67\
234
-\x04\0\0\x20\0\0\0\x61\x15\0\0\0\0\0\0\x4f\x54\0\0\0\0\0\0\x7b\x4a\xa8\xff\0\0\
235
+\x04\0\0\x20\0\0\0\x61\x15\0\0\0\0\0\0\x4f\x54\0\0\0\0\0\0\x7b\x4a\xa0\xff\0\0\
236
\0\0\x61\x14\x08\0\0\0\0\0\x61\x11\x0c\0\0\0\0\0\x67\x01\0\0\x20\0\0\0\x4f\x41\
237
-\0\0\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\x0f\x23\0\0\0\0\0\0\x61\x31\0\0\0\0\0\0\
238
-\x61\x32\x04\0\0\0\0\0\x61\x34\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x69\xa5\x62\
239
-\xff\0\0\0\0\x6b\x5a\xca\xff\0\0\0\0\x69\xa5\x60\xff\0\0\0\0\x6b\x5a\xc8\xff\0\
240
-\0\0\0\x67\x03\0\0\x20\0\0\0\x4f\x43\0\0\0\0\0\0\x7b\x3a\xc0\xff\0\0\0\0\x67\
241
-\x02\0\0\x20\0\0\0\x4f\x12\0\0\0\0\0\0\x7b\x2a\xb8\xff\0\0\0\0\x05\0\x6b\0\0\0\
242
-\0\0\x71\xa2\x5a\xff\0\0\0\0\x15\x02\x04\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\
243
+\0\0\0\0\0\0\x7b\x1a\xa8\xff\0\0\0\0\x0f\x23\0\0\0\0\0\0\x61\x31\0\0\0\0\0\0\
244
+\x61\x32\x04\0\0\0\0\0\x61\x34\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x69\xa5\x5a\
245
+\xff\0\0\0\0\x6b\x5a\xc2\xff\0\0\0\0\x69\xa5\x58\xff\0\0\0\0\x6b\x5a\xc0\xff\0\
246
+\0\0\0\x67\x03\0\0\x20\0\0\0\x4f\x43\0\0\0\0\0\0\x7b\x3a\xb8\xff\0\0\0\0\x67\
247
+\x02\0\0\x20\0\0\0\x4f\x12\0\0\0\0\0\0\x7b\x2a\xb0\xff\0\0\0\0\x05\0\x6b\0\0\0\
248
+\0\0\x71\xa2\x52\xff\0\0\0\0\x15\x02\x04\0\0\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\
249
\0\0\x04\0\0\0\x15\x02\x01\0\0\0\0\0\x05\0\xf1\xfe\0\0\0\0\x57\x01\0\0\x01\0\0\
250
-\0\x15\x01\xd0\0\0\0\0\0\x61\xa1\x64\xff\0\0\0\0\x63\x1a\xa8\xff\0\0\0\0\x61\
251
-\xa1\x68\xff\0\0\0\0\x63\x1a\xac\xff\0\0\0\0\x05\0\x5e\0\0\0\0\0\xb7\x09\0\0\
252
-\x3c\0\0\0\x79\xa8\x28\xff\0\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\
253
-\0\xac\xff\0\0\0\0\x05\0\xc5\0\0\0\0\0\x71\xa2\x5a\xff\0\0\0\0\x15\x02\x26\0\0\
254
+\0\x15\x01\xcd\0\0\0\0\0\x61\xa1\x5c\xff\0\0\0\0\x63\x1a\xa0\xff\0\0\0\0\x61\
255
+\xa1\x60\xff\0\0\0\0\x63\x1a\xa4\xff\0\0\0\0\x05\0\x5e\0\0\0\0\0\xb7\x09\0\0\
256
+\x3c\0\0\0\x79\xa8\x20\xff\0\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x15\
257
+\0\xac\xff\0\0\0\0\x05\0\xc2\0\0\0\0\0\x71\xa2\x52\xff\0\0\0\0\x15\x02\x26\0\0\
258
\0\0\0\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x20\0\0\0\x15\x02\x23\0\0\0\0\0\x57\x01\
259
\0\0\0\x01\0\0\xb7\x02\0\0\x10\0\0\0\xb7\x03\0\0\x10\0\0\0\x15\x01\x01\0\0\0\0\
260
-\0\xb7\x03\0\0\x30\0\0\0\x71\xa4\x5d\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\
261
-\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x64\xff\xff\xff\xbf\x34\0\0\0\0\0\
262
-\0\x15\x01\x02\0\0\0\0\0\xbf\xa4\0\0\0\0\0\0\x07\x04\0\0\x84\xff\xff\xff\x71\
263
-\xa5\x5c\xff\0\0\0\0\xbf\x31\0\0\0\0\0\0\x15\x05\xbd\xff\0\0\0\0\x05\0\xbb\xff\
264
-\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x5a\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\
265
-\x1a\xd0\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xd0\xff\xff\xff\x79\xa1\
266
-\x40\xff\0\0\0\0\x79\xa2\x48\xff\0\0\0\0\xb7\x04\0\0\x08\0\0\0\xb7\x05\0\0\x01\
267
-\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\xa0\0\
268
+\0\xb7\x03\0\0\x30\0\0\0\x71\xa4\x55\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\
269
+\0\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x5c\xff\xff\xff\xbf\x34\0\0\0\0\0\
270
+\0\x15\x01\x02\0\0\0\0\0\xbf\xa4\0\0\0\0\0\0\x07\x04\0\0\x7c\xff\xff\xff\x71\
271
+\xa5\x54\xff\0\0\0\0\xbf\x31\0\0\0\0\0\0\x15\x05\xbd\xff\0\0\0\0\x05\0\xbb\xff\
272
+\0\0\0\0\xb7\x01\0\0\x01\0\0\0\x73\x1a\x52\xff\0\0\0\0\xb7\x01\0\0\0\0\0\0\x7b\
273
+\x1a\xc8\xff\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\xc8\xff\xff\xff\x79\xa1\
274
+\x38\xff\0\0\0\0\x79\xa2\x40\xff\0\0\0\0\xb7\x04\0\0\x08\0\0\0\xb7\x05\0\0\x01\
275
+\0\0\0\x85\0\0\0\x44\0\0\0\x67\0\0\0\x20\0\0\0\x77\0\0\0\x20\0\0\0\x55\0\x9d\0\
276
\0\0\0\0\x05\0\xa8\xfe\0\0\0\0\x15\x09\xf3\xfe\x87\0\0\0\x05\0\x83\xff\0\0\0\0\
277
-\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\x15\x02\x9a\0\0\0\0\0\x57\x01\0\0\
278
+\xbf\x12\0\0\0\0\0\0\x57\x02\0\0\x08\0\0\0\x15\x02\x97\0\0\0\0\0\x57\x01\0\0\
279
\x40\0\0\0\xb7\x02\0\0\x0c\0\0\0\xb7\x03\0\0\x0c\0\0\0\x15\x01\x01\0\0\0\0\0\
280
-\xb7\x03\0\0\x2c\0\0\0\x71\xa4\x5c\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\
281
-\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x58\xff\xff\xff\x0f\x23\0\0\0\0\0\0\
282
+\xb7\x03\0\0\x2c\0\0\0\x71\xa4\x54\xff\0\0\0\0\x15\x04\x01\0\0\0\0\0\xbf\x32\0\
283
+\0\0\0\0\0\xbf\xa3\0\0\0\0\0\0\x07\x03\0\0\x50\xff\xff\xff\x0f\x23\0\0\0\0\0\0\
284
\x61\x32\x04\0\0\0\0\0\x67\x02\0\0\x20\0\0\0\x61\x34\0\0\0\0\0\0\x4f\x42\0\0\0\
285
-\0\0\0\x7b\x2a\xa8\xff\0\0\0\0\x61\x32\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x67\
286
-\x03\0\0\x20\0\0\0\x4f\x23\0\0\0\0\0\0\x7b\x3a\xb0\xff\0\0\0\0\x71\xa2\x5d\xff\
287
-\0\0\0\0\x15\x02\x0c\0\0\0\0\0\x15\x01\x0b\0\0\0\0\0\x61\xa1\xa0\xff\0\0\0\0\
288
-\x67\x01\0\0\x20\0\0\0\x61\xa2\x9c\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xc0\
289
-\xff\0\0\0\0\x61\xa1\x98\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x94\xff\0\0\
290
+\0\0\0\x7b\x2a\xa0\xff\0\0\0\0\x61\x32\x08\0\0\0\0\0\x61\x33\x0c\0\0\0\0\0\x67\
291
+\x03\0\0\x20\0\0\0\x4f\x23\0\0\0\0\0\0\x7b\x3a\xa8\xff\0\0\0\0\x71\xa2\x55\xff\
292
+\0\0\0\0\x15\x02\x0c\0\0\0\0\0\x15\x01\x0b\0\0\0\0\0\x61\xa1\x98\xff\0\0\0\0\
293
+\x67\x01\0\0\x20\0\0\0\x61\xa2\x94\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xb8\
294
+\xff\0\0\0\0\x61\xa1\x90\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x8c\xff\0\0\
295
\0\0\x05\0\x0a\0\0\0\0\0\xb7\x09\0\0\x2b\0\0\0\x05\0\xae\xff\0\0\0\0\x61\xa1\
296
-\x80\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x7c\xff\0\0\0\0\x4f\x21\0\0\0\0\
297
-\0\0\x7b\x1a\xc0\xff\0\0\0\0\x61\xa1\x78\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\
298
-\xa2\x74\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xb8\xff\0\0\0\0\xb7\x02\0\0\0\
299
+\x78\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\xa2\x74\xff\0\0\0\0\x4f\x21\0\0\0\0\
300
+\0\0\x7b\x1a\xb8\xff\0\0\0\0\x61\xa1\x70\xff\0\0\0\0\x67\x01\0\0\x20\0\0\0\x61\
301
+\xa2\x6c\xff\0\0\0\0\x4f\x21\0\0\0\0\0\0\x7b\x1a\xb0\xff\0\0\0\0\xb7\x02\0\0\0\
302
\0\0\0\x07\x08\0\0\x04\0\0\0\x61\x03\0\0\0\0\0\0\xb7\x05\0\0\0\0\0\0\xbf\xa1\0\
303
-\0\0\0\0\0\x07\x01\0\0\xa8\xff\xff\xff\x0f\x21\0\0\0\0\0\0\x71\x14\0\0\0\0\0\0\
304
+\0\0\0\0\0\x07\x01\0\0\xa0\xff\xff\xff\x0f\x21\0\0\0\0\0\0\x71\x14\0\0\0\0\0\0\
305
\xbf\x41\0\0\0\0\0\0\x67\x01\0\0\x38\0\0\0\xc7\x01\0\0\x3f\0\0\0\x5f\x31\0\0\0\
306
\0\0\0\xaf\x51\0\0\0\0\0\0\xbf\x85\0\0\0\0\0\0\x0f\x25\0\0\0\0\0\0\x71\x55\0\0\
307
\0\0\0\0\x67\x03\0\0\x01\0\0\0\xbf\x50\0\0\0\0\0\0\x77\0\0\0\x07\0\0\0\x4f\x03\
308
@@ -XXX,XX +XXX,XX @@ static inline const void *rss_bpf__elf_bytes(size_t *sz)
309
\0\x57\0\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x03\0\0\0\0\0\0\x57\x04\0\0\
310
\x01\0\0\0\x87\x04\0\0\0\0\0\0\x5f\x34\0\0\0\0\0\0\xaf\x41\0\0\0\0\0\0\x57\x05\
311
\0\0\x01\0\0\0\x67\x03\0\0\x01\0\0\0\x4f\x53\0\0\0\0\0\0\x07\x02\0\0\x01\0\0\0\
312
-\xbf\x15\0\0\0\0\0\0\x15\x02\x01\0\x24\0\0\0\x05\0\xa9\xff\0\0\0\0\xbf\x12\0\0\
313
-\0\0\0\0\x67\x02\0\0\x20\0\0\0\x77\x02\0\0\x20\0\0\0\x15\x02\x0e\0\0\0\0\0\x71\
314
-\x63\x06\0\0\0\0\0\x71\x64\x07\0\0\0\0\0\x67\x04\0\0\x08\0\0\0\x4f\x34\0\0\0\0\
315
-\0\0\x3f\x42\0\0\0\0\0\0\x2f\x42\0\0\0\0\0\0\x1f\x21\0\0\0\0\0\0\x63\x1a\x58\
316
-\xff\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x58\xff\xff\xff\x18\x01\0\0\0\0\0\
317
-\0\0\0\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\x55\0\x05\0\0\0\0\0\x71\x61\x08\0\0\0\0\
318
-\0\x71\x60\x09\0\0\0\0\0\x67\0\0\0\x08\0\0\0\x4f\x10\0\0\0\0\0\0\x95\0\0\0\0\0\
319
-\0\0\x69\0\0\0\0\0\0\0\x05\0\xfd\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
320
+\xbf\x15\0\0\0\0\0\0\x15\x02\x01\0\x24\0\0\0\x05\0\xa9\xff\0\0\0\0\x67\x01\0\0\
321
+\x20\0\0\0\x77\x01\0\0\x20\0\0\0\x15\x01\x0c\0\0\0\0\0\x71\x62\x06\0\0\0\0\0\
322
+\x71\x63\x07\0\0\0\0\0\x67\x03\0\0\x08\0\0\0\x4f\x23\0\0\0\0\0\0\x9f\x31\0\0\0\
323
+\0\0\0\x63\x1a\x50\xff\0\0\0\0\xbf\xa2\0\0\0\0\0\0\x07\x02\0\0\x50\xff\xff\xff\
324
+\x18\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x85\0\0\0\x01\0\0\0\x55\0\x05\0\0\0\0\0\
325
+\x71\x61\x08\0\0\0\0\0\x71\x60\x09\0\0\0\0\0\x67\0\0\0\x08\0\0\0\x4f\x10\0\0\0\
326
+\0\0\0\x95\0\0\0\0\0\0\0\x69\0\0\0\0\0\0\0\x05\0\xfd\xff\0\0\0\0\0\0\0\0\0\0\0\
327
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
328
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
329
-\0\x47\x50\x4c\x20\x76\x32\0\0\x9f\xeb\x01\0\x18\0\0\0\0\0\0\0\x10\x05\0\0\x10\
330
-\x05\0\0\x65\x11\0\0\0\0\0\0\0\0\0\x02\x03\0\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\
331
-\x20\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x02\0\0\0\x05\0\0\0\
332
-\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\
333
-\0\0\0\x02\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\
334
-\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x0a\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\0\0\0\0\
335
-\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x01\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\
336
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x47\x50\
337
+\x4c\x20\x76\x32\0\0\x9f\xeb\x01\0\x18\0\0\0\0\0\0\0\x58\x05\0\0\x58\x05\0\0\
338
+\x6b\x11\0\0\0\0\0\0\0\0\0\x02\x03\0\0\0\x01\0\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\
339
+\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x02\0\0\0\x05\0\0\0\0\0\0\
340
+\x01\x04\0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x06\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\
341
+\x02\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\x03\0\
342
+\0\0\0\x02\0\0\0\x04\0\0\0\x0a\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\0\0\0\0\0\0\0\
343
+\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x0c\0\0\0\0\0\0\0\
344
+\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\0\x04\0\0\0\0\0\0\x05\0\0\x04\x28\0\0\0\
345
\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x07\0\0\0\
346
-\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\0\x3e\0\0\0\0\0\0\x0e\x0b\0\0\0\x01\0\0\
347
-\0\0\0\0\0\0\0\0\x02\x0e\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\
348
-\x28\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\
349
-\x05\0\0\0\x40\0\0\0\x27\0\0\0\x0d\0\0\0\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\
350
-\0\x59\0\0\0\0\0\0\x0e\x0f\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x12\0\0\0\0\0\0\0\
351
-\0\0\0\x03\0\0\0\0\x02\0\0\0\x04\0\0\0\x80\0\0\0\0\0\0\0\x04\0\0\x04\x20\0\0\0\
352
-\x19\0\0\0\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x01\0\0\0\
353
-\x80\0\0\0\x32\0\0\0\x11\0\0\0\xc0\0\0\0\x72\0\0\0\0\0\0\x0e\x13\0\0\0\x01\0\0\
354
-\0\0\0\0\0\0\0\0\x02\x16\0\0\0\x90\0\0\0\x22\0\0\x04\xc0\0\0\0\x9a\0\0\0\x17\0\
355
-\0\0\0\0\0\0\x9e\0\0\0\x17\0\0\0\x20\0\0\0\xa7\0\0\0\x17\0\0\0\x40\0\0\0\xac\0\
356
-\0\0\x17\0\0\0\x60\0\0\0\xba\0\0\0\x17\0\0\0\x80\0\0\0\xc3\0\0\0\x17\0\0\0\xa0\
357
-\0\0\0\xd0\0\0\0\x17\0\0\0\xc0\0\0\0\xd9\0\0\0\x17\0\0\0\xe0\0\0\0\xe4\0\0\0\
358
-\x17\0\0\0\0\x01\0\0\xed\0\0\0\x17\0\0\0\x20\x01\0\0\xfd\0\0\0\x17\0\0\0\x40\
359
-\x01\0\0\x05\x01\0\0\x17\0\0\0\x60\x01\0\0\x0e\x01\0\0\x19\0\0\0\x80\x01\0\0\
360
-\x11\x01\0\0\x17\0\0\0\x20\x02\0\0\x16\x01\0\0\x17\0\0\0\x40\x02\0\0\x21\x01\0\
361
-\0\x17\0\0\0\x60\x02\0\0\x26\x01\0\0\x17\0\0\0\x80\x02\0\0\x2f\x01\0\0\x17\0\0\
362
-\0\xa0\x02\0\0\x37\x01\0\0\x17\0\0\0\xc0\x02\0\0\x3e\x01\0\0\x17\0\0\0\xe0\x02\
363
-\0\0\x49\x01\0\0\x17\0\0\0\0\x03\0\0\x53\x01\0\0\x1a\0\0\0\x20\x03\0\0\x5e\x01\
364
-\0\0\x1a\0\0\0\xa0\x03\0\0\x68\x01\0\0\x17\0\0\0\x20\x04\0\0\x74\x01\0\0\x17\0\
365
-\0\0\x40\x04\0\0\x7f\x01\0\0\x17\0\0\0\x60\x04\0\0\0\0\0\0\x1b\0\0\0\x80\x04\0\
366
-\0\x89\x01\0\0\x1d\0\0\0\xc0\x04\0\0\x90\x01\0\0\x17\0\0\0\0\x05\0\0\x99\x01\0\
367
-\0\x17\0\0\0\x20\x05\0\0\0\0\0\0\x1f\0\0\0\x40\x05\0\0\xa2\x01\0\0\x17\0\0\0\
368
-\x80\x05\0\0\xab\x01\0\0\x21\0\0\0\xa0\x05\0\0\xb7\x01\0\0\x1d\0\0\0\xc0\x05\0\
369
-\0\xc0\x01\0\0\0\0\0\x08\x18\0\0\0\xc6\x01\0\0\0\0\0\x01\x04\0\0\0\x20\0\0\0\0\
370
-\0\0\0\0\0\0\x03\0\0\0\0\x17\0\0\0\x04\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\
371
-\0\x17\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xd3\x01\0\0\x1c\
372
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2a\0\0\0\xdd\x01\0\0\0\0\0\x08\x1e\0\0\0\xe3\
373
-\x01\0\0\0\0\0\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xf6\x01\0\
374
-\0\x20\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2b\0\0\0\xf9\x01\0\0\0\0\0\x08\x22\0\0\
375
-\0\xfe\x01\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\0\0\0\0\0\x01\0\0\x0d\x02\0\0\0\x0c\
376
-\x02\0\0\x15\0\0\0\x10\x02\0\0\x01\0\0\x0c\x23\0\0\0\x32\x11\0\0\0\0\0\x01\x01\
377
-\0\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x25\0\0\0\x04\0\0\0\x07\0\0\0\x37\
378
-\x11\0\0\0\0\0\x0e\x26\0\0\0\x01\0\0\0\x40\x11\0\0\x03\0\0\x0f\0\0\0\0\x0c\0\0\
379
-\0\0\0\0\0\x20\0\0\0\x10\0\0\0\0\0\0\0\x20\0\0\0\x14\0\0\0\0\0\0\0\x20\0\0\0\
380
-\x46\x11\0\0\x01\0\0\x0f\0\0\0\0\x27\0\0\0\0\0\0\0\x07\0\0\0\x4e\x11\0\0\0\0\0\
381
-\x07\0\0\0\0\x5c\x11\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\x5f\x41\x52\x52\
382
-\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\x79\x70\x65\0\
383
-\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x6c\x75\x65\x5f\x73\x69\x7a\x65\0\
384
-\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\0\x74\x61\x70\x5f\x72\x73\x73\x5f\
385
-\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\0\x74\
386
+\x80\0\0\0\x32\0\0\0\x09\0\0\0\xc0\0\0\0\x3e\0\0\0\x0b\0\0\0\0\x01\0\0\x48\0\0\
387
+\0\0\0\0\x0e\x0d\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x10\0\0\0\0\0\0\0\0\0\0\x03\
388
+\0\0\0\0\x02\0\0\0\x04\0\0\0\x28\0\0\0\0\0\0\0\x05\0\0\x04\x28\0\0\0\x19\0\0\0\
389
+\x01\0\0\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x0f\0\0\0\x80\0\0\0\
390
+\x32\0\0\0\x09\0\0\0\xc0\0\0\0\x3e\0\0\0\x0b\0\0\0\0\x01\0\0\x63\0\0\0\0\0\0\
391
+\x0e\x11\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x14\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\
392
+\x02\0\0\0\x04\0\0\0\x80\0\0\0\0\0\0\0\x05\0\0\x04\x28\0\0\0\x19\0\0\0\x01\0\0\
393
+\0\0\0\0\0\x1e\0\0\0\x05\0\0\0\x40\0\0\0\x27\0\0\0\x01\0\0\0\x80\0\0\0\x32\0\0\
394
+\0\x13\0\0\0\xc0\0\0\0\x3e\0\0\0\x0b\0\0\0\0\x01\0\0\x7c\0\0\0\0\0\0\x0e\x15\0\
395
+\0\0\x01\0\0\0\0\0\0\0\0\0\0\x02\x18\0\0\0\x9a\0\0\0\x22\0\0\x04\xc0\0\0\0\xa4\
396
+\0\0\0\x19\0\0\0\0\0\0\0\xa8\0\0\0\x19\0\0\0\x20\0\0\0\xb1\0\0\0\x19\0\0\0\x40\
397
+\0\0\0\xb6\0\0\0\x19\0\0\0\x60\0\0\0\xc4\0\0\0\x19\0\0\0\x80\0\0\0\xcd\0\0\0\
398
+\x19\0\0\0\xa0\0\0\0\xda\0\0\0\x19\0\0\0\xc0\0\0\0\xe3\0\0\0\x19\0\0\0\xe0\0\0\
399
+\0\xee\0\0\0\x19\0\0\0\0\x01\0\0\xf7\0\0\0\x19\0\0\0\x20\x01\0\0\x07\x01\0\0\
400
+\x19\0\0\0\x40\x01\0\0\x0f\x01\0\0\x19\0\0\0\x60\x01\0\0\x18\x01\0\0\x1b\0\0\0\
401
+\x80\x01\0\0\x1b\x01\0\0\x19\0\0\0\x20\x02\0\0\x20\x01\0\0\x19\0\0\0\x40\x02\0\
402
+\0\x2b\x01\0\0\x19\0\0\0\x60\x02\0\0\x30\x01\0\0\x19\0\0\0\x80\x02\0\0\x39\x01\
403
+\0\0\x19\0\0\0\xa0\x02\0\0\x41\x01\0\0\x19\0\0\0\xc0\x02\0\0\x48\x01\0\0\x19\0\
404
+\0\0\xe0\x02\0\0\x53\x01\0\0\x19\0\0\0\0\x03\0\0\x5d\x01\0\0\x1c\0\0\0\x20\x03\
405
+\0\0\x68\x01\0\0\x1c\0\0\0\xa0\x03\0\0\x72\x01\0\0\x19\0\0\0\x20\x04\0\0\x7e\
406
+\x01\0\0\x19\0\0\0\x40\x04\0\0\x89\x01\0\0\x19\0\0\0\x60\x04\0\0\0\0\0\0\x1d\0\
407
+\0\0\x80\x04\0\0\x93\x01\0\0\x1f\0\0\0\xc0\x04\0\0\x9a\x01\0\0\x19\0\0\0\0\x05\
408
+\0\0\xa3\x01\0\0\x19\0\0\0\x20\x05\0\0\0\0\0\0\x21\0\0\0\x40\x05\0\0\xac\x01\0\
409
+\0\x19\0\0\0\x80\x05\0\0\xb5\x01\0\0\x23\0\0\0\xa0\x05\0\0\xc1\x01\0\0\x1f\0\0\
410
+\0\xc0\x05\0\0\xca\x01\0\0\0\0\0\x08\x1a\0\0\0\xd0\x01\0\0\0\0\0\x01\x04\0\0\0\
411
+\x20\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x19\0\0\0\x04\0\0\0\x05\0\0\0\0\0\0\0\0\0\
412
+\0\x03\0\0\0\0\x19\0\0\0\x04\0\0\0\x04\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\0\0\xdd\
413
+\x01\0\0\x1e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2c\0\0\0\xe7\x01\0\0\0\0\0\x08\
414
+\x20\0\0\0\xed\x01\0\0\0\0\0\x01\x08\0\0\0\x40\0\0\0\0\0\0\0\x01\0\0\x05\x08\0\
415
+\0\0\0\x02\0\0\x22\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x2d\0\0\0\x03\x02\0\0\0\0\0\
416
+\x08\x24\0\0\0\x08\x02\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\0\0\0\0\0\x01\0\0\x0d\
417
+\x02\0\0\0\x16\x02\0\0\x17\0\0\0\x1a\x02\0\0\x01\0\0\x0c\x25\0\0\0\x38\x11\0\0\
418
+\0\0\0\x01\x01\0\0\0\x08\0\0\x01\0\0\0\0\0\0\0\x03\0\0\0\0\x27\0\0\0\x04\0\0\0\
419
+\x07\0\0\0\x3d\x11\0\0\0\0\0\x0e\x28\0\0\0\x01\0\0\0\x46\x11\0\0\x03\0\0\x0f\0\
420
+\0\0\0\x0e\0\0\0\0\0\0\0\x28\0\0\0\x12\0\0\0\0\0\0\0\x28\0\0\0\x16\0\0\0\0\0\0\
421
+\0\x28\0\0\0\x4c\x11\0\0\x01\0\0\x0f\0\0\0\0\x29\0\0\0\0\0\0\0\x07\0\0\0\x54\
422
+\x11\0\0\0\0\0\x07\0\0\0\0\x62\x11\0\0\0\0\0\x07\0\0\0\0\0\x69\x6e\x74\0\x5f\
423
+\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x74\
424
+\x79\x70\x65\0\x6b\x65\x79\x5f\x73\x69\x7a\x65\0\x76\x61\x6c\x75\x65\x5f\x73\
425
+\x69\x7a\x65\0\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\0\x6d\x61\x70\x5f\
426
+\x66\x6c\x61\x67\x73\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\
427
+\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\0\x74\x61\x70\x5f\x72\x73\x73\
428
+\x5f\x6d\x61\x70\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\0\x74\x61\
429
+\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\
430
+\x6f\x6e\x5f\x74\x61\x62\x6c\x65\0\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\0\x6c\
431
+\x65\x6e\0\x70\x6b\x74\x5f\x74\x79\x70\x65\0\x6d\x61\x72\x6b\0\x71\x75\x65\x75\
432
+\x65\x5f\x6d\x61\x70\x70\x69\x6e\x67\0\x70\x72\x6f\x74\x6f\x63\x6f\x6c\0\x76\
433
+\x6c\x61\x6e\x5f\x70\x72\x65\x73\x65\x6e\x74\0\x76\x6c\x61\x6e\x5f\x74\x63\x69\
434
+\0\x76\x6c\x61\x6e\x5f\x70\x72\x6f\x74\x6f\0\x70\x72\x69\x6f\x72\x69\x74\x79\0\
435
+\x69\x6e\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\x65\x78\0\x69\x66\x69\x6e\
436
+\x64\x65\x78\0\x74\x63\x5f\x69\x6e\x64\x65\x78\0\x63\x62\0\x68\x61\x73\x68\0\
437
+\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\0\x64\x61\x74\x61\0\x64\x61\x74\x61\
438
+\x5f\x65\x6e\x64\0\x6e\x61\x70\x69\x5f\x69\x64\0\x66\x61\x6d\x69\x6c\x79\0\x72\
439
+\x65\x6d\x6f\x74\x65\x5f\x69\x70\x34\0\x6c\x6f\x63\x61\x6c\x5f\x69\x70\x34\0\
440
+\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x36\0\x6c\x6f\x63\x61\x6c\x5f\x69\x70\x36\
441
+\0\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\0\x6c\x6f\x63\x61\x6c\x5f\x70\
442
+\x6f\x72\x74\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\x74\x73\x74\x61\x6d\x70\0\
443
+\x77\x69\x72\x65\x5f\x6c\x65\x6e\0\x67\x73\x6f\x5f\x73\x65\x67\x73\0\x67\x73\
444
+\x6f\x5f\x73\x69\x7a\x65\0\x74\x73\x74\x61\x6d\x70\x5f\x74\x79\x70\x65\0\x68\
445
+\x77\x74\x73\x74\x61\x6d\x70\0\x5f\x5f\x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\
446
+\x65\x64\x20\x69\x6e\x74\0\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\x5f\x5f\x75\
447
+\x36\x34\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\x6e\x67\x20\x6c\x6f\x6e\
448
+\x67\0\x73\x6b\0\x5f\x5f\x75\x38\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x63\x68\
449
+\x61\x72\0\x73\x6b\x62\0\x74\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\
450
+\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x73\x6f\x63\x6b\x65\x74\0\x2f\x68\x6f\x6d\
451
+\x65\x2f\x61\x6e\x64\x2f\x57\x6f\x72\x6b\x2f\x44\x61\x79\x6e\x69\x78\x2f\x71\
452
+\x65\x6d\x75\x2f\x74\x6f\x6f\x6c\x73\x2f\x65\x62\x70\x66\x2f\x72\x73\x73\x2e\
453
+\x62\x70\x66\x2e\x63\0\x69\x6e\x74\x20\x74\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\
454
+\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\x67\x28\x73\x74\x72\x75\x63\x74\x20\
455
+\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\x20\x2a\x73\x6b\x62\x29\0\x20\x20\x20\x20\
456
+\x5f\x5f\x75\x33\x32\x20\x6b\x65\x79\x20\x3d\x20\x30\x3b\0\x20\x20\x20\x20\x63\
457
+\x6f\x6e\x66\x69\x67\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\
458
+\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\
459
+\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\x2c\x20\
460
+\x26\x6b\x65\x79\x29\x3b\0\x20\x20\x20\x20\x74\x6f\x65\x20\x3d\x20\x62\x70\x66\
461
+\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\
462
\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\
463
-\x5f\x6b\x65\x79\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\
464
-\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\0\x5f\x5f\x73\x6b\x5f\
465
-\x62\x75\x66\x66\0\x6c\x65\x6e\0\x70\x6b\x74\x5f\x74\x79\x70\x65\0\x6d\x61\x72\
466
-\x6b\0\x71\x75\x65\x75\x65\x5f\x6d\x61\x70\x70\x69\x6e\x67\0\x70\x72\x6f\x74\
467
-\x6f\x63\x6f\x6c\0\x76\x6c\x61\x6e\x5f\x70\x72\x65\x73\x65\x6e\x74\0\x76\x6c\
468
-\x61\x6e\x5f\x74\x63\x69\0\x76\x6c\x61\x6e\x5f\x70\x72\x6f\x74\x6f\0\x70\x72\
469
-\x69\x6f\x72\x69\x74\x79\0\x69\x6e\x67\x72\x65\x73\x73\x5f\x69\x66\x69\x6e\x64\
470
-\x65\x78\0\x69\x66\x69\x6e\x64\x65\x78\0\x74\x63\x5f\x69\x6e\x64\x65\x78\0\x63\
471
-\x62\0\x68\x61\x73\x68\0\x74\x63\x5f\x63\x6c\x61\x73\x73\x69\x64\0\x64\x61\x74\
472
-\x61\0\x64\x61\x74\x61\x5f\x65\x6e\x64\0\x6e\x61\x70\x69\x5f\x69\x64\0\x66\x61\
473
-\x6d\x69\x6c\x79\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x34\0\x6c\x6f\x63\x61\
474
-\x6c\x5f\x69\x70\x34\0\x72\x65\x6d\x6f\x74\x65\x5f\x69\x70\x36\0\x6c\x6f\x63\
475
-\x61\x6c\x5f\x69\x70\x36\0\x72\x65\x6d\x6f\x74\x65\x5f\x70\x6f\x72\x74\0\x6c\
476
-\x6f\x63\x61\x6c\x5f\x70\x6f\x72\x74\0\x64\x61\x74\x61\x5f\x6d\x65\x74\x61\0\
477
-\x74\x73\x74\x61\x6d\x70\0\x77\x69\x72\x65\x5f\x6c\x65\x6e\0\x67\x73\x6f\x5f\
478
-\x73\x65\x67\x73\0\x67\x73\x6f\x5f\x73\x69\x7a\x65\0\x74\x73\x74\x61\x6d\x70\
479
-\x5f\x74\x79\x70\x65\0\x68\x77\x74\x73\x74\x61\x6d\x70\0\x5f\x5f\x75\x33\x32\0\
480
-\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x66\x6c\x6f\x77\x5f\x6b\x65\
481
-\x79\x73\0\x5f\x5f\x75\x36\x34\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x6c\x6f\
482
-\x6e\x67\x20\x6c\x6f\x6e\x67\0\x73\x6b\0\x5f\x5f\x75\x38\0\x75\x6e\x73\x69\x67\
483
-\x6e\x65\x64\x20\x63\x68\x61\x72\0\x73\x6b\x62\0\x74\x75\x6e\x5f\x72\x73\x73\
484
-\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x74\x75\x6e\x5f\x72\
485
-\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\0\x2f\x68\x6f\x6d\x65\x2f\x73\x68\
486
-\x72\x65\x65\x73\x68\x2f\x63\x2f\x71\x65\x6d\x75\x2f\x74\x6f\x6f\x6c\x73\x2f\
487
-\x65\x62\x70\x66\x2f\x72\x73\x73\x2e\x62\x70\x66\x2e\x63\0\x69\x6e\x74\x20\x74\
488
-\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\
489
-\x67\x28\x73\x74\x72\x75\x63\x74\x20\x5f\x5f\x73\x6b\x5f\x62\x75\x66\x66\x20\
490
-\x2a\x73\x6b\x62\x29\0\x20\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x6b\x65\x79\x20\
491
-\x3d\x20\x30\x3b\0\x20\x20\x20\x20\x63\x6f\x6e\x66\x69\x67\x20\x3d\x20\x62\x70\
492
-\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\
493
-\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\
494
-\x72\x61\x74\x69\x6f\x6e\x73\x2c\x20\x26\x6b\x65\x79\x29\x3b\0\x20\x20\x20\x20\
495
-\x74\x6f\x65\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\
496
-\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
497
-\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\x2c\x20\x26\x6b\x65\x79\
498
-\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\x20\x26\x26\
499
-\x20\x74\x6f\x65\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\
500
-\x21\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x72\x65\x64\x69\x72\x65\x63\x74\x29\x20\
501
-\x7b\0\x20\x20\x20\x20\x5f\x5f\x75\x38\x20\x72\x73\x73\x5f\x69\x6e\x70\x75\x74\
502
-\x5b\x48\x41\x53\x48\x5f\x43\x41\x4c\x43\x55\x4c\x41\x54\x49\x4f\x4e\x5f\x42\
503
-\x55\x46\x46\x45\x52\x5f\x53\x49\x5a\x45\x5d\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\
504
-\x20\x20\x73\x74\x72\x75\x63\x74\x20\x70\x61\x63\x6b\x65\x74\x5f\x68\x61\x73\
505
-\x68\x5f\x69\x6e\x66\x6f\x5f\x74\x20\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\
506
-\x6f\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x21\x69\x6e\x66\
507
-\x6f\x20\x7c\x7c\x20\x21\x73\x6b\x62\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x62\
508
-\x65\x31\x36\x20\x72\x65\x74\x20\x3d\x20\x30\x3b\0\x20\x20\x20\x20\x65\x72\x72\
509
-\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\
510
-\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\x66\
511
-\x66\x73\x65\x74\x2c\x20\x26\x72\x65\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\
512
-\x72\x65\x74\x29\x2c\0\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\
513
-\0\x20\x20\x20\x20\x73\x77\x69\x74\x63\x68\x20\x28\x62\x70\x66\x5f\x6e\x74\x6f\
514
-\x68\x73\x28\x72\x65\x74\x29\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\
515
-\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\
516
-\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\
517
-\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x72\x65\x74\x2c\x20\x73\x69\x7a\x65\x6f\
518
-\x66\x28\x72\x65\x74\x29\x2c\0\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x72\
519
-\x65\x74\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x6c\x33\x5f\x70\x72\x6f\x74\x6f\
520
-\x63\x6f\x6c\x20\x3d\x3d\x20\x30\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\
521
-\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x34\x20\x3d\x20\x31\x3b\0\x20\
522
-\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x68\x64\x72\
523
-\x20\x69\x70\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\
524
-\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\
525
-\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\
526
-\x2c\x20\x26\x69\x70\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x69\x70\x29\x2c\0\x20\
527
-\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\
528
-\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\
529
-\x6d\x65\x6e\x74\x65\x64\x20\x3d\x20\x21\x21\x69\x70\x2e\x66\x72\x61\x67\x5f\
530
-\x6f\x66\x66\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\
531
-\x6e\x5f\x73\x72\x63\x20\x3d\x20\x69\x70\x2e\x73\x61\x64\x64\x72\x3b\0\x20\x20\
532
-\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x6e\x5f\x64\x73\x74\x20\
533
-\x3d\x20\x69\x70\x2e\x64\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
534
-\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x20\x69\x70\x2e\x70\x72\
535
-\x6f\x74\x6f\x63\x6f\x6c\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x6c\x34\x5f\x6f\
536
-\x66\x66\x73\x65\x74\x20\x3d\x20\x69\x70\x2e\x69\x68\x6c\x20\x2a\x20\x34\x3b\0\
537
-\x20\x20\x20\x20\x69\x66\x20\x28\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\
538
-\x20\x21\x3d\x20\x30\x20\x26\x26\x20\x21\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\
539
-\x66\x72\x61\x67\x6d\x65\x6e\x74\x65\x64\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\
540
-\x20\x20\x69\x66\x20\x28\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\
541
-\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x54\x43\x50\x29\x20\x7b\0\x20\x20\x20\
542
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x74\
543
-\x63\x70\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
544
-\x73\x74\x72\x75\x63\x74\x20\x74\x63\x70\x68\x64\x72\x20\x74\x63\x70\x20\x3d\
545
-\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\
546
-\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\
547
-\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6c\x34\
548
-\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x74\x63\x70\x2c\x20\x73\x69\x7a\x65\
549
-\x6f\x66\x28\x74\x63\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
550
-\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\
551
-\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x34\
552
-\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\
553
-\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x74\x63\x70\x20\x26\x26\0\x20\x20\
554
-\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\
555
-\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\
556
-\x20\x69\x70\x76\x36\x68\x64\x72\x20\x69\x70\x36\x20\x3d\x20\x7b\x7d\x3b\0\x20\
557
-\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\
558
+\x5f\x6b\x65\x79\x2c\x20\x26\x6b\x65\x79\x29\x3b\0\x20\x20\x20\x20\x69\x66\x20\
559
+\x28\x63\x6f\x6e\x66\x69\x67\x20\x26\x26\x20\x74\x6f\x65\x29\x20\x7b\0\x20\x20\
560
+\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x21\x63\x6f\x6e\x66\x69\x67\x2d\x3e\
561
+\x72\x65\x64\x69\x72\x65\x63\x74\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x75\x38\
562
+\x20\x72\x73\x73\x5f\x69\x6e\x70\x75\x74\x5b\x48\x41\x53\x48\x5f\x43\x41\x4c\
563
+\x43\x55\x4c\x41\x54\x49\x4f\x4e\x5f\x42\x55\x46\x46\x45\x52\x5f\x53\x49\x5a\
564
+\x45\x5d\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\
565
+\x70\x61\x63\x6b\x65\x74\x5f\x68\x61\x73\x68\x5f\x69\x6e\x66\x6f\x5f\x74\x20\
566
+\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\
567
+\x20\x20\x69\x66\x20\x28\x21\x69\x6e\x66\x6f\x20\x7c\x7c\x20\x21\x73\x6b\x62\
568
+\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x62\x65\x31\x36\x20\x72\x65\x74\x20\x3d\
569
+\x20\x30\x3b\0\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\
570
\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\
571
-\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\x2c\x20\x26\x69\x70\x36\x2c\x20\x73\x69\
572
-\x7a\x65\x6f\x66\x28\x69\x70\x36\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\
573
-\x6e\x66\x6f\x2d\x3e\x69\x6e\x36\x5f\x73\x72\x63\x20\x3d\x20\x69\x70\x36\x2e\
574
-\x73\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\
575
-\x3e\x69\x6e\x36\x5f\x64\x73\x74\x20\x3d\x20\x69\x70\x36\x2e\x64\x61\x64\x64\
576
+\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x72\x65\
577
+\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x72\x65\x74\x29\x2c\0\x20\x20\x20\x20\
578
+\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x73\x77\x69\x74\x63\
579
+\x68\x20\x28\x62\x70\x66\x5f\x6e\x74\x6f\x68\x73\x28\x72\x65\x74\x29\x29\x20\
580
+\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
581
+\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\
582
+\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\
583
+\x72\x65\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x72\x65\x74\x29\x2c\0\x20\x20\
584
+\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x72\x65\x74\x3b\0\x20\x20\x20\x20\x69\x66\
585
+\x20\x28\x6c\x33\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x3d\x20\x30\x29\
586
+\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\
587
+\x69\x70\x76\x34\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\
588
+\x72\x75\x63\x74\x20\x69\x70\x68\x64\x72\x20\x69\x70\x20\x3d\x20\x7b\x7d\x3b\0\
589
+\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\
590
+\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\
591
+\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\x2c\x20\x26\x69\x70\x2c\x20\x73\x69\
592
+\x7a\x65\x6f\x66\x28\x69\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\
593
+\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\
594
+\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\x65\x64\x20\x3d\x20\
595
+\x21\x21\x69\x70\x2e\x66\x72\x61\x67\x5f\x6f\x66\x66\x3b\0\x20\x20\x20\x20\x20\
596
+\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x6e\x5f\x73\x72\x63\x20\x3d\x20\x69\
597
+\x70\x2e\x73\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\
598
+\x6f\x2d\x3e\x69\x6e\x5f\x64\x73\x74\x20\x3d\x20\x69\x70\x2e\x64\x61\x64\x64\
599
\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\
600
-\x6f\x6c\x20\x3d\x20\x69\x70\x36\x2e\x6e\x65\x78\x74\x68\x64\x72\x3b\0\x20\x20\
601
-\x20\x20\x73\x77\x69\x74\x63\x68\x20\x28\x68\x64\x72\x5f\x74\x79\x70\x65\x29\
602
-\x20\x7b\0\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x76\x36\x5f\x6f\
603
-\x70\x74\x5f\x68\x64\x72\x20\x65\x78\x74\x5f\x68\x64\x72\x20\x3d\x20\x7b\x7d\
604
-\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
605
+\x6f\x6c\x20\x3d\x20\x69\x70\x2e\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x3b\0\x20\x20\
606
+\x20\x20\x20\x20\x20\x20\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x3d\x20\x69\
607
+\x70\x2e\x69\x68\x6c\x20\x2a\x20\x34\x3b\0\x20\x20\x20\x20\x69\x66\x20\x28\x6c\
608
+\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x21\x3d\x20\x30\x20\x26\x26\x20\
609
+\x21\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\x65\
610
+\x64\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x6c\x34\x5f\
611
+\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\
612
+\x5f\x54\x43\x50\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
613
+\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x74\x63\x70\x20\x3d\x20\x31\x3b\0\x20\x20\
614
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x74\x63\
615
+\x70\x68\x64\x72\x20\x74\x63\x70\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\
616
+\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\
617
+\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\
618
+\x76\x65\x28\x73\x6b\x62\x2c\x20\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\
619
+\x26\x74\x63\x70\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x74\x63\x70\x29\x2c\0\x20\
620
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\
621
+\x20\x7b\0\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\
622
+\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x34\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\
623
+\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\
624
+\x73\x5f\x74\x63\x70\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\
625
+\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\
626
+\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x76\x36\x68\x64\x72\x20\
627
+\x69\x70\x36\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\
628
+\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\
629
+\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x30\
630
+\x2c\x20\x26\x69\x70\x36\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x69\x70\x36\x29\
631
+\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x6e\x36\x5f\
632
+\x73\x72\x63\x20\x3d\x20\x69\x70\x36\x2e\x73\x61\x64\x64\x72\x3b\0\x20\x20\x20\
633
+\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x6e\x36\x5f\x64\x73\x74\x20\
634
+\x3d\x20\x69\x70\x36\x2e\x64\x61\x64\x64\x72\x3b\0\x20\x20\x20\x20\x20\x20\x20\
635
+\x20\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x20\x69\x70\x36\x2e\
636
+\x6e\x65\x78\x74\x68\x64\x72\x3b\0\x20\x20\x20\x20\x73\x77\x69\x74\x63\x68\x20\
637
+\x28\x68\x64\x72\x5f\x74\x79\x70\x65\x29\x20\x7b\0\x20\x20\x20\x20\x73\x74\x72\
638
+\x75\x63\x74\x20\x69\x70\x76\x36\x5f\x6f\x70\x74\x5f\x68\x64\x72\x20\x65\x78\
639
+\x74\x5f\x68\x64\x72\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
640
+\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\
641
+\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\
642
+\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x65\x78\x74\x5f\x68\
643
+\x64\x72\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x2a\x6c\x34\x5f\
644
+\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\
645
+\x5f\x52\x4f\x55\x54\x49\x4e\x47\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\
646
+\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x69\x70\x76\x36\x5f\x72\x74\x5f\
647
+\x68\x64\x72\x20\x65\x78\x74\x5f\x72\x74\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\
648
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
649
\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\
650
\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\
651
-\x74\x2c\x20\x26\x65\x78\x74\x5f\x68\x64\x72\x2c\0\x20\x20\x20\x20\x20\x20\x20\
652
-\x20\x69\x66\x20\x28\x2a\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\
653
-\x3d\x20\x49\x50\x50\x52\x4f\x54\x4f\x5f\x52\x4f\x55\x54\x49\x4e\x47\x29\x20\
654
-\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\
655
-\x20\x69\x70\x76\x36\x5f\x72\x74\x5f\x68\x64\x72\x20\x65\x78\x74\x5f\x72\x74\
656
-\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\
657
-\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\
658
-\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\
659
-\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x65\x78\x74\x5f\x72\x74\
660
-\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x28\x65\
661
-\x78\x74\x5f\x72\x74\x2e\x74\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\
662
-\x53\x52\x43\x52\x54\x5f\x54\x59\x50\x45\x5f\x32\x29\x20\x26\x26\0\x20\x20\x20\
663
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\
664
-\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x66\x66\x73\x65\x74\x6f\x66\
665
-\x28\x73\x74\x72\x75\x63\x74\x20\x72\x74\x32\x5f\x68\x64\x72\x2c\x20\x61\x64\
666
-\x64\x72\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
667
-\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\
668
-\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\
669
-\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\
670
-\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
671
-\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x5f\
672
-\x65\x78\x74\x5f\x64\x73\x74\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\
673
-\x20\x20\x20\x20\x20\x7d\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\
674
-\x5f\x28\x28\x70\x61\x63\x6b\x65\x64\x29\x29\x20\x6f\x70\x74\x20\x3d\x20\x7b\
675
-\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\
676
-\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x3d\x20\x28\x6f\x70\x74\x2e\x74\
677
-\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\x54\x4c\x56\x5f\x50\x41\x44\
678
-\x31\x29\x20\x3f\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
679
-\x20\x69\x66\x20\x28\x6f\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x31\
680
-\x20\x3e\x3d\x20\x65\x78\x74\x5f\x68\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\x20\
681
-\x2a\x20\x38\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
682
-\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\
683
-\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\
684
-\x6b\x62\x2c\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\
685
-\x74\x5f\x6f\x66\x66\x73\x65\x74\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
686
-\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x6f\x70\x74\x2e\x74\x79\x70\x65\x20\
687
-\x3d\x3d\x20\x49\x50\x56\x36\x5f\x54\x4c\x56\x5f\x48\x41\x4f\x29\x20\x7b\0\x20\
688
+\x74\x2c\x20\x26\x65\x78\x74\x5f\x72\x74\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\
689
+\x20\x20\x20\x20\x69\x66\x20\x28\x28\x65\x78\x74\x5f\x72\x74\x2e\x74\x79\x70\
690
+\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\x53\x52\x43\x52\x54\x5f\x54\x59\x50\
691
+\x45\x5f\x32\x29\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
692
+\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\
693
+\x2b\x20\x6f\x66\x66\x73\x65\x74\x6f\x66\x28\x73\x74\x72\x75\x63\x74\x20\x72\
694
+\x74\x32\x5f\x68\x64\x72\x2c\x20\x61\x64\x64\x72\x29\x2c\0\x20\x20\x20\x20\x20\
695
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\
696
+\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\
697
+\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\
698
+\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\
699
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\
700
+\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\x5f\x64\x73\x74\x20\x3d\
701
+\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x5f\x5f\
702
+\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\x5f\x28\x28\x70\x61\x63\x6b\x65\x64\
703
+\x29\x29\x20\x6f\x70\x74\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\
704
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6f\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\
705
+\x20\x2b\x3d\x20\x28\x6f\x70\x74\x2e\x74\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\
706
+\x56\x36\x5f\x54\x4c\x56\x5f\x50\x41\x44\x31\x29\x20\x3f\0\x20\x20\x20\x20\x20\
707
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x6f\x70\x74\x5f\
708
+\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x31\x20\x3e\x3d\x20\x65\x78\x74\x5f\x68\
709
+\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\x20\x2a\x20\x38\x29\x20\x7b\0\x20\x20\x20\
710
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\
711
+\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\
712
+\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x2a\x6c\x34\x5f\x6f\
713
+\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\x2c\0\
714
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\
715
+\x28\x6f\x70\x74\x2e\x74\x79\x70\x65\x20\x3d\x3d\x20\x49\x50\x56\x36\x5f\x54\
716
+\x4c\x56\x5f\x48\x41\x4f\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
717
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\x34\x5f\x6f\
718
+\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\x74\x5f\x6f\x66\x66\x73\x65\x74\0\x20\
719
\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
720
-\x20\x20\x20\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x20\x6f\x70\
721
-\x74\x5f\x6f\x66\x66\x73\x65\x74\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
722
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\
723
-\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\
724
-\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
725
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\
726
-\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
727
-\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\
728
-\x5f\x73\x72\x63\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
729
-\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\
730
-\x65\x64\x20\x3d\x20\x74\x72\x75\x65\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x2a\
731
-\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x20\x2b\x3d\x20\x28\x65\x78\x74\x5f\x68\
732
-\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\x20\x2b\x20\x31\x29\x20\x2a\x20\x38\x3b\0\
733
-\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\
734
-\x6c\x20\x3d\x20\x65\x78\x74\x5f\x68\x64\x72\x2e\x6e\x65\x78\x74\x68\x64\x72\
735
-\x3b\0\x20\x20\x20\x20\x66\x6f\x72\x20\x28\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\
736
-\x69\x6e\x74\x20\x69\x20\x3d\x20\x30\x3b\x20\x69\x20\x3c\x20\x49\x50\x36\x5f\
737
-\x45\x58\x54\x45\x4e\x53\x49\x4f\x4e\x53\x5f\x43\x4f\x55\x4e\x54\x3b\x20\x2b\
738
-\x2b\x69\x29\x20\x7b\0\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\
739
-\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\
740
-\x36\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\
741
-\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\
742
-\x36\x5f\x65\x78\x74\x5f\x64\x73\x74\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\
743
-\x20\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\
744
-\x6f\x2e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\x5f\x73\x72\x63\x20\x26\
745
-\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\
746
-\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x75\x64\x70\
747
-\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\
748
-\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x68\x61\x73\x68\x5f\x74\x79\x70\
749
-\x65\x73\x20\x26\x20\x56\x49\x52\x54\x49\x4f\x5f\x4e\x45\x54\x5f\x52\x53\x53\
750
-\x5f\x48\x41\x53\x48\x5f\x54\x59\x50\x45\x5f\x49\x50\x76\x34\x29\x20\x7b\0\x20\
751
-\x20\x20\x20\x5f\x5f\x62\x75\x69\x6c\x74\x69\x6e\x5f\x6d\x65\x6d\x63\x70\x79\
752
-\x28\x26\x72\x73\x73\x5f\x69\x6e\x70\x75\x74\x5b\x2a\x62\x79\x74\x65\x73\x5f\
753
-\x77\x72\x69\x74\x74\x65\x6e\x5d\x2c\x20\x70\x74\x72\x2c\x20\x73\x69\x7a\x65\
754
-\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\
755
-\x3e\x69\x73\x5f\x75\x64\x70\x20\x3d\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\
756
-\x20\x20\x20\x20\x20\x73\x74\x72\x75\x63\x74\x20\x75\x64\x70\x68\x64\x72\x20\
757
-\x75\x64\x70\x20\x3d\x20\x7b\x7d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
758
-\x20\x20\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\
759
-\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\
760
-\x62\x2c\x20\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\x2c\x20\x26\x75\x64\x70\x2c\
761
-\x20\x73\x69\x7a\x65\x6f\x66\x28\x75\x64\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\
762
+\x65\x72\x72\x20\x3d\x20\x62\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\
763
+\x62\x79\x74\x65\x73\x5f\x72\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\0\
764
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
765
+\x20\x69\x66\x20\x28\x65\x72\x72\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\
766
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\
767
+\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\x5f\x73\x72\x63\x20\x3d\x20\x31\x3b\0\
768
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\
769
+\x73\x5f\x66\x72\x61\x67\x6d\x65\x6e\x74\x65\x64\x20\x3d\x20\x74\x72\x75\x65\
770
+\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x2a\x6c\x34\x5f\x6f\x66\x66\x73\x65\x74\
771
+\x20\x2b\x3d\x20\x28\x65\x78\x74\x5f\x68\x64\x72\x2e\x68\x64\x72\x6c\x65\x6e\
772
+\x20\x2b\x20\x31\x29\x20\x2a\x20\x38\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x2a\
773
+\x6c\x34\x5f\x70\x72\x6f\x74\x6f\x63\x6f\x6c\x20\x3d\x20\x65\x78\x74\x5f\x68\
774
+\x64\x72\x2e\x6e\x65\x78\x74\x68\x64\x72\x3b\0\x20\x20\x20\x20\x66\x6f\x72\x20\
775
+\x28\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\x20\x69\x20\x3d\x20\x30\
776
+\x3b\x20\x69\x20\x3c\x20\x49\x50\x36\x5f\x45\x58\x54\x45\x4e\x53\x49\x4f\x4e\
777
+\x53\x5f\x43\x4f\x55\x4e\x54\x3b\x20\x2b\x2b\x69\x29\x20\x7b\0\x20\x20\x20\x20\
778
+\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\
779
+\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x36\x29\x20\x7b\0\x20\x20\x20\x20\x20\
780
+\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\
781
+\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x36\x5f\x65\x78\x74\x5f\x64\x73\x74\
782
+\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\
783
+\x70\x61\x63\x6b\x65\x74\x5f\x69\x6e\x66\x6f\x2e\x69\x73\x5f\x69\x70\x76\x36\
784
+\x5f\x65\x78\x74\x5f\x73\x72\x63\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\x20\x20\
785
+\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\x28\x70\x61\x63\x6b\x65\x74\x5f\x69\
786
+\x6e\x66\x6f\x2e\x69\x73\x5f\x75\x64\x70\x20\x26\x26\0\x20\x20\x20\x20\x20\x20\
787
\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\x69\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\
788
\x2d\x3e\x68\x61\x73\x68\x5f\x74\x79\x70\x65\x73\x20\x26\x20\x56\x49\x52\x54\
789
\x49\x4f\x5f\x4e\x45\x54\x5f\x52\x53\x53\x5f\x48\x41\x53\x48\x5f\x54\x59\x50\
790
-\x45\x5f\x49\x50\x76\x36\x29\x20\x7b\0\x20\x20\x20\x20\x66\x6f\x72\x20\x28\x62\
791
-\x79\x74\x65\x20\x3d\x20\x30\x3b\x20\x62\x79\x74\x65\x20\x3c\x20\x48\x41\x53\
792
-\x48\x5f\x43\x41\x4c\x43\x55\x4c\x41\x54\x49\x4f\x4e\x5f\x42\x55\x46\x46\x45\
793
-\x52\x5f\x53\x49\x5a\x45\x3b\x20\x62\x79\x74\x65\x2b\x2b\x29\x20\x7b\0\x20\x20\
794
-\x20\x20\x5f\x5f\x75\x33\x32\x20\x6c\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\
795
-\x5f\x62\x69\x74\x73\x20\x3d\x20\x6b\x65\x79\x2d\x3e\x6c\x65\x66\x74\x6d\x6f\
796
-\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
797
-\x5f\x5f\x75\x38\x20\x69\x6e\x70\x75\x74\x5f\x62\x79\x74\x65\x20\x3d\x20\x69\
798
-\x6e\x70\x75\x74\x5b\x62\x79\x74\x65\x5d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
799
-\x20\x20\x20\x20\x69\x66\x20\x28\x69\x6e\x70\x75\x74\x5f\x62\x79\x74\x65\x20\
800
-\x26\x20\x28\x31\x20\x3c\x3c\x20\x37\x29\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\
801
-\x20\x20\x5f\x5f\x75\x38\x20\x6b\x65\x79\x5f\x62\x79\x74\x65\x20\x3d\x20\x6b\
802
-\x65\x79\x2d\x3e\x6e\x65\x78\x74\x5f\x62\x79\x74\x65\x5b\x62\x79\x74\x65\x5d\
803
-\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
804
-\x20\x20\x28\x6c\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\
805
-\x20\x3c\x3c\x20\x31\x29\x20\x7c\x20\x28\x28\x6b\x65\x79\x5f\x62\x79\x74\x65\
806
-\x20\x26\x20\x28\x31\x20\x3c\x3c\x20\x37\x29\x29\x20\x3e\x3e\x20\x37\x29\x3b\0\
807
-\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x68\x61\x73\x68\x29\x20\x7b\0\
808
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x74\
809
-\x61\x62\x6c\x65\x5f\x69\x64\x78\x20\x3d\x20\x68\x61\x73\x68\x20\x25\x20\x63\
810
-\x6f\x6e\x66\x69\x67\x2d\x3e\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x73\
811
-\x5f\x6c\x65\x6e\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x71\x75\
812
-\x65\x75\x65\x20\x3d\x20\x62\x70\x66\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\
813
-\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
814
-\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\x2c\0\
815
-\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x71\x75\x65\
816
-\x75\x65\x29\x20\x7b\0\x7d\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
817
-\x20\x20\x20\x20\x72\x65\x74\x75\x72\x6e\x20\x2a\x71\x75\x65\x75\x65\x3b\0\x63\
818
-\x68\x61\x72\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x6d\x61\x70\x73\0\x6c\x69\
819
-\x63\x65\x6e\x73\x65\0\x62\x70\x66\x5f\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\
820
-\x62\x70\x66\x5f\x73\x6f\x63\x6b\0\0\0\0\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x14\0\
821
-\0\0\x14\0\0\0\x6c\x0c\0\0\x80\x0c\0\0\0\0\0\0\x08\0\0\0\x26\x02\0\0\x01\0\0\0\
822
-\0\0\0\0\x24\0\0\0\x10\0\0\0\x26\x02\0\0\xc6\0\0\0\0\0\0\0\x37\x02\0\0\x61\x02\
823
-\0\0\0\x50\x08\0\x10\0\0\0\x37\x02\0\0\x92\x02\0\0\x0b\x68\x08\0\x20\0\0\0\x37\
824
-\x02\0\0\0\0\0\0\0\0\0\0\x28\0\0\0\x37\x02\0\0\xa5\x02\0\0\x0e\x74\x08\0\x50\0\
825
-\0\0\x37\x02\0\0\xea\x02\0\0\x0b\x78\x08\0\x88\0\0\0\x37\x02\0\0\x2a\x03\0\0\
826
-\x10\x80\x08\0\x90\0\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x98\0\0\0\x37\x02\0\0\x2a\
827
-\x03\0\0\x10\x80\x08\0\xa0\0\0\0\x37\x02\0\0\x43\x03\0\0\x16\x84\x08\0\xa8\0\0\
828
-\0\x37\x02\0\0\x43\x03\0\0\x0d\x84\x08\0\xc0\0\0\0\x37\x02\0\0\x64\x03\0\0\x0a\
829
-\xfc\x05\0\xe8\0\0\0\x37\x02\0\0\x9b\x03\0\0\x1f\x0c\x06\0\x38\x01\0\0\x37\x02\
830
-\0\0\xcb\x03\0\0\x0f\xa0\x04\0\x40\x01\0\0\x37\x02\0\0\xe4\x03\0\0\x0c\x20\x04\
831
-\0\x50\x01\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x58\x01\0\0\x37\x02\0\0\xf8\x03\0\0\
832
-\x0b\x2c\x04\0\x90\x01\0\0\x37\x02\0\0\x3e\x04\0\0\x09\x34\x04\0\xa0\x01\0\0\
833
-\x37\x02\0\0\x4d\x04\0\0\x0d\x44\x04\0\xb8\x01\0\0\x37\x02\0\0\x4d\x04\0\0\x05\
834
-\x44\x04\0\xd8\x01\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xe0\x01\0\0\x37\x02\0\0\x6b\
835
-\x04\0\0\x0f\x58\x04\0\x10\x02\0\0\x37\x02\0\0\x3e\x04\0\0\x09\x70\x04\0\x18\
836
-\x02\0\0\x37\x02\0\0\xb5\x04\0\0\x0c\x80\x04\0\x20\x02\0\0\x37\x02\0\0\xc5\x04\
837
-\0\0\x09\xbc\x04\0\x50\x02\0\0\x37\x02\0\0\xe1\x04\0\0\x17\xd4\x04\0\x60\x02\0\
838
-\0\x37\x02\0\0\xfc\x04\0\0\x16\xdc\x04\0\x80\x02\0\0\x37\x02\0\0\xe1\x04\0\0\
839
-\x17\xd4\x04\0\x88\x02\0\0\x37\x02\0\0\x1a\x05\0\0\x0f\xe0\x04\0\xc0\x02\0\0\
840
-\x37\x02\0\0\x5d\x05\0\0\x0d\xe8\x04\0\xc8\x02\0\0\x37\x02\0\0\x70\x05\0\0\x24\
841
-\0\x05\0\xd0\x02\0\0\x37\x02\0\0\x70\x05\0\0\x20\0\x05\0\xe0\x02\0\0\x37\x02\0\
842
-\0\x9d\x05\0\0\x1b\xf8\x04\0\xe8\x02\0\0\x37\x02\0\0\x9d\x05\0\0\x16\xf8\x04\0\
843
-\xf0\x02\0\0\x37\x02\0\0\xbe\x05\0\0\x1b\xfc\x04\0\xf8\x02\0\0\x37\x02\0\0\xbe\
844
-\x05\0\0\x16\xfc\x04\0\0\x03\0\0\x37\x02\0\0\xdf\x05\0\0\x1a\x08\x05\0\x08\x03\
845
-\0\0\x37\x02\0\0\x70\x05\0\0\x1d\0\x05\0\x10\x03\0\0\x37\x02\0\0\x02\x06\0\0\
846
-\x18\x0c\x05\0\x18\x03\0\0\x37\x02\0\0\x02\x06\0\0\x1c\x0c\x05\0\x30\x03\0\0\
847
-\x37\x02\0\0\x22\x06\0\0\x15\x68\x05\0\x40\x03\0\0\x37\x02\0\0\x22\x06\0\0\x1a\
848
-\x68\x05\0\x58\x03\0\0\x37\x02\0\0\x56\x06\0\0\x0d\x6c\x05\0\x78\x03\0\0\x37\
849
-\x02\0\0\x80\x06\0\0\x1a\x70\x05\0\x88\x03\0\0\x37\x02\0\0\x9e\x06\0\0\x1b\x78\
850
-\x05\0\xa8\x03\0\0\x37\x02\0\0\x80\x06\0\0\x1a\x70\x05\0\xb0\x03\0\0\x37\x02\0\
851
-\0\xc2\x06\0\0\x13\x7c\x05\0\xe8\x03\0\0\x37\x02\0\0\x13\x07\0\0\x11\x84\x05\0\
852
-\xf0\x03\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x10\x04\0\0\x37\x02\0\0\x2a\x07\0\0\
853
-\x15\x28\x06\0\x18\x04\0\0\x37\x02\0\0\x2a\x07\0\0\x09\x28\x06\0\x20\x04\0\0\
854
-\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x04\0\0\x37\x02\0\0\x49\x07\0\0\x19\x2c\x06\0\
855
-\x80\x04\0\0\x37\x02\0\0\x49\x07\0\0\x20\x2c\x06\0\xa0\x04\0\0\x37\x02\0\0\0\0\
856
-\0\0\0\0\0\0\xf0\x04\0\0\x37\x02\0\0\x6b\x07\0\0\x17\x14\x05\0\0\x05\0\0\x37\
857
-\x02\0\0\x86\x07\0\0\x18\x1c\x05\0\x30\x05\0\0\x37\x02\0\0\x6b\x07\0\0\x17\x14\
858
-\x05\0\x48\x05\0\0\x37\x02\0\0\xa7\x07\0\0\x0f\x20\x05\0\x80\x05\0\0\x37\x02\0\
859
-\0\x5d\x05\0\0\x0d\x28\x05\0\x88\x05\0\0\x37\x02\0\0\xec\x07\0\0\x1d\x38\x05\0\
860
-\xc8\x05\0\0\x37\x02\0\0\x0f\x08\0\0\x1d\x3c\x05\0\x08\x06\0\0\x37\x02\0\0\x32\
861
-\x08\0\0\x1b\x44\x05\0\x10\x06\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\x58\
862
-\x06\0\0\x37\x02\0\0\x6d\x08\0\0\x19\xb8\x02\0\xd0\x06\0\0\x37\x02\0\0\0\0\0\0\
863
-\0\0\0\0\xd8\x06\0\0\x37\x02\0\0\x93\x08\0\0\x0f\xc8\x02\0\x10\x07\0\0\x37\x02\
864
-\0\0\x5d\x05\0\0\x0d\xd0\x02\0\x20\x07\0\0\x37\x02\0\0\xd8\x08\0\0\x0d\xe0\x02\
865
-\0\x40\x07\0\0\x37\x02\0\0\x07\x09\0\0\x20\xe4\x02\0\x68\x07\0\0\x37\x02\0\0\
866
-\x33\x09\0\0\x13\xec\x02\0\xa8\x07\0\0\x37\x02\0\0\x13\x07\0\0\x11\xf4\x02\0\
867
-\xb0\x07\0\0\x37\x02\0\0\x7b\x09\0\0\x19\x04\x03\0\xb8\x07\0\0\x37\x02\0\0\x7b\
868
-\x09\0\0\x34\x04\x03\0\xe0\x07\0\0\x37\x02\0\0\xb1\x09\0\0\x15\x18\x03\0\xf0\
869
-\x07\0\0\x37\x02\0\0\xf2\x09\0\0\x17\x14\x03\0\x30\x08\0\0\x37\x02\0\0\x29\x0a\
870
-\0\0\x15\x24\x03\0\x38\x08\0\0\x37\x02\0\0\x44\x0a\0\0\x27\x34\x03\0\x70\x08\0\
871
-\0\x37\x02\0\0\x6f\x0a\0\0\x27\x50\x03\0\x80\x08\0\0\x37\x02\0\0\x9f\x0a\0\0\
872
-\x1c\xb4\x03\0\x88\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x20\xc0\x03\0\x98\x08\0\0\
873
-\x37\x02\0\0\xdb\x0a\0\0\x2f\xc0\x03\0\xa0\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x36\
874
-\xc0\x03\0\xa8\x08\0\0\x37\x02\0\0\xdb\x0a\0\0\x15\xc0\x03\0\x18\x09\0\0\x37\
875
-\x02\0\0\x17\x0b\0\0\x43\x64\x03\0\x38\x09\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x40\
876
-\x09\0\0\x37\x02\0\0\x17\x0b\0\0\x17\x64\x03\0\x80\x09\0\0\x37\x02\0\0\x29\x0a\
877
-\0\0\x15\x6c\x03\0\x88\x09\0\0\x37\x02\0\0\x67\x0b\0\0\x19\x7c\x03\0\x90\x09\0\
878
-\0\x37\x02\0\0\x67\x0b\0\0\x15\x7c\x03\0\x98\x09\0\0\x37\x02\0\0\x97\x0b\0\0\
879
-\x19\x84\x03\0\xa0\x09\0\0\x37\x02\0\0\xc7\x0b\0\0\x1b\x80\x03\0\xe8\x09\0\0\
880
-\x37\x02\0\0\x02\x0c\0\0\x19\x94\x03\0\xf0\x09\0\0\x37\x02\0\0\x21\x0c\0\0\x2b\
881
-\xa4\x03\0\x10\x0a\0\0\x37\x02\0\0\x9f\x0a\0\0\x1f\xb4\x03\0\x30\x0a\0\0\x37\
882
-\x02\0\0\x50\x0c\0\0\x21\xd4\x03\0\x40\x0a\0\0\x37\x02\0\0\x78\x0c\0\0\x20\xe4\
883
-\x03\0\x48\x0a\0\0\x37\x02\0\0\x78\x0c\0\0\x2c\xe4\x03\0\x60\x0a\0\0\x37\x02\0\
884
-\0\x78\x0c\0\0\x14\xe4\x03\0\x70\x0a\0\0\x37\x02\0\0\xa8\x0c\0\0\x20\xe0\x03\0\
885
-\x80\x0a\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xb0\x0a\0\0\x37\x02\0\0\xd0\
886
-\x0c\0\0\x38\xc0\x02\0\xd0\x0a\0\0\x37\x02\0\0\xd0\x0c\0\0\x05\xc0\x02\0\xe8\
887
-\x0a\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xf8\x0a\0\0\x37\x02\0\0\x0e\x0d\
888
-\0\0\x1c\xc4\x06\0\x08\x0b\0\0\x37\x02\0\0\x0e\x0d\0\0\x10\xc4\x06\0\x10\x0b\0\
889
-\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x60\x0b\0\0\x37\x02\0\0\x49\x07\0\0\x19\xc8\x06\
890
-\0\x68\x0b\0\0\x37\x02\0\0\x49\x07\0\0\x20\xc8\x06\0\xa0\x0b\0\0\x37\x02\0\0\
891
-\x34\x0d\0\0\x2d\0\x07\0\xb0\x0b\0\0\x37\x02\0\0\x34\x0d\0\0\x1d\0\x07\0\xb8\
892
-\x0b\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\0\x07\0\xc8\x0b\0\0\x37\x02\0\0\x63\x0d\0\
893
-\0\x2d\xd4\x06\0\xf8\x0b\0\0\x37\x02\0\0\x63\x0d\0\0\x1d\xd4\x06\0\x08\x0c\0\0\
894
-\x37\x02\0\0\x63\x0d\0\0\x2d\xd4\x06\0\x18\x0c\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\
895
-\xe8\x0c\0\0\x37\x02\0\0\x92\x0d\0\0\x20\x68\x06\0\xf0\x0c\0\0\x37\x02\0\0\x92\
896
-\x0d\0\0\x27\x68\x06\0\x18\x0d\0\0\x37\x02\0\0\xbb\x0d\0\0\x27\xa4\x06\0\x20\
897
-\x0d\0\0\x37\x02\0\0\xbb\x0d\0\0\x14\xa4\x06\0\x28\x0d\0\0\x37\x02\0\0\x04\x0e\
898
-\0\0\x05\x98\x01\0\x38\x0d\0\0\x37\x02\0\0\x04\x0e\0\0\x05\x98\x01\0\x60\x0d\0\
899
-\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x0d\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x80\x0d\
900
-\0\0\x37\x02\0\0\x92\x0d\0\0\x20\x44\x07\0\x88\x0d\0\0\x37\x02\0\0\x92\x0d\0\0\
901
-\x27\x44\x07\0\xc0\x0d\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\x7c\x07\0\xd0\x0d\0\0\
902
-\x37\x02\0\0\x34\x0d\0\0\x1d\x7c\x07\0\xd8\x0d\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\
903
-\x7c\x07\0\xe8\x0d\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\x50\x07\0\x18\x0e\0\0\x37\
904
-\x02\0\0\x63\x0d\0\0\x1d\x50\x07\0\x28\x0e\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\x50\
905
-\x07\0\x40\x0e\0\0\x37\x02\0\0\x41\x0e\0\0\x1a\xa0\x05\0\x50\x0e\0\0\x37\x02\0\
906
-\0\x5f\x0e\0\0\x1b\xa8\x05\0\x60\x0e\0\0\x37\x02\0\0\x41\x0e\0\0\x1a\xa0\x05\0\
907
-\x68\x0e\0\0\x37\x02\0\0\x83\x0e\0\0\x13\xac\x05\0\xa0\x0e\0\0\x37\x02\0\0\x13\
908
-\x07\0\0\x11\xb4\x05\0\xb0\x0e\0\0\x37\x02\0\0\x55\x08\0\0\x05\x30\x02\0\xc0\
909
-\x0e\0\0\x37\x02\0\0\xd4\x0e\0\0\x27\xc8\x07\0\xd0\x0e\0\0\x37\x02\0\0\xd4\x0e\
910
-\0\0\x14\xc8\x07\0\xf0\x0e\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\xcc\x07\0\0\x0f\0\0\
911
-\x37\x02\0\0\x63\x0d\0\0\x1d\xcc\x07\0\x08\x0f\0\0\x37\x02\0\0\x63\x0d\0\0\x2d\
912
-\xcc\x07\0\x30\x0f\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x80\x0f\0\0\x37\x02\0\0\x34\
913
-\x0d\0\0\x1d\xf8\x07\0\x88\x0f\0\0\x37\x02\0\0\x34\x0d\0\0\x2d\xf8\x07\0\x98\
914
-\x0f\0\0\x37\x02\0\0\x04\x0e\0\0\x05\x98\x01\0\xf0\x0f\0\0\x37\x02\0\0\x04\x0e\
915
-\0\0\x05\x98\x01\0\x30\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x48\x10\0\0\x37\x02\
916
-\0\0\x1d\x0f\0\0\x05\xd0\x01\0\x50\x10\0\0\x37\x02\0\0\x5f\x0f\0\0\x23\xc4\x01\
917
-\0\x68\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x10\0\0\x37\x02\0\0\x93\x0f\0\0\
918
-\x1b\xd4\x01\0\x90\x10\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xa8\x10\0\0\
919
-\x37\x02\0\0\xe3\x0f\0\0\x19\xd8\x01\0\xc0\x10\0\0\x37\x02\0\0\x11\x10\0\0\x27\
920
-\xfc\x01\0\xc8\x10\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xd8\x10\0\0\x37\
921
-\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xe0\x10\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\
922
-\x01\0\x08\x11\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x20\x11\0\0\x37\x02\0\
923
-\0\x11\x10\0\0\x27\xfc\x01\0\x28\x11\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\
924
-\x30\x11\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\x58\x11\0\0\x37\x02\0\0\x11\
925
-\x10\0\0\x27\xfc\x01\0\x60\x11\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x78\
926
-\x11\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\x80\x11\0\0\x37\x02\0\0\xba\x0f\
927
-\0\0\x11\xe8\x01\0\xa8\x11\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\xb0\x11\0\
928
-\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xc8\x11\0\0\x37\x02\0\0\x11\x10\0\0\
929
-\x2d\xfc\x01\0\xd0\x11\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xf8\x11\0\0\
930
-\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\x10\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\
931
-\xfc\x01\0\x18\x12\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\x20\x12\0\0\x37\
932
-\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\x48\x12\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\
933
-\x01\0\x60\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\x68\x12\0\0\x37\x02\0\
934
-\0\x11\x10\0\0\x2d\xfc\x01\0\x70\x12\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\
935
-\x98\x12\0\0\x37\x02\0\0\x11\x10\0\0\x46\xfc\x01\0\xb0\x12\0\0\x37\x02\0\0\x11\
936
-\x10\0\0\x27\xfc\x01\0\xb8\x12\0\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xc0\
937
-\x12\0\0\x37\x02\0\0\xba\x0f\0\0\x11\xe8\x01\0\xe0\x12\0\0\x37\x02\0\0\x11\x10\
938
-\0\0\x46\xfc\x01\0\xe8\x12\0\0\x37\x02\0\0\x11\x10\0\0\x27\xfc\x01\0\xf0\x12\0\
939
-\0\x37\x02\0\0\x11\x10\0\0\x2d\xfc\x01\0\xf8\x12\0\0\x37\x02\0\0\x1d\x0f\0\0\
940
-\x3d\xd0\x01\0\x08\x13\0\0\x37\x02\0\0\x1d\x0f\0\0\x05\xd0\x01\0\x18\x13\0\0\
941
-\x37\x02\0\0\x5d\x10\0\0\x0d\x98\x08\0\x30\x13\0\0\x37\x02\0\0\x5d\x10\0\0\x0d\
942
-\x98\x08\0\x38\x13\0\0\x37\x02\0\0\x71\x10\0\0\x2e\x9c\x08\0\x58\x13\0\0\x37\
943
-\x02\0\0\x71\x10\0\0\x24\x9c\x08\0\x70\x13\0\0\x37\x02\0\0\x71\x10\0\0\x13\x9c\
944
-\x08\0\x80\x13\0\0\x37\x02\0\0\x71\x10\0\0\x2e\x9c\x08\0\x88\x13\0\0\x37\x02\0\
945
-\0\xb0\x10\0\0\x15\xa8\x08\0\xa0\x13\0\0\x37\x02\0\0\xf8\x10\0\0\x11\xb4\x08\0\
946
-\xa8\x13\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xc8\x13\0\0\x37\x02\0\0\x11\x11\0\0\
947
-\x01\xd8\x08\0\xd0\x13\0\0\x37\x02\0\0\x13\x11\0\0\x18\xb8\x08\0\0\0\0\0\0\0\0\
948
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\
949
-\0\0\0\0\xde\0\0\0\0\0\x03\0\xc8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7a\x01\0\0\0\
950
-\0\x03\0\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\0\0\x03\0\xa8\x13\0\0\0\0\
951
-\0\0\0\0\0\0\0\0\0\0\xc7\0\0\0\0\0\x03\0\xd0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
952
-\x2c\x02\0\0\0\0\x03\0\x20\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf7\0\0\0\0\0\x03\0\
953
-\xe8\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1c\x02\0\0\0\0\x03\0\x10\x04\0\0\0\0\0\0\
954
-\0\0\0\0\0\0\0\0\x28\x01\0\0\0\0\x03\0\xe0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf3\
955
-\x01\0\0\0\0\x03\0\x30\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xeb\x01\0\0\0\0\x03\0\
956
-\x38\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x44\x02\0\0\0\0\x03\0\xf0\x03\0\0\0\0\0\0\
957
-\0\0\0\0\0\0\0\0\xe3\x01\0\0\0\0\x03\0\xf8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x18\
958
-\x01\0\0\0\0\x03\0\xe8\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x30\x01\0\0\0\0\x03\0\
959
-\xa0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa9\x01\0\0\0\0\x03\0\x40\x10\0\0\0\0\0\0\
960
-\0\0\0\0\0\0\0\0\x51\x01\0\0\0\0\x03\0\x78\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5c\
961
-\x02\0\0\0\0\x03\0\xb0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\x02\0\0\0\0\x03\0\
962
-\x50\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc2\x01\0\0\0\0\x03\0\xc0\x06\0\0\0\0\0\0\
963
-\0\0\0\0\0\0\0\0\x69\x01\0\0\0\0\x03\0\x20\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x61\
964
-\x01\0\0\0\0\x03\0\x60\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x38\x01\0\0\0\0\x03\0\
965
-\x30\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x01\0\0\0\0\x03\0\x40\x0a\0\0\0\0\0\0\
966
-\0\0\0\0\0\0\0\0\xba\x01\0\0\0\0\x03\0\xe0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa1\
967
-\x01\0\0\0\0\x03\0\x48\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x01\0\0\0\0\x03\0\
968
-\x18\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xfb\x01\0\0\0\0\x03\0\x80\x08\0\0\0\0\0\0\
969
-\0\0\0\0\0\0\0\0\x99\x01\0\0\0\0\x03\0\xf8\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x59\
970
-\x01\0\0\0\0\x03\0\x50\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x54\x02\0\0\0\0\x03\0\
971
-\x08\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xef\0\0\0\0\0\x03\0\xe8\x0a\0\0\0\0\0\0\0\
972
-\0\0\0\0\0\0\0\x4c\x02\0\0\0\0\x03\0\xb0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x24\
973
-\x02\0\0\0\0\x03\0\xd8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x89\x01\0\0\0\0\x03\0\
974
-\x80\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x01\0\0\0\0\x03\0\xb0\x0b\0\0\0\0\0\0\
975
-\0\0\0\0\0\0\0\0\xd6\0\0\0\0\0\x03\0\xc8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\
976
-\x02\0\0\0\0\x03\0\xf8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb2\x01\0\0\0\0\x03\0\
977
-\x18\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xdb\x01\0\0\0\0\x03\0\x10\x0c\0\0\0\0\0\0\
978
-\0\0\0\0\0\0\0\0\x3c\x02\0\0\0\0\x03\0\x18\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x91\
979
-\x01\0\0\0\0\x03\0\x60\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x81\x01\0\0\0\0\x03\0\
980
-\xc0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe7\0\0\0\0\0\x03\0\xd0\x0d\0\0\0\0\0\0\0\
981
-\0\0\0\0\0\0\0\x34\x02\0\0\0\0\x03\0\xe8\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd3\
982
-\x01\0\0\0\0\x03\0\x18\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x01\0\0\0\0\x03\0\0\
983
-\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xce\0\0\0\0\0\x03\0\x18\x0f\0\0\0\0\0\0\0\0\0\
984
-\0\0\0\0\0\x0b\x02\0\0\0\0\x03\0\xf0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xca\x01\0\
985
-\0\0\0\x03\0\x30\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x71\x01\0\0\0\0\x03\0\x60\x10\
986
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\x01\0\0\0\0\x03\0\x18\x13\0\0\0\0\0\0\0\0\0\0\
987
-\0\0\0\0\x64\x02\0\0\0\0\x03\0\xd0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4e\0\0\0\
988
-\x12\0\x03\0\0\0\0\0\0\0\0\0\xe0\x13\0\0\0\0\0\0\x33\0\0\0\x11\0\x05\0\0\0\0\0\
989
-\0\0\0\0\x20\0\0\0\0\0\0\0\x01\0\0\0\x11\0\x05\0\x20\0\0\0\0\0\0\0\x20\0\0\0\0\
990
-\0\0\0\x90\0\0\0\x11\0\x05\0\x40\0\0\0\0\0\0\0\x20\0\0\0\0\0\0\0\x87\0\0\0\x11\
991
-\0\x06\0\0\0\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\x28\0\0\0\0\0\0\0\x01\0\0\0\x37\0\0\
992
-\0\x50\0\0\0\0\0\0\0\x01\0\0\0\x38\0\0\0\x88\x13\0\0\0\0\0\0\x01\0\0\0\x39\0\0\
993
-\0\xd8\x04\0\0\0\0\0\0\x04\0\0\0\x37\0\0\0\xe4\x04\0\0\0\0\0\0\x04\0\0\0\x38\0\
994
-\0\0\xf0\x04\0\0\0\0\0\0\x04\0\0\0\x39\0\0\0\x08\x05\0\0\0\0\0\0\x04\0\0\0\x3a\
995
-\0\0\0\x2c\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\0\0\0\0\0\0\0\x04\0\0\0\x01\0\
996
-\0\0\x50\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
997
-\0\x70\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
998
-\x90\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
999
-\xb0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1000
-\xd0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1001
-\xf0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1002
-\x10\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1003
-\0\x30\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\
1004
-\0\0\x50\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x01\0\0\0\0\0\0\x04\0\0\0\x01\
1005
-\0\0\0\x70\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x01\0\0\0\0\0\0\x04\0\0\0\
1006
-\x01\0\0\0\x90\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x01\0\0\0\0\0\0\x04\0\0\
1007
-\0\x01\0\0\0\xb0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x01\0\0\0\0\0\0\x04\0\
1008
-\0\0\x01\0\0\0\xd0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x01\0\0\0\0\0\0\x04\
1009
-\0\0\0\x01\0\0\0\xf0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x02\0\0\0\0\0\0\x04\
1010
-\0\0\0\x01\0\0\0\x10\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x02\0\0\0\0\0\0\
1011
-\x04\0\0\0\x01\0\0\0\x30\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x02\0\0\0\0\0\
1012
-\0\x04\0\0\0\x01\0\0\0\x50\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x02\0\0\0\0\
1013
-\0\0\x04\0\0\0\x01\0\0\0\x70\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x02\0\0\0\
1014
-\0\0\0\x04\0\0\0\x01\0\0\0\x90\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x02\0\0\
1015
-\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x02\0\
1016
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x02\
1017
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x03\
1018
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\
1019
-\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1020
-\x40\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1021
-\0\x60\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\
1022
-\0\0\x80\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x03\0\0\0\0\0\0\x04\0\0\0\x01\
1023
-\0\0\0\xa0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x03\0\0\0\0\0\0\x04\0\0\0\
1024
-\x01\0\0\0\xc0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x03\0\0\0\0\0\0\x04\0\0\
1025
-\0\x01\0\0\0\xe0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x03\0\0\0\0\0\0\x04\0\
1026
-\0\0\x01\0\0\0\0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x04\0\0\0\0\0\0\x04\0\
1027
-\0\0\x01\0\0\0\x20\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x04\0\0\0\0\0\0\x04\
1028
-\0\0\0\x01\0\0\0\x40\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x04\0\0\0\0\0\0\
1029
-\x04\0\0\0\x01\0\0\0\x60\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x04\0\0\0\0\0\
1030
-\0\x04\0\0\0\x01\0\0\0\x80\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x04\0\0\0\0\
1031
-\0\0\x04\0\0\0\x01\0\0\0\xa0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x04\0\0\0\
1032
-\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x04\0\0\
1033
-\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x04\0\
1034
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x05\0\
1035
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x05\
1036
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\
1037
-\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1038
-\x70\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1039
-\0\x90\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\
1040
-\0\0\xb0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x05\0\0\0\0\0\0\x04\0\0\0\x01\
1041
-\0\0\0\xd0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x05\0\0\0\0\0\0\x04\0\0\0\
1042
-\x01\0\0\0\xf0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x06\0\0\0\0\0\0\x04\0\0\0\
1043
-\x01\0\0\0\x10\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x06\0\0\0\0\0\0\x04\0\0\
1044
-\0\x01\0\0\0\x30\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x06\0\0\0\0\0\0\x04\0\
1045
-\0\0\x01\0\0\0\x50\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x06\0\0\0\0\0\0\x04\
1046
-\0\0\0\x01\0\0\0\x70\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x06\0\0\0\0\0\0\
1047
-\x04\0\0\0\x01\0\0\0\x90\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x06\0\0\0\0\0\
1048
-\0\x04\0\0\0\x01\0\0\0\xb0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x06\0\0\0\0\
1049
-\0\0\x04\0\0\0\x01\0\0\0\xd0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x06\0\0\0\
1050
-\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x07\0\0\0\
1051
-\0\0\0\x04\0\0\0\x01\0\0\0\x10\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x07\0\0\
1052
-\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x07\0\
1053
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x07\
1054
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\
1055
-\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1056
-\xa0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1057
-\0\xc0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\
1058
-\0\0\xe0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x07\0\0\0\0\0\0\x04\0\0\0\x01\
1059
-\0\0\0\0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x08\0\0\0\0\0\0\x04\0\0\0\x01\
1060
-\0\0\0\x20\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x08\0\0\0\0\0\0\x04\0\0\0\
1061
-\x01\0\0\0\x40\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x08\0\0\0\0\0\0\x04\0\0\
1062
-\0\x01\0\0\0\x60\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x08\0\0\0\0\0\0\x04\0\
1063
-\0\0\x01\0\0\0\x80\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x08\0\0\0\0\0\0\x04\
1064
-\0\0\0\x01\0\0\0\xa0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x08\0\0\0\0\0\0\
1065
-\x04\0\0\0\x01\0\0\0\xc0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x08\0\0\0\0\0\
1066
-\0\x04\0\0\0\x01\0\0\0\xe0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x08\0\0\0\0\
1067
-\0\0\x04\0\0\0\x01\0\0\0\0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x09\0\0\0\0\
1068
-\0\0\x04\0\0\0\x01\0\0\0\x20\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x09\0\0\0\
1069
-\0\0\0\x04\0\0\0\x01\0\0\0\x40\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x09\0\0\
1070
-\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x09\0\
1071
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x09\
1072
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\
1073
-\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1074
-\xd0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1075
-\0\xf0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1076
-\0\x10\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\
1077
-\0\0\x30\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0a\0\0\0\0\0\0\x04\0\0\0\x01\
1078
-\0\0\0\x50\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x0a\0\0\0\0\0\0\x04\0\0\0\
1079
-\x01\0\0\0\x70\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0a\0\0\0\0\0\0\x04\0\0\
1080
-\0\x01\0\0\0\x90\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0a\0\0\0\0\0\0\x04\0\
1081
-\0\0\x01\0\0\0\xb0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x0a\0\0\0\0\0\0\x04\
1082
-\0\0\0\x01\0\0\0\xd0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x0a\0\0\0\0\0\0\
1083
-\x04\0\0\0\x01\0\0\0\xf0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0b\0\0\0\0\0\0\
1084
-\x04\0\0\0\x01\0\0\0\x10\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0b\0\0\0\0\0\
1085
-\0\x04\0\0\0\x01\0\0\0\x30\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0b\0\0\0\0\
1086
-\0\0\x04\0\0\0\x01\0\0\0\x50\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x0b\0\0\0\
1087
-\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0b\0\0\
1088
-\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0b\0\
1089
-\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x0b\
1090
-\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\
1091
-\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\
1092
-\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1093
-\x20\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1094
-\0\x40\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\
1095
-\0\0\x60\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0c\0\0\0\0\0\0\x04\0\0\0\x01\
1096
-\0\0\0\x80\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0c\0\0\0\0\0\0\x04\0\0\0\
1097
-\x01\0\0\0\x40\x41\x42\x43\x44\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\
1098
-\x5f\x74\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\0\x2e\x74\x65\x78\x74\0\
1099
-\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\0\x2e\x6d\x61\x70\x73\0\x74\
1100
-\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x63\x6f\x6e\x66\x69\x67\x75\x72\
1101
-\x61\x74\x69\x6f\x6e\x73\0\x74\x75\x6e\x5f\x72\x73\x73\x5f\x73\x74\x65\x65\x72\
1102
-\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x2e\x72\x65\x6c\x74\x75\x6e\x5f\x72\x73\x73\
1103
-\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\
1104
-\x73\x69\x67\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\x74\x61\x70\x5f\x72\x73\x73\
1105
-\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x5f\x74\x61\
1106
-\x62\x6c\x65\0\x2e\x73\x74\x72\x74\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\
1107
-\x72\x65\x6c\x2e\x42\x54\x46\0\x4c\x42\x42\x30\x5f\x39\0\x4c\x42\x42\x30\x5f\
1108
-\x39\x39\0\x4c\x42\x42\x30\x5f\x37\x39\0\x4c\x42\x42\x30\x5f\x31\x30\x39\0\x4c\
1109
-\x42\x42\x30\x5f\x38\x38\0\x4c\x42\x42\x30\x5f\x34\x38\0\x4c\x42\x42\x30\x5f\
1110
-\x31\x38\0\x4c\x42\x42\x30\x5f\x31\x30\x38\0\x4c\x42\x42\x30\x5f\x39\x37\0\x4c\
1111
-\x42\x42\x30\x5f\x37\x37\0\x4c\x42\x42\x30\x5f\x36\x37\0\x4c\x42\x42\x30\x5f\
1112
-\x34\x37\0\x4c\x42\x42\x30\x5f\x31\x37\0\x4c\x42\x42\x30\x5f\x36\x36\0\x4c\x42\
1113
-\x42\x30\x5f\x34\x36\0\x4c\x42\x42\x30\x5f\x33\x36\0\x4c\x42\x42\x30\x5f\x31\
1114
-\x30\x36\0\x4c\x42\x42\x30\x5f\x35\x35\0\x4c\x42\x42\x30\x5f\x34\x35\0\x4c\x42\
1115
-\x42\x30\x5f\x33\x35\0\x4c\x42\x42\x30\x5f\x32\x35\0\x4c\x42\x42\x30\x5f\x31\
1116
-\x30\x35\0\x4c\x42\x42\x30\x5f\x34\0\x4c\x42\x42\x30\x5f\x39\x34\0\x4c\x42\x42\
1117
-\x30\x5f\x38\x34\0\x4c\x42\x42\x30\x5f\x35\x34\0\x4c\x42\x42\x30\x5f\x34\x34\0\
1118
+\x45\x5f\x49\x50\x76\x34\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x62\x75\x69\x6c\
1119
+\x74\x69\x6e\x5f\x6d\x65\x6d\x63\x70\x79\x28\x26\x72\x73\x73\x5f\x69\x6e\x70\
1120
+\x75\x74\x5b\x2a\x62\x79\x74\x65\x73\x5f\x77\x72\x69\x74\x74\x65\x6e\x5d\x2c\
1121
+\x20\x70\x74\x72\x2c\x20\x73\x69\x7a\x65\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\
1122
+\x20\x20\x20\x20\x20\x69\x6e\x66\x6f\x2d\x3e\x69\x73\x5f\x75\x64\x70\x20\x3d\
1123
+\x20\x31\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x73\x74\x72\x75\
1124
+\x63\x74\x20\x75\x64\x70\x68\x64\x72\x20\x75\x64\x70\x20\x3d\x20\x7b\x7d\x3b\0\
1125
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x65\x72\x72\x20\x3d\x20\x62\
1126
+\x70\x66\x5f\x73\x6b\x62\x5f\x6c\x6f\x61\x64\x5f\x62\x79\x74\x65\x73\x5f\x72\
1127
+\x65\x6c\x61\x74\x69\x76\x65\x28\x73\x6b\x62\x2c\x20\x6c\x34\x5f\x6f\x66\x66\
1128
+\x73\x65\x74\x2c\x20\x26\x75\x64\x70\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x75\
1129
+\x64\x70\x29\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x7d\x20\x65\x6c\x73\x65\x20\
1130
+\x69\x66\x20\x28\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x68\x61\x73\x68\x5f\x74\x79\
1131
+\x70\x65\x73\x20\x26\x20\x56\x49\x52\x54\x49\x4f\x5f\x4e\x45\x54\x5f\x52\x53\
1132
+\x53\x5f\x48\x41\x53\x48\x5f\x54\x59\x50\x45\x5f\x49\x50\x76\x36\x29\x20\x7b\0\
1133
+\x20\x20\x20\x20\x66\x6f\x72\x20\x28\x62\x79\x74\x65\x20\x3d\x20\x30\x3b\x20\
1134
+\x62\x79\x74\x65\x20\x3c\x20\x48\x41\x53\x48\x5f\x43\x41\x4c\x43\x55\x4c\x41\
1135
+\x54\x49\x4f\x4e\x5f\x42\x55\x46\x46\x45\x52\x5f\x53\x49\x5a\x45\x3b\x20\x62\
1136
+\x79\x74\x65\x2b\x2b\x29\x20\x7b\0\x20\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x6c\
1137
+\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\x20\x3d\x20\x6b\
1138
+\x65\x79\x2d\x3e\x6c\x65\x66\x74\x6d\x6f\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\
1139
+\x73\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x5f\x5f\x75\x38\x20\x69\x6e\x70\x75\
1140
+\x74\x5f\x62\x79\x74\x65\x20\x3d\x20\x69\x6e\x70\x75\x74\x5b\x62\x79\x74\x65\
1141
+\x5d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x69\x66\x20\x28\x69\
1142
+\x6e\x70\x75\x74\x5f\x62\x79\x74\x65\x20\x26\x20\x28\x31\x20\x3c\x3c\x20\x37\
1143
+\x29\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x5f\x5f\x75\x38\x20\x6b\x65\
1144
+\x79\x5f\x62\x79\x74\x65\x20\x3d\x20\x6b\x65\x79\x2d\x3e\x6e\x65\x78\x74\x5f\
1145
+\x62\x79\x74\x65\x5b\x62\x79\x74\x65\x5d\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\
1146
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x28\x6c\x65\x66\x74\x6d\x6f\
1147
+\x73\x74\x5f\x33\x32\x5f\x62\x69\x74\x73\x20\x3c\x3c\x20\x31\x29\x20\x7c\x20\
1148
+\x28\x28\x6b\x65\x79\x5f\x62\x79\x74\x65\x20\x26\x20\x28\x31\x20\x3c\x3c\x20\
1149
+\x37\x29\x29\x20\x3e\x3e\x20\x37\x29\x3b\0\x20\x20\x20\x20\x20\x20\x20\x20\x69\
1150
+\x66\x20\x28\x68\x61\x73\x68\x29\x20\x7b\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\
1151
+\x20\x20\x20\x5f\x5f\x75\x33\x32\x20\x74\x61\x62\x6c\x65\x5f\x69\x64\x78\x20\
1152
+\x3d\x20\x68\x61\x73\x68\x20\x25\x20\x63\x6f\x6e\x66\x69\x67\x2d\x3e\x69\x6e\
1153
+\x64\x69\x72\x65\x63\x74\x69\x6f\x6e\x73\x5f\x6c\x65\x6e\x3b\0\x20\x20\x20\x20\
1154
+\x20\x20\x20\x20\x20\x20\x20\x20\x71\x75\x65\x75\x65\x20\x3d\x20\x62\x70\x66\
1155
+\x5f\x6d\x61\x70\x5f\x6c\x6f\x6f\x6b\x75\x70\x5f\x65\x6c\x65\x6d\x28\x26\x74\
1156
+\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\x74\
1157
+\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\x2c\0\x20\x20\x20\x20\x20\x20\x20\x20\x20\
1158
+\x20\x20\x20\x69\x66\x20\x28\x71\x75\x65\x75\x65\x29\x20\x7b\0\x7d\0\x20\x20\
1159
+\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x72\x65\x74\x75\x72\
1160
+\x6e\x20\x2a\x71\x75\x65\x75\x65\x3b\0\x63\x68\x61\x72\0\x5f\x6c\x69\x63\x65\
1161
+\x6e\x73\x65\0\x2e\x6d\x61\x70\x73\0\x6c\x69\x63\x65\x6e\x73\x65\0\x62\x70\x66\
1162
+\x5f\x66\x6c\x6f\x77\x5f\x6b\x65\x79\x73\0\x62\x70\x66\x5f\x73\x6f\x63\x6b\0\0\
1163
+\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x14\0\0\0\x14\0\0\0\x1c\x0d\0\0\x30\x0d\0\0\0\
1164
+\0\0\0\x08\0\0\0\x30\x02\0\0\x01\0\0\0\0\0\0\0\x26\0\0\0\x10\0\0\0\x30\x02\0\0\
1165
+\xd1\0\0\0\0\0\0\0\x37\x02\0\0\x67\x02\0\0\0\x5c\x08\0\x10\0\0\0\x37\x02\0\0\
1166
+\x98\x02\0\0\x0b\x74\x08\0\x20\0\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x28\0\0\0\x37\
1167
+\x02\0\0\xab\x02\0\0\x0e\x80\x08\0\x50\0\0\0\x37\x02\0\0\xf0\x02\0\0\x0b\x84\
1168
+\x08\0\x88\0\0\0\x37\x02\0\0\x30\x03\0\0\x10\x8c\x08\0\x90\0\0\0\x37\x02\0\0\0\
1169
+\0\0\0\0\0\0\0\x98\0\0\0\x37\x02\0\0\x30\x03\0\0\x10\x8c\x08\0\xa0\0\0\0\x37\
1170
+\x02\0\0\x49\x03\0\0\x16\x90\x08\0\xa8\0\0\0\x37\x02\0\0\x49\x03\0\0\x0d\x90\
1171
+\x08\0\xc0\0\0\0\x37\x02\0\0\x6a\x03\0\0\x0a\x08\x06\0\xe8\0\0\0\x37\x02\0\0\
1172
+\xa1\x03\0\0\x1f\x18\x06\0\x38\x01\0\0\x37\x02\0\0\xd1\x03\0\0\x0f\xac\x04\0\
1173
+\x40\x01\0\0\x37\x02\0\0\xea\x03\0\0\x0c\x2c\x04\0\x50\x01\0\0\x37\x02\0\0\0\0\
1174
+\0\0\0\0\0\0\x58\x01\0\0\x37\x02\0\0\xfe\x03\0\0\x0b\x38\x04\0\x80\x01\0\0\x37\
1175
+\x02\0\0\x44\x04\0\0\x09\x40\x04\0\x90\x01\0\0\x37\x02\0\0\x44\x04\0\0\x09\x40\
1176
+\x04\0\xa0\x01\0\0\x37\x02\0\0\x53\x04\0\0\x0d\x50\x04\0\xb8\x01\0\0\x37\x02\0\
1177
+\0\x53\x04\0\0\x05\x50\x04\0\xd8\x01\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xe0\x01\0\
1178
+\0\x37\x02\0\0\x71\x04\0\0\x0f\x64\x04\0\0\x02\0\0\x37\x02\0\0\x71\x04\0\0\x09\
1179
+\x64\x04\0\x10\x02\0\0\x37\x02\0\0\x44\x04\0\0\x09\x7c\x04\0\x18\x02\0\0\x37\
1180
+\x02\0\0\xbb\x04\0\0\x0c\x8c\x04\0\x20\x02\0\0\x37\x02\0\0\xcb\x04\0\0\x09\xc8\
1181
+\x04\0\x50\x02\0\0\x37\x02\0\0\xe7\x04\0\0\x17\xe0\x04\0\x60\x02\0\0\x37\x02\0\
1182
+\0\x02\x05\0\0\x16\xe8\x04\0\x80\x02\0\0\x37\x02\0\0\xe7\x04\0\0\x17\xe0\x04\0\
1183
+\x88\x02\0\0\x37\x02\0\0\x20\x05\0\0\x0f\xec\x04\0\xb0\x02\0\0\x37\x02\0\0\x63\
1184
+\x05\0\0\x0d\xf4\x04\0\xc0\x02\0\0\x37\x02\0\0\x63\x05\0\0\x0d\xf4\x04\0\xc8\
1185
+\x02\0\0\x37\x02\0\0\x76\x05\0\0\x24\x0c\x05\0\xd0\x02\0\0\x37\x02\0\0\x76\x05\
1186
+\0\0\x20\x0c\x05\0\xe0\x02\0\0\x37\x02\0\0\xa3\x05\0\0\x1b\x04\x05\0\xe8\x02\0\
1187
+\0\x37\x02\0\0\xa3\x05\0\0\x16\x04\x05\0\xf0\x02\0\0\x37\x02\0\0\xc4\x05\0\0\
1188
+\x1b\x08\x05\0\xf8\x02\0\0\x37\x02\0\0\xc4\x05\0\0\x16\x08\x05\0\0\x03\0\0\x37\
1189
+\x02\0\0\xe5\x05\0\0\x1a\x14\x05\0\x08\x03\0\0\x37\x02\0\0\x76\x05\0\0\x1d\x0c\
1190
+\x05\0\x10\x03\0\0\x37\x02\0\0\x08\x06\0\0\x18\x18\x05\0\x18\x03\0\0\x37\x02\0\
1191
+\0\x08\x06\0\0\x1c\x18\x05\0\x30\x03\0\0\x37\x02\0\0\x28\x06\0\0\x15\x74\x05\0\
1192
+\x40\x03\0\0\x37\x02\0\0\x28\x06\0\0\x1a\x74\x05\0\x58\x03\0\0\x37\x02\0\0\x5c\
1193
+\x06\0\0\x0d\x78\x05\0\x78\x03\0\0\x37\x02\0\0\x86\x06\0\0\x1a\x7c\x05\0\x88\
1194
+\x03\0\0\x37\x02\0\0\xa4\x06\0\0\x1b\x84\x05\0\xa8\x03\0\0\x37\x02\0\0\x86\x06\
1195
+\0\0\x1a\x7c\x05\0\xb0\x03\0\0\x37\x02\0\0\xc8\x06\0\0\x13\x88\x05\0\xd8\x03\0\
1196
+\0\x37\x02\0\0\x19\x07\0\0\x11\x90\x05\0\xe8\x03\0\0\x37\x02\0\0\x19\x07\0\0\
1197
+\x11\x90\x05\0\xf0\x03\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x10\x04\0\0\x37\x02\0\0\
1198
+\x30\x07\0\0\x15\x34\x06\0\x18\x04\0\0\x37\x02\0\0\x30\x07\0\0\x09\x34\x06\0\
1199
+\x20\x04\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x04\0\0\x37\x02\0\0\x4f\x07\0\0\
1200
+\x19\x38\x06\0\x80\x04\0\0\x37\x02\0\0\x4f\x07\0\0\x20\x38\x06\0\xa0\x04\0\0\
1201
+\x37\x02\0\0\0\0\0\0\0\0\0\0\xf0\x04\0\0\x37\x02\0\0\x71\x07\0\0\x17\x20\x05\0\
1202
+\0\x05\0\0\x37\x02\0\0\x8c\x07\0\0\x18\x28\x05\0\x30\x05\0\0\x37\x02\0\0\x71\
1203
+\x07\0\0\x17\x20\x05\0\x48\x05\0\0\x37\x02\0\0\xad\x07\0\0\x0f\x2c\x05\0\x70\
1204
+\x05\0\0\x37\x02\0\0\x63\x05\0\0\x0d\x34\x05\0\x80\x05\0\0\x37\x02\0\0\x63\x05\
1205
+\0\0\x0d\x34\x05\0\x88\x05\0\0\x37\x02\0\0\xf2\x07\0\0\x1d\x44\x05\0\xc8\x05\0\
1206
+\0\x37\x02\0\0\x15\x08\0\0\x1d\x48\x05\0\x08\x06\0\0\x37\x02\0\0\x38\x08\0\0\
1207
+\x1b\x50\x05\0\x10\x06\0\0\x37\x02\0\0\x5b\x08\0\0\x05\x3c\x02\0\x58\x06\0\0\
1208
+\x37\x02\0\0\x73\x08\0\0\x19\xc4\x02\0\xd0\x06\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\
1209
+\xd8\x06\0\0\x37\x02\0\0\x99\x08\0\0\x0f\xd4\x02\0\0\x07\0\0\x37\x02\0\0\x63\
1210
+\x05\0\0\x0d\xdc\x02\0\x18\x07\0\0\x37\x02\0\0\x63\x05\0\0\x0d\xdc\x02\0\x20\
1211
+\x07\0\0\x37\x02\0\0\xde\x08\0\0\x0d\xec\x02\0\x40\x07\0\0\x37\x02\0\0\x0d\x09\
1212
+\0\0\x20\xf0\x02\0\x68\x07\0\0\x37\x02\0\0\x39\x09\0\0\x13\xf8\x02\0\x90\x07\0\
1213
+\0\x37\x02\0\0\x19\x07\0\0\x11\0\x03\0\xa8\x07\0\0\x37\x02\0\0\x19\x07\0\0\x11\
1214
+\0\x03\0\xb0\x07\0\0\x37\x02\0\0\x81\x09\0\0\x19\x10\x03\0\xb8\x07\0\0\x37\x02\
1215
+\0\0\x81\x09\0\0\x34\x10\x03\0\xe0\x07\0\0\x37\x02\0\0\xb7\x09\0\0\x15\x24\x03\
1216
+\0\xf0\x07\0\0\x37\x02\0\0\xf8\x09\0\0\x17\x20\x03\0\x18\x08\0\0\x37\x02\0\0\
1217
+\x2f\x0a\0\0\x15\x30\x03\0\x30\x08\0\0\x37\x02\0\0\x2f\x0a\0\0\x15\x30\x03\0\
1218
+\x38\x08\0\0\x37\x02\0\0\x4a\x0a\0\0\x27\x40\x03\0\x70\x08\0\0\x37\x02\0\0\x75\
1219
+\x0a\0\0\x27\x5c\x03\0\x80\x08\0\0\x37\x02\0\0\xa5\x0a\0\0\x1c\xc0\x03\0\x88\
1220
+\x08\0\0\x37\x02\0\0\xe1\x0a\0\0\x20\xcc\x03\0\x98\x08\0\0\x37\x02\0\0\xe1\x0a\
1221
+\0\0\x2f\xcc\x03\0\xa0\x08\0\0\x37\x02\0\0\xe1\x0a\0\0\x36\xcc\x03\0\xa8\x08\0\
1222
+\0\x37\x02\0\0\xe1\x0a\0\0\x15\xcc\x03\0\x18\x09\0\0\x37\x02\0\0\x1d\x0b\0\0\
1223
+\x43\x70\x03\0\x38\x09\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x40\x09\0\0\x37\x02\0\0\
1224
+\x1d\x0b\0\0\x17\x70\x03\0\x68\x09\0\0\x37\x02\0\0\x2f\x0a\0\0\x15\x78\x03\0\
1225
+\x80\x09\0\0\x37\x02\0\0\x2f\x0a\0\0\x15\x78\x03\0\x88\x09\0\0\x37\x02\0\0\x6d\
1226
+\x0b\0\0\x19\x88\x03\0\x90\x09\0\0\x37\x02\0\0\x6d\x0b\0\0\x15\x88\x03\0\x98\
1227
+\x09\0\0\x37\x02\0\0\x9d\x0b\0\0\x19\x90\x03\0\xa0\x09\0\0\x37\x02\0\0\xcd\x0b\
1228
+\0\0\x1b\x8c\x03\0\xd0\x09\0\0\x37\x02\0\0\x08\x0c\0\0\x19\xa0\x03\0\xe8\x09\0\
1229
+\0\x37\x02\0\0\x08\x0c\0\0\x19\xa0\x03\0\xf0\x09\0\0\x37\x02\0\0\x27\x0c\0\0\
1230
+\x2b\xb0\x03\0\x10\x0a\0\0\x37\x02\0\0\xa5\x0a\0\0\x1f\xc0\x03\0\x30\x0a\0\0\
1231
+\x37\x02\0\0\x56\x0c\0\0\x21\xe0\x03\0\x40\x0a\0\0\x37\x02\0\0\x7e\x0c\0\0\x20\
1232
+\xf0\x03\0\x48\x0a\0\0\x37\x02\0\0\x7e\x0c\0\0\x2c\xf0\x03\0\x60\x0a\0\0\x37\
1233
+\x02\0\0\x7e\x0c\0\0\x14\xf0\x03\0\x70\x0a\0\0\x37\x02\0\0\xae\x0c\0\0\x20\xec\
1234
+\x03\0\x80\x0a\0\0\x37\x02\0\0\x5b\x08\0\0\x05\x3c\x02\0\xb0\x0a\0\0\x37\x02\0\
1235
+\0\xd6\x0c\0\0\x38\xcc\x02\0\xd0\x0a\0\0\x37\x02\0\0\xd6\x0c\0\0\x05\xcc\x02\0\
1236
+\xe8\x0a\0\0\x37\x02\0\0\x5b\x08\0\0\x05\x3c\x02\0\xf8\x0a\0\0\x37\x02\0\0\x14\
1237
+\x0d\0\0\x1c\xd0\x06\0\x08\x0b\0\0\x37\x02\0\0\x14\x0d\0\0\x10\xd0\x06\0\x10\
1238
+\x0b\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x60\x0b\0\0\x37\x02\0\0\x4f\x07\0\0\x19\
1239
+\xd4\x06\0\x68\x0b\0\0\x37\x02\0\0\x4f\x07\0\0\x20\xd4\x06\0\xa0\x0b\0\0\x37\
1240
+\x02\0\0\x3a\x0d\0\0\x2d\x0c\x07\0\xb0\x0b\0\0\x37\x02\0\0\x3a\x0d\0\0\x1d\x0c\
1241
+\x07\0\xb8\x0b\0\0\x37\x02\0\0\x3a\x0d\0\0\x2d\x0c\x07\0\xc8\x0b\0\0\x37\x02\0\
1242
+\0\x69\x0d\0\0\x2d\xe0\x06\0\xf8\x0b\0\0\x37\x02\0\0\x69\x0d\0\0\x1d\xe0\x06\0\
1243
+\x08\x0c\0\0\x37\x02\0\0\x69\x0d\0\0\x2d\xe0\x06\0\x18\x0c\0\0\x37\x02\0\0\0\0\
1244
+\0\0\0\0\0\0\xe8\x0c\0\0\x37\x02\0\0\x98\x0d\0\0\x20\x74\x06\0\xf0\x0c\0\0\x37\
1245
+\x02\0\0\x98\x0d\0\0\x27\x74\x06\0\x18\x0d\0\0\x37\x02\0\0\xc1\x0d\0\0\x27\xb0\
1246
+\x06\0\x20\x0d\0\0\x37\x02\0\0\xc1\x0d\0\0\x14\xb0\x06\0\x28\x0d\0\0\x37\x02\0\
1247
+\0\x0a\x0e\0\0\x05\xa4\x01\0\x38\x0d\0\0\x37\x02\0\0\x0a\x0e\0\0\x05\xa4\x01\0\
1248
+\x60\x0d\0\0\x37\x02\0\0\x63\x05\0\0\x0d\x60\x05\0\x70\x0d\0\0\x37\x02\0\0\0\0\
1249
+\0\0\0\0\0\0\x80\x0d\0\0\x37\x02\0\0\x98\x0d\0\0\x20\x50\x07\0\x88\x0d\0\0\x37\
1250
+\x02\0\0\x98\x0d\0\0\x27\x50\x07\0\xc0\x0d\0\0\x37\x02\0\0\x3a\x0d\0\0\x2d\x88\
1251
+\x07\0\xd0\x0d\0\0\x37\x02\0\0\x3a\x0d\0\0\x1d\x88\x07\0\xd8\x0d\0\0\x37\x02\0\
1252
+\0\x3a\x0d\0\0\x2d\x88\x07\0\xe8\x0d\0\0\x37\x02\0\0\x69\x0d\0\0\x2d\x5c\x07\0\
1253
+\x18\x0e\0\0\x37\x02\0\0\x69\x0d\0\0\x1d\x5c\x07\0\x28\x0e\0\0\x37\x02\0\0\x69\
1254
+\x0d\0\0\x2d\x5c\x07\0\x40\x0e\0\0\x37\x02\0\0\x47\x0e\0\0\x1a\xac\x05\0\x50\
1255
+\x0e\0\0\x37\x02\0\0\x65\x0e\0\0\x1b\xb4\x05\0\x60\x0e\0\0\x37\x02\0\0\x47\x0e\
1256
+\0\0\x1a\xac\x05\0\x68\x0e\0\0\x37\x02\0\0\x89\x0e\0\0\x13\xb8\x05\0\x90\x0e\0\
1257
+\0\x37\x02\0\0\x19\x07\0\0\x11\xc0\x05\0\xa0\x0e\0\0\x37\x02\0\0\x19\x07\0\0\
1258
+\x11\xc0\x05\0\xb0\x0e\0\0\x37\x02\0\0\x5b\x08\0\0\x05\x3c\x02\0\xc0\x0e\0\0\
1259
+\x37\x02\0\0\xda\x0e\0\0\x27\xd4\x07\0\xd0\x0e\0\0\x37\x02\0\0\xda\x0e\0\0\x14\
1260
+\xd4\x07\0\xf0\x0e\0\0\x37\x02\0\0\x69\x0d\0\0\x2d\xd8\x07\0\0\x0f\0\0\x37\x02\
1261
+\0\0\x69\x0d\0\0\x1d\xd8\x07\0\x08\x0f\0\0\x37\x02\0\0\x69\x0d\0\0\x2d\xd8\x07\
1262
+\0\x30\x0f\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x80\x0f\0\0\x37\x02\0\0\x3a\x0d\0\0\
1263
+\x1d\x04\x08\0\x88\x0f\0\0\x37\x02\0\0\x3a\x0d\0\0\x2d\x04\x08\0\x98\x0f\0\0\
1264
+\x37\x02\0\0\x0a\x0e\0\0\x05\xa4\x01\0\xf0\x0f\0\0\x37\x02\0\0\x0a\x0e\0\0\x05\
1265
+\xa4\x01\0\x30\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x48\x10\0\0\x37\x02\0\0\x23\
1266
+\x0f\0\0\x05\xdc\x01\0\x50\x10\0\0\x37\x02\0\0\x65\x0f\0\0\x23\xd0\x01\0\x68\
1267
+\x10\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\x70\x10\0\0\x37\x02\0\0\x99\x0f\0\0\x1b\
1268
+\xe0\x01\0\x90\x10\0\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\xa8\x10\0\0\x37\
1269
+\x02\0\0\xe9\x0f\0\0\x19\xe4\x01\0\xc0\x10\0\0\x37\x02\0\0\x17\x10\0\0\x27\x08\
1270
+\x02\0\xc8\x10\0\0\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\xd8\x10\0\0\x37\x02\0\
1271
+\0\x17\x10\0\0\x2d\x08\x02\0\xe0\x10\0\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\
1272
+\x08\x11\0\0\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\x20\x11\0\0\x37\x02\0\0\x17\
1273
+\x10\0\0\x27\x08\x02\0\x28\x11\0\0\x37\x02\0\0\x17\x10\0\0\x2d\x08\x02\0\x30\
1274
+\x11\0\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\x58\x11\0\0\x37\x02\0\0\x17\x10\
1275
+\0\0\x27\x08\x02\0\x60\x11\0\0\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\x78\x11\0\
1276
+\0\x37\x02\0\0\x17\x10\0\0\x2d\x08\x02\0\x80\x11\0\0\x37\x02\0\0\xc0\x0f\0\0\
1277
+\x11\xf4\x01\0\xa8\x11\0\0\x37\x02\0\0\x17\x10\0\0\x27\x08\x02\0\xb0\x11\0\0\
1278
+\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\xc8\x11\0\0\x37\x02\0\0\x17\x10\0\0\x2d\
1279
+\x08\x02\0\xd0\x11\0\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\xf8\x11\0\0\x37\
1280
+\x02\0\0\x17\x10\0\0\x46\x08\x02\0\x10\x12\0\0\x37\x02\0\0\x17\x10\0\0\x27\x08\
1281
+\x02\0\x18\x12\0\0\x37\x02\0\0\x17\x10\0\0\x2d\x08\x02\0\x20\x12\0\0\x37\x02\0\
1282
+\0\xc0\x0f\0\0\x11\xf4\x01\0\x48\x12\0\0\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\
1283
+\x60\x12\0\0\x37\x02\0\0\x17\x10\0\0\x27\x08\x02\0\x68\x12\0\0\x37\x02\0\0\x17\
1284
+\x10\0\0\x2d\x08\x02\0\x70\x12\0\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\x98\
1285
+\x12\0\0\x37\x02\0\0\x17\x10\0\0\x46\x08\x02\0\xb0\x12\0\0\x37\x02\0\0\x17\x10\
1286
+\0\0\x27\x08\x02\0\xb8\x12\0\0\x37\x02\0\0\x17\x10\0\0\x2d\x08\x02\0\xc0\x12\0\
1287
+\0\x37\x02\0\0\xc0\x0f\0\0\x11\xf4\x01\0\xe0\x12\0\0\x37\x02\0\0\x17\x10\0\0\
1288
+\x46\x08\x02\0\xe8\x12\0\0\x37\x02\0\0\x17\x10\0\0\x27\x08\x02\0\xf0\x12\0\0\
1289
+\x37\x02\0\0\x17\x10\0\0\x2d\x08\x02\0\xf8\x12\0\0\x37\x02\0\0\x23\x0f\0\0\x3d\
1290
+\xdc\x01\0\x08\x13\0\0\x37\x02\0\0\x23\x0f\0\0\x05\xdc\x01\0\x18\x13\0\0\x37\
1291
+\x02\0\0\x63\x10\0\0\x0d\xa4\x08\0\x28\x13\0\0\x37\x02\0\0\x63\x10\0\0\x0d\xa4\
1292
+\x08\0\x30\x13\0\0\x37\x02\0\0\x77\x10\0\0\x2e\xa8\x08\0\x50\x13\0\0\x37\x02\0\
1293
+\0\x77\x10\0\0\x24\xa8\x08\0\x58\x13\0\0\x37\x02\0\0\x77\x10\0\0\x13\xa8\x08\0\
1294
+\x68\x13\0\0\x37\x02\0\0\x77\x10\0\0\x2e\xa8\x08\0\x70\x13\0\0\x37\x02\0\0\xb6\
1295
+\x10\0\0\x15\xb4\x08\0\x88\x13\0\0\x37\x02\0\0\xfe\x10\0\0\x11\xc0\x08\0\x90\
1296
+\x13\0\0\x37\x02\0\0\0\0\0\0\0\0\0\0\xb0\x13\0\0\x37\x02\0\0\x17\x11\0\0\x01\
1297
+\xe4\x08\0\xb8\x13\0\0\x37\x02\0\0\x19\x11\0\0\x18\xc4\x08\0\0\0\0\0\0\0\0\0\0\
1298
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\
1299
+\0\0\0\0\0\0\x0d\x01\0\0\0\0\x03\0\xb0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x78\x01\
1300
+\0\0\0\0\x03\0\xb8\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2e\x01\0\0\0\0\x03\0\x90\x13\
1301
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbd\0\0\0\0\0\x03\0\xd0\x01\0\0\0\0\0\0\0\0\0\0\0\
1302
+\0\0\0\x2a\x02\0\0\0\0\x03\0\x20\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\x01\0\0\0\
1303
+\0\x03\0\xe8\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x43\x02\0\0\0\0\x03\0\x10\x04\0\0\
1304
+\0\0\0\0\0\0\0\0\0\0\0\0\x26\x01\0\0\0\0\x03\0\xe0\x02\0\0\0\0\0\0\0\0\0\0\0\0\
1305
+\0\0\x1a\x02\0\0\0\0\x03\0\x30\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x12\x02\0\0\0\0\
1306
+\x03\0\x38\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd4\0\0\0\0\0\x03\0\xf0\x03\0\0\0\0\
1307
+\0\0\0\0\0\0\0\0\0\0\x0a\x02\0\0\0\0\x03\0\xf8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1308
+\x47\x01\0\0\0\0\x03\0\xe8\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x57\x01\0\0\0\0\x03\
1309
+\0\xa0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd0\x01\0\0\0\0\x03\0\x40\x10\0\0\0\0\0\
1310
+\0\0\0\0\0\0\0\0\0\x7f\x01\0\0\0\0\x03\0\x78\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1311
+\x53\x02\0\0\0\0\x03\0\xb0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe9\x01\0\0\0\0\x03\
1312
+\0\x50\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc8\x01\0\0\0\0\x03\0\xc0\x06\0\0\0\0\0\
1313
+\0\0\0\0\0\0\0\0\0\xb0\x01\0\0\0\0\x03\0\x60\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1314
+\x8f\x01\0\0\0\0\x03\0\x60\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5f\x01\0\0\0\0\x03\
1315
+\0\x30\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4f\x01\0\0\0\0\x03\0\x40\x0a\0\0\0\0\0\
1316
+\0\0\0\0\0\0\0\0\0\xe1\x01\0\0\0\0\x03\0\xe0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1317
+\xc0\x01\0\0\0\0\x03\0\x48\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x67\x01\0\0\0\0\x03\
1318
+\0\x18\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x22\x02\0\0\0\0\x03\0\x80\x08\0\0\0\0\0\
1319
+\0\0\0\0\0\0\0\0\0\xb8\x01\0\0\0\0\x03\0\xf8\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1320
+\x87\x01\0\0\0\0\x03\0\x50\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe4\0\0\0\0\0\x03\0\
1321
+\x08\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1e\x01\0\0\0\0\x03\0\xe8\x0a\0\0\0\0\0\0\
1322
+\0\0\0\0\0\0\0\0\xdc\0\0\0\0\0\x03\0\xb0\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4b\
1323
+\x02\0\0\0\0\x03\0\xd8\x0a\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa8\x01\0\0\0\0\x03\0\
1324
+\x80\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3f\x01\0\0\0\0\x03\0\xb0\x0b\0\0\0\0\0\0\
1325
+\0\0\0\0\0\0\0\0\xfd\0\0\0\0\0\x03\0\xc8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3b\
1326
+\x02\0\0\0\0\x03\0\xf8\x0b\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd9\x01\0\0\0\0\x03\0\
1327
+\x18\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x02\0\0\0\0\x03\0\x10\x0c\0\0\0\0\0\0\
1328
+\0\0\0\0\0\0\0\0\xcc\0\0\0\0\0\x03\0\x18\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa0\
1329
+\x01\0\0\0\0\x03\0\xc0\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x16\x01\0\0\0\0\x03\0\
1330
+\xd0\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc4\0\0\0\0\0\x03\0\xe8\x0d\0\0\0\0\0\0\0\
1331
+\0\0\0\0\0\0\0\xfa\x01\0\0\0\0\x03\0\x18\x0e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x37\
1332
+\x01\0\0\0\0\x03\0\0\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf5\0\0\0\0\0\x03\0\x18\
1333
+\x0f\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x32\x02\0\0\0\0\x03\0\xf0\x0f\0\0\0\0\0\0\0\0\
1334
+\0\0\0\0\0\0\xf1\x01\0\0\0\0\x03\0\x30\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x97\x01\
1335
+\0\0\0\0\x03\0\x60\x10\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6f\x01\0\0\0\0\x03\0\x18\
1336
+\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xec\0\0\0\0\0\x03\0\xb8\x13\0\0\0\0\0\0\0\0\0\
1337
+\0\0\0\0\0\x59\0\0\0\x12\0\x03\0\0\0\0\0\0\0\0\0\xc8\x13\0\0\0\0\0\0\x3e\0\0\0\
1338
+\x11\0\x05\0\0\0\0\0\0\0\0\0\x28\0\0\0\0\0\0\0\x01\0\0\0\x11\0\x05\0\x28\0\0\0\
1339
+\0\0\0\0\x28\0\0\0\0\0\0\0\x86\0\0\0\x11\0\x05\0\x50\0\0\0\0\0\0\0\x28\0\0\0\0\
1340
+\0\0\0\x7d\0\0\0\x11\0\x06\0\0\0\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\x28\0\0\0\0\0\0\
1341
+\0\x01\0\0\0\x36\0\0\0\x50\0\0\0\0\0\0\0\x01\0\0\0\x37\0\0\0\x70\x13\0\0\0\0\0\
1342
+\0\x01\0\0\0\x38\0\0\0\x20\x05\0\0\0\0\0\0\x04\0\0\0\x36\0\0\0\x2c\x05\0\0\0\0\
1343
+\0\0\x04\0\0\0\x37\0\0\0\x38\x05\0\0\0\0\0\0\x04\0\0\0\x38\0\0\0\x50\x05\0\0\0\
1344
+\0\0\0\x04\0\0\0\x39\0\0\0\x2c\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\0\0\0\0\0\
1345
+\0\0\x04\0\0\0\x01\0\0\0\x50\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\0\0\0\0\0\0\
1346
+\0\x04\0\0\0\x01\0\0\0\x70\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\0\0\0\0\0\0\0\
1347
+\x04\0\0\0\x01\0\0\0\x90\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\0\0\0\0\0\0\0\
1348
+\x04\0\0\0\x01\0\0\0\xb0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\0\0\0\0\0\0\0\
1349
+\x04\0\0\0\x01\0\0\0\xd0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\0\0\0\0\0\0\0\
1350
+\x04\0\0\0\x01\0\0\0\xf0\0\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x01\0\0\0\0\0\0\
1351
+\x04\0\0\0\x01\0\0\0\x10\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x01\0\0\0\0\0\
1352
+\0\x04\0\0\0\x01\0\0\0\x30\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x01\0\0\0\0\
1353
+\0\0\x04\0\0\0\x01\0\0\0\x50\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x01\0\0\0\
1354
+\0\0\0\x04\0\0\0\x01\0\0\0\x70\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x01\0\0\
1355
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x01\0\
1356
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x01\
1357
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\
1358
+\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x01\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\
1359
+\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1360
+\x20\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1361
+\0\x40\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\
1362
+\0\0\x60\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x02\0\0\0\0\0\0\x04\0\0\0\x01\
1363
+\0\0\0\x80\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x02\0\0\0\0\0\0\x04\0\0\0\
1364
+\x01\0\0\0\xa0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x02\0\0\0\0\0\0\x04\0\0\
1365
+\0\x01\0\0\0\xc0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x02\0\0\0\0\0\0\x04\0\
1366
+\0\0\x01\0\0\0\xe0\x02\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x02\0\0\0\0\0\0\x04\
1367
+\0\0\0\x01\0\0\0\0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x03\0\0\0\0\0\0\x04\
1368
+\0\0\0\x01\0\0\0\x20\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x03\0\0\0\0\0\0\
1369
+\x04\0\0\0\x01\0\0\0\x40\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x03\0\0\0\0\0\
1370
+\0\x04\0\0\0\x01\0\0\0\x60\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x03\0\0\0\0\
1371
+\0\0\x04\0\0\0\x01\0\0\0\x80\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x03\0\0\0\
1372
+\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x03\0\0\
1373
+\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x03\0\
1374
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x03\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x03\
1375
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x04\
1376
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\
1377
+\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1378
+\x50\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1379
+\0\x70\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\
1380
+\0\0\x90\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x04\0\0\0\0\0\0\x04\0\0\0\x01\
1381
+\0\0\0\xb0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x04\0\0\0\0\0\0\x04\0\0\0\
1382
+\x01\0\0\0\xd0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x04\0\0\0\0\0\0\x04\0\0\
1383
+\0\x01\0\0\0\xf0\x04\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x05\0\0\0\0\0\0\x04\0\0\
1384
+\0\x01\0\0\0\x10\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x05\0\0\0\0\0\0\x04\0\
1385
+\0\0\x01\0\0\0\x30\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x05\0\0\0\0\0\0\x04\
1386
+\0\0\0\x01\0\0\0\x50\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x05\0\0\0\0\0\0\
1387
+\x04\0\0\0\x01\0\0\0\x70\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x05\0\0\0\0\0\
1388
+\0\x04\0\0\0\x01\0\0\0\x90\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x05\0\0\0\0\
1389
+\0\0\x04\0\0\0\x01\0\0\0\xb0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x05\0\0\0\
1390
+\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x05\0\0\
1391
+\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x05\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x06\0\0\
1392
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x06\0\
1393
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x06\
1394
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\
1395
+\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1396
+\x80\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1397
+\0\xa0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\
1398
+\0\0\xc0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x06\0\0\0\0\0\0\x04\0\0\0\x01\
1399
+\0\0\0\xe0\x06\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x06\0\0\0\0\0\0\x04\0\0\0\
1400
+\x01\0\0\0\0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x07\0\0\0\0\0\0\x04\0\0\0\
1401
+\x01\0\0\0\x20\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x07\0\0\0\0\0\0\x04\0\0\
1402
+\0\x01\0\0\0\x40\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x07\0\0\0\0\0\0\x04\0\
1403
+\0\0\x01\0\0\0\x60\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x07\0\0\0\0\0\0\x04\
1404
+\0\0\0\x01\0\0\0\x80\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x07\0\0\0\0\0\0\
1405
+\x04\0\0\0\x01\0\0\0\xa0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x07\0\0\0\0\0\
1406
+\0\x04\0\0\0\x01\0\0\0\xc0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x07\0\0\0\0\
1407
+\0\0\x04\0\0\0\x01\0\0\0\xe0\x07\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x07\0\0\0\
1408
+\0\0\0\x04\0\0\0\x01\0\0\0\0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x08\0\0\0\
1409
+\0\0\0\x04\0\0\0\x01\0\0\0\x20\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x08\0\0\
1410
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x08\0\
1411
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x08\
1412
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\
1413
+\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1414
+\xb0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1415
+\0\xd0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\
1416
+\0\0\xf0\x08\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\
1417
+\0\0\x10\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x09\0\0\0\0\0\0\x04\0\0\0\x01\
1418
+\0\0\0\x30\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x09\0\0\0\0\0\0\x04\0\0\0\
1419
+\x01\0\0\0\x50\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x09\0\0\0\0\0\0\x04\0\0\
1420
+\0\x01\0\0\0\x70\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x09\0\0\0\0\0\0\x04\0\
1421
+\0\0\x01\0\0\0\x90\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x09\0\0\0\0\0\0\x04\
1422
+\0\0\0\x01\0\0\0\xb0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x09\0\0\0\0\0\0\
1423
+\x04\0\0\0\x01\0\0\0\xd0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x09\0\0\0\0\0\
1424
+\0\x04\0\0\0\x01\0\0\0\xf0\x09\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0a\0\0\0\0\0\
1425
+\0\x04\0\0\0\x01\0\0\0\x10\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0a\0\0\0\0\
1426
+\0\0\x04\0\0\0\x01\0\0\0\x30\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0a\0\0\0\
1427
+\0\0\0\x04\0\0\0\x01\0\0\0\x50\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x60\x0a\0\0\
1428
+\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0a\0\
1429
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0a\
1430
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\
1431
+\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1432
+\xe0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x0a\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1433
+\0\0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1434
+\0\x20\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\
1435
+\0\0\x40\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x0b\0\0\0\0\0\0\x04\0\0\0\x01\
1436
+\0\0\0\x60\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0b\0\0\0\0\0\0\x04\0\0\0\
1437
+\x01\0\0\0\x80\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0b\0\0\0\0\0\0\x04\0\0\
1438
+\0\x01\0\0\0\xa0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x0b\0\0\0\0\0\0\x04\0\
1439
+\0\0\x01\0\0\0\xc0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x0b\0\0\0\0\0\0\x04\
1440
+\0\0\0\x01\0\0\0\xe0\x0b\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\x0b\0\0\0\0\0\0\
1441
+\x04\0\0\0\x01\0\0\0\0\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\x0c\0\0\0\0\0\0\
1442
+\x04\0\0\0\x01\0\0\0\x20\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x30\x0c\0\0\0\0\0\
1443
+\0\x04\0\0\0\x01\0\0\0\x40\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x50\x0c\0\0\0\0\
1444
+\0\0\x04\0\0\0\x01\0\0\0\x60\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x70\x0c\0\0\0\
1445
+\0\0\0\x04\0\0\0\x01\0\0\0\x80\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x90\x0c\0\0\
1446
+\0\0\0\0\x04\0\0\0\x01\0\0\0\xa0\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xb0\x0c\0\
1447
+\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xc0\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xd0\x0c\
1448
+\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xe0\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\xf0\
1449
+\x0c\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\0\x0d\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x10\
1450
+\x0d\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x20\x0d\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\
1451
+\x30\x0d\0\0\0\0\0\0\x04\0\0\0\x01\0\0\0\x40\x0d\0\0\0\0\0\0\x04\0\0\0\x01\0\0\
1452
+\0\x3f\x40\x41\x42\x43\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x74\
1453
+\x6f\x65\x70\x6c\x69\x74\x7a\x5f\x6b\x65\x79\0\x2e\x74\x65\x78\x74\0\x2e\x72\
1454
+\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\0\x2e\x72\x65\x6c\x73\x6f\x63\x6b\x65\
1455
+\x74\0\x2e\x6d\x61\x70\x73\0\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\
1456
+\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x73\0\x74\x75\x6e\x5f\x72\
1457
+\x73\x73\x5f\x73\x74\x65\x65\x72\x69\x6e\x67\x5f\x70\x72\x6f\x67\0\x2e\x6c\x6c\
1458
+\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\0\x5f\x6c\x69\x63\x65\x6e\x73\x65\0\
1459
+\x74\x61\x70\x5f\x72\x73\x73\x5f\x6d\x61\x70\x5f\x69\x6e\x64\x69\x72\x65\x63\
1460
+\x74\x69\x6f\x6e\x5f\x74\x61\x62\x6c\x65\0\x2e\x73\x74\x72\x74\x61\x62\0\x2e\
1461
+\x73\x79\x6d\x74\x61\x62\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\0\x4c\x42\x42\x30\
1462
+\x5f\x39\0\x4c\x42\x42\x30\x5f\x38\x39\0\x4c\x42\x42\x30\x5f\x36\x39\0\x4c\x42\
1463
+\x42\x30\x5f\x35\x39\0\x4c\x42\x42\x30\x5f\x34\x39\0\x4c\x42\x42\x30\x5f\x33\
1464
+\x39\0\x4c\x42\x42\x30\x5f\x31\x30\x39\0\x4c\x42\x42\x30\x5f\x39\x38\0\x4c\x42\
1465
+\x42\x30\x5f\x37\x38\0\x4c\x42\x42\x30\x5f\x31\x38\0\x4c\x42\x42\x30\x5f\x31\
1466
+\x30\x38\0\x4c\x42\x42\x30\x5f\x38\x37\0\x4c\x42\x42\x30\x5f\x34\x37\0\x4c\x42\
1467
+\x42\x30\x5f\x31\x37\0\x4c\x42\x42\x30\x5f\x31\x30\x37\0\x4c\x42\x42\x30\x5f\
1468
+\x39\x36\0\x4c\x42\x42\x30\x5f\x37\x36\0\x4c\x42\x42\x30\x5f\x36\x36\0\x4c\x42\
1469
+\x42\x30\x5f\x34\x36\0\x4c\x42\x42\x30\x5f\x36\x35\0\x4c\x42\x42\x30\x5f\x34\
1470
+\x35\0\x4c\x42\x42\x30\x5f\x33\x35\0\x4c\x42\x42\x30\x5f\x31\x30\x35\0\x4c\x42\
1471
+\x42\x30\x5f\x34\0\x4c\x42\x42\x30\x5f\x35\x34\0\x4c\x42\x42\x30\x5f\x34\x34\0\
1472
\x4c\x42\x42\x30\x5f\x33\x34\0\x4c\x42\x42\x30\x5f\x31\x30\x34\0\x4c\x42\x42\
1473
-\x30\x5f\x38\x33\0\x4c\x42\x42\x30\x5f\x35\x33\0\x4c\x42\x42\x30\x5f\x32\x33\0\
1474
-\x4c\x42\x42\x30\x5f\x31\x30\x33\0\x4c\x42\x42\x30\x5f\x39\x32\0\x4c\x42\x42\
1475
-\x30\x5f\x38\x32\0\x4c\x42\x42\x30\x5f\x37\x32\0\x4c\x42\x42\x30\x5f\x36\x32\0\
1476
-\x4c\x42\x42\x30\x5f\x35\x32\0\x4c\x42\x42\x30\x5f\x34\x32\0\x4c\x42\x42\x30\
1477
-\x5f\x32\x32\0\x4c\x42\x42\x30\x5f\x31\x30\x32\0\x4c\x42\x42\x30\x5f\x38\x31\0\
1478
-\x4c\x42\x42\x30\x5f\x36\x31\0\x4c\x42\x42\x30\x5f\x35\x31\0\x4c\x42\x42\x30\
1479
-\x5f\x31\x31\0\x4c\x42\x42\x30\x5f\x39\x30\0\x4c\x42\x42\x30\x5f\x37\x30\0\x4c\
1480
-\x42\x42\x30\x5f\x36\x30\0\x4c\x42\x42\x30\x5f\x35\x30\0\x4c\x42\x42\x30\x5f\
1481
-\x34\x30\0\x4c\x42\x42\x30\x5f\x32\x30\0\x4c\x42\x42\x30\x5f\x31\x31\x30\0\0\0\
1482
+\x30\x5f\x39\x33\0\x4c\x42\x42\x30\x5f\x38\x33\0\x4c\x42\x42\x30\x5f\x35\x33\0\
1483
+\x4c\x42\x42\x30\x5f\x34\x33\0\x4c\x42\x42\x30\x5f\x33\x33\0\x4c\x42\x42\x30\
1484
+\x5f\x32\x33\0\x4c\x42\x42\x30\x5f\x31\x30\x33\0\x4c\x42\x42\x30\x5f\x38\x32\0\
1485
+\x4c\x42\x42\x30\x5f\x35\x32\0\x4c\x42\x42\x30\x5f\x32\x32\0\x4c\x42\x42\x30\
1486
+\x5f\x31\x30\x32\0\x4c\x42\x42\x30\x5f\x39\x31\0\x4c\x42\x42\x30\x5f\x38\x31\0\
1487
+\x4c\x42\x42\x30\x5f\x37\x31\0\x4c\x42\x42\x30\x5f\x36\x31\0\x4c\x42\x42\x30\
1488
+\x5f\x35\x31\0\x4c\x42\x42\x30\x5f\x34\x31\0\x4c\x42\x42\x30\x5f\x31\x31\0\x4c\
1489
+\x42\x42\x30\x5f\x31\x30\x31\0\x4c\x42\x42\x30\x5f\x38\x30\0\x4c\x42\x42\x30\
1490
+\x5f\x36\x30\0\x4c\x42\x42\x30\x5f\x35\x30\0\x4c\x42\x42\x30\x5f\x32\x30\0\0\0\
1491
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1492
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xae\0\0\0\x03\0\0\0\
1493
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x25\x4a\0\0\0\0\0\0\x6d\x02\0\0\0\0\0\0\0\0\0\
1494
-\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\0\0\0\x01\0\0\0\x06\0\0\0\0\0\
1495
-\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\
1496
-\0\0\0\0\0\0\0\0\0\0\0\0\0\x68\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1497
-\0\x40\0\0\0\0\0\0\0\xe0\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\
1498
-\0\0\0\0\0\0\x64\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x3d\0\0\
1499
-\0\0\0\0\x30\0\0\0\0\0\0\0\x0c\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\
1500
-\0\0\x2d\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x14\0\0\0\0\0\0\
1501
-\x60\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\0\0\0\
1502
-\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x14\0\0\0\0\0\0\x07\0\0\0\0\0\
1503
-\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc2\0\0\0\x01\0\0\0\0\0\
1504
-\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x88\x14\0\0\0\0\0\0\x8d\x16\0\0\0\0\0\0\0\0\0\0\0\
1505
-\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbe\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\
1506
-\0\0\0\0\0\0\0\0\x70\x3d\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\x0c\0\0\0\x07\0\0\0\x08\
1507
-\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x24\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1508
-\0\0\0\x18\x2b\0\0\0\0\0\0\xa0\x0c\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\
1509
-\0\0\0\0\0\0\0\0\0\x20\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\
1510
-\x3d\0\0\0\0\0\0\x70\x0c\0\0\0\0\0\0\x0c\0\0\0\x09\0\0\0\x08\0\0\0\0\0\0\0\x10\
1511
-\0\0\0\0\0\0\0\x79\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\x20\
1512
-\x4a\0\0\0\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\
1513
-\0\0\0\xb6\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb8\x37\0\0\0\0\0\0\
1514
-\x88\x05\0\0\0\0\0\0\x01\0\0\0\x36\0\0\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\0\0";
1515
+\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa4\0\0\0\x03\0\0\0\0\0\0\0\0\0\
1516
+\0\0\0\0\0\0\0\0\0\0\xbd\x4b\0\0\0\0\0\0\x5b\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1517
+\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1a\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\
1518
+\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\
1519
+\0\0\0\0\0\0\0\0\x31\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\
1520
+\0\0\0\0\0\xc8\x13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1521
+\0\x2d\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x28\x3e\0\0\0\0\0\0\
1522
+\x30\0\0\0\0\0\0\0\x0c\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x38\
1523
+\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\x14\0\0\0\0\0\0\x78\0\0\
1524
+\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x7e\0\0\0\x01\0\0\
1525
+\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x80\x14\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\0\0\
1526
+\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb8\0\0\0\x01\0\0\0\0\0\0\0\0\0\
1527
+\0\0\0\0\0\0\0\0\0\0\x88\x14\0\0\0\0\0\0\xdb\x16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1528
+\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb4\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\
1529
+\0\0\0\0\0\x58\x3e\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\x0c\0\0\0\x07\0\0\0\x08\0\0\0\
1530
+\0\0\0\0\x10\0\0\0\0\0\0\0\x24\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1531
+\x64\x2b\0\0\0\0\0\0\x50\x0d\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\
1532
+\0\0\0\0\0\0\x20\0\0\0\x09\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x98\x3e\0\0\
1533
+\0\0\0\0\x20\x0d\0\0\0\0\0\0\x0c\0\0\0\x09\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\
1534
+\0\0\0\x6f\0\0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\xb8\x4b\0\0\
1535
+\0\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
1536
+\xac\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb8\x38\0\0\0\0\0\0\x70\
1537
+\x05\0\0\0\0\0\0\x01\0\0\0\x35\0\0\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\0\0";
1538
}
1539
1540
#ifdef __cplusplus
1541
diff --git a/meson.build b/meson.build
35
index XXXXXXX..XXXXXXX 100644
1542
index XXXXXXX..XXXXXXX 100644
36
--- a/net/colo.c
1543
--- a/meson.build
37
+++ b/net/colo.c
1544
+++ b/meson.build
38
@@ -XXX,XX +XXX,XX @@ void connection_destroy(void *opaque)
1545
@@ -XXX,XX +XXX,XX @@ elif get_option('vduse_blk_export').disabled()
39
g_slice_free(Connection, conn);
1546
endif
1547
1548
# libbpf
1549
-libbpf = dependency('libbpf', required: get_option('bpf'), method: 'pkg-config')
1550
+bpf_version = '1.1.0'
1551
+libbpf = dependency('libbpf', version: '>=' + bpf_version, required: get_option('bpf'), method: 'pkg-config')
1552
if libbpf.found() and not cc.links('''
1553
#include <bpf/libbpf.h>
1554
+ #include <linux/bpf.h>
1555
int main(void)
1556
{
1557
+ // check flag availability
1558
+ int flag = BPF_F_MMAPABLE;
1559
bpf_object__destroy_skeleton(NULL);
1560
return 0;
1561
}''', dependencies: libbpf)
1562
libbpf = not_found
1563
if get_option('bpf').enabled()
1564
- error('libbpf skeleton test failed')
1565
+ error('libbpf skeleton/mmaping test failed')
1566
else
1567
- warning('libbpf skeleton test failed, disabling')
1568
+ warning('libbpf skeleton/mmaping test failed, disabling')
1569
endif
1570
endif
1571
1572
diff --git a/tools/ebpf/rss.bpf.c b/tools/ebpf/rss.bpf.c
1573
index XXXXXXX..XXXXXXX 100644
1574
--- a/tools/ebpf/rss.bpf.c
1575
+++ b/tools/ebpf/rss.bpf.c
1576
@@ -XXX,XX +XXX,XX @@ struct {
1577
__uint(key_size, sizeof(__u32));
1578
__uint(value_size, sizeof(struct rss_config_t));
1579
__uint(max_entries, 1);
1580
+ __uint(map_flags, BPF_F_MMAPABLE);
1581
} tap_rss_map_configurations SEC(".maps");
1582
1583
struct {
1584
@@ -XXX,XX +XXX,XX @@ struct {
1585
__uint(key_size, sizeof(__u32));
1586
__uint(value_size, sizeof(struct toeplitz_key_data_t));
1587
__uint(max_entries, 1);
1588
+ __uint(map_flags, BPF_F_MMAPABLE);
1589
} tap_rss_map_toeplitz_key SEC(".maps");
1590
1591
struct {
1592
@@ -XXX,XX +XXX,XX @@ struct {
1593
__uint(key_size, sizeof(__u32));
1594
__uint(value_size, sizeof(__u16));
1595
__uint(max_entries, INDIRECTION_TABLE_SIZE);
1596
+ __uint(map_flags, BPF_F_MMAPABLE);
1597
} tap_rss_map_indirection_table SEC(".maps");
1598
1599
static inline void net_rx_rss_add_chunk(__u8 *rss_input, size_t *bytes_written,
1600
@@ -XXX,XX +XXX,XX @@ static inline __u32 calculate_rss_hash(struct __sk_buff *skb,
1601
return result;
40
}
1602
}
41
1603
42
-Packet *packet_new(const void *data, int size)
1604
-SEC("tun_rss_steering")
43
+Packet *packet_new(const void *data, int size, int vnet_hdr_len)
1605
+SEC("socket")
1606
int tun_rss_steering_prog(struct __sk_buff *skb)
44
{
1607
{
45
Packet *pkt = g_slice_new(Packet);
1608
46
47
pkt->data = g_memdup(data, size);
48
pkt->size = size;
49
pkt->creation_ms = qemu_clock_get_ms(QEMU_CLOCK_HOST);
50
+ pkt->vnet_hdr_len = vnet_hdr_len;
51
52
return pkt;
53
}
54
diff --git a/net/colo.h b/net/colo.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/net/colo.h
57
+++ b/net/colo.h
58
@@ -XXX,XX +XXX,XX @@ typedef struct Packet {
59
int size;
60
/* Time of packet creation, in wall clock ms */
61
int64_t creation_ms;
62
+ /* Get vnet_hdr_len from filter */
63
+ uint32_t vnet_hdr_len;
64
} Packet;
65
66
typedef struct ConnectionKey {
67
@@ -XXX,XX +XXX,XX @@ Connection *connection_get(GHashTable *connection_track_table,
68
ConnectionKey *key,
69
GQueue *conn_list);
70
void connection_hashtable_reset(GHashTable *connection_track_table);
71
-Packet *packet_new(const void *data, int size);
72
+Packet *packet_new(const void *data, int size, int vnet_hdr_len);
73
void packet_destroy(void *opaque, void *user_data);
74
75
#endif /* QEMU_COLO_PROXY_H */
76
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/net/filter-rewriter.c
79
+++ b/net/filter-rewriter.c
80
@@ -XXX,XX +XXX,XX @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
81
char *buf = g_malloc0(size);
82
83
iov_to_buf(iov, iovcnt, 0, buf, size);
84
- pkt = packet_new(buf, size);
85
+ pkt = packet_new(buf, size, 0);
86
g_free(buf);
87
88
/*
89
--
1609
--
90
2.7.4
1610
2.7.4
91
92
diff view generated by jsdifflib